Deploy Descriptor
Introduction
Control-M Automation API enables you to use Deploy Descriptor to change job definition properties in JSON format before building, deploying, or running the JSON file.
Using the Deploy Descriptor enables you to streamline your code across different environments (for example, between Development, Test, or Production). Since each Control-M environment has different properties, the Deploy Descriptor enables you to programmatically manipulate these properties.
Deploy Descriptor scenarios
The following scenarios are examples of the typical usage of Deploy Descriptors.
Moving from a Test to Production Environment:
In the following example, the Property element defines the job property that is going to be modified. The Deploy Descriptor changes the Control-M/Server to the new value in production using the Assign element and changes the Application and SubApplication to have a "P" (production) prefix instead of "T" (test) using the Replace element. This name change is also applied to folder names, replacing the prefix "T" with a "P".
{
"DeployDescriptor":
[
{
"Property" :"ControlmServer",
"Assign" : "ProdControlM"
},
{
"Property" :"Application",
"Replace" : [ {"T(.*)" : "P$1"} ]
},
{
"Property" :"SubApplication",
"Replace" : [ {"T(.*)" : "P$1"} ]
},
{
"ApplyOn" : {"Type":"Folder"},
"Property" : "@",
"Replace" : [ {"T(.*)" : "P$1"} ]
}
]
}
Mapping Jobs to Hosts in Different Environments
Development, Test, and Production environments rarely have the same computer resources, and you might need to distribute the jobs differently between hosts in the different environments.
In this example, we want to change the name of the host on which the job will run to "host1", only if this job is part of the Finance Application.
The Property that we want to change is "Host". The Source is the field to match — in this example, "Application". When deploying the code file from the Development environment to the Test environment, all jobs belonging to the "Finance" application will be replaced to a single host named "host1".
In the Replace syntax, the value on the left applies to the Source, and the value on the right applies to the Property.
{
"DeployDescriptor":
[
{
"Comment": "Change Host of a Job based on application.",
"ApplyOn": {"Type":"Job.*"},
"Property": "Host",
"Source": "Application",
"Replace": [ { "Finance.*":"host1"} ]
}
]
}
In the following example, when deploying the code file from the Test environment to the Production environment, each job is mapped to a different host based on its job name. See JSON path notation for the "@" syntax.
{
"DeployDescriptor":
[
{
"Comment": "Change Host of a Job based on job name.",
"Property": "Host",
"ApplyOn" : {"Type":"Job.*"},
"Source": "@",
"Replace": [
{ "FinanceJ12":"host1"},
{ "FinanceJ23":"host2"},
{ "FinanceJ45":"host3"}
]
}
]
}
Moving Back from Production to Development
1. The following command shows how to retrieve the jobs or folders from the Production environment:
>ctm deploy jobs::get -s "ctm=*&folder=*" -e ProdEnv > ProdDefinitions.json
2. The ProdDefinitions.json file contains the production job definitions.
In the following example, the Deploy Descriptor modifies the Control-M/Server property to the value in the Development environment using the Assign element and modifies the Application and SubApplication to a "D" prefix (for Development) instead of "P" (for Production) using the Replace element.
The following code example appears in the DeployDescriptor.json file:
{
"DeployDescriptor":
[
{
"Comment": "Assign Control-M server of a Job.",
"Property" :"ControlmServer",
"Assign" : "DevControlM"
},
{
"Comment": "Change Application of a Job based on its name.",
"Property" :"Application",
"Replace" : [ {"P(.*)" : "D$1"} ]
},
{
"Comment": "Change SubApplication of a Job based on its name.",
"Property" :"SubApplication",
"Replace" : [ {"P(.*)" : "D$1"} ]
}
]
}
The following command enables you to deploy the ProdDefinition.json file to the Development environment using the Deploy Descriptor to change to the development values:
>ctm deploy ProdDefinitions.json DeployDescriptor.json -e development
Debugging and Building the Deploy Descriptor
To debug Deploy Descriptor, use deploy transform to return the JSON jobs definition after processing Deploy Descriptor modifications:
>ctm deploy transform Jobs.json DeployDescriptor.json
To verify that the Deploy Descriptor is valid, you can use build :
>ctm build DeployDescriptor.json
Using JSON Path to Locate Attributes
The code elements can be located using JSON Path syntax and the following extensions:
- "@" - refers to the name of an element for which you can define a custom name; for example, the name of a Job, Folder, or Subfolder, as well as the name of an Event or any other nested object.
- .parent() - refers to the name of the parent element in the JSON.
"." - enables you to navigate between the elements.
NOTE: If the element name contains a dash "-", use bracket notation instead of dot notation. For example, to locate a job named JOB-NAME in a folder, use $['JOB-NAME'] instead of $.JOB-NAME.
The following example shows "@" that is used to refer to the job name, @.parent() is used to refer to Folder name, and $.PreCommands.FailJobOnCommandFailure allows you to describe a specific job property value:
{
"DeployDescriptor":
[
{
"ApplyOn" : {
"Type":"Job",
"@" : "JobTQ.*",
"@.parent()" : "FolderTQ.*",
"$.PreCommands.FailJobOnCommandFailure" : "True"
},
"Property":"Application",
"Assign": "App1"
}
]
}
The following example demonstrates a more complex scenario for replacing names of elements for deployment of code from a Test environment to a Production environment, with deep changes in folder and subfolder structure:
{
"DeployDescriptor": [
{
"Comment": "Changes the name of all subfolders to match the production standard",
"Property": "@",
"ApplyOn": {
"Type": "SubFolder"
},
"Replace": [{
"(.*)#(.*)": "Prod$1_$2"
}]
},
{
"Comment": "Changes the name of dummy jobs to match the production standard",
"Property": "@",
"ApplyOn": {
"Type": "Job:Dummy"
},
"Replace": [{
"(.*)#(.*)": "JOBDummy_$2"
}]
},
{
"Comment": "Assigns the name of the production ControlmServer to all elements that have this property.",
"Property": "ControlmServer",
"Assign": "LocalControlM"
},
{
"Comment": "Assigns the RunAs property to the correct user for all jobs in the folder and subfolders.",
"Property": "RunAs",
"Assign": "ctmdk"
},
{
"Comment": "Changes all resources to match the production standard ",
"Property": "@",
"ApplyOn": {
"Type": "Resource.*"
},
"Replace": [{
"TST(.*)": "Prod$1"
}]
},
{
"Property": "Description",
"Comment": "Assigns a new description to a specific subfolder.",
"ApplyOn": {
"Type": "SubFolder",
"@": "Folder#3"
},
"Assign": "NewDescription"
}
]
}
Using Regular Expression Patterns for Matching and Modifying Values
You can use Regular Expressions (regex) to match values of job properties. The following example modifies the names of all Applications that start with "A" by adding "Was" to the current Application name. When using a regex set, use $Number for the ordered matched elements.
For more information on how to use the ApplyOn filtering, see ApplyOn.
{
"DeployDescriptor":
[
{
"ApplyOn" : {
"Application" : "A.*"
},
"Property":"Application",
"Replace": [ {"(.*)" : "Was$1"} ]
}
]
}
DeployDescriptor Code Syntax
DeployDescriptor is the root element, and it includes one or more rules. The rules are applied in the order that they appear in the file.
The following example shows how one rule modifies Application name and the next rule evaluates the Application name property that was modified and modifies it once more:
{
"DeployDescriptor":
[
{
"Property" :"Application",
"Replace" : [ {"P(.*)" : "D$1"} ]
},
{
"Property" :"Application",
"Replace" : [ {"D(.*)" : "T$1"} ]
}
]
}
Rule
A rule defines the property to modify and how to modify it.
The rule has two parts:
- Filter capabilities using the ApplyOn element (optional)
- Modification capabilities, defined by Property, Assign, Replace, and Source
The following example presents a rule that includes the filter and modification capabilities:
{
"ApplyOn" : {
"Comment": "This is the filtering element",
"Type" : "Job:Hadoop:Spark:Python",
"Application" : "a.*"
},
"Comment": "The following are the modification elements",
"Property":"Application",
"Replace": [ { "(.*)" : "Was$1" } ]
}
Filtering
ApplyOn
ApplyOn filters the JSON objects to which the rule applies.
The following example shows how ApplyOn is used to filter only jobs that are of type Hadoop Spark Python, in which the Application name starts with "a" and the $.PreCommands.FailJobOnCommandFailure is set to true.
The rule appends "Was" to the name of the Application property.
{
"DeployDescriptor":
[
{
"ApplyOn" : {
"Type" : "Job:Hadoop:Spark:Python",
"Application" : "a.*",
"$.PreCommands.FailJobOnCommandFailure" : "True"
},
"Property":"Application",
"Replace": [ { "(.*)" : "Was$1" } ]
}
]
}
The ApplyOn can filter on multiple properties at once. A single property filter has the following parts:
Description | |
Name | The JSON path to locate a property in the definition file |
Value | The regular expression for matching the property value |
Modifying
Property
The Property element specifies the property to update. This element is mandatory.
Property element uses JSON path to locate the property in the definition file.
The following example shows you how to modify the Application property.
{
"Property":"Application",
"Replace": [ { "(.*)" : "Was$1" } ]
}
Assign
Assign enables you to set a new value to the specified Property . Assign is only used to update an existing property and cannot be used to add a property to an element.
The following example shows how to use Assign, to set SparkScript to "/home/etc/script.py" property in the definitions file.
{
"Property": "SparkScript",
"Assign": "/home/etc/script.py"
}
Replace
Replace enables you to modify the value of the specified Property.
Replace contains one or more replacement rules. The first rule that matches the property's original value is applied.
{
"Property":"Application",
"Replace": [ { "FNC_JOB15_WIN" : "FNC_JOB15" },
{ "FNC_JOB16_WIN" : "FNC_JOB16" }
]
}
The Replace rule that matches the original value, modifies the Property value using a regular expression mechanism.
The original value is taken from the Property by default.
If Source is defined, the value is taken from the Source . The Source has the following parts:
Description | |
Name | The regular expression to match the original value |
Value | The regular expression to format the new value When using a regex set, you can use $Number for the ordered matched elements. |
A definition file contains two jobs where the Application property for the first job is "FNC_JOB15_WIN" and "FNC_JOB16_WIN" for the second job.
The following example shows a Replace rule where "FNC_JOB15_WIN" is replaced with "FNC_JOB15" and "FNC_JOB16_WIN" is replaced with "FNC_JOB16":
{
"Property":"Application",
"Replace": [ { "FNC_JOB15_WIN" : "FNC_JOB15" },
{ "FNC_JOB16_WIN" : "FNC_JOB16" }
]
}
The following example shows a Replace rule where "FNC_JOB15_WIN" is replaced with "FNC_APP" and "FNC_JOB16_WIN" is replaced with "FNC_APP":
{
"Property":"Application",
"Replace": [ { "FNC_.*" : "FNC_APP" } ]
}
The following example shows a Replace rule where "FNC_JOB15_WIN is replaced with "FNC-WIN- JOB15" and "FNC_JOB16_WIN" is replaced with "FNC-WIN-JOB16":
{
"Property":"Application",
"Replace": [ { "FNC_(.*)_(.*)" : "FNC-$2-$1" } ]
}
Source
If Source is defined, the Replace original value is taken from the Source. Source value uses JSON path to locate the property in the definition file.
The following example shows how to modify the "Host" property, based on the value of the job name. All job names that start with "Spark" are modified to run on "host1", jobs that start with "MyA" are modified to run on "host2" and all other jobs are modified to run on "host3".
{
"Property": "Host",
"Source": "@",
"Replace": [
{ "Spark.*": "host1"},
{ "MyA.*" : "host2"},
{ ".*" : "host3"}
]
}
Comment
Allows you to add comments in the Deploy Descriptor JSON. This element is optional.
The following example shows how to add a comment:
{
"Comment" : "Change the run as property according to the application and the name of the object",
"ApplyOn" : {
"$.Application" : "m.*",
"@" : "F.*1"
},
"Property": "RunAs",
"Assign": "prodUser"
}
Related information
For more information about Control-M, use the following resources:
Comments
Log in or register to comment.