Skip to content

Commit

Permalink
Initial port of authentication strategies from branch "feature/auth-s…
Browse files Browse the repository at this point in the history
…trategies-old"

#108
#136
  • Loading branch information
tintoy committed Jul 30, 2022
1 parent 11381a7 commit fc12ce6
Show file tree
Hide file tree
Showing 31 changed files with 939 additions and 214 deletions.
2 changes: 1 addition & 1 deletion samples/ConfigFromConfigMap/ConfigFromConfigMap.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<LangVersion>latest</LangVersion>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand Down
4 changes: 2 additions & 2 deletions samples/ExtensionsSample/ExtensionsSample.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/WatchEvents/WatchEvents.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand Down
4 changes: 2 additions & 2 deletions samples/noob-exec/NoobExec.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<AssemblyName>noob-exec</AssemblyName>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<LangVersion>latest</LangVersion>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<Description>Microsoft.Extensions.Configuration support for KubeClient</Description>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<Description>Custom Resource Definition (CRD) support for KubeClient</Description>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<Description>Dependency-injection support for KubeClient</Description>
</PropertyGroup>
Expand Down
56 changes: 20 additions & 36 deletions src/KubeClient.Extensions.KubeConfig/K8sConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
namespace KubeClient
{
using Extensions.KubeConfig.Models;
using KubeClient.Authentication;
using Microsoft.Extensions.Logging;
using System.Security.Cryptography.X509Certificates;

/// <summary>
/// Kubernetes client configuration.
Expand Down Expand Up @@ -194,70 +196,52 @@ public KubeClientOptions ConfigureKubeClientOptions(KubeClientOptions kubeClient
kubeClientOptions.AllowInsecure = targetCluster.Config.AllowInsecure;
kubeClientOptions.CertificationAuthorityCertificate = targetCluster.Config.GetCACertificate();

X509Certificate2 clientCertificate = targetUser.Config.GetClientCertificate();

// Mixed authentication types are not supported.
if (kubeClientOptions.ClientCertificate == null)
if (clientCertificate == null)
{
string accessToken = targetUser.Config.GetRawToken();
if (!String.IsNullOrWhiteSpace(accessToken))
{
kubeClientOptions.AccessToken = accessToken;
kubeClientOptions.AuthStrategy = KubeAuthStrategy.BearerToken;
}
kubeClientOptions.AuthStrategy = KubeAuthStrategy.BearerToken(accessToken);
else if (!String.IsNullOrEmpty(targetUser.Config.Username) && !String.IsNullOrEmpty(targetUser.Config.Password))
kubeClientOptions.AuthStrategy = KubeAuthStrategy.Basic(targetUser.Config.Username, targetUser.Config.Password);
else if (targetUser.Config.AuthProvider != null)
{
kubeClientOptions.Username = targetUser.Config.Username;
kubeClientOptions.Password = targetUser.Config.Password;
kubeClientOptions.AuthStrategy = KubeAuthStrategy.Basic;
}
else
{
kubeClientOptions.AuthStrategy = KubeAuthStrategy.None;
}
BearerTokenProviderAuthStrategy authStrategy = new BearerTokenProviderAuthStrategy();

AuthProviderConfig authProvider = targetUser.Config.AuthProvider;
if (authProvider != null)
{
kubeClientOptions.AuthStrategy = KubeAuthStrategy.BearerTokenProvider;
AuthProviderConfig authProvider = targetUser.Config.AuthProvider;

if (authProvider.Config.TryGetValue("cmd-path", out object accessTokenCommand))
kubeClientOptions.AccessTokenCommand = (string)accessTokenCommand;
authStrategy.Command = (string)accessTokenCommand;

if (authProvider.Config.TryGetValue("cmd-args", out object accessTokenCommandArguments))
kubeClientOptions.AccessTokenCommandArguments = (string)accessTokenCommandArguments;
authStrategy.Arguments = (string)accessTokenCommandArguments;

if (authProvider.Config.TryGetValue("token-key", out object accessTokenSelector))
kubeClientOptions.AccessTokenSelector = (string)accessTokenSelector;
authStrategy.Selector = (string)accessTokenSelector;

if (authProvider.Config.TryGetValue("expiry-key", out object accessTokenExpirySelector))
kubeClientOptions.AccessTokenExpirySelector = (string)accessTokenExpirySelector;
authStrategy.ExpirySelector = (string)accessTokenExpirySelector;

if (authProvider.Config.TryGetValue("access-token", out object initialAccessToken))
kubeClientOptions.InitialAccessToken = (string)initialAccessToken;
authStrategy.InitialToken = (string)initialAccessToken;

if (authProvider.Config.TryGetValue("expiry", out object initialTokenExpiry))
{
kubeClientOptions.InitialTokenExpiryUtc = DateTime.Parse((string)initialTokenExpiry,
authStrategy.InitialTokenExpiryUtc = DateTime.Parse((string)initialTokenExpiry,
provider: CultureInfo.InvariantCulture,
styles: DateTimeStyles.AssumeUniversal
);
}
}

CredentialPluginConfig execProvider = targetUser.Config.Exec;
if (execProvider != null)
{
kubeClientOptions.AuthStrategy = KubeAuthStrategy.CredentialPlugin;
kubeClientOptions.AccessTokenCommand = execProvider.Command;
kubeClientOptions.AccessTokenCommandArguments = string.Join(" ", execProvider.Arguments);
kubeClientOptions.AccessTokenSelector = ".status.token";
kubeClientOptions.AccessTokenExpirySelector = ".status.expirationTimestamp";
if (execProvider.EnvironmentVariables?.Count > 0)
foreach (var envVar in execProvider.EnvironmentVariables)
Environment.SetEnvironmentVariable(envVar.Name, envVar.Value);
kubeClientOptions.AuthStrategy = authStrategy;
}
else
kubeClientOptions.AuthStrategy = KubeAuthStrategy.None;
}
else
kubeClientOptions.AuthStrategy = KubeAuthStrategy.ClientCertificate;
kubeClientOptions.AuthStrategy = KubeAuthStrategy.ClientCertificate(clientCertificate);

return kubeClientOptions;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.4</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<Description>Kubernetes client configuration support for KubeClient</Description>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<Description>WebSockets support for KubeClient</Description>
</PropertyGroup>
Expand Down
83 changes: 83 additions & 0 deletions src/KubeClient/Authentication/BasicAuthStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using HTTPlease;
using System;
using System.Net.Http;

namespace KubeClient.Authentication
{
using MessageHandlers;

/// <summary>
/// A Kubernetes API authentication strategy that uses HTTP Basic (username / password) authentication.
/// </summary>
public class BasicAuthStrategy
: KubeAuthStrategy
{
/// <summary>
/// Create a new <see cref="BasicAuthStrategy"/>.
/// </summary>
public BasicAuthStrategy()
{
}

/// <summary>
/// The username for authentication to the Kubernetes API.
/// </summary>
public string UserName { get; set; }

/// <summary>
/// The password for authentication to the Kubernetes API.
/// </summary>
public string Password { get; set; }

/// <summary>
/// Validate the authentication strategy's configuration.
/// </summary>
/// <exception cref="KubeClientException">
/// The authentication strategy's configuration is incomplete or invalid.
/// </exception>
public override void Validate()
{
if (string.IsNullOrEmpty(UserName))
throw new KubeClientException("The username for for authentication to the Kubernetes API has not been configured.");

if (string.IsNullOrEmpty(Password))
throw new KubeClientException("The password for for authentication to the Kubernetes API has not been configured.");
}

/// <summary>
/// Configure the <see cref="ClientBuilder"/> used to create <see cref="HttpClient"/>s used by the API client.
/// </summary>
/// <param name="clientBuilder">
/// The <see cref="ClientBuilder"/> to configure.
/// </param>
/// <returns>
/// The configured <see cref="ClientBuilder"/>.
/// </returns>
public override ClientBuilder Configure(ClientBuilder clientBuilder)
{
if (clientBuilder == null)
throw new ArgumentNullException(nameof(clientBuilder));

Validate();

return clientBuilder.AddHandler(
() => new BasicAuthenticationHandler(UserName, Password)
);
}

/// <summary>
/// Create a deep clone of the authentication strategy.
/// </summary>
/// <returns>
/// The cloned <see cref="KubeAuthStrategy"/>.
/// </returns>
public override KubeAuthStrategy Clone()
{
return new BasicAuthStrategy
{
UserName = UserName,
Password = Password
};
}
}
}
74 changes: 74 additions & 0 deletions src/KubeClient/Authentication/BearerTokenAuthStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using HTTPlease;
using System;
using System.Net.Http;

namespace KubeClient.Authentication
{
using MessageHandlers;

/// <summary>
/// A Kubernetes API authentication strategy that uses a static access token.
/// </summary>
public class BearerTokenAuthStrategy
: KubeAuthStrategy
{
/// <summary>
/// Create a new <see cref="BearerTokenAuthStrategy"/>.
/// </summary>
public BearerTokenAuthStrategy()
{
}

/// <summary>
/// The static access token to use.
/// </summary>
public string Token { get; set; }

/// <summary>
/// Validate the authentication strategy's configuration.
/// </summary>
/// <exception cref="KubeClientException">
/// The authentication strategy's configuration is incomplete or invalid.
/// </exception>
public override void Validate()
{
if (string.IsNullOrWhiteSpace(Token))
throw new KubeClientException("The access token for authentication to the Kubernetes API has not been configured.");
}

/// <summary>
/// Configure the <see cref="ClientBuilder"/> used to create <see cref="HttpClient"/>s used by the API client.
/// </summary>
/// <param name="clientBuilder">
/// The <see cref="ClientBuilder"/> to configure.
/// </param>
/// <returns>
/// The configured <see cref="ClientBuilder"/>.
/// </returns>
public override ClientBuilder Configure(ClientBuilder clientBuilder)
{
if (clientBuilder == null)
throw new ArgumentNullException(nameof(clientBuilder));

Validate();

return clientBuilder.AddHandler(
() => new StaticBearerTokenHandler(Token)
);
}

/// <summary>
/// Create a deep clone of the authentication strategy.
/// </summary>
/// <returns>
/// The cloned <see cref="KubeAuthStrategy"/>.
/// </returns>
public override KubeAuthStrategy Clone()
{
return new BearerTokenAuthStrategy
{
Token = Token
};
}
}
}
Loading

0 comments on commit fc12ce6

Please sign in to comment.