How to define a software component?

The following example shows how to model the software component HelloWorld from the example and upload it to the service catalog of the designer. You will learn how to control the HelloWorld component to create, configure, start, stop, and delete on a hosted compute node.

Step 1. Import TOSCA types

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., otc.nodes.SoftwareComponent.Python) by deriving from the existing TOSCA type tosca.nodes.SoftwareComponent:

node_types:
# This is the node name, can be arbitrary
otc.nodes.SoftwareComponent.Python:
derived_from: tosca.nodes.SoftwareComponent

By deriving from the tosca.nodes.SoftwareComponent, the Python component can be hosted on a compute node as in Figure 1.

Figure 1: A Python component

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

We can add additional properties for the Python component by adding 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.

otc.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: 2.0.1
    • range: [0, 100], [ 0, UNBOUNDED ]
    • list: [ 80, 8080 ]
    • map: { user1: 1001, user2: 1002 }

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.

otc.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.

First, we define an environment variable (e.g., myVar1) in a python script (e.g., create.py):

# scripts/create.py
from os import environ
# Set output val using two different ways
myVar1="Resolved {0}".format(var1)

Then we define a runtime attribute (e.g., resolvedOutput1), which gets the value from the environment variable (e.g., myVar1):

interfaces:
Standard:
create:
inputs:
var1: {get_property: [SELF, outputVar1]}
implementation: scripts/create.py
attributes:
# Get the environment variable "myVar1" as an output
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.

Full example