Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 36 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ Application and System certs are used by NSX ALB for SSL offloading and require
This integration is compatible with Keyfactor Universal Orchestrator version 10.1 and later.

## Support
The VMware NSX Advanced Load Balancer (Avi) Universal Orchestrator extension If you have a support issue, please open a support ticket by either contacting your Keyfactor representative or via the Keyfactor Support Portal at https://support.keyfactor.com.
The VMware NSX Advanced Load Balancer (Avi) Universal Orchestrator extension is supported by Keyfactor. If you require support for any issues or have feature request, please open a support ticket by either contacting your Keyfactor representative or via the Keyfactor Support Portal at https://support.keyfactor.com.

> To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.
> If you want to contribute bug fixes or additional enhancements, use the **[Pull requests](../../pulls)** tab.

## Requirements & Prerequisites

Expand Down Expand Up @@ -173,21 +173,51 @@ the Keyfactor Command Portal

![VMware-NSX Custom Fields Tab](docsource/images/VMware-NSX-custom-fields-store-type-dialog.png)


###### Server Username
The username of the user to log on as in VMware NSX ALB.


> [!IMPORTANT]
> This field is created by the `Needs Server` on the Basic tab, do not create this field manually.




###### Server Password
The password of the user to log on as in VMware NSX ALB.


> [!IMPORTANT]
> This field is created by the `Needs Server` on the Basic tab, do not create this field manually.




###### X-Avi-Version
The API Version of Avi / NSX to target. A default is set for the version this was originally developed and tested against.

![VMware-NSX Custom Field - ApiVersion](docsource/images/VMware-NSX-custom-field-ApiVersion-dialog.png)
![VMware-NSX Custom Field - ApiVersion](docsource/images/VMware-NSX-custom-field-ApiVersion-validation-options-dialog.png)





</details>

## Installation

1. **Download the latest VMware NSX Advanced Load Balancer (Avi) Universal Orchestrator extension from GitHub.**

Navigate to the [VMware NSX Advanced Load Balancer (Avi) Universal Orchestrator extension GitHub version page](https://github.com/Keyfactor/vmware-nsx-orchestrator/releases/latest). Refer to the compatibility matrix below to determine whether the `net6.0` or `net8.0` asset should be downloaded. Then, click the corresponding asset to download the zip archive.
Navigate to the [VMware NSX Advanced Load Balancer (Avi) Universal Orchestrator extension GitHub version page](https://github.com/Keyfactor/vmware-nsx-orchestrator/releases/latest). Refer to the compatibility matrix below to determine the asset should be downloaded. Then, click the corresponding asset to download the zip archive.

| Universal Orchestrator Version | Latest .NET version installed on the Universal Orchestrator server | `rollForward` condition in `Orchestrator.runtimeconfig.json` | `vmware-nsx-orchestrator` .NET version to download |
| --------- | ----------- | ----------- | ----------- |
| Older than `11.0.0` | | | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net6.0` | | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `Disable` | `net6.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `LatestMajor` | `net8.0` |
| `11.6` _and_ newer | `net8.0` | | `net8.0` |
| Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `Disable` | `net6.0` || Between `11.0.0` and `11.5.1` (inclusive) | `net8.0` | `LatestMajor` | `net8.0` |
| `11.6` _and_ newer | `net8.0` | | `net8.0` |

Unzip the archive containing extension assemblies to a known location.

Expand Down
116 changes: 116 additions & 0 deletions scripts/store_types/bash/curl_create_store_types.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env bash

# Creates all 1 store types via the Keyfactor Command REST API using curl.
#
# Authentication (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD + KEYFACTOR_DOMAIN
#
# Always required:
# KEYFACTOR_HOSTNAME Command hostname (e.g. my-command.example.com)
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.

if [ -z "${KEYFACTOR_HOSTNAME}" ]; then
echo "ERROR: KEYFACTOR_HOSTNAME is required"
exit 1
fi

BASE_URL="https://${KEYFACTOR_HOSTNAME}/keyfactorapi"

# ---------------------------------------------------------------------------
# Resolve auth
# ---------------------------------------------------------------------------
if [ -n "${KEYFACTOR_AUTH_ACCESS_TOKEN}" ]; then
BEARER_TOKEN="${KEYFACTOR_AUTH_ACCESS_TOKEN}"
elif [ -n "${KEYFACTOR_AUTH_CLIENT_ID}" ] && [ -n "${KEYFACTOR_AUTH_CLIENT_SECRET}" ] && [ -n "${KEYFACTOR_AUTH_TOKEN_URL}" ]; then
echo "Fetching OAuth token..."
BEARER_TOKEN=$(curl -s -X POST "${KEYFACTOR_AUTH_TOKEN_URL}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=${KEYFACTOR_AUTH_CLIENT_ID}" \
--data-urlencode "client_secret=${KEYFACTOR_AUTH_CLIENT_SECRET}" | jq -r '.access_token')
if [ -z "${BEARER_TOKEN}" ] || [ "${BEARER_TOKEN}" = "null" ]; then
echo "ERROR: Failed to fetch OAuth token from ${KEYFACTOR_AUTH_TOKEN_URL}"
exit 1
fi
elif [ -n "${KEYFACTOR_USERNAME}" ] && [ -n "${KEYFACTOR_PASSWORD}" ] && [ -n "${KEYFACTOR_DOMAIN}" ]; then
BEARER_TOKEN=""
else
echo "ERROR: Authentication required. Set one of:"
echo " KEYFACTOR_AUTH_ACCESS_TOKEN"
echo " KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET + KEYFACTOR_AUTH_TOKEN_URL"
echo " KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD + KEYFACTOR_DOMAIN"
exit 1
fi

if [ -n "${BEARER_TOKEN}" ]; then
CURL_AUTH=("-H" "Authorization: Bearer ${BEARER_TOKEN}")
else
CURL_AUTH=("-u" "${KEYFACTOR_USERNAME}@${KEYFACTOR_DOMAIN}:${KEYFACTOR_PASSWORD}")
fi

create_store_type() {
local name="$1"
local body="$2"
echo "Creating ${name} store type..."
response=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "${BASE_URL}/certificatestoretypes" \
-H "Content-Type: application/json" \
-H "x-keyfactor-requested-with: APIClient" \
"${CURL_AUTH[@]}" \
-d "${body}")
if [ "$response" = "200" ] || [ "$response" = "201" ]; then
echo " OK (HTTP ${response})"
else
echo " FAILED (HTTP ${response})"
fi
}

# ---------------------------------------------------------------------------
# VMware-NSX — This is the URL for the VMware NSX instance. It also includes an optional tenant in square brackets before the URL. A tenant value is required when the certificates being managed are in a different tenant from the default tenant set for the NSX User specified for the store. This should look like either: [optional-tenant-name]https://my.nsx.url/ OR https://my.nsx.url/
# ---------------------------------------------------------------------------
create_store_type "VMware-NSX" '{
"Name": "VMware-NSX",
"ShortName": "VMware-NSX",
"Capability": "VMware-NSX",
"LocalStore": false,
"SupportedOperations": {
"Add": true,
"Create": false,
"Discovery": false,
"Enrollment": false,
"Remove": true
},
"Properties": [
{
"Name": "ApiVersion",
"DisplayName": "X-Avi-Version",
"Type": "String",
"DependsOn": "",
"DefaultValue": "20.1.1",
"Required": true,
"IsPAMEligible": false
}
],
"EntryParameters": [],
"PasswordOptions": {
"EntrySupported": false,
"StoreRequired": false,
"Style": "Default"
},
"StorePathType": "MultipleChoice",
"StorePathValue": "[\"Application\",\"Controller\",\"CA\"]",
"PrivateKeyAllowed": "Optional",
"JobProperties": [],
"ServerRequired": true,
"PowerShell": false,
"BlueprintAllowed": false,
"CustomAliasAllowed": "Required",
"StorePathDescription": "A selection from the different certificate types supported: Application, Controller, or CA."
}'


echo "Completed."
28 changes: 28 additions & 0 deletions scripts/store_types/bash/kfutil_create_store_types.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

# Creates all 1 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.

if ! command -v kfutil &> /dev/null; then
echo "kfutil could not be found. Please install kfutil"
echo "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
fi

if [ -z "$KEYFACTOR_HOSTNAME" ]; then
echo "KEYFACTOR_HOSTNAME not set — launching kfutil login"
kfutil login
fi

kfutil store-types create --name "VMware-NSX"

echo "Done. All store types created."
29 changes: 29 additions & 0 deletions scripts/store_types/powershell/kfutil_create_store_types.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Creates all 1 store types using kfutil.
# kfutil reads definitions from the Keyfactor integration catalog.
#
# Auth environment variables (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_HOSTNAME + KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD
# + KEYFACTOR_DOMAIN
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.

# Uncomment if kfutil is not in your PATH
# Set-Alias -Name kfutil -Value 'C:\Program Files\Keyfactor\kfutil\kfutil.exe'

if ($null -eq (Get-Command "kfutil" -ErrorAction SilentlyContinue)) {
Write-Host "kfutil could not be found. Please install kfutil"
Write-Host "See https://github.com/Keyfactor/kfutil#quickstart"
exit 1
}

if (-not $env:KEYFACTOR_HOSTNAME) {
Write-Host "KEYFACTOR_HOSTNAME not set — launching kfutil login"
& kfutil login
}

& kfutil store-types create --name "VMware-NSX"

Write-Host "Done. All store types created."
110 changes: 110 additions & 0 deletions scripts/store_types/powershell/restmethod_create_store_types.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Creates all 1 store types via the Keyfactor Command REST API
# using PowerShell Invoke-RestMethod.
#
# Authentication (first matching method is used):
# OAuth access token: KEYFACTOR_AUTH_ACCESS_TOKEN
# OAuth client creds: KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET
# + KEYFACTOR_AUTH_TOKEN_URL
# Basic auth (AD): KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD + KEYFACTOR_DOMAIN
#
# Always required:
# KEYFACTOR_HOSTNAME Command hostname (e.g. my-command.example.com)
#
# Auto-generated by doctool generate-store-type-scripts — do not edit by hand.

if (-not $env:KEYFACTOR_HOSTNAME) {
Write-Error "KEYFACTOR_HOSTNAME is required"
exit 1
}

$uri = "https://$($env:KEYFACTOR_HOSTNAME)/keyfactorapi/certificatestoretypes"
$headers = @{
'Content-Type' = "application/json"
'x-keyfactor-requested-with' = "APIClient"
}

# ---------------------------------------------------------------------------
# Resolve auth
# ---------------------------------------------------------------------------
if ($env:KEYFACTOR_AUTH_ACCESS_TOKEN) {
$headers['Authorization'] = "Bearer $($env:KEYFACTOR_AUTH_ACCESS_TOKEN)"
} elseif ($env:KEYFACTOR_AUTH_CLIENT_ID -and $env:KEYFACTOR_AUTH_CLIENT_SECRET -and $env:KEYFACTOR_AUTH_TOKEN_URL) {
Write-Host "Fetching OAuth token..."
$tokenBody = @{
grant_type = 'client_credentials'
client_id = $env:KEYFACTOR_AUTH_CLIENT_ID
client_secret = $env:KEYFACTOR_AUTH_CLIENT_SECRET
}
$tokenResp = Invoke-RestMethod -Method Post -Uri $env:KEYFACTOR_AUTH_TOKEN_URL -Body $tokenBody
$headers['Authorization'] = "Bearer $($tokenResp.access_token)"
} elseif ($env:KEYFACTOR_USERNAME -and $env:KEYFACTOR_PASSWORD -and $env:KEYFACTOR_DOMAIN) {
$cred = [System.Convert]::ToBase64String(
[System.Text.Encoding]::ASCII.GetBytes(
"$($env:KEYFACTOR_USERNAME)@$($env:KEYFACTOR_DOMAIN):$($env:KEYFACTOR_PASSWORD)"))
$headers['Authorization'] = "Basic $cred"
} else {
Write-Error ("Authentication required. Set one of:`n" +
" KEYFACTOR_AUTH_ACCESS_TOKEN`n" +
" KEYFACTOR_AUTH_CLIENT_ID + KEYFACTOR_AUTH_CLIENT_SECRET + KEYFACTOR_AUTH_TOKEN_URL`n" +
" KEYFACTOR_USERNAME + KEYFACTOR_PASSWORD + KEYFACTOR_DOMAIN")
exit 1
}

function New-StoreType {
param([string]$Name, [string]$Body)
Write-Host "Creating $Name store type..."
try {
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $Body -ContentType "application/json" | Out-Null
Write-Host " OK"
} catch {
Write-Warning " FAILED: $($_.Exception.Message)"
}
}

# ---------------------------------------------------------------------------
# VMware-NSX — This is the URL for the VMware NSX instance. It also includes an optional tenant in square brackets before the URL. A tenant value is required when the certificates being managed are in a different tenant from the default tenant set for the NSX User specified for the store. This should look like either: [optional-tenant-name]https://my.nsx.url/ OR https://my.nsx.url/
# ---------------------------------------------------------------------------
New-StoreType "VMware-NSX" @'
{
"Name": "VMware-NSX",
"ShortName": "VMware-NSX",
"Capability": "VMware-NSX",
"LocalStore": false,
"SupportedOperations": {
"Add": true,
"Create": false,
"Discovery": false,
"Enrollment": false,
"Remove": true
},
"Properties": [
{
"Name": "ApiVersion",
"DisplayName": "X-Avi-Version",
"Type": "String",
"DependsOn": "",
"DefaultValue": "20.1.1",
"Required": true,
"IsPAMEligible": false
}
],
"EntryParameters": [],
"PasswordOptions": {
"EntrySupported": false,
"StoreRequired": false,
"Style": "Default"
},
"StorePathType": "MultipleChoice",
"StorePathValue": "[\"Application\",\"Controller\",\"CA\"]",
"PrivateKeyAllowed": "Optional",
"JobProperties": [],
"ServerRequired": true,
"PowerShell": false,
"BlueprintAllowed": false,
"CustomAliasAllowed": "Required",
"StorePathDescription": "A selection from the different certificate types supported: Application, Controller, or CA."
}
'@


Write-Host "Completed."
Loading
Loading