defmodule Carny.Identifier do @moduledoc """ Identifiers are the objects that represent a given resource. i.e. bulwark:my-company:deployments """ alias __MODULE__ defstruct organization: "", domain: "", resource: "" @doc """ Parse an arn into an identifier struct ## Examples iex> Carny.Identifier.parse("bulwark:my-company:deployments") %Carny.Identifier{domain: "my-company", organization: "bulwark", resource: "deployments"} """ def parse(str) when is_binary(str), do: String.split(str, ":") |> parse() def parse([organization, domain, resource]), do: %Identifier{ organization: organization, domain: domain, resource: resource } def parse(_), do: {:error, :badmatch} @doc """ Takes an identifier and creates a list of each component. Useful when you're trying to build a string to represent the Identifier. """ def parts(%{organization: o, domain: d, resource: r}), do: [o, d, r] @doc ~S""" Returns a global identifier, aka "*" """ def global(), do: %Identifier{organization: "*", domain: "*", resource: "*"} @doc """ Given two identifiers see if the first matches the second """ def validate_against(identifier, resource) do identifier = replace_wildcards(identifier, resource) |> Map.take([:organization, :domain, :resource]) resource = resource |> Map.take([:organization, :domain, :resource]) # Do a pattern match match?( ^identifier, resource ) end @doc ~S""" Replaces all the variables in a given resource with "*" if the compared to resource has a "*" in that field """ def replace_wildcards(a, b) do a = if b.organization == "*", do: Map.put(a, :organization, "*"), else: a a = if b.domain == "*", do: Map.put(a, :domain, "*"), else: a if b.resource == "*", do: Map.put(a, :resource, "*"), else: a end end