-
-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auth provider for Azure? #162
Comments
|
Has there been any work done towards this? I may be able to contribute if so. |
Not that I know of. Also, OIDC SSO only works in an interactive mode because at some point, a browser has to be opened. |
Hi @CraigCottingham @mruoss Would you be interested in having this somewhere in the repo? defmodule KubeAzureAuth.AuthProvider 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
IO.inspect(config)
%{
"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 write new access token adn refresh back to file
{: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) do
# TODO figure out how to request scope apiserver_id
payload =
URI.encode_query(%{
"client_id" => client_id,
"grant_type" => "refresh_token",
"refresh_token" => refresh_token
})
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 |
@Hanspagh Thank you for this! I'm incorporating it into my code now, to make sure that it works. One question: The check for if the token has expired ( I'm making some other relatively minor changes, mainly to make it easier to update the refresh token. I'll post either here or to a gist once I have it working. |
@CraigCottingham, I think you got it completely right, it should be inverted, comparisons are hard :D. Again, this was just hacked together to see if it would work, to be "feature" complete with the python implementation we should also write the refreshed token back into the config. |
Do I get it right that this is already implemented? Would someone care to create a PR for this?
Yes, absolutely. Just next to |
Before I dive down the rabbit hole of implementing my own auth provider, has anyone gotten the
k8s
library working with Azure AKS?The problem I'm encountering trying to use
k8s
out of the box is that the user config in~/.kube/config
looks like it should be handled by the standardAuthProvider
module, but it contains a different set of keys.None of the keys in the destructuring at https://github.com/coryodaniel/k8s/blob/1.1.4/lib/k8s/conn/auth/auth_provider.ex#L22-L27 exist, so the code bombs out with "no match of right hand side".
The text was updated successfully, but these errors were encountered: