Automating Code Deployment

This tutorial teaches you how to use a script to automate DevOps tasks. In order to complete this tutorial, you need a valid Control-M endpoint and API token, or an endpoint with a username and password.

Before You Begin

  • Ensure that Control-M Automation API is set up, as described in Control-M Automation API Installation.

  • Ensure that Git is installed, which can be obtained from Git Downloads.

  • Run the following command to verify that you have local copies of the tutorial samples from GitHub and the source code:

    git clone https://github.com/controlm/automation-api-quickstart.git

Begin

  1. Add an environment named ciEnvironment using the environment add command.

    The following command specifies a valid API token, as described in Authentication Service.

    Copy
    ctm environment add ciEnvironment "https://<controlmEndPointHost>:8443/automation-api" "<token>"

    The following command and response show how to add an environment using a username and password (instead of an API token). In this case, it is a workbench environment, so the endpoint is on the localhost and the username and password are both workbench.

    Copy
    > ctm environment add ciEnvironment "https://[controlmEndPointHost]:8443/automation-api" "workbench" "workbench"
     
    info:    Environment 'ciEnvironment' was created
    info:    ciEnvironment:
    {"endPoint":"https://localhost:8443/automation-api","workbench":"workbench"}
  2. Access the tutorial sample with the following command:

    cd automation-api-quickstart/control-m/102-automate-code-deployment

  3. Deploy the code to the ciEnvironment using the deploy command.

    Include the "-e" option in the command to specify a destination environment that differs from the default environment.

    Ensure that the version of the destination environment matches the version of the CLI.

    The following example shows a deploy command with a response:

    Copy
    > ctm deploy AutomationAPISampleFlow.json -e ciEnvironment
     
    [
       {
          "deploymentFile": "AutomationAPISampleFlow.json",
          "successfulFoldersCount": 0,
          "successfulSmartFoldersCount": 1,
          "successfulSubFoldersCount": 0,
          "successfulJobsCount": 2,
          "successfulConnectionProfilesCount": 0,
          "successfulDriversCount": 0,
          "isDeployDescriptorValid": false,
          "deployedFolders": [
             "AutomationAPISampleFlow"
          ]
       }
    ]
  4. Retrieve the jobs from the ciEnvironment to a new JSON file named ciEnvironmentJobs.json by running the following deploy jobs::get command:

    Copy
    ctm deploy jobs::get -s "server=*&folder=*" -e ciEnvironment > ciEnvironmentJobs.json
  5. Apply a Deploy Descriptor to the ciEnvironmentJobs.json using the following deploy transform command:

    Copy
    ctm deploy transform ciEnvironmentJobs.json DeployDescriptor.json -e workbench

    The Deploy Descriptor enables you to modify the jobs so that you can deploy them back to your Development environment (workbench). The modifications are necessary because the two environments (ciEnvironment and the Development environment) differ in their resources. Therefore, the following Deploy Descriptor contains rules to do the following:

    • Modify the Host property value to "workbench" (the host in the Development environment) in any job whose name begins with "Command" or "Script".

    • Add a "Dev" prefix to the Application property for any job in the source code.

    • Set the RunAs user to "workbench" .

    Copy
    {
       "DeployDescriptor":
       [
          {
             "Comment": "Set run as user in Defaults to the Dev automation user",
             "ApplyOn": {
                "@":"Defaults"
             },
             "Property" :"RunAs",
             "Assign" : "workbench"
          },
          {
             "Comment": "Modify Application property to comply with Development environment",
             "Property" :"Application",
             "Replace" : [ {"(.*)" : "Dev$1"} ]
          },
          {
             "Comment": "Distribute jobs across hosts available in Development environment based on job names",
             "Property": "Host",
             "Source": "@",
             "Replace": [
                { "Command.*" : "workbench"},
                { "Script.*"  : "workbench"}
             ]
          }
       ]   
    }

    The deploy transform command debugs the modifications, and the following output is returned. Note that the name of the application now begins with "Dev", and the two hosts are now "workbench" :

    Copy
    {
       "Defaults" : {
          "Application" : "DevSampleApp",
          "SubApplication" : "SampleSubApp",
          "RunAs" : "workbench",
          "Job" : {
             "When" : {
                "Months" : [ "JAN", "OCT", "DEC" ],
                "MonthDays" : [ "22", "1", "11" ],
                "WeekDays" : [ "MON", "TUE", "WED", "THU", "FRI" ],
                "FromTime" : "0300",
                "ToTime" : "2100"
             },
             "ActionIfFailure" : {
                "Type" : "If",
                "CompletionStatus" : "NOTOK",
                "mailToTeam" : {
                   "Type" : "Mail",
                   "Message" : "%%JOBNAME failed",
                   "To" : "[email protected]"
                }
             }
          }
       },
       "AutomationAPISampleFlow" : {
          "Type" : "Folder",
          "Comment" : "Code reviewed by John",
          "CommandJob" : {
             "Type" : "Job:Command",
             "Command" : "echo my 1st job",
             "Host" : "workbench"
          },
          "ScriptJob" : {
             "Type" : "Job:Script",
             "FilePath" : "SCRIPT_PATH",
             "FileName" : "SCRIPT_NAME",
             "Host" : "workbench"
          },
          "Flow" : {
             "Type" : "Flow",
             "Sequence" : [ "CommandJob", "ScriptJob" ]
          }
       }
    }
  6. Use the following deploy command to deploy the jobs to the Development environment while applying the rules from the Deploy Descriptor:

    Copy
    ctm deploy ciEnvironmentJobs.json DeployDescriptor.json -e workbench
  7. Use the following code in Jenkins to push Git changes to Control-M and automate the deployment of Control-M object definitions from the source directory to ciEnvironment:

    Copy
    #!/bin/bash
    for f in *.json; do
    echo "Deploying file $f";
    ctm deploy $f -e ciEnvironment;
    done
  8. Use the following Python script that uses the REST API to automate the deployment of Control-M object definitions from the source directory to ciEnvironment:

    Copy
    import requests  # pip install requests if you don't have it already
    import urllib3
     
    urllib3.disable_warnings() # disable warnings when creating unverified requests
     
    endPoint = 'https://<controlmEndPointHost>:8443/automation-api'
     
    user = '<ControlMUser>'
    passwd = '<ControlMPassword>'
     
    # -----------------
    # login
    r_login = requests.post(endPoint + '/session/login', json={"username": user, "password": passwd}, verify=False)
    print(r_login.content)
    print(r_login.status_code)
    if r_login.status_code != requests.codes.ok:
    exit(1)
     
    token = r_login.json()['token']
     
    # -----------------
    # Built
    uploaded_files = [
    ('definitionsFile', ('Jobs.json', open('c:\\src\ctmdk\Jobs.json', 'rb'), 'application/json'))
    ]
     
    r = requests.post(endPoint + '/deploy', files=uploaded_files, headers={'Authorization': 'Bearer ' + token}, verify=False)
     
    print(r.content)
    print(r.status_code)
     
    exit(r.status_code == requests.codes.ok)