diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..fa3ed22
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,12 @@
+# See GitHub's documentation for more information on this file:
+# https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/configuration-options-for-dependency-updates
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "gomod"
+ directory: "/"
+ schedule:
+ interval: "daily"
\ No newline at end of file
diff --git a/TestConsole/TestConsole.csproj b/TestConsole/TestConsole.csproj
index 718969a..cf64fd0 100644
--- a/TestConsole/TestConsole.csproj
+++ b/TestConsole/TestConsole.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/TestConsole/tests.json b/TestConsole/tests.json
new file mode 100644
index 0000000..e69de29
diff --git a/TestConsole/tests.yml b/TestConsole/tests.yml
new file mode 100644
index 0000000..e69de29
diff --git a/dev_k8s_cluster/keyfactor_command/enrollments.tf b/dev_k8s_cluster/keyfactor_command/enrollments.tf
index fd08ccc..a5e24d2 100644
--- a/dev_k8s_cluster/keyfactor_command/enrollments.tf
+++ b/dev_k8s_cluster/keyfactor_command/enrollments.tf
@@ -1,11 +1,91 @@
+resource "keyfactor_certificate" "pfx_enrollment_00" {
+ common_name = "K8S PFX Enrollment Certificate 01"
+ country = "US"
+ state = "Ohio"
+ locality = "Cleveland"
+ organization = "Keyfactor"
+ organizational_unit = "Engineering"
+ dns_sans = ["K8S PFX Enrollment Certificate 00"]
+ // Please don't use this password in production pass in an environmental variable or something
+ certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
+ certificate_template = var.webserver_template
+ metadata = {
+ "Email-Contact" = "terraform@example.com"
+ }
+}
+
resource "keyfactor_certificate" "pfx_enrollment_01" {
+ common_name = "K8S PFX Enrollment Certificate 01"
+ country = "US"
+ state = "Ohio"
+ locality = "Cleveland"
+ organization = "Keyfactor"
+ organizational_unit = "Engineering"
+ dns_sans = ["K8S PFX Enrollment Certificate 01"]
+ // Please don't use this password in production pass in an environmental variable or something
+ certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
+ certificate_template = var.webserver_template
+ metadata = {
+ "Email-Contact" = "terraform@example.com"
+ }
+}
+
+resource "keyfactor_certificate" "pfx_enrollment_02" {
+ common_name = "K8S PFX Enrollment Certificate 02"
+ country = "US"
+ state = "Ohio"
+ locality = "Cleveland"
+ organization = "Keyfactor"
+ organizational_unit = "Engineering"
+ dns_sans = ["K8S PFX Enrollment Certificate 02"]
+ // Please don't use this password in production pass in an environmental variable or something
+ certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
+ certificate_template = var.webserver_template
+ metadata = {
+ "Email-Contact" = "terraform@example.com"
+ }
+}
+
+resource "keyfactor_certificate" "pfx_enrollment_03" {
+ common_name = "K8S PFX Enrollment Certificate 03"
+ country = "US"
+ state = "Ohio"
+ locality = "Cleveland"
+ organization = "Keyfactor"
+ organizational_unit = "Engineering"
+ dns_sans = ["K8S PFX Enrollment Certificate 03"]
+ // Please don't use this password in production pass in an environmental variable or something
+ certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
+ certificate_template = var.webserver_template
+ metadata = {
+ "Email-Contact" = "terraform@example.com"
+ }
+}
+
+resource "keyfactor_certificate" "pfx_enrollment_04" {
+ common_name = "K8S PFX Enrollment Certificate 04"
+ country = "US"
+ state = "Ohio"
+ locality = "Cleveland"
+ organization = "Keyfactor"
+ organizational_unit = "Engineering"
+ dns_sans = ["K8S PFX Enrollment Certificate 04"]
+ // Please don't use this password in production pass in an environmental variable or something
+ certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
+ certificate_template = var.webserver_template
+ metadata = {
+ "Email-Contact" = "terraform@example.com"
+ }
+}
+
+resource "keyfactor_certificate" "pfx_enrollment_05" {
common_name = "K8S PFX Enrollment Certificate"
country = "US"
state = "Ohio"
locality = "Cleveland"
organization = "Keyfactor"
organizational_unit = "Engineering"
- dns_sans = ["K8S PFX Enrollment Certificate"]
+ dns_sans = ["K8S PFX Enrollment Certificate 05"]
// Please don't use this password in production pass in an environmental variable or something
certificate_authority = "${var.default_ca_domain}\\${var.default_cert_ca}"
certificate_template = var.webserver_template
diff --git a/dev_k8s_cluster/keyfactor_command/kfc_stores.tf b/dev_k8s_cluster/keyfactor_command/kfc_stores.tf
deleted file mode 100644
index c6c808d..0000000
--- a/dev_k8s_cluster/keyfactor_command/kfc_stores.tf
+++ /dev/null
@@ -1,31 +0,0 @@
-data keyfactor_agent "k8s" {
- agent_identifier = var.client_machine_name
-}
-
-
-
-resource "keyfactor_certificate_store" "tls_store" {
- client_machine = data.keyfactor_agent.k8s.client_machine
- # Orchestrator client name
- store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}" # Varies based on store type
- agent_identifier = data.keyfactor_agent.k8s.agent_identifier
- # Orchestrator GUID or Orchestrator ClientMachine
- store_type = "K8STLSSecr" # Must exist in KeyFactor
- server_username = "kubeconfig"
- server_password = file(var.kubeconfig_file)
- server_use_ssl = true
- inventory_schedule = "5m"
- properties = {
- KubeSecretType = "tls_secret"
-# KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
-# KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
-# KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
-# SeparateChain = true # todo: invalid property
-# IncludeCertChain = true # todo: invalid property
- }
-}
-
-resource "keyfactor_certificate_deployment" "k8stlssecr" {
- certificate_id = keyfactor_certificate.pfx_enrollment_01.certificate_id
- certificate_store_id = keyfactor_certificate_store.tls_store.id
-}
\ No newline at end of file
diff --git a/dev_k8s_cluster/keyfactor_command/kfc_tlssecr_stores.tf b/dev_k8s_cluster/keyfactor_command/kfc_tlssecr_stores.tf
new file mode 100644
index 0000000..de89535
--- /dev/null
+++ b/dev_k8s_cluster/keyfactor_command/kfc_tlssecr_stores.tf
@@ -0,0 +1,137 @@
+data keyfactor_agent "k8s" {
+ agent_identifier = var.client_machine_name
+}
+
+
+
+resource "keyfactor_certificate_store" "tls_store_00" {
+ client_machine = data.keyfactor_agent.k8s.client_machine
+ # Orchestrator client name
+ store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}00" # Varies based on store type
+ agent_identifier = data.keyfactor_agent.k8s.agent_identifier
+ # Orchestrator GUID or Orchestrator ClientMachine
+ store_type = "K8STLSSecr" # Must exist in KeyFactor
+ server_username = "kubeconfig"
+ server_password = file(var.kubeconfig_file)
+ server_use_ssl = true
+ inventory_schedule = "5m"
+ properties = {
+ KubeSecretType = "tls_secret"
+# KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
+# KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
+# KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
+# SeparateChain = true # todo: invalid property
+# IncludeCertChain = true # todo: invalid property
+ }
+}
+
+resource "keyfactor_certificate_deployment" "k8stlssecr_00" {
+ certificate_id = keyfactor_certificate.pfx_enrollment_00.certificate_id
+ certificate_store_id = keyfactor_certificate_store.tls_store_00.id
+}
+
+
+
+resource "keyfactor_certificate_store" "tls_store_01" {
+ client_machine = data.keyfactor_agent.k8s.client_machine
+ # Orchestrator client name
+ store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}01" # Varies based on store type
+ agent_identifier = data.keyfactor_agent.k8s.agent_identifier
+ # Orchestrator GUID or Orchestrator ClientMachine
+ store_type = "K8STLSSecr" # Must exist in KeyFactor
+ server_username = "kubeconfig"
+ server_password = file(var.kubeconfig_file)
+ server_use_ssl = true
+ inventory_schedule = "5m"
+ properties = {
+ KubeSecretType = "tls_secret"
+ # KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
+ # KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
+ # KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
+ # SeparateChain = true # todo: invalid property
+ # IncludeCertChain = true # todo: invalid property
+ }
+}
+
+resource "keyfactor_certificate_deployment" "k8stlssecr_01" {
+ certificate_id = keyfactor_certificate.pfx_enrollment_01.certificate_id
+ certificate_store_id = keyfactor_certificate_store.tls_store_01.id
+}
+
+resource "keyfactor_certificate_store" "tls_store_02" {
+ client_machine = data.keyfactor_agent.k8s.client_machine
+ # Orchestrator client name
+ store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}02" # Varies based on store type
+ agent_identifier = data.keyfactor_agent.k8s.agent_identifier
+ # Orchestrator GUID or Orchestrator ClientMachine
+ store_type = "K8STLSSecr" # Must exist in KeyFactor
+ server_username = "kubeconfig"
+ server_password = file(var.kubeconfig_file)
+ server_use_ssl = true
+ inventory_schedule = "5m"
+ properties = {
+ KubeSecretType = "tls_secret"
+ # KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
+ # KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
+ # KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
+ # SeparateChain = true # todo: invalid property
+ # IncludeCertChain = true # todo: invalid property
+ }
+}
+
+resource "keyfactor_certificate_deployment" "k8stlssecr_02" {
+ certificate_id = keyfactor_certificate.pfx_enrollment_02.certificate_id
+ certificate_store_id = keyfactor_certificate_store.tls_store_02.id
+}
+
+resource "keyfactor_certificate_store" "tls_store_03" {
+ client_machine = data.keyfactor_agent.k8s.client_machine
+ # Orchestrator client name
+ store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}03" # Varies based on store type
+ agent_identifier = data.keyfactor_agent.k8s.agent_identifier
+ # Orchestrator GUID or Orchestrator ClientMachine
+ store_type = "K8STLSSecr" # Must exist in KeyFactor
+ server_username = "kubeconfig"
+ server_password = file(var.kubeconfig_file)
+ server_use_ssl = true
+ inventory_schedule = "5m"
+ properties = {
+ KubeSecretType = "tls_secret"
+ # KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
+ # KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
+ # KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
+ # SeparateChain = true # todo: invalid property
+ # IncludeCertChain = true # todo: invalid property
+ }
+}
+
+resource "keyfactor_certificate_deployment" "k8stlssecr_03" {
+ certificate_id = keyfactor_certificate.pfx_enrollment_03.certificate_id
+ certificate_store_id = keyfactor_certificate_store.tls_store_03.id
+}
+
+resource "keyfactor_certificate_store" "tls_store_04" {
+ client_machine = data.keyfactor_agent.k8s.client_machine
+ # Orchestrator client name
+ store_path = "${var.kube_cluster_name}/${var.kube_namespace}/${var.kube_tlssecr_name}04" # Varies based on store type
+ agent_identifier = data.keyfactor_agent.k8s.agent_identifier
+ # Orchestrator GUID or Orchestrator ClientMachine
+ store_type = "K8STLSSecr" # Must exist in KeyFactor
+ server_username = "kubeconfig"
+ server_password = file(var.kubeconfig_file)
+ server_use_ssl = true
+ inventory_schedule = "5m"
+ properties = {
+ KubeSecretType = "tls_secret"
+ # KubeNamespace = var.kube_namespace # this SHOULD take precedence over the store_path
+ # KubeSecretName = var.k8stlssecr_name # this SHOULD take precedence over the store_path
+ # KubeSvcCreds = file(var.kubeconfig_file) # todo: invalid property
+ # SeparateChain = true # todo: invalid property
+ # IncludeCertChain = true # todo: invalid property
+ }
+}
+
+resource "keyfactor_certificate_deployment" "k8stlssecr_04" {
+ certificate_id = keyfactor_certificate.pfx_enrollment_04.certificate_id
+ certificate_store_id = keyfactor_certificate_store.tls_store_04.id
+}
\ No newline at end of file
diff --git a/kubernetes-orchestrator-extension/Clients/KubeClient.cs b/kubernetes-orchestrator-extension/Clients/KubeClient.cs
index 2edda13..817ba14 100644
--- a/kubernetes-orchestrator-extension/Clients/KubeClient.cs
+++ b/kubernetes-orchestrator-extension/Clients/KubeClient.cs
@@ -16,6 +16,7 @@
using System.Text;
using k8s;
using k8s.Autorest;
+using k8s.Exceptions;
using k8s.KubeConfigModels;
using k8s.Models;
using Keyfactor.Extensions.Orchestrator.K8S.Jobs;
@@ -37,14 +38,14 @@ public class KubeCertificateManagerClient
{
private readonly ILogger _logger;
- public KubeCertificateManagerClient(string kubeconfig)
+ public KubeCertificateManagerClient(string kubeconfig, bool useSSL = true)
{
_logger = LogHandler.GetClassLogger(MethodBase.GetCurrentMethod()?.DeclaringType);
Client = GetKubeClient(kubeconfig);
ConfigJson = kubeconfig;
try
{
- ConfigObj = ParseKubeConfig(kubeconfig);
+ ConfigObj = ParseKubeConfig(kubeconfig, !useSSL); // invert useSSL to skip TLS verification
}
catch (Exception)
{
@@ -63,10 +64,12 @@ public string GetClusterName()
_logger.LogTrace("Entered GetClusterName()");
try
{
+ _logger.LogTrace("Returning cluster name from ConfigObj");
return ConfigObj.Clusters.FirstOrDefault()?.Name;
}
catch (Exception)
{
+ _logger.LogWarning("Error getting cluster name from ConfigObj attempting to return client base uri");
return GetHost();
}
}
@@ -77,33 +80,48 @@ public string GetHost()
return Client.BaseUri.ToString();
}
- private K8SConfiguration ParseKubeConfig(string kubeconfig)
+ private K8SConfiguration ParseKubeConfig(string kubeconfig, bool skipTLSVerify = false)
{
_logger.LogTrace("Entered ParseKubeConfig()");
var k8SConfiguration = new K8SConfiguration();
- // test if kubeconfig is base64 encoded
- _logger.LogDebug("Testing if kubeconfig is base64 encoded");
+
+ _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");
+ }
+
try
{
+ // test if kubeconfig is base64 encoded
+ _logger.LogDebug("Testing if kubeconfig is base64 encoded");
var decodedKubeconfig = Encoding.UTF8.GetString(Convert.FromBase64String(kubeconfig));
kubeconfig = decodedKubeconfig;
_logger.LogDebug("Successfully decoded kubeconfig from base64");
}
catch
{
- // not base64 encoded so do nothing
+ _logger.LogTrace("Kubeconfig is not base64 encoded");
}
- // check if json is escaped
+ _logger.LogTrace("Checking if kubeconfig is escaped JSON");
if (kubeconfig.StartsWith("\\"))
{
- _logger.LogDebug("Unescaping kubeconfig JSON");
+ _logger.LogDebug("Un-escaping kubeconfig JSON");
kubeconfig = kubeconfig.Replace("\\", "");
kubeconfig = kubeconfig.Replace("\\n", "\n");
+ _logger.LogDebug("Successfully un-escaped kubeconfig JSON");
}
// parse kubeconfig as a dictionary of string, string
- if (!kubeconfig.StartsWith("{")) return k8SConfiguration;
+ 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");
+ // return k8SConfiguration;
+ }
+
_logger.LogDebug("Parsing kubeconfig as a dictionary of string, string");
@@ -130,6 +148,21 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig)
_logger.LogTrace("Entering foreach loop to parse clusters...");
foreach (var clusterMetadata in JsonConvert.DeserializeObject(cl.ToString() ?? string.Empty))
{
+ _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"))
+ {
+ 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");
+ skipTLSVerify = true;
+ }
+ }
+
var clusterObj = new Cluster
{
Name = clusterMetadata["name"]?.ToString(),
@@ -137,11 +170,10 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig)
{
Server = clusterMetadata["cluster"]?["server"]?.ToString(),
CertificateAuthorityData = clusterMetadata["cluster"]?["certificate-authority-data"]?.ToString(),
- SkipTlsVerify = false
+ 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 { clusterObj };
}
@@ -188,6 +220,7 @@ private K8SConfiguration ParseKubeConfig(string kubeconfig)
_logger.LogTrace("Finished parsing contexts");
_logger.LogDebug("Finished parsing kubeconfig");
+
return k8SConfiguration;
}
@@ -207,36 +240,34 @@ 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
{
- _logger.LogDebug(
- "Config defined in store parameters takes highest precedence - calling BuildConfigFromConfigObject()");
try
{
+ _logger.LogDebug(
+ "Config defined in store parameters takes highest precedence - calling BuildConfigFromConfigObject()");
config = KubernetesClientConfiguration.BuildConfigFromConfigObject(k8SConfiguration);
_logger.LogDebug("Finished calling BuildConfigFromConfigObject()");
}
catch (Exception e)
{
- _logger.LogError("Error building config from config object: " + e.Message);
+ _logger.LogError("Error building config from config object: {Error}", e.Message);
config = KubernetesClientConfiguration.BuildDefaultConfig();
}
}
- else if
- (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 though");
+ "No config defined in store parameters, using default config. This should never happen!");
config = KubernetesClientConfiguration.BuildDefaultConfig();
_logger.LogDebug("Finished calling BuildDefaultConfig()");
}
else
{
- // Logger.LogDebug($"Attempting to load config from file {credentialFileName}");
+ _logger.LogDebug("Calling BuildConfigFromConfigFile()");
config = KubernetesClientConfiguration.BuildConfigFromConfigFile(
strWorkPath != null && !credentialFileName.Contains(strWorkPath)
? Path.Join(strWorkPath, credentialFileName)
@@ -277,15 +308,15 @@ public X509Certificate2 FindCertificateByAlias(X509Certificate2Collection certif
{
var foundCertificate = certificates
.OfType()
- .FirstOrDefault(cert => cert.SubjectName.Name.Contains(alias));
+ .FirstOrDefault(cert => cert.SubjectName.Name != null && cert.SubjectName.Name.Contains(alias));
return foundCertificate;
}
public V1Secret RemoveFromPKCS12SecretStore(K8SJobCertificate jobCertificate, string secretName,
- string namespaceName, string secretType, string certdataFieldName,
+ string namespaceName, string secretType, string certDataFieldName,
string storePasswd, V1Secret k8SSecretData,
- bool append = false, bool overwrite = true, bool passwdIsK8sSecret = false, string passwordSecretPath = "",
+ bool append = false, bool overwrite = true, bool passwdIsK8SSecret = false, string passwordSecretPath = "",
string passwordFieldName = "password",
string[] certdataFieldNames = null)
{
@@ -308,14 +339,12 @@ public V1Secret RemoveFromPKCS12SecretStore(K8SJobCertificate jobCertificate, st
{
_logger.LogTrace("existingPkcs12DataObj.Data is not null");
- // KeyValuePair updated_data = new KeyValuePair();
-
foreach (var fieldName in existingPkcs12DataObj?.Data.Keys)
{
//check if key is in certdataFieldNames
//if fieldname contains a . then split it and use the last part
var searchFieldName = fieldName;
- certdataFieldName = fieldName;
+ certDataFieldName = fieldName;
if (fieldName.Contains("."))
{
var splitFieldName = fieldName.Split(".");
@@ -400,13 +429,13 @@ public V1Secret RemoveFromPKCS12SecretStore(K8SJobCertificate jobCertificate, st
Type = "Opaque",
Data = new Dictionary
{
- { certdataFieldName, p12bytes }
+ { certDataFieldName, p12bytes }
}
};
switch (string.IsNullOrEmpty(storePasswd))
{
case false
- when string.IsNullOrEmpty(passwordSecretPath) && passwdIsK8sSecret
+ when string.IsNullOrEmpty(passwordSecretPath) && passwdIsK8SSecret
: // password is not empty and passwordSecretPath is empty
{
_logger.LogDebug("Adding password to secret...");
@@ -415,7 +444,7 @@ when string.IsNullOrEmpty(passwordSecretPath) && passwdIsK8sSecret
break;
}
case false
- when !string.IsNullOrEmpty(passwordSecretPath) && passwdIsK8sSecret
+ when !string.IsNullOrEmpty(passwordSecretPath) && passwdIsK8SSecret
: // password is not empty and passwordSecretPath is not empty
{
_logger.LogDebug("Adding password secret path to secret...");
@@ -1745,6 +1774,7 @@ public List DiscoverSecrets(string[] allowedKeys, string secType, string
_logger.LogTrace("Entered DiscoverSecrets()");
V1NamespaceList namespaces;
var clusterName = GetClusterName() ?? GetHost();
+ _logger.LogTrace("clusterName: {ClusterName}", clusterName);
var nsList = new string[] { };
@@ -1759,22 +1789,25 @@ public List DiscoverSecrets(string[] allowedKeys, string secType, string
}
- _logger.LogDebug("Attempting to list k8s namespaces from " + clusterName);
+ _logger.LogDebug("Attempting to list k8s namespaces from {ClusterName}", clusterName);
+ _logger.LogDebug("Calling CoreV1.ListNamespace()");
namespaces = Client.CoreV1.ListNamespace();
- _logger.LogTrace("namespaces.Items.Count: " + namespaces.Items.Count);
- _logger.LogTrace("namespaces.Items: " + namespaces.Items);
+ _logger.LogDebug("returned from CoreV1.ListNamespace()");
+ _logger.LogTrace("namespaces.Items.Count: {Count}", namespaces.Items.Count);
+ _logger.LogTrace("namespaces.Items: {Items}", namespaces.Items.ToString());
- nsList = ns.Contains(",") ? ns.Split(",") : new[] { ns };
- foreach (var nsLI in nsList)
+ nsList = ns.Contains(',') ? ns.Split(",") : new[] { ns };
+ foreach (var nsLi in nsList)
{
+ _logger.LogTrace("Iterating through namespace list {NamespaceList}", nsLi);
var secretsList = new List();
- _logger.LogTrace("Entering foreach loop to list all secrets in each returned namespace.");
+ _logger.LogTrace("Entering foreach loop to list all secrets in each returned namespace");
foreach (var nsObj in namespaces.Items)
{
- if (nsLI != "all" && nsLI != nsObj.Metadata.Name)
+ if (nsLi != "all" && nsLi != nsObj.Metadata.Name)
{
- _logger.LogWarning("Skipping namespace " + nsObj.Metadata.Name +
- " because it does not match the namespace filter.");
+ _logger.LogWarning(
+ "Skipping namespace '{Namespace}' because it does not match the namespace filter", nsObj.Metadata.Name);
continue;
}
diff --git a/kubernetes-orchestrator-extension/Jobs/Discovery.cs b/kubernetes-orchestrator-extension/Jobs/Discovery.cs
index 14bc38c..5867be5 100644
--- a/kubernetes-orchestrator-extension/Jobs/Discovery.cs
+++ b/kubernetes-orchestrator-extension/Jobs/Discovery.cs
@@ -11,6 +11,7 @@
using Keyfactor.Extensions.Orchestrator.K8S.Clients;
using Keyfactor.Orchestrators.Common.Enums;
using Keyfactor.Orchestrators.Extensions;
+using Keyfactor.Logging;
using Keyfactor.Orchestrators.Extensions.Interfaces;
using Microsoft.Extensions.Logging;
@@ -39,29 +40,48 @@ public JobResult ProcessJob(DiscoveryJobConfiguration config, SubmitDiscoveryUpd
//NLog Logging to c:\CMS\Logs\CMS_Agent_Log.txt
- InitializeStore(config);
- Logger.LogInformation("Begin Discovery for K8S Orchestrator Extension for job " + config.JobId);
- Logger.LogInformation($"Discovery for store type: {config.Capability}");
+ Logger = LogHandler.GetClassLogger(GetType());
+ Logger.LogInformation("Begin Discovery for K8S Orchestrator Extension for job {JobID}", config.JobId);
+ Logger.LogInformation("Discovery for store type: {Capability}", config.Capability);
+ try
+ {
+ Logger.LogDebug("Calling InitializeStore()");
+ InitializeStore(config);
+ Logger.LogDebug("Store initialized successfully");
+ } catch (Exception ex)
+ {
+ Logger.LogError("Failed to initialize store: {Error}", ex.Message);
+ return FailJob("Failed to initialize store: " + ex.Message, config.JobHistoryId);
+ }
+
+
var locations = new List();
KubeSvcCreds = ServerPassword;
- KubeClient = new KubeCertificateManagerClient(KubeSvcCreds);
+ Logger.LogDebug("Calling KubeCertificateManagerClient()");
+ KubeClient = new KubeCertificateManagerClient(KubeSvcCreds, config.UseSSL);
+ if (KubeClient == null)
+ {
+ Logger.LogError("Failed to create KubeCertificateManagerClient");
+ return FailJob("Failed to create KubeCertificateManagerClient", config.JobHistoryId);
+ }
- var namespaces = config.JobProperties["dirs"].ToString()?.Split(',');
+ var namespaces = config.JobProperties["dirs"].ToString()?.Split(',') ?? Array.Empty();
if (namespaces is { Length: 0 })
{
+ Logger.LogDebug("No namespaces provided, using `default` namespace");
namespaces = new[] { "default" };
}
- Logger.LogDebug("Namespaces: " + string.Join(",", namespaces));
+ Logger.LogDebug("Namespaces: {Namespaces}", string.Join(",", namespaces));
- var ignoreNamespace = config.JobProperties["ignoreddirs"].ToString()?.Split(',');
- Logger.LogDebug("Ignored Namespaces: " + string.Join(",", ignoreNamespace));
+ var ignoreNamespace = config.JobProperties["ignoreddirs"].ToString()?.Split(',') ?? Array.Empty();
+ Logger.LogDebug("Ignored Namespaces: {Namespaces}", string.Join(",", ignoreNamespace));
- var secretAllowedKeys = config.JobProperties["patterns"].ToString()?.Split(',');
- Logger.LogDebug("Secret Allowed Keys: " + string.Join(",", secretAllowedKeys));
+ var secretAllowedKeys = config.JobProperties["patterns"].ToString()?.Split(',') ?? Array.Empty();
+ Logger.LogDebug("Secret Allowed Keys: {AllowedKeys}",string.Join(",", secretAllowedKeys));
- Logger.LogTrace("Discovery entering switch block based on capability: " + config.Capability);
+ Logger.LogTrace("Discovery entering switch block based on capability {Capability}", config.Capability);
try
{
//Code logic to:
diff --git a/kubernetes-orchestrator-extension/Jobs/JobBase.cs b/kubernetes-orchestrator-extension/Jobs/JobBase.cs
index e02bf40..1da7a35 100644
--- a/kubernetes-orchestrator-extension/Jobs/JobBase.cs
+++ b/kubernetes-orchestrator-extension/Jobs/JobBase.cs
@@ -24,9 +24,11 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.IO.Pem;
using Org.BouncyCastle.X509;
using PemWriter = Org.BouncyCastle.OpenSsl.PemWriter;
+using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
namespace Keyfactor.Extensions.Orchestrator.K8S.Jobs;
@@ -90,7 +92,8 @@ public class K8SJobCertificate
public bool HasPrivateKey { get; set; } = false;
public bool HasPassword { get; set; } = false;
-
+
+
public X509CertificateEntry CertificateEntry { get; set; }
public X509CertificateEntry[] CertificateEntryChain { get; set; }
@@ -104,28 +107,31 @@ public class K8SJobCertificate
public abstract class JobBase
{
- static protected readonly string[] SupportedKubeStoreTypes;
+ protected static readonly string[] SupportedKubeStoreTypes;
- static protected readonly string[] RequiredProperties;
+ protected static readonly string[] RequiredProperties;
- static protected readonly string[] TLSAllowedKeys;
- static protected readonly string[] OpaqueAllowedKeys;
- static protected readonly string[] CertAllowedKeys;
- static protected readonly string[] Pkcs12AllowedKeys;
- static protected readonly string[] JksAllowedKeys;
- static protected readonly string DefaultPFXSecretFieldName = "pfx";
- static protected readonly string DefaultJKSSecretFieldName = "jks";
- static protected readonly string DefaultPFXPasswordSecretFieldName = "password";
+ protected static readonly string[] TLSAllowedKeys;
+ protected static readonly string[] OpaqueAllowedKeys;
+ protected static readonly string[] CertAllowedKeys;
+ protected static readonly string[] Pkcs12AllowedKeys;
+ protected static readonly string[] JksAllowedKeys;
+ protected static readonly string DefaultPFXSecretFieldName = "pfx";
+ protected static readonly string DefaultJKSSecretFieldName = "jks";
+ protected static readonly string DefaultPFXPasswordSecretFieldName = "password";
- internal protected bool SeparateChain { get; set; } = false; //Don't arbitrarily change this to true without specifying BREAKING CHANGE in the release notes.
- internal protected bool IncludeCertChain { get; set; } = true; //Don't arbitrarily change this to false without specifying BREAKING CHANGE in the release notes.
+ protected internal bool SeparateChain { get; set; } = false; //Don't arbitrarily change this to true without specifying BREAKING CHANGE in the release notes.
+ protected internal bool IncludeCertChain { get; set; } = true; //Don't arbitrarily change this to false without specifying BREAKING CHANGE in the release notes.
- internal protected string OperationType { get; set; }
+ protected internal string OperationType { get; set; }
+ protected internal bool SkipTlsValidation { get; set; } = false;
- static protected string CertChainSeparator = ",";
- internal protected KubeCertificateManagerClient KubeClient;
+ protected static string CertChainSeparator = ",";
+
+
+ protected internal KubeCertificateManagerClient KubeClient;
- internal protected ILogger Logger;
+ protected internal ILogger Logger;
static JobBase()
{
CertAllowedKeys = new[] { "cert", "csr" };
@@ -188,7 +194,7 @@ protected void InitializeStore(InventoryJobConfiguration config)
InventoryConfig = config;
Capability = config.Capability;
Logger = LogHandler.GetClassLogger(GetType());
- Logger.LogTrace("Entered InitializeStore() for INVENTORY.");
+ Logger.LogTrace("Entered InitializeStore() for INVENTORY");
var props = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties);
//var props = Jsonconfig.CertificateStoreDetails.Properties;
ServerUsername = config?.ServerUsername;
@@ -208,13 +214,24 @@ protected void InitializeStore(DiscoveryJobConfiguration config)
{
DiscoveryConfig = config;
Logger = LogHandler.GetClassLogger(GetType());
- Logger.LogTrace("Entered InitializeStore() for DISCOVERY.");
+ Logger.LogTrace("Entered InitializeStore() for DISCOVERY");
var props = config.JobProperties;
Capability = config?.Capability;
ServerUsername = config?.ServerUsername;
ServerPassword = config?.ServerPassword;
+ // check that config has UseSSL bool set
+ if (config.UseSSL)
+ {
+ Logger.LogInformation("UseSSL is set to true, setting SkipTlsValidation to false");
+ SkipTlsValidation = false;
+ }
+ else
+ {
+ Logger.LogInformation("UseSSL is set to false, setting SkipTlsValidation to true");
+ SkipTlsValidation = true;
+ }
- Logger.LogTrace($"ServerUsername: {ServerUsername}");
+ Logger.LogTrace("ServerUsername: {ServerUsername}", ServerUsername);
Logger.LogTrace("Calling InitializeProperties()");
InitializeProperties(props);
@@ -224,7 +241,7 @@ protected void InitializeStore(ManagementJobConfiguration config)
{
ManagementConfig = config;
Logger = LogHandler.GetClassLogger(GetType());
- Logger.LogTrace("Entered InitializeStore() for MANAGEMENT.");
+ Logger.LogTrace("Entered InitializeStore() for MANAGEMENT");
var props = JsonConvert.DeserializeObject(config.CertificateStoreDetails.Properties);
Capability = config?.Capability;
ServerUsername = config?.ServerUsername;
@@ -390,48 +407,48 @@ public bool isNamespaceStore(string capability)
public string resolveStorePath(string spath)
{
Logger.LogTrace("Entered resolveStorePath()");
- Logger.LogTrace("Passed Store Path: " + spath);
+ Logger.LogTrace("Passed Store Path: {Path}", spath);
- Logger.LogTrace("Attempting to split storepath by '/'");
+ Logger.LogTrace("Attempting to split store path by '/'");
var sPathParts = spath.Split("/");
- Logger.LogTrace("Split count: " + sPathParts.Length);
+ Logger.LogTrace("Split count: {Count}", sPathParts.Length);
var isNsStore = isNamespaceStore(Capability);
switch (sPathParts.Length)
{
case 1 when Capability.Contains("NS"):
- Logger.LogInformation("Store path is 1 part and capability is namespace. Assuming that storepath is namespace and setting KubeSecretName equal empty.");
- Logger.LogWarning($"Store is of type namespace. Setting KubeSecretName equal empty and namespace to storepath.");
+ Logger.LogInformation("Store path is 1 part and capability is namespace, assuming that store path is namespace and setting 'KubeSecretName' equal empty");
+ Logger.LogWarning("Store is of type namespace. Setting KubeSecretName equal empty and namespace to store path");
KubeSecretName = "";
KubeNamespace = sPathParts[0];
break;
case 1 when Capability.Contains("Cluster"):
Logger.LogTrace(
- "Store path is 1 part and capability is cluster. Assuming that storepath is the cluster name and setting KubeSecretName and KubeNamespace equal empty.");
- Logger.LogWarning($"Store is of type cluster. Setting KubeSecretName and KubeNamespace equal empty.");
+ "Store path is 1 part and capability is cluster, assuming that store path is the cluster name and setting 'KubeSecretName' and 'KubeNamespace' equal empty");
+ Logger.LogWarning("Store is of type cluster, setting 'KubeSecretName' and 'KubeNamespace' equal empty");
KubeSecretName = "";
KubeNamespace = "";
break;
case 1:
- Logger.LogTrace("Store path is 1 part assuming that it is the secret name");
+ Logger.LogTrace("Store path is 1 part assuming that it is the 'KubeSecretName'");
if (string.IsNullOrEmpty(KubeSecretName))
{
- Logger.LogTrace("No KubeSecretName set. Setting KubeSecretName to store path.");
+ Logger.LogTrace("No 'KubeSecretName' set, setting 'KubeSecretName' to store path");
KubeSecretName = sPathParts[0];
}
break;
case 2 when Capability.Contains("Cluster"):
- Logger.LogError("Store path is 2 parts and capability is cluster. This is not a valid combination.");
+ Logger.LogError("Store path is 2 parts and capability is cluster, this is not a valid combination");
break;
case 2 when Capability.Contains("NS"):
var nsPrefix = sPathParts[0];
var nsName = sPathParts[1];
Logger.LogTrace(
- "Store path is 2 parts and capability is namespace. Assuming that storepath pattern is either cluster/namespacename or namespace/namespacename");
- Logger.LogDebug("Discarding namespace prefix and setting namespace to storepath");
+ "Store path is 2 parts and capability is namespace, assuming that store path pattern is either 'cluster/namespacename' or 'namespace/namespacename'");
+ Logger.LogDebug("Discarding namespace prefix and setting namespace to store path");
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogTrace("No KubeNamespace set. Setting KubeNamespace to store path.");
+ Logger.LogTrace("No 'KubeNamespace' set, setting 'KubeNamespace' to store path");
KubeNamespace = nsName;
}
break;
@@ -441,33 +458,33 @@ public string resolveStorePath(string spath)
var kSn = sPathParts[1];
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogTrace("No KubeNamespace set. Setting KubeNamespace to store path.");
+ Logger.LogTrace("No 'KubeNamespace' set, setting 'KubeNamespace' to store path");
KubeNamespace = kNs;
}
if (string.IsNullOrEmpty(KubeSecretName))
{
- Logger.LogTrace("No KubeSecretName set. Setting KubeSecretName to store path.");
+ Logger.LogTrace("No 'KubeSecretName' set, setting 'KubeSecretName' to store path");
KubeSecretName = kSn;
}
break;
case 3 when Capability.Contains("Cluster"):
- Logger.LogError("Store path is 2 parts and capability is cluster. This is not a valid combination.");
+ Logger.LogError("Store path is 2 parts and capability is cluster, this is not a valid combination");
break;
case 3 when Capability.Contains("NS"):
- Logger.LogTrace("Store path is 3 parts assuming that storepath pattern is the cluster/namespace/namespacename");
+ Logger.LogTrace("Store path is 3 parts assuming that store path pattern is the 'cluster/namespace/namespacename'");
var nsCluster = sPathParts[0];
var nsClarifier = sPathParts[1];
var nsName3 = sPathParts[2];
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogTrace("No KubeNamespace set. Setting KubeNamespace to store path.");
+ Logger.LogTrace("No 'KubeNamespace' set, setting 'KubeNamespace' to store path");
KubeNamespace = nsName3;
}
KubeSecretName = "";
break;
case 3:
- Logger.LogTrace("Store path is 3 parts assuming that it is the cluster/namespace/secret name");
+ Logger.LogTrace("Store path is 3 parts assuming that it is the 'cluster/namespace/secret' name");
var kH = sPathParts[0];
var kN = sPathParts[1];
var kS = sPathParts[2];
@@ -479,17 +496,17 @@ public string resolveStorePath(string spath)
}
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogTrace("No KubeNamespace set. Setting KubeNamespace to store path.");
+ Logger.LogTrace("No 'KubeNamespace' set, setting 'KubeNamespace' to store path");
KubeNamespace = kN;
}
if (string.IsNullOrEmpty(KubeSecretName))
{
- Logger.LogTrace("No KubeSecretName set. Setting KubeSecretName to store path.");
+ Logger.LogTrace("No 'KubeSecretName' set, setting 'KubeSecretName' to store path");
KubeSecretName = kS;
}
break;
case 4 when Capability.Contains("Cluster") || Capability.Contains("NS"):
- Logger.LogError($"Store path is 4 parts and capability is {Capability}. This is not a valid combination.");
+ Logger.LogError("Store path is 4 parts and capability is {Capability}. This is not a valid combination", Capability);
break;
case 4:
Logger.LogTrace("Store path is 4 parts assuming that it is the cluster/namespace/secret type/secret name");
@@ -499,17 +516,17 @@ public string resolveStorePath(string spath)
var kSN = sPathParts[3];
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogTrace("No KubeNamespace set. Setting KubeNamespace to store path.");
+ Logger.LogTrace("No 'KubeNamespace' set, setting 'KubeNamespace' to store path");
KubeNamespace = kNN;
}
if (string.IsNullOrEmpty(KubeSecretName))
{
- Logger.LogTrace("No KubeSecretName set. Setting KubeSecretName to store path.");
+ Logger.LogTrace("No 'KubeSecretName' set, setting 'KubeSecretName' to store path");
KubeSecretName = kSN;
}
break;
default:
- Logger.LogWarning("Unable to resolve store path. Please check the store path and try again.");
+ Logger.LogWarning("Unable to resolve store path, please check the store path and try again");
break;
}
return GetStorePath();
@@ -520,13 +537,12 @@ private void InitializeProperties(dynamic storeProperties)
Logger.LogTrace("Entered InitializeProperties()");
if (storeProperties == null)
throw new ConfigurationException(
- $"Invalid configuration. Please provide {RequiredProperties}. Or review the documentation at https://github.com/Keyfactor/kubernetes-orchestrator#custom-fields-tab.");
+ $"Invalid configuration. Please provide {RequiredProperties}. Or review the documentation at https://github.com/Keyfactor/kubernetes-orchestrator#custom-fields-tab");
// check if key is present and set values if not
-
try
{
- Logger.LogDebug("Setting K8S values from store properties.");
+ Logger.LogDebug("Setting K8S values from store properties");
KubeNamespace = storeProperties["KubeNamespace"];
KubeSecretName = storeProperties["KubeSecretName"];
KubeSecretType = storeProperties["KubeSecretType"];
@@ -539,7 +555,7 @@ private void InitializeProperties(dynamic storeProperties)
}
else
{
- Logger.LogDebug("PasswordIsSeparateSecret not found in store properties.");
+ Logger.LogDebug("PasswordIsSeparateSecret not found in store properties");
PasswordIsSeparateSecret = false;
}
@@ -550,7 +566,7 @@ private void InitializeProperties(dynamic storeProperties)
}
else
{
- Logger.LogDebug("PasswordFieldName not found in store properties.");
+ Logger.LogDebug("PasswordFieldName not found in store properties");
PasswordFieldName = "";
}
@@ -561,7 +577,7 @@ private void InitializeProperties(dynamic storeProperties)
}
else
{
- Logger.LogDebug("StorePasswordPath not found in store properties.");
+ Logger.LogDebug("StorePasswordPath not found in store properties");
StorePasswordPath = "";
}
@@ -572,66 +588,63 @@ private void InitializeProperties(dynamic storeProperties)
}
else
{
- Logger.LogDebug("KubeSecretKey not found in store properties.");
+ Logger.LogDebug("KubeSecretKey not found in store properties");
CertificateDataFieldName = "";
}
}
catch (Exception)
{
- Logger.LogError("Unknown error while parsing store properties.");
- Logger.LogWarning("Setting KubeSecretType and KubeSvcCreds to empty strings.");
+ Logger.LogError("Unknown error while parsing store properties");
+ Logger.LogWarning("Setting KubeSecretType and KubeSvcCreds to empty strings");
KubeSecretType = "";
KubeSvcCreds = "";
}
//check if storeProperties contains ServerUsername key
-
-
- Logger.LogInformation("Attempting to resolve ServerUsername from store properties or PAM provider.");
+ Logger.LogInformation("Attempting to resolve 'ServerUsername' from store properties or PAM provider");
var pamServerUsername = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "ServerUsername", ServerUsername);
if (!string.IsNullOrEmpty(pamServerUsername))
{
- Logger.LogInformation("ServerUsername resolved from PAM provider. Setting ServerUsername to resolved value.");
- Logger.LogTrace("PAMServerUsername: " + pamServerUsername);
+ Logger.LogInformation("ServerUsername resolved from PAM provider, setting 'ServerUsername' to resolved value");
+ Logger.LogTrace("PAMServerUsername: {Username}", pamServerUsername);
ServerUsername = pamServerUsername;
}
else
{
- Logger.LogInformation("ServerUsername not resolved from PAM provider. Attempting to resolve Server Username from store properties.");
+ Logger.LogInformation("ServerUsername not resolved from PAM provider, attempting to resolve 'Server Username' from store properties");
pamServerUsername = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "Server Username", ServerUsername);
if (!string.IsNullOrEmpty(pamServerUsername))
{
- Logger.LogInformation("ServerUsername resolved from store properties. Setting ServerUsername to resolved value.");
- Logger.LogTrace("PAMServerUsername: " + pamServerUsername);
+ Logger.LogInformation("ServerUsername resolved from store properties. Setting ServerUsername to resolved value");
+ Logger.LogTrace("PAMServerUsername: {Username}", pamServerUsername);
ServerUsername = pamServerUsername;
}
}
if (string.IsNullOrEmpty(ServerUsername))
{
- Logger.LogInformation("ServerUsername is empty. Setting ServerUsername to default value.");
+ Logger.LogInformation("ServerUsername is empty, setting 'ServerUsername' to default value: 'kubeconfig'");
ServerUsername = "kubeconfig";
}
// Check if ServerPassword is empty and resolve from store properties or PAM provider
-
try
{
- Logger.LogInformation("Attempting to resolve ServerPassword from store properties or PAM provider.");
+ Logger.LogInformation("Attempting to resolve 'ServerPassword' from store properties or PAM provider");
var pamServerPassword = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "ServerPassword", ServerPassword);
if (!string.IsNullOrEmpty(pamServerPassword))
{
- Logger.LogInformation("ServerPassword resolved from PAM provider. Setting ServerPassword to resolved value.");
+ Logger.LogInformation("ServerPassword resolved from PAM provider, setting 'ServerPassword' to resolved value");
// Logger.LogTrace("PAMServerPassword: " + pamServerPassword);
ServerPassword = pamServerPassword;
}
else
{
- Logger.LogInformation("ServerPassword not resolved from PAM provider. Attempting to resolve Server Password from store properties.");
+ Logger.LogInformation("ServerPassword not resolved from PAM provider, attempting to resolve 'Server Password' from store properties");
pamServerPassword = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "Server Password", ServerPassword);
if (!string.IsNullOrEmpty(pamServerPassword))
{
- Logger.LogInformation("ServerPassword resolved from store properties. Setting ServerPassword to resolved value.");
+ Logger.LogInformation("ServerPassword resolved from store properties, setting 'ServerPassword' to resolved value");
// Logger.LogTrace("PAMServerPassword: " + pamServerPassword);
ServerPassword = pamServerPassword;
}
@@ -639,42 +652,42 @@ private void InitializeProperties(dynamic storeProperties)
}
catch (Exception e)
{
- Logger.LogError("Unable to resolve ServerPassword from store properties or PAM provider, defaulting to empty string.");
+ Logger.LogError("Unable to resolve 'ServerPassword' from store properties or PAM provider, defaulting to empty string");
ServerPassword = "";
- Logger.LogError(e.Message);
- Logger.LogTrace(e.ToString());
- Logger.LogTrace(e.StackTrace);
- // throw new ConfigurationException("Invalid configuration. ServerPassword not provided or is invalid.");
+ Logger.LogError("{Message}", e.Message);
+ Logger.LogTrace("{Message}",e.ToString());
+ Logger.LogTrace("{Trace}", e.StackTrace);
+ // throw new ConfigurationException("Invalid configuration. ServerPassword not provided or is invalid");
}
- // } else {
- // Logger.LogError("Unable to resolve ServerPassword from store properties or PAM provider, defaulting to empty string.");
- // throw new ConfigurationException("Invalid configuration. ServerPassword not provided or is invalid.");
- // }
try
{
+ Logger.LogInformation("Attempting to resolve 'StorePassword' from store properties or PAM provider");
var pamStorePassword = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "StorePassword", StorePassword);
if (!string.IsNullOrEmpty(pamStorePassword))
{
+ Logger.LogInformation("StorePassword resolved from PAM provider, setting 'StorePassword' to resolved value");
StorePassword = pamStorePassword;
}
else
{
+ Logger.LogInformation("StorePassword not resolved from PAM provider, attempting to resolve 'Store Password' from store properties");
pamStorePassword = (string)PAMUtilities.ResolvePAMField(_resolver, Logger, "Store Password", StorePassword);
if (!string.IsNullOrEmpty(pamStorePassword))
{
+ Logger.LogInformation("StorePassword resolved from store properties, setting 'StorePassword' to resolved value");
StorePassword = pamStorePassword;
}
}
}
catch (Exception e)
{
- Logger.LogError("Unable to resolve StorePassword from store properties or PAM provider, defaulting to empty string.");
+ Logger.LogError("Unable to resolve 'StorePassword' from store properties or PAM provider, defaulting to empty string");
StorePassword = "";
- Logger.LogError(e.Message);
- Logger.LogTrace(e.ToString());
- Logger.LogTrace(e.StackTrace);
- // throw new ConfigurationException("Invalid configuration. StorePassword not provided or is invalid.");
+ Logger.LogError("{Message}", e.Message);
+ Logger.LogTrace("{Message}",e.ToString());
+ Logger.LogTrace("{Trace}", e.StackTrace);
+ // throw new ConfigurationException("Invalid configuration. StorePassword not provided or is invalid");
}
if (ServerUsername == "kubeconfig" || string.IsNullOrEmpty(ServerUsername))
@@ -689,6 +702,7 @@ private void InitializeProperties(dynamic storeProperties)
case "pfx":
case "p12":
case "pkcs12":
+ Logger.LogInformation("Kubernetes certificate store type is 'pfx'. Setting default values for 'PasswordFieldName' and 'CertificateDataFieldName'");
PasswordFieldName = storeProperties.ContainsKey("PasswordFieldName") ? storeProperties["PasswordFieldName"] : DefaultPFXPasswordSecretFieldName;
PasswordIsSeparateSecret = storeProperties.ContainsKey("PasswordIsSeparateSecret") ? storeProperties["PasswordIsSeparateSecret"] : false;
StorePasswordPath = storeProperties.ContainsKey("StorePasswordPath") ? storeProperties["StorePasswordPath"] : "";
@@ -697,6 +711,7 @@ private void InitializeProperties(dynamic storeProperties)
CertificateDataFieldName = storeProperties.ContainsKey("CertificateDataFieldName") ? storeProperties["CertificateDataFieldName"] : DefaultPFXSecretFieldName;
break;
case "jks":
+ Logger.LogInformation("Kubernetes certificate store type is 'jks'. Setting default values for 'PasswordFieldName' and 'CertificateDataFieldName'");
PasswordFieldName = storeProperties.ContainsKey("PasswordFieldName") ? storeProperties["PasswordFieldName"] : DefaultPFXPasswordSecretFieldName;
PasswordIsSeparateSecret = storeProperties.ContainsKey("PasswordIsSeparateSecret") ? bool.Parse(storeProperties["PasswordIsSeparateSecret"]) : false;
StorePasswordPath = storeProperties.ContainsKey("StorePasswordPath") ? storeProperties["StorePasswordPath"] : "";
@@ -706,38 +721,44 @@ private void InitializeProperties(dynamic storeProperties)
break;
}
- KubeClient = new KubeCertificateManagerClient(KubeSvcCreds);
-
- KubeHost = KubeClient.GetHost();
- KubeCluster = KubeClient.GetClusterName();
+ Logger.LogTrace("Creating new KubeCertificateManagerClient object");
+ // KubeClient = new KubeCertificateManagerClient(KubeSvcCreds);
+ //
+ // Logger.LogTrace("Getting KubeHost and KubeCluster from KubeClient");
+ // KubeHost = KubeClient.GetHost();
+ // Logger.LogTrace("KubeHost: {KubeHost}", KubeHost);
+ //
+ // Logger.LogTrace("Getting cluster name from KubeClient");
+ // KubeCluster = KubeClient.GetClusterName();
+ // Logger.LogTrace("KubeCluster: {KubeCluster}", KubeCluster);
if (string.IsNullOrEmpty(KubeSecretName) && !string.IsNullOrEmpty(StorePath) && !Capability.Contains("NS") && !Capability.Contains("Cluster"))
{
- Logger.LogDebug("KubeSecretName is empty. Attempting to set KubeSecretName from StorePath.");
+ Logger.LogDebug("KubeSecretName is empty, attempting to set 'KubeSecretName' from StorePath");
resolveStorePath(StorePath);
}
if (string.IsNullOrEmpty(KubeNamespace) && !string.IsNullOrEmpty(StorePath))
{
- Logger.LogDebug("KubeNamespace is empty. Attempting to set KubeNamespace from StorePath.");
+ Logger.LogDebug("KubeNamespace is empty, attempting to set 'KubeNamespace' from StorePath");
resolveStorePath(StorePath);
}
if (string.IsNullOrEmpty(KubeNamespace))
{
- Logger.LogDebug("KubeNamespace is empty. Setting KubeNamespace to 'default'.");
+ Logger.LogDebug("KubeNamespace is empty, setting 'KubeNamespace' to 'default'");
KubeNamespace = "default";
}
- Logger.LogDebug($"KubeNamespace: {KubeNamespace}");
- Logger.LogDebug($"KubeSecretName: {KubeSecretName}");
- Logger.LogDebug($"KubeSecretType: {KubeSecretType}");
+ Logger.LogDebug("KubeNamespace: {KubeNamespace}", KubeNamespace);
+ Logger.LogDebug("KubeSecretName: {KubeSecretName}", KubeSecretName);
+ Logger.LogDebug("KubeSecretType: {KubeSecretType}", KubeSecretName);
if (!string.IsNullOrEmpty(KubeSecretName)) return;
// KubeSecretName = StorePath.Split("/").Last();
- Logger.LogWarning("KubeSecretName is empty. Setting KubeSecretName to StorePath.");
+ Logger.LogWarning("KubeSecretName is empty, setting 'KubeSecretName' to StorePath");
KubeSecretName = StorePath;
- Logger.LogTrace("KubeSecretName: " + KubeSecretName);
+ Logger.LogTrace("KubeSecretName: {KubeSecretName}", KubeSecretName);
}
@@ -767,45 +788,51 @@ public string GetStorePath()
secretType = KubeSecretType.ToLower();
}
- Logger.LogTrace("secretType: " + secretType);
- Logger.LogTrace("Entered switch statement based on secretType.");
+ Logger.LogTrace("secretType: {SecretType}", secretType);
+ Logger.LogTrace("Entered switch statement based on secretType");
switch (secretType)
{
case "secret":
case "opaque":
case "tls":
case "tls_secret":
- Logger.LogDebug("Kubernetes secret resource type. Setting secretType to 'secret'.");
+ Logger.LogDebug("Kubernetes secret resource type, setting secretType to 'secret'");
secretType = "secret";
break;
case "cert":
case "certs":
case "certificate":
case "certificates":
- Logger.LogDebug("Kubernetes certificate resource type. Setting secretType to 'certificate'.");
+ Logger.LogDebug("Kubernetes certificate resource type, setting secretType to 'certificate'");
secretType = "certificate";
break;
case "namespace":
- storePath = $"{KubeClient.GetClusterName()}/namespace/{KubeNamespace}";
+ Logger.LogDebug("Kubernetes namespace resource type, setting secretType to 'namespace'");
KubeSecretType = "namespace";
+
+ Logger.LogDebug("Setting store path to 'cluster/namespace/namespacename' for 'namespace' secret type");
+ storePath = $"{KubeClient.GetClusterName()}/namespace/{KubeNamespace}";
+ Logger.LogDebug("Returning storePath: {StorePath}", storePath);
return storePath;
case "cluster":
+ Logger.LogDebug("Kubernetes cluster resource type, setting secretType to 'cluster'");
KubeSecretType = "cluster";
+ Logger.LogDebug("Returning storePath: {StorePath}", storePath);
return storePath;
default:
- Logger.LogWarning("Unknown secret type. Will use value provided.");
- Logger.LogTrace($"secretType: {secretType}");
+ Logger.LogWarning("Unknown secret type '{SecretType}' will use value provided", secretType);
+ Logger.LogTrace("secretType: {SecretType}", secretType);
break;
}
- Logger.LogTrace("Building StorePath.");
+ Logger.LogDebug("Building StorePath");
storePath = $"{KubeClient.GetClusterName()}/{KubeNamespace}/{secretType}/{KubeSecretName}";
- Logger.LogDebug("Returning StorePath: " + storePath);
+ Logger.LogDebug("Returning storePath: {StorePath}", storePath);
return storePath;
}
catch (Exception e)
{
- Logger.LogError("Unknown error constructing canonical store path.");
+ Logger.LogError("Unknown error constructing canonical store path {Error}", e.Message);
return StorePath;
}
@@ -813,10 +840,10 @@ public string GetStorePath()
protected byte[] GetKeyBytes(X509Certificate2 certObj, string certPassword = null)
{
- Logger.LogTrace("Entered GetKeyBytes()");
- Logger.LogTrace("Key algo: " + certObj.GetKeyAlgorithm());
- Logger.LogTrace("Has private key: " + certObj.HasPrivateKey);
- Logger.LogTrace("Pub key: " + certObj.GetPublicKey());
+ Logger.LogDebug("Entered GetKeyBytes()");
+ Logger.LogTrace("Key algo: {KeyAlgo}", certObj.GetKeyAlgorithm());
+ Logger.LogTrace("Has private key: {HasPrivateKey}",certObj.HasPrivateKey);
+ Logger.LogTrace("Pub key: {PublicKey}", certObj.GetPublicKey());
byte[] keyBytes;
@@ -843,7 +870,7 @@ protected byte[] GetKeyBytes(X509Certificate2 certObj, string certPassword = nul
Logger.LogTrace("GetDSAPrivateKey().ExportPkcs8PrivateKey(): completed");
break;
default:
- Logger.LogWarning("Unknown key algorithm. Attempting to export as PKCS12.");
+ Logger.LogWarning("Unknown key algorithm, attempting to export as PKCS12");
Logger.LogTrace("Export(X509ContentType.Pkcs12, certPassword)");
keyBytes = certObj.Export(X509ContentType.Pkcs12, certPassword);
Logger.LogTrace("Export(X509ContentType.Pkcs12, certPassword) complete");
@@ -851,24 +878,23 @@ protected byte[] GetKeyBytes(X509Certificate2 certObj, string certPassword = nul
}
if (keyBytes != null) return keyBytes;
- Logger.LogError("Key bytes are null. This is unexpected.");
- throw new Exception("Key bytes are null. This is unexpected.");
-
- return keyBytes;
+ Logger.LogError("Unable to parse private key");
+
+ throw new InvalidKeyException($"Unable to parse private key from certificate '{certObj.Thumbprint}'");
}
catch (Exception e)
{
- Logger.LogError("Unknown error getting key bytes, but we're going to try a different method.");
- Logger.LogError(e.Message);
- Logger.LogTrace(e.ToString());
- Logger.LogTrace(e.StackTrace);
+ Logger.LogError("Unknown error getting key bytes, but we're going to try a different method");
+ Logger.LogError("{Message}", e.Message);
+ Logger.LogTrace("{Message}",e.ToString());
+ Logger.LogTrace("{Trace}", e.StackTrace);
try
{
if (certObj.HasPrivateKey)
{
try
{
- Logger.LogDebug("Attempting to export private key as PKCS8.");
+ Logger.LogDebug("Attempting to export private key as PKCS8");
Logger.LogTrace("ExportPkcs8PrivateKey()");
keyBytes = certObj.PrivateKey.ExportPkcs8PrivateKey();
Logger.LogTrace("ExportPkcs8PrivateKey() complete");
@@ -878,12 +904,12 @@ protected byte[] GetKeyBytes(X509Certificate2 certObj, string certPassword = nul
}
catch (Exception e2)
{
- Logger.LogError("Unknown error exporting private key as PKCS8, but we're going to try a a final method .");
+ Logger.LogError("Unknown error exporting private key as PKCS8, but we're going to try a a final method ");
Logger.LogError(e2.Message);
Logger.LogTrace(e2.ToString());
Logger.LogTrace(e2.StackTrace);
//attempt to export encrypted pkcs8
- Logger.LogDebug("Attempting to export encrypted PKCS8 private key.");
+ Logger.LogDebug("Attempting to export encrypted PKCS8 private key");
Logger.LogTrace("ExportEncryptedPkcs8PrivateKey()");
keyBytes = certObj.PrivateKey.ExportEncryptedPkcs8PrivateKey(certPassword,
new PbeParameters(
@@ -898,16 +924,16 @@ protected byte[] GetKeyBytes(X509Certificate2 certObj, string certPassword = nul
}
catch (Exception ie)
{
- Logger.LogError("Unknown error exporting private key as PKCS8, returning null.");
- Logger.LogError(ie.Message);
- Logger.LogTrace(ie.ToString());
- Logger.LogTrace(ie.StackTrace);
+ Logger.LogError("Unknown error exporting private key as PKCS8, returning null");
+ Logger.LogError("{Message}", ie.Message);
+ Logger.LogTrace("{Message}",ie.ToString());
+ Logger.LogTrace("{Trace}", ie.StackTrace);
}
- return new byte[] { };
+ return Array.Empty();
}
}
- static protected JobResult FailJob(string message, long jobHistoryId)
+ protected static JobResult FailJob(string message, long jobHistoryId)
{
return new JobResult
{
@@ -917,7 +943,7 @@ static protected JobResult FailJob(string message, long jobHistoryId)
};
}
- static protected JobResult SuccessJob(long jobHistoryId, string jobMessage = null)
+ protected static JobResult SuccessJob(long jobHistoryId, string jobMessage = null)
{
var result = new JobResult
{
@@ -940,72 +966,71 @@ protected string ParseJobPrivateKey(ManagementJobConfiguration config)
if (string.IsNullOrWhiteSpace(config.JobCertificate.Alias)) Logger.LogTrace("No Alias Found");
// Load PFX
- Logger.LogTrace("Loading PFX...");
+ Logger.LogTrace("Loading PFX from job contents");
var pfxBytes = Convert.FromBase64String(config.JobCertificate.Contents);
- Logger.LogTrace("Loaded PFX...");
- Pkcs12Store p;
- string alias = config.JobCertificate.Alias;
+ Logger.LogTrace("PFX loaded successfully");
+
+ var alias = config.JobCertificate.Alias;
+ Logger.LogTrace("Alias: {Alias}", alias);
- Logger.LogTrace("Creating Pkcs12Store...");
+ Logger.LogTrace("Creating Pkcs12Store object");
// Load the PKCS12 bytes into a Pkcs12Store object
- using (MemoryStream pkcs12Stream = new MemoryStream(pfxBytes))
- {
- Pkcs12Store store = new Pkcs12StoreBuilder().Build();
+ using var pkcs12Stream = new MemoryStream(pfxBytes);
+ var store = new Pkcs12StoreBuilder().Build();
- store.Load(pkcs12Stream, config.JobCertificate.PrivateKeyPassword.ToCharArray());
+ Logger.LogDebug("Attempting to load PFX into store using password");
+ store.Load(pkcs12Stream, config.JobCertificate.PrivateKeyPassword.ToCharArray());
- // Find the private key entry with the given alias
- foreach (string aliasName in store.Aliases)
- {
- if (aliasName.Equals(alias) && store.IsKeyEntry(aliasName))
- {
- AsymmetricKeyEntry keyEntry = store.GetKey(aliasName);
+ // Find the private key entry with the given alias
+ Logger.LogDebug("Attempting to get private key entry with alias");
+ foreach (var aliasName in store.Aliases)
+ {
+ Logger.LogTrace("Alias: {Alias}", aliasName);
+ if (!aliasName.Equals(alias) || !store.IsKeyEntry(aliasName)) continue;
+ Logger.LogDebug("Alias found, attempting to get private key");
+ var keyEntry = store.GetKey(aliasName);
- // Convert the private key to unencrypted PEM format
- using (StringWriter stringWriter = new StringWriter())
- {
- PemWriter pemWriter = new PemWriter(stringWriter);
- pemWriter.WriteObject(keyEntry.Key);
- pemWriter.Writer.Flush();
+ // Convert the private key to unencrypted PEM format
+ using var stringWriter = new StringWriter();
+ var pemWriter = new PemWriter(stringWriter);
+ pemWriter.WriteObject(keyEntry.Key);
+ pemWriter.Writer.Flush();
- return stringWriter.ToString();
- }
- }
- }
+ Logger.LogDebug("Private key found for alias {Alias}, returning private key", alias);
+ return stringWriter.ToString();
}
+ Logger.LogDebug("Alias '{Alias}' not found, returning null private key", alias);
return null; // Private key with the given alias not found
-
-
}
protected string getK8SStorePassword(V1Secret certData)
{
Logger.LogDebug("Entered getK8SStorePassword()");
- Logger.LogDebug("Attempting to get store password from K8S secret.");
- var storePasswordBytes = new byte[] { };
+ Logger.LogDebug("Attempting to get store password from K8S secret");
+ var storePasswordBytes = Array.Empty();
// if secret is a buddy pass
if (!string.IsNullOrEmpty(StorePassword))
{
- Logger.LogDebug("StorePassword is not null or empty, using StorePassword");
- var passwordHash = GetSHA256Hash(StorePassword);
- Logger.LogTrace("Password hash: " + passwordHash);
+ Logger.LogDebug("Using provided 'StorePassword'");
+ // var passwordHash = GetSHA256Hash(StorePassword);
+ // Logger.LogTrace("Password hash: " + passwordHash);
storePasswordBytes = Encoding.UTF8.GetBytes(StorePassword);
}
else if (!string.IsNullOrEmpty(StorePasswordPath))
{
// Split password path into namespace and secret name
- Logger.LogDebug("Store password is null or empty, using StorePasswordPath");
+ Logger.LogDebug("Store password is null or empty and StorePasswordPath is set, attempting to read password from K8S buddy secret");
Logger.LogTrace("Password path: {Path}", StorePasswordPath);
- Logger.LogDebug("Splitting password path by /");
+ Logger.LogTrace("Splitting password path by /");
var passwordPath = StorePasswordPath.Split("/");
Logger.LogDebug("Password path length: {Len}", passwordPath.Length.ToString());
var passwordNamespace = "";
var passwordSecretName = "";
if (passwordPath.Length == 1)
{
- Logger.LogDebug("Password path length is 1, using KubeNamespace.");
+ Logger.LogDebug("Password path length is 1, using KubeNamespace");
passwordNamespace = KubeNamespace;
Logger.LogTrace("Password namespace: {Namespace}", passwordNamespace);
passwordSecretName = passwordPath[0];
@@ -1026,17 +1051,27 @@ protected string getK8SStorePassword(V1Secret certData)
Logger.LogDebug("Attempting to read K8S buddy secret");
var k8sPasswordObj = KubeClient.ReadBuddyPass(passwordSecretName, passwordNamespace);
storePasswordBytes = k8sPasswordObj.Data[PasswordFieldName];
- var passwordHash = GetSHA256Hash(Encoding.UTF8.GetString(storePasswordBytes));
- Logger.LogTrace("Password hash: {Pwd}", passwordHash);
+ // var passwordHash = GetSHA256Hash(Encoding.UTF8.GetString(storePasswordBytes));
+ // Logger.LogTrace("Password hash: {Pwd}", passwordHash);
+ if (storePasswordBytes == null)
+ {
+ Logger.LogError("Password not found in K8S buddy secret");
+ throw new InvalidK8SSecretException("Password not found in K8S buddy secret"); // todo: should this be thrown?
+ }
Logger.LogDebug("K8S buddy secret read successfully");
}
else if (certData != null && certData.Data.TryGetValue(PasswordFieldName, out var value1))
{
Logger.LogDebug("Attempting to read password from PasswordFieldName");
storePasswordBytes = value1;
- var passwordHash = GetSHA256Hash(Encoding.UTF8.GetString(storePasswordBytes));
- Logger.LogTrace("Password hash: {Pwd}", passwordHash);
- Logger.LogDebug("Password read successfully.");
+ // var passwordHash = GetSHA256Hash(Encoding.UTF8.GetString(storePasswordBytes));
+ // Logger.LogTrace("Password hash: {Pwd}", passwordHash);
+ if (storePasswordBytes == null)
+ {
+ Logger.LogError("Password not found in K8S secret");
+ throw new InvalidK8SSecretException("Password not found in K8S secret"); // todo: should this be thrown?
+ }
+ Logger.LogDebug("Password read successfully");
}
else
{
@@ -1044,12 +1079,12 @@ protected string getK8SStorePassword(V1Secret certData)
var passwdEx = "";
if (!string.IsNullOrEmpty(StorePasswordPath))
{
- passwdEx = "Store secret '" + StorePasswordPath + "'did not contain key '" + CertificateDataFieldName + "' or '" + PasswordFieldName + "'." +
- " Please provide a valid store password and try again.";
+ passwdEx = "Store secret '" + StorePasswordPath + "'did not contain key '" + CertificateDataFieldName + "' or '" + PasswordFieldName + "'" +
+ " Please provide a valid store password and try again";
}
else
{
- passwdEx = "Invalid store password. Please provide a valid store password and try again.";
+ passwdEx = "Invalid store password. Please provide a valid store password and try again";
}
Logger.LogError("{Msg}", passwdEx);
throw new Exception(passwdEx);
@@ -1058,63 +1093,88 @@ protected string getK8SStorePassword(V1Secret certData)
//convert password to string
var storePassword = Encoding.UTF8.GetString(storePasswordBytes);
// Logger.LogTrace("Store password: {Pwd}", storePassword);
- var passwordHash2 = GetSHA256Hash(storePassword);
- Logger.LogTrace("Password hash: {Pwd}", passwordHash2);
+ // var passwordHash2 = GetSHA256Hash(storePassword);
+ // Logger.LogTrace("Password hash: {Pwd}", passwordHash2);
+ Logger.LogDebug("Returning store password");
return storePassword;
}
protected Pkcs12Store LoadPkcs12Store(byte[] pkcs12Data, string password)
{
+ Logger.LogDebug("Entered LoadPkcs12Store()");
var storeBuilder = new Pkcs12StoreBuilder();
var store = storeBuilder.Build();
+ Logger.LogDebug("Attempting to load PKCS12 store");
using var pkcs12Stream = new MemoryStream(pkcs12Data);
if (password != null) store.Load(pkcs12Stream, password.ToCharArray());
+ Logger.LogDebug("PKCS12 store loaded successfully");
return store;
}
- protected string getCertificatePem(Pkcs12Store store, string password, string alias = "")
+ protected string GetCertificatePem(Pkcs12Store store, string password, string alias = "")
{
+ Logger.LogDebug("Entered GetCertificatePem()");
if (string.IsNullOrEmpty(alias))
{
alias = store.Aliases.Cast().FirstOrDefault(store.IsKeyEntry);
}
+
+ Logger.LogDebug("Attempting to get certificate with alias {Alias}", alias);
var cert = store.GetCertificate(alias).Certificate;
using var stringWriter = new StringWriter();
var pemWriter = new PemWriter(stringWriter);
+
+ Logger.LogDebug("Attempting to write certificate to PEM format");
pemWriter.WriteObject(cert);
pemWriter.Writer.Flush();
+ Logger.LogTrace("certificate:\n{Cert}", stringWriter.ToString());
+
+ Logger.LogDebug("Returning certificate in PEM format");
return stringWriter.ToString();
}
protected string getPrivateKeyPem(Pkcs12Store store, string password, string alias = "")
{
+ Logger.LogDebug("Entered getPrivateKeyPem()");
if (string.IsNullOrEmpty(alias))
{
- alias = store.Aliases.Cast().FirstOrDefault(store.IsKeyEntry);
+ Logger.LogDebug("Alias is empty, attempting to get key entry alias");
+ alias = store.Aliases.FirstOrDefault(store.IsKeyEntry);
}
+
+ Logger.LogDebug("Attempting to get private key with alias {Alias}", alias);
var privateKey = store.GetKey(alias).Key;
using var stringWriter = new StringWriter();
var pemWriter = new PemWriter(stringWriter);
+
+ Logger.LogDebug("Attempting to write private key to PEM format");
pemWriter.WriteObject(privateKey);
pemWriter.Writer.Flush();
+ // Logger.LogTrace("private key:\n{Key}", stringWriter.ToString());
+ Logger.LogDebug("Returning private key in PEM format for alias '{Alias}'", alias);
return stringWriter.ToString();
}
protected List getCertChain(Pkcs12Store store, string password, string alias = "")
{
+ Logger.LogDebug("Entered getCertChain()");
if (string.IsNullOrEmpty(alias))
{
+ Logger.LogDebug("Alias is empty, attempting to get key entry alias");
alias = store.Aliases.Cast().FirstOrDefault(store.IsKeyEntry);
}
+
var chain = new List();
+ Logger.LogDebug("Attempting to get certificate chain with alias {Alias}", alias);
var chainCerts = store.GetCertificateChain(alias);
foreach (var chainCert in chainCerts)
{
+ Logger.LogTrace("Adding certificate to chain");
using var stringWriter = new StringWriter();
var pemWriter = new PemWriter(stringWriter);
pemWriter.WriteObject(chainCert.Certificate);
@@ -1122,6 +1182,8 @@ protected List getCertChain(Pkcs12Store store, string password, string a
chain.Add(stringWriter.ToString());
}
+ Logger.LogTrace("Certificate chain:\n{Chain}", string.Join("\n", chain));
+ Logger.LogDebug("Returning certificate chain");
return chain;
}
@@ -1141,16 +1203,14 @@ public static bool IsDerFormat(byte[] data)
public static string ConvertDerToPem(byte[] data)
{
var pemObject = new PemObject("CERTIFICATE", data);
- using (var stringWriter = new StringWriter())
- {
- var pemWriter = new PemWriter(stringWriter);
- pemWriter.WriteObject(pemObject);
- pemWriter.Writer.Flush();
- return stringWriter.ToString();
- }
+ using var stringWriter = new StringWriter();
+ var pemWriter = new PemWriter(stringWriter);
+ pemWriter.WriteObject(pemObject);
+ pemWriter.Writer.Flush();
+ return stringWriter.ToString();
}
- public string GetSHA256Hash(string input)
+ protected static string GetSHA256Hash(string input)
{
var passwordHashBytes = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(input));
var passwordHash = BitConverter.ToString(passwordHashBytes).Replace("-", "").ToLower();
diff --git a/kubernetes-orchestrator-extension/Keyfactor.Orchestrators.K8S.csproj b/kubernetes-orchestrator-extension/Keyfactor.Orchestrators.K8S.csproj
index 5f3befe..ce85ab7 100644
--- a/kubernetes-orchestrator-extension/Keyfactor.Orchestrators.K8S.csproj
+++ b/kubernetes-orchestrator-extension/Keyfactor.Orchestrators.K8S.csproj
@@ -21,10 +21,10 @@
-
-
+
+
-
+