Skip to content

Commit

Permalink
Merge e183886 into 2147c31
Browse files Browse the repository at this point in the history
  • Loading branch information
spbsoluble authored Sep 17, 2024
2 parents 2147c31 + e183886 commit 52f80f1
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 406 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# 1.1.3

## Bug Fixes
- fix(base): Add additional logging to debug issue with K8SNS store type.
- fix(client): Handle skip TLS flag when passed to a job.

## Chores:
- chore(deps): Bump `Keyfactor.Logging` to `v1.1.2`
- chore(deps): Bump `Keyfactor.PKI` to `v5.5.0`

# 1.1.2

## Bug Fixes
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

# Kubernetes Orchestrator Extension

The Kubernetes Orchestrator allows for the remote management of certificate stores defined in a Kubernetes cluster. The following types of Kubernetes resources are supported: kubernetes secrets of `kubernetes.io/tls` or `Opaque` and kubernetes certificates `certificates.k8s.io/v1`
The Kubernetes Orchestrator allows for the remote management of certificate stores defined in a Kubernetes cluster. The following types of Kubernetes resources are supported:
- Secrets - Kubernetes secrets of type `kubernetes.io/tls` or `Opaque`
- Certificates - Kubernetes certificates of type `certificates.k8s.io/v1`

#### Integration status: Production - Ready for use in production environments.

Expand Down
88 changes: 49 additions & 39 deletions kubernetes-orchestrator-extension/Clients/KubeClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
Expand Down Expand Up @@ -84,14 +85,15 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify =
{
_logger.LogTrace("Entered ParseKubeConfig()");
var k8SConfiguration = new K8SConfiguration();

_logger.LogTrace("Checking if kubeconfig is null or empty");
if (string.IsNullOrEmpty(kubeconfig))
{
_logger.LogError("kubeconfig is null or empty");
throw new KubeConfigException("kubeconfig is null or empty, please provide a valid kubeconfig in JSON format. For more information on how to create a kubeconfig file, please visit https://github.com/Keyfactor/k8s-orchestrator/tree/main/scripts/kubernetes#example-service-account-json");
throw new KubeConfigException(
"kubeconfig is null or empty, please provide a valid kubeconfig in JSON format. For more information on how to create a kubeconfig file, please visit https://github.com/Keyfactor/k8s-orchestrator/tree/main/scripts/kubernetes#example-service-account-json");
}

try
{
// test if kubeconfig is base64 encoded
Expand All @@ -118,10 +120,11 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify =
if (!kubeconfig.StartsWith("{"))
{
_logger.LogError("kubeconfig is not a JSON object");
throw new KubeConfigException("kubeconfig is not a JSON object, please provide a valid kubeconfig in JSON format. For more information on how to create a kubeconfig file, please visit: https://github.com/Keyfactor/k8s-orchestrator/tree/main/scripts/kubernetes#get_service_account_credssh");
throw new KubeConfigException(
"kubeconfig is not a JSON object, please provide a valid kubeconfig in JSON format. For more information on how to create a kubeconfig file, please visit: https://github.com/Keyfactor/k8s-orchestrator/tree/main/scripts/kubernetes#get_service_account_credssh");
// return k8SConfiguration;
}
}


_logger.LogDebug("Parsing kubeconfig as a dictionary of string, string");

Expand Down Expand Up @@ -151,18 +154,21 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify =
_logger.LogTrace("Creating Cluster object for cluster '{Name}'", clusterMetadata["name"]?.ToString());
// get environment variable for skip tls verify and convert to bool
var skipTlsEnvStr = Environment.GetEnvironmentVariable("KEYFACTOR_ORCHESTRATOR_SKIP_TLS_VERIFY");
_logger.LogTrace("KEYFACTOR_ORCHESTRATOR_SKIP_TLS_VERIFY environment variable: {SkipTlsVerify}", skipTlsEnvStr);
if (!string.IsNullOrEmpty(skipTlsEnvStr) && (bool.TryParse(skipTlsEnvStr, out var skipTlsVerifyEnv) || skipTlsEnvStr == "1"))
_logger.LogTrace("KEYFACTOR_ORCHESTRATOR_SKIP_TLS_VERIFY environment variable: {SkipTlsVerify}",
skipTlsEnvStr);
if (!string.IsNullOrEmpty(skipTlsEnvStr) &&
(bool.TryParse(skipTlsEnvStr, out var skipTlsVerifyEnv) || skipTlsEnvStr == "1"))
{
if (skipTlsEnvStr == "1") skipTlsVerifyEnv = true;
_logger.LogDebug("Setting skip-tls-verify to {SkipTlsVerify}", skipTlsVerifyEnv);
if (skipTlsVerifyEnv && !skipTLSVerify)
{
_logger.LogWarning("Skipping TLS verification is enabled in environment variable KEYFACTOR_ORCHESTRATOR_SKIP_TLS_VERIFY this takes the highest precedence and verification will be skipped. To disable this, set the environment variable to 'false' or remove it");
_logger.LogWarning(
"Skipping TLS verification is enabled in environment variable KEYFACTOR_ORCHESTRATOR_SKIP_TLS_VERIFY this takes the highest precedence and verification will be skipped. To disable this, set the environment variable to 'false' or remove it");
skipTLSVerify = true;
}
}

var clusterObj = new Cluster
{
Name = clusterMetadata["name"]?.ToString(),
Expand All @@ -173,7 +179,8 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify =
SkipTlsVerify = skipTLSVerify
}
};
_logger.LogTrace("Adding cluster '{Name}'({@Endpoint}) to K8SConfiguration", clusterObj.Name, clusterObj.ClusterEndpoint);
_logger.LogTrace("Adding cluster '{Name}'({@Endpoint}) to K8SConfiguration", clusterObj.Name,
clusterObj.ClusterEndpoint);
k8SConfiguration.Clusters = new List<Cluster> { clusterObj };
}

