CloudBolt API v2.0

The CloudBolt API uses REST methodology and ascribes to the latest in industry-proven conventions and design. Our adoption of Hypertext Application Language (HAL) brings many benefits to our API, such as making it explorable and self-descriptive.

Documentation for our API is made available from within the API itself or in a web UI, making the CloudBolt API easy to learn and consumable for developers of any modern language.

HAL decouples the CloudBolt server’s API from the API clients, adding a level of automatic resilience to changes in the API that was not possible with API standards just a few years ago.

The resultant API is highly functional, enabling creative and powerful integrations, and even fun to learn and use. We welcome feedback on any aspect of the API and its documentation.

API Conventions

URLs / Resources

/{plural-noun} : Collections of type “noun”.

/{plural-noun}/id : Items within a collection.

/{single-noun} : A singleton item (one that exists without a collection).

Collections and items are both called resources. Collections will be more common, but two examples of singletons are:

/user : Representing the currently authenticated user.

/user/current-order : The user’s current order

Functionality that is better expressed in RPC style vs REST are exposed under an actions/ subpath.

Example: /resource-handlers/actions/sync-vms.

Verbs

For collections and subcollections:

GET : Retrieve the collection

POST : Create a new item in the collection (not applicable to all collections)

For items:

GET : Retrieve the item

For actions:

POST : Trigger the action

Query String Parameters

CloudBolt API recognizes three special parameters that can be passed in the querystring part of the url:

Attributes

The attributes parameter can be used to append to the list of attributes that are returned for the Resource or Collection being retrieved. It takes a comma delimited list of the Resource attributes.

Example: /api/v2/users/?attributes=user.first-name,user.last-name,user.is-superuser

Filter

The filter parameter can be used to limit the resources returned in a collection. It takes a semi-colon delimited list of key-value pairs, where the key and value are separated by a colon. It supports any Django QuerySet filter syntax where a single value of type string or numeric is expected (this includes booleans represented as 0 or 1).

Examples:

  • /api/v2/servers/?filter=hostname:linprodsvr0213
  • /api/v2/servers/?filter=environment.name.contains:Dev
  • /api/v2/users/?filter=user.first-name.startswith:A
  • /api/v2/jobs/?filter=type:provision;status:success

Authentication

Access to API end-points require the use of a bearer token in the request header. The API is subject to the same authentication and permissions model as the rest of CloudBolt, meaning that the security for which users can perform which actions will be consistent, regardless of whether they use the API or the web UI. It also means that requesting the access token supports the same parameters as when logging into the CloudBolt web interface.

Only users with the API Access global role enabled on the user’s profile will be able to obtain a bearer token and, therefore, be able to use the API.

Token Based Access to Resources

Access to API resources requires the use of a bearer token in the request header. The special end-point for requesting the token is api/v2/api-token-auth/. The end-point expects clients to POST a JSON representation of authentication attributes like:

  • username - The username for the user requesting the token.
  • password - The password to which the user credentials should be checked against
  • token - A current user token, if CloudBolt is setup with 2-factor authentication
  • domain - The AD/LDAP directory domain the user belongs to, if not an internal user.

The token default expiration is set to 5 minutes. This can be changed by adding the following section to your customer_settings.py file and modifying the time in seconds to your preference:

import datetime
from settings import JWT_AUTH

JWT_AUTH['JWT_EXPIRATION_DELTA'] = datetime.timedelta(seconds=300)

For a complete list of all advanced settings related to the bearer token see http://getblimp.github.io/django-rest-framework-jwt/#additional-settings

Object IDs

There are two types of IDs used to access objects through the API. Global IDs are the recommended type of ID for your objects. They stay consistent across multiple instances of CloudBolt and make maintaining objects simple when importing and exporting. Primary Key IDs can still be used in 9.1 and greater for backwards compatibility.

  • Global ID (Recommended): Consists of a prefix which indicates the object type (e.g. BP for Blueprint), a dash, and 8 unique characters (a random combination of lowercase letters and digits). Example: BP-a238b32r. Some additional set up is required after upgrade to fully use this feature. See Transitioning to Global IDs below.
  • Primary Key ID: An object is assigned a number. Each subsequent object gets the next number in ascending order. These ID types do not persist across multiple instances of CloudBolt, which can make maintenance difficult.

Objects with Global IDs

The first objects to transition to this new Global ID are those referenced by a URL when ordering a Blueprint through the API. The specific object types, with their prefixes, are:

  • Blueprint (BP)
  • Group (GRP)
  • Application (APP)
  • Environment (ENV)
  • OS Build (OSB)

Global IDs are shown on the Details page of appropriate objects and demonstrated in the API. The objects listed above will get a Global ID assigned. The Primary Key (PK) ID found in the URL in the web UI is still available for use if desired, both for these objects and other types that do not yet support Global IDs.

Locations and Limitations of Global IDs in CloudBolt

Global IDs can be viewed and/or used in CloudBolt in the following locations:

  • The collections list view for Blueprints, Environments, Groups, OS Builds, and Applications (view only).
  • Most places that reference a Blueprint, Environment, Group, OS Build, or Application with a link (view only).
  • When ordering a Blueprint and providing a Blueprint, Group, Environment, OS Build, or Application.

Global IDs have the following limitations:

  • Global IDs can not be used when specifying the Group and Environment for a server modification or decommissioning order.

Transitioning to Global IDs

In 9.1 and greater, Global IDs are automatically assigned to objects. In order to take advantage of the consistency of Global IDs, a transition process is required. The process to ensure Global IDs are consistent across multiple recently-upgraded CloudBolt instances depends on the object type.

After upgrading, all instances of included object types will have new Global IDs. CloudBolt does not have a mechanism to know which object instances in different CloudBolt servers should have the same Global ID, so you must configure them yourself.

In these examples, there are two CloudBolt instances: a Development environment and a Production environment.

Blueprints and Environments

Use the below steps for transitioning Blueprints. The transition steps for Environments are the same, but performed through the Environments pages. This process must be repeated for each Blueprint or Environment you wish to access and/or order through the API using its Global ID.

  1. In your Development environment, click Catalog.
  2. Select the Blueprint you would like to have matching Global IDs.
  3. Click Manage Blueprint.
  4. In the Overview tab, click Export. Choose Export with instance-specific info from this CloudBolt instance.
  5. Navigate to your Production environment.
  6. Select the same Blueprint you exported from the Development environment.
  7. Click Delete to remove the matching Blueprint that doesn’t have the same Global ID as your Development environment.
  8. Click back to the Catalog main page.
  9. Click Upload.
  10. Click Choose File and select the zip file you just exported. Click Save. You will now have a Blueprint on each CloudBolt instance with matching Global IDs.

Groups

Global IDs for Groups can be updated using shell_plus on the Production server to match the Global IDs in the Development server. See the suggested steps below:

  1. SSH to the Development server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  2. Run the script below to capture a dictionary mapping of the Global ID for each Group name on your Development sever. It includes the name of the parent Group (when one exists), because Group names are only forced to be unique in combination with their parent’s name.

    group_dict = {}
    for group in Group.objects.all():
        group_name = group.name
        if group.parent:
            group_name = '{}/{}'.format(group.parent.name, group_name)
        group_dict[group_name] = group.global_id
    
  3. Copy the resulting dictionary (group_dict) somewhere you can access it from your Production server.

  4. SSH to the Production server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  5. Set a variable called group_dict to the dictionary you captured from the Development server. Example:

    group_dict = {'Bonds': 'GRP-y1girt9h', 'Bonds/sub-Bonds': 'GRP-uznv72nq'}
    
  6. Run the script below to find every Group with a name (in combination with any parent’s name to improve uniqueness) in the dictionary from your Development server that exists in the Production server and set its Global ID to the correct value.

    for group_name, global_id in group_dict.items():
        group_name_parts = group_name.split('/')
        parent_name = None
        name = group_name_parts[-1]
        if len(group_name_parts) == 2:
            parent_name = group_name_parts[0]
        group = Group.objects.filter(name=name, parent__name=parent_name).first()
        if group:
            group.global_id = global_id
            group.save()
    

