diff --git a/backend/lib/edgehog/containers/changes/create_default_network.ex b/backend/lib/edgehog/containers/changes/create_default_network.ex new file mode 100644 index 000000000..284ff5574 --- /dev/null +++ b/backend/lib/edgehog/containers/changes/create_default_network.ex @@ -0,0 +1,69 @@ +# +# This file is part of Edgehog. +# +# Copyright 2024 SECO Mind Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +defmodule Edgehog.Containers.Changes.CreateDefaultNetwork do + @moduledoc false + use Ash.Resource.Change + + alias Edgehog.Containers.ContainerNetwork + alias Edgehog.Containers.Network + + @impl Ash.Resource.Change + def change(changeset, _opts, _ctx) do + Ash.Changeset.after_action(changeset, fn _changeset, release -> + with {:ok, release} <- Ash.load(release, :containers), + {:ok, network} <- create_default_network(release.tenant_id), + :ok <- create_networks(release, network) do + {:ok, release} + end + end) + end + + defp create_networks(release, network) do + Enum.reduce_while(release.containers, :ok, fn container, _acc -> + add_network(container, network) + end) + end + + defp create_default_network(tenant) do + default_network_parameters = %{ + driver: "bridge", + options: ["isolate=true"], + internal: true, + enable_ipv6: false + } + + Network + |> Ash.Changeset.for_create(:create, default_network_parameters) + |> Ash.create(tenant: tenant) + end + + defp add_network(container, network) do + params = %{ + container_id: container.id, + network_id: network.id + } + + case Ash.create(ContainerNetwork, params, tenant: container.tenant_id) do + {:ok, _device} -> {:cont, :ok} + {:error, reason} -> {:halt, {:error, reason}} + end + end +end diff --git a/backend/lib/edgehog/containers/manual_actions/send_deploy_request.ex b/backend/lib/edgehog/containers/manual_actions/send_deploy_request.ex index 145cba079..619c51e41 100644 --- a/backend/lib/edgehog/containers/manual_actions/send_deploy_request.ex +++ b/backend/lib/edgehog/containers/manual_actions/send_deploy_request.ex @@ -23,7 +23,6 @@ defmodule Edgehog.Containers.ManualActions.SendDeployRequest do use Ash.Resource.Actions.Implementation - alias Edgehog.Containers.Network alias Edgehog.Devices @impl Ash.Resource.Actions.Implementation @@ -38,16 +37,10 @@ defmodule Edgehog.Containers.ManualActions.SendDeployRequest do containers = release.containers images = containers |> Enum.map(& &1.image) |> Enum.uniq() - # send one network for each container, so that each container is isolated networks = containers - |> Enum.filter(&(&1.networks == [])) - |> Enum.map(fn container -> - Network - |> Ash.Changeset.for_create(:create, %{driver: "bridge"}) - |> Ash.Changeset.manage_relationship(:containers, [container], type: :create) - |> Ash.create!(tenant: deployment.tenant_id) - end) + |> Enum.flat_map(& &1.networks) + |> Enum.uniq_by(& &1.id) with :ok <- send_create_image_requests(device, images), :ok <- send_create_container_requests(device, containers), diff --git a/backend/lib/edgehog/containers/release.ex b/backend/lib/edgehog/containers/release.ex index 06fb053eb..a3c9ccc30 100644 --- a/backend/lib/edgehog/containers/release.ex +++ b/backend/lib/edgehog/containers/release.ex @@ -24,6 +24,7 @@ defmodule Edgehog.Containers.Release do domain: Edgehog.Containers, extensions: [AshGraphql.Resource] + alias Edgehog.Containers.Changes alias Edgehog.Validations graphql do @@ -47,6 +48,8 @@ defmodule Edgehog.Containers.Release do on_no_match: {:create, :create_with_nested}, on_match: :ignore ) + + change Changes.CreateDefaultNetwork end end diff --git a/backend/test/edgehog_web/schema/mutation/deploy_release_test.exs b/backend/test/edgehog_web/schema/mutation/deploy_release_test.exs index 6e0ad920d..0198f8e44 100644 --- a/backend/test/edgehog_web/schema/mutation/deploy_release_test.exs +++ b/backend/test/edgehog_web/schema/mutation/deploy_release_test.exs @@ -33,8 +33,8 @@ defmodule EdgehogWeb.Schema.Mutation.DeployReleaseTest do containers = 3 # one image per container images = containers - # one network per container - networks = containers + # one network for the release + networks = 1 device = device_fixture(tenant: tenant) release = release_fixture(tenant: tenant, containers: containers)