all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fe1d:164b
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: e41a7fc0-dea7-43c2-97de-5eca427d078a
        host_id: 82101243836454d7401d5893feae9e2c5df7cc291646d8a99b33b53b
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fe1d:164b
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.0.100
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.193.198
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fe1d:164b
        region: null
        slot: null
  vars:
    zuul:
      _inheritance_path:
      - '<Job base explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-config/zuul.d/jobs.yaml@main#2>'
      - '<Job python-osism-unit-tests explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/python-osism/.zuul.yaml@main#133>'
      - '<Job python-osism-unit-tests explicit: None implied: None source: osism/python-osism/.zuul.yaml@main#143>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: 23fbf8a30fc74969925c7a682e4956c6
      build_refs:
      - branch: main
        change: '2547'
        change_message: "Add integration test for the Ansible Vault password round
          trip\n\n## What\n\n`get_ansible_vault_password()` (`osism/utils/__init__.py:355`)
          glues Fernet to\nRedis: the key comes from a keyfile, the token from Redis.
          Conductor workers\nread the vault secret through it (`osism/tasks/conductor/utils.py:75`).
          Every\nexisting test mocks one side of that chain, so nothing checks that
          the bytes\n`osism set vault password` writes come back through a live client
          and decrypt\nto the same string.\n\nThis adds one module to the integration
          lane that runs the chain against the\nlive Redis of the `python-osism-integration-tests`
          job, plus the single\nproduction change the module needs to redirect the
          keyfile.\n\nPart of #2400. Follow-up to #2368.\n\n## Changes (in commit
          order)\n\n1. **Hoist the Ansible Vault keyfile path into a module constant**:
          the path\n   lived in a local variable inside `get_ansible_vault_password()`,
          which no\n   test can redirect. It becomes `ANSIBLE_VAULT_KEYFILE`\n   (`osism/utils/__init__.py:29`)
          and the function reads that global at call\n   time. The default path is
          byte-identical, so there is no behavior change.\n\n2. **Add integration
          tests for the Ansible Vault password round trip**: new\n   module `tests/integration/test_vault.py`
          with seven tests.\n   - the direct round trip: a password encrypted with
          the keyfile's Fernet key\n     and stored under `ansible_vault_password`
          comes back as plaintext;\n   - no Redis key: `ValueError` matching \"not
          set in Redis\";\n   - blank password, both `\"\"` and a whitespace-only
          string: `ValueError`\n     matching \"empty or contains only whitespace\";\n
          \  - token written under a different Fernet key: `InvalidToken`;\n   - missing
          keyfile: `FileNotFoundError`, before Redis is touched;\n   - the command
          round trip in-process: `SetPassword` with a piped-stdin stub\n     generates
          the keyfile and stores the token, `Check --format script`\n     returns
          0 and prints `PASSED`, `UnsetPassword` removes the key again.\n\n   A `vault_keyfile`
          fixture points `utils.ANSIBLE_VAULT_KEYFILE`,\n   `SetPassword.keyfile`
          and `Check.keyfile` at `tmp_path`. An autouse\n   `clean_vault_key` fixture
          deletes the `ansible_vault_password` key before\n   and after every test,
          since the key name is fixed and the Redis database is\n   shared by the
          whole integration session.\n\nNo change to `tests/integration/conftest.py`,\n`playbooks/test-integration.yml`,
          `Pipfile` or `setup.cfg`, and no new\ndependency: `cryptography` is already
          imported the same way by\n`osism/commands/vault.py:25`.\n\n## Notes\n\n-
          `Check`'s last step decrypts a `secrets.yml` found on the host. It needs\n
          \ ansible-core and would tie the test to the filesystem, so\n  `Check._find_secrets_file`
          is stubbed to return `None`.\n- The commands run in-process rather than
          as a subprocess: there is no\n  environment-variable override for the keyfile
          path, so a child process\n  offers no way to redirect it.\n- `SetPassword.keyfile`
          and `Check.keyfile` (`osism/commands/vault.py:18`,\n  `:134`) keep their
          own class attributes. Folding them into the new constant\n  would change
          command classes this change does not otherwise touch.\n\n## Test plan\n\n-
          Verified against a throwaway `redis:7-alpine` container:\n  `REDIS_HOST=localhost
          OSISM_REQUIRE_REDIS=1 pytest tests/integration/test_vault.py`\n  gives 7
          passed. With the constant absent, all 7 error on\n  `AttributeError: module
          'osism.utils' has no attribute 'ANSIBLE_VAULT_KEYFILE'`.\n- `pytest tests/unit/commands/test_vault.py
          tests/unit/utils/test_init_task_output.py`\n  gives 77 passed. The existing
          unit tests patch `builtins.open` without\n  asserting the path, so the hoist
          leaves them green.\n- `black --check` reports both files unchanged. `flake8`
          and `mypy` were not\n  run locally; the jobs of the same name cover them
          here.\n\nCloses #2402\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          with Claude:claude-opus-5[1m]_\n"
        change_url: https://github.com/osism/python-osism/pull/2547
        commit_id: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        patchset: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      buildset: 1d8c8a1c207a40918cd9f44a9791a4e2
      buildset_refs:
      - branch: main
        change: '2547'
        change_message: "Add integration test for the Ansible Vault password round
          trip\n\n## What\n\n`get_ansible_vault_password()` (`osism/utils/__init__.py:355`)
          glues Fernet to\nRedis: the key comes from a keyfile, the token from Redis.
          Conductor workers\nread the vault secret through it (`osism/tasks/conductor/utils.py:75`).
          Every\nexisting test mocks one side of that chain, so nothing checks that
          the bytes\n`osism set vault password` writes come back through a live client
          and decrypt\nto the same string.\n\nThis adds one module to the integration
          lane that runs the chain against the\nlive Redis of the `python-osism-integration-tests`
          job, plus the single\nproduction change the module needs to redirect the
          keyfile.\n\nPart of #2400. Follow-up to #2368.\n\n## Changes (in commit
          order)\n\n1. **Hoist the Ansible Vault keyfile path into a module constant**:
          the path\n   lived in a local variable inside `get_ansible_vault_password()`,
          which no\n   test can redirect. It becomes `ANSIBLE_VAULT_KEYFILE`\n   (`osism/utils/__init__.py:29`)
          and the function reads that global at call\n   time. The default path is
          byte-identical, so there is no behavior change.\n\n2. **Add integration
          tests for the Ansible Vault password round trip**: new\n   module `tests/integration/test_vault.py`
          with seven tests.\n   - the direct round trip: a password encrypted with
          the keyfile's Fernet key\n     and stored under `ansible_vault_password`
          comes back as plaintext;\n   - no Redis key: `ValueError` matching \"not
          set in Redis\";\n   - blank password, both `\"\"` and a whitespace-only
          string: `ValueError`\n     matching \"empty or contains only whitespace\";\n
          \  - token written under a different Fernet key: `InvalidToken`;\n   - missing
          keyfile: `FileNotFoundError`, before Redis is touched;\n   - the command
          round trip in-process: `SetPassword` with a piped-stdin stub\n     generates
          the keyfile and stores the token, `Check --format script`\n     returns
          0 and prints `PASSED`, `UnsetPassword` removes the key again.\n\n   A `vault_keyfile`
          fixture points `utils.ANSIBLE_VAULT_KEYFILE`,\n   `SetPassword.keyfile`
          and `Check.keyfile` at `tmp_path`. An autouse\n   `clean_vault_key` fixture
          deletes the `ansible_vault_password` key before\n   and after every test,
          since the key name is fixed and the Redis database is\n   shared by the
          whole integration session.\n\nNo change to `tests/integration/conftest.py`,\n`playbooks/test-integration.yml`,
          `Pipfile` or `setup.cfg`, and no new\ndependency: `cryptography` is already
          imported the same way by\n`osism/commands/vault.py:25`.\n\n## Notes\n\n-
          `Check`'s last step decrypts a `secrets.yml` found on the host. It needs\n
          \ ansible-core and would tie the test to the filesystem, so\n  `Check._find_secrets_file`
          is stubbed to return `None`.\n- The commands run in-process rather than
          as a subprocess: there is no\n  environment-variable override for the keyfile
          path, so a child process\n  offers no way to redirect it.\n- `SetPassword.keyfile`
          and `Check.keyfile` (`osism/commands/vault.py:18`,\n  `:134`) keep their
          own class attributes. Folding them into the new constant\n  would change
          command classes this change does not otherwise touch.\n\n## Test plan\n\n-
          Verified against a throwaway `redis:7-alpine` container:\n  `REDIS_HOST=localhost
          OSISM_REQUIRE_REDIS=1 pytest tests/integration/test_vault.py`\n  gives 7
          passed. With the constant absent, all 7 error on\n  `AttributeError: module
          'osism.utils' has no attribute 'ANSIBLE_VAULT_KEYFILE'`.\n- `pytest tests/unit/commands/test_vault.py
          tests/unit/utils/test_init_task_output.py`\n  gives 77 passed. The existing
          unit tests patch `builtins.open` without\n  asserting the path, so the hoist
          leaves them green.\n- `black --check` reports both files unchanged. `flake8`
          and `mypy` were not\n  run locally; the jobs of the same name cover them
          here.\n\nCloses #2402\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          with Claude:claude-opus-5[1m]_\n"
        change_url: https://github.com/osism/python-osism/pull/2547
        commit_id: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        patchset: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
        src_dir: src/github.com/osism/python-osism
        topic: null
      change: '2547'
      change_message: "Add integration test for the Ansible Vault password round trip\n\n##
        What\n\n`get_ansible_vault_password()` (`osism/utils/__init__.py:355`) glues
        Fernet to\nRedis: the key comes from a keyfile, the token from Redis. Conductor
        workers\nread the vault secret through it (`osism/tasks/conductor/utils.py:75`).
        Every\nexisting test mocks one side of that chain, so nothing checks that
        the bytes\n`osism set vault password` writes come back through a live client
        and decrypt\nto the same string.\n\nThis adds one module to the integration
        lane that runs the chain against the\nlive Redis of the `python-osism-integration-tests`
        job, plus the single\nproduction change the module needs to redirect the keyfile.\n\nPart
        of #2400. Follow-up to #2368.\n\n## Changes (in commit order)\n\n1. **Hoist
        the Ansible Vault keyfile path into a module constant**: the path\n   lived
        in a local variable inside `get_ansible_vault_password()`, which no\n   test
        can redirect. It becomes `ANSIBLE_VAULT_KEYFILE`\n   (`osism/utils/__init__.py:29`)
        and the function reads that global at call\n   time. The default path is byte-identical,
        so there is no behavior change.\n\n2. **Add integration tests for the Ansible
        Vault password round trip**: new\n   module `tests/integration/test_vault.py`
        with seven tests.\n   - the direct round trip: a password encrypted with the
        keyfile's Fernet key\n     and stored under `ansible_vault_password` comes
        back as plaintext;\n   - no Redis key: `ValueError` matching \"not set in
        Redis\";\n   - blank password, both `\"\"` and a whitespace-only string: `ValueError`\n
        \    matching \"empty or contains only whitespace\";\n   - token written under
        a different Fernet key: `InvalidToken`;\n   - missing keyfile: `FileNotFoundError`,
        before Redis is touched;\n   - the command round trip in-process: `SetPassword`
        with a piped-stdin stub\n     generates the keyfile and stores the token,
        `Check --format script`\n     returns 0 and prints `PASSED`, `UnsetPassword`
        removes the key again.\n\n   A `vault_keyfile` fixture points `utils.ANSIBLE_VAULT_KEYFILE`,\n
        \  `SetPassword.keyfile` and `Check.keyfile` at `tmp_path`. An autouse\n   `clean_vault_key`
        fixture deletes the `ansible_vault_password` key before\n   and after every
        test, since the key name is fixed and the Redis database is\n   shared by
        the whole integration session.\n\nNo change to `tests/integration/conftest.py`,\n`playbooks/test-integration.yml`,
        `Pipfile` or `setup.cfg`, and no new\ndependency: `cryptography` is already
        imported the same way by\n`osism/commands/vault.py:25`.\n\n## Notes\n\n- `Check`'s
        last step decrypts a `secrets.yml` found on the host. It needs\n  ansible-core
        and would tie the test to the filesystem, so\n  `Check._find_secrets_file`
        is stubbed to return `None`.\n- The commands run in-process rather than as
        a subprocess: there is no\n  environment-variable override for the keyfile
        path, so a child process\n  offers no way to redirect it.\n- `SetPassword.keyfile`
        and `Check.keyfile` (`osism/commands/vault.py:18`,\n  `:134`) keep their own
        class attributes. Folding them into the new constant\n  would change command
        classes this change does not otherwise touch.\n\n## Test plan\n\n- Verified
        against a throwaway `redis:7-alpine` container:\n  `REDIS_HOST=localhost OSISM_REQUIRE_REDIS=1
        pytest tests/integration/test_vault.py`\n  gives 7 passed. With the constant
        absent, all 7 error on\n  `AttributeError: module 'osism.utils' has no attribute
        'ANSIBLE_VAULT_KEYFILE'`.\n- `pytest tests/unit/commands/test_vault.py tests/unit/utils/test_init_task_output.py`\n
        \ gives 77 passed. The existing unit tests patch `builtins.open` without\n
        \ asserting the path, so the hoist leaves them green.\n- `black --check` reports
        both files unchanged. `flake8` and `mypy` were not\n  run locally; the jobs
        of the same name cover them here.\n\nCloses #2402\n\n---\n\n_Implemented by
        [planwerk-agent](https://github.com/planwerk/planwerk-agent) with Claude:claude-opus-5[1m]_\n"
      change_url: https://github.com/osism/python-osism/pull/2547
      child_jobs: []
      commit_id: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
      event_id: ac46e8a0-8f06-11f1-8ddb-3261e8fca163
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/23fbf8a30fc74969925c7a682e4956c6/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/23fbf8a30fc74969925c7a682e4956c6/work/logs
        result_data_file: /var/lib/zuul/builds/23fbf8a30fc74969925c7a682e4956c6/work/results.json
        src_root: /var/lib/zuul/builds/23fbf8a30fc74969925c7a682e4956c6/work/src
        work_root: /var/lib/zuul/builds/23fbf8a30fc74969925c7a682e4956c6/work
      include_vars: []
      items:
      - branch: main
        change: '2547'
        change_message: "Add integration test for the Ansible Vault password round
          trip\n\n## What\n\n`get_ansible_vault_password()` (`osism/utils/__init__.py:355`)
          glues Fernet to\nRedis: the key comes from a keyfile, the token from Redis.
          Conductor workers\nread the vault secret through it (`osism/tasks/conductor/utils.py:75`).
          Every\nexisting test mocks one side of that chain, so nothing checks that
          the bytes\n`osism set vault password` writes come back through a live client
          and decrypt\nto the same string.\n\nThis adds one module to the integration
          lane that runs the chain against the\nlive Redis of the `python-osism-integration-tests`
          job, plus the single\nproduction change the module needs to redirect the
          keyfile.\n\nPart of #2400. Follow-up to #2368.\n\n## Changes (in commit
          order)\n\n1. **Hoist the Ansible Vault keyfile path into a module constant**:
          the path\n   lived in a local variable inside `get_ansible_vault_password()`,
          which no\n   test can redirect. It becomes `ANSIBLE_VAULT_KEYFILE`\n   (`osism/utils/__init__.py:29`)
          and the function reads that global at call\n   time. The default path is
          byte-identical, so there is no behavior change.\n\n2. **Add integration
          tests for the Ansible Vault password round trip**: new\n   module `tests/integration/test_vault.py`
          with seven tests.\n   - the direct round trip: a password encrypted with
          the keyfile's Fernet key\n     and stored under `ansible_vault_password`
          comes back as plaintext;\n   - no Redis key: `ValueError` matching \"not
          set in Redis\";\n   - blank password, both `\"\"` and a whitespace-only
          string: `ValueError`\n     matching \"empty or contains only whitespace\";\n
          \  - token written under a different Fernet key: `InvalidToken`;\n   - missing
          keyfile: `FileNotFoundError`, before Redis is touched;\n   - the command
          round trip in-process: `SetPassword` with a piped-stdin stub\n     generates
          the keyfile and stores the token, `Check --format script`\n     returns
          0 and prints `PASSED`, `UnsetPassword` removes the key again.\n\n   A `vault_keyfile`
          fixture points `utils.ANSIBLE_VAULT_KEYFILE`,\n   `SetPassword.keyfile`
          and `Check.keyfile` at `tmp_path`. An autouse\n   `clean_vault_key` fixture
          deletes the `ansible_vault_password` key before\n   and after every test,
          since the key name is fixed and the Redis database is\n   shared by the
          whole integration session.\n\nNo change to `tests/integration/conftest.py`,\n`playbooks/test-integration.yml`,
          `Pipfile` or `setup.cfg`, and no new\ndependency: `cryptography` is already
          imported the same way by\n`osism/commands/vault.py:25`.\n\n## Notes\n\n-
          `Check`'s last step decrypts a `secrets.yml` found on the host. It needs\n
          \ ansible-core and would tie the test to the filesystem, so\n  `Check._find_secrets_file`
          is stubbed to return `None`.\n- The commands run in-process rather than
          as a subprocess: there is no\n  environment-variable override for the keyfile
          path, so a child process\n  offers no way to redirect it.\n- `SetPassword.keyfile`
          and `Check.keyfile` (`osism/commands/vault.py:18`,\n  `:134`) keep their
          own class attributes. Folding them into the new constant\n  would change
          command classes this change does not otherwise touch.\n\n## Test plan\n\n-
          Verified against a throwaway `redis:7-alpine` container:\n  `REDIS_HOST=localhost
          OSISM_REQUIRE_REDIS=1 pytest tests/integration/test_vault.py`\n  gives 7
          passed. With the constant absent, all 7 error on\n  `AttributeError: module
          'osism.utils' has no attribute 'ANSIBLE_VAULT_KEYFILE'`.\n- `pytest tests/unit/commands/test_vault.py
          tests/unit/utils/test_init_task_output.py`\n  gives 77 passed. The existing
          unit tests patch `builtins.open` without\n  asserting the path, so the hoist
          leaves them green.\n- `black --check` reports both files unchanged. `flake8`
          and `mypy` were not\n  run locally; the jobs of the same name cover them
          here.\n\nCloses #2402\n\n---\n\n_Implemented by [planwerk-agent](https://github.com/planwerk/planwerk-agent)
          with Claude:claude-opus-5[1m]_\n"
        change_url: https://github.com/osism/python-osism/pull/2547
        commit_id: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        patchset: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
        project:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          name: osism/python-osism
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
        topic: null
      job: python-osism-unit-tests
      jobtags: []
      max_attempts: 3
      message: QWRkIGludGVncmF0aW9uIHRlc3QgZm9yIHRoZSBBbnNpYmxlIFZhdWx0IHBhc3N3b3JkIHJvdW5kIHRyaXAKCiMjIFdoYXQKCmBnZXRfYW5zaWJsZV92YXVsdF9wYXNzd29yZCgpYCAoYG9zaXNtL3V0aWxzL19faW5pdF9fLnB5OjM1NWApIGdsdWVzIEZlcm5ldCB0bwpSZWRpczogdGhlIGtleSBjb21lcyBmcm9tIGEga2V5ZmlsZSwgdGhlIHRva2VuIGZyb20gUmVkaXMuIENvbmR1Y3RvciB3b3JrZXJzCnJlYWQgdGhlIHZhdWx0IHNlY3JldCB0aHJvdWdoIGl0IChgb3Npc20vdGFza3MvY29uZHVjdG9yL3V0aWxzLnB5Ojc1YCkuIEV2ZXJ5CmV4aXN0aW5nIHRlc3QgbW9ja3Mgb25lIHNpZGUgb2YgdGhhdCBjaGFpbiwgc28gbm90aGluZyBjaGVja3MgdGhhdCB0aGUgYnl0ZXMKYG9zaXNtIHNldCB2YXVsdCBwYXNzd29yZGAgd3JpdGVzIGNvbWUgYmFjayB0aHJvdWdoIGEgbGl2ZSBjbGllbnQgYW5kIGRlY3J5cHQKdG8gdGhlIHNhbWUgc3RyaW5nLgoKVGhpcyBhZGRzIG9uZSBtb2R1bGUgdG8gdGhlIGludGVncmF0aW9uIGxhbmUgdGhhdCBydW5zIHRoZSBjaGFpbiBhZ2FpbnN0IHRoZQpsaXZlIFJlZGlzIG9mIHRoZSBgcHl0aG9uLW9zaXNtLWludGVncmF0aW9uLXRlc3RzYCBqb2IsIHBsdXMgdGhlIHNpbmdsZQpwcm9kdWN0aW9uIGNoYW5nZSB0aGUgbW9kdWxlIG5lZWRzIHRvIHJlZGlyZWN0IHRoZSBrZXlmaWxlLgoKUGFydCBvZiAjMjQwMC4gRm9sbG93LXVwIHRvICMyMzY4LgoKIyMgQ2hhbmdlcyAoaW4gY29tbWl0IG9yZGVyKQoKMS4gKipIb2lzdCB0aGUgQW5zaWJsZSBWYXVsdCBrZXlmaWxlIHBhdGggaW50byBhIG1vZHVsZSBjb25zdGFudCoqOiB0aGUgcGF0aAogICBsaXZlZCBpbiBhIGxvY2FsIHZhcmlhYmxlIGluc2lkZSBgZ2V0X2Fuc2libGVfdmF1bHRfcGFzc3dvcmQoKWAsIHdoaWNoIG5vCiAgIHRlc3QgY2FuIHJlZGlyZWN0LiBJdCBiZWNvbWVzIGBBTlNJQkxFX1ZBVUxUX0tFWUZJTEVgCiAgIChgb3Npc20vdXRpbHMvX19pbml0X18ucHk6MjlgKSBhbmQgdGhlIGZ1bmN0aW9uIHJlYWRzIHRoYXQgZ2xvYmFsIGF0IGNhbGwKICAgdGltZS4gVGhlIGRlZmF1bHQgcGF0aCBpcyBieXRlLWlkZW50aWNhbCwgc28gdGhlcmUgaXMgbm8gYmVoYXZpb3IgY2hhbmdlLgoKMi4gKipBZGQgaW50ZWdyYXRpb24gdGVzdHMgZm9yIHRoZSBBbnNpYmxlIFZhdWx0IHBhc3N3b3JkIHJvdW5kIHRyaXAqKjogbmV3CiAgIG1vZHVsZSBgdGVzdHMvaW50ZWdyYXRpb24vdGVzdF92YXVsdC5weWAgd2l0aCBzZXZlbiB0ZXN0cy4KICAgLSB0aGUgZGlyZWN0IHJvdW5kIHRyaXA6IGEgcGFzc3dvcmQgZW5jcnlwdGVkIHdpdGggdGhlIGtleWZpbGUncyBGZXJuZXQga2V5CiAgICAgYW5kIHN0b3JlZCB1bmRlciBgYW5zaWJsZV92YXVsdF9wYXNzd29yZGAgY29tZXMgYmFjayBhcyBwbGFpbnRleHQ7CiAgIC0gbm8gUmVkaXMga2V5OiBgVmFsdWVFcnJvcmAgbWF0Y2hpbmcgIm5vdCBzZXQgaW4gUmVkaXMiOwogICAtIGJsYW5rIHBhc3N3b3JkLCBib3RoIGAiImAgYW5kIGEgd2hpdGVzcGFjZS1vbmx5IHN0cmluZzogYFZhbHVlRXJyb3JgCiAgICAgbWF0Y2hpbmcgImVtcHR5IG9yIGNvbnRhaW5zIG9ubHkgd2hpdGVzcGFjZSI7CiAgIC0gdG9rZW4gd3JpdHRlbiB1bmRlciBhIGRpZmZlcmVudCBGZXJuZXQga2V5OiBgSW52YWxpZFRva2VuYDsKICAgLSBtaXNzaW5nIGtleWZpbGU6IGBGaWxlTm90Rm91bmRFcnJvcmAsIGJlZm9yZSBSZWRpcyBpcyB0b3VjaGVkOwogICAtIHRoZSBjb21tYW5kIHJvdW5kIHRyaXAgaW4tcHJvY2VzczogYFNldFBhc3N3b3JkYCB3aXRoIGEgcGlwZWQtc3RkaW4gc3R1YgogICAgIGdlbmVyYXRlcyB0aGUga2V5ZmlsZSBhbmQgc3RvcmVzIHRoZSB0b2tlbiwgYENoZWNrIC0tZm9ybWF0IHNjcmlwdGAKICAgICByZXR1cm5zIDAgYW5kIHByaW50cyBgUEFTU0VEYCwgYFVuc2V0UGFzc3dvcmRgIHJlbW92ZXMgdGhlIGtleSBhZ2Fpbi4KCiAgIEEgYHZhdWx0X2tleWZpbGVgIGZpeHR1cmUgcG9pbnRzIGB1dGlscy5BTlNJQkxFX1ZBVUxUX0tFWUZJTEVgLAogICBgU2V0UGFzc3dvcmQua2V5ZmlsZWAgYW5kIGBDaGVjay5rZXlmaWxlYCBhdCBgdG1wX3BhdGhgLiBBbiBhdXRvdXNlCiAgIGBjbGVhbl92YXVsdF9rZXlgIGZpeHR1cmUgZGVsZXRlcyB0aGUgYGFuc2libGVfdmF1bHRfcGFzc3dvcmRgIGtleSBiZWZvcmUKICAgYW5kIGFmdGVyIGV2ZXJ5IHRlc3QsIHNpbmNlIHRoZSBrZXkgbmFtZSBpcyBmaXhlZCBhbmQgdGhlIFJlZGlzIGRhdGFiYXNlIGlzCiAgIHNoYXJlZCBieSB0aGUgd2hvbGUgaW50ZWdyYXRpb24gc2Vzc2lvbi4KCk5vIGNoYW5nZSB0byBgdGVzdHMvaW50ZWdyYXRpb24vY29uZnRlc3QucHlgLApgcGxheWJvb2tzL3Rlc3QtaW50ZWdyYXRpb24ueW1sYCwgYFBpcGZpbGVgIG9yIGBzZXR1cC5jZmdgLCBhbmQgbm8gbmV3CmRlcGVuZGVuY3k6IGBjcnlwdG9ncmFwaHlgIGlzIGFscmVhZHkgaW1wb3J0ZWQgdGhlIHNhbWUgd2F5IGJ5CmBvc2lzbS9jb21tYW5kcy92YXVsdC5weToyNWAuCgojIyBOb3RlcwoKLSBgQ2hlY2tgJ3MgbGFzdCBzdGVwIGRlY3J5cHRzIGEgYHNlY3JldHMueW1sYCBmb3VuZCBvbiB0aGUgaG9zdC4gSXQgbmVlZHMKICBhbnNpYmxlLWNvcmUgYW5kIHdvdWxkIHRpZSB0aGUgdGVzdCB0byB0aGUgZmlsZXN5c3RlbSwgc28KICBgQ2hlY2suX2ZpbmRfc2VjcmV0c19maWxlYCBpcyBzdHViYmVkIHRvIHJldHVybiBgTm9uZWAuCi0gVGhlIGNvbW1hbmRzIHJ1biBpbi1wcm9jZXNzIHJhdGhlciB0aGFuIGFzIGEgc3VicHJvY2VzczogdGhlcmUgaXMgbm8KICBlbnZpcm9ubWVudC12YXJpYWJsZSBvdmVycmlkZSBmb3IgdGhlIGtleWZpbGUgcGF0aCwgc28gYSBjaGlsZCBwcm9jZXNzCiAgb2ZmZXJzIG5vIHdheSB0byByZWRpcmVjdCBpdC4KLSBgU2V0UGFzc3dvcmQua2V5ZmlsZWAgYW5kIGBDaGVjay5rZXlmaWxlYCAoYG9zaXNtL2NvbW1hbmRzL3ZhdWx0LnB5OjE4YCwKICBgOjEzNGApIGtlZXAgdGhlaXIgb3duIGNsYXNzIGF0dHJpYnV0ZXMuIEZvbGRpbmcgdGhlbSBpbnRvIHRoZSBuZXcgY29uc3RhbnQKICB3b3VsZCBjaGFuZ2UgY29tbWFuZCBjbGFzc2VzIHRoaXMgY2hhbmdlIGRvZXMgbm90IG90aGVyd2lzZSB0b3VjaC4KCiMjIFRlc3QgcGxhbgoKLSBWZXJpZmllZCBhZ2FpbnN0IGEgdGhyb3dhd2F5IGByZWRpczo3LWFscGluZWAgY29udGFpbmVyOgogIGBSRURJU19IT1NUPWxvY2FsaG9zdCBPU0lTTV9SRVFVSVJFX1JFRElTPTEgcHl0ZXN0IHRlc3RzL2ludGVncmF0aW9uL3Rlc3RfdmF1bHQucHlgCiAgZ2l2ZXMgNyBwYXNzZWQuIFdpdGggdGhlIGNvbnN0YW50IGFic2VudCwgYWxsIDcgZXJyb3Igb24KICBgQXR0cmlidXRlRXJyb3I6IG1vZHVsZSAnb3Npc20udXRpbHMnIGhhcyBubyBhdHRyaWJ1dGUgJ0FOU0lCTEVfVkFVTFRfS0VZRklMRSdgLgotIGBweXRlc3QgdGVzdHMvdW5pdC9jb21tYW5kcy90ZXN0X3ZhdWx0LnB5IHRlc3RzL3VuaXQvdXRpbHMvdGVzdF9pbml0X3Rhc2tfb3V0cHV0LnB5YAogIGdpdmVzIDc3IHBhc3NlZC4gVGhlIGV4aXN0aW5nIHVuaXQgdGVzdHMgcGF0Y2ggYGJ1aWx0aW5zLm9wZW5gIHdpdGhvdXQKICBhc3NlcnRpbmcgdGhlIHBhdGgsIHNvIHRoZSBob2lzdCBsZWF2ZXMgdGhlbSBncmVlbi4KLSBgYmxhY2sgLS1jaGVja2AgcmVwb3J0cyBib3RoIGZpbGVzIHVuY2hhbmdlZC4gYGZsYWtlOGAgYW5kIGBteXB5YCB3ZXJlIG5vdAogIHJ1biBsb2NhbGx5OyB0aGUgam9icyBvZiB0aGUgc2FtZSBuYW1lIGNvdmVyIHRoZW0gaGVyZS4KCkNsb3NlcyAjMjQwMgoKLS0tCgpfSW1wbGVtZW50ZWQgYnkgW3BsYW53ZXJrLWFnZW50XShodHRwczovL2dpdGh1Yi5jb20vcGxhbndlcmsvcGxhbndlcmstYWdlbnQpIHdpdGggQ2xhdWRlOmNsYXVkZS1vcHVzLTVbMW1dXwo=
      patchset: c3d1cfc81e2dfc9ebbaea82e5d0d0f3732271147
      pipeline: check
      playbook_context:
        playbook_projects:
          trusted/project_0/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          trusted/project_1/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          trusted/project_2/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
          untrusted/project_0/github.com/osism/python-osism:
            canonical_name: github.com/osism/python-osism
            checkout: main
            commit: 3621b907c8b7d3e5d393ae98ede342827620729f
          untrusted/project_1/github.com/osism/zuul-config:
            canonical_name: github.com/osism/zuul-config
            checkout: main
            commit: 71b711c422c10c242a8f785dc6d41ed9d12e9cd3
          untrusted/project_2/github.com/osism/openinfra-zuul-jobs:
            canonical_name: github.com/osism/openinfra-zuul-jobs
            checkout: master
            commit: 242732586e2cba04d04867d3e302888c766bc231
          untrusted/project_3/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: dcb06ea8a3ad422cc9d98b376216617b2daa6a02
        playbooks:
        - path: untrusted/project_0/github.com/osism/python-osism/playbooks/test-unit.yml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_1/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_1/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_2/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_2/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_3/zuul-jobs
            link_target: untrusted/project_3/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_3/zuul-jobs/roles
      post_review: false
      post_timeout: 1800
      pre_timeout: null
      project:
        canonical_hostname: github.com
        canonical_name: github.com/osism/python-osism
        name: osism/python-osism
        short_name: python-osism
        src_dir: src/github.com/osism/python-osism
      projects:
        github.com/osism/python-osism:
          canonical_hostname: github.com
          canonical_name: github.com/osism/python-osism
          checkout: main
          checkout_description: zuul branch
          commit: 3621b907c8b7d3e5d393ae98ede342827620729f
          name: osism/python-osism
          required: false
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
      ref: refs/pull/2547/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
