How can you trigger an existing workflow/workflow-template outside argo-events template or namespace? - argo-workflows

Based on documentation, we can trigger the creation of a workflow. Is there is a way to trigger an existing workflow (deployed in argo namespace) from a sensor in argo-events namespace?
Something like:
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook
spec:
template:
serviceAccountName: operate-workflow-sa
dependencies:
- name: test-dep
eventSourceName: webhook
eventName: example
triggers:
- template:
name: webhook-workflow-trigger
argoWorkflow:
source:
resource: existing-workflow-in-another-namespace
Existing Workflow:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: sb1-
labels:
workflows.argoproj.io/archive-strategy: "false"
spec:
entrypoint: full
serviceAccountName: argo
volumes:
- name: kaniko-secret
secret:
secretName: regcred
items:
- key: .dockerconfigjson
path: config.json
- name: github-access
secret:
secretName: github-access
items:
- key: token
path: token
templates:
- name: full
dag:
tasks:
- name: build
templateRef:
name: container-image
template: build-kaniko-git
clusterScope: true
arguments:
parameters:
- name: repo_url
value: git://github.com/letthefireflieslive/test-app-sb1
- name: repo_ref
value: refs/heads/main
- name: container_image
value: legnoban/test-app-sb1
- name: container_tag
value: 1.0.2
- name: promote-dev
templateRef:
name: promote
template: promote
clusterScope: true
arguments:
parameters:
- name: repo_owner
value: letthefireflieslive
- name: repo_name
value: vcs
- name: repo_branch
value: master
- name: deployment_path
value: overlays/eg/dev/sb1/deployment.yml
- name: image_owner
value: legnoban
- name: image_name
value: test-app-sb1
- name: tag
value: 1.0.2
dependencies:
- build

In Argo, a Workflow is representation of a job that is running or has completed running, as such this is probably not what you want to do.
What you can do is create a template that will create a workflow (run a job) and then refer to this template in your trigger. In this way you can create a workflow based on the template.
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: sb1-workflowtemplate
spec:
entrypoint: full
templates:
- name: full
dag:
tasks:
- name: build
templateRef:
name: container-image
template: build-kaniko-git
clusterScope: true
arguments:
parameters:
- name: repo_url
value: git://github.com/letthefireflieslive/test-app-sb1
- name: repo_ref
value: refs/heads/main
- name: container_image
value: legnoban/test-app-sb1
- name: container_tag
value: 1.0.2
- name: promote-dev
templateRef:
name: promote
template: promote
clusterScope: true
arguments:
parameters:
- name: repo_owner
value: letthefireflieslive
- name: repo_name
value: vcs
- name: repo_branch
value: master
- name: deployment_path
value: overlays/eg/dev/sb1/deployment.yml
- name: image_owner
value: legnoban
- name: image_name
value: test-app-sb1
- name: tag
value: 1.0.2
dependencies:
- build
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: webhook
spec:
template:
serviceAccountName: operate-workflow-sa
dependencies:
- name: test-dep
eventSourceName: webhook
eventName: example
triggers:
- template:
name: webhook-workflow-trigger
argoWorkflow:
source:
resource:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: sb1-
spec:
workflowTemplateRef:
name: sb1-workflowtemplate

You should be able to do this, but you need to have serviceaccount in the sensor who can manage workflows. This means clusterrole and clusterrbinding assigned to this account:
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-events-core
namespace: argo-events
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argo-events-core
namespace: argo-events
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflowtemplates
- cronworkflows
- clusterworkflowtemplates
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argo-events-core
namespace: argo-events
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-events-core
subjects:
- kind: ServiceAccount
name: argo-events-core
namespace: argo-events

Related

Tekton YAML TriggerTemplate - string substitution

I have this kind of yaml file to define a trigger
`
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
name: app-template-pr-deploy
spec:
params:
- name: target-branch
- name: commit
- name: actor
- name: pull-request-number
- name: namespace
resourcetemplates:
- apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
generateName: app-pr-$(tt.params.actor)-
labels:
actor: $(tt.params.actor)
spec:
serviceAccountName: myaccount
pipelineRef:
name: app-pr-deploy
podTemplate:
nodeSelector:
location: somelocation
params:
- name: branch
value: $(tt.params.target-branch)
** - name: namespace
value: $(tt.params.target-branch)**
- name: commit
value: $(tt.params.commit)
- name: pull-request-number
value: $(tt.params.pull-request-number)
resources:
- name: app-cluster
resourceRef:
name: app-location-cluster
`
The issue is that sometime target-branch is like "integration/feature" and then the namespace is not valid
I would like to check if there is an unvalid character in the value and replace it if there is.
Any way to do it ?
Didn't find any valuable way to do it beside creating a task to execute this via shell script later in the pipeline.
This is something you could do from your EventListener, using something such as:
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: xx
spec:
triggers:
- name: demo
interceptors:
- name: addvar
ref:
name: cel
params:
- name: overlays
value:
- key: branch_name
expression: "body.ref.split('/')[2]"
bindings:
- ref: your-triggerbinding
template:
ref: your-triggertemplate
Then, from your TriggerTemplate, you would add the "branch_name" param, parsed from your EventListener.
Note: payload from git notification may vary. Sample above valid with github. Translating remote/origin/master into master, or abc/def/ghi/jkl into ghi.
I've created a separate task that is doing all the magic I needed and output a valid namespace name into a different variable.
Then instead of use namespace variable, i use valid-namespace all the way thru the pipeline.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: validate-namespace-task-v1
spec:
description: >-
This task will validate namespaces
params:
- name: namespace
type: string
default: undefined
results:
- name: valid-namespace
description: this should be a valid namespace
steps:
- name: triage-validate-namespace
image: some-image:0.0.1
script: |
#!/bin/bash
echo -n "$(params.namespace)" | sed "s/[^[:alnum:]-]/-/g" | tr '[:upper:]' '[:lower:]'| tee $(results.valid-namespace.path)
Thanks

