转换时间

问题描述 投票:0回答:1

我正在尝试将

%Y%m%d%H%M%S%Z
格式的证书到期日期转换为纪元,该日期将用于与从 Java 密钥库收集的另一个日期进行比较。为了保持简单(因为证书日期是 UTC/Zulu,Java 密钥库采用 CST),我想我会将日期转换为 UTC 和纪元,以便稍后在我的剧本中进行比较。但是,我收到一条错误,指出我的变量无法转换为字典。

以下是我收到错误之前的证书任务。

- name: Verifying Server Cert is present
  ansible.builtin.stat:
    path: /opt/ssl/{{ ansible_facts['hostname'] }}.crt
  register: cert_file
  tags: debug

- name: End play if cert if not found.
  ansible.builtin.assert:
    that:
      - cert_file.stat.exists == true
    fail_msg: Server Cert not found.
  tags: debug

- name: Find cert files under /opt/ssl
  ansible.builtin.find:
    paths: /opt/ssl
    file_type: file
    patterns: "*.crt"
    recurse: true
  register: find_result
  tags: cert
  when: cert_file.stat.exists == true

- name: Gather Cert info
  openssl_certificate_info:
    path: "{{ item.path }}"
  register: cert_info
  loop: "{{ find_result.files }}"
  tags: cert
  when: cert_file.stat.exists == true

- name: debug cert_info
  debug:
    msg: "{{ cert_info }}"

- name: Set full certificate expiration fact 
  ansible.builtin.set_fact:
    cert_exp_full: "{{ item.not_after }}"
  loop: "{{ cert_info.results }}"
  loop_control:
    label: "{{ item.subject.commonName}}"
  tags: cert
  when: cert_file.stat.exists == true

- name: debug
  debug:
    msg: "{{ cert_exp_full }}"

- name: Convert to epoch | Times are in UTC/Zulu
  ansible.builtin.set_fact:
    cert_epoch: "{{ (cert_exp_full | to_datetime('%Y%m%d%H%M%S%z')).strftime('%s') }}"
  tags: cert
  when: cert_file.stat.exists == true

那么输出如下:

PLAY [all] *****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************************
ok: [dtest08]

TASK [certs : Verifying Server Cert is present] ****************************************************************************************************************************************************************************
ok: [dtest08]

TASK [certs : End play if cert if not found.] ******************************************************************************************************************************************************************************
ok: [dtest08] => changed=false 
  msg: All assertions passed

TASK [certs : Find cert files under /opt/ssl] ******************************************************************************************************************************************************************************
ok: [dtest08]

