From 80ed59c0224d74daaab48bcfb552da886fd66440 Mon Sep 17 00:00:00 2001 From: Andrew Dryga Date: Wed, 7 Jun 2023 18:27:45 -0600 Subject: [PATCH] Normalize CIDR resource addresses --- .../domain/resources/resource/changeset.ex | 22 +++++++++++++------ elixir/apps/domain/lib/domain/validator.ex | 5 ++++- .../domain/test/domain/resources_test.exs | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/elixir/apps/domain/lib/domain/resources/resource/changeset.ex b/elixir/apps/domain/lib/domain/resources/resource/changeset.ex index 66a338c4e..7d5d4bc2e 100644 --- a/elixir/apps/domain/lib/domain/resources/resource/changeset.ex +++ b/elixir/apps/domain/lib/domain/resources/resource/changeset.ex @@ -53,13 +53,21 @@ defmodule Domain.Resources.Resource.Changeset do defp validate_cidr_address(changeset) do changeset = validate_and_normalize_cidr(changeset, :address) - if has_errors?(changeset, :address) do - changeset - else - Network.cidrs() - |> Enum.reduce(changeset, fn {_type, cidr}, changeset -> - validate_not_in_cidr(changeset, :address, cidr) - end) + cond do + has_errors?(changeset, :address) -> + changeset + + get_field(changeset, :address) == "0.0.0.0/0" -> + changeset + + get_field(changeset, :address) == "::/0" -> + changeset + + true -> + Network.cidrs() + |> Enum.reduce(changeset, fn {_type, cidr}, changeset -> + validate_not_in_cidr(changeset, :address, cidr) + end) end end diff --git a/elixir/apps/domain/lib/domain/validator.ex b/elixir/apps/domain/lib/domain/validator.ex index 1b481a7b7..caca8f4dd 100644 --- a/elixir/apps/domain/lib/domain/validator.ex +++ b/elixir/apps/domain/lib/domain/validator.ex @@ -168,7 +168,8 @@ defmodule Domain.Validator do validate_change(changeset, ip_or_cidr_field, fn _ip_or_cidr_field, ip_or_cidr -> case Domain.Types.INET.cast(ip_or_cidr) do {:ok, ip_or_cidr} -> - if Domain.Types.CIDR.contains?(cidr, ip_or_cidr) do + if Domain.Types.CIDR.contains?(cidr, ip_or_cidr) or + Domain.Types.CIDR.contains?(ip_or_cidr, cidr) do [{ip_or_cidr_field, "can not be in the CIDR #{cidr}"}] else [] @@ -183,6 +184,8 @@ defmodule Domain.Validator do def validate_and_normalize_cidr(changeset, field, _opts \\ []) do with {_data_or_changes, value} <- fetch_change(changeset, field), {:ok, cidr} <- Domain.Types.CIDR.cast(value) do + {range_start, _range_end} = Domain.Types.CIDR.range(cidr) + cidr = %{cidr | address: range_start} put_change(changeset, field, to_string(cidr)) else :error -> diff --git a/elixir/apps/domain/test/domain/resources_test.exs b/elixir/apps/domain/test/domain/resources_test.exs index 7b668aeac..3e1214695 100644 --- a/elixir/apps/domain/test/domain/resources_test.exs +++ b/elixir/apps/domain/test/domain/resources_test.exs @@ -284,7 +284,7 @@ defmodule Domain.ResourcesTest do assert {:ok, resource} = create_resource(attrs, subject) - assert resource.address == attrs.address + assert resource.address == "192.168.1.0/28" assert resource.name == attrs.address assert resource.account_id == account.id