Use environment variable as default for another env variable in Kubernetes

Is there a way to use an environment variable as the default for another? For example:
apiVersion: v1
kind: Pod
metadata:
name: Work
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: ALWAYS_SET
value: "default"
- name: SOMETIMES_SET
value: "custom"
- name: RESULT
value: "$(SOMETIMES_SET) ? $(SOMETIMES_SET) : $(ALWAYS_SET)"
I don't think there is a way to do that but anyway you can try something like this
apiVersion: v1
kind: Pod
metadata:
name: Work
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
args:
- RESULT=${SOMETIMES_SET:-${ALWAYS_SET}}; command_to_run_app
command:
- sh
- -c
env:
- name: ALWAYS_SET
value: "default"
- name: SOMETIMES_SET
value: "custom"

How to trigger an existing Argo cronworkflow?

I have tried many versions of this template below
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: tibco-events-sensor
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: 'false'
serviceAccountName: operate-workflow-sa
dependencies:
- name: tibco-dep
eventSourceName: tibco-events-source
eventName: whatever
triggers:
- template:
name: has-wf-event-trigger
argoWorkflow:
group: argoproj.io
version: v1alpha1
resource: Workflow
operation: resubmit
metadata:
generateName: has-wf-argo-events-
source:
resource:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: has-wf-full-refresh
Keep getting errors of workflows not found
"rpc err
or: code = NotFound desc = workflows.argoproj.io \"has-wf-full-refresh\" not found"
I have hundreds of workflows launched as cronworkflows. And i would like to switch them to be event driven vs cron based. Id prefer not to change already existing flows. I just want to submit or resubmit them.
I figured out that the argoWorkflow trigger template doesnt support CronWorkflows. I ended up using the httptrigger template.
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: tibco-events-sensor
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: 'false'
serviceAccountName: operate-workflow-sa
dependencies:
- name: tibco-dep
eventSourceName: tibco-events-source
eventName: whatever
triggers:
- template:
name: http-trigger
http:
url: http://argo-workflows.argo-workflows:2746/api/v1/workflows/lab-uat/submit
secureHeaders:
- name: Authorization
valueFrom:
secretKeyRef:
name: argo-workflows-sa-token
key: bearer-token
payload:
- src:
dependencyName: tibco-dep
value: CronWorkflow
dest: resourceKind
- src:
dependencyName: tibco-dep
value: coinflip
dest: resourceName
- src:
dependencyName: tibco-dep
value: coinflip-event-
dest: submitOptions.generateName
method: POST
retryStrategy:
steps: 3
duration: 3s
policy:
status:
allow:
- 200

Patching list in kubernetes manifest with Kustomize

I want to patch (overwrite) list in kubernetes manifest with Kustomize.
I am using patchesStrategicMerge method.
When I patch the parameters which are not in list the patching works as expected - only addressed parameters in patch.yaml are replaced, rest is untouched.
When I patch list the whole list is replaced.
How can I replace only specific items in the list and the res of the items in list stay untouched?
I found these two resources:
https://github.com/kubernetes-sigs/kustomize/issues/581
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md
but wasn't able to make desired solution of it.
exmaple code:
orig-file.yaml
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: alertmanager-slack-config
namespace: system-namespace
spec:
test: test
other: other-stuff
receivers:
- name: default
slackConfigs:
- name: slack
username: test-user
channel: "#alerts"
sendResolved: true
apiURL:
name: slack-webhook-url
key: address
patch.yaml:
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: alertmanager-slack-config
namespace: system-namespace
spec:
test: brase-yourself
receivers:
- name: default
slackConfigs:
- name: slack
username: Karl
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- orig-file.yaml
patchesStrategicMerge:
- patch.yaml
What I get:
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: alertmanager-slack-config
namespace: system-namespace
spec:
other: other-stuff
receivers:
- name: default
slackConfigs:
- name: slack
username: Karl
test: brase-yourself
What I want:
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: alertmanager-slack-config
namespace: system-namespace
spec:
other: other-stuff
receivers:
- name: default
slackConfigs:
- name: slack
username: Karl
channel: "#alerts"
sendResolved: true
apiURL:
name: slack-webhook-url
key: address
test: brase-yourself
What you can do is to use jsonpatch instead of patchesStrategicMerge, so in your case:
cat <<EOF >./kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- orig-file.yaml
patches:
- path: patch.yaml
target:
group: monitoring.coreos.com
version: v1alpha1
kind: AlertmanagerConfig
name: alertmanager-slack-config
EOF
patch:
cat <<EOF >./patch.yaml
- op: replace
path: /spec/receivers/0/slackConfigs/0/username
value: Karl
EOF

