如何将脚本模板的结果作为输入参数传递给 argo 工作流程中 dag 中的另一个任务

Bir*_*iru 3 kubernetes 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
Run Code Online (Sandbox Code Playgroud)

在上面的脚本模板中,我添加了两个变量templates_lst和的打印语句manifests_lst。我想将这两个变量结果作为输入传递给 dag 中的其他两个任务。另外两个任务是templatesmanifests

我访问输出值的方式是"{{tasks.prepare-lst.outputs.parameters.templates_lst}}""{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"。它不工作

我怎样才能做到这一点?

Mic*_*haw 5

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

Run Code Online (Sandbox Code Playgroud)

  • 我修好了它。问题是列表未正确存储在文件中。我使用了 `json.dumps` 将列表中字符串的单引号替换为双引号,这适用于 `withParam` @Michael Crenshaw - 我更新了您的答案并接受它作为工作解决方案。 (2认同)