diff --git a/docs/.vuepress/pr-feed-config.json b/docs/.vuepress/pr-feed-config.json index acae4bcec..2fbd04180 100644 --- a/docs/.vuepress/pr-feed-config.json +++ b/docs/.vuepress/pr-feed-config.json @@ -3,7 +3,7 @@ "version": "5.19.0", "lastSelfHostedDate": "2026-02-02", "lastSaasRelease": "2025-01-26", - "lastSaasCut": "rba/5.20-RBA-20260218-cf38829-cdc0cba", + "lastSaasCut": "rba/5.20-RBA-20260309-570ed66-70d7d67", "description": "Last self-hosted release version and date" } } diff --git a/docs/.vuepress/public/assets/img/job-conditionals-1.png b/docs/.vuepress/public/assets/img/job-conditionals-1.png new file mode 100644 index 000000000..e44ed750c Binary files /dev/null and b/docs/.vuepress/public/assets/img/job-conditionals-1.png differ diff --git a/docs/.vuepress/public/assets/img/job-conditionals-2.png b/docs/.vuepress/public/assets/img/job-conditionals-2.png new file mode 100644 index 000000000..909023429 Binary files /dev/null and b/docs/.vuepress/public/assets/img/job-conditionals-2.png differ diff --git a/docs/.vuepress/public/assets/img/job-conditionals-debugoutput.png b/docs/.vuepress/public/assets/img/job-conditionals-debugoutput.png new file mode 100644 index 000000000..968a96ca1 Binary files /dev/null and b/docs/.vuepress/public/assets/img/job-conditionals-debugoutput.png differ diff --git a/docs/.vuepress/public/assets/img/job-conditionals-picker-node.png b/docs/.vuepress/public/assets/img/job-conditionals-picker-node.png new file mode 100644 index 000000000..55e65fd5c Binary files /dev/null and b/docs/.vuepress/public/assets/img/job-conditionals-picker-node.png differ diff --git a/docs/.vuepress/public/assets/img/job-conditionals-picker-wf.png b/docs/.vuepress/public/assets/img/job-conditionals-picker-wf.png new file mode 100644 index 000000000..cdcd7c368 Binary files /dev/null and b/docs/.vuepress/public/assets/img/job-conditionals-picker-wf.png differ diff --git a/docs/.vuepress/public/feeds/development-atom.xml b/docs/.vuepress/public/feeds/development-atom.xml index ea84e675b..84d18a053 100644 --- a/docs/.vuepress/public/feeds/development-atom.xml +++ b/docs/.vuepress/public/feeds/development-atom.xml @@ -3,9 +3,30 @@ Rundeck Development Updates - 2026-02-18T21:41:07.844Z + 2026-03-09T21:10:20.789Z https://docs.rundeck.com/feeds/development Recent merged pull requests and development updates from Rundeck + + Fix command injection vulnerability in exec commands with ${option.name} + + rundeck-pr-rundeck-10003 + 2026-03-05T21:46:23.000Z + Fix command injection vulnerability in exec commands with ${option.name} (Merged: Mar 5, 2026) + + + Implement conditional workflow logic + + rundeck-pr-rundeckpro-4598 + 2026-03-05T18:39:52.000Z + Implement conditional workflow logic (Merged: Mar 5, 2026) + + + Update to commons-lang3 for CVE-2025-48924 + + rundeck-pr-rundeck-9990 + 2026-02-19T22:33:08.000Z + Update to commons-lang3 for CVE-2025-48924 (Merged: Feb 19, 2026) + Improve Next Ui management diff --git a/docs/.vuepress/public/feeds/development.xml b/docs/.vuepress/public/feeds/development.xml index 868926d5a..28937bf89 100644 --- a/docs/.vuepress/public/feeds/development.xml +++ b/docs/.vuepress/public/feeds/development.xml @@ -5,8 +5,29 @@ https://docs.rundeck.com/docs Recent merged pull requests and development updates from Rundeck en-us - Wed, 18 Feb 2026 21:41:07 GMT + Mon, 09 Mar 2026 21:10:20 GMT + + Fix command injection vulnerability in exec commands with ${option.name} + https://docs.rundeck.com/docs/history/updates/ + Fix command injection vulnerability in exec commands with ${option.name} (Merged: Mar 5, 2026) + Thu, 05 Mar 2026 21:46:23 GMT + rundeck-pr-rundeck-10003 + + + Implement conditional workflow logic + https://docs.rundeck.com/docs/history/updates/ + Implement conditional workflow logic (Merged: Mar 5, 2026) + Thu, 05 Mar 2026 18:39:52 GMT + rundeck-pr-rundeckpro-4598 + + + Update to commons-lang3 for CVE-2025-48924 + https://docs.rundeck.com/docs/history/updates/ + Update to commons-lang3 for CVE-2025-48924 (Merged: Feb 19, 2026) + Thu, 19 Feb 2026 22:33:08 GMT + rundeck-pr-rundeck-9990 + Improve Next Ui management https://docs.rundeck.com/docs/history/updates/ diff --git a/docs/.vuepress/sidebar-menus/learning.ts b/docs/.vuepress/sidebar-menus/learning.ts index d914b10f7..ec3cab905 100644 --- a/docs/.vuepress/sidebar-menus/learning.ts +++ b/docs/.vuepress/sidebar-menus/learning.ts @@ -126,6 +126,7 @@ export default [{ children: [ '/learning/howto/use-example-jobs.md', '/learning/howto/passing-variables.md', + '/learning/howto/using-conditional-logic.md', '/learning/howto/calling-apis.md', '/learning/howto/log4shell.md', '/learning/howto/use-roi-metrics.md', diff --git a/docs/.vuepress/sidebar-menus/user-guide.ts b/docs/.vuepress/sidebar-menus/user-guide.ts index 30a7ca593..0cadef22e 100644 --- a/docs/.vuepress/sidebar-menus/user-guide.ts +++ b/docs/.vuepress/sidebar-menus/user-guide.ts @@ -37,10 +37,12 @@ export default [{ children: [ { text: 'Overview', link: '/manual/jobs/index.md' }, '/manual/jobs/creating-jobs', + '/manual/jobs/ai-generated-runbooks.md', '/manual/jobs/job-workflows', '/manual/jobs/job-options', '/manual/jobs/job-notifications', '/manual/jobs/job-variables', + {text: 'Conditional Logic', link: '/manual/jobs/conditional-logic'}, { text: 'Job Step Plugins', link: '/manual/jobs/job-plugins/index.md', @@ -145,9 +147,15 @@ export default [{ } ] }, - '/manual/jobs/job-queue.md', - '/manual/jobs/job-resume.md', - '/manual/jobs/job-retry-failed-nodes.md', + { + text: 'Execution Control & Recovery (Commercial)', + collapsible: true, + children: [ + '/manual/jobs/job-queue.md', + '/manual/jobs/job-resume.md', + '/manual/jobs/job-retry-failed-nodes.md', + ] + }, { text: 'Log Filters', collapsible: true, @@ -181,9 +189,14 @@ export default [{ '/manual/notifications/jira.md' ] }, - '/manual/jobs/result-data.md', - '/manual/jobs/roi-metrics.md', - '/manual/jobs/ai-generated-runbooks.md', + { + text: 'Job Analytics & Reporting', + collapsible: true, + children: [ + '/manual/jobs/result-data.md', + '/manual/jobs/roi-metrics.md', + ] + }, { text: 'Workflow Strategies', link: '/manual/jobs/workflow-strategies/index.md', diff --git a/docs/administration/configuration/config-file-reference.md b/docs/administration/configuration/config-file-reference.md index cac5542d9..52ffcced7 100644 --- a/docs/administration/configuration/config-file-reference.md +++ b/docs/administration/configuration/config-file-reference.md @@ -544,6 +544,16 @@ Configure authentication, session management, and security policies. **Security tip:** Keep `showTracesOnResponse=false` in production to avoid exposing internal details. +#### Conditional Logic Feature + +**Early Access Feature** + +| Property | Default | Description | +|----------|---------|-------------| +| `rundeck.feature.earlyAccessJobConditional.enabled` | `false` | Enable Conditional Logic workflow steps (Early Access) | + +Enables dynamic conditional execution in workflows based on runtime conditions. When enabled, users can add Conditional Logic steps to jobs that evaluate conditions (job options, node attributes, job context) and execute substeps only when conditions are met. Requires Sequential or Parallel workflow strategy. See [Conditional Logic Steps](/manual/jobs/conditional-logic.md) for complete documentation. + #### Local User Management (Enterprise) **Purpose:** Create and manage users directly in Rundeck's database (alternative to LDAP/SSO). diff --git a/docs/administration/security/audit-stream-plugin.md b/docs/administration/security/audit-stream-plugin.md index 9eae872ae..09adf2fb9 100644 --- a/docs/administration/security/audit-stream-plugin.md +++ b/docs/administration/security/audit-stream-plugin.md @@ -888,9 +888,9 @@ After successfully configuring the Audit Stream Plugin, consider these next step ### Documentation - [Audit Trail Log](/administration/security/audit-trail.md) - Understanding Rundeck's local audit log file (available in all editions) - [Audit Events Listener Plugin Development Guide](/developer/audit-events-listeners.md) - Learn about the underlying plugin framework -- [Rundeck Security Overview](/administration/security/default.md) - Understanding Rundeck's security model -- [Key Storage](/administration/security/key-storage.md) - Securely storing API credentials -- [System Configuration](/administration/configuration/system-configuration.md) - Managing plugin settings +- [Rundeck Security Overview](/administration/security/index.md) - Understanding Rundeck's security model +- [Key Storage](/manual/key-storage/index.md) - Securely storing API credentials +- [System Configuration](/administration/configuration/index.md) - Managing plugin settings ### External Resources - [Datadog Events API Documentation](https://docs.datadoghq.com/api/latest/events/) diff --git a/docs/history/updates/index.md b/docs/history/updates/index.md index 9d1b05962..41b61f43b 100644 --- a/docs/history/updates/index.md +++ b/docs/history/updates/index.md @@ -1,7 +1,7 @@ --- title: Recent Updates description: Latest merged changes from the Rundeck development team -date: 2026-02-18T21:41:07.823Z +date: 2026-03-09T21:10:20.760Z feed: true index: true --- @@ -15,6 +15,21 @@ This page shows recently merged pull requests from both the Runbook Automation p ## Recent Changes +#### ::circle-dot:: Fix command injection vulnerability in exec commands with ${option.name} [PR #10003](https://github.com/rundeck/rundeck/pull/10003) + + + Fixed a critical command injection vulnerability in exec commands where shell control characters in job option values were not properly escaped, now protecting against malicious input by applying shell escaping to all `${option.name}` values by default while providing a compatibility flag for edge cases. + +#### ::circle-dot:: Implement conditional workflow logic + + + Introduces backend support for Conditional Logic workflow steps, enabling dynamic workflow execution based on runtime conditions such as job options, node attributes, and prior step outputs. + +#### ::circle-dot:: Update to commons-lang3 for CVE-2025-48924 [PR #9990](https://github.com/rundeck/rundeck/pull/9990) + + + Updated Apache Commons Lang library to the latest version (commons-lang3) to address CVE-2025-48924, ensuring continued security and compatibility with modern Java standards. + #### ::circle-dot:: Improve Next Ui management [PR #9981](https://github.com/rundeck/rundeck/pull/9981) @@ -41,6 +56,6 @@ The development updates are automatically generated from both our private reposi --- -**List Last updated:** 2026-02-18 +**List Last updated:** 2026-03-09 diff --git a/docs/learning/howto/using-conditional-logic.md b/docs/learning/howto/using-conditional-logic.md new file mode 100644 index 000000000..fd869c4d9 --- /dev/null +++ b/docs/learning/howto/using-conditional-logic.md @@ -0,0 +1,489 @@ +--- + +title: "Using Conditional Logic in a Job" +date: 2026-03-09 +image: /images/chevron-logo-red-on-white.png +feed: + description: "Learn how to create dynamic workflows that make decisions at runtime using Conditional Logic steps. This guide walks through simple and complex examples of using conditions based on job options, node attributes, and environment settings." + +--- + +# Using Conditional Logic in a Job + +**Early Access Feature** - Available in Runbook Automation 5.20.0+ + +## Overview + +Conditional Logic steps enable workflows to make decisions during execution based on runtime conditions. Instead of creating multiple jobs for different scenarios or writing complex scripts with if/then logic, you can use Conditional Logic steps to branch your workflow based on: + +- Job options (environment, configuration values) +- Node attributes (OS family, hostname, tags) +- Job context (project name, job name, execution user) +- Data captured from previous steps + +This guide provides hands-on examples to help you understand how to use conditional logic effectively. + +## Prerequisites + +1. **Runbook Automation 5.20.0+** with the conditional logic feature enabled +2. **Feature flag enabled** in `rundeck-config.properties`: + ```properties + rundeck.feature.earlyAccessJobConditional.enabled=true + ``` +3. **Basic understanding** of job workflows and job options +4. **Workflow strategy** set to Sequential or Parallel (not Node First or Ruleset) + +::: tip New to Rundeck? +If you're new to Rundeck, we recommend completing the [Getting Started Tutorial](/learning/tutorial/index.md) first. This guide assumes familiarity with creating jobs, adding steps, and using job options. +::: + +## Understanding Conditional Logic + +Conditional Logic steps come in two types: + +- **Node Conditional Logic**: Evaluates conditions independently on each node based on node attributes +- **Workflow Conditional Logic**: Evaluates conditions once per job execution in a global context + +Both types support: +- Multiple conditions with AND logic (all must be true) +- Multiple condition sets with OR logic (any set can be true) +- Various operators: equals, not equals, contains, matches (regex), greater than, less than + +## Hands-On Examples + +The following examples demonstrate conditional logic in action. Import these jobs to see how conditions work, then run them with different option values to observe the behavior. + +:::tabs +@tab Simple Conditional Example + +### Simple Conditional: Version Check + +This example demonstrates a basic conditional step that executes only when a specific version is selected. + +**Use Case:** Run deployment steps only for version 5.20 + +**What This Job Does:** +1. Accepts a `version` option as input +2. Uses a Node Conditional Logic step to check if version equals "5.20" +3. If the condition is true, executes an echo command +4. If the condition is false, skips the substep + +**Condition Structure:** +- **Field:** `${option.version}` +- **Operator:** `equals` +- **Value:** `5.20` + +**Job Definition (JSON):** + +```json +[ { + "defaultTab" : "nodes", + "description" : "Simple example showing a single condition checking a job option value.", + "executionEnabled" : true, + "loglevel" : "INFO", + "name" : "Simple Conditional Example", + "nodeFilterEditable" : false, + "nodefilters" : { + "dispatch" : { + "excludePrecedence" : true, + "keepgoing" : false, + "rankOrder" : "ascending", + "successOnEmptyNodeFilter" : false, + "threadcount" : "1" + }, + "filter" : ".*" + }, + "nodesSelectedByDefault" : true, + "options" : [ { + "name" : "version", + "label" : "Version", + "description" : "Enter a version number (try 5.20 or 5.19)", + "type" : "text", + "required" : true + } ], + "scheduleEnabled" : true, + "schedules" : [ ], + "sequence" : { + "commands" : [ { + "conditionGroups" : [ [ { + "key" : "${option.version}", + "operator" : "==", + "value" : "5.20" + } ] ], + "description" : "Check if version is 5.20", + "nodeStep" : true, + "subSteps" : [ { + "exec" : "echo 'Running deployment for version 5.20'" + } ], + "type" : "conditional" + } ], + "keepgoing" : false, + "strategy" : "sequential" + } +} ] +``` + +**How to Use This Example:** + +1. Copy the JSON above and save it as `simple-conditional-example.json` +2. Import the job into your Rundeck project: + - Navigate to the Jobs page + - Click the gear icon and select "Import Job" + - Upload the JSON file +3. Run the job and enter `5.20` for the version option + - The conditional step will evaluate to true + - The echo command will execute +4. Run the job again and enter `5.19` for the version option + - The conditional step will evaluate to false + - The substep will be skipped + - Check the execution log to see the skip message + +**What to Observe:** + +- In the Job Editor, expand the conditional step to see the condition configuration +- In execution logs when condition is **true**: You'll see the echo output +- In execution logs when condition is **false**: You'll see a message like "Conditional step skipped" +- Enable Debug logging to see detailed condition evaluation + +**Key Takeaways:** +- Fields must use `${}` syntax to reference variables +- The operator `==` is equivalent to "equals" +- Substeps only execute when the condition evaluates to true +- Simple conditionals are perfect for single-criteria decisions + +@tab Complex Conditional Example + +### Complex Conditionals: Multi-Environment Deployment + +This example demonstrates advanced conditional logic using multiple condition sets with OR logic and multiple conditions per set with AND logic. + +**Use Case:** Run deployment steps in specific scenarios: +- Always run in Dev environment, OR +- Run on Windows servers (but skip version 5.20), OR +- Run on Linux servers (but skip version 5.19) + +**What This Job Does:** +1. Accepts three options: `environment`, `os`, and `version` +2. Uses a Node Conditional Logic step with three condition sets (OR logic) +3. Each condition set can have multiple conditions (AND logic) +4. Executes substeps when ANY condition set evaluates to true + +**Condition Structure:** + +**Condition Set 1:** Dev environment +- Field: `${option.environment}` Operator: `equals` Value: `Dev` + +**OR** + +**Condition Set 2:** Windows + not version 5.20 +- Field: `${option.os}` Operator: `equals` Value: `Windows` +- **AND** Field: `${option.version}` Operator: `not equals` Value: `5.20` + +**OR** + +**Condition Set 3:** Linux + not version 5.19 +- Field: `${option.os}` Operator: `equals` Value: `Linux` +- **AND** Field: `${option.version}` Operator: `not equals` Value: `5.19` + +**Job Definition (JSON):** + +```json +[ { + "defaultTab" : "nodes", + "description" : "Complex example showing multiple condition sets with OR logic and multiple conditions per set with AND logic.", + "executionEnabled" : true, + "loglevel" : "INFO", + "name" : "Complex Conditionals", + "nodeFilterEditable" : false, + "nodefilters" : { + "dispatch" : { + "excludePrecedence" : true, + "keepgoing" : false, + "rankOrder" : "ascending", + "successOnEmptyNodeFilter" : false, + "threadcount" : "1" + }, + "filter" : ".*" + }, + "nodesSelectedByDefault" : true, + "options" : [ { + "label" : "Version", + "name" : "version", + "description" : "Application version", + "type" : "text", + "required" : true + }, { + "enforced" : true, + "label" : "Environment", + "name" : "environment", + "required" : true, + "type" : "text", + "values" : [ "Prod", "Dev" ], + "valuesListDelimiter" : "," + }, { + "enforced" : true, + "label" : "Operating System", + "name" : "os", + "required" : true, + "type" : "text", + "values" : [ "Linux", "Windows" ], + "valuesListDelimiter" : "," + } ], + "scheduleEnabled" : true, + "schedules" : [ ], + "sequence" : { + "commands" : [ { + "conditionGroups" : [ [ { + "key" : "${option.environment}", + "operator" : "==", + "value" : "Dev" + } ], [ { + "key" : "${option.os}", + "operator" : "==", + "value" : "Windows" + }, { + "key" : "${option.version}", + "operator" : "!=", + "value" : "5.20" + } ], [ { + "key" : "${option.os}", + "operator" : "==", + "value" : "Linux" + }, { + "key" : "${option.version}", + "operator" : "!=", + "value" : "5.19" + } ] ], + "description" : "Check deployment conditions", + "nodeStep" : true, + "subSteps" : [ { + "description" : "Output Variables", + "exec" : "echo 'Deploying on ${option.os} version ${option.version} in ${option.environment}'" + } ], + "type" : "conditional" + } ], + "keepgoing" : false, + "strategy" : "sequential" + } +} ] +``` + +**How to Use This Example:** + +1. Copy the JSON above and save it as `complex-conditionals-example.json` +2. Import the job into your Rundeck project +3. Run the job with different option combinations to see how conditions evaluate + +**Test Scenarios:** + +Try these combinations to understand the OR/AND logic: + +| Environment | OS | Version | Will Execute? | Why? | +|-------------|---------|---------|---------------|-----------------------------------------------------------------------------------------| +| Dev | Linux | 5.20 | ✅ Yes | Matches Set 1 (Dev environment) | +| Dev | Windows | 5.19 | ✅ Yes | Matches Set 1 (Dev environment) | +| Prod | Windows | 5.19 | ✅ Yes | Matches Set 2 (Windows AND not 5.20) | +| Prod | Windows | 5.20 | ❌ No | Set 1 fails (Prod enviroment), Set 2 fails (version IS 5.20), Set 3 fails (not Linux) | +| Prod | Linux | 5.20 | ✅ Yes | Matches Set 3 (Linux AND not 5.19) | +| Prod | Linux | 5.19 | ❌ No | Set 1 fails (Prod enviroment), Set 2 fails (not Windows), Set 3 fails (version IS 5.19) | + +**What to Observe:** + +1. **In the Job Editor:** + - Expand the conditional step to see all three condition sets + - Notice the OR separator between condition sets + - Notice the AND logic within each set (multiple conditions in Set 2 and Set 3) + +2. **In Execution Logs:** + - When conditions are met: You'll see the echo output with the selected values + - When conditions are not met: You'll see "Conditional step skipped" + - Enable Debug logging to see detailed evaluation of each condition and condition set + +3. **Debug Mode Output:** + - Shows each condition being evaluated + - Shows resolved variable values + - Shows pass/fail for each condition + - Shows which condition set (if any) matched + +**Key Takeaways:** +- OR logic lets you define multiple scenarios where the step should execute +- AND logic within a set requires ALL conditions to be true +- Complex conditionals can handle sophisticated business logic without external scripts +- You can combine up to 5 conditions per set and up to 5 condition sets per step + +::: + +## Real-World Use Cases + +### Environment-Based Workflows + +Use conditionals to run different steps based on environment: + +``` +Workflow Conditional Logic: ${option.environment} equals "production" +├─ Substep: Send approval notification +├─ Substep: Backup database +└─ Substep: Enable maintenance mode +``` + +### OS-Specific Commands + +Target specific operating systems without changing node filters: + +``` +Node Conditional Logic: ${node.osFamily} equals "unix" +└─ Substep: Run Linux-specific commands + +Node Conditional Logic: ${node.osFamily} equals "windows" +└─ Substep: Run Windows-specific commands +``` + +### Version-Aware Deployments + +Skip or include steps based on application versions: + +``` +Workflow Conditional Logic: ${option.version} greater than "5.0" +└─ Substep: Use new API endpoints +``` + +### Tag-Based Node Targeting + +Execute steps only on nodes with specific tags: + +``` +Node Conditional Logic: ${node.tags} contains "database" +└─ Substep: Database maintenance commands +``` + +## Building Your Own Conditional Jobs + +### Step-by-Step Guide + +1. **Plan Your Conditions** + - Identify what should trigger different behavior + - Determine if you need Node or Workflow conditional logic + - Map out your AND/OR logic requirements + +2. **Create Job Options** + - Add options for values you'll check in conditions + - Use enforced values for dropdown choices + - Make options required if conditions depend on them + +3. **Add Conditional Step** + - In the Job Editor, click "Add a step" + - Select Node Conditional Logic or Workflow Conditional Logic + - Give the step a descriptive name + +4. **Configure Conditions** + - Add your first condition (Field, Operator, Value) + - Click "Add" to add more conditions to the same set (AND logic) + - Click "Add Condition Set" to create alternate conditions (OR logic) + +5. **Add Substeps** + - Click "+ Add Condition Step" + - Select and configure steps that run when conditions are met + - Add multiple substeps as needed + +6. **Test Thoroughly** + - Run with different option values + - Enable Debug logging to see condition evaluation + - Verify substeps execute only when expected + +## Tips for Effective Conditionals + +### Condition Design +- **Keep it simple**: Prefer multiple simple conditions over complex regex +- **Use descriptive names**: Help others understand what the conditional does +- **Test with debug mode**: Always verify conditions evaluate as expected +- **Document your logic**: Add notes in the job description + +### Common Patterns + +**Multiple Environments:** +``` +Set 1: ${option.environment} equals "dev" +OR +Set 2: ${option.environment} equals "staging" +``` + +**OS + Tag Combination:** +``` +Set 1: ${node.osFamily} equals "unix" AND ${node.tags} contains "web" +OR +Set 2: ${node.osFamily} equals "windows" AND ${node.tags} contains "iis" +``` + +**Exclude Specific Cases:** +``` +${option.environment} not equals "production" +``` + +### Troubleshooting + +**Conditions not evaluating correctly?** +- Enable Debug logging when running the job +- Verify option names match exactly (case-sensitive) +- Ensure Fields use `${}` syntax: `${option.name}` not `option.name` +- Check that node attributes exist on target nodes + +**Substeps not appearing?** +- Verify substeps match parent type (Node substeps for Node Conditional, Workflow substeps for Workflow Conditional) +- Check that at least one condition is defined +- Ensure all required fields are filled + +**Cannot import job?** +- Conditional Logic requires JSON or YAML format (XML is not supported) +- Verify the feature flag is enabled before importing + +## Advanced Scenarios + +### Using Data from Previous Steps + +Conditional Logic can evaluate data captured from previous steps using log filters: + +1. Add a step with a Log Filter (e.g., Key Value Data) to capture output +2. In a later conditional step, reference the captured data: `${data.variableName}` + +Example: +``` +Step 1: Command with Key Value Data log filter capturing "status" +Step 2: Workflow Conditional Logic: ${data.status} equals "ready" + └─ Substep: Proceed with deployment +``` + +### Multi-Level Conditional Logic + +Since nested conditionals are not supported, use Job Reference steps: + +1. Create Job B with its own conditional logic +2. In Job A, add a conditional step +3. Add a Job Reference substep pointing to Job B +4. When Job A's condition is met, it calls Job B, which evaluates its own conditions + +This pattern enables sophisticated multi-level conditional workflows. + +### Combining with Workflow Strategies + +Conditional Logic respects your job's workflow strategy: + +- **Sequential Strategy**: Evaluates conditionals for all nodes before moving to the next step +- **Parallel Strategy**: Evaluates conditionals concurrently across nodes + +## Related Documentation + +- [Conditional Logic Steps Reference](/manual/jobs/conditional-logic.md) - Complete feature documentation +- [Job Options](/manual/jobs/job-options.md) - Creating and using job options +- [Job Variables](/manual/jobs/job-variables.md) - Complete variable reference +- [Workflow Strategies](/manual/jobs/workflow-strategies/index.md) - Understanding workflow execution +- [Log Filters](/manual/log-filters/index.md) - Capturing data for use in conditions +- [Pass Data Between Steps](/learning/howto/passing-variables.md) - Working with variables and log filters + +## Next Steps + +Now that you understand conditional logic basics: + +1. **Experiment** with the example jobs - modify conditions and observe behavior +2. **Combine** conditionals with other features like log filters and job references +3. **Build** your own conditional workflows for your specific use cases +4. **Share feedback** with Rundeck support - this is an Early Access feature under active development diff --git a/docs/manual/document-format-reference/job-json-v44.md b/docs/manual/document-format-reference/job-json-v44.md index 13ca7f739..71587fd57 100644 --- a/docs/manual/document-format-reference/job-json-v44.md +++ b/docs/manual/document-format-reference/job-json-v44.md @@ -578,6 +578,78 @@ Example: } ``` +### Conditional Logic Step Entry + +::: tip Since Rundeck 5.20.0 +Conditional Logic steps are an Early Access commercial feature that requires the feature flag `rundeck.feature.earlyAccessJobConditional.enabled=true`. +::: + +Defines a step that conditionally executes substeps based on runtime conditions. Available for both Node Steps and Workflow Steps. + +`type` + +: Must be `"conditional.logic"` + +`nodeStep` + +: Boolean: `true` for Node Conditional Logic, `false` for Workflow Conditional Logic + +`description` + +: Optional step name/description + +`conditionGroups` + +: Array of condition sets (OR logic between sets) + * `conditions` - Array of individual conditions (AND logic within set) + * `field` - Field reference using `${}` syntax (e.g., `"${node.osFamily}"`, `"${option.environment}"`) + * `operator` - One of: `"equals"`, `"not equals"`, `"contains"`, `"matches"`, `"greater than"`, `"less than"` + * `value` - Comparison value (literal or variable reference with `${}` syntax) + +`steps` + +: Array of substeps to execute when conditions are met (must match `nodeStep` type) + +Example: + +```json +{ + "type": "conditional.logic", + "nodeStep": true, + "description": "Check Linux Nodes", + "conditionGroups": [ + { + "conditions": [ + { + "field": "${node.osFamily}", + "operator": "equals", + "value": "unix" + } + ] + } + ], + "steps": [ + { + "exec": "echo 'Condition met'" + } + ] +} +``` + +**Available Field References:** +- Job Context: `${job.name}`, `${job.project}`, `${job.username}`, `${job.id}` +- Job Options: `${option.[name]}` +- Node Attributes (Node steps only): `${node.hostname}`, `${node.osFamily}`, `${node.tags}`, etc. +- Data Variables: `${data.[name]}` + +**Limitations:** +- Only works with Sequential and Parallel workflow strategies +- Cannot nest conditional steps (use Job Reference steps for multi-level logic) +- Substeps must match parent type (node substeps for node conditionals) +- XML format not supported + +See [Conditional Logic Steps](/manual/jobs/conditional-logic.md) for complete documentation. + ### Options Options for a job can be specified with a list of Maps. Each map contains a `name` key with the name of the option, and the content is a map defining the [Option](#option). diff --git a/docs/manual/document-format-reference/job-yaml-v12.md b/docs/manual/document-format-reference/job-yaml-v12.md index 4db2f506f..ccd5d0923 100644 --- a/docs/manual/document-format-reference/job-yaml-v12.md +++ b/docs/manual/document-format-reference/job-yaml-v12.md @@ -541,6 +541,67 @@ Example: job: "${option.job}" ``` +### Conditional Logic Step Entry + +::: tip Since Rundeck 5.20.0 +Conditional Logic steps are an Early Access commercial feature that requires the feature flag `rundeck.feature.earlyAccessJobConditional.enabled=true`. +::: + +Defines a step that conditionally executes substeps based on runtime conditions. Available for both Node Steps and Workflow Steps. + +`type` + +: Must be `"conditional.logic"` + +`nodeStep` + +: Boolean: `true` for Node Conditional Logic, `false` for Workflow Conditional Logic + +`description` + +: Optional step name/description + +`conditionGroups` + +: Array of condition sets (OR logic between sets) + * `conditions` - Array of individual conditions (AND logic within set) + * `field` - Field reference using `${}` syntax (e.g., `"${node.osFamily}"`, `"${option.environment}"`) + * `operator` - One of: `"equals"`, `"not equals"`, `"contains"`, `"matches"`, `"greater than"`, `"less than"` + * `value` - Comparison value (literal or variable reference with `${}` syntax) + +`steps` + +: Array of substeps to execute when conditions are met (must match `nodeStep` type) + +Example: + +```yaml + - type: conditional.logic + nodeStep: true + description: Check Linux Nodes + conditionGroups: + - conditions: + - field: "${node.osFamily}" + operator: equals + value: unix + steps: + - exec: echo 'Condition met' +``` + +**Available Field References:** +- Job Context: `${job.name}`, `${job.project}`, `${job.username}`, `${job.id}` +- Job Options: `${option.[name]}` +- Node Attributes (Node steps only): `${node.hostname}`, `${node.osFamily}`, `${node.tags}`, etc. +- Data Variables: `${data.[name]}` + +**Limitations:** +- Only works with Sequential and Parallel workflow strategies +- Cannot nest conditional steps (use Job Reference steps for multi-level logic) +- Substeps must match parent type (node substeps for node conditionals) +- XML format not supported + +See [Conditional Logic Steps](/manual/jobs/conditional-logic.md) for complete documentation. + ### Options Options for a job can be specified with a list of Maps. Each map contains a `name` key with the name of the option, and the content is a map defining the [Option](#option). diff --git a/docs/manual/jobs/conditional-logic.md b/docs/manual/jobs/conditional-logic.md new file mode 100644 index 000000000..62e8a19ee --- /dev/null +++ b/docs/manual/jobs/conditional-logic.md @@ -0,0 +1,539 @@ +# Conditional Logic Steps (Commercial) + +**Early Access Feature** - Available in Runbook Automation 5.20.0+ + +Conditional Logic steps enable dynamic workflow execution based on runtime conditions. Use these steps to create intelligent automation that makes decisions during execution without requiring external scripts or complex logic. + +## Overview + +Conditional Logic steps evaluate conditions at runtime and execute substeps only when those conditions are met. This enables workflows to branch based on: + +- Job options (environment, configuration values) +- Node attributes (OS family, hostname, tags) +- Job context (project name, job name, execution user) +- Data captured from previous steps (via log filters) + +### Key Features + +- **AND/OR Logic**: Combine multiple conditions with flexible grouping +- **Multiple Operators**: Equals, not equals, contains, regex matching, numeric comparisons +- **Node and Workflow Types**: Execute conditionally per-node or once per workflow +- **Nested Substeps**: Add multiple steps that execute when conditions are met +- **Debug Mode**: View detailed condition evaluation in execution logs + +### Limitations (Current Release) + +This is an Early Access feature with the following limitations: + +- **Workflow Strategy**: Only works with Sequential and Parallel strategies (not Node First or Ruleset) +- **No Nested Conditionals**: Cannot place a conditional step inside another conditional step. To achieve multi-level conditional logic, use Job Reference steps to call other jobs that contain conditionals. +- **Substep Type Matching**: Substeps must be the same type (node/workflow) as the parent conditional step +- **Step Output Requires Log Filters**: To reference output from previous steps in conditions, use log filters to capture the data, then reference it using `${data.*}` syntax. +- **Error Handlers/Log Filters**: Only supported on root-level steps, not on substeps within conditionals + +## Enabling Conditional Logic + +Conditional Logic is an **Early Access commercial feature** controlled by a feature flag. + +::: warning Early Access Feature +This feature is under active development. If you encounter issues or have feedback, please report them to Rundeck support. You can disable the feature at any time by setting the feature flag to `false` and restarting Rundeck. + +**Important:** If you disable the feature flag after creating jobs with conditional logic steps, those jobs will be preserved but will fail to execute until the conditional steps are removed or the feature is re-enabled. +::: + +### Configuration + +Add this property to `rundeck-config.properties`: + +```properties +rundeck.feature.earlyAccessJobConditional.enabled=true +``` + +**For On-Prem Installations:** +After adding the property, restart Rundeck for the change to take effect. + +**For SaaS Deployments:** +Once the property is set, the feature activates automatically without requiring a restart. + +## Understanding Conditional Step Types + +Conditional Logic steps come in two types, matching Rundeck's step execution model: + +### Node Conditional Logic + +Executes conditionally **on each node** that matches the job's node filter. Conditions are evaluated independently for each node based on that node's attributes. + +**Available Condition Fields:** +- Job Context (job name, project, user) +- Job Options +- Node Attributes (hostname, OS family, tags, custom attributes) +- Data captured via log filters + +**Use Cases:** +- Run commands only on Linux nodes: Field `${node.osFamily}` equals `unix` +- Target specific hostnames: Field `${node.hostname}` contains `web` +- Filter by node tags: Field `${node.tags}` contains `production` + +![job-conditionals-picker](/assets/img/job-conditionals-picker-node.png) + +### Workflow Conditional Logic + +Executes conditionally **once per job execution** on the Rundeck server. Conditions are evaluated in a global context without node-specific variables. + +**Available Condition Fields:** +- Job Context (job name, project, user) +- Job Options +- Data captured via log filters + +**Note:** Node Attributes are NOT available for workflow conditional steps. + +**Use Cases:** +- Run steps only in production environment: Field `${option.environment}` equals `production` +- Skip steps for specific users: Field `${job.username}` not equals `serviceaccount` +- Execute based on captured data: Field `${data.status}` equals `ready` + +![job-conditionals-picker-wf](/assets/img/job-conditionals-picker-wf.png) + +## Adding Conditional Logic Steps + +### Step 1: Open the Step Picker + +In the Job Editor's Workflow tab: + +1. Click **"Add a step"** button +2. The Early Access step picker modal opens with two tabs: **Node Steps** and **Workflow Steps** + +### Step 2: Select Conditional Type + +- For **Node Conditional Logic**: Click the "Node Steps" tab, then select "Node Conditional Logic" +- For **Workflow Conditional Logic**: Click the "Workflow Steps" tab, then select "Workflow Conditional Logic" + +The conditional step editor opens inline at the end of your workflow. + +### Step 3: Configure the Conditional Step + +The conditional step editor has three main sections: + +#### 1. Step Name + +Enter a descriptive name for this conditional step (e.g., "Check Linux Nodes", "Production Environment Only"). + +#### 2. Define Conditions + +Build your condition logic using the condition editor: + +**Adding a Single Condition:** + +1. **Field**: Select what to evaluate using `${}` syntax (e.g., `${node.osFamily}`, `${option.environment}`, `${job.project}`) +2. **Operator**: Choose how to compare (equals, not equals, contains, matches, etc.) +3. **Value**: Enter a literal value or use variable syntax like `${option.env}` + +**Adding Multiple Conditions (AND Logic):** + +Within a condition set, click **"Add"** to add another condition. All conditions in a set must be true (AND logic). + +Example: `${node.osFamily} equals unix` **AND** `${node.hostname} contains web` + +**Adding Condition Sets (OR Logic):** + +Click **"Add Condition Set"** to create a new set. The step executes if ANY condition set is true (OR logic). + +Example: +- Set 1: `${node.osFamily} equals unix` **AND** `${node.tags} contains web` +- **OR** +- Set 2: `${node.osFamily} equals windows` **AND** `${node.tags} contains iis` + +![job-conditionals-2](/assets/img/job-conditionals-2.png) + +**Limits:** +- Maximum 5 conditions per condition set +- Maximum 5 condition sets per step + +#### 3. Set the Steps + +Add substeps that execute when conditions are met: + +1. Click **"+ Add Condition Step"** +2. The step picker modal opens (same as adding regular steps) +3. Select and configure the substep +4. Repeat to add multiple substeps + +**Important:** Substeps must match the parent type: +- Node Conditional Logic → Only Node Steps as substeps +- Workflow Conditional Logic → Only Workflow Steps as substeps + +### Step 4: Save the Conditional Step + +Click **"Save Step"** to add the conditional step to your workflow. + +Click **"Cancel"** to discard changes. + +![job-conditionals-1](/assets/img/job-conditionals-1.png) + +## Available Operators + +The following operators are available for condition evaluation: + +| Operator | Description | Example | +|----------|-------------|---------| +| `equals` | Exact match (case-sensitive) | Field: `${node.osFamily}` Value: `unix` | +| `not equals` | Does not match | Field: `${option.env}` Value: `dev` | +| `contains` | Value contains substring | Field: `${node.hostname}` Value: `web` | +| `matches` | Regular expression match | Field: `${node.hostname}` Value: `^web[0-9]+$` | +| `greater than` | Numeric comparison | Field: `${option.count}` Value: `5` | +| `less than` | Numeric comparison | Field: `${option.timeout}` Value: `60` | + +## Using Variables in Conditions + +### Field References + +Fields must use `${}` syntax to reference data sources using dot notation: + +**Job Context:** +- `${job.name}` - Job name +- `${job.project}` - Project name +- `${job.username}` - User executing the job +- `${job.id}` - Job UUID + +**Job Options:** +- `${option.[name]}` - Value of a job option (e.g., `${option.environment}`) + +**Node Attributes** (Node Conditional Logic only): +- `${node.hostname}` - Node hostname +- `${node.name}` - Node name +- `${node.osFamily}` - Operating system family (unix, windows) +- `${node.osName}` - Operating system name +- `${node.tags}` - Node tags (comma-separated) +- `${node.[attribute]}` - Any custom node attribute + +**Data Variables:** +- `${data.[name]}` - Data captured via log filters (e.g., `${data.status}`) + +### Value References + +Values can be either literal strings/numbers or variable references using `${}` syntax: + +**Literal Values:** +``` +Field: ${node.osFamily} Operator: equals Value: unix +Field: ${option.count} Operator: greater than Value: 10 +Field: ${node.hostname} Operator: contains Value: web +``` + +**Variable References:** +``` +Field: ${node.hostname} Operator: equals Value: ${option.target_host} +Field: ${data.status} Operator: equals Value: ${option.expected_status} +``` + +**Autocomplete Support:** + +When typing in the Value field, an autocomplete menu displays available variables grouped by type: +- **Job** tab: Job context variables +- **Options** tab: Available job options + +## Managing Conditional Steps + +### Editing Conditional Steps + +1. Click the **Edit** button on the conditional step card +2. The inline editor opens with current configuration +3. Modify conditions, substeps, or step name +4. Click **"Save"** to apply changes or **"Cancel"** to discard + +### Reordering Steps + +Conditional steps can be reordered like any other workflow step: + +1. Hover over the conditional step card +2. Click and drag the **handle icon** (⋮⋮) to move the step +3. A blue horizontal bar shows the drop position +4. Release to place the step in the new position + +Use **"Undo"** above the workflow to revert reordering. + +### Duplicating Steps + +Click **"Duplicate"** on a conditional step card to create a copy with the same configuration. The duplicate appears immediately after the original step. + +### Deleting Steps + +Click **"Delete"** on a conditional step card to remove it from the workflow. Use **"Undo"** to restore a deleted step. + +## Execution Behavior + +### Condition Evaluation + +When a job executes: + +1. The workflow engine evaluates conditions for each conditional step +2. For **Node Conditional Logic**: Conditions are evaluated independently for each node +3. For **Workflow Conditional Logic**: Conditions are evaluated once at the workflow level +4. If conditions are true, substeps execute; if false, substeps are skipped + +### Debug Mode + +Enable Debug logging level when running a job to see detailed condition evaluation. + +Debug output shows: +- Each condition being evaluated +- Resolved values for variables +- Whether each condition passed or failed +- Whether the overall condition set was true or false + +![job-conditionals-debugoutput](/assets/img/job-conditionals-debugoutput.png) + +### Execution Log Display + +In the execution log: + +- **Conditions Met**: Substeps appear in the log and execute normally +- **Conditions Not Met**: A log message indicates the conditional step was skipped, and substeps do not appear + +### Workflow Strategies + +Conditional Logic steps respect the job's workflow strategy: + +**Sequential Strategy:** +- Evaluates conditional for all nodes before moving to next step +- Substeps execute on matching nodes according to sequential ordering + +**Parallel Strategy:** +- All steps (including conditionals) run in parallel +- Conditional evaluation happens concurrently across nodes +- Substeps execute in parallel when conditions are met + +## Advanced Scenarios + +### Complex Condition Logic + +Combine AND/OR logic for sophisticated conditions: + +**Example: Linux web servers OR Windows IIS servers** + +Condition Set 1 (Linux): +- Field: `${node.osFamily}` Operator: `equals` Value: `unix` +- Field: `${node.tags}` Operator: `contains` Value: `web` + +**OR** + +Condition Set 2 (Windows): +- Field: `${node.osFamily}` Operator: `equals` Value: `windows` +- Field: `${node.tags}` Operator: `contains` Value: `iis` + +### Using Job Reference Substeps + +Since nested conditionals are not supported, use Job Reference steps to achieve multi-level conditional logic: + +1. Create a job with conditional logic (Job B) +2. In your main job (Job A), add a conditional step +3. Add a Job Reference step as a substep, pointing to Job B +4. When Job A's condition is met, it calls Job B, which then evaluates its own conditionals + +This pattern enables sophisticated multi-level conditional workflows. + +### Environment-Based Workflows + +Use job options with conditionals to create environment-aware workflows: + +**Job Options:** +- `environment` (choice: dev, staging, production) + +**Conditional Steps:** +1. Workflow Conditional Logic: Field `${option.environment}` equals `production` + - Substeps: Send notification, require approval, backup database +2. Workflow Conditional Logic: Field `${option.environment}` not equals `production` + - Substeps: Skip approval, use test credentials + +### Node Attribute Filtering + +Target specific nodes without modifying node filters: + +**Example: Run commands only on database nodes** + +Node Conditional Logic: +- Condition: Field `${node.tags}` Operator: `contains` Value: `database` +- Substeps: Database maintenance commands + +This allows the job to have a broader node filter but selectively execute steps. + +## Troubleshooting + +### Conditional Step Not Available + +**Problem:** Conditional Logic steps don't appear in the step picker. + +**Solutions:** +- Verify `rundeck.feature.earlyAccessJobConditional.enabled=true` in `rundeck-config.properties` +- Restart Rundeck after enabling the feature flag +- Check workflow strategy is Sequential or Parallel (not Node First or Ruleset) + +### Conditions Not Evaluating Correctly + +**Problem:** Substeps execute when they shouldn't (or vice versa). + +**Solutions:** +- Enable Debug mode when running the job to see condition evaluation details +- Verify option names match exactly (case-sensitive) +- For node attributes, confirm the attribute exists on target nodes +- **Important**: Fields must use `${}` syntax (e.g., `${node.osFamily}` not `node.osFamily`) +- Values can be literal or use `${}` syntax for variables +- Use `contains` instead of `equals` for partial matching + +**Note on Step Output:** +- Use `${data.*}` to reference data captured via log filters from previous steps +- To use output from previous steps: add a log filter (e.g., Key Value Data) to capture the output, then reference it using `${data.variableName}` in your conditions + +### Cannot Add Substeps + +**Problem:** Cannot add substeps or wrong substep types appear. + +**Solutions:** +- Ensure substeps match parent type (Node substeps for Node Conditional, Workflow substeps for Workflow Conditional) +- Check that you haven't exceeded the maximum number of substeps (no hard limit, but consider workflow complexity) + +### Validation Errors + +**Problem:** Cannot save conditional step. + +**Solutions:** +- Ensure all required fields are filled (Field and Value are required) +- At least one condition must be defined +- Check for syntax errors in regex patterns (for `matches` operator) +- **Important**: Fields must use `${}` syntax - verify syntax like `${option.name}` not `$option.name` + +### Import/Export Issues + +**Problem:** Cannot import job with conditionals. + +**Solutions:** +- Conditional Logic is supported in JSON and YAML formats only +- XML format is NOT supported - attempting to import XML with conditionals will fail +- When exporting, use JSON or YAML format +- Ensure the feature flag is enabled before importing jobs with conditionals + +## Job Definition Format + +Conditional Logic steps are supported in **JSON and YAML** job definition formats. + +### Format Support + +| Format | Supported | Notes | +|--------|-----------|-------| +| JSON | ✅ Yes | Recommended format | +| YAML | ✅ Yes | Recommended format | +| XML | ❌ No | Will cause errors if job contains conditionals | + +### Structure + +Conditional steps use the following structure in job definitions: + +**JSON Example:** +```json +[ + { + "name": "Example Job", + "loglevel": "INFO", + "sequence": { + "commands": [ + { + "type": "conditional.logic", + "nodeStep": true, + "description": "Check Linux Nodes", + "conditionGroups": [ + { + "conditions": [ + { + "field": "${node.osFamily}", + "operator": "equals", + "value": "unix" + } + ] + } + ], + "steps": [ + { + "exec": "echo 'Running on Linux'" + } + ] + } + ] + } + } +] +``` + +**YAML Example:** +```yaml +- name: Example Job + loglevel: INFO + sequence: + commands: + - type: conditional.logic + nodeStep: true + description: Check Linux Nodes + conditionGroups: + - conditions: + - field: "${node.osFamily}" + operator: equals + value: "unix" + steps: + - exec: echo 'Running on Linux' +``` + +### Import Validation + +When importing job definitions: + +- **Feature flag required**: Jobs with `type: conditional.logic` steps require the feature flag to be enabled +- **Strategy validation**: Import will fail if workflow strategy is Node First or Ruleset +- **Substep type validation**: Import will fail if substeps don't match parent type (node/workflow) + +**Error Example:** +``` +Import failed: Job contains conditional logic steps but feature +'rundeck.feature.earlyAccessJobConditional.enabled' is not enabled. +``` + +### Export Restrictions + +When exporting jobs: + +**XML Export:** +- Attempting to export a job with conditional steps to XML format will **fail with an error** +- Error message: `XML format does not support conditional logic steps. Use JSON or YAML format.` + +**JSON/YAML Export:** +- Jobs with conditionals export successfully +- All condition definitions, substeps, and configuration are preserved + +## Best Practices + +### Condition Design + +- **Keep conditions simple**: Prefer multiple simple conditions over complex regex patterns +- **Use descriptive step names**: Help other users understand what the conditional does +- **Test with debug mode**: Always verify condition evaluation before production use +- **Document expected behavior**: Use job description to explain conditional logic + +### Performance Considerations + +- **Limit condition complexity**: Many conditions or complex regex can impact performance +- **Avoid unnecessary conditionals**: If all nodes should execute, don't add conditionals +- **Use node filters first**: Filter nodes at the job level, use conditionals for fine-grained control + +### Maintainability + +- **Consistent naming**: Use standard naming conventions for options and data variables +- **Limit nesting depth**: Use Job References instead of trying to nest conditionals +- **Group related substeps**: Keep logically related steps together within a conditional +- **Comment your logic**: Add notes in job description explaining complex conditional workflows + +## Related Documentation + +- [Job Workflows](/manual/jobs/job-workflows.md) - Overview of workflow execution +- [Job Variables](/manual/jobs/job-variables.md) - Complete variable reference +- [Workflow Strategies](/manual/jobs/workflow-strategies/index.md) - Strategy details +- [Job Options](/manual/jobs/job-options.md) - Creating and using job options +- [Log Filters](/manual/log-filters/index.md) - Capturing data for use in conditions +- [Document Format Reference](/manual/document-format-reference/index.md) - Job definition formats