You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible调用Harbor API时字符串ID转整数失败如何解决?

问题解决方案

你遇到的422错误核心是提交的JSON中id、project_id字段实际还是字符串类型,并非数值类型,Harbor后端Go语言的结构体严格要求对应字段为int64类型,无法自动转换字符串格式的数值。绝大多数情况下该问题是YAML书写时错误给jinja2表达式加了引号,导致转成int的数值又被包裹为字符串导致的。

步骤1:先验证原始字段类型

先执行debug任务确认GET返回的字段确实为字符串类型,排除其他问题:

- name: 验证返回字段类型
  ansible.builtin.debug:
    msg:
      - project_id值:{{ item.project_id }},类型:{{ item.project_id | type_debug }}
      - retention_id值:{{ item.metadata.retention_id }},类型:{{ item.metadata.retention_id | type_debug }}
  loop: "{{ projects_result.json }}"

如果输出类型确实为AnsibleUnicode或者str,继续后续操作。

步骤2:正确编写PUT请求的uri任务

注意两个核心规则:

  • 必须指定body_format: json,让Ansible自动将YAML格式的body序列化为合法JSON,保留数值类型
  • 数值类型的字段(id、project_id)的jinja2表达式不要加引号包裹,避免转成的int又被封装为字符串

正确的任务示例:

- name: 更新Harbor项目镜像保留规则
  ansible.builtin.uri:
    url: "https://<你的Harbor域名>/api/v2.0/projects/{{ item.project_id | int }}/retention"
    method: PUT
    headers:
      Authorization: "Basic {{ (harbor_admin_username + ':' + harbor_admin_password) | b64encode }}"
    validate_certs: no
    body_format: json
    body:
      # 注意以下两个字段的jinja2表达式没有加引号
      id: {{ item.metadata.retention_id | int }}
      project_id: {{ item.project_id | int }}
      # 其他保留规则字段按你的需求填写,以下为示例
      algorithm: "or"
      rules:
        - action: "retain"
          template: "latestPushedK"
          parameters:
            latestPushedK: 15 # 保留最近推送的15个镜像
          tag_selectors: []
          scope_selectors:
            repository:
              - kind: "doublestar"
                decoration: "matches"
                pattern: "**" # 匹配项目下所有镜像仓库
    status_code: 200
  loop: "{{ projects_result.json }}"

可选:预处理变量避免类型问题

如果上述写法还是出现问题,可以先将字段转成整数存入事实变量,再调用:

- name: 预处理ID字段为整数类型
  ansible.builtin.set_fact:
    processed_retention_id: "{{ item.metadata.retention_id | int }}"
    processed_project_id: "{{ item.project_id | int }}"
  loop: "{{ projects_result.json }}"
  register: processed_result

- name: 提取处理后的项目列表
  ansible.builtin.set_fact:
    processed_projects: "{{ processed_result.results | map(attribute='ansible_facts') | list }}"

- name: 更新保留规则
  ansible.builtin.uri:
    # 省略其他配置,和上面一致
    body:
      id: {{ item.processed_retention_id }}
      project_id: {{ item.processed_project_id }}
      # 其他字段省略
  loop: "{{ processed_projects }}"

验证方法

执行前可以加debug任务查看即将提交的字段格式,如果输出的id、project_id没有引号,就是正确的数值类型:

- name: 验证提交字段格式
  ansible.builtin.debug:
    msg:
      id: {{ item.metadata.retention_id | int }}
      project_id: {{ item.project_id | int }}
  loop: "{{ projects_result.json }}"

内容的提问来源于stack exchange,提问作者nagilli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:18:00