Workflow extensions¶
Since 7.0
In 7.0 This new mechanism replaces the old workflow system in 6.4. This new version allows the admin to execute custom code or ansible when other significant events occour not just pre-and post deploy.
Refer to Managing extensions for more details on how to register and publish an extension.
Supported workflow stages¶
The following values are accepted as events (stages
) that trigger the execution of the attached tasks.
preDeploy
- Executed in the top part of the deploy graphpostDeploy
- Executed at the end of the deploy graphserverRegistered
- Executed after a server is registeredserverDecommissioned
- Executed after a server is decommissionedswitchRegistered
- Executed after a switch is registeredswitchDecommissioned
- Executed after a switch is decommissionedserverInstanceGroupCreateDNS
- Executed when DNS entries are created for servers instance groupsserverInstanceGroupUpdateDNS
- Executed when DNS entries are updated for servers instance groupsserverInstanceGroupDeleteDNS
- Executed when DNS entries are deleted for servers instance groupsserverInstanceUpdateDNS
- Executed when DNS entries are created and updated for server instancesserverInstanceDeleteDNS
- Executed when DNS entries are deleted for server instancesserverCreateDNS
- Executed when DNS entries are created for servers’s BMCsserverDeleteDNS
- Executed when DNS entries are deleted for servers’s BMCsswitchCreateDNS
- Executed when DNS entries are created for switch’s Management InterfaceswitchDeleteDNS
- Executed when DNS entries are deleted for switch’s Management Interface
Context objects¶
Additional information is provided to the task execution with contextual information that depends on the event (stage
). See below on the task types on how to access these objects.
For
serverRegistered
,serverDecommissioned
,switchRegistered
: TheServer
andNetwork
objects are available. The user can refer to the Server and NetworkDevice objects’ parameters depending on the asset that is being changed. Refer to your environment’s [API documentation].For
serverInstanceGroupCreateDNS
,serverInstanceGroupUpdateDNS
,serverInstanceGroupDeleteDN
,serverInstanceUpdateDNS
,serverInstanceDeleteDNS
: A server DNS record set object similar to this:"serverInstanceGroupDNSRecordSet": { "zone": { "zoneName": "eveng-qa02.metalcloud.io", "soaEmail": "admin.eveng-qa02.metalcloud.io", "nameServers": [ "ns1.evenq-qa02.metalcloud.io" ], "ttl": 3600, "isDefault": true }, "infrastructureId": 3870, "serverInstanceGroup": { "label": "instance-array-3386" }, "hostname": "lambda", "fqdn": "lambda.eveng-qa02.metalcloud.io", "ips": [ { "status": "allocated", "ip": "10.20.50.36" } ] }
For
serverCreateDNS
,serverDeleteDNS
an object similar to is provided invariables.json
:{ "serverDNSRecordSet": { "zone": { "zoneName": "us08.metalsoft.io", "soaEmail": "admin.us08.metalsoft.io", "nameServers": ["n1.metalsoft.io"], "ttl": 3600, "isDefault": true }, "serverId": 10, "serverSerialNumber": "serial-number", "managementAddress": "192.168.100.100", "hostname": "server-10", "fqdn": "server-10.us08.metalsoft.io", "ip": { "status": "allocated", "ip": "192.168.100.100" }, "operation": "create" } }
For
switchCreateDNS
,switchDeleteDNS
the following payload is provided:"switchDNSRecordSet": { "zone": { "zoneName": "us08.metalsoft.io", "soaEmail": "admin.us08.metalsoft.io", "nameServers": ["n1.metalsoft.io"], "ttl": 3600, "isDefault": true }, "switchId": 10, "managementAddress": "192.168.100.100", "hostname": "switch-10", "fqdn": "switch-10.us08.metalsoft.io", "ip": { "status": "allocated", "ip": "192.168.100.100" }, "operation": "create" }
Supported task types¶
The following are task types that can be used:
Ansible
taskType: ExtensionTaskAnsible
: This will execute an ansible playbook from a directory that can include multiple modules etc. provided as a zip available at a provided URL. We call this anAnsible Bundle
. TheBundle
is downloaded by the Site Controller and Ansible is invoked on the Site Controller to execute the playbook.
Note that the Ansible Runner capability and container must exist on the Site Controller.
Example:
{
"label": "create-dns-records-for-instance-group",
"taskType": "ExtensionTaskAnsible",
"options": {
"asset": "power-dns-configuration",
"playbook": "deploy_dns_flexible.yaml"
}
}
An asset of type Bundle
with the label equal to the asset
param (in the example it is power-dns-configuration
) referred in the task must exist in the assets
section of the file. For example:
"assets": [
{
"label": "power-dns-configuration",
"name": "power-dns-configuration",
"assetType": "Bundle",
"url": "https://repo.metalsoft.io/.extensions_ms/workflows/power_dns.zip"
}
],
Note that the asset will be pulled from the URL from the Site Controller and extracted in a directory before execution.
Options¶
asset
- The asset to callplaybook
- The playbook to execute that must exist within the asset bundle.executionTimeout
- Timeout for the executionexecutionTimeoutTick
- How often to retry in case of an error
Variables¶
When the Ansible bundle is executed the following variables.yaml
will be available in the directory. The content will depend on the execution stage
as described above at the Context Objects section.
HTTP request
taskType
ExtensionTaskWebhook
:Performs an HTTP request to a given endpoint with specific options.
{ "label": "testInitial", "taskType": "ExtensionTaskWebhook", "options": { "endpoint":"www.google.com", "method":"GET", "requestTemplate":"test" } }
Options
endpoint
- The endpoint to call. Must be a valid URL.method
- The method to use, one of GET, POST, PATCH, DELETEheaders
- An array of headers to send such as:headers: {"Content-type": "application/json", "header2": "value2"}
requestTemplate
- This is the payload of the request. It can be a Nunjucks (a subset of Jinja2) template. See the Context Objects for available objects according to the stage. Example:"requestTemplate": "{\"server_vendor\": {{ server.serverVendor }}, \"property2\": \"value2\"}"
expectedResponseStatuses
- This is an array of codes such as[200,201]
SSH execution Execute a command via SSH.
{
"label": "show running config",
"taskType": "ExtensionTaskSsh",
"options": {
"host": "192.168.100.100",
"port": 22,
"timeout": 1800,
"commandTemplate": "show running config"
}
}
Options¶
host
- The host to ssh toport
- The port to ssh totimeout
- The timeout for executing the commandcommandTemplate
It can be a Nunjucks (a subset of Jinja2) template.See the Context Objects for available objects according to the stage.
An end-to-end example is available here:¶
The following example includes everything including the ansible bundles
Example extension definition¶
Example extension:
{
"name": "testExtensionType",
"label": "test",
"description": "My App Description",
"kind": "workflow",
"definition": {
"kind": "ExtensionDefinition",
"schemaVersion": "1.1",
"name": "string",
"label": "string",
"extensionType": "string",
"vendor": "string",
"extensionVersion": "string",
"description": "string",
"icon": "string",
"dependencies": {
"controllerVersion": "string"
},
"inputs": [
],
"outputs": [
],
"assets": [
],
"onAssetChange": [
{
"stage": "server Registered",
"tasks": [
{
"label": "testInitial",
"taskType": "ExtensionTaskWebhook",
"options": {
"endpoint":"www.google.com",
"method":"GET",
"requestTemplate":"test"
}
}
]
}
]
}
}
More complex example¶
{
"onCreate": [
{
"stage": "preDeploy",
"tasks": [
{
"label": "string",
"taskType": "ExtensionTaskAnsible",
"options": {
"asset": "string",
"playbook": "string",
"executionTimeout": 1,
"executionTimeoutTick": 1,
"version": "string"
}
}
]
},
{
"stage": "postDeploy",
"tasks": [
{
"label": "string",
"taskType": "ExtensionTaskAnsible",
"options": {
"asset": "string",
"playbook": "string",
"executionTimeout": 1,
"executionTimeoutTick": 1,
"version": "string"
}
}
]
}
],
"onAssetChange": [
{
"stage": "serverRegistered",
"tasks": [
{
"label": "string",
"taskType": "ExtensionTaskAnsible",
"options": {
"asset": "string",
"playbook": "string",
"executionTimeout": 1,
"executionTimeoutTick": 1,
"version": "string"
}
}
]
},
{
"stage": "serverDecommissioned",
"tasks": [
{
"label": "string",
"taskType": "ExtensionTaskAnsible",
"options": {
"asset": "string",
"playbook": "string",
"executionTimeout": 1,
"executionTimeoutTick": 1,
"version": "string"
}
}
]
}
]
}