如何将脚本模板的结果作为输入参数传递给 argo 工作流中 dag 中的另一个任务
How to pass result of script template as an input parameter to another task in dag in argo workflows
我创建了一个 WorkflowTemplate
,我想在其中将脚本模板的结果作为输入参数传递给另一个任务
这是我的WorkflowTemplate
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: dag-wft
spec:
entrypoint: whalesay
templates:
- name: whalesay
inputs:
parameters:
- name: message
default: '["tests/hello", "templates/hello", "manifests/hello"]'
dag:
tasks:
- name: prepare-lst
template: prepare-list-script
arguments:
parameters:
- name: message
value: "{{inputs.parameters.message}}"
- name: templates
depends: prepare-lst
templateRef:
name: final-dag-wft
template: whalesay-final
arguments:
parameters:
- name: fnl_message
value: "{{item}}"
withParam: "{{tasks.prepare-lst.outputs.parameters.templates_lst}}"
- name: manifests
depends: prepare-lst && (templates.Succeeded || templates.Skipped)
templateRef:
name: final-dag-wft
template: whalesay-final
arguments:
parameters:
- name: fnl_message
value: "{{item}}"
withParam: "{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"
- name: prepare-list-script
inputs:
parameters:
- name: message
script:
image: python
command: [python]
source: |
manifests_lst = []
# templates list preparation
templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
print(templates_lst)
# manifests list preparation
for i in "{{inputs.parameters.message}}":
if 'templates/' not in i:
manifests_lst.append(i)
print(manifests_lst)
outputs:
parameters:
- name: templates_lst
- name: manifests_lst
在上面的脚本模板中,我添加了两个变量 templates_lst
和 manifests_lst
的打印语句。我想将这两个变量结果作为输入传递给 dag 中的其他两个任务。另外两个任务是 templates
和 manifests
我访问输出值的方式是 "{{tasks.prepare-lst.outputs.parameters.templates_lst}}"
和 "{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"
。它不工作
我该怎么做?
1.完全定义你的输出参数
您的输出参数规范不完整。您需要指定输出参数的来源。
因为你有多个输出参数,你不能只使用标准输出 ({{tasks.prepare-lst.outputs.parameters.result}}
)。您必须编写两个文件并从每个文件中导出一个输出参数。
2。加载 JSON 数组使其可迭代
如果遍历数组的字符串表示形式,一次只会得到一个字符。
3。使用环境变量将输入传递给 Python
虽然这不是绝对必要的,但我认为这是最佳做法。如果恶意行为者能够设置 message
参数,他们就可以将 Python 注入您的工作流程。将参数作为环境变量传递,使字符串保持为字符串。
变化:
- name: prepare-list-script
inputs:
parameters:
- name: message
script:
image: python
command: [python]
+ env:
+ - name: MESSAGE
+ value: "{{inputs.parameters.message}}"
source: |
+ import json
+ import os
+ message = json.loads(os.environ["MESSAGE"])
manifests_lst = []
# templates list preparation
- templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
+ templates_lst = ['templates/' for template in message if 'templates/' in template]
- print(templates_lst)
+ with open('/mnt/out/templates_lst.txt', 'w') as outfile:
+ outfile.write(str(json.dumps(templates_lst)))
# manifests list preparation
for i in "{{inputs.parameters.message}}":
if 'templates/' not in i:
manifests_lst.append(i)
- print(manifests_lst)
+ with open('/mnt/out/manifests_lst.txt', 'w') as outfile:
+ outfile.write(str(json.dumps(manifests_lst)))
+ volumeMounts:
+ - name: out
+ mountPath: /mnt/out
+ volumes:
+ - name: out
+ emptyDir: { }
outputs:
parameters:
- name: templates_lst
+ valueFrom:
+ path: /mnt/out/templates_lst.txt
- name: manifests_lst
+ valueFrom:
+ path: /mnt/out/manifests_lst.txt
我创建了一个 WorkflowTemplate
,我想在其中将脚本模板的结果作为输入参数传递给另一个任务
这是我的WorkflowTemplate
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: dag-wft
spec:
entrypoint: whalesay
templates:
- name: whalesay
inputs:
parameters:
- name: message
default: '["tests/hello", "templates/hello", "manifests/hello"]'
dag:
tasks:
- name: prepare-lst
template: prepare-list-script
arguments:
parameters:
- name: message
value: "{{inputs.parameters.message}}"
- name: templates
depends: prepare-lst
templateRef:
name: final-dag-wft
template: whalesay-final
arguments:
parameters:
- name: fnl_message
value: "{{item}}"
withParam: "{{tasks.prepare-lst.outputs.parameters.templates_lst}}"
- name: manifests
depends: prepare-lst && (templates.Succeeded || templates.Skipped)
templateRef:
name: final-dag-wft
template: whalesay-final
arguments:
parameters:
- name: fnl_message
value: "{{item}}"
withParam: "{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"
- name: prepare-list-script
inputs:
parameters:
- name: message
script:
image: python
command: [python]
source: |
manifests_lst = []
# templates list preparation
templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
print(templates_lst)
# manifests list preparation
for i in "{{inputs.parameters.message}}":
if 'templates/' not in i:
manifests_lst.append(i)
print(manifests_lst)
outputs:
parameters:
- name: templates_lst
- name: manifests_lst
在上面的脚本模板中,我添加了两个变量 templates_lst
和 manifests_lst
的打印语句。我想将这两个变量结果作为输入传递给 dag 中的其他两个任务。另外两个任务是 templates
和 manifests
我访问输出值的方式是 "{{tasks.prepare-lst.outputs.parameters.templates_lst}}"
和 "{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"
。它不工作
我该怎么做?
1.完全定义你的输出参数
您的输出参数规范不完整。您需要指定输出参数的来源。
因为你有多个输出参数,你不能只使用标准输出 ({{tasks.prepare-lst.outputs.parameters.result}}
)。您必须编写两个文件并从每个文件中导出一个输出参数。
2。加载 JSON 数组使其可迭代
如果遍历数组的字符串表示形式,一次只会得到一个字符。
3。使用环境变量将输入传递给 Python
虽然这不是绝对必要的,但我认为这是最佳做法。如果恶意行为者能够设置 message
参数,他们就可以将 Python 注入您的工作流程。将参数作为环境变量传递,使字符串保持为字符串。
变化:
- name: prepare-list-script
inputs:
parameters:
- name: message
script:
image: python
command: [python]
+ env:
+ - name: MESSAGE
+ value: "{{inputs.parameters.message}}"
source: |
+ import json
+ import os
+ message = json.loads(os.environ["MESSAGE"])
manifests_lst = []
# templates list preparation
- templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
+ templates_lst = ['templates/' for template in message if 'templates/' in template]
- print(templates_lst)
+ with open('/mnt/out/templates_lst.txt', 'w') as outfile:
+ outfile.write(str(json.dumps(templates_lst)))
# manifests list preparation
for i in "{{inputs.parameters.message}}":
if 'templates/' not in i:
manifests_lst.append(i)
- print(manifests_lst)
+ with open('/mnt/out/manifests_lst.txt', 'w') as outfile:
+ outfile.write(str(json.dumps(manifests_lst)))
+ volumeMounts:
+ - name: out
+ mountPath: /mnt/out
+ volumes:
+ - name: out
+ emptyDir: { }
outputs:
parameters:
- name: templates_lst
+ valueFrom:
+ path: /mnt/out/templates_lst.txt
- name: manifests_lst
+ valueFrom:
+ path: /mnt/out/manifests_lst.txt