Octopus - Lookup Space ID

Octopus.Script exported 2023-09-11 by mcasperson belongs to ‘Octopus’ category.

This step queries an Octopus server to return the ID of a named space. The ID is captured in an output variables called SpaceID.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Server URL

SpaceLookup.ThisInstance.Server.Url = #{Octopus.Web.ServerUri}

The URL of the Octopus Server hosting the space to resolved.

Server API Key

SpaceLookup.ThisInstance.Api.Key =

The Octopus API Key

Space Name

SpaceLookup.Lookup.Space.Name =

The name of the space return the ID of

Script body

Steps based on this template will execute the following Python script.

# This script exists for those scenarios where the tenant space is created as part of the same process that
# attempts to populate the space. The tenant space ID variable, saved when the space is created, won't be refreshed
# in the middle of the deployment, so we query it directly.

import argparse
import json
import urllib.request
import urllib.parse
import os
import sys
import time

# If this script is not being run as part of an Octopus step, return variables from environment variables.
# Periods are replaced with underscores, and the variable name is converted to uppercase
if "get_octopusvariable" not in globals():
    def get_octopusvariable(variable):
        return os.environ[re.sub('\\.', '_', variable.upper())]

# If this script is not being run as part of an Octopus step, just print any set variable to std out.
if "set_octopusvariable" not in globals():
    def set_octopusvariable(name, variable):
        print(variable)


def get_octopusvariable_quiet(variable):
    """
    Gets an octopus variable, or an empty string if it does not exist.
    :param variable: The variable name
    :return: The variable value, or an empty string if the variable does not exist
    """
    try:
        return get_octopusvariable(variable)
    except:
        return ''


def init_argparse():
    parser = argparse.ArgumentParser(
        usage='%(prog)s [OPTION] [FILE]...',
        description='Lookup a space ID from the name'
    )
    parser.add_argument('--server-url',
                        action='store',
                        default=get_octopusvariable_quiet(
                            'SpaceLookup.ThisInstance.Server.Url') or get_octopusvariable_quiet(
                            'ThisInstance.Server.Url'),
                        help='Sets the Octopus server URL.')
    parser.add_argument('--api-key',
                        action='store',
                        default=get_octopusvariable_quiet(
                            'SpaceLookup.ThisInstance.Api.Key') or get_octopusvariable_quiet('ThisInstance.Api.Key'),
                        help='Sets the Octopus API key.')
    parser.add_argument('--space-name',
                        action='store',
                        default=get_octopusvariable_quiet('SpaceLookup.Lookup.Space.Name') or get_octopusvariable_quiet(
                            'Lookup.Space.Name') or get_octopusvariable_quiet('Octopus.Deployment.Tenant.Name'),
                        help='The name of the space to lookup.')

    return parser.parse_known_args()


parser, _ = init_argparse()

# Variable precondition checks
if len(parser.server_url) == 0:
    print("--server-url, ThisInstance.Server.Url, or SerializeProject.ThisInstance.Server.Url must be defined")
    sys.exit(1)

if len(parser.api_key) == 0:
    print("--api-key, ThisInstance.Api.Key, or ThisInstance.Api.Key must be defined")
    sys.exit(1)

if len(parser.space_name) == 0:
    print("--space-name, Lookup.Space.Name, SpaceLookup.Lookup.Space.Name, or Octopus.Deployment.Tenant.Name must be defined")
    sys.exit(1)

url = parser.server_url + '/api/Spaces?partialName=' + urllib.parse.quote(parser.space_name) + "&take=1000"
headers = {
    'X-Octopus-ApiKey': parser.api_key,
    'Accept': 'application/json'
}
request = urllib.request.Request(url, headers=headers)

# Retry the request for up to a minute.
response = None
for x in range(12):
    response = urllib.request.urlopen(request)
    if response.getcode() == 200:
        break
    time.sleep(5)

if not response or not response.getcode() == 200:
    print('The API query failed')
    sys.exit(1)

data = json.loads(response.read().decode("utf-8"))

space = [x for x in data['Items'] if x['Name'] == parser.space_name]

if len(space) != 0:
    print('Space ' + parser.space_name + ' has ID ' + space[0]['Id'])
    print('The space ID is available as the output variable #{Octopus.Action[' + get_octopusvariable_quiet('Octopus.Action.Name') + '].Output.SpaceID}')
    set_octopusvariable("SpaceID", space[0]['Id'])
