Stitch Processors
A Stitch processor is a part of a Stitch rule that is responsible for modifying the application's resource configuration files during the deployment planning phase. Processors are defined in a Stitch YAML file in the processor array.
A processor is applied if the condition
in the Stitch rule containing the processor is satisfied. Processors are ordered by phase
and weight
properties. Each processor's output is merged with the input(the output from the previous processor).
Here's an example of a Stitch rule with a processor that adds a label to any Kubernetes resource file:
kind: Rules
metadata:
namespace: k8s-labels
spec:
- name: "k8s.AddLabel"
condition:
deployedType: k8s.Resources
processor:
- type: freemarker
description: "Adding label to kubernetes spec"
phase: POST_FLIGHT
weight: 30
merge:
type: overlay
parameters:
template: |
{ "metadata" : {
"labels": {
"labelToAdd": "addedLabel"
}
}
}
Processor types
You can specify the type of a Stitch processor in the type
property, as shown in the example above. Some of the supported processor types are:
- FreeMarker (type: freemarker)
- jsonpatch (type: patch)
- Groovy (type: groovy)
- Macro (type: macroname)
- AddYamlObject (type: addYamlObject)
You can also create a new processor type with custom defined handling.
Only if a supported processor type is not found in either the core or the custom types, then Deploy will try to apply a Macro.
See Stitch Macros for information about Macros usage.
FreeMarker processor type
The FreeMarker processor type is used to render FreeMarker templates (see Official FreeMarker documentation).
A FreeMarker template has direct access to the deployment context through the ctx
variable, as defined by the Java interface com.xebialabs.deployit.plugin.stitch.service.engine.context.DeploymentContext
Parameters
- template - inline FreeMarker template
- templateFile - the relative path to the external file containing FreeMarker template
- variables - variables that can be used to render the FreeMarker template. It is possible to resolve them using SpEL expressions.
You can define either the template
parameter or the templateFile
parameter, but not both.
Here's an example of using the FreeMarker processor with inline template definition: :
...
- type: freemarker
description: "Adding label to kubernetes spec"
parameters:
template: |
{ "metadata" : {
"labels": {
"myLabel": "${myValue}",
"fromContext": "${ctx.environment.name}"
}
}
}
variables:
myValue: the value
...
Here's an example of a FreeMarker processor using an external template file:
...
- type: freemarker
description: "Adding label to kubernetes spec with external ftl file"
parameters:
templateFile: templates/myTemplate.ftl
...
JSON Patch processor type
A JSON Patch processor type is used for small scale adjustments to the input file. The full specification for the JSON patch can be found here.
Stitch supports all JSON Patch operations such as: add
, remove
, replace
, copy
, move
, test
. For test
operation, if the condition isn't met whole patch is not applied, resulting in the processor being ignored.
Parameters
- patch - patch to be applied, it has same format as the JSON Patch but in YAML
- patchFile - external patch file, both YAML and JSON files are supported
You can define either the patch
parameter or the patchFile
parameter, but not both.
Here's an example of using a JSON Patch processor type:
- type: patch
description: "Using patching to create and change content"
parameters:
patch:
- op: add
path: "/base/patchAdd"
value: "I was added"
- op: replace
path: "/base/replace"
value: "I was replaced"
- op: remove
path: "/base/remove"
Here's an example of a JSON patch processor type using an external file (.json, .yaml and .yml file extensions are supported):
...
- type: freemarker
description: "Using patch processor with external json file"
parameters:
patchFile: patches/patch.json
...
Groovy processor type
This processor allows modifying the input using Groovy scripts. A Groovy script can be provided using one of the two parameters, script
or scriptFile
. A Groovy script should have a method with a name stitch
and four arguments: spec
, params
, document
, context
.
Parameters
- script - inline Groovy script to be executed
- scriptFile - external Groovy script file to be executed
Stitch method arguments
spec
- original input in a JSON string format
params
- parameters from a processor
document
- a Document
instance based on a Document API, which is a part of the stitch-api
library
(interface com.xebialabs.deployit.plugin.stitch.service.engine.processor.handler.groovy.Document
). It
can be used to modify the input in a useful way and add/remove/update any properties of the input document.
To return the modified version of the document, thedocument.getMutatedDocument()
method is used.
See the following example to get more insight.
Example of an inline Groovy script:
...
- type: groovy
description: "Using groovy processor with inline groovy script."
parameters:
script: |
import com.xebialabs.deployit.plugin.stitch.service.engine.processor.handler.groovy.MapFunction
def stitch(spec, params, document, ctx) {
document.map('$..labels', new MapFunction() {
Object map(currentValue) {
currentValue.put("myCustomLabel", "myGroovyValue")
currentValue
}
})
document.getMutatedDocument()
}
...
Example of an external Groovy script file:
...
- type: groovy
description: "Using groovy processor with external groovy script."
parameters:
scriptFile: groovy/script.groovy
...
Add YamlObject processor type
This processor allows easy appending of a YAML object into an array. A YAML object can be provided using one of the two parameters, yaml
or yamlFile
. If the input into this processor is not an array there won't be any change to it.
Parameters
- yaml - inline yaml file to be appended into input list
- yamlFile - external yaml file to be appended into input list
Example of an AddYamlProcessor with an inline YAML object:
...
- type: addYamlObject
description: "Using add yaml object processor to add k8s PDB"
merge:
type: none
parameters:
yaml: |
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: pet-clinic
...
Example of an AddYamlObject processor with an external YAML file:
...
- type: addYamlObject
description: "Using addYamlObject with external yaml file to add k8s PDB."
parameters:
yamlFile: yaml/k8s-pdb.yaml
...
Ordering execution with phase and weight
The execution order of Stitch processors is determined by two properties, phase
and weight
. First, all the processors are grouped by phase. Then within a phase, all processors are ordered by weight. In this way, all phases are executed in order. While both phase
and weight
properties require integer values, for phases, there are also the following predefined constants with their integer values:
- PRE_FLIGHT - 0
- BASE_DEFINITION - 10
- GENERATE - 20
- TRANSFORM - 50
- OVERLAY - 60
- PATCH_ADD - 70
- PATCH - 80
- PATCH_REMOVE - 90
- POST_FLIGHT - 100
Both phase
and weight
properties are optional. The default value for phase
is TRANSFORM
and for weight
is 50
.
The order of the execution is deterministic. Given the same definition, it will always execute in the same order, even if processors have the same phase and weight. With that in mind, processors that have same phase and weight shouldn't be transforming same things in input.
Merging documents
The merge
property specifies how the result of the current processor is merged with the result of the previous processor.
This means that the output of one processor is the input of the next processor, where starting input comes from the plugin.
Property is not required and default value is overlay
.
Merge types
- overlay - merge at the root, making the current content overlay possible existing data.
- jsonPath - merge at the root(s) found by defined json path, also overlaying from that point in tree. It is possible to merge from multiple points in the tree. You can also see the specification for json path here.
- none - do not merge output with the input, return the output from the current processor as is.
Here's an example of merge types definitions:
...
- type: freemarker
merge:
type: overlay
...
and:
...
- type: freemarker
merge:
type: jsonpath
path: "$.store.book[0]"
...
SpEL expressions
SpEL (Spring Expression Language) is a powerful expression language. In processors, it is used to resolve values of variables from the processor parameter. The only variable available inside those expressions is ctx
, which is the deployment context as defined by the Java interface com.xebialabs.deployit.plugin.stitch.service.engine.context.DeploymentContext
.
SpEL is also used for conditions in Rules and to resolve parameters in Macros. Here's an example of using SpEL to resolve variables in processor:
...
- type: freemarker
description: "Adding label to kubernetes spec"
parameters:
template: |
{ "metadata" : {
"labels": {
"application": "${application}",
"environment": "${environment}"
}
}
}
variables:
application: "#{#ctx.deployedApplication.id}"
environment: "#{#ctx.deployedApplication.environment.name}"
...
Custom processors
You can create new processor types which is explained here.