Make Change Requests Conditional

You can configure change requests to be available for deployed resources or virtual services only when those resources or virtual services meet specific conditions. Making the availability of change requests to users conditional allows you to provide change requests that are appropriate for the selected resources or virtual services and your operational needs.

The conditions you configure could be general, or very exacting, depending on your use case. For example, you could limit change requests to be available only for load balancers or services that are deployed to AWS.

However, you could also set very specific conditions. For example, consider "Delete Policy" and "Modify Policy" change requests that are created for NSX firewall policies deployed through Terraform. To prevent users from removing network-critical policies, you could set conditions so that the change requests can only be used for firewall policies categorized as “Intranet“.

Conditional change requests can be configured for resources that are inventoried by Commander and for XaaS (Anything-as-a-Service) resources:

  • Inventoried resources — These are well-known objects that appear in the Inventory tree that can be directly managed through the Admin Portal.
  • XaaS resources — These are non-inventoried, generic resources that don't appear in the Inventory tree and can't be managed directly through the Admin Portal. These include Terraform resources or generic resources that belong to AWS stacks, GCP deployments, or Azure Resource Groups.

For more information, see Generic resources.

To set conditions on change requests for XaaS resources, use the #{target.context} variable in your conditional expression, which will return a JSON object that provides the resource's identifying name and type. This information can be parsed and used to filter the changes that can be requested on the given generic resource.

For convenience, you can use the #{target.context.type} variable, which would resolve on the context type provided in the JSON (for example, a load balancer provisioned through Terraform), and the #{target.context.name} variable, which would resolve on the context name (for example, the given name of one of many provisioned load balancers).

Define conditional expressions

To set a condition, you must define a valid expression that's composed with a combination of the following elements:

  • Variables — Predefined expressions that reference Commander metadata. For a list of the available variables, see Variables Reference.
  • Operators — Symbols that indicate the mathematical, relational, or logical operations to perform in the expression. The operators must be lower case.
  • Constants — The constants used in the expression can be numbers, Booleans, or strings.

Syntax rules

Commander uses the following syntax rules for conditional expressions.

These syntax rules apply to both conditional change requests and conditional workflow steps. For more information, see Make Workflow Steps Conditional.

  • Invalid conditions are evaluated to false.
  • You must enclose each variable in quotation marks.
  • When using Boolean operators, you must enclose each condition in parentheses. For example:
    ("#{target.state}" -eq running) -and ("#{target.cloudAccount.type}" -eq amazon_aws)
  • Parameters with spaces must be enclosed in double quotation marks. For example:
    "2019/03/12 08:30"
  • Because conditions are parsed after variable substitution has occurred, if a variable value will contain spaces, the entire variable must be enclosed in double quotation marks. For example:
    "#{request.requestedServices[1].components[1].description}"
  • Escaping of characters isn't supported. Escape characters are passed as is.
  • An empty string "" is used to indicate null or not set.
  • If a variable can be resolved as a number, a Boolean entity, or a date, it will be treated as such; otherwise it will be interpreted as a string.
    • Number: A positive and negative floating point number or integer
    • Boolean: True or false, case-insensitive
    • Date: YYYY/MM/DD hh:mm:ss
  • A variable will be resolved as a date if it matches one of these patterns:

    YYYY/MM/DD hh:mm:ss

    YYYY/MM/DD hh:mm

    YYYY/MM/DD hh:

    YYYY/MM/DD

    where:

    YYYY = four-digit year

    MM = two-digit month (01=January, etc.)

    DD = two-digit day of month (01 through 31)

    hh = two digits of hour (00 through 23) (am/pm NOT allowed)

    mm = two digits of minute (00 through 59)

    ss = two digits of second (00 through 59)

  • Accuracy of date matching is determined by the specified date.

    Example 1: "#{target.settings.expiryDate}" -gt 2021/01/01 would resolve to true for VMs with an expiry date after Jan 1st, 2021 at 00:00:00.

    Example 2: "#{target.settings.expiryDate}" -lt "2021/03/12 08:30" would resolve to true for VMs with an expiry date before March 12, 2021 at 08:30:00.

    Example 3: "#{target.settings.expiryDate}" -ge "2021/04/01 13:00" would resolve to April 1st, 2021 at 1:00:00 PM or later.

  • For strings and enumerations:
    • All string comparisons are case-insensitive.
    • If the data type of a Commander variable is an enumeration, then the list of string choices is limited.
  • If the left and right side of the expression aren't the same data type, the expression will evaluate to false. For example:
    "#{target.cpuCount}" -eq true

    In this example, the data type for the left side of the expression is Integer, and the data type for the right side is Boolean, so this expression will evaluate to false.

  • If the left side of an expression can't immediately be interpreted by Commander, and the right side of the expression is a date, the left side will also be evaluated as a date. For example:
    "#{any.numeric.property}" -eq 2021/01/01

    This expression would be evaluated as two dates.

Troubleshooting

When you encounter a syntax error, ensure that your condition follows Commander's conditional expression syntax rules.

Also check for the following:

  • Mismatched and misplaced parentheses.
  • An operator without a hyphen preceding it.
  • Unclosed quotes.

Example Change Request Conditional Expressions

The following examples show how conditional expressions may be used for change requests to address a variety of use cases.

Commander inventoried resource example

  • The following conditional expression will limit change requests to inventoried objects deployed on AWS:
    "#{target.mediatorType}" -eq "Amazon Web Services"

Non-Terraform generic resource example

  • The following conditional expression will limit a change request to an asset type of AWS security group:
    "#{target.context.type} -eq "aws::securitygroup::etc"

Terraform resource examples

  • The following conditional expression will limit "Delete Policy" and "Modify Policy" change requests on NSX Firewall Policies deployed through Terraform to policies categorized as "Intranet" only. When this condition is applied, users won't be able to access change requests that might remove critical "Internet Facing" policies which protect the network.
    >“#{target.context.instances[0].attributes.category}” -eq Intranet
  • The following conditional expression will limit "Increase Load Balance Pool size" change requests to load balancers with pools where minimum number of active users is between 2 and 10 inclusive:
    (“#{target.context.instances[0].attributes.min_active_members}” -ge 2) -and (“#{target.context.instances[0].attributes.min_active_members}” -le 10)
  • The following conditional expression will limit "Backup Database" change requests to only MySQL databases deployed in AWS using Terraform:
    “#{target.context.instances[0].attributes.engine}” -eq mysql