How to define a service catalog?

The following tutorial shows how to model the service catalog HelloWorld from the example. You can import your service catalog to the Cloud Topology Designer, or exchange it with other users. You will learn how to control it (i.e., to create, configure, start, stop, and delete) on a hosted compute node.

Step 1. Import TOSCA types

  • Create a file types.yaml
  • To import the TOSCA type definition:
imports:
- tosca-normative-types:1.0.0-ALIEN20

Step 2. Define a node type

Define a new node type (e.g., myservice.nodes.SoftwareComponent.Python) by deriving from the existing TOSCA type tosca.nodes.SoftwareComponent:

node_types:
# This is the node name, can be arbitrary
myservice.nodes.SoftwareComponent.Python:
derived_from: tosca.nodes.SoftwareComponent
# optional icon
tags:
icon: /images/python.png
important

A node type starting with otc.* is not allowed. We reserve this domain for all types defined by the Open Telekom Cloud.

By deriving from the tosca.nodes.SoftwareComponent, your component can be hosted on a compute node as follows:

The TOSCA type tosca.nodes.SoftwareComponent also comes up with the default property component_version. Therefore, the Python component also inherits this property (see Figure 1, on the right). In the editor, users can specify the value for the property.

Step 3. Define custom node properties

You can add additional properties for the Python component (e.g., add a new property hello_message from the type string). The new property is set to the default value Hello World!. The required field indicates that users have to specify a value for this property in the editor.

myservice.nodes.SoftwareComponent.Python:
...
properties:
hello_message:
description: A simple message to print
type: string
required: true
default: "Hello World!"
info

TOSCA also supports the following simple types for a property:

  • YAML Types: integer, string, boolean, float
  • TOSCA types:
    • version: (e.g., 2.0.1)
    • range (e.g., [0, 100], [ 0, UNBOUNDED ])
    • list (e.g., [ 80, 8080 ])
    • map (e.g., { "firstname": "darth", "lastname": "vader" }

Step 4. Define the interfaces

The interfaces are the implementations to control the lifecycle of the component. The orchestration engine will call the interfaces at runtime to create, configure, start, stop, and delete the component.

In the following example, we implement the start interface by providing a python script start.py. The orchestrator will call this a python script to start the HelloWorld component.

myservice.nodes.SoftwareComponent.Python:
...
properties:
hello_message:
...
interfaces:
Standard:
start:
inputs:
# the keyword SELF indicates the node itself.
msg: {get_property: [SELF, hello_message]}
implementation: scripts/start.py

The start interface has the input variable msp. It gets the value from the node property hello_message.

note
  • Use the function get_property to get the value of a node property.
  • Use the keyword SELF to reference to the current node.

The input param msp of the start interface is available as an environment variable in the python script, so you can use as follows:

# scripts/start.py
print(msg)
tip
  • We also support the following implementation scripts: python, shell script, and ansible.

Step 5. Define the output value

We can define the output result for the Python component. The outputs can be displayed in the designer after the deployment completes, or it can be used as an input value for another components or another interfaces.

  • Define an interface create with a python script (e.g., create.py):
interfaces:
Standard:
...
create:
implementation: scripts/create.py
  • Define an environment variable (e.g., myVar1) in the python script:
# scripts/create.py
from os import environ
# Set value for the enviroment variable myVar1
myVar1="Resolved {0}".format(var1)
  • Define a runtime attribute (e.g., resolvedOutput1), which gets the environment variable myVar1 from the interface create:
myservice.nodes.SoftwareComponent.Python:
...
attributes:
resolvedOutput1: { get_operation_output: [SELF, Standard, create, myVar1]}
note
  • Use the keyword attributes to define the output result of a node.
  • Use the function get_operation_output to get an output from an interface implementation.

Step 6. Package

  • To package the TOSCA definition, zip all contents (the yaml definition file and the python script).
  • Upload the zip file to the service catalog in Catalog / Manage archives / Browse.

Expected result

  • In the editor, the Python component has the properties hello_message (defined in step 2) and the attribute resolvedOutput1 (defined in step 5).
  • During the deployment, the orchestrator executes the python scripts create.py and start.py on the hosted compute.

Full example