OS Builds

Global IDs for OS Builds can be updated in shell_plus on the Production server to match the Global IDs found on the Development server. See the suggested steps below:

  1. SSH to the Development server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  2. Run the script below to capture a dictionary mapping of the Global ID for each OS Build name on your Development server.

    osbuild_dict = {}
    for osbuild in OSBuild.objects.all():
        osbuild_dict[osbuild.name] = osbuild.global_id
    
  3. Copy the resulting dictionary (osbuild_dict) somewhere accessible from your Production server.

  4. SSH to the Production server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  5. Set a variable called osbuild_dict to the dictionary you captured from the Development server. Example:

    osbuild_dict = {'CentOS 6.6': 'OSB-hotoh6mk', 'Windows 2008': 'OSB-zqlnfxq1'}
    
  6. Run the script below to find every OS Build with a name in the dictionary from your Development server that exists in the Production server and set its Global ID to the correct value.

    for osbuild_name, global_id in osbuild_dict.items():
        osbuild = OSBuild.objects.filter(name=osbuild_name).first()
        if osbuild:
            osbuild.global_id = global_id
            osbuild.save()
    

Applications

Global IDs for Applications can be updated in shell_plus on the Production server to match the Global IDs found on the Development server. See the suggested steps below:

  1. SSH to the Development server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  2. Run the script below to capture a dictionary mapping of the Global ID for each Application name on your Development server.

    app_dict = {}
    for app in Application.objects.all():
        app_dict[app.name] = app.global_id
    
  3. Copy the resulting dictionary (app_dict) somewhere you can access it from your Production server.

  4. SSH to the Production server and open shell_plus (/opt/cloudbolt/manage.py shell_plus).

  5. Set a variable called app_dict to the dictionary you captured from the Development server. Example:

    app_dict = {'http': 'APP-ixn4oyi9', 'mysql': 'APP-x9ls2l2k'}
    
  6. Run the script below to find every Application with a name in the dictionary from your Development server that exists in the Production server and set its Global ID to the correct value.

    for app_name, global_id in app_dict.items():
        app = Application.objects.filter(name=app_name).first()
        if app:
            app.global_id = global_id
            app.save()
    

Relationships & Properties

Resources contain relationships and properties (see “Format of HTTP success bodies (HAL)” for their representation).

  • relationships: Expose related resources (example: a server resource has an “owner” relationship that points to a user resource).
  • properties: Are data attached to a resource that are not resources themselves (example: a server has a “mem_size” property that is a simple numerical value).

Format of HTTP success bodies (HAL)

When a request for a CloudBolt API resource is successful, CloudBolt responds with an application/hal+json document. HAL stands for “Hypertext Application Language”, and defines a JSON-compliant format for expressing hyperlinks in APIs. The HAL IETF spec: http://tools.ietf.org/html/draft-kelly-json-hal-06.

Using HAL gives these benefits:

  • A well-defined response format (so we don’t have to invent/document our own).
  • Simple discovery/traversal of relationships.
  • Clients that don’t need to know how to build URLs — only follow relationships. This reduces client/server coupling down to an interface of relationships.
  • Mechanism for including partials of related resources so they don’t have to be requested separately in many cases (imagine pre-fetching and Django ORM’s select_related).
  • No need to update HAL-aware API clients when new relations or URLs are added or changed — the new relations will be immediately available for use.
  • Interactive point-and-click browsing of our API.

Format of HTTP error bodies

{
  "status_code": 400-500,
  "detail": "Human readable error description",
  "error": "String representation of error",
}

Getting Started

Developers should feel free to interact with the API using any clients, libraries or tools that support making http requests. An example of retrieving the top level collections available using cURL, would look something like this, for instance:

$ curl -X POST -H "Content-Type: application/json" -d '{"username": "[username]", "password": "[password]"}' --insecure  https://[cb_server]/api/v2/api-token-auth/ -o token.txt
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current  Dload  Upload   Total   Spent    Left  Speed
100   243  100   197  100    46    542    126 --:--:-- --:--:-- --:--:--   542
$ cat token.txt | python -mjson.tool
{
    "token": "[encrypted_token_value]"
}
$ curl -H "Authorization: Bearer [encrypted_token_value]"--insecure https://[cb_server]/api/v2/ -o collections.txt
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current  Dload  Upload   Total   Spent    Left  Speed
113   226    0   226    0     0   1336      0 --:--:-- --:--:-- --:--:--  1345
$ cat collections.txt | python -mjson.tool
{
  "jobs": "/api/v2/jobs/",
  "users": "/api/v2/users/",
  "rules": "/api/v2/rules/",
  "blueprints": "/api/v2/blueprints/",
  "recurring-jobs": "/api/v2/recurring-jobs/",
  "server-actions": "/api/v2/server-actions/",
  "environments": "/api/v2/environments/",
  "servers": "/api/v2/servers/",
  "orchestration-actions": "/api/v2/orchestration-actions/",
  "applications": "/api/v2/applications/",
  "resource-actions": "/api/v2/resource-actions/",
  "actions": "/api/v2/actions/",
  "groups": "/api/v2/groups/",
  "resources": "/api/v2/resources/",
  "os-builds": "/api/v2/os-builds/",
  "orders": "/api/v2/orders/",
  "resource-types": "/api/v2/resource-types/",
  "resource-handlers": "/api/v2/resource-handlers/"
}

Out-Of-The-Box API Tools

CloudBolt ships with tools to help you quick-start developing API consumable resources:

  • An API version that can be browsed.

    To explore the available collections, resources and actions, Click Admin > System > API Browser.

    ../../_images/api-Browser.png
  • A sample API client you can download here.

To use the sample Python scripts:

  1. Unpack the zip on a server with Python 2.6, 2.7, or 3.x
  2. cd api_samples/python_client/samples/
  3. Run ./order_blueprint.py -h
  4. Determine which IDs to use and parameters to pass. One easy way to do this is to submit an order from the CloudBolt web UI, then navigate to that order in the API browser (ex. /api/v2/orders/<your_order_id/>), and inspect the items in the order.

To use the sample Python client module to make API calls from an interactive Python shell:

  1. cd api_samples/python_client
  2. type: python to start the Python interpreter, and enter the following code:
>>> from api_client import CloudBoltAPIClient
>>> username = "YOUR_USERNAME"
>>> password = "YOUR_PASSWORD"
>>> hostname = "CB_HOST_NAME"
>>> c = CloudBoltAPIClient(username, password, host=hostname, port=443, protocol="https")
>>> c.get('/v2')
{
    "actions": "/api/v2/actions/",
    "applications": "/api/v2/applications/",
    "environments": "/api/v2/environments/",
    "groups": "/api/v2/groups/",
    "jobs": "/api/v2/jobs/",
    "orchestration-actions": "/api/v2/orchestration-actions/",
    "orders": "/api/v2/orders/",
    "os-builds": "/api/v2/os-builds/",
    "resource-types": "/api/v2/resource-types/",
    "resource-handlers": "/api/v2/resource-handlers/"
    "servers": "/api/v2/servers/",
    "server-actions": "/api/v2/server-actions/",
    "resources": "/api/v2/resources/",
    "resource-actions": "/api/v2/resource-actions/",
    "blueprints": "/api/v2/blueprints/",
    "recurring-jobs": "/api/v2/recurring-jobs/",
    "users": "/api/v2/users/",
    "rules": "/api/v2/rules/",
}

To adjust the maximum page size of the results:

  1. In your customer_settings.py file, add the following to adjust maximum page size:

    from settings import REST_FRAMEWORK
    
    REST_FRAMEWORK['MAX_PAGE_SIZE'] = ###
    
  2. Add the ?page_size=### tag to the API request for the page size you would like.

Using AD/LDAP Credentials For API Requests

CB API Requests are subject to the same permissions and authentication rules as web portal users. In order to use your AD/LDAP integration for API calls simply use the domain keyword argument. To make API calls using the jdoe account on domain example.com, the sample python client should be initialized as:

