Skip to content

Commit

Permalink
add azure auth provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanspagh committed Feb 15, 2023
1 parent 10b956a commit f5726ae
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
erlang 25.2
elixir 1.14.2
erlang 24.1.7
elixir 1.14.0-otp-23
k3d 5.4.6
kind 0.17.0
92 changes: 92 additions & 0 deletions lib/k8s/conn/auth/azure.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
defmodule K8s.Conn.Auth.Azure do
@moduledoc """
`auth-provider` for azure
"""
alias K8s.Conn.RequestOptions
@behaviour K8s.Conn.Auth

defstruct [:token]

@type t :: %__MODULE__{
token: String.t()
}

@impl true
@spec create(map, String.t()) :: {:ok, t} | :skip
def create(
%{
"auth-provider" => %{
"config" => config,
"name" => "azure"
}
},
_
) do
%{
"access-token" => token,
"tenant-id" => tenant,
"expires-on" => expires_on,
"refresh-token" => refresh_token,
"client-id" => client_id,
"apiserver-id" => apiserver_id
} = config

if parse_expires(expires_on) <= DateTime.utc_now() do
# TODO current we don't have access to the credential file, so we wont be able to write the refresh token back into this, hence we will request a new token on every request when the original has expired
{:ok,
%__MODULE__{
token: refresh_token(tenant, refresh_token, client_id, apiserver_id)
}}
else
{:ok,
%__MODULE__{
token: token
}}
end
end

def create(_, _), do: :skip

def parse_expires(expires_on) do
case Integer.parse(expires_on) do
{expires_on, _} -> DateTime.from_unix!(expires_on)
:error -> DateTime.from_iso8601(expires_on)
end
end

defimpl RequestOptions, for: __MODULE__ do
@spec generate(KubeAzureAuth.AuthProvider.t()) :: RequestOptions.generate_t()
def generate(%KubeAzureAuth.AuthProvider{} = provider) do
{:ok,
%RequestOptions{
headers: [{:Authorization, "Bearer #{provider.token}"}],
ssl_options: []
}}
end
end

defp refresh_token(
tenant,
refresh_token,
client_id,
apiserver_id \\ "00000002-0000-0000-c000-000000000000"
) do
payload =
URI.encode_query(%{
"client_id" => client_id,
"grant_type" => "refresh_token",
"refresh_token" => refresh_token,
"scope" => apiserver_id
})

HTTPoison.post!(
"https://login.microsoftonline.com/#{tenant}/oauth2/v2.0/token",
payload,
%{
"Content-Type" => "application/x-www-form-urlencoded"
}
).body
|> Jason.decode!()
|> Map.get("access_token")
end
end

0 comments on commit f5726ae

Please sign in to comment.