Job and Folder Properties

[1]:
from aapi import *

Allowed arguments for both Folder, SubFolder and Jobs:

  • application: Descriptive name for a set of related Jobs, Folders or SubFolders

  • sub_application: Descriptive name for a set of related Jobs, Folders or SubFolders with a same application

  • run_as : The OS user responsible for running a job (or all jobs in a folder or subfolder). By default, jobs are run by the user account where the Control-M/Agent is installed. To specify a diferent user, the agent must be running as root

  • days_keep_active : Defines the number of days to keep a job if the job did not run at its scheduled date. You can set this property for a Job, Folder, or SubFolder. Jobs in a folder are kept until the maximum DaysKeepActive value for any of the jobs in the folder has passed. This enables you to retrieve job status of all the jobs in the folder

  • confirm : Defines a job, folder, or subfolder that requires user confirmation

  • created_by: Specifies the Control‑M user responsible for job definitions. You can define this property for a Job object or Folder object

  • description : Description of th Job, Folder or SubFolder

  • priority : Defines the priority that a job has over other jobs. You can set this property for a Job, Folder, or SubFolder

  • run_as_dummy : (boolean) Runs any job as a dummy job

  • retroactive_order : (boolean) Orders a job retroactively to make up for days on which the job did not run. For example, Control-M was down for two days due to a hardware issue; as soon as jobs can run again, this job is scheduled retroactively to run an additional two times, to make up for the days that Control-M was inactive

  • rerun : See below Rerun section

  • time_zone : Adds the time zone to jobs, folder, or subfolder. Time zones should be defined at least 48 hours before the intended execution date. We recommend to define the same time zone for all jobs in a folder

  • variables : list of variables in a key, value format. See below Variables

  • when : See below When section

  • if_list : List of If objects. See below If section

  • notify_list List of Notify objects. See below Notify

[2]:
folder = Folder('SampleFolder',
                controlm_server='ctmserver',
                site_standard='sitestd',
                business_fields=[{'Department': 'HR'}, {'Company': 'BMC'}],
                order_method=Folder.OrderMethod.Manual,
                application='ApplicationName',
                sub_application='SubApplication',
                run_as='controlm',
                when=Folder.When(week_days=['SUN']),
                active_retention_policy=Folder.ActiveRetentionPolicy.KeepAll,
                days_keep_active='41',
                confirm=True,
                created_by='user',
                description='FolderSample with lot of properties set',
                priority=Folder.Priority.High,
                rerun=Folder.Rerun(every='2'),
                rerun_limit=Folder.RerunLimit(times='3'),
                time_zone='HAW',
                variables=[{'var1': 'val'}, {'var2': 'val2'}]
                )

folder.sub_folder_list.append(
    SubFolder('MySubFolder1', job_list=[
        # this job will run as dummy, the command will not be executed
        JobCommand('MyFirstJob', command='ls', run_as_dummy=True),
        # This job is marked as 'confirm', it will not run until user confirms
        JobCommand('OtherJob', command='ls', confirm=True),
    ],
        if_list=[
        IfCompletionStatus('goodScenario', completion_status='OK', on_list=[
            ActionMail('sendMail', message='All jobs ran successfully',
                       to='team@comp.com', subject='Jobs notification')
        ]),

        IfCompletionStatus('badScenario', completion_status='NOK', on_list=[
            ActionRun('runCorrectiveJob',
                      folder='REMEDY_FOLDER', job='RemedyJob')
        ])

    ],
        notify_list=[
        NotifyNotOK(
            'alertIfNOK', destination=Notify.Destination.Alerts, message='Jobs not ok'),
        NotifyDoesNotEnd('alertIfJobIsStuck', by='1200',
                         destination=Notify.Destination.Alerts, message='Jobs didnt end'),
    ]
    )
)

When

AutomationAPI Documentation

Enables you to define scheduling parameters for Jobs, Folders and SubFolders, including the option of using calendars. If When is used in a Folder or SubFolder, those parameters apply to all Jobs in the Folder or Subfolder.

Note: Several parameters under the When parameter enable you to reference previously defined calendars.

When working in a Control-M Workbench environment, jobs will not wait for time constants and will run in an ad-hoc manner. Once deployed to a Control-M instance, all time constraints will be obeyed.

