June 25, 2020


Managing Image Templates

A variety of examples on how to work with Image Templates, aka SoftLayer_Virtual_Guest_Block_Device_Template_Group

Create an Image Template

The script creates a standard image template, it makes a call to the SoftLayer_Virtual_Guest::createArchiveTransaction method sending the IDs of the disks in the request, the response will provide an ID property which is the Transaction number until the template has been created. This will take the Virtual Guest offline for this process.

import SoftLayer
from pprint import pprint as pp


# The virtual guest ID you want to create a template

virtualGuestId = 39202937
# The name of the image template

groupName = 'fmirGroupImageTemplate'
# An optional note for the image template

note = 'an optional fmir note'

"""

Build a skeleton SoftLayer_Virtual_Guest_Block_Device object

containing the disks you want to the image.

In this case we are going take an image template of 2 disks

from the virtual machine.

"""
blockDevices = [
    {"id": 60788837},  # "complexType": "SoftLayer_Virtual_Guest_Block_Device"

    {"id": 59411427},  # "complexType": "SoftLayer_Virtual_Guest_Block_Device"

]

# Declare a new API service object

client = SoftLayer.create_client_from_env()

try:
    # Creating the transaction for the image template

    response = client.call(
        'SoftLayer_Virtual_Guest', 
        'createArchiveTransaction',
        groupName,
        blockDevices,
        note,
        id=virtualGuestId)
    pp(response)
