all:
  children:
    zuul_unreachable:
      hosts: {}
  hosts:
    debian-bookworm:
      ansible_connection: ssh
      ansible_host: 2a13:1a81:8000:3124:f816:3eff:fe71:fc2a
      ansible_port: 22
      ansible_python_interpreter: auto
      ansible_user: zuul
      nodepool:
        az: nova
        cloud: regiocloud-a-ci
        external_id: 624b703e-9801-4767-b596-864dafc11551
        host_id: 5afd8fc909abddfe2ce3a956a91bbe56629648b7209fd0acfa541862
        interface_ip: 2a13:1a81:8000:3124:f816:3eff:fe71:fc2a
        label: debian-bookworm
        node_properties: {}
        private_ipv4: 10.128.7.9
        private_ipv6: null
        provider: regiocloud-a
        public_ipv4: 81.163.192.226
        public_ipv6: 2a13:1a81:8000:3124:f816:3eff:fe71:fc2a
        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-black explicit: None implied: {MatchAny:{ImpliedBranchMatcher:main}}
        source: osism/zuul-jobs/.zuul.yaml@main#54>'
      - '<Job python-black explicit: None implied: None source: osism/python-osism/.zuul.yaml@main#143>'
      ansible_version: '9'
      attempts: 1
      branch: main
      build: 5571d8ab53344caa9387934443f9b2d8
      build_refs:
      - branch: main
        change: '2342'
        change_message: "Add unit tests for ironic.py pure helpers\n\nCloses #2226.\n\nAdds
          `tests/unit/tasks/conductor/test_ironic_helpers.py` covering the pure\nhelpers
          and the `_prepare_node_attributes` builder in\n`osism/tasks/conductor/ironic.py`
          \u2014 everything testable without the full\nsync orchestration (the sync
          entry points stay in the companion sub-issue).\n\n## Change set\n\nA single
          new test module (no production code touched), organized by helper:\n\n-
          **`_derive_as_from_hostname_yrzn`** \u2014 storage vs. non-storage type
          digit,\n  `< 5` parts \u2192 `None`, single-digit padding, already-two-digit
          values left\n  alone.\n- **`_get_metalbox_primary_ip4_fallback`** \u2014
          invalid YAML, non-list setting,\n  non-dict element skipped, `tag` stripped
          + `role=\"metalbox\"` added (asserted\n  via captured `filter` kwargs),
          first/second metalbox IP selection, and the\n  two no-IP / no-metalbox warning
          paths.\n- **`_get_metalbox_primary_ip4`** \u2014 no OOB IP (fallback not
          called), subnet\n  match, no-match \u2192 fallback, matching subnet but
          no `primary_ip4` \u2192 early\n  `None` (no fallback), match on the second
          interface, and IPv4/IPv6 mixing.\n- **`_render_templates`** \u2014 flat/nested
          dict, nested list, list of dicts,\n  non-template and non-string values
          untouched, multiple vars, in-place\n  mutation returning `None`.\n- **`_prepare_node_attributes`**
          \u2014 base/config-context/custom-field merging\n  and order, driver pruning,
          template variables (board creds, OOB address,\n  `ironic_osism_*` propagation),
          `osism-ipa-type=yrzn001` kernel enrichment\n  (frr params, metalbox, AS
          fallback, unknown type), `skip_kernel_params`,\n  `extra_kernel_params`,
          `driver_info` persistence, `extra` serialization, and\n  the returned tuple.\n-
          **`_prettify_for_display`** \u2014 JSON parsing in `extra`, non-JSON left\n
          \ untouched, deep copy with/without `extra`.\n\n## Mocking notes\n\n- Module-level
          collaborators (`deep_decrypt`, `deep_merge`, `get_vault`,\n  `get_device_oob_ip`,
          `SUPPORTED_IPA_TYPES`, `_derive_as_from_hostname_yrzn`,\n  `_get_metalbox_primary_ip4`)
          are patched at `osism.tasks.conductor.ironic.*`.\n- The NetBox client is
          patched via `osism.utils.nb` (with `create=True`), which\n  is what the
          helpers' local `from osism import utils` resolves to \u2014 matching\n  the
          existing `test_netbox.py` and sonic test fixtures. `ironic.py` has no\n
          \ module-level `utils` attribute (it imports it as `osism_utils`), so the\n
          \ literal `osism.tasks.conductor.ironic.utils.nb` path from the issue is
          not a\n  valid patch target; `osism.utils.nb` is the established equivalent.\n-
          `deep_decrypt` / `deep_merge` are stubbed as no-ops; their real behavior
          is\n  covered by the conductor.utils tests, so the merge cases assert call\n
          \ identity/order rather than merged output.\n\n## Deviation from the issue\n\nThe
          issue lists `_derive_as_from_hostname_yrzn(\"comp-nw-22-3-7-1\")` \u2192\n`\"4200143307\"`.
          The implementation pads rack/server and produces\n`\"4200140703\"` (matches
          the function's own docstring example\n`stor-nw-22-60-59-6` \u2192 `4200155960`).
          The test encodes the verified value\n`\"4200140703\"`; the same case (non-storage
          type 4, single-digit padding) is\nstill covered.\n\n## Verification\n\n-
          `black --check`, `flake8` \u2014 pass on the new file.\n- `pytest` / coverage
          \u2014 left to the `python-osism-unit-tests` Zuul job.\n\nAI-assisted: Claude
          Code"
        change_url: https://github.com/osism/python-osism/pull/2342
        commit_id: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        patchset: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        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: 421f1c70b49c48538ca8ccd758bef805
      buildset_refs:
      - branch: main
        change: '2342'
        change_message: "Add unit tests for ironic.py pure helpers\n\nCloses #2226.\n\nAdds
          `tests/unit/tasks/conductor/test_ironic_helpers.py` covering the pure\nhelpers
          and the `_prepare_node_attributes` builder in\n`osism/tasks/conductor/ironic.py`
          \u2014 everything testable without the full\nsync orchestration (the sync
          entry points stay in the companion sub-issue).\n\n## Change set\n\nA single
          new test module (no production code touched), organized by helper:\n\n-
          **`_derive_as_from_hostname_yrzn`** \u2014 storage vs. non-storage type
          digit,\n  `< 5` parts \u2192 `None`, single-digit padding, already-two-digit
          values left\n  alone.\n- **`_get_metalbox_primary_ip4_fallback`** \u2014
          invalid YAML, non-list setting,\n  non-dict element skipped, `tag` stripped
          + `role=\"metalbox\"` added (asserted\n  via captured `filter` kwargs),
          first/second metalbox IP selection, and the\n  two no-IP / no-metalbox warning
          paths.\n- **`_get_metalbox_primary_ip4`** \u2014 no OOB IP (fallback not
          called), subnet\n  match, no-match \u2192 fallback, matching subnet but
          no `primary_ip4` \u2192 early\n  `None` (no fallback), match on the second
          interface, and IPv4/IPv6 mixing.\n- **`_render_templates`** \u2014 flat/nested
          dict, nested list, list of dicts,\n  non-template and non-string values
          untouched, multiple vars, in-place\n  mutation returning `None`.\n- **`_prepare_node_attributes`**
          \u2014 base/config-context/custom-field merging\n  and order, driver pruning,
          template variables (board creds, OOB address,\n  `ironic_osism_*` propagation),
          `osism-ipa-type=yrzn001` kernel enrichment\n  (frr params, metalbox, AS
          fallback, unknown type), `skip_kernel_params`,\n  `extra_kernel_params`,
          `driver_info` persistence, `extra` serialization, and\n  the returned tuple.\n-
          **`_prettify_for_display`** \u2014 JSON parsing in `extra`, non-JSON left\n
          \ untouched, deep copy with/without `extra`.\n\n## Mocking notes\n\n- Module-level
          collaborators (`deep_decrypt`, `deep_merge`, `get_vault`,\n  `get_device_oob_ip`,
          `SUPPORTED_IPA_TYPES`, `_derive_as_from_hostname_yrzn`,\n  `_get_metalbox_primary_ip4`)
          are patched at `osism.tasks.conductor.ironic.*`.\n- The NetBox client is
          patched via `osism.utils.nb` (with `create=True`), which\n  is what the
          helpers' local `from osism import utils` resolves to \u2014 matching\n  the
          existing `test_netbox.py` and sonic test fixtures. `ironic.py` has no\n
          \ module-level `utils` attribute (it imports it as `osism_utils`), so the\n
          \ literal `osism.tasks.conductor.ironic.utils.nb` path from the issue is
          not a\n  valid patch target; `osism.utils.nb` is the established equivalent.\n-
          `deep_decrypt` / `deep_merge` are stubbed as no-ops; their real behavior
          is\n  covered by the conductor.utils tests, so the merge cases assert call\n
          \ identity/order rather than merged output.\n\n## Deviation from the issue\n\nThe
          issue lists `_derive_as_from_hostname_yrzn(\"comp-nw-22-3-7-1\")` \u2192\n`\"4200143307\"`.
          The implementation pads rack/server and produces\n`\"4200140703\"` (matches
          the function's own docstring example\n`stor-nw-22-60-59-6` \u2192 `4200155960`).
          The test encodes the verified value\n`\"4200140703\"`; the same case (non-storage
          type 4, single-digit padding) is\nstill covered.\n\n## Verification\n\n-
          `black --check`, `flake8` \u2014 pass on the new file.\n- `pytest` / coverage
          \u2014 left to the `python-osism-unit-tests` Zuul job.\n\nAI-assisted: Claude
          Code"
        change_url: https://github.com/osism/python-osism/pull/2342
        commit_id: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        patchset: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        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: '2342'
      change_message: "Add unit tests for ironic.py pure helpers\n\nCloses #2226.\n\nAdds
        `tests/unit/tasks/conductor/test_ironic_helpers.py` covering the pure\nhelpers
        and the `_prepare_node_attributes` builder in\n`osism/tasks/conductor/ironic.py`
        \u2014 everything testable without the full\nsync orchestration (the sync
        entry points stay in the companion sub-issue).\n\n## Change set\n\nA single
        new test module (no production code touched), organized by helper:\n\n- **`_derive_as_from_hostname_yrzn`**
        \u2014 storage vs. non-storage type digit,\n  `< 5` parts \u2192 `None`, single-digit
        padding, already-two-digit values left\n  alone.\n- **`_get_metalbox_primary_ip4_fallback`**
        \u2014 invalid YAML, non-list setting,\n  non-dict element skipped, `tag`
        stripped + `role=\"metalbox\"` added (asserted\n  via captured `filter` kwargs),
        first/second metalbox IP selection, and the\n  two no-IP / no-metalbox warning
        paths.\n- **`_get_metalbox_primary_ip4`** \u2014 no OOB IP (fallback not called),
        subnet\n  match, no-match \u2192 fallback, matching subnet but no `primary_ip4`
        \u2192 early\n  `None` (no fallback), match on the second interface, and IPv4/IPv6
        mixing.\n- **`_render_templates`** \u2014 flat/nested dict, nested list, list
        of dicts,\n  non-template and non-string values untouched, multiple vars,
        in-place\n  mutation returning `None`.\n- **`_prepare_node_attributes`** \u2014
        base/config-context/custom-field merging\n  and order, driver pruning, template
        variables (board creds, OOB address,\n  `ironic_osism_*` propagation), `osism-ipa-type=yrzn001`
        kernel enrichment\n  (frr params, metalbox, AS fallback, unknown type), `skip_kernel_params`,\n
        \ `extra_kernel_params`, `driver_info` persistence, `extra` serialization,
        and\n  the returned tuple.\n- **`_prettify_for_display`** \u2014 JSON parsing
        in `extra`, non-JSON left\n  untouched, deep copy with/without `extra`.\n\n##
        Mocking notes\n\n- Module-level collaborators (`deep_decrypt`, `deep_merge`,
        `get_vault`,\n  `get_device_oob_ip`, `SUPPORTED_IPA_TYPES`, `_derive_as_from_hostname_yrzn`,\n
        \ `_get_metalbox_primary_ip4`) are patched at `osism.tasks.conductor.ironic.*`.\n-
        The NetBox client is patched via `osism.utils.nb` (with `create=True`), which\n
        \ is what the helpers' local `from osism import utils` resolves to \u2014
        matching\n  the existing `test_netbox.py` and sonic test fixtures. `ironic.py`
        has no\n  module-level `utils` attribute (it imports it as `osism_utils`),
        so the\n  literal `osism.tasks.conductor.ironic.utils.nb` path from the issue
        is not a\n  valid patch target; `osism.utils.nb` is the established equivalent.\n-
        `deep_decrypt` / `deep_merge` are stubbed as no-ops; their real behavior is\n
        \ covered by the conductor.utils tests, so the merge cases assert call\n  identity/order
        rather than merged output.\n\n## Deviation from the issue\n\nThe issue lists
        `_derive_as_from_hostname_yrzn(\"comp-nw-22-3-7-1\")` \u2192\n`\"4200143307\"`.
        The implementation pads rack/server and produces\n`\"4200140703\"` (matches
        the function's own docstring example\n`stor-nw-22-60-59-6` \u2192 `4200155960`).
        The test encodes the verified value\n`\"4200140703\"`; the same case (non-storage
        type 4, single-digit padding) is\nstill covered.\n\n## Verification\n\n- `black
        --check`, `flake8` \u2014 pass on the new file.\n- `pytest` / coverage \u2014
        left to the `python-osism-unit-tests` Zuul job.\n\nAI-assisted: Claude Code"
      change_url: https://github.com/osism/python-osism/pull/2342
      child_jobs: []
      commit_id: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
      event_id: 451dadc0-7620-11f1-8be3-9335493d05a9
      executor:
        hostname: 521e9411259a
        inventory_file: /var/lib/zuul/builds/5571d8ab53344caa9387934443f9b2d8/ansible/inventory.yaml
        log_root: /var/lib/zuul/builds/5571d8ab53344caa9387934443f9b2d8/work/logs
        result_data_file: /var/lib/zuul/builds/5571d8ab53344caa9387934443f9b2d8/work/results.json
        src_root: /var/lib/zuul/builds/5571d8ab53344caa9387934443f9b2d8/work/src
        work_root: /var/lib/zuul/builds/5571d8ab53344caa9387934443f9b2d8/work
      include_vars: []
      items:
      - branch: main
        change: '2342'
        change_message: "Add unit tests for ironic.py pure helpers\n\nCloses #2226.\n\nAdds
          `tests/unit/tasks/conductor/test_ironic_helpers.py` covering the pure\nhelpers
          and the `_prepare_node_attributes` builder in\n`osism/tasks/conductor/ironic.py`
          \u2014 everything testable without the full\nsync orchestration (the sync
          entry points stay in the companion sub-issue).\n\n## Change set\n\nA single
          new test module (no production code touched), organized by helper:\n\n-
          **`_derive_as_from_hostname_yrzn`** \u2014 storage vs. non-storage type
          digit,\n  `< 5` parts \u2192 `None`, single-digit padding, already-two-digit
          values left\n  alone.\n- **`_get_metalbox_primary_ip4_fallback`** \u2014
          invalid YAML, non-list setting,\n  non-dict element skipped, `tag` stripped
          + `role=\"metalbox\"` added (asserted\n  via captured `filter` kwargs),
          first/second metalbox IP selection, and the\n  two no-IP / no-metalbox warning
          paths.\n- **`_get_metalbox_primary_ip4`** \u2014 no OOB IP (fallback not
          called), subnet\n  match, no-match \u2192 fallback, matching subnet but
          no `primary_ip4` \u2192 early\n  `None` (no fallback), match on the second
          interface, and IPv4/IPv6 mixing.\n- **`_render_templates`** \u2014 flat/nested
          dict, nested list, list of dicts,\n  non-template and non-string values
          untouched, multiple vars, in-place\n  mutation returning `None`.\n- **`_prepare_node_attributes`**
          \u2014 base/config-context/custom-field merging\n  and order, driver pruning,
          template variables (board creds, OOB address,\n  `ironic_osism_*` propagation),
          `osism-ipa-type=yrzn001` kernel enrichment\n  (frr params, metalbox, AS
          fallback, unknown type), `skip_kernel_params`,\n  `extra_kernel_params`,
          `driver_info` persistence, `extra` serialization, and\n  the returned tuple.\n-
          **`_prettify_for_display`** \u2014 JSON parsing in `extra`, non-JSON left\n
          \ untouched, deep copy with/without `extra`.\n\n## Mocking notes\n\n- Module-level
          collaborators (`deep_decrypt`, `deep_merge`, `get_vault`,\n  `get_device_oob_ip`,
          `SUPPORTED_IPA_TYPES`, `_derive_as_from_hostname_yrzn`,\n  `_get_metalbox_primary_ip4`)
          are patched at `osism.tasks.conductor.ironic.*`.\n- The NetBox client is
          patched via `osism.utils.nb` (with `create=True`), which\n  is what the
          helpers' local `from osism import utils` resolves to \u2014 matching\n  the
          existing `test_netbox.py` and sonic test fixtures. `ironic.py` has no\n
          \ module-level `utils` attribute (it imports it as `osism_utils`), so the\n
          \ literal `osism.tasks.conductor.ironic.utils.nb` path from the issue is
          not a\n  valid patch target; `osism.utils.nb` is the established equivalent.\n-
          `deep_decrypt` / `deep_merge` are stubbed as no-ops; their real behavior
          is\n  covered by the conductor.utils tests, so the merge cases assert call\n
          \ identity/order rather than merged output.\n\n## Deviation from the issue\n\nThe
          issue lists `_derive_as_from_hostname_yrzn(\"comp-nw-22-3-7-1\")` \u2192\n`\"4200143307\"`.
          The implementation pads rack/server and produces\n`\"4200140703\"` (matches
          the function's own docstring example\n`stor-nw-22-60-59-6` \u2192 `4200155960`).
          The test encodes the verified value\n`\"4200140703\"`; the same case (non-storage
          type 4, single-digit padding) is\nstill covered.\n\n## Verification\n\n-
          `black --check`, `flake8` \u2014 pass on the new file.\n- `pytest` / coverage
          \u2014 left to the `python-osism-unit-tests` Zuul job.\n\nAI-assisted: Claude
          Code"
        change_url: https://github.com/osism/python-osism/pull/2342
        commit_id: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        patchset: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
        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-black
      jobtags: []
      max_attempts: 3
      message: QWRkIHVuaXQgdGVzdHMgZm9yIGlyb25pYy5weSBwdXJlIGhlbHBlcnMKCkNsb3NlcyAjMjIyNi4KCkFkZHMgYHRlc3RzL3VuaXQvdGFza3MvY29uZHVjdG9yL3Rlc3RfaXJvbmljX2hlbHBlcnMucHlgIGNvdmVyaW5nIHRoZSBwdXJlCmhlbHBlcnMgYW5kIHRoZSBgX3ByZXBhcmVfbm9kZV9hdHRyaWJ1dGVzYCBidWlsZGVyIGluCmBvc2lzbS90YXNrcy9jb25kdWN0b3IvaXJvbmljLnB5YCDigJQgZXZlcnl0aGluZyB0ZXN0YWJsZSB3aXRob3V0IHRoZSBmdWxsCnN5bmMgb3JjaGVzdHJhdGlvbiAodGhlIHN5bmMgZW50cnkgcG9pbnRzIHN0YXkgaW4gdGhlIGNvbXBhbmlvbiBzdWItaXNzdWUpLgoKIyMgQ2hhbmdlIHNldAoKQSBzaW5nbGUgbmV3IHRlc3QgbW9kdWxlIChubyBwcm9kdWN0aW9uIGNvZGUgdG91Y2hlZCksIG9yZ2FuaXplZCBieSBoZWxwZXI6CgotICoqYF9kZXJpdmVfYXNfZnJvbV9ob3N0bmFtZV95cnpuYCoqIOKAlCBzdG9yYWdlIHZzLiBub24tc3RvcmFnZSB0eXBlIGRpZ2l0LAogIGA8IDVgIHBhcnRzIOKGkiBgTm9uZWAsIHNpbmdsZS1kaWdpdCBwYWRkaW5nLCBhbHJlYWR5LXR3by1kaWdpdCB2YWx1ZXMgbGVmdAogIGFsb25lLgotICoqYF9nZXRfbWV0YWxib3hfcHJpbWFyeV9pcDRfZmFsbGJhY2tgKiog4oCUIGludmFsaWQgWUFNTCwgbm9uLWxpc3Qgc2V0dGluZywKICBub24tZGljdCBlbGVtZW50IHNraXBwZWQsIGB0YWdgIHN0cmlwcGVkICsgYHJvbGU9Im1ldGFsYm94ImAgYWRkZWQgKGFzc2VydGVkCiAgdmlhIGNhcHR1cmVkIGBmaWx0ZXJgIGt3YXJncyksIGZpcnN0L3NlY29uZCBtZXRhbGJveCBJUCBzZWxlY3Rpb24sIGFuZCB0aGUKICB0d28gbm8tSVAgLyBuby1tZXRhbGJveCB3YXJuaW5nIHBhdGhzLgotICoqYF9nZXRfbWV0YWxib3hfcHJpbWFyeV9pcDRgKiog4oCUIG5vIE9PQiBJUCAoZmFsbGJhY2sgbm90IGNhbGxlZCksIHN1Ym5ldAogIG1hdGNoLCBuby1tYXRjaCDihpIgZmFsbGJhY2ssIG1hdGNoaW5nIHN1Ym5ldCBidXQgbm8gYHByaW1hcnlfaXA0YCDihpIgZWFybHkKICBgTm9uZWAgKG5vIGZhbGxiYWNrKSwgbWF0Y2ggb24gdGhlIHNlY29uZCBpbnRlcmZhY2UsIGFuZCBJUHY0L0lQdjYgbWl4aW5nLgotICoqYF9yZW5kZXJfdGVtcGxhdGVzYCoqIOKAlCBmbGF0L25lc3RlZCBkaWN0LCBuZXN0ZWQgbGlzdCwgbGlzdCBvZiBkaWN0cywKICBub24tdGVtcGxhdGUgYW5kIG5vbi1zdHJpbmcgdmFsdWVzIHVudG91Y2hlZCwgbXVsdGlwbGUgdmFycywgaW4tcGxhY2UKICBtdXRhdGlvbiByZXR1cm5pbmcgYE5vbmVgLgotICoqYF9wcmVwYXJlX25vZGVfYXR0cmlidXRlc2AqKiDigJQgYmFzZS9jb25maWctY29udGV4dC9jdXN0b20tZmllbGQgbWVyZ2luZwogIGFuZCBvcmRlciwgZHJpdmVyIHBydW5pbmcsIHRlbXBsYXRlIHZhcmlhYmxlcyAoYm9hcmQgY3JlZHMsIE9PQiBhZGRyZXNzLAogIGBpcm9uaWNfb3Npc21fKmAgcHJvcGFnYXRpb24pLCBgb3Npc20taXBhLXR5cGU9eXJ6bjAwMWAga2VybmVsIGVucmljaG1lbnQKICAoZnJyIHBhcmFtcywgbWV0YWxib3gsIEFTIGZhbGxiYWNrLCB1bmtub3duIHR5cGUpLCBgc2tpcF9rZXJuZWxfcGFyYW1zYCwKICBgZXh0cmFfa2VybmVsX3BhcmFtc2AsIGBkcml2ZXJfaW5mb2AgcGVyc2lzdGVuY2UsIGBleHRyYWAgc2VyaWFsaXphdGlvbiwgYW5kCiAgdGhlIHJldHVybmVkIHR1cGxlLgotICoqYF9wcmV0dGlmeV9mb3JfZGlzcGxheWAqKiDigJQgSlNPTiBwYXJzaW5nIGluIGBleHRyYWAsIG5vbi1KU09OIGxlZnQKICB1bnRvdWNoZWQsIGRlZXAgY29weSB3aXRoL3dpdGhvdXQgYGV4dHJhYC4KCiMjIE1vY2tpbmcgbm90ZXMKCi0gTW9kdWxlLWxldmVsIGNvbGxhYm9yYXRvcnMgKGBkZWVwX2RlY3J5cHRgLCBgZGVlcF9tZXJnZWAsIGBnZXRfdmF1bHRgLAogIGBnZXRfZGV2aWNlX29vYl9pcGAsIGBTVVBQT1JURURfSVBBX1RZUEVTYCwgYF9kZXJpdmVfYXNfZnJvbV9ob3N0bmFtZV95cnpuYCwKICBgX2dldF9tZXRhbGJveF9wcmltYXJ5X2lwNGApIGFyZSBwYXRjaGVkIGF0IGBvc2lzbS50YXNrcy5jb25kdWN0b3IuaXJvbmljLipgLgotIFRoZSBOZXRCb3ggY2xpZW50IGlzIHBhdGNoZWQgdmlhIGBvc2lzbS51dGlscy5uYmAgKHdpdGggYGNyZWF0ZT1UcnVlYCksIHdoaWNoCiAgaXMgd2hhdCB0aGUgaGVscGVycycgbG9jYWwgYGZyb20gb3Npc20gaW1wb3J0IHV0aWxzYCByZXNvbHZlcyB0byDigJQgbWF0Y2hpbmcKICB0aGUgZXhpc3RpbmcgYHRlc3RfbmV0Ym94LnB5YCBhbmQgc29uaWMgdGVzdCBmaXh0dXJlcy4gYGlyb25pYy5weWAgaGFzIG5vCiAgbW9kdWxlLWxldmVsIGB1dGlsc2AgYXR0cmlidXRlIChpdCBpbXBvcnRzIGl0IGFzIGBvc2lzbV91dGlsc2ApLCBzbyB0aGUKICBsaXRlcmFsIGBvc2lzbS50YXNrcy5jb25kdWN0b3IuaXJvbmljLnV0aWxzLm5iYCBwYXRoIGZyb20gdGhlIGlzc3VlIGlzIG5vdCBhCiAgdmFsaWQgcGF0Y2ggdGFyZ2V0OyBgb3Npc20udXRpbHMubmJgIGlzIHRoZSBlc3RhYmxpc2hlZCBlcXVpdmFsZW50LgotIGBkZWVwX2RlY3J5cHRgIC8gYGRlZXBfbWVyZ2VgIGFyZSBzdHViYmVkIGFzIG5vLW9wczsgdGhlaXIgcmVhbCBiZWhhdmlvciBpcwogIGNvdmVyZWQgYnkgdGhlIGNvbmR1Y3Rvci51dGlscyB0ZXN0cywgc28gdGhlIG1lcmdlIGNhc2VzIGFzc2VydCBjYWxsCiAgaWRlbnRpdHkvb3JkZXIgcmF0aGVyIHRoYW4gbWVyZ2VkIG91dHB1dC4KCiMjIERldmlhdGlvbiBmcm9tIHRoZSBpc3N1ZQoKVGhlIGlzc3VlIGxpc3RzIGBfZGVyaXZlX2FzX2Zyb21faG9zdG5hbWVfeXJ6bigiY29tcC1udy0yMi0zLTctMSIpYCDihpIKYCI0MjAwMTQzMzA3ImAuIFRoZSBpbXBsZW1lbnRhdGlvbiBwYWRzIHJhY2svc2VydmVyIGFuZCBwcm9kdWNlcwpgIjQyMDAxNDA3MDMiYCAobWF0Y2hlcyB0aGUgZnVuY3Rpb24ncyBvd24gZG9jc3RyaW5nIGV4YW1wbGUKYHN0b3ItbnctMjItNjAtNTktNmAg4oaSIGA0MjAwMTU1OTYwYCkuIFRoZSB0ZXN0IGVuY29kZXMgdGhlIHZlcmlmaWVkIHZhbHVlCmAiNDIwMDE0MDcwMyJgOyB0aGUgc2FtZSBjYXNlIChub24tc3RvcmFnZSB0eXBlIDQsIHNpbmdsZS1kaWdpdCBwYWRkaW5nKSBpcwpzdGlsbCBjb3ZlcmVkLgoKIyMgVmVyaWZpY2F0aW9uCgotIGBibGFjayAtLWNoZWNrYCwgYGZsYWtlOGAg4oCUIHBhc3Mgb24gdGhlIG5ldyBmaWxlLgotIGBweXRlc3RgIC8gY292ZXJhZ2Ug4oCUIGxlZnQgdG8gdGhlIGBweXRob24tb3Npc20tdW5pdC10ZXN0c2AgWnV1bCBqb2IuCgpBSS1hc3Npc3RlZDogQ2xhdWRlIENvZGU=
      patchset: 8a115d0d7f679333eaa58b1e47496b42c0824d7d
      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: 1d71e58c93442038e695a5d883d57a603182c7ae
          untrusted/project_0/github.com/osism/zuul-jobs:
            canonical_name: github.com/osism/zuul-jobs
            checkout: main
            commit: 1d71e58c93442038e695a5d883d57a603182c7ae
          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
        playbooks:
        - path: untrusted/project_0/github.com/osism/zuul-jobs/playbooks/python-black/run.yml
          roles:
          - checkout: main
            checkout_description: zuul branch
            link_name: ansible/playbook_0/role_0/zuul-config
            link_target: untrusted/project_1/github.com/osism/zuul-config
            role_path: ansible/playbook_0/role_0/zuul-config/roles
          - checkout: master
            checkout_description: project default branch
            link_name: ansible/playbook_0/role_1/openinfra-zuul-jobs
            link_target: untrusted/project_2/github.com/osism/openinfra-zuul-jobs
            role_path: ansible/playbook_0/role_1/openinfra-zuul-jobs/roles
          - checkout: main
            checkout_description: playbook branch
            link_name: ansible/playbook_0/role_2/zuul-jobs
            link_target: untrusted/project_0/github.com/osism/zuul-jobs
            role_path: ansible/playbook_0/role_2/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: 7ce79356899bca32a709847de6413103a95d2a1c
          name: osism/python-osism
          required: false
          short_name: python-osism
          src_dir: src/github.com/osism/python-osism
      ref: refs/pull/2342/head
      resources: {}
      tenant: osism
      timeout: 1800
      topic: null
      voting: true