>>> from api_client import CloudBoltAPIClient
>>> username = "jdoe"
>>> password = "jdoe_directory_password"
>>> domain = "example.com"
>>> hostname = "CB_HOST_NAME"
>>> c = CloudBoltAPIClient(username, password, domain=domain, host=hostname, port=443, protocol="https")

Sample Use Cases

This section illustrates how to interact with the API with a list of ordered steps that could be used for different actions. Sample requests and responses are demonstrated with the use of the Python client described in the previous section.

Ordering a New Server

  1. Get your user id from your profile view in the web UI.

  2. Get groups available to the currently authenticated user.

    >>> c.get("/api/v2/users/2/orderable-groups")
    {
        "links": {
            "self": {
            "href": "/api/v2/users/2/orderable-groups/",
            "title": "Orderable Groups Where '[user name]' Is A Requestor"
            }
        },
        "_embedded": [
            {
                "link": {
                    "self": {
                        "href": "/api/v2/groups/GRP-2345abcd",
                        "title": "Group Foo"
                    }
                },
                "name": "Group Foo"
            },
            {
                "link": {
                    "self": {
                        "href": "/api/v2/groups/GRP-3abc4def",
                        "title": "Group Bar"
                    }
                },
                "name": "Group Bar"
            }
        ]
    }
    
  3. Select a Group (Foo, Global ID: GRP-2345abcd)

  4. Get Environments available for the Group.

    >>> c.get("/api/v2/groups/GRP-2345abcd/orderable-environments")
    {
        "links": {
            "self": {
                "href": "/api/v2/groups/GRP-2345abcd/orderable-environments/",
                "title": "Orderable Environments For CB"
            }
        },
        "_embedded": [
            {
                "link": {
                    "self": {
                        "href": "/api/v2/environments/BP-2abc4def",
                        "title": "Advanced Environment"
                    }
                },
                "name": "Advanced Environment"
            },
            {
                "link": {
                    "self": {
                        "href": "/api/v2/environments/BP-3xyz4567",
                        "title": "Simple Environment"
                    }
                },
                "name": "Simple Environment"
            }
        ]
    }
    
  5. Select an environment (‘Simple Environment’, Global ID: BP-3xyz4567)

  6. Create an order to provision a custom server. This is done by submitting an order for the Blueprint called “Custom Server”.

Note

You can place an order on behalf of another user by passing “recipient” key with that user’s ID as a value in the order payload. For example: "recipient": "/api/v2/users/3"

Tip

One way to get familiar with the body of the request is to submit a Custom Server order in the CB web UI, then click the API… button on the order details page. The dialog that appears will contain the body of the request, which you can copy and paste, then tailor to your needs.

>>> body = """
... {
...     "group": "/api/v2/groups/GRP-2345abcd",
...     "recipient": "/api/v2/users/2",
...     "submit-now": "true",
...     "items": {
...         "deploy-items": [
...             {
...                 "blueprint": "/api/v2/blueprints/<Global ID of the Custom Server Blueprint>",
...                 "blueprint-items-arguments": {
...                     "build-item-Server": {
...                         "attributes": {
...                             "quantity": 1
...                         },
...                         "environment": "/api/v2/environments/BP-3xyz4567",
...                         "os-build": "/api/v2/os-builds/OSB-zyxwvut1",
...                         "parameters": {
...                             "expiration-date": "2019-12-19",
...                             "vm-size": "small"
...                         }
...                     }
...                 },
...                 "resource-name": ""
...             }
...         ]
...     },
... }"""
>>> c.post("/api/v2/orders/", body=body)
{
    "_links": {
        "self": {
            "href": "/api/v2/orders/1",
            "title": "Order id 1"
        },
        "group": {
            "href": "/api/v2/groups/GRP-2345abcd",
            "title": "CB"
        },
        "owner": {
            "href": "/api/v2/users/2",
            "title": "User id 2"
        },
        "approved-by": {
            "href": "/api/v2/users/2",
            "title": "User id 2"
        },
        "actions": [
            {
                "duplicate": {
                    "href": "/api/v2/orders/1/actions/duplicate",
                    "title": "Duplicate 'Order id 1'"
                }
            }
        ],
    },
    "name": "Installation of Custom Server",
    "status": "ACTIVE",
    "rate": "0.00/month",
    "create-date": "2019-03-13T14:26:41",
    "approve-date": "2019-03-13T15:53:47",
    "items": {
        {'deploy-items': [
            {'blueprint': '/api/v2/blueprints/BP-a123b456',
            'blueprint-items-arguments': {
                'build-item-Server': {
                    'attributes': {'quantity': 1},
                    'environment': '/api/v2/environments/BP-3xyz4567',
                    'os-build': '/api/v2/os-builds/OSB-zyxwvut1',
                    'parameters': {
                        'expiration-date': '2019-12-19',
                        'vm-size': 'small'
                    }
                }
            },
        'resource-name': 'Custom Server'}
        ]}
    }
}