Parameters:

  • week_days

Note: Not supported in SubFolder

One or more of the following: “SUN”,”MON”,”TUE”,”WED”,”THU”,”FRI”,”SAT”

For all days of the week, use “ALL” (the default value). In addition, you can specify a specific day in a specific week of the month using a value with the following format: DdayWn

For example, DMONW2 means Monday of the 2nd week of the month. Valid values for n are 1-6.

  • months

Note: Not supported in SubFolder

One or more of the following:

“JAN”, “FEB”, “MAR”, “APR”,”MAY”,”JUN”, “JUL”, “AUG”,

“SEP”, “OCT”, “NOV”, “DEC”

For all months of the year, use “ALL” (the default value).

  • month_days

Note: Not supported in SubFolder

One or more days in the range of 1 to 31

For all days of the month, use “ALL” (the default value).

  • from_time

FromTime specifies that a job will not start before this time

Format: HHMM

  • to_time

ToTime specifies that a job will not start after this time

Format: HHMM

To allow the job to be submitted even after its original scheduling date (if it was not submitted on the original date), specify a value of “>”.

  • schedule

Note: Not supported in SubFolder

One of the following options:

- "Everyday" - scheduling is applied every day, provided that the running criteria are met
- "Never" - no scheduling is defined, and the job must be ordered manually
  • specific_dates

Note: Not supported in SubFolder

Specific dates for running jobs.

For each date, use the format “MM/DD” (enclosed in quotes). Separate multiple dates with commas.

Note: The SpecificDates option cannot be used in combination with options WeekDays, Months, or MonthDays. However, since the default for these options is “ALL”, you must specify these options with a value of “NONE”.

[3]:
when = Job.When(
    schedule='Never',
    months=['JAN', 'OCT', 'DEC'],
    month_days=['22', '1', '11'],
    week_days=['MON', 'TUE'],
    from_time='1500',
    to_time='1800'
)

# example with specific dates
when = Job.When(
    week_days=['NONE'],
    months=['NONE'],
    month_days=['NONE'],
    specific_dates=['03/10', '03/01']
)

If

AutomationAPI Documentation

If statements trigger one or more actions when job-related criteria are fulfilled (for example, the job ended with a specific status or the job failed several times).

IfCompletionStatus

Triggers actions based on job completion status. In this example, if the job runs unsuccessfully, it sends an email and runs another job. You can set this property for a Job, Folder, or SubFolder

[4]:
job = JobCommand('Job1', command='echo Hello')
job.if_list.append(
    IfCompletionStatus('action_if_failure',
                       completion_status='NOTOK',
                       on_list=[
                           ActionMail(
                               'mailToTeam', message='Job %%JOBNAME failed', to='myteam@mail.com'),
                           ActionRun('runcorrectiveJob',
                                     folder='FolderName', job='JobName')
                       ]
                       )
)

IfNumberOfReruns

Trigger an action based on number of job reruns. You can set this property for a Job, Folder, or SubFolder

