54 lines
1.5 KiB
Elixir
54 lines
1.5 KiB
Elixir
defmodule Towerops.Integrations.Integration do
|
|
@moduledoc """
|
|
Schema for per-organization third-party integrations.
|
|
|
|
Each organization can have one integration per provider. Credentials
|
|
are encrypted at rest using Cloak AES-256-GCM.
|
|
"""
|
|
use Ecto.Schema
|
|
|
|
import Ecto.Changeset
|
|
|
|
alias Towerops.Encrypted
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
@foreign_key_type :binary_id
|
|
|
|
@valid_providers ~w(preseem)
|
|
@valid_sync_statuses ~w(never success partial failed)
|
|
|
|
schema "integrations" do
|
|
field :provider, :string
|
|
field :enabled, :boolean, default: false
|
|
field :credentials, Encrypted.Map
|
|
field :sync_interval_minutes, :integer, default: 10
|
|
field :last_synced_at, :utc_datetime
|
|
field :last_sync_status, :string, default: "never"
|
|
|
|
belongs_to :organization, Towerops.Organizations.Organization
|
|
|
|
timestamps(type: :utc_datetime)
|
|
end
|
|
|
|
def changeset(integration, attrs) do
|
|
integration
|
|
|> cast(attrs, [
|
|
:organization_id,
|
|
:provider,
|
|
:enabled,
|
|
:credentials,
|
|
:sync_interval_minutes,
|
|
:last_synced_at,
|
|
:last_sync_status
|
|
])
|
|
|> validate_required([:organization_id, :provider])
|
|
|> validate_inclusion(:provider, @valid_providers)
|
|
|> validate_inclusion(:last_sync_status, @valid_sync_statuses)
|
|
|> validate_number(:sync_interval_minutes, greater_than: 0)
|
|
|> unique_constraint([:organization_id, :provider],
|
|
error_key: :provider,
|
|
message: "has already been taken"
|
|
)
|
|
|> foreign_key_constraint(:organization_id)
|
|
end
|
|
end
|