Skip to content

Commit

Permalink
fix(base): Add back client initialization to job base
Browse files Browse the repository at this point in the history
chore: Refactor discovery, create base discovery class and each store type gets inherits and modifies as needed.
  • Loading branch information
spbsoluble committed Jun 6, 2024
1 parent 7555726 commit f2eede3
Show file tree
Hide file tree
Showing 11 changed files with 827 additions and 279 deletions.
524 changes: 262 additions & 262 deletions kubernetes-orchestrator-extension/Jobs/Discovery.cs

Large diffs are not rendered by default.

67 changes: 67 additions & 0 deletions kubernetes-orchestrator-extension/Jobs/DiscoveryBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using k8s.Exceptions;
using Keyfactor.Extensions.Orchestrator.K8S.Clients;
using Keyfactor.Orchestrators.Extensions;
using Keyfactor.Logging;
using Microsoft.Extensions.Logging;

namespace Keyfactor.Extensions.Orchestrator.K8S.Jobs;

// The Discovery class implements IAgentJobExtension and is meant to find all certificate stores based on the information passed when creating the job in KF Command
public abstract class DiscoveryBase : JobBase
{
protected List<string> DiscoveredLocations = new();
protected string[] SearchNamespaces = Array.Empty<string>();
protected string[] IgnoredNamespaces = Array.Empty<string>();
protected string[] SecretAllowedKeys = Array.Empty<string>();
protected string SecretType;

protected void Init(DiscoveryJobConfiguration config)
{
//NLog Logging to c:\CMS\Logs\CMS_Agent_Log.txt
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);
Logger.LogTrace("{StackTrace}", ex.ToString());
// return FailJob("Failed to initialize store: " + ex.Message, config.JobHistoryId);
throw new Exception("Failed to initialize store: " + ex.Message);
}

KubeSvcCreds = ServerPassword;
Logger.LogDebug("Calling KubeCertificateManagerClient()");
KubeClient = new KubeCertificateManagerClient(KubeSvcCreds, config.UseSSL); //todo does this throw an exception?
Logger.LogDebug("Returned from KubeCertificateManagerClient()");
if (KubeClient == null)
{
Logger.LogError("Failed to create KubeCertificateManagerClient");
throw new KubeConfigException("Failed to create KubeCertificateManagerClient");
}

SearchNamespaces = config.JobProperties["dirs"].ToString()?.Split(',') ?? Array.Empty<string>();
if (SearchNamespaces is null or { Length: 0 })
{
Logger.LogDebug("No namespaces provided, using `default` namespace");
SearchNamespaces = new[] { "default" };
}

Logger.LogDebug("Namespaces: {Namespaces}", string.Join(",", SearchNamespaces));

IgnoredNamespaces = config.JobProperties["ignoreddirs"].ToString()?.Split(',') ?? Array.Empty<string>();
Logger.LogDebug("Ignored Namespaces: {Namespaces}", string.Join(",", IgnoredNamespaces));

SecretAllowedKeys = config.JobProperties["patterns"].ToString()?.Split(',') ?? Array.Empty<string>();
Logger.LogDebug("Secret Allowed Keys: {AllowedKeys}", string.Join(",", SecretAllowedKeys));

Logger.LogDebug("Returning from DiscoveryBase Init()");
}
}
20 changes: 11 additions & 9 deletions kubernetes-orchestrator-extension/Jobs/JobBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.IO.Pem;
using Org.BouncyCastle.X509;
using ECCurve = Org.BouncyCastle.Math.EC.ECCurve;
using PemWriter = Org.BouncyCastle.OpenSsl.PemWriter;

namespace Keyfactor.Extensions.Orchestrator.K8S.Jobs;
Expand Down Expand Up @@ -259,6 +260,7 @@ protected void InitializeStore(ManagementJobConfiguration config)
ServerUsername = config.ServerUsername;
ServerPassword = config.ServerPassword;
StorePath = config.CertificateStoreDetails?.StorePath;


Logger.LogTrace("ServerUsername: {ServerUsername}", ServerUsername);
Logger.LogTrace("StorePath: {StorePath}", StorePath);
Expand Down Expand Up @@ -877,15 +879,15 @@ private void InitializeProperties(dynamic storeProperties)
}

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);
KubeClient = new KubeCertificateManagerClient(KubeSvcCreds, true); // todo source this from config or pass in

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"))
Expand Down
98 changes: 98 additions & 0 deletions kubernetes-orchestrator-extension/StoreTypes/K8SCert/Discovery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright 2024 Keyfactor
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