At this point, the order has been submitted and auto-approved and the job that creates the server has been started.

Modifying a Server

Add a mod-item to an unsubmitted order:

>>> body = """
... {
...     "environment": "/api/v2/environments/3",
...     "server": "/api/v2/servers/1",
...     "parameters": {
...         "mem_size": "2 GB"
        }
... }"""
>>> c.post("/api/v2/orders/2/mod-items/", body=body)
{
    "_links": {
        "self": {
            "href": "/api/v2/orders/2",
            "title": "Order id 2"
        },
        "group": {
            "href": "/api/v2/groups/2",
            "title": "CB"
        },
        "owner": {
            "href": "/api/v2/users/2",
            "title": "User id 2"
        },
        "actions": [
            {
                "submit": {
                    "href": "/api/v2/orders/2/actions/submit",
                    "title": "Submit 'Order id 2'"
                }
            },
            {
                "cancel": {
                    "href": "/api/v2/orders/2/actions/cancel",
                    "title": "Cancel 'Order id 2'"
                }
            }
        ]
    },
    "summary": "Modification of demo-api.cloudboltsw.com",
    "status": "CART",
    "rate": "0.00/month",
    "create-date": "2014-03-18T09:03:15",
    "items": {
        "mod-items": [
            {
                "environment": "/api/v2/environments/3",
                "server": "/api/v2/servers/1",
                "delta": {
                    "Mem Size": "1 GB -> 2 GB"
                }
            }
        ]
    }
}

Adding New Disks to a Server

Add a mod-item to an unsubmitted order:

>>> body = """
... {
...     "environment": "/api/v2/environments/3",
...     "server": "/api/v2/servers/1",
...     "parameters": {
...         "new_disk_size": "5 GB"
        }
... }"""
>>> c.post("/api/v2/orders/2/mod-items/", body=body)
{
    "_links": {
        "self": {
            "href": "/api/v2/orders/2",
             "title": "Order id 2"
        },
        "group": {
            "href": "/api/v2/groups/2",
            "title": "CB"
        },
        "owner": {
            "href": "/api/v2/users/2",
            "title": "User id 2"
        },
        "actions": [
            {
                "submit": {
                    "href": "/api/v2/orders/2/actions/submit",
                    "title": "Submit 'Order id 2'"
                }
            },
            {
                "cancel": {
                    "href": "/api/v2/orders/2/actions/cancel",
                    "title": "Cancel 'Order id 2'"
                }
            }
        ]
    },
    "summary": "Modification of demo-api.cloudboltsw.com",
    "status": "CART",
    "rate": "0.00/month",
    "create-date": "2014-03-18T09:03:15",
    "items": {
        "mod-items": [
            {
                "environment": "/api/v2/environments/3",
                "server": "/api/v2/servers/1",
                "delta": {}
            }
        ]
    }
}

Deleting a Server

Create a decommission order:

>>> body = """
... {
...    "group": "/api/v2/groups/2",
...    "items": {
...        "decom-items": [
...            {
...                "environment": "/api/v2/environments/3",
...                "servers": [
...                    "/api/v2/servers/1"
...                ]
...            }
...        ]
...    }
... }"""
>>> c.post("/api/v2/orders/", body=body)
{
    "_links": {
        "self": {
            "href": "/api/v2/orders/3",
             "title": "Order id 3"
        },
        "group": {
            "href": "/api/v2/groups/2",
            "title": "CB"
        },
        "owner": {
            "href": "/api/v2/users/2",
            "title": "User id 2"
        },
        "actions": [
            {
                "submit": {
                    "href": "/api/v2/orders/3/actions/submit",
                    "title": "Submit 'Order id 3'"
                }
            },
            {
                "cancel": {
                    "href": "/api/v2/orders/3/actions/cancel",
                    "title": "Cancel 'Order id 3'"
                }
            }
        ]
    },
    "summary": "Deletion of demo-api.cloudboltsw.com",
    "status": "CART",
    "rate": "0.00/month",
    "create-date": "2014-03-18T09:03:15",
    "items": {
        "decom-items": [
            {
                "environment": "/api/v2/environments/3",
                "servers": [
                    {
                        "href": "/api/v2/servers/1",
                        "title": "demo-api.cloudboltsw.com"
                    }
                ]
            }
        ]
    }
}

Selected Recipes

Importing Templates Via API

CloudBolt provides the ability to import templates via the API for specific Resource Handlers. Currently, only VMWare is supported.

Templates can be assigned to zero or more Environments upon import, and can be assigned to an existing OS Build if desired.

The requested template must be available to the Resource Handler, otherwise the HTTP request will fail and return an error.

Simple Example:

curl -X POST \
  http://[cb_server]/api/v2/resource-handlers/[resource-handler-ID]/import-template/ \
  -H 'Authorization: [encrypted_token_value]' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' \
  -d '{
    "template": "templatename",
    "environment": "envname",
    "os-build": "osbuildname"

}'

Environments

Users can assign a template to zero or more Environments that are available to the Resource Handler. To achieve these options, assign the environment key in your JSON POST data as detailed below:

  • 0 Environments: Omit the environment key;
  • 1 Environment: Pass a single string (e.g. "myenv");
  • 1+ Environments: Pass a list of strings (e.g. ["myenv1", "myenv2"]).

If multiple environments are requested and assigning the template to any environment succeeds, the POST request will succeed. You will, however, be notified in the HTTP response which environments failed.

# One Environment

{
    "template": "templatename",
    "environment": "myenv"
}

# Multiple Environments

{
    "template": "templatename",
    "environment": ["myenv1", "myenv2"]
}

OS Builds

  • Imported templates can be assigned to an existing OS Build. If the requested OS Build already has a template associated with it for the requested Resource Handler, the new template (from the API request) will replace the original template.
  • If an OS Build is specified but it doesn’t already exist in your CloudBolt, a new OS Build will be created with the requested name.
  • If an OS Build is not specified in the POST request, CloudBolt will use the default (or template) name and create a new OS Build.

Multiple Templates

  • Multiple templates can be imported using the same API call. To accomplish this, pass a list of JSON dictionaries that match the format specified above.
  • If a single POST request contains two or more templates with identical names, or two or more OS Builds with identical names, the request will fail and the error message returned by the response will explain where the naming collision occurred.
# Single Template

{
    "template": "templatename",
    "environment": "envname",
    "os-build": "osbuildname"
}

# Multiple Templates

[
    {
        "template": "templatename1",
        "environment": "envname1",
        "os-build": "osbuildname1"
    },
    {
        "template": "templatename2",
        "environment": ["envname2", "envname3"],
        "os-build": "osbuildname2"
    }
]

Viewing the Order Form Components for a Blueprint

Users can request a Blueprint Order Form be returned as a JSON payload. When making a request to this API endpoint, both a Group and Environment must be supplied as query parameters for the GET request.

If the requested Blueprint, Group, or Environment cannot be found, the request will fail.

Simple Example:

curl -X GET \
  http://[cb_server]/api/v2/blueprints/[blueprint-ID]/order-form/?group=[group-ID]&environment=[environment-ID] \
  -H 'Authorization: [encrypted_token_value]' \
  -H 'cache-control: no-cache'