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

Ansible Tower/AAP API分页查询及时间匹配问题求助

问题与解决方案:Ansible Tower/AAP Jobs API 数据查询优化

初始问题:获取最新半小时任务数据的分页困境

需要在Playbook中查询Ansible Tower的Jobs REST API,获取最近半小时的任务数据。最初使用以下代码拉取数据:

- name: Pull Jobs Data
  uri:
    url: https://ansible.xxxx.com/api/v2/jobs/?format=json&page=1&page_size=200
    headers:
      Content-Type: application/json
      Authorization: "Bearer {{ lookup('env', 'TOWER_PASSWORD') }}"
  register: jobs_data

- name: Get last half hour of data
  debug:
    var: "{{item}}"
  when:
  - item['started'] > current_epoch_half_hour_back
  loop: "{{ jobs_data['json']['results'] }}"

但由于数据保留两周(约15000页),page=1返回的是最旧数据,无法获取最新内容。且红帽建议不要修改配置文件将page_size调至200以上,因此需要一种无需硬编码页码、从最新数据开始查询的方法。

问题更新:排序解决分页顺序,但时间筛选失效

添加负序排序参数后解决了分页顺序问题,让page=1返回最新数据:

url: https://aap.prci.com/api/v2/jobs/?format=json&page=1&page_size=600&order_by=-{{'started'}}

但在AAP中,最近半小时数据的筛选条件失效(该条件在Tower中可正常工作)。当前生成时间参数并筛选的代码如下:

- set_fact:
    half_hour_back: "{{ '%Y-%m-%dT%H:%M:%S'|strftime((ansible_date_time.epoch|int) - (60*60*0.5)) }}"

- name: Add jobs data to dictionary
  set_fact:
    list_of_jobs_info: "{{ list_of_jobs_info + [{ 'job_id' : item['id'], 'job_name' : item['name'], 'job_status' : item['status'] }] }}"
  when:
    - item['status'] == "canceled"
    - item['started'] > half_hour_back
  loop: "{{ jobs_data['json']['results'] }}"

API返回的started字段格式为:

"started": "2022-11-15T20:00:07.881083Z"

推测AAP API对数据类型/格式检查更严格,需要生成匹配格式的half_hour_back变量以实现正确的时间比较。

解决方案

1. 从最新数据开始查询(无需硬编码页码)

使用API的order_by参数按started字段倒序排序,这样page=1直接返回最新的任务数据,无需定位到最后一页。结合分页遍历,直到获取到半小时前的数据或没有更多分页:

- name: Pull latest Jobs Data (page 1, sorted by started descending)
  uri:
    url: "https://aap.prci.com/api/v2/jobs/?format=json&page=1&page_size=200&order_by=-started"
    headers:
      Content-Type: application/json
      Authorization: "Bearer {{ lookup('env', 'TOWER_PASSWORD') }}"
  register: jobs_data

- name: Initialize jobs list
  set_fact:
    list_of_jobs_info: []
    current_page: 1

- name: Iterate through pages to collect recent jobs
  uri:
    url: "https://aap.prci.com/api/v2/jobs/?format=json&page={{ current_page }}&page_size=200&order_by=-started"
    headers:
      Content-Type: application/json
      Authorization: "Bearer {{ lookup('env', 'TOWER_PASSWORD') }}"
  register: current_page_data
  until: 
    - current_page_data.json.results | selectattr('started', '<=', half_hour_back) | list | length > 0
    - current_page_data.json.next is not defined
  loop_control:
    extended: yes
  when: current_page_data.json.next is defined or current_page == 1
  register: all_jobs_data

# 后续处理所有页面的数据...

2. 修复时间比较的格式问题

AAP中字符串形式的时间比较是严格的字典序,之前生成的half_hour_back缺少毫秒部分和时区标识Z,导致比较逻辑失效。有两种可靠的解决方式:

方式一:统一转换为时间戳比较

将API返回的started时间字符串转换为Unix时间戳,与提前计算好的半小时前的时间戳对比:

- set_fact:
    half_hour_back_epoch: "{{ (ansible_date_time.epoch | int) - 1800 }}"  # 30分钟=1800秒

- name: Add jobs data to dictionary
  set_fact:
    list_of_jobs_info: "{{ list_of_jobs_info + [{ 'job_id' : item['id'], 'job_name' : item['name'], 'job_status' : item['status'] }] }}"
  when:
    - item['status'] == "canceled"
    - (item['started'] | to_datetime('%Y-%m-%dT%H:%M:%S.%fZ')).strftime('%s') | int > half_hour_back_epoch
  loop: "{{ jobs_data['json']['results'] }}"

方式二:生成完全匹配格式的时间字符串

生成包含毫秒(设为000000)和时区Z的时间字符串,确保与API返回格式一致:

- set_fact:
    half_hour_back: "{{ '%Y-%m-%dT%H:%M:%S.000000Z' | strftime((ansible_date_time.epoch | int) - 1800) }}"

- name: Add jobs data to dictionary
  set_fact:
    list_of_jobs_info: "{{ list_of_jobs_info + [{ 'job_id' : item['id'], 'job_name' : item['name'], 'job_status' : item['status'] }] }}"
  when:
    - item['status'] == "canceled"
    - item['started'] > half_hour_back
  loop: "{{ jobs_data['json']['results'] }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:00:48