如何使用 os_volume_snapshot 模块编写剧本以删除超过 10 天的 OpenStack 卷快照

how to write a playbook to delete OpenStack volume snapshot of older than 10 days using os_volume_snapshot module

---
- name: Creating a volume snapshot
  hosts: Test-ctrl
  gather_facts: True
  tasks:
  - name: Creating snapshot of Test
    os_volume_snapshot:
      auth:
        auth_url: http://20.10.X.X:5000/v3/
        username: XXXXXXX
        password: XCXCXCXC
        project_name: test-stack
        project_domain_name: Default
        user_domain_name: Default
      state: absent
      validate_certs: False
      display_name: Test- {{ lookup('pipe','date +%Y-%m-%d-%H-%M-%S') }}
      volume: Test-1
      force: yes

如何编写剧本来删除超过 10 天的 OpenStack 卷快照

这是我创建音量的剧本。但自定义删除超过 10 天或 5 天的卷 ?????

我也需要这样做,但遗憾的是,os_volume_snapshot 模块无法做到这一点。也不可能在 Ansible (2.9) 中使用任何 OpenStack 模块。此外,os_volume_snapshot 使 volume 参数成为必需参数(这很愚蠢 - 因为您不需要知道原始卷的名称即可删除快照)。

所以,如果你“必须”使用 os_volume_snapshot 那么你就不走运了。

内置的 os_ 模块在 Ansible 中全面控制 OpenStack 集群方面是一个“正在进行的工作”,对于您所确定的任务,它几乎没有用处.

但是...等等...

像你一样,我需要自动化这个并且它可以完成 使用 Ansible 和 官方 python-openstackclient 模块。好的 - 它不是“纯粹的”Ansible(即它不使用纯内置模块)但它是一个使用内置 command 模块的剧本并且它有效。

(顺便说一句 - 以下内容不提供任何保证 - 使用风险自负)

所以,这是我 运行 的剧本,它 删除已达到定义期限的快照卷 。您将需要提供以下变量...

Yes, there are better ways to provide OpenStack variables (like cloud files or OS_ environment variables etc.) but I've made all those that are required explicit so it's easier to know what's actually required.

  • os_auth_url(即“https://example.com:5000/v3”)
  • os_username
  • os_password
  • os_project_name
  • os_project_domain_name(即“默认”)
  • os_user_domain_name

  • retirement_age_days。天数的 +ve 值,其中已达到该期限的所有快照卷都将被删除。如果为 0,则删除所有快照。

剧本的作用摘要:-

  1. 它使用openstack volume snapshot list获取项目中的快照卷列表
  2. 然后它使用 openstack volume snapshot show 获取有关每个快照的信息(即它的 created_at 日期)并构建大量卷年龄(以天为单位)
  3. 然后它使用 openstack volume snapshot delete 删除所有被认为太旧的卷
---

- hosts: localhost
  tasks:

  # Delete all project snapshots that are too old.

  # The user is expected to define the variable 'retirement_age_days'
  # where all volumes that have reached that age are deleted.
  # If 0 all snapshots are deleted.
  #
  # The user is also required to define OpenStack variables.

  - name: Assert control variables
    assert:
      that:
      - retirement_age_days is defined
      - retirement_age_days|int >= 0
      - os_auth_url is defined
      - os_username is defined
      - os_password is defined
      - os_project_name is defined
      - os_project_domain_name is defined
      - os_user_domain_name is defined

  # Expectation here is that you have the following OpenStack information: -
  #
  # - auth_url (i.e. "https://example.com:5000/v3")
  # - username
  # - password
  # - project_name
  # - project_domain_name (i.e. "Default")
  # - user_domain_name

  # We rely in the OpenStack client - the Ansible "os_" module
  # (Ansible 2.9) does not do what we need, so we need the client.
  # It' Python so make sure it's available...

  - name: Install prerequisite Python modules
    pip:
      name:
      - python-openstackclient==5.3.1
      extra_args: --user

  - name: Set snapshot command
    set_fact:
      snapshot_cmd: openstack volume snapshot

  # To avoid cluttering the command-line we
  # define all the credential material as a map of variables
  # that we then apply as the 'environment' for each command invocation.

  - name: Define OpenStack environment
    set_fact:
      os_env:
        OS_AUTH_URL: "{{ os_auth_url }}"
        OS_USERNAME: "{{ os_username }}"
        OS_PASSWORD: "{{ os_password }}"
        OS_PROJECT_NAME: "{{ os_project_name }}"
        OS_PROJECT_DOMAIN_NAME: "{{ os_project_domain_name }}"
        OS_USER_DOMAIN_NAME: "{{ os_user_domain_name }}"

  # Get all the snapshot names in the project.
  # The result is a json structure that we parse
  # in order to get just the names...

  - name: Get snapshots
    command: "{{ snapshot_cmd }} list --format json"
    environment: "{{ os_env }}"
    changed_when: false
    register: snap_result

  - name: Collect snapshot volume names
    set_fact:
      snap_volume_names: "{{ snap_result.stdout|from_json|json_query(query)|flatten }}"
    vars:
      query: "[*].Name"

  - name: Display existing snapshot volumes
    debug:
      var: snap_volume_names

  # For each snapshot, get its 'info'.
  # The combined results are then parsed in order to
  # locate each volume's 'created_at' date.
  # We compare that to 'now' in order to build a list of
  # volume ages (in days)...

  - name: Get snapshot volume info
    command: "{{ snapshot_cmd }} show {{ item }} --format json"
    environment: "{{ os_env }}"
    changed_when: false
    register: snap_volume_info
    loop: "{{ snap_volume_names }}"

  - name: Create snapshot age list (days)
    set_fact:
      snap_volume_ages: >-
        {{
          snap_volume_ages|default([]) +
          [ ((ansible_date_time.iso8601|to_datetime(fmt_1)) -
             (item.stdout|from_json|json_query(query)|to_datetime(fmt_2))).days ]
        }}
    vars:
      query: "created_at"
      fmt_1: "%Y-%m-%dT%H:%M:%SZ"
      fmt_2: "%Y-%m-%dT%H:%M:%S.%f"
    loop: "{{ snap_volume_info.results }}"

  # Using the combined volume names and ages lists
  # iterate through the ages and delete volumes have reached their age limit...

  - name: Delete old snapshots
    command: "{{ snapshot_cmd }} delete {{ item.1 }}"
    environment: "{{ os_env }}"
    changed_when: true
    when: item.0 >= retirement_age_days|int
    with_together:
    - "{{ snap_volume_ages|default([]) }}"
    - "{{ snap_volume_names|default([]) }}"