Override Argo Workflows generateName from Sensor - github

I'm looking into customizing workflow names. I see that argo submit --generate-name can override the .metadata.generateName property, but does anyone know if this is possible with a Sensor that triggers a Workflow?
I'm using a GitHub event to trigger these workflows, but it would be nice to pull the repository name out of the event and set it as the generateName on the Workflow.
Here's an example of what I was hoping would work, but doesn't seem to as far as I can tell. Maybe I've got the syntax wrong? Does anyone know if something like this is possible?
(Note, I've removed a large part of this sensor so that just the important parts are shown. Basically, I want to parse a GitHub event payload for the repository name. Set it on the workflow arguments. Then use those to override the workflow's generateName property.)
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
name: github-sensor
spec:
dependencies:
- name: github-webhook-sensor
eventSourceName: github-events
eventName: github
triggers:
- template:
name: github
k8s:
group: argoproj.io
version: v1alpha1
resource: workflows
operation: create
source:
resource:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: {{ workflow.parameters.name }}
spec:
arguments:
parameters:
- name: "git-repository-name"
parameters:
# Parameter: git-repository-name
- src:
dependencyName: github-webhook-sensor
dataKey: body.repository.name
dest: spec.arguments.parameters.0.value

I think you can do this to prepend the generated name with the repo name (and a hypen):
...
source:
resource:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: "-"
spec:
arguments:
parameters:
- name: "git-repository-name"
parameters:
- src:
dependencyName: github-webhook-sensor
dataKey: body.repository.name
dest: metadata.generateName
operation: prepend
# Parameter: git-repository-name
- src:
dependencyName: github-webhook-sensor
dataKey: body.repository.name
dest: spec.arguments.parameters.0.value
You can also use name instead of generateName, but I'm not sure how that will behave if multiple triggers come.

Related

How do I use templateDefaults with templates in an argo workslows WorkflowTemplate

I'd like to use the templateDefaults feature to share common environment variables & images between a set of script templates defined in a WorkflowTemplate resource, something like this;
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
spec:
templateDefaults:
script:
image: someimage:v1.2.3
templates:
- name: foo
script:
name: 'foo'
...
- name: bar
script:
name: 'bar'
...
this does not work for me when i reference the template in another workflow - the templateDefaults seem to get ignored & i get an error that the script image is not defined.
Is there an alternative way to accomplish this?
As stated in this Ticket:
templatedefault will not work in templateRef scenario. Because templateRef is just referring the template not the entire workflowSpec in workflowtemplate. you have to move the templateDefault to caller (Workflow) spec.

How do I set helm values (not files) in ArgoCD Application spec

