public async Task GetToken() { var isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT; var cmd = Path.Combine(Directory.GetCurrentDirectory(), "assets", isWindows ? "mock-gcloud.cmd" : "mock-gcloud.sh"); if (!isWindows) { System.Diagnostics.Process.Start("chmod", $"+x {cmd}").WaitForExit(); } var sut = new GcpTokenProvider(cmd); var result = await sut.GetAuthenticationHeaderAsync(CancellationToken.None); result.Scheme.Should().Be("Bearer"); result.Parameter.Should().Be("ACCESS-TOKEN"); }
private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext) { if (string.IsNullOrWhiteSpace(activeContext.ContextDetails.User)) { return; } var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals( activeContext.ContextDetails.User, StringComparison.OrdinalIgnoreCase)); if (userDetails == null) { throw new KubeConfigException($"User not found for context {activeContext.Name} in kubeconfig"); } if (userDetails.UserCredentials == null) { throw new KubeConfigException($"User credentials not found for user: {userDetails.Name} in kubeconfig"); } var userCredentialsFound = false; // Basic and bearer tokens are mutually exclusive if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.Token)) { AccessToken = userDetails.UserCredentials.Token; userCredentialsFound = true; } else if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.UserName) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.Password)) { Username = userDetails.UserCredentials.UserName; Password = userDetails.UserCredentials.Password; userCredentialsFound = true; } // Token and cert based auth can co-exist if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificateData) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKeyData)) { ClientCertificateData = userDetails.UserCredentials.ClientCertificateData; ClientCertificateKeyData = userDetails.UserCredentials.ClientKeyData; userCredentialsFound = true; } if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificate) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKey)) { ClientCertificateFilePath = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientCertificate); ClientKeyFilePath = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientKey); userCredentialsFound = true; } if (userDetails.UserCredentials.AuthProvider != null) { if (userDetails.UserCredentials.AuthProvider.Config != null && (userDetails.UserCredentials.AuthProvider.Config.ContainsKey("access-token") || userDetails.UserCredentials.AuthProvider.Config.ContainsKey("id-token"))) { switch (userDetails.UserCredentials.AuthProvider.Name) { case "azure": { var config = userDetails.UserCredentials.AuthProvider.Config; if (config.ContainsKey("expires-on")) { var expiresOn = int.Parse(config["expires-on"]); DateTimeOffset expires; expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn); if (DateTimeOffset.Compare( expires, DateTimeOffset.Now) <= 0) { var tenantId = config["tenant-id"]; var clientId = config["client-id"]; var apiServerId = config["apiserver-id"]; var refresh = config["refresh-token"]; var newToken = RenewAzureToken( tenantId, clientId, apiServerId, refresh); config["access-token"] = newToken; } } AccessToken = config["access-token"]; userCredentialsFound = true; break; } case "gcp": { // config var config = userDetails.UserCredentials.AuthProvider.Config; TokenProvider = new GcpTokenProvider(config["cmd-path"]); userCredentialsFound = true; break; } case "oidc": { var config = userDetails.UserCredentials.AuthProvider.Config; AccessToken = config["id-token"]; if (config.ContainsKey("client-id") && config.ContainsKey("idp-issuer-url") && config.ContainsKey("id-token") && config.ContainsKey("refresh-token")) { string clientId = config["client-id"]; string clientSecret = config.ContainsKey("client-secret") ? config["client-secret"] : null; string idpIssuerUrl = config["idp-issuer-url"]; string idToken = config["id-token"]; string refreshToken = config["refresh-token"]; TokenProvider = new OidcTokenProvider(clientId, clientSecret, idpIssuerUrl, idToken, refreshToken); userCredentialsFound = true; } break; } } } } if (userDetails.UserCredentials.ExternalExecution != null) { if (string.IsNullOrWhiteSpace(userDetails.UserCredentials.ExternalExecution.Command)) { throw new KubeConfigException( "External command execution to receive user credentials must include a command to execute"); } if (string.IsNullOrWhiteSpace(userDetails.UserCredentials.ExternalExecution.ApiVersion)) { throw new KubeConfigException("External command execution missing ApiVersion key"); } var(accessToken, clientCertificateData, clientCertificateKeyData) = ExecuteExternalCommand(userDetails.UserCredentials.ExternalExecution); AccessToken = accessToken; // When reading ClientCertificateData from a config file it will be base64 encoded, and code later in the system (see CertUtils.GeneratePfx) // expects ClientCertificateData and ClientCertificateKeyData to be base64 encoded because of this. However the string returned by external // auth providers is the raw certificate and key PEM text, so we need to take that and base64 encoded it here so it can be decoded later. ClientCertificateData = clientCertificateData == null ? null : Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(clientCertificateData)); ClientCertificateKeyData = clientCertificateKeyData == null ? null : Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(clientCertificateKeyData)); userCredentialsFound = true; } if (!userCredentialsFound) { throw new KubeConfigException( $"User: {userDetails.Name} does not have appropriate auth credentials in kubeconfig"); } }
private void SetUserDetails(K8SConfiguration k8SConfig, Context activeContext) { if (string.IsNullOrWhiteSpace(activeContext.ContextDetails.User)) { return; } var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User, StringComparison.OrdinalIgnoreCase)); if (userDetails == null) { throw new KubeConfigException($"User not found for context {activeContext.Name} in kubeconfig"); } if (userDetails.UserCredentials == null) { throw new KubeConfigException($"User credentials not found for user: {userDetails.Name} in kubeconfig"); } var userCredentialsFound = false; // Basic and bearer tokens are mutually exclusive if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.Token)) { AccessToken = userDetails.UserCredentials.Token; userCredentialsFound = true; } else if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.UserName) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.Password)) { Username = userDetails.UserCredentials.UserName; Password = userDetails.UserCredentials.Password; userCredentialsFound = true; } // Token and cert based auth can co-exist if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificateData) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKeyData)) { ClientCertificateData = userDetails.UserCredentials.ClientCertificateData; ClientCertificateKeyData = userDetails.UserCredentials.ClientKeyData; userCredentialsFound = true; } if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificate) && !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKey)) { ClientCertificateFilePath = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientCertificate); ClientKeyFilePath = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientKey); userCredentialsFound = true; } if (userDetails.UserCredentials.AuthProvider != null) { if (userDetails.UserCredentials.AuthProvider.Config != null && userDetails.UserCredentials.AuthProvider.Config.ContainsKey("access-token")) { switch (userDetails.UserCredentials.AuthProvider.Name) { case "azure": { var config = userDetails.UserCredentials.AuthProvider.Config; if (config.ContainsKey("expires-on")) { var expiresOn = Int32.Parse(config["expires-on"]); DateTimeOffset expires; #if NET452 var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero); expires = epoch.AddSeconds(expiresOn); #else expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn); #endif if (DateTimeOffset.Compare(expires , DateTimeOffset.Now) <= 0) { var tenantId = config["tenant-id"]; var clientId = config["client-id"]; var apiServerId = config["apiserver-id"]; var refresh = config["refresh-token"]; var newToken = RenewAzureToken(tenantId , clientId , apiServerId , refresh); config["access-token"] = newToken; } } AccessToken = config["access-token"]; userCredentialsFound = true; break; } case "gcp": { // config var config = userDetails.UserCredentials.AuthProvider.Config; TokenProvider = new GcpTokenProvider(config["cmd-path"]); userCredentialsFound = true; break; } } } } if (userDetails.UserCredentials.ExternalExecution != null) { if (string.IsNullOrWhiteSpace(userDetails.UserCredentials.ExternalExecution.Command)) { throw new KubeConfigException( "External command execution to receive user credentials must include a command to execute"); } if (string.IsNullOrWhiteSpace(userDetails.UserCredentials.ExternalExecution.ApiVersion)) { throw new KubeConfigException("External command execution missing ApiVersion key"); } var(accessToken, clientCertificateData, clientCertificateKeyData) = ExecuteExternalCommand(userDetails.UserCredentials.ExternalExecution); AccessToken = accessToken; ClientCertificateData = clientCertificateData; ClientCertificateKeyData = clientCertificateKeyData; userCredentialsFound = true; } if (!userCredentialsFound) { throw new KubeConfigException( $"User: {userDetails.Name} does not have appropriate auth credentials in kubeconfig"); } }