-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
94 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |