Octopus.Script exported 2021-08-23 by benjimac93 belongs to ‘Octopus’ category.
Clone an Octopus tenant. The project connections and tenant tags will be cloned and the non-sensitive variables can optionally be cloned.
Parameters
When steps based on the template are included in a project’s deployment process, the parameters below can be set.
Octopus URL
CloneTenantStep_OctopusUrl = #{if Octopus.Web.ServerUri}#{Octopus.Web.ServerUri}#{else}#{Octopus.Web.BaseUrl}#{/if}
The URL of the Octopus Server to clone the tenant to.
Octopus API Key
CloneTenantStep_ApiKey =
The Octopus API Key to use for the API requests
Id of Tenant to Clone
CloneTenantStep_TenantIdToClone =
The Id of the tenant to clone. This will be in the format of Tenants-1
New Tenant Name
CloneTenantStep_TenantName =
The name of the tenant to create. Note this must be unique
Clone Variables?
CloneTenantStep_CloneVariables =
Flag indicating whether the source tenant’s variables should be cloned to the new tenant. Note this does not copy sensitive variables
Clone Tags?
CloneTenantStep_CloneTags = True
Flag indicating whether the source tenant’s tags should be cloned.
Space Id
CloneTenantStep_SpaceId =
The Id of the Space used to clone the tenant. Leave blank if you are using an Octopus version earlier than 2019.1 or if you wish to use the Octopus.Space.Id variable value.
Script body
Steps based on this template will execute the following PowerShell script.
$securityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12
[Net.ServicePointManager]::SecurityProtocol = $securityProtocol
$octopusBaseUrl = $CloneTenantStep_OctopusUrl.Trim('/')
$apiKey = $CloneTenantStep_ApiKey
$tenantToClone = $CloneTenantStep_TenantIdToClone
$tenantName = $CloneTenantStep_TenantName
$cloneVariables = $CloneTenantStep_CloneVariables
$cloneTags = $CloneTenantStep_CloneTags
$spaceId = $CloneTenantStep_SpaceId
$ErrorActionPreference = 'Stop'
if ([string]::IsNullOrWhiteSpace($octopusBaseUrl)) {
throw "The step parameter 'Octopus Base Url' was not found. This step requires the Octopus Server URL to function, please provide one and try again."
}
if ([string]::IsNullOrWhiteSpace($apiKey)) {
throw "The step parameter 'Octopus API Key' was not found. This step requires an API Key to function, please provide one and try again."
}
if ([string]::IsNullOrWhiteSpace($tenantToClone)) {
throw "The step parameter 'Id of Tenant to Clone' was not found. Please provide one and try again."
}
if ([string]::IsNullOrWhiteSpace($tenantName)) {
throw "The step parameter 'New Tenant Name' was not found. Please provide one and try again."
}
function Invoke-OctopusApi {
param(
[Parameter(Position = 0, Mandatory)]$Uri,
[ValidateSet("Get", "Post", "Put", "Delete")]$Method = 'Get',
$Body
)
$uriParts = @($octopusBaseUrl, $Uri.TrimStart('/'))
$uri = ($uriParts -join '/')
Write-Verbose "Uri: $uri"
$requestParameters = @{
Uri = $uri
Method = $Method
Headers = @{ "X-Octopus-ApiKey" = $apiKey }
UseBasicParsing = $true
}
if ($null -ne $Body) { $requestParameters.Add('Body', ($Body | ConvertTo-Json -Depth 10)) }
return Invoke-WebRequest @requestParameters | % Content | ConvertFrom-Json
}
function Test-SpacesApi {
Write-Verbose "Checking API compatibility";
$rootDocument = Invoke-OctopusApi 'api/';
if($rootDocument.Links -ne $null -and $rootDocument.Links.Spaces -ne $null) {
Write-Verbose "Spaces API found"
return $true;
}
Write-Verbose "Pre-spaces API found"
return $false;
}
if([string]::IsNullOrWhiteSpace($spaceId)) {
if(Test-SpacesApi) {
$spaceId = $OctopusParameters['Octopus.Space.Id'];
if([string]::IsNullOrWhiteSpace($spaceId)) {
throw "This step needs to be run in a context that provides a value for the 'Octopus.Space.Id' system variable. In this case, we received a blank value, which isn't expected - please reach out to our support team at https://help.octopus.com if you encounter this error or try providing the Space Id parameter.";
}
}
}
$apiPrefix = "api/"
$tenantUrlBase = @($octopusBaseUrl, 'app#')
if ($spaceId) {
$apiPrefix += $spaceId
$tenantUrlBase += $spaceId
}
Write-Host "Fetching source tenant"
$tenant = Invoke-OctopusApi "$apiPrefix/tenants/$tenantToClone"
$sourceTenantId = $tenant.Id
$sourceTenantName = $tenant.Name
$tenant.Id = $null
$tenant.Name = $tenantName
if ($cloneTags -ne $true) {
Write-Host "Clearing tenant tags"
$tenant.TenantTags = @()
}
Write-Host "Creating new tenant"
$newTenant = Invoke-OctopusApi "$apiPrefix/tenants" -Method Post -Body $tenant
if ($cloneVariables -eq $true) {
Write-Host "Cloning variables"
$variables = Invoke-OctopusApi $tenant.Links.Variables
$variables.TenantId = $newTenant.Id
$variables.TenantName = $tenantName
Invoke-OctopusApi $newTenant.Links.Variables -Method Put -Body $variables | Out-Null
}
$tenantUrl = ($tenantUrlBase + "tenants" + $newTenant.Id + "overview") -join '/'
$sourceTenantUrl = ($tenantUrlBase + "tenants" + $sourceTenantId + "overview") -join '/'
Write-Highlight "New tenant [$tenantName]($tenantUrl) has been cloned from [$sourceTenantName]($sourceTenantUrl)"
Provided under the Apache License version 2.0.
To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
{
"Id": "3b0f8df0-93b8-44eb-86dd-264d1283ae70",
"Name": "Clone Tenant",
"Description": "Clone an Octopus [tenant](https://octopus.com/docs/deployment-patterns/multi-tenant-deployments). The project connections and tenant tags will be cloned and the non-sensitive variables can optionally be cloned.",
"Version": 4,
"ExportedAt": "2021-08-23T12:40:10.975Z",
"ActionType": "Octopus.Script",
"Author": "benjimac93",
"Packages": [],
"Parameters": [
{
"Id": "cbedd129-210e-4bab-a446-3f89192653c7",
"Name": "CloneTenantStep_OctopusUrl",
"Label": "Octopus URL",
"HelpText": "The URL of the Octopus Server to clone the tenant to.",
"DefaultValue": "#{if Octopus.Web.ServerUri}#{Octopus.Web.ServerUri}#{else}#{Octopus.Web.BaseUrl}#{/if}",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "ea2614f0-bd41-4011-b263-7d2b12af5977",
"Name": "CloneTenantStep_ApiKey",
"Label": "Octopus API Key",
"HelpText": "The Octopus API Key to use for the API requests",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "Sensitive"
}
},
{
"Id": "b29e27fb-362e-45e2-a244-6d590875fb68",
"Name": "CloneTenantStep_TenantIdToClone",
"Label": "Id of Tenant to Clone",
"HelpText": "The Id of the tenant to clone. This will be in the format of *Tenants-1*",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "b9b3a6c7-6c83-4a79-9a94-febc6c5818d3",
"Name": "CloneTenantStep_TenantName",
"Label": "New Tenant Name",
"HelpText": "The name of the tenant to create. *Note this must be unique*",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
},
{
"Id": "be821ad4-b195-4b11-81c2-f432ff05b86d",
"Name": "CloneTenantStep_CloneVariables",
"Label": "Clone Variables?",
"HelpText": "Flag indicating whether the source tenant's variables should be cloned to the new tenant. *Note this does not copy sensitive variables*",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "Checkbox"
}
},
{
"Id": "831db28c-edc2-496b-b082-e6de827ca5df",
"Name": "CloneTenantStep_CloneTags",
"Label": "Clone Tags?",
"HelpText": "Flag indicating whether the source tenant's tags should be cloned.",
"DefaultValue": "True",
"DisplaySettings": {
"Octopus.ControlType": "Checkbox"
}
},
{
"Id": "f9320a59-9752-43a5-b46a-a4d1486cfced",
"Name": "CloneTenantStep_SpaceId",
"Label": "Space Id",
"HelpText": "The Id of the Space used to clone the tenant. **Leave blank if you are using an Octopus version earlier than 2019.1 or if you wish to use the Octopus.Space.Id variable value.**",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
}
}
],
"Properties": {
"Octopus.Action.Script.ScriptSource": "Inline",
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptBody": "$securityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12\n[Net.ServicePointManager]::SecurityProtocol = $securityProtocol\n\n$octopusBaseUrl = $CloneTenantStep_OctopusUrl.Trim('/')\n$apiKey = $CloneTenantStep_ApiKey\n$tenantToClone = $CloneTenantStep_TenantIdToClone\n$tenantName = $CloneTenantStep_TenantName\n$cloneVariables = $CloneTenantStep_CloneVariables\n$cloneTags = $CloneTenantStep_CloneTags\n$spaceId = $CloneTenantStep_SpaceId\n\n$ErrorActionPreference = 'Stop'\n\nif ([string]::IsNullOrWhiteSpace($octopusBaseUrl)) {\n throw \"The step parameter 'Octopus Base Url' was not found. This step requires the Octopus Server URL to function, please provide one and try again.\"\n}\n\nif ([string]::IsNullOrWhiteSpace($apiKey)) {\n throw \"The step parameter 'Octopus API Key' was not found. This step requires an API Key to function, please provide one and try again.\"\n}\n\nif ([string]::IsNullOrWhiteSpace($tenantToClone)) {\n throw \"The step parameter 'Id of Tenant to Clone' was not found. Please provide one and try again.\"\n}\n\nif ([string]::IsNullOrWhiteSpace($tenantName)) {\n throw \"The step parameter 'New Tenant Name' was not found. Please provide one and try again.\"\n}\n\nfunction Invoke-OctopusApi {\n param(\n [Parameter(Position = 0, Mandatory)]$Uri,\n [ValidateSet(\"Get\", \"Post\", \"Put\", \"Delete\")]$Method = 'Get',\n $Body\n )\n \n $uriParts = @($octopusBaseUrl, $Uri.TrimStart('/')) \n $uri = ($uriParts -join '/')\n\n Write-Verbose \"Uri: $uri\"\n \n $requestParameters = @{\n Uri = $uri\n Method = $Method\n Headers = @{ \"X-Octopus-ApiKey\" = $apiKey }\n UseBasicParsing = $true\n }\n \n if ($null -ne $Body) { $requestParameters.Add('Body', ($Body | ConvertTo-Json -Depth 10)) }\n \n return Invoke-WebRequest @requestParameters | % Content | ConvertFrom-Json\n}\n\nfunction Test-SpacesApi {\n\tWrite-Verbose \"Checking API compatibility\";\n\t$rootDocument = Invoke-OctopusApi 'api/';\n if($rootDocument.Links -ne $null -and $rootDocument.Links.Spaces -ne $null) {\n \tWrite-Verbose \"Spaces API found\"\n \treturn $true;\n }\n Write-Verbose \"Pre-spaces API found\"\n return $false;\n}\n\nif([string]::IsNullOrWhiteSpace($spaceId)) {\n\tif(Test-SpacesApi) {\n \t$spaceId = $OctopusParameters['Octopus.Space.Id'];\n \tif([string]::IsNullOrWhiteSpace($spaceId)) {\n \tthrow \"This step needs to be run in a context that provides a value for the 'Octopus.Space.Id' system variable. In this case, we received a blank value, which isn't expected - please reach out to our support team at https://help.octopus.com if you encounter this error or try providing the Space Id parameter.\";\n \t}\n\t}\n}\n\n$apiPrefix = \"api/\"\n$tenantUrlBase = @($octopusBaseUrl, 'app#')\n\nif ($spaceId) {\n\t$apiPrefix += $spaceId\n $tenantUrlBase += $spaceId\n}\n\nWrite-Host \"Fetching source tenant\"\n$tenant = Invoke-OctopusApi \"$apiPrefix/tenants/$tenantToClone\"\n\n$sourceTenantId = $tenant.Id\n$sourceTenantName = $tenant.Name\n$tenant.Id = $null\n$tenant.Name = $tenantName\n\nif ($cloneTags -ne $true) {\n\tWrite-Host \"Clearing tenant tags\"\n $tenant.TenantTags = @()\n}\n\nWrite-Host \"Creating new tenant\"\n$newTenant = Invoke-OctopusApi \"$apiPrefix/tenants\" -Method Post -Body $tenant\n\nif ($cloneVariables -eq $true) {\n\tWrite-Host \"Cloning variables\"\n $variables = Invoke-OctopusApi $tenant.Links.Variables\n $variables.TenantId = $newTenant.Id\n $variables.TenantName = $tenantName\n\n Invoke-OctopusApi $newTenant.Links.Variables -Method Put -Body $variables | Out-Null\n}\n\n$tenantUrl = ($tenantUrlBase + \"tenants\" + $newTenant.Id + \"overview\") -join '/'\n$sourceTenantUrl = ($tenantUrlBase + \"tenants\" + $sourceTenantId + \"overview\") -join '/'\n\nWrite-Highlight \"New tenant [$tenantName]($tenantUrl) has been cloned from [$sourceTenantName]($sourceTenantUrl)\""
},
"Category": "Octopus",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/clone-tenant.json",
"Website": "/step-templates/3b0f8df0-93b8-44eb-86dd-264d1283ae70",
"Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
"$Meta": {
"Type": "ActionTemplate"
}
}
Page updated on Monday, August 23, 2021