TASK [certs : Gather Cert info] ********************************************************************************************************************************************************************************************
ok: [dtest08] => (item={'path': '/opt/ssl/dtest08.crt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 0, 'gid': 0, 'size': 1253, 'inode': 34241578, 'dev': 64768, 'nlink': 1, 'atime': 1704382642.2240086, 'mtime': 1675972923.0, 'ctime': 1701979001.5420384, 'gr_name': 'root', 'pw_name': 'root', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})

TASK [certs : debug cert_info] *********************************************************************************************************************************************************************************************
ok: [dtest08] => 
  msg:
    changed: false
    msg: All items completed
    results:
    - ansible_loop_var: item
      authority_cert_issuer: null
      authority_cert_serial_number: null
      authority_key_identifier: null
      basic_constraints: null
      basic_constraints_critical: false
      changed: false
      expired: false
      extended_key_usage: null
      extended_key_usage_critical: false
      extensions_by_oid: {}
      failed: false
      invocation:
        module_args:
          path: /opt/ssl/dtest08.crt
          select_crypto_backend: auto
          valid_at: null
      issuer:
        commonName: dtest
        countryName: US
        emailAddress: [email protected]
        localityName: Sheboygan
        organizationName: Default Company Ltd
        stateOrProvinceName: Wisconsin
      issuer_ordered:
      - - countryName
        - US
      - - stateOrProvinceName
        - Wisconsin
      - - localityName
        - Sheboygan
      - - organizationName
        - Default Company Ltd
      - - commonName
        - dtest
      - - emailAddress
        - [email protected]
      item:
        atime: 1704382642.2240086
        ctime: 1701979001.5420384
        dev: 64768
        gid: 0
        gr_name: root
        inode: 34241578
        isblk: false
        ischr: false
        isdir: false
        isfifo: false
        isgid: false
        islnk: false
        isreg: true
        issock: false
        isuid: false
        mode: '0644'
        mtime: 1675972923.0
        nlink: 1
        path: /opt/ssl/dtest08.crt
        pw_name: root
        rgrp: true
        roth: true
        rusr: true
        size: 1253
        uid: 0
        wgrp: false
        woth: false
        wusr: true
        xgrp: false
        xoth: false
        xusr: false
      key_usage: null
      key_usage_critical: false
      not_after: 20240209200203Z
      not_before: 20230209200203Z
      ocsp_must_staple: null
      ocsp_must_staple_critical: false
      ocsp_uri: null
      public_key: |-
        -----BEGIN PUBLIC KEY-----
         <REMOVED>
        -----END PUBLIC KEY-----
      public_key_fingerprints:
        blake2b: <REMOVED>
        blake2s: <REMOVED>
        md5: <REMOVED>
        sha1: <REMOVED>
        sha224: <REMOVED>
        sha256: <REMOVED>
        sha384: <REMOVED>
        sha3_224: <REMOVED>
        sha3_256: <REMOVED>
        sha3_384: <REMOVED>
        sha3_512: <REMOVED>
        sha512: <REMOVED>
        shake_128: <REMOVED>
        shake_256: <REMOVED>
      serial_number: <REMOVED>
      signature_algorithm: sha256WithRSAEncryption
      subject:
        commonName: dtest08
        countryName: US
        localityName: Sheboyga
        organizationName: Default Company Ltd
        stateOrProvinceName: Wisconsin
      subject_alt_name: null
      subject_alt_name_critical: false
      subject_key_identifier: null
      subject_ordered:
      - - countryName
        - US
      - - stateOrProvinceName
        - Wisconsin
      - - localityName
        - Sheboyga
      - - organizationName
        - Default Company Ltd
      - - commonName
        - dtest08
      valid_at: {}
      version: 1

TASK [certs : Set full certificate expiration fact] ************************************************************************************************************************************************
ok: [dtest08] => (item=dtest08)

TASK [certs : debug] *******************************************************************************************************************************************************************************************************
ok: [dtest08] => 
  msg: 20240209200203Z

TASK [certs : Convert to epoch | Times are in UTC/Zulu] ********************************************************************************************************************************************************************
fatal: [dtest08]: FAILED! => 
  msg: |-
    the field 'args' has an invalid value ({'cert_epoch': "{{ (cert_exp_full | to_datetime('%Y%m%d%H%M%S%z')).strftime('%s') }}"}), and could not be converted to an dict.The error was: time data '20240209200203Z' does not match format '%Y%m%d%H%M%S%z'
  
    The error appears to be in '/root/ansible/certs/roles/certs/tasks/main.yml': line 49, column 3, but may
    be elsewhere in the file depending on the exact syntax problem.
  
    The offending line appears to be:
  
  
    - name: Convert to epoch | Times are in UTC/Zulu
      ^ here

可能导致我的问题的另一个项目是我需要使用的 python 和 ansible 版本。

# ansible --version
ansible 2.9.25
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Jun 14 2022, 12:54:58) [GCC 8.5.0 20210514 (Red Hat 8.5.0-10)]

在运行 ansible v2.15.4 和 python3.11 的本地服务器上,这是有效的。

如何使用 ansible 2.9.25 和 python 3.6 克服此错误?我假设这是一个我不知道的语法问题(我对 python 不太熟悉)。提前致谢。

python ansible ssl-certificate
1个回答
0
投票

%z 是导致问题的原因 正确的时间格式为 %Y%m%d%H%M%SZ

Python 中的类似问题已被问到这里 如何将祖鲁时间换算为新纪元?

我尝试过的示例剧本

- name: Convert certificate expiration date to epoch
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Set certificate expiration date
      set_fact:
        cert_exp_date: '20240209200203Z'

    - name: Convert date to epoch
      ansible.builtin.set_fact:
        cert_epoch: "{{ (cert_exp_date | to_datetime('%Y%m%d%H%M%SZ')).strftime('%s') }}"

输出:

TASK [Convert date to epoch] ****************************************************************************************
ok: [localhost] => {"ansible_facts": {"cert_epoch": "1707508923"}, "changed": false}

用Python测试

Python 3.8.10 (default, Nov 22 2023, 10:22:35) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> date_str = '20240209200203Z'
>>> date_obj = datetime.strptime(date_str, "%Y%m%d%H%M%SZ")
>>> int(date_obj.timestamp())
1707508923
© www.soinside.com 2019 - 2024. All rights reserved.