except SoftLayer.SoftLayerAPIError as e:
    """

    # Handle or Print the SoftLayer error if there was one.

    """
    print("Unable to create the image template. \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))

List Image Templates

Using the python manager

import SoftLayer
from pprint import pprint as pp

# Declare a new API service object

client = SoftLayer.create_client_from_env()
imageManager = SoftLayer.ImageManager(client)

# Declare variables

object_mask = "mask[children[blockDevices[diskImage[softwareReferences[softwareDescription]]]]]"

result = imageManager.list_private_images(mask=object_mask)
pp(result)


Calling API Directly

Get private image template

import SoftLayer
from pprint import pprint as pp

# Declare the API client

client = SoftLayer.create_client_from_env(Y)

# declaring an object mask to get more information about the images templates

objectMask = """mask[summary, note, status[name],

storageRepository[datacenter],

transaction[transactionGroup,transactionStatus],

children[

    storageRepository[datacenter],

    blockDevices[diskImage[type]]

]]

"""


result = client.call(
    'Account',
    'getPrivateBlockDeviceTemplateGroups',
    mask=objectMask
)
pp(result)


Important Manual Pages

Update Locations

This will enable an Image Template in a selected datacenter. This is useful to do if you need to provision anything with this template, in the seleceted datacenter.

"""

Update Locations



The script create(s) transaction(s) to set the archived block device available locations.



Important manual pages:

"""
import SoftLayer

from pprint import pprint as pp

# The virtual guest ID you want to create a template

imageTemplateId = 1796623

"""

Build a skeleton of SoftLayer_Location array containing the locations identifiers.

This locations can be obtained by using 

SoftLayer_Virtual_Guest_Block_Device_Template_Group::getStorageLocations method.

"""
locations = [
    {"id": 265592 },  # Amsterdam 1

    {"id": 1004997},  # Chennai 1

    {"id": 138124},   # Dallas 5 

]

# Declare a new API service object

client = SoftLayer.create_client_from_env()

try:
    # Creating the transaction to update locations on image template

    response = client.call(
            'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
            'setAvailableLocations', 
            locations,
            id=imageTemplateId
    )
    pp(response)
except SoftLayer.SoftLayerAPIError as e:
    """

    # Handle and Print any API errors

    """
    print("Unable to update the locations. \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))

Important Manual Pages

Image from External Source

This script creates a transaction to import a disk image from an external source and creates a standard image template

Use SoftLayer_Virtual_Guest::getCreateObjectOptions() for a list of operatingSystemReferenceCode options.

For IBM Cloud Object Storage, use SoftLayer_Virtual_Guest_Block_Device_Template_Group::copyFromIcos().

"""

Create Image Template from external source

"""
import SoftLayer
from pprint import pprint as pp

# Declare the group name to be applied to the imported template

name = 'imageTemplateTest'
# Declare the note to be applied to the imported template

note = 'An optional note'

'''

Declare referenceCode of the operating system software description for the imported VHD

Some Examples: 

CENTOS_6_32, CENTOS_6_64, CENTOS_7_64,

REDHAT_6_32, REDHAT_6_64, REDHAT_7_64,

UBUNTU_12_32, UBUNTU_12_64, UBUNTU_14_32, UBUNTU_14_64,

WIN_2003-STD-SP2-5_32, WIN_2003-STD-SP2-5_64,

WIN_2008-STD-R2-SP1_64, WIN_2012-STD_64.

'''
operatingSystemReferenceCode = 'CENTOS_6_64'

'''

Define the parameters below, which refers to object storage where the image template is stored. 

It will help to build the uri.

'''
# Declare the object storage account name

objectStorageAccountName = 'SLOS307608-10'
# Declare the cluster name where the image is stored

clusterName = 'dal05'
# Declare the container name where the image is stored

containerName = 'OS'
# Declare the file name of the image stored in the object storage, it should be .vhd or 

fileName = 'testImage2.vhd-0.vhd'

"""

Creating an SoftLayer_Container_Virtual_Guest_block_Device_Template_Configuration Skeleton

which contains the information from external source

"""
configuration = {
    'name': name,
    'note': note,
    'operatingSystemReferenceCode': operatingSystemReferenceCode,
    'uri': 'swift://' + objectStorageAccountName + '@' + clusterName + '/' + containerName + '/' + fileName
}

# Declare the API client

client = SoftLayer.create_client_from_env()

try:
    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group', 
        'createFromExternalSource',
        configuration
    )
    pp(result)
except SoftLayer.SoftLayerAPIError as e:
    print("Unable to create the image template from external source: \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))
    exit(1)

Important manual pages:

Copy To External Source

This will take an existing Image Template, and copy it to an object storage repository.

For IBM Cloud Object Storage, use SoftLayer_Virtual_Guest_Block_Device_Template_Group::copyToIcos().

import SoftLayer

# Declare the image template identifier that you wish to export

imageTemplateId = 1796405

'''

Define the parameters below, which refers to object storage where the image template will be copied.

It will help to build the uri.

'''
# Declare the object storage account name

objectStorageAccountName = 'SLOS307608-10'
# Declare the cluster name where the image will be copied

clusterName = 'dal05'
# Declare the container name where the image will be copied

containerName = 'OS'
# Declare the file name of the image stored in the object storage, it should be .vhd or 

fileName = 'testImage4f.iso'

# Declare the API client

client = SoftLayer.create_client_from_env()
groupService = client['SoftLayer_Virtual_Guest_Block_Device_Template_Group']

"""

Creating an SoftLayer_Container_Virtual_Guest_block_Device_Template_Configuration Skeleton

"""
configuration = {
    'uri': 'swift://' + objectStorageAccountName + '@' + clusterName + '/' + containerName + '/' + fileName
}

try:
    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'copyToExternalSource',
        configuration,
        id=imageTemplateId
    )
    print(result)
except SoftLayer.SoftLayerAPIError as e:
    print('Unable to copy: \nfaultCode= %s, \nfaultString= %s'
          % (e.faultCode, e.faultString))
    exit(1)

Important manual pages:

Delete Image Template

Removes an image template from your account by making an API call to SoftLayer_Virtual_Guest_Block_Device_Template_Group::deleteObject

import SoftLayer

"""

The image template which you wish to delete

To get the list of images templates in your account 

call the SoftLayer_Account::getPrivateBlockDeviceTemplateGroups method

"""
imageTemplateId = 1796335

# Declare the API client

client = SoftLayer.create_client_from_env()
blockDeviceTemplateGroupService = client['SoftLayer_Virtual_Guest_Block_Device_Template_Group']

try:
    # Calling the getObject to delete the image template

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'deleteObject',
        id=imageTemplateId
    )
    print(result)
except SoftLayer.SoftLayerAPIError as e:
    """

    # Handle SoftLayer API Errors, if any..

    """
    print("Unable to delete the image template. \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))

Important Manual Pages

Add/Remove BYOL OS License Attribute

This script will Add or Remove the BYOL attribute from an Image template.

A template with the BYOL attribute will require you to provide a license after installation. A template without the BYOL attribute will have a license provided by IBM, possibly at an additional cost.

import SoftLayer
from pprint import pprint as pp

# The image template which you wish more details

imageTemplateId = 1797793

# Declaring the API client

client = SoftLayer.create_client_from_env()

try:
    # calling the deleteByolAttribute to remove OS License, this will return a boolean.


    ## REMOVE

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'deleteByolAttribute'
        id=imageTemplateId
    )

    ## ADD

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'addByolAttribute'
        id=imageTemplateId
    )

    pp(result)