[5]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfNumberOfReruns('actionByNumberOfReruns',
                     number_of_reruns='>=4',
                     on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfNumberOfFailures

Triggers an action based on number of job failures. You can set this property for a Job, Folder, or SubFolder

[6]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfNumberOfFailures('ActionByNumberOfFailures',
                       number_of_failures='1',
                       on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfJobNotSubmitted

Triggers an action based on whether the job is not submitted

[7]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfJobNotSubmitted('ActionByJobNotSubmitted',
                      on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfJobOutputNotFound

Triggers an action based on whether the job output is not found

[8]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfJobOutputNotFound('ActionByOutputNotFound',
                      on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfNumberOfExecutions

Triggers an action based on number of job executions. You can set this property for a Job, Folder, or SubFolder

[9]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfNumberOfExecutions('ActionByNumberExecutions',
                         number_of_executions='>=5',
                         on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfOutput

Triggers an action based on whether a specified string is found within the job output. You can set this property for a Job, Folder, or SubFolde

[10]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfOutput('OutputFound',
             code='myfile.sh',
             statement='ls -l',
             on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')])
)

IfVariableValue

Note: This feature requires Control-M/Enterprise Manager version 9.0.21 Triggers an action based on whether a logical condition defined for a variable value is true

[11]:
job = JobCommand('Job2', command='echo Hello')
job.if_list.append(
    IfVariableValue('VariableValue',
                    variable_name='IpAddress',
                    variable_value='1',
                    operator=IfVariableValue.Operator.EndWith,
                    on_list=[ActionRun('RunJob', folder='Folder1', job='Job1')],
                    do_list=[ActionRun('RunJob1', folder='Folder1', job='Job1')])
)

print(job.dumps_aapi(indent=2))
{
  "Type": "Job:Command",
  "VariableValue": {
    "Type": "If:VariableValue",
    "RunJob": {
      "Type": "Action:Run",
      "Folder": "Folder1",
      "Job": "Job1"
    },
    "RunJob1": {
      "Type": "Action:Run",
      "Folder": "Folder1",
      "Job": "Job1"
    },
    "VariableName": "IpAddress",
    "VariableValue": "1",
    "Operator": "EndWith"
  },
  "Command": "echo Hello"
}

If Actions

AutomationAPI Documentation

Actions that can be triggered in response to an If statement that is fulfilled

ActionMail

Action that sends an e-mail

Arguments:

  • urgency : level of urgency of the message. Default: Regular

  • subject : subject line for the message

  • message : the message text

  • to : List of recipients separated by semicolon (;)

  • cc : List of recipients who receive a copy of the message separated by semicolon (;)

  • attach_output : whether to include the job output as an email attachement

[12]:
action = ActionMail(
    'mailToTeam',
    urgency=ActionMail.Urgency.Urgent,
    subject='Completion Mail',
    message='%%JOBNAME just completed',
    to='team@comp.com',
    cc='other@comp.com',
    attach_output=True
)

ActionRerun

Action that reruns the job

[13]:
action = ActionRerun('rerunAction')

ActionSet

Action that sets a variable

[14]:
action = ActionSet('SetVariable', variable='var1', value='1')

ActionSetToOk

Action that sets the job status to OK

[15]:
action = ActionSetToOK('SetToOk')

ActionSetToNotOK

Action that sets the job status to NotOK

[16]:
action = ActionSetToNotOK('SetToNotOk')

ActionStopCyclicRun

Action that disables the cyclic attribute of the job

[17]:
action = ActionStopCyclicRun('SetToOk')

ActionRun

Action that runs another job

[18]:
action = ActionRun('CorrectiveJob',
                   folder='FolderName',
                   job='JobName',
                   controlm_server='ctmserver',
                   date='010218',
                   variables=[{'cvar1': 'val1'}, {'cvar2': 'val2'}],
                   run_as_independent_flow=True
                   )

ActionNotify

Action that sends a notification

[19]:
action = ActionNotify('NotifyAction',
                      message='job just ran',
                      destination=ActionNotify.Destination.JobLog,
                      urgency=ActionNotify.Urgency.VeryUrgent)

ActionRemedy

Action that creates a Remedy ticket

[20]:
action = ActionRemedy('RemedyTicket',
                      summary='CONTROL-M job %%JOBNAME on node %%NODEID return code %%COMPSTAT',
                      message='CONTROL-M job %%JOBNAME run %%RUNCOUNT ended on node %%NODEID return code %%COMPSTAT Application: %%APPLIC',
                      urgency=ActionRemedy.Urgency.Low
                      )

ActionOutput

Action that copies the output to a specified destination

[21]:
action = ActionOutput(
    'CopyOutput', operation=ActionOutput.Operation.Copy,
    destination='/home/copyHere')

Notify

AutomationAPI Documentaion

Create a notification for certain scenarios before, during and after job execution. You can set notifications for a Job, Folder, or SubFolder

NotifyOk

Notify if jobs is executed without errors

[22]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyOK('Notify1',
             message='Job OK',
             destination=Notify.Destination.JobLog)
)

NotifyNotOk

Notify if the job is executed with errors

[23]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyNotOK('Notify1',
             message='Job NOT OK',
             destination=Notify.Destination.Alerts)
)

NotifyDoesNotStart

Notify if the job has not started

[24]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyDoesNotStart('Notify1',
             message='Job did not start',
             by='1510',
             destination=Notify.Destination.Console)
)

NotifyExecutionTime

Notify if the execution time is different than expected

[25]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyExecutionTime('Notify1',
                        message="Job didn't complete in less than 3 minutes",
                        destination=Notify.Destination.JobLog,
                        criteria=NotifyExecutionTime.Criteria.LessThan,
                        value='3'
                        )
)

NotifyDoesNotEnd

Notify if the job does not end by the specified time

[26]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyDoesNotEnd('Notify1',
                     message="Job didn't by 12h20",
                     destination=Notify.Destination.JobLog,
                     by='1220'
                     )
)

