# Argo + KooCli 操作华为云资源

前面写过一篇使用 Argo Workflow 操作 AWS 资源的例子，今天要写的是类似的，在 Argo Workflow 中，使用 CLI 客户端操作华为云资源的办法。

华为云提供的 [KooCLI](https://support.huaweicloud.com/function-hcli/index.html) 是一个命令行工具，其中提供了很多华为云的操作能力。要在 Argo Workflow 中使用 KooCLI，首先需要构建 KooCLI 的容器镜像，Dockerfile 如下：

~~~dockerfile
FROM ubuntu:24.04
RUN apt-get update -y && apt-get install curl -y
RUN curl -sSL https://cn-north-4-hdn-koocli.obs.cn-north-4.myhuaweicloud.com/cli/latest/hcloud_install.sh -o ./hcloud_install.sh \
  && bash ./hcloud_install.sh -y \
  && yes | hcloud --help

WORKDIR hcloud
~~~

整个过程和官网的说明是类似的，这里我加了一行初始化操作：`yes | hcloud --help`，这是因为启动 `hcloud` 的时候，首先会弹出一个 License 界面，需要输入 `yes` 才继续。所以这里使用 `yes` 命令进行一个初始化。

容器镜像构造结束之后，就可以在 Argo Workflow 中使用 KooCLI 了。

> 这次测试使用的是 Argo Workflow 的 v3.5.11 版本。

简单粗暴上代码，在 `https://gist.github.com/fleeto/7c70b58a6ee7bdb93494f94f77db7c20`

上述代码有几个要点：

## 入参

在 `spec.arguments.parameters` 中，定义了 `ak`、`sk` 以及 `region` 三个参数，用于配置华为云的 AK、SK 以及区域。

~~~yaml
  arguments:
    parameters:
    - name: ak
      value: "AKAKAK"
    - name: sk
      value: "SKSKSSK"
    - name: region
      value: "cn-north-4"
~~~

## 执行 KooCLI

在 `list-ecs` 步骤中，使用了前面构建的 KooCLI 镜像，用无配置方式，通过 `hcloud ECS ListCloudServers` 命令，获取到当前区域下的所有云服务器：

~~~yaml
- name: list-ecs
  container:
    image: dustise/koocli:v0.0.2
    command:
    - hcloud
    args:
    - ECS
    - ListCloudServers
    - --cli-region={{workflow.parameters.region}}
    - --cli-access-key={{workflow.parameters.ak}}
    - --cli-secret-key={{workflow.parameters.sk}}
~~~

这一步骤中，我没有定义输出参数，这是因为在 Argo Workflow 中，可以使用 `steps.[步骤名称].outputs.result` 的方式，默认导出 STDOUT 内容，但是需要注意的是，这种方式最大支持 256kb 的内容。

还有一种方式就是把内容输出给文本文件，然后用如下形式声明：

~~~yaml
outputs:
  parameters:
  - name: hello-param
    valueFrom:
      path: /tmp/hello_world.txt 
~~~

KooCLI 输出的 JSON 中，可以使用 `--cli-query` 开关，使用 `JMESPath` 方式对结果进行整理，原始的输出格式大致如下：

~~~json
{
  "servers": [
    {},]}
~~~

要想只输出 `servers` 数组，可以加入 `--cli-query=servers` 开关，就能输出只包含 `servers` 数组的内容了。

## 引用输出结果进行循环

这里使用了 `withParam` 语法，对 `list-ecs` 步骤的输出结果进行循环，每次循环，都会把当前循环的元素赋值给 `item` 变量，输出 `item` 变量的 `id` 属性。

循环变量里，我们使用了一个奇怪的表达式：`"{{=toJSON(jsonpath(steps.list.outputs.result, '$.servers'))}}"`：

- `{{=` 代表使用表达式进行运算。
- 使用 `jsonpath` 获得数组
- toJSON 把对象编码为 JSON

注意，不同的 Argo workflow 版本，这一点不太一样，目前看到的[官网讨论](https://github.com/argoproj/argo-workflows/discussions/8930#discussioncomment-10866254)是：

- 3.4: `{{=toJson(jsonpath(...))}}`
- 3.5: `{{=toJSON(jsonpath(...))}}`
- 3.6: `{{=jsonpath(...)}}`

## 运行

`argo submit` 或者 `kubectl create` 执行之后，可以看到，KooCLI 用了一个容器进行查询，随后在循环中，每个示例都有一个对应的 Pod 执行 ECHO 任务。
