[AAP-91391]: Add execution_environment, group, notification_template, project_update, job_wait, and workflow_job_template modules - #249
Conversation
…390) - New Shape 1 CRUD module with copy_from, instance_groups/input_inventories associations, and constructed inventory support. - Add manage_associations/manage_sub_resource/copy_resource SDK methods to base_client/platform_manager/direct_client/rpc_client (shared infra, first use in this collection) — ported from PR ansible#228's job_template work, with lookup_endpoint values corrected to full /api/controller/v2/ paths (PR ansible#228 passed bare resource names, which would have resolved against the Gateway instead of Controller). - Add a `controller` action_groups entry to meta/runtime.yml (previously gateway-only), and generalize test_completeness.py's meta/runtime.yml check to scan every action_groups entry instead of just "gateway". - Extend tools/mock_gateway_server.py with /api/controller/v2/ routing, generic association/copy sub-endpoints, and a controller-side organizations lookup that reuses the Gateway's org store (shared ID space, matching real AAP). - Unit tests for the transform mixin; a 3-connection-mode Molecule scenario covering create/idempotency/update/rename/copy_from/associations/ constructed-inventory/delete; a live-API integration test target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Shape 1 CRUD module, Pattern A (no associations/copy). Depends on inventory for name->id lookup and inventory-scoped name uniqueness. - New module, action plugin, transform mixin, Ansible model. - Register under meta/runtime.yml action_groups.controller. - Register hosts as a generic Controller resource in the mock server. - Unit tests, 3-connection-mode Molecule scenario, integration test target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…(AAP-91390) Shape 1 CRUD module, Pattern C (notification_templates_started/success/error associations, no copy_from). Depends on inventory for name->id lookup and inventory-scoped name uniqueness. - New module, action plugin, transform mixin, Ansible model. - Drops the legacy organization option (disambiguation-only, no direct API field; not carried over since lookup_resource_id only supports a single filter field) and custom_virtualenv (no longer supported by the API) — both documented in the module's notes. - Register under meta/runtime.yml action_groups.controller. - Register inventory_sources, credentials, execution_environments, projects, and notification_templates as generic Controller resources in the mock server. - Unit tests, 3-connection-mode Molecule scenario, integration test target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…roller (AAP-91390) Shape 2 launch resource (POST to an existing inventory_source's /update/ sub-action, then optionally poll the launched inventory_update job for completion) — same wait/poll SDK infrastructure as ad_hoc_command (DEFAULT_WAIT_TIMEOUT, WaitTimeoutError, _wait_for_resource_completion), ported into this branch since it didn't exist here yet. Also fixes two real, previously-latent bugs in the shared operation executor (_execute_operations in platform_manager.py and direct_client.py), found by actually running this module's Molecule scenario rather than trusting unit tests alone: - An EndpointOperation intentionally declared with fields=[] (a no-body launch trigger) was being silently skipped as "nothing to do" — every prior operation in the collection happened to have a non-empty fields list, so this never surfaced before. - path_params substitution only ever handled a param literally named "id"; any custom path param name (here, inventory_source_id) was left unsubstituted in the URL. Fixed to resolve by the param's own name. Also adds tests/unit/plugins/**/__init__.py — two new test files sharing a basename across directories (test_inventory_source_update.py) collided under pytest's rootdir-relative import without them. - New module, action plugin (adapted from the ad_hoc_command Shape 2 pattern), transform mixin, Ansible model. - Drops the legacy organization option (disambiguation-only, no direct API field), documented in the module's notes. - Register under meta/runtime.yml action_groups.controller. - Register inventory_updates as a generic Controller resource in the mock server, with a pending -> successful poll-advance lifecycle. - Unit tests (transform mixin, action plugin check_mode/WaitTimeoutError, and a regression test for the two _execute_operations bugs), 3-connection-mode Molecule scenario, integration test target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Shape 1 CRUD module, Pattern C (credentials/labels/instance_groups associations, no copy_from). Depends on unified_job_template for name->id lookup and unified_job_template-scoped name uniqueness. - New module, action plugin, transform mixin, Ansible model. - Drops the legacy organization option (disambiguation-only, no direct API field), documented in the module's notes. - Register under meta/runtime.yml action_groups.controller. - Register schedules, unified_job_templates, and labels as generic Controller resources in the mock server. - Unit tests, 3-connection-mode Molecule scenario, integration test target (uses an inventory_source as the schedulable unified_job_template, since job_template isn't part of this migration batch). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…1390) Shape 2 launch resource (POST to an existing job_template's /launch/ sub-action, then optionally poll the launched job for completion) — same wait/poll SDK infrastructure as ad_hoc_command/inventory_source_update. Resolves the job_template by name via unified_job_templates rather than a job_template-specific endpoint, since this collection doesn't ship a job_template CRUD module (excluded from this batch — see PR ansible#228). Refines the _execute_operations fix from the inventory_source_update commit: that fix gated the "still call the API with an empty body" case on the operation's fields list being empty, which correctly handled inventory_source_update's true no-body trigger but broke job_launch's launch (real optional fields like extra_vars/limit, all simply unset on the common "just launch it" call). The correct, final gate is `depends_on` — matching DirectHTTPClient's already-correct behavior exactly: skip only a *secondary* operation (depends_on set) with nothing to send; a *primary* operation always fires. Verified inventory_source_update, schedule, host, inventory, and inventory_source Molecule scenarios all still pass under the corrected gate. - New module, action plugin (adapted from the ad_hoc_command Shape 2 pattern), transform mixin, Ansible model. - Drops the legacy organization option and the client-side ask_*_on_launch prompt validation, documented in the module's notes. - Register under meta/runtime.yml action_groups.controller. - Register job_templates and jobs as generic Controller resources in the mock server, with a pending -> successful poll-advance lifecycle shared with inventory_updates. Teach the mock's unified_job_templates GET (list) to union job_templates/inventory_sources/its own dedicated store, mirroring real Controller (a polymorphic view sharing IDs, not a separate table) — needed so a resolved unified_job_template id is actually launchable. - Unit tests (transform mixin, action plugin check_mode/WaitTimeoutError, updated _execute_operations regression coverage), 3-connection-mode Molecule scenario, integration test target (uses an inventory_source as the launchable unified_job_template, same as schedule_test). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Molecule inventory.yml files are dicts (all: {vars, children}), not
playbooks, but ansible-lint misclassifies them as such based on the
filename. Every prior scenario's inventory.yml is already listed in
.ansible-lint's exclude_paths individually; the 6 new scenarios from this
PR were missing.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The connection-manager-review checklist (from PR ansible#244's pr-review skill) flagged two gaps in the manage_associations/manage_sub_resource/copy_resource and launch/wait infrastructure added in this PR: - No isolated unit tests: these were only exercised indirectly through Molecule and action-plugin flows, never with a directly mocked session. Add 13 unit tests covering association diffing (resolve/associate/ disassociate/idempotent-no-op/lookup-failure), manage_sub_resource (no-op/delete/update/idempotent/error), and copy_resource (name lookup, ID-based fallback, not-found). - No architecture doc update: document all three generic methods plus the launch/wait mechanism (wait/interval/timeout popping, DEFAULT_WAIT_TIMEOUT, WaitTimeoutError) in docs/03-sdk-architecture.md's RPC Interface section. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…fixes - manage_associations/manage_sub_resource now propagate GET/POST/DELETE failures instead of silently treating them as success or no-op - inventory copy_from is now idempotent; inventory/inventory_source/schedule validate association list fields and skip mutating syncs under check_mode - job_launch resolves job_template via /job_templates/ directly, avoiding an id collision with workflow_job_templates on /unified_job_templates/ - DirectHTTPClient.lookup_resource_id no longer double-prefixes absolute /api/ paths passed by Controller-routed FK lookups Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…, sub-resources, path-param polling
- manage_associations gains disassociate_missing=False for legacy
"preserve_existing_*" semantics (group's hosts/children)
- _find_resource (platform_manager.py, direct_client.py) now substitutes
every declared path param, not just "{id}" — needed by job_wait's
job_type-scoped GET path
- Register controller action_groups entries for the batch-2 modules
- Mock server: add groups, workflow_job_templates, project_updates,
workflow_jobs Controller resources; generic sub_resources (survey_spec)
GET/POST/DELETE support; projects->update launch mapping
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ller (AAP-91391) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ller (AAP-91391) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…AP-91391) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ller (AAP-91391) Scope excludes the legacy module's workflow_nodes/destroy_current_nodes options — building the workflow's node graph is a separate resource (workflow_job_template_node, not yet migrated) with its own CRUD and association surface, not a field of the workflow_job_template itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 178 files, which is 78 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (178)
You can disable this status message by setting the Comment |
CasC NotificationThis PR touches areas that may affect the CasC collections (e.g. infra.aap_configuration). Detected changes in CasC-monitored areas:
Please tag the CasC collections team in this PR so they are aware of the change.
|
Description
Migrates 6 modules from awx.awx/ansible.controller to ansible.platform, per AAP-91391
Note: Is based on #248
execution_environment— CRUDgroup— CRUD, withhosts/childrenassociations (supports legacypreserve_existing_hosts/preserve_existing_childrenviadisassociate_missing=False)notification_template— CRUD, withcopy_fromproject_update— launch/wait (syncs a project)job_wait— wait on an existing job/update by polling{job_type}/{id}/workflow_job_template— CRUD, associations (labels/notification_templates_started/success/error/approvals),survey_spec,copy_from(node-graph management (workflow_nodes) is explicitly out of scope — documented as anotes:entry, left for a futureworkflow_job_template_nodemodule)Excluded from the Jira list:
organization/token/settings(already migrated as native Gateway resources)Shared SDK changes
manage_associations()(base_client.py/platform_manager.py/direct_client.py/rpc_client.py) gains adisassociate_missing: bool = Trueparameter, so a "preserve existing" legacy option (e.g.group'spreserve_existing_hosts) can add without disassociating anything not listed._find_resource(used by "find" operations and every_wait_for_resource_completionpoll) in bothplatform_manager.pyanddirect_client.pyto substitute every declared path param, not just a literal{id}— needed for resources likejob_waitwhose GET path is scoped by more than the primary key (/{job_type}/{id}/). This is a separate code path from_execute_operations's existing path-param fix from batch 1.sub_resourcessupport totools/mock_gateway_server.py'sGenericResource(get_sub_resource/set_sub_resource/delete_sub_resource+ routing) for GET/POST/DELETE sub-endpoints backed by a single stored blob per item (e.g.workflow_job_template'ssurvey_spec) — distinct fromassociations' id-reference-list semantics.groups,workflow_job_templates,project_updates,workflow_jobsstores in the mock server, extend the launch/poll sub-action mapping forprojects.update → project_updates, and generalize the pending→successful polling lifecycle to all 4 async resource types.meta/runtime.yml'saction_groups.controllerlist.Type of Change
Self-Review Checklist
meta/routing.yml)deprecated:block inDOCUMENTATIONwith removal versionTesting Instructions
Prerequisites
Steps to Test
Expected Results
Additional Context
Required Actions
CasC Notification
Screenshots/Logs