Argo Workflow not passing input parameters to WorkflowTemplate

I have broken down my workflow scenario into 2 separate WorkflowTemplates. outer-template would just define the steps and inner-template would hold that job definition that will spin up desired container, with all other fancy stuff. Now when I submit a request request.yaml, it does pass the parameter message down to outer and inner template and fails with this error:
hello-59jg8-394098346:
Boundary ID: hello-59jg8-1953291600
Children:
hello-59jg8-534805352
Display Name: [0]
Finished At: 2021-06-15T00:41:45Z
Id: hello-59jg8-394098346
Message: child 'hello-59jg8[0].init-step[0].step-1' errored
Name: hello-59jg8[0].init-step[0]
Phase: Error
Started At: 2021-06-15T00:41:45Z
Template Name: HelloWorld
Template Scope: namespaced/outer-template
Type: StepGroup
hello-59jg8-534805352:
Boundary ID: hello-59jg8-1953291600
Display Name: step-1
Finished At: 2021-06-15T00:41:45Z
Id: hello-59jg8-534805352
Message: inputs.parameters.message was not supplied
Name: hello-59jg8[0].init-step[0].step-1
Phase: Error
Started At: 2021-06-15T00:41:45Z
Template Ref:
Name: inner-template
Template: InnerJob
Template Scope: namespaced/outer-template
Type: Skipped
Phase: Failed
Started At: 2021-06-15T00:41:45Z
Stored Templates:
Below 2 are WorkflowTemplates and third one is the request.
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: inner-template
namespace: cali
labels:
workflows.argoproj.io/controller-instanceid: cali
spec:
templates:
- name: InnerJob
metadata:
annotations:
sidecar.istio.io/inject: "false"
inputs:
parameters:
- name: message
- name: stepName
value: ""
resource:
action: create
successCondition: status.succeeded > 0
failureCondition: status.failed > 0
manifest: |
apiVersion: batch/v1
kind: Job
metadata:
generateName: hello-pod-
annotations:
sidecar.istio.io/inject: "false"
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
spec:
containers:
- name: hellopods
image: centos:7
command: [sh, -c]
args: ["echo ${message}; sleep 5; echo done; exit 0"]
env:
- name: message
value: "{{inputs.parameters.message}}"
- name: stepName
value: "{{inputs.parameters.stepName}}"
restartPolicy: Never
outputs:
parameters:
- name: job-name
valueFrom:
jsonPath: '{.metadata.name}'
- name: job-obj
valueFrom:
jqFilter: '.'
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: outer-template
namespace: cali
labels:
workflows.argoproj.io/controller-instanceid: cali
spec:
entrypoint: HelloWorld
templates:
- name: HelloWorld
inputs:
parameters:
- name: message
steps:
- - name: step-1
templateRef:
name: inner-template
template: InnerJob
arguments:
parameters:
- name: message
- name: stepName
value: "this is step 1"
- - name: step-2
templateRef:
name: inner-template
template: InnerJob
arguments:
parameters:
- name: message
- name: stepName
value: "this is step 2"
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-
namespace: cali
labels:
workflows.argoproj.io/controller-instanceid: cali
spec:
entrypoint: HelloWorld
serviceAccountName: argo
templates:
- name: HelloWorld
steps:
- - arguments:
parameters:
- name: message
value: "Hello World....."
name: init-step
templateRef:
name: outer-template
template: HelloWorld
When passing an argument to a template in a step, you have to explicitly set the argument value.
In the outer-template WorkflowTemplate, you invoke inner-template twice. In each case you have half-specified the message argument. You have to also set the value for each parameter.
You should set value: "{{inputs.parameters.message}}" in step-1 and step-2. That will pull the message input parameter from outer-template.HelloWorld.
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: outer-template
namespace: cali
labels:
workflows.argoproj.io/controller-instanceid: cali
spec:
entrypoint: HelloWorld
templates:
- name: HelloWorld
inputs:
parameters:
- name: message
steps:
- - name: step-1
templateRef:
name: inner-template
template: InnerJob
arguments:
parameters:
- name: message
value: "{{inputs.parameters.message}}"
- name: stepName
value: "this is step 1"
- - name: step-2
templateRef:
name: inner-template
template: InnerJob
arguments:
parameters:
- name: message
value: "{{inputs.parameters.message}}"
- name: stepName
value: "this is step 2"