else:
    print('Failed to find space called ' + parser.space_name)
    sys.exit(1)

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "324f747e-e2cd-439d-a660-774baf4991f2",
  "Name": "Octopus - Lookup Space ID",
  "Description": "This step queries an Octopus server to return the ID of a named space. The ID is captured in an output variables called `SpaceID`.",
  "Version": 2,
  "ExportedAt": "2023-09-11T21:15:03.881Z",
  "ActionType": "Octopus.Script",
  "Author": "mcasperson",
  "Packages": [],
  "Parameters": [
    {
      "Id": "69b98409-b4ba-401f-8986-042b6d58584f",
      "Name": "SpaceLookup.ThisInstance.Server.Url",
      "Label": "Server URL",
      "HelpText": "The URL of the Octopus Server hosting the space to resolved.",
      "DefaultValue": "#{Octopus.Web.ServerUri}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "9089cd55-75d6-4e91-a390-d7a3359e3c59",
      "Name": "SpaceLookup.ThisInstance.Api.Key",
      "Label": "Server API Key",
      "HelpText": "The Octopus API Key",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "4f5d46a5-ea76-478f-a5fa-0bacad6afa5b",
      "Name": "SpaceLookup.Lookup.Space.Name",
      "Label": "Space Name",
      "HelpText": "The name of the space return the ID of",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.RunOnServer": "true",
    "Octopus.Action.Script.ScriptBody": "# This script exists for those scenarios where the tenant space is created as part of the same process that\n# attempts to populate the space. The tenant space ID variable, saved when the space is created, won't be refreshed\n# in the middle of the deployment, so we query it directly.\n\nimport argparse\nimport json\nimport urllib.request\nimport urllib.parse\nimport os\nimport sys\nimport time\n\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\n# Periods are replaced with underscores, and the variable name is converted to uppercase\nif \"get_octopusvariable\" not in globals():\n    def get_octopusvariable(variable):\n        return os.environ[re.sub('\\\\.', '_', variable.upper())]\n\n# If this script is not being run as part of an Octopus step, just print any set variable to std out.\nif \"set_octopusvariable\" not in globals():\n    def set_octopusvariable(name, variable):\n        print(variable)\n\n\ndef get_octopusvariable_quiet(variable):\n    \"\"\"\n    Gets an octopus variable, or an empty string if it does not exist.\n    :param variable: The variable name\n    :return: The variable value, or an empty string if the variable does not exist\n    \"\"\"\n    try:\n        return get_octopusvariable(variable)\n    except:\n        return ''\n\n\ndef init_argparse():\n    parser = argparse.ArgumentParser(\n        usage='%(prog)s [OPTION] [FILE]...',\n        description='Lookup a space ID from the name'\n    )\n    parser.add_argument('--server-url',\n                        action='store',\n                        default=get_octopusvariable_quiet(\n                            'SpaceLookup.ThisInstance.Server.Url') or get_octopusvariable_quiet(\n                            'ThisInstance.Server.Url'),\n                        help='Sets the Octopus server URL.')\n    parser.add_argument('--api-key',\n                        action='store',\n                        default=get_octopusvariable_quiet(\n                            'SpaceLookup.ThisInstance.Api.Key') or get_octopusvariable_quiet('ThisInstance.Api.Key'),\n                        help='Sets the Octopus API key.')\n    parser.add_argument('--space-name',\n                        action='store',\n                        default=get_octopusvariable_quiet('SpaceLookup.Lookup.Space.Name') or get_octopusvariable_quiet(\n                            'Lookup.Space.Name') or get_octopusvariable_quiet('Octopus.Deployment.Tenant.Name'),\n                        help='The name of the space to lookup.')\n\n    return parser.parse_known_args()\n\n\nparser, _ = init_argparse()\n\n# Variable precondition checks\nif len(parser.server_url) == 0:\n    print(\"--server-url, ThisInstance.Server.Url, or SerializeProject.ThisInstance.Server.Url must be defined\")\n    sys.exit(1)\n\nif len(parser.api_key) == 0:\n    print(\"--api-key, ThisInstance.Api.Key, or ThisInstance.Api.Key must be defined\")\n    sys.exit(1)\n\nif len(parser.space_name) == 0:\n    print(\"--space-name, Lookup.Space.Name, SpaceLookup.Lookup.Space.Name, or Octopus.Deployment.Tenant.Name must be defined\")\n    sys.exit(1)\n\nurl = parser.server_url + '/api/Spaces?partialName=' + urllib.parse.quote(parser.space_name) + \"&take=1000\"\nheaders = {\n    'X-Octopus-ApiKey': parser.api_key,\n    'Accept': 'application/json'\n}\nrequest = urllib.request.Request(url, headers=headers)\n\n# Retry the request for up to a minute.\nresponse = None\nfor x in range(12):\n    response = urllib.request.urlopen(request)\n    if response.getcode() == 200:\n        break\n    time.sleep(5)\n\nif not response or not response.getcode() == 200:\n    print('The API query failed')\n    sys.exit(1)\n\ndata = json.loads(response.read().decode(\"utf-8\"))\n\nspace = [x for x in data['Items'] if x['Name'] == parser.space_name]\n\nif len(space) != 0:\n    print('Space ' + parser.space_name + ' has ID ' + space[0]['Id'])\n    print('The space ID is available as the output variable #{Octopus.Action[' + get_octopusvariable_quiet('Octopus.Action.Name') + '].Output.SpaceID}')\n    set_octopusvariable(\"SpaceID\", space[0]['Id'])\nelse:\n    print('Failed to find space called ' + parser.space_name)\n    sys.exit(1)\n",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "Python"
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/octopus-lookup-space-id.json",
  "Website": "/step-templates/324f747e-e2cd-439d-a660-774baf4991f2",
  "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"
  }
}

History

Page updated on Monday, September 11, 2023