using System;
using System.Linq;
using Keyfactor.Extensions.Orchestrator.K8S.Jobs;
using Keyfactor.Orchestrators.Common.Enums;
using Keyfactor.Orchestrators.Extensions;
using Keyfactor.Orchestrators.Extensions.Interfaces;
using Microsoft.Extensions.Logging;

namespace Keyfactor.Extensions.Orchestrator.K8S.StoreTypes.K8SCert;

// The Discovery class implements IAgentJobExtension and is meant to find all certificate stores based on the information passed when creating the job in KF Command
public class Discovery : DiscoveryBase, IDiscoveryJobExtension
{

public Discovery(IPAMSecretResolver resolver)
{
_resolver = resolver;
}

//Job Entry Point
public JobResult ProcessJob(DiscoveryJobConfiguration config, SubmitDiscoveryUpdate submitDiscovery)
{
//METHOD ARGUMENTS...
//config - contains context information passed from KF Command to this job run:
//
// config.ServerUsername, config.ServerPassword - credentials for orchestrated server - use to authenticate to certificate store server.
// config.ClientMachine - server name or IP address of orchestrated server
//
// config.JobProperties["dirs"] - Directories to search
// config.JobProperties["extensions"] - Extensions to search
// config.JobProperties["ignoreddirs"] - Directories to ignore
// config.JobProperties["patterns"] - File name patterns to match

try
{
Init(config: config);
Logger.LogDebug("Enter ProcessJob()");
SecretType = "cert";
Logger.LogTrace("SecretType: {SecretType}", SecretType);
Logger.LogTrace("Job capability: {Capability}", config.Capability);

// // Run discovery
// SecretAllowedKeys = SecretAllowedKeys.Concat(TLSAllowedKeys).ToArray();
// Logger.LogInformation(
// "Discovering k8s secrets for cluster `{ClusterName}` with allowed keys: `{AllowedKeys}` and secret types: `kubernetes.io/tls, Opaque`",
// KubeHost, string.Join(",", SecretAllowedKeys));
// Logger.LogDebug("Calling KubeClient.DiscoverSecrets()");
// DiscoveredLocations = KubeClient.DiscoverSecrets(SecretAllowedKeys, SecretType, string.Join(",", SearchNamespaces));
// Logger.LogDebug("Returned from KubeClient.DiscoverSecrets()");
//
// //Sends store locations back to KF command where they can be approved or rejected
// Logger.LogInformation("Submitting discovered locations to Keyfactor Command...");
// Logger.LogTrace("Discovery locations: {Locations}", string.Join(",", DiscoveredLocations));
// Logger.LogDebug("Calling submitDiscovery.Invoke()");
// submitDiscovery.Invoke(DiscoveredLocations.Distinct().ToArray());
// Logger.LogDebug("Returned from submitDiscovery.Invoke()");
// Logger.LogDebug("Returning successful JobResult");
// Logger.LogInformation("Discovery completed successfully for {JobId}", config.JobId);
// //Status: 2=Success, 3=Warning, 4=Error
// return new JobResult
// {
// Result = OrchestratorJobStatusJobResult.Success,
// JobHistoryId = config.JobHistoryId,
// FailureMessage =
// "Discovered the following locations: " +
// string.Join(",\n", DiscoveredLocations), // This is what gets written to the Command UI job log.
// };
Logger.LogError("Capability not supported: CertStores.K8SCert.Discovery");
return FailJob("Discovery not supported for store type `K8SCert`", config.JobHistoryId);
}
catch (Exception ex)
{
//Status: 2=Success, 3=Warning, 4=Error
Logger.LogError("Discovery job has failed due to an unknown error");
Logger.LogError("{Message}", ex.Message);
Logger.LogTrace("{Message}", ex.ToString());
// iterate through the inner exceptions
var inner = ex.InnerException;
while (inner != null)
{
Logger.LogError("Inner Exception: {Message}", inner.Message);
Logger.LogTrace("{Message}", inner.ToString());
inner = inner.InnerException;
}

Logger.LogInformation("End DISCOVERY for K8S Orchestrator Extension for job '{JobID}' with failure",
config.JobId);
return FailJob(ex.Message, config.JobHistoryId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2024 Keyfactor
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
// and limitations under the License.

using System;
using System.Linq;
using Keyfactor.Extensions.Orchestrator.K8S.Jobs;
using Keyfactor.Orchestrators.Common.Enums;
using Keyfactor.Orchestrators.Extensions;
using Keyfactor.Orchestrators.Extensions.Interfaces;
using Microsoft.Extensions.Logging;

namespace Keyfactor.Extensions.Orchestrator.K8S.StoreTypes.K8SCluster;

// The Discovery class implements IAgentJobExtension and is meant to find all certificate stores based on the information passed when creating the job in KF Command
public class Discovery : DiscoveryBase, IDiscoveryJobExtension
{

public Discovery(IPAMSecretResolver resolver)
{
_resolver = resolver;
}

//Job Entry Point
public JobResult ProcessJob(DiscoveryJobConfiguration config, SubmitDiscoveryUpdate submitDiscovery)
{
//METHOD ARGUMENTS...
//config - contains context information passed from KF Command to this job run:
//
// config.ServerUsername, config.ServerPassword - credentials for orchestrated server - use to authenticate to certificate store server.
// config.ClientMachine - server name or IP address of orchestrated server
//
// config.JobProperties["dirs"] - Directories to search
// config.JobProperties["extensions"] - Extensions to search
// config.JobProperties["ignoreddirs"] - Directories to ignore
// config.JobProperties["patterns"] - File name patterns to match

try
{
Init(config: config);
Logger.LogDebug("Enter ProcessJob()");
SecretType = "cluster";
Logger.LogTrace("SecretType: {SecretType}", SecretType);
Logger.LogTrace("Job capability: {Capability}", config.Capability);

// Run discovery
SecretAllowedKeys = SecretAllowedKeys.Concat(TLSAllowedKeys).ToArray();
Logger.LogInformation(
"Discovering k8s secrets for cluster `{ClusterName}` with allowed keys: `{AllowedKeys}` and secret types: `kubernetes.io/tls, Opaque`",
KubeHost, string.Join(",", SecretAllowedKeys));
Logger.LogDebug("Calling KubeClient.DiscoverSecrets()");
DiscoveredLocations = KubeClient.DiscoverSecrets(SecretAllowedKeys, SecretType, string.Join(",", SearchNamespaces));
Logger.LogDebug("Returned from KubeClient.DiscoverSecrets()");

//Sends store locations back to KF command where they can be approved or rejected
Logger.LogInformation("Submitting discovered locations to Keyfactor Command...");
Logger.LogTrace("Discovery locations: {Locations}", string.Join(",", DiscoveredLocations));
Logger.LogDebug("Calling submitDiscovery.Invoke()");
submitDiscovery.Invoke(DiscoveredLocations.Distinct().ToArray());
Logger.LogDebug("Returned from submitDiscovery.Invoke()");
Logger.LogDebug("Returning successful JobResult");
Logger.LogInformation("Discovery completed successfully for {JobId}", config.JobId);
//Status: 2=Success, 3=Warning, 4=Error
return new JobResult
{
Result = OrchestratorJobStatusJobResult.Success,
JobHistoryId = config.JobHistoryId,
FailureMessage =
"Discovered the following locations: " +
string.Join(",\n", DiscoveredLocations), // This is what gets written to the Command UI job log.
};
}
catch (Exception ex)
{
//Status: 2=Success, 3=Warning, 4=Error
Logger.LogError("Discovery job has failed due to an unknown error");
Logger.LogError("{Message}", ex.Message);
Logger.LogTrace("{Message}", ex.ToString());
// iterate through the inner exceptions
var inner = ex.InnerException;
while (inner != null)
{
Logger.LogError("Inner Exception: {Message}", inner.Message);
Logger.LogTrace("{Message}", inner.ToString());
inner = inner.InnerException;
}

Logger.LogInformation("End DISCOVERY for K8S Orchestrator Extension for job '{JobID}' with failure",
config.JobId);
return FailJob(ex.Message, config.JobHistoryId);
}
}
}
Loading

0 comments on commit f2eede3

Please sign in to comment.