Sample Store Type
SAMPLETYPE
Inventory
Entry Parameters are a new feature introduced in Keyfactor 9 that allow additional information to be associated with individual certificate entries.
For more information on creating and customizing store types, refer to the Keyfactor Platform documentation.
Now let's create the project and solution for our extension in Visual Studio.
There are a a couple Keyfactor NuGet packages that we will use for this example.
Keyfactor.Logging
Keyfactor.Orchestrators.IOrchestratorJobExtensions
These are available on the Keyfactor public NuGet package repository.
You will also need to install NLog
and NLog.Extensions.Logging
which are available on the public NuGet server.
These were the latest versions at the time of writing this. It's not necessary to match the exact version of the package above
Now that we have our new project created and have added the necessary NuGet packages, let's create Job classes that will run when the platform requests them for the new store type we created. For each job that our new store type should support, we will need to create a corresponding Job
class instance that encapsulates the functionality. Each job that the orchestrator should support for this store type will need an implementation of the Interface for that job type. The interfaces are defined in the Keyfactor.Orchestrators.Extensions.
namespace.
IInventoryJobExtension
IManagementJobExtension
IReenrollmentJobExtension
Let's start by implementing an Inventory job.
Now that we have our empty solution, let's create an Inventory job definition and add some logging.
Jobs
.Inventory
, and name it Inventory.cs
.Inventory.cs
with the following:using System.Collections.Generic;
using Keyfactor.Logging;
using Keyfactor.Orchestrators.Common.Enums;
using Keyfactor.Orchestrators.Extensions;
using Microsoft.Extensions.Logging;
namespace UniversalOrchestratorExtensionSample.Jobs
{
public class Inventory : IInventoryJobExtension
{
// The below property is not necessary for the Universal Orchestrator
// and will be removed from the interface in a future release.
public string ExtensionName => string.Empty; // <--
private readonly ILogger _logger = LogHandler.GetClassLogger<Inventory>();
public JobResult ProcessJob(InventoryJobConfiguration jobConfiguration, SubmitInventoryUpdate submitInventoryUpdate)
{
_logger.MethodEntry();
_logger.LogInformation($"Calling Invoke with 0 items.");
bool invokeResult = submitInventoryUpdate.Invoke(new List<CurrentInventoryItem>());
_logger.MethodExit();
return new JobResult
{
JobHistoryId = jobConfiguration.JobHistoryId,
Result = invokeResult == true ? OrchestratorJobStatusJobResult.Success : OrchestratorJobStatusJobResult.Failure
};
}
}
}
IInventoryJobExtension
interface.ProcessJob
method. Generally, these need to be implemented with job handling logic for each job type the extension should support.ProcessJob
from the Orchestrator to our extension is the InventoryJobConfiguration
object, which can contain details such as folder path, remote access keys and passwords that may be needed by the operation.SubmitInventoryUpdate
callback that is provided as a parameter to ProcessJob
from the Orchestrator; and should pass the results of the inventory check to the callback.The inventory job will typically contain the logic for gathering information about certificates in a store. In the above example we are simply logging the request.
The SubmitInventoryUpdate
callback returns true
if the Orchestrator was successful in transmitting the result to the Keyfactor platform. If it returns false
, the Orchestrator had a problem submitting the results. In that case, the Orchestrator logs should contain more details of the error.
The JobResult
response should reflect success or failure of the operation, but it is also possible to return a Warning status. These statuses appear next to the job run details in the Keyfactor Portal.
In order to register the extension with the orchestrator, we need to create a manifest file that describes our copiled libraries.
manifest.json
.UniversalOrchestratorExtensionSample
, and a single inventory job, manifest.json
should include the following content:{
"extensions": {
"Keyfactor.Orchestrators.Extensions.IOrchestratorJobExtension": {
"CertStores.SampleStore.Inventory": {
"assemblypath": "UniversalOrchestratorExtensionSample.dll",
"TypeFullName": "UniversalOrchestratorExtensionSample.Jobs.Inventory"
}
}
}
}
Considerations:
Inventory
job is required.config
, pre-script
and post-script
properties that allow other parameters to be set and consumed when the job runs, and describe scripts that should run before and after your custom code.<namespace>.<class name>
of the job.Set the properties of manifest.json
to either "Always Copy" or "Copy if Newer" to make sure it's included in our build output.
Build the solution with either Debug or Release configuration and navigate to the corresponding output folder. The contents should look something like this:
The next step is to register the extension with the orchestrator. This is simply done by adding the appropriate files to the extensions folder. The manifest file we created above tells the Orchestrator what jobs are available in our extension.
Note: The universal orchestrator service is named Keyfactor Orchestrator Service (default) by default
Navigate to the extensions directory under the Universal Orchestrator working directory. By default this is C:\Program Files\Keyfactor\Keyfactor Orchestrator\extensions
.
Create a folder that corresponds to the extension. The folder name does not need to match to the extension name.
Copy the entire contents of the build output above into this folder.
Start the Orchestrator service.
Once approved we can go through the process of adding a new certificate store and kick off the inventory request.
To do this, navigate to Locations/Certificate Stores:
Click the "Add" button to add a new Cert Store as shown below and you will be presented with the dialog displayed in Step 5.
Fill in the following values (shown above)
After all the fields are filled out click the "Save" button.
Let's confirm that our new extension is getting executed when we run the Inventory job.
Search for "Orchestrator.exe" and select "Attach".
Add a breakpoint at the first line of processJob
in Inventory.cs
.
Go to the Keyfactor Platform and navigate to Locations > Certificate Stores, select the one we created, and click Schedule Inventory.
Select Interval and then every 2 or 3 minutes.
If successful, the breakpoint should be hit once the job is kicked off.
jobConfiguration
parameter. Let's confirm that our logging is working properly by reviewing the Orchestrator logs.
By default, they are located at C:\Program Files\Keyfactor\Keyfactor Orchestrator\logs
.
Navigate to the logs folder
Open the Log.txt
file and confirm that we can see our log entries.
The log files can also be very useful when debugging. The valid trace levels are Trace, Warn, Info and Error; with Trace providing the most detailed information.. The level can be set for the Universal Orchestrator in the following location:
C:\Program Files\Keyfactor\Keyfactor Orchestrator\configuration\nlog.config
Congratulations! You have sucessfully built and configured an extension for the Keyfactor Universal Orchestrator.
We hope that you have gained a deeper understanding of the process.
We are always updating this documentation so check back soon for more samples and examples.
The source code for the sample can be found here.