except SoftLayer.SoftLayerAPIError as e:
    """

    # Handle SoftLayer API errors

    """
    print("Unable to remove OS License (BYOL) on image template: \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))

Important Manual Pages

Disable/Enable CloudInit

Sets the Cloud Init Attribute for an Image Template

import SoftLayer
from pprint import pprint as pp

# The image template which you wish more details

imageTemplateId = 1796623

# Declaring the API client

client = SoftLayer.create_client_from_env()
try:
    # calling the deleteCloudInitAttribute to disable cloudInit, this will return a boolean.


    # DISABLE

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'deleteCloudInitAttribute',
        id=imageTemplateId
    )
    # ENABLE

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'addCloudInitAttribute',
        id=imageTemplateId
    )
    pp(result)
except SoftLayer.SoftLayerAPIError as e:
    print("Unable to delete cloudInit on image template: \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))

Important Manual Pages

Get Package and Items from Image

Will return a list of packages that this image template can be ordered on.

import SoftLayer
from pprint import pprint as pp

# Declare the image template id

imageTemplateId = 429428

# Create a client instance

client = SoftLayer.Client()

# Build a SoftLayer_VIrtual_Guest_Block_Device_Template_Group object

imageTemplate = {"id": imageTemplateId}
try:
    packages = client.call(
        'SoftLayer_Product_Package',
        'getAvailablePackagesForImageTemplate',
        imageTemplate
    )
    print("============= PACKAGES ============")
    pp(packages)

    for package in packages:
        # If you already know the package you want to order from, you dont need to iterate through all possible packages.

        print("============= ITEMS for %s ============".format(package['id']))
        items = client.call(
            'SoftLayer_Product_Package',
            'getItemsFromImageTemplate',
            imageTemplate,
            id=package['id']
        )
        pp(items)
except SoftLayer.SoftLayerAPIError as e:
    print("Unable to get available packages for an image faultCode=%s, faultString=%s" % (e.faultCode, e.faultString))
    exit(1)

A example with nicer output.


# So we can talk to the SoftLayer API:

import SoftLayer
from prettytable import PrettyTable


# Declare the image template id

imageTemplateId = 33566
# Create a client instance

client = SoftLayer.Client()
# Build a SoftLayer_VIrtual_Guest_Block_Device_Template_Group object

imageTemplate = {"id": imageTemplateId}

# Declare an object mask to get prices for items

priceMask = 'mask[pricingLocationGroup[locations]]'


# Get available packages for the image template

packages = client.call(
    'SoftLayer_Product_Package',
    'getAvailablePackagesForImageTemplate',
    imageTemplate
)
for package in packages:
    # Build table

    x = PrettyTable(["Price Id", "Item Id", "Description", "Datacenters"])
    x.align["Price Id"] = "l"  # Left align city names

    x.padding_width = 1
    print('***** Package: %s *****' % package['id'])
    # Get Item Prices, in order to verify the active prices

    itemPrices = client['SoftLayer_Product_Package'].getItemPrices(id=package['id'], mask=priceMask)
    # Get Items from the image template

    items = client['SoftLayer_Product_Package'].getItemsFromImageTemplate(imageTemplate, id=package['id'])
    # We define a item verification, in order to avoid duplicate data in the loop

    itemVerication = 0
    for item in items:
        if item['id'] != itemVerication:
            for itemPrice in itemPrices:
                if itemPrice['item']['id'] == item['id']:
                    locationDC = ''
                    pack = ''
                    if 'pricingLocationGroup' in itemPrice:
                        for locations in itemPrice['pricingLocationGroup']['locations']:
                            locationDC = locationDC + ' ' + locations['longName']
                    else:
                        locationDC = 'Standard price'
                    x.add_row([itemPrice['id'], itemPrice['item']['id'], itemPrice['item']['description'], locationDC])
            itemVerication = item['id']
    print(x)


Important manual pages:

Share/Unshare Template

The script shares an image template to another account.


import SoftLayer
from pprint import pprint as pp

# The image template which you wish to share

imageTemplateId = 1796623

# the account you wish to share the image template

accountToShare = 207819

# Declare the API client

client = SoftLayer.create_client_from_env()
try:
    # Calling the permitSharingAccess method to share the image template


    # PERMIT

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'permitSharingAccess',
        accountToShare, id=imageTemplateId
        )

    # DENY

    result = client.call(
        'SoftLayer_Virtual_Guest_Block_Device_Template_Group',
        'denySharingAccess',
        accountToShare, id=imageTemplateId
        )
    pp(result)
except SoftLayer.SoftLayerAPIError as e:
    """

    # If there was an error returned from the SoftLayer API then bomb out with the

    # error message.

    """
    print("Unable to share the image template. \nfaultCode= %s, \nfaultString= %s"
          % (e.faultCode, e.faultString))


Feedback?

We would love to hear it
Open an issue