NotifyReRun

Notify if the job reruns

[27]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyRerun('Notify1',
                message="Job reran",
                destination=Notify.Destination.JobLog
                )
)

NotifyLateCyclicSubmit

Note: This feature requires Control-M/Enterprise Manager version 9.0.21

Notify if the second or subsequent cyclic submission is late by a specified number of minutes

[28]:
job = JobCommand('Job1', command='ls -l')
job.notify_list.append(
    NotifyLateCyclicSubmit('Notify1',
                           message="Cyclic job did not submit on time",
                           destination=Notify.Destination.JobLog,
                           by='10'  # Job cyclic is late by 10 minutes
                           )
)

Resources

AutomationAPI Documentation

ResourcePool

Sets a pool (previously known as quantitative resources or semaphore) on a job, to control access to a resource that is concurrently shared by other jobs

[29]:
folder = Folder('ResourceSample',
                job_list=[
                    JobCommand('job1', command='ls', resource_list=[
                        ResourcePool('semaphore1', quantity='3')
                    ]
                    )
                ]
                )

ResourceLock

Sets a lock (previously known as a control resource or mutex) as shared or exclusive. If the resource is shared, other jobs can use the resource concurrently. If set to exclusive, the job has to wait until the resource is available before it can run. You can set a lock on a Job, Folder, or SubFolder

[30]:
folder = Folder('ResourceSample',
                job_list=[
                    JobCommand('job1', command='ls', resource_list=[
                        ResourceLock(
                            'lock1', lock_type=ResourceLock.LockType.Exclusive)
                    ]
                    )
                ]
                )

Rerun

Allows to define cyclic jobs or folders

Arguments:

  • every : The frequency at which to run the cyclic job or folder, expressed as a whole number of the specified time unit

  • units : One of the following: “Minutes” “Hours” or “Days”. The default is “Minutes”

  • from_ : Start - next run time is calculated an N Units from the start time of the current run, End - next run time is calculated as N Units from the end time of current run, Target - run starts every N units

  • times : Number of cycles to run (as a string). To run forever, define “0”

[31]:
job = JobCommand('Job1', command='ls', rerun=Job.Rerun(
    every='4',
    from_=Job.Rerun.From.End,
    times='3',
     units=Job.Rerun.Units.Days))

Variables

Events

Events can be generated by Control-M or can trigger jobs. Events are defined by a name and a date.

Here is a list of the various capabilities of event usages:

A job can wait for events before running, add events after running, or delete events after running. See WaitForEvents, AddEvents, and DeleteEvents

You can set events for a Job, Folder, or SubFolder. For “Date”, you can use the following values:

Date Type

Description

AnyDate

Any scheduled date

OrderDate

Control-M scheduled date.If you do not specify a Date value, this is the default.

PreviousOrderDate

Previous Control-M scheduled date

NextOrderDate

Next Control-M scheduled date

MMDD

Specific date Example: “0511”

WaitForEvents

The following example shows how to define events that the job must wait for before running:

[32]:
waitForEventList = WaitForEvents([Event(event="e1"), Event(event="e2"), Event(event="e3", date=Event.Date.AnyDate)])
job = JobCommand('Job1', command='echo Hello')
job.event_list.append(waitForEventList)

AddEvents

The following example shows how to specify events for the job to add after running:

[33]:
addEventListObject = AddEvents([EventOutAdd(event="e4",date=Event.Date.NoDate)])
job = JobCommand('Job1', command='echo Hello')
job.event_list.append(addEventListObject)

DeleteEvents

The following example shows how to specify events for the job to remove after running:

[34]:
deleteEventListObject = DeleteEvents([EventOutDelete(event="e5",date=Event.Date.NextOrderDate)])
job = JobCommand('Job1', command='echo Hello')
job.event_list.append(deleteEventListObject)