I looked all over the ArgoCD docs for this but somehow I cannot seem to find an answer. I have an application spec like so:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myapp
namespace: argocd
spec:
destination:
namespace: default
server: https://kubernetes.default.svc
project: default
source:
helm:
valueFiles:
- my-values.yaml
path: .
repoURL: ssh://git#blah.git
targetRevision: HEAD
However, I also need to specify a particular helm value (like you'd do with --set in the helm command. I see in the ArgoCD web UI that it has a spot for Values, but I have tried every combination of entries I can think of (somekey=somevalue, somekey:somevalue, somekey,somevalue). I also tried editing the manifest directly, but I still get similar errors trying to do so.
The error is long nonsense that ends with error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type map[string]interface {}
What is the correct syntax to set a single value, either through the web UI or the manifest file?
you would use parameters via spec.source.helm.parameters
something like:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: my-project
source:
repoURL: https://charts.my-company.com
targetRevision: "1234"
chart: my-chart
helm:
parameters:
- name: my.helm.key
value: some-val
destination:
name: k8s-dev
namespace: my-ns
Sample from Argo Docs - https://argo-cd.readthedocs.io/en/stable/user-guide/helm/#build-environment
To override just a few arbitrary parameters in the values you indeed can use parameters: as the equivalent of Helm's --set option or fileParameters: instead of --set-file:
...
helm:
# Extra parameters to set (same as setting through values.yaml, but these take precedence)
parameters:
- name: "nginx-ingress.controller.service.annotations.external-dns\\.alpha\\.kubernetes\\.io/hostname"
value: mydomain.example.com
- name: "ingress.annotations.kubernetes\\.io/tls-acme"
value: "true"
forceString: true # ensures that value is treated as a string
# Use the contents of files as parameters (uses Helm's --set-file)
fileParameters:
- name: config
path: files/config.json
But to answer your original question, for the "Values" option in the GUI you pass literal YAML block in the manifest, like:
helm:
# Helm values files for overriding values in the helm chart
# The path is relative to the spec.source.path directory defined above
valueFiles:
- values-prod.yaml
# Values file as block file
values: |
ingress:
enabled: true
path: /
hosts:
- mydomain.example.com
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
labels: {}
Check ArgoCD sample application for more details.

Templates and Values in different repos via ArgoCD

I'm looking for insights for the following situation...
I have one ArgoCD application pointing to a Git repo (A), where there's a values.yaml;
I would like to use the Helm templates stored in a different repo (B);
Any suggestions/alternatives on how to make this work?
I think helm dependency can help solve your problem.
In file Chart.yaml of repo (A), declares dependency (chart of repo B)
# Chart.yaml
dependencies:
- name: chartB
version: "0.0.1"
repository: "https://link_to_chart_B"
Link references:
https://github.com/argoproj/argocd-example-apps/tree/master/helm-dependency
P/s: You need add repo chart into ArgoCD.
The way we solved it is by writing a very simple helm plugin
and pass to it the URL where the Helm chart location (chartmuseum in our case) as an env variable
server:
name: server
config:
configManagementPlugins: |
- name: helm-yotpo
generate:
command: ["sh", "-c"]
args: ["helm template --version ${HELM_CHART_VERSION} --repo ${HELM_REPO_URL} --namespace ${NAMESPACE} $HELM_CHART_NAME --name-template=${HELM_RELEASE_NAME} -f $(pwd)/${HELM_VALUES_FILE} "]
you can run the helm command with the flag of --repo
and in the ArgoCD Application yaml you call the new plugin
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: application-test
namespace: infra
spec:
destination:
namespace: infra
server: https://kubernetes.default.svc
project: infra
source:
path: "helm-values-files/telegraf"
repoURL: https://github.com/YotpoLtd/argocd-example.git
targetRevision: HEAD
plugin:
name: helm-yotpo
env:
- name: HELM_RELEASE_NAME
value: "telegraf-test"
- name: HELM_CHART_VERSION
value: "1.8.18"
- name: NAMESPACE
value: "infra"
- name: HELM_REPO_URL
value: "https://helm.influxdata.com/"
- name: HELM_CHART_NAME
value: "telegraf"
- name: HELM_VALUES_FILE
value: "telegraf.yaml"
you can read more about it in the following blog
post

How do I use a JSON array from a ConfigMap as a parameter in my Argo workflow?

I'm trying to read a list of urls stored as Json in a ConfigMap and then pass these as parameters to the next step in my Argo workflow.
My config map looks like this:
apiVersion: v1
kind: ConfigMap
metadata:
name: urls
data:
urls: |
[
{"url": "https://www.google.com/"},
{"url": "https://stackoverflow.com/"}
]
And my workflow template looks like this (metadata omitted for brevity):
templates:
- name: main
dag:
tasks:
- name: get-urls
template: urls
- name: url-thingy
dependencies: ['get-urls']
templateRef:
name: do-thing-with-the-urls
template: url-thing
arguments:
parameters:
- name: url
value: "{{ item.url }}"
withParam: "{{tasks['get-urls'].outputs.result}}"
- name: urls
resource:
action: get
manifest: |
apiVersion: v1
kind: ConfigMap
metadata:
name: urls
outputs:
parameters:
- name: urls
valueFrom:
jsonPath: '{.data.urls}'
This loads the ConfigMap file and I can see the urls listed out in the get-urls step under outputs. When it tries to execute the url-thingy step tho it fails with the message:
withParam value could not be parsed as a JSON list: {{tasks['get-urls'].outputs.result}}: invalid character '{' looking for beginning of object key string
I feel like I'm close to the solution, but I'm not sure where I'm going wrong? Is withParam the right way of accessing my list?
try {{=toJson(tasks['get-urls'].outputs.result)}}

Extracting resource in Argo workflow using "resource" template/step with "get" action and passing to downstream steps?

I'm exploring an easy way to read K8S resources in the Argo workflow. The current documentation is focusing mainly on create/patch with conditions (https://argoproj.github.io/argo/examples/#kubernetes-resources), while I'm curious if it's possible to perform "action: get", extra part of the resource state (or full resource) and pass it downstream as artifact or result output. Any ideas?
action: get is not a feature available from Argo.
However, it's easy to use kubectl from within a Pod and then send the JSON output to an output parameter. This uses a BASH script to send the JSON to the result output parameter, but an explicit output parameter or an output artifact are also viable options.
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: kubectl-bash-
spec:
entrypoint: kubectl-example
templates:
- name: kubectl-example
steps:
- - name: generate
template: get-workflows
- - name: print
template: print-message
arguments:
parameters:
- name: message
value: "{{steps.generate.outputs.result}}"
- name: get-workflows
script:
image: bitnami/kubectl:latest
command: [bash]
source: |
some_workflow=$(kubectl get workflows -n argo | sed -n 2p | awk '{print $1;}')
kubectl get workflow "$some_workflow" -ojson
- name: print-message
inputs:
parameters:
- name: message
container:
image: alpine:latest
command: [sh, -c]
args: ["echo result was: '{{inputs.parameters.message}}'"]
Keep in mind that kubectl will run with the permissions of the Workflow's ServiceAccount. Be sure to submit the Workflow using a ServiceAccount which has access to the resource you want to get.