# SPDX-License-Identifier: MIT defmodule TestcontainerEx.CephContainer do @moduledoc """ Provides functionality for creating and managing Ceph container configurations. """ alias TestcontainerEx.CephContainer alias TestcontainerEx.Container.Builder alias TestcontainerEx.Container.Config alias TestcontainerEx.LogWaitStrategy import TestcontainerEx.Container.Config, only: [is_valid_image: 1] @default_image "quay.io/ceph/demo" @default_tag "latest-quincy" @default_image_with_tag "#{@default_image}:#{@default_tag}" @default_bucket "test" @default_access_key "test" @default_secret_key :crypto.strong_rand_bytes(16) |> Base.encode16(case: :lower) @default_port 8080 @default_wait_timeout 300_000 @type t :: %__MODULE__{} @enforce_keys [:image, :access_key, :secret_key, :bucket, :port, :wait_timeout] defstruct [ :image, :access_key, :secret_key, :bucket, :port, :wait_timeout, check_image: @default_image, reuse: false ] def new, do: %__MODULE__{ image: @default_image_with_tag, wait_timeout: @default_wait_timeout, port: @default_port, access_key: @default_access_key, secret_key: @default_secret_key, bucket: @default_bucket } def with_image(%__MODULE__{} = config, image) when is_binary(image) do %{config | image: image} end def with_access_key(%__MODULE__{} = config, access_key) when is_binary(access_key) do %{config | access_key: access_key} end def with_secret_key(%__MODULE__{} = config, secret_key) when is_binary(secret_key) do %{config | secret_key: secret_key} end def with_bucket(%__MODULE__{} = config, bucket) when is_binary(bucket) do %{config | bucket: bucket} end def with_port(%__MODULE__{} = config, port) when is_integer(port) do %{config | port: port} end def with_wait_timeout(%__MODULE__{} = config, wait_timeout) when is_integer(wait_timeout) do %{config | wait_timeout: wait_timeout} end def with_check_image(%__MODULE__{} = config, check_image) when is_valid_image(check_image) do %__MODULE__{config | check_image: check_image} end def with_reuse(%__MODULE__{} = config, reuse) when is_boolean(reuse) do %__MODULE__{config | reuse: reuse} end def default_image, do: @default_image def port(%Config{} = container), do: TestcontainerEx.get_port(container, @default_port) def connection_url(%Config{} = container) do "http://#{TestcontainerEx.get_host(container)}:#{port(container)}" end def connection_opts(%Config{} = container) do [ port: CephContainer.port(container), scheme: "http://", host: TestcontainerEx.get_host(container), access_key_id: container.environment[:CEPH_DEMO_ACCESS_KEY], secret_access_key: container.environment[:CEPH_DEMO_SECRET_KEY] ] end defimpl Builder do @spec build(CephContainer.t()) :: Config.t() @impl true def build(%CephContainer{} = config) do Config.new(config.image) |> Config.with_exposed_port(config.port) |> Config.with_environment(:CEPH_DEMO_UID, "demo") |> Config.with_environment(:CEPH_DEMO_BUCKET, config.bucket) |> Config.with_environment(:CEPH_DEMO_ACCESS_KEY, config.access_key) |> Config.with_environment(:CEPH_DEMO_SECRET_KEY, config.secret_key) |> Config.with_environment(:CEPH_PUBLIC_NETWORK, "0.0.0.0/0") |> Config.with_environment(:MON_IP, "127.0.0.1") |> Config.with_environment(:RGW_NAME, "localhost") |> Config.with_waiting_strategy( LogWaitStrategy.new( ~r/.*Bucket 's3:\/\/#{config.bucket}\/' created.*/, config.wait_timeout, 5000 ) ) |> Config.with_check_image(config.check_image) |> Config.with_reuse(config.reuse) |> Config.valid_image!() end @impl true def after_start(_config, _container, _conn), do: :ok end end