Expand Down Expand Up @@ -220,7 +227,7 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify =

_logger.LogTrace("Finished parsing contexts");
_logger.LogDebug("Finished parsing kubeconfig");

return k8SConfiguration;
}

Expand All @@ -240,7 +247,7 @@ private IKubernetes GetKubeClient(string kubeconfig)
_logger.LogDebug("Calling ParseKubeConfig()");
var k8SConfiguration = ParseKubeConfig(kubeconfig);
_logger.LogDebug("Finished calling ParseKubeConfig()");

// use k8sConfiguration over credentialFileName
KubernetesClientConfiguration config;
if (k8SConfiguration != null) // Config defined in store parameters takes highest precedence
Expand All @@ -258,7 +265,9 @@ private IKubernetes GetKubeClient(string kubeconfig)
config = KubernetesClientConfiguration.BuildDefaultConfig();
}
}
else if (string.IsNullOrEmpty(credentialFileName)) // If no config defined in store parameters, use default config. This should never happen though.
else if
(string.IsNullOrEmpty(
credentialFileName)) // If no config defined in store parameters, use default config. This should never happen though.
{
_logger.LogWarning(
"No config defined in store parameters, using default config. This should never happen!");
Expand Down Expand Up @@ -1800,7 +1809,7 @@ public List<string> DiscoverSecrets(string[] allowedKeys, string secType, string
_logger.LogTrace("Client BaseUrl: {BaseUrl}", Client.BaseUri);
_logger.LogDebug("Calling CoreV1.ListNamespace()");
namespaces = Client.CoreV1.ListNamespace();

_logger.LogDebug("returned from CoreV1.ListNamespace()");
_logger.LogTrace("namespaces.Items.Count: {Count}", namespaces.Items.Count);
_logger.LogTrace("namespaces.Items: {Items}", namespaces.Items.ToString());
Expand All @@ -1816,7 +1825,8 @@ public List<string> DiscoverSecrets(string[] allowedKeys, string secType, string
if (nsLi != "all" && nsLi != nsObj.Metadata.Name)
{
_logger.LogWarning(
"Skipping namespace '{Namespace}' because it does not match the namespace filter", nsObj.Metadata.Name);
"Skipping namespace '{Namespace}' because it does not match the namespace filter",
nsObj.Metadata.Name);
continue;
}

Expand Down Expand Up @@ -1977,6 +1987,28 @@ public List<string> DiscoverSecrets(string[] allowedKeys, string secType, string
return locations;
}

public struct JksSecret
{
public string SecretPath;
public string SecretFieldName;
public V1Secret Secret;
public string Password;
public string PasswordPath;
public List<string> AllowedKeys;
public Dictionary<string, byte[]> Inventory;
}

public struct Pkcs12Secret
{
public string SecretPath;
public string SecretFieldName;
public V1Secret Secret;
public string Password;
public string PasswordPath;
public List<string> AllowedKeys;
public Dictionary<string, byte[]> Inventory;
}

public JksSecret GetJksSecret(string secretName, string namespaceName, string password = null,
string passwordPath = null, List<string> allowedKeys = null)
{
Expand Down Expand Up @@ -2170,7 +2202,7 @@ public CsrObject GenerateCertificateRequest(string name, string[] sans, IPAddres
X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature,
false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(new OidCollection { new("1.3.6.1.5.5.7.3.1") }, false));
new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(sanBuilder.Build());
var csr = request.CreateSigningRequest();
var csrPem = "-----BEGIN CERTIFICATE REQUEST-----\r\n" +
Expand Down Expand Up @@ -2291,28 +2323,6 @@ public V1Secret CreateOrUpdatePkcs12Secret(Pkcs12Secret k8SData, string kubeSecr
return Client.CoreV1.ReplaceNamespacedSecret(s1, kubeSecretName, kubeNamespace);
}

public struct JksSecret
{
public string SecretPath;
public string SecretFieldName;
public V1Secret Secret;
public string Password;
public string PasswordPath;
public List<string> AllowedKeys;
public Dictionary<string, byte[]> Inventory;
}

public struct Pkcs12Secret
{
public string SecretPath;
public string SecretFieldName;
public V1Secret Secret;
public string Password;
public string PasswordPath;
public List<string> AllowedKeys;
public Dictionary<string, byte[]> Inventory;
}

public struct CsrObject
{
public string Csr;
Expand Down
12 changes: 6 additions & 6 deletions kubernetes-orchestrator-extension/Jobs/Inventory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ public JobResult ProcessJob(InventoryJobConfiguration config, SubmitInventoryUpd
Logger.LogInformation("Begin INVENTORY for K8S Orchestrator Extension for job " + config.JobId);
Logger.LogInformation($"Inventory for store type: {config.Capability}");

Logger.LogDebug($"Server: {KubeClient.GetHost()}");
Logger.LogDebug($"Store Path: {StorePath}");
Logger.LogDebug("KubeSecretType: " + KubeSecretType);
Logger.LogDebug("KubeSecretName: " + KubeSecretName);
Logger.LogDebug("KubeNamespace: " + KubeNamespace);
Logger.LogDebug("Host: " + KubeClient.GetHost());
Logger.LogDebug("Server: {Host}", KubeClient.GetHost());
Logger.LogDebug("Store Path: {StorePath}", StorePath);
Logger.LogDebug("KubeSecretType: {KubeSecretType}", KubeSecretType);
Logger.LogDebug("KubeSecretName: {KubeSecretName}", KubeSecretName);
Logger.LogDebug("KubeNamespace: {KubeNamespace}", KubeNamespace);
Logger.LogDebug("Host: {Host}", KubeClient.GetHost());

Logger.LogTrace("Inventory entering switch based on KubeSecretType: " + KubeSecretType + "...");

Expand Down
Loading

0 comments on commit 52f80f1

Please sign in to comment.