/// <summary> /// Add a <see cref="KubeApiClient"/> to the service collection. /// </summary> /// <param name="services"> /// The service collection to configure. /// </param> /// <param name="options"> /// <see cref="KubeClientOptions"/> containing the client configuration to use. /// </param> /// <returns> /// The configured service collection. /// </returns> public static IServiceCollection AddKubeClient(this IServiceCollection services, KubeClientOptions options) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } options.EnsureValid(); KubeApiClient ResolveWithOptions(IServiceProvider serviceProvider) { KubeClientOptions clientOptions = options.Clone(); if (clientOptions.LoggerFactory == null) { clientOptions.LoggerFactory = serviceProvider.GetService <ILoggerFactory>(); } return(KubeApiClient.Create(options)); } services.AddScoped <KubeApiClient>(ResolveWithOptions); services.AddScoped <IKubeApiClient>(ResolveWithOptions); return(services); }
/// <summary> /// Create and configure a <see cref="KubeApiClient"/> using the specified options. /// </summary> /// <param name="options"> /// The <see cref="KubeClientOptions"/> used to configure the client. /// </param> /// <returns> /// The configured <see cref="KubeApiClient"/>. /// </returns> public static KubeApiClient Create(KubeClientOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } options.EnsureValid(); var clientBuilder = new ClientBuilder(); switch (options.AuthStrategy) { case KubeAuthStrategy.Basic: { clientBuilder = clientBuilder.AddHandler( () => new BasicAuthenticationHandler(options.Username, options.Password) ); break; } case KubeAuthStrategy.BearerToken: { clientBuilder = clientBuilder.AddHandler( () => new StaticBearerTokenHandler(options.AccessToken) ); break; } case KubeAuthStrategy.BearerTokenProvider: { clientBuilder = clientBuilder.AddHandler( () => new CommandBearerTokenHandler( accessTokenCommand: options.AccessTokenCommand, accessTokenCommandArguments: options.AccessTokenCommandArguments, accessTokenSelector: options.AccessTokenSelector, accessTokenExpirySelector: options.AccessTokenExpirySelector, initialAccessToken: options.InitialAccessToken, initialTokenExpiryUtc: options.InitialTokenExpiryUtc ) ); break; } case KubeAuthStrategy.ClientCertificate: { if (options.ClientCertificate == null) { throw new KubeClientException("Cannot specify ClientCertificate authentication strategy without supplying a client certificate."); } clientBuilder = clientBuilder.WithClientCertificate(options.ClientCertificate); break; } } if (options.AllowInsecure) { clientBuilder = clientBuilder.AcceptAnyServerCertificate(); } else if (options.CertificationAuthorityCertificate != null) { clientBuilder = clientBuilder.WithServerCertificate(options.CertificationAuthorityCertificate); } if (options.LoggerFactory != null) { LogMessageComponents logComponents = LogMessageComponents.Basic; if (options.LogHeaders) { logComponents |= LogMessageComponents.Headers; } if (options.LogPayloads) { logComponents |= LogMessageComponents.Body; } clientBuilder = clientBuilder.WithLogging( logger: options.LoggerFactory.CreateLogger( typeof(KubeApiClient).FullName + ".Http" ), requestComponents: logComponents, responseComponents: logComponents ); } HttpClient httpClient = clientBuilder.CreateClient(options.ApiEndPoint); return(new KubeApiClient(httpClient, options)); }
/// <summary> /// Configure <see cref="KubeClientOptions"/> from the settings specified in the <see cref="K8sConfig"/>. /// </summary> /// <param name="kubeClientOptions"> /// /// </param> /// <param name="kubeContextName"> /// The name of the Kubernetes context to use. /// /// If not specified, then the current context (as configured) will be used. /// </param> /// <param name="defaultKubeNamespace"> /// The default Kubernetes namespace to use. /// </param> /// <returns> /// The configured <see cref="KubeClientOptions"/>. /// </returns> public KubeClientOptions ConfigureKubeClientOptions(KubeClientOptions kubeClientOptions, string kubeContextName = null, string defaultKubeNamespace = null) { if (kubeClientOptions == null) { throw new ArgumentNullException(nameof(kubeClientOptions)); } string targetContextName = kubeContextName ?? CurrentContextName; if (String.IsNullOrWhiteSpace(targetContextName)) { throw new InvalidOperationException("The kubeContextName parameter was not specified, and the Kubernetes client configuration does not specify a current context."); } Context targetContext = Contexts.Find(context => context.Name == targetContextName); if (targetContext == null) { throw new InvalidOperationException($"Cannot find a context in the Kubernetes client configuration named '{targetContextName}'."); } Cluster targetCluster = Clusters.Find(cluster => cluster.Name == targetContext.Config.ClusterName); if (targetCluster == null) { throw new InvalidOperationException($"Cannot find a cluster in the Kubernetes client configuration named '{targetContext.Config.ClusterName}'."); } UserIdentity targetUser = UserIdentities.Find(user => user.Name == targetContext.Config.UserName); if (targetUser == null) { throw new InvalidOperationException($"Cannot find a user identity in the Kubernetes client configuration named '{targetContext.Config.UserName}'."); } kubeClientOptions.ApiEndPoint = new Uri(targetCluster.Config.Server); kubeClientOptions.KubeNamespace = defaultKubeNamespace; kubeClientOptions.ClientCertificate = targetUser.Config.GetClientCertificate(); kubeClientOptions.AllowInsecure = targetCluster.Config.AllowInsecure; kubeClientOptions.CertificationAuthorityCertificate = targetCluster.Config.GetCACertificate(); // Mixed authentication types are not supported. if (kubeClientOptions.ClientCertificate == null) { string accessToken = targetUser.Config.GetRawToken(); if (!String.IsNullOrWhiteSpace(accessToken)) { kubeClientOptions.AccessToken = accessToken; kubeClientOptions.AuthStrategy = KubeAuthStrategy.BearerToken; } else { kubeClientOptions.AuthStrategy = KubeAuthStrategy.None; } AuthProviderConfig authProvider = targetUser.Config.AuthProvider; if (authProvider != null) { kubeClientOptions.AuthStrategy = KubeAuthStrategy.BearerTokenProvider; if (authProvider.Config.TryGetValue("cmd-path", out object accessTokenCommand)) { kubeClientOptions.AccessTokenCommand = (string)accessTokenCommand; } if (authProvider.Config.TryGetValue("cmd-args", out object accessTokenCommandArguments)) { kubeClientOptions.AccessTokenCommandArguments = (string)accessTokenCommandArguments; } if (authProvider.Config.TryGetValue("token-key", out object accessTokenSelector)) { kubeClientOptions.AccessTokenSelector = (string)accessTokenSelector; } if (authProvider.Config.TryGetValue("expiry-key", out object accessTokenExpirySelector)) { kubeClientOptions.AccessTokenExpirySelector = (string)accessTokenExpirySelector; } if (authProvider.Config.TryGetValue("access-token", out object initialAccessToken)) { kubeClientOptions.InitialAccessToken = (string)initialAccessToken; } if (authProvider.Config.TryGetValue("expiry", out object initialTokenExpiry)) { kubeClientOptions.InitialTokenExpiryUtc = DateTime.Parse((string)initialTokenExpiry, provider: CultureInfo.InvariantCulture, styles: DateTimeStyles.AssumeUniversal ); } } } else { kubeClientOptions.AuthStrategy = KubeAuthStrategy.ClientCertificate; } return(kubeClientOptions); }