From 4a380f3375bf6f35eded3233ddc23f92eda6cca4 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Tue, 15 Oct 2024 09:32:35 +0100 Subject: [PATCH] Revert "Renaming to platform variables" (#932) Co-authored-by: Sean Sullivan --- .github/files/ansible.cfg | 2 +- .github/workflows/pre-commit.yml | 2 +- changelogs/fragments/Rewrite.yml | 3 - .../filetree_node_schedule_survey.yml | 3 + galaxy.yml | 3 +- roles/controller_ad_hoc_command/README.md | 24 +-- .../defaults/main.yml | 2 +- .../meta/argument_specs.yml | 26 +-- .../controller_ad_hoc_command/tasks/main.yml | 13 +- .../controller_ad_hoc_command/tests/test.yml | 4 +- .../README.md | 24 +-- .../defaults/main.yml | 2 +- .../meta/argument_specs.yml | 26 +-- .../tasks/main.yml | 13 +- .../tests/test.yml | 4 +- roles/controller_applications/README.md | 34 ++-- .../controller_applications/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_applications/tasks/main.yml | 23 +-- roles/controller_applications/tests/test.yml | 4 +- roles/controller_bulk_host_create/README.md | 22 +-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 8 +- .../tasks/main.yml | 17 +- roles/controller_bulk_job_launch/README.md | 32 +-- .../defaults/main.yml | 6 +- .../meta/argument_specs.yml | 26 +-- .../controller_bulk_job_launch/tasks/main.yml | 13 +- .../README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yml | 4 +- roles/controller_credential_types/README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yml | 4 +- roles/controller_credentials/README.md | 34 ++-- .../controller_credentials/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_credentials/tasks/main.yml | 21 +- roles/controller_credentials/tests/test.yml | 4 +- .../README.md | 28 +-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yml | 4 +- roles/controller_host_groups/README.md | 34 ++-- .../controller_host_groups/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_host_groups/tasks/main.yml | 23 +-- roles/controller_host_groups/tests/test.yml | 4 +- roles/controller_hosts/README.md | 34 ++-- roles/controller_hosts/defaults/main.yml | 8 +- .../controller_hosts/meta/argument_specs.yml | 36 ++-- roles/controller_hosts/tasks/main.yml | 23 +-- roles/controller_hosts/tests/test.yml | 4 +- roles/controller_instance_groups/README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../controller_instance_groups/tasks/main.yml | 23 +-- .../controller_instance_groups/tests/test.yml | 4 +- roles/controller_instances/README.md | 34 ++-- roles/controller_instances/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_instances/tasks/main.yml | 17 +- roles/controller_instances/tests/test.yml | 4 +- roles/controller_inventories/README.md | 34 ++-- .../controller_inventories/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_inventories/tasks/main.yml | 23 +-- roles/controller_inventories/tests/test.yml | 4 +- .../README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 38 ++-- .../tasks/main.yml | 17 +- .../tests/test.yml | 4 +- roles/controller_inventory_sources/README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yml | 4 +- roles/controller_job_launch/README.md | 24 +-- roles/controller_job_launch/defaults/main.yml | 2 +- .../meta/argument_specs.yml | 26 +-- roles/controller_job_launch/tasks/main.yml | 13 +- roles/controller_job_launch/tests/test.yml | 4 +- roles/controller_job_templates/README.md | 36 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_job_templates/tasks/main.yml | 23 +-- roles/controller_job_templates/tests/test.yml | 4 +- roles/controller_jobs_cancel/README.md | 24 +-- .../controller_jobs_cancel/defaults/main.yml | 2 +- .../meta/argument_specs.yml | 26 +-- roles/controller_jobs_cancel/tasks/main.yml | 13 +- roles/controller_jobs_cancel/tests/test.yml | 4 +- roles/controller_labels/README.md | 34 ++-- roles/controller_labels/defaults/main.yml | 8 +- .../controller_labels/meta/argument_specs.yml | 36 ++-- roles/controller_labels/tasks/main.yml | 23 +-- roles/controller_labels/tests/test.yml | 4 +- roles/controller_license/README.md | 26 +-- roles/controller_license/defaults/main.yml | 2 +- .../meta/argument_specs.yml | 26 +-- roles/controller_license/tasks/manifest.yml | 13 +- .../controller_license/tasks/subscription.yml | 26 +-- roles/controller_license/tests/test.yml | 4 +- .../README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yml | 4 +- roles/controller_organizations/README.md | 34 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_organizations/tasks/main.yml | 23 +-- roles/controller_organizations/tests/test.yml | 4 +- roles/controller_project_update/README.md | 30 +-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../controller_project_update/tasks/main.yml | 17 +- .../controller_project_update/tests/test.yml | 4 +- roles/controller_projects/README.md | 22 +-- roles/controller_projects/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_projects/tasks/main.yml | 23 +-- roles/controller_projects/tests/test.yml | 4 +- roles/controller_roles/README.md | 34 ++-- roles/controller_roles/defaults/main.yml | 8 +- .../controller_roles/meta/argument_specs.yml | 36 ++-- roles/controller_roles/tasks/main.yml | 23 +-- roles/controller_roles/tests/test.yml | 4 +- roles/controller_schedules/README.md | 34 ++-- roles/controller_schedules/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_schedules/tasks/main.yml | 23 +-- roles/controller_schedules/tests/test.yml | 4 +- roles/controller_settings/README.md | 34 ++-- roles/controller_settings/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- roles/controller_settings/tasks/main.yml | 17 +- roles/controller_settings/tests/test.yml | 4 +- roles/controller_teams/README.md | 40 ++-- roles/controller_teams/defaults/main.yml | 10 +- .../controller_teams/meta/argument_specs.yml | 42 ++-- roles/controller_teams/tasks/main.yml | 33 ++-- roles/controller_teams/tests/test.yml | 4 +- roles/controller_users/README.md | 34 ++-- roles/controller_users/defaults/main.yml | 8 +- .../controller_users/meta/argument_specs.yml | 36 ++-- roles/controller_users/tasks/main.yml | 23 +-- roles/controller_users/tests/test.yml | 4 +- .../README.md | 38 ++-- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 36 ++-- .../tasks/add_workflows_schema.yml | 38 ++-- .../tasks/main.yml | 23 +-- .../tests/test.yaml | 4 +- roles/controller_workflow_launch/README.md | 24 +-- .../defaults/main.yml | 2 +- .../meta/argument_specs.yml | 34 ++-- .../controller_workflow_launch/tasks/main.yml | 13 +- .../controller_workflow_launch/tests/test.yml | 4 +- roles/dispatch/README.md | 4 +- roles/dispatch/defaults/main.yml | 4 +- roles/dispatch/meta/argument_specs.yml | 36 ++-- roles/dispatch/tests/test.yml | 4 +- roles/eda_controller_tokens/README.md | 21 +- roles/eda_controller_tokens/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 44 ++--- roles/eda_controller_tokens/tasks/main.yml | 14 +- roles/eda_credentials/README.md | 19 +- roles/eda_credentials/defaults/main.yml | 8 +- roles/eda_credentials/meta/argument_specs.yml | 44 ++--- roles/eda_credentials/tasks/main.yml | 14 +- roles/eda_decision_environments/README.md | 19 +- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 44 ++--- .../eda_decision_environments/tasks/main.yml | 14 +- roles/eda_projects/README.md | 19 +- roles/eda_projects/defaults/main.yml | 8 +- roles/eda_projects/meta/argument_specs.yml | 44 ++--- roles/eda_projects/tasks/main.yml | 14 +- roles/eda_rulebook_activations/README.md | 19 +- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 44 ++--- roles/eda_rulebook_activations/tasks/main.yml | 14 +- roles/eda_users/README.md | 19 +- roles/eda_users/defaults/main.yml | 8 +- roles/eda_users/meta/argument_specs.yml | 44 ++--- roles/eda_users/tasks/main.yml | 14 +- roles/gateway_applications/README.md | 10 +- roles/gateway_applications/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 14 +- roles/gateway_applications/tasks/main.yml | 16 +- roles/gateway_authenticator_maps/README.md | 10 +- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- .../gateway_authenticator_maps/tasks/main.yml | 16 +- roles/gateway_authenticators/README.md | 10 +- .../gateway_authenticators/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_authenticators/tasks/main.yml | 16 +- roles/gateway_http_ports/README.md | 10 +- roles/gateway_http_ports/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_http_ports/tasks/main.yml | 16 +- roles/gateway_organizations/README.md | 10 +- roles/gateway_organizations/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_organizations/tasks/main.yml | 16 +- roles/gateway_role_user_assignments/README.md | 10 +- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- .../tasks/main.yml | 16 +- roles/gateway_routes/README.md | 10 +- roles/gateway_routes/defaults/main.yml | 8 +- roles/gateway_routes/meta/argument_specs.yml | 42 ++-- roles/gateway_routes/tasks/main.yml | 16 +- roles/gateway_service_clusters/README.md | 10 +- .../defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_service_clusters/tasks/main.yml | 16 +- roles/gateway_service_keys/README.md | 10 +- roles/gateway_service_keys/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_service_keys/tasks/main.yml | 16 +- roles/gateway_service_nodes/README.md | 10 +- roles/gateway_service_nodes/defaults/main.yml | 8 +- .../meta/argument_specs.yml | 42 ++-- roles/gateway_service_nodes/tasks/main.yml | 16 +- roles/gateway_services/README.md | 14 +- roles/gateway_services/defaults/main.yml | 8 +- .../gateway_services/meta/argument_specs.yml | 42 ++-- roles/gateway_services/tasks/main.yml | 16 +- roles/gateway_settings/README.md | 16 +- roles/gateway_settings/defaults/main.yml | 8 +- .../gateway_settings/meta/argument_specs.yml | 44 +++-- roles/gateway_settings/tasks/main.yml | 16 +- roles/gateway_teams/README.md | 12 +- roles/gateway_teams/defaults/main.yml | 10 +- roles/gateway_teams/meta/argument_specs.yml | 50 ++--- roles/gateway_teams/tasks/main.yml | 26 +-- roles/gateway_users/README.md | 10 +- roles/gateway_users/defaults/main.yml | 8 +- roles/gateway_users/meta/argument_specs.yml | 42 ++-- roles/gateway_users/tasks/main.yml | 16 +- .../README.md | 12 +- .../defaults/main.yml | 6 +- .../meta/argument_specs.yml | 8 +- .../meta/main.yml | 6 +- .../tasks/main.yml | 2 +- .../templates/ansible.cfg.j2 | 0 .../tests/test.yml | 6 +- .../tests/vars/config.yml | 0 roles/hub_collection/README.md | 30 +-- roles/hub_collection/defaults/main.yml | 12 +- roles/hub_collection/meta/argument_specs.yml | 43 ++-- roles/hub_collection/tasks/main.yml | 41 ++-- roles/hub_collection/tests/test.yml | 2 +- roles/hub_collection_remote/README.md | 30 +-- roles/hub_collection_remote/defaults/main.yml | 12 +- .../meta/argument_specs.yml | 35 ++-- roles/hub_collection_remote/tasks/main.yml | 14 +- roles/hub_collection_remote/tests/test.yml | 2 +- roles/hub_collection_repository/README.md | 30 +-- .../defaults/main.yml | 12 +- .../meta/argument_specs.yml | 35 ++-- .../hub_collection_repository/tasks/main.yml | 14 +- .../hub_collection_repository/tests/test.yml | 2 +- .../hub_collection_repository_sync/README.md | 30 +-- .../defaults/main.yml | 12 +- .../meta/argument_specs.yml | 35 ++-- .../tasks/main.yml | 14 +- .../tests/test.yml | 2 +- roles/hub_ee_image/README.md | 28 +-- roles/hub_ee_image/defaults/main.yml | 12 +- roles/hub_ee_image/meta/argument_specs.yml | 38 ++-- roles/hub_ee_image/tasks/main.yml | 14 +- roles/hub_ee_image/tests/test.yml | 2 +- roles/hub_ee_namespace/README.md | 28 +-- roles/hub_ee_namespace/defaults/main.yml | 12 +- .../hub_ee_namespace/meta/argument_specs.yml | 38 ++-- roles/hub_ee_namespace/tasks/main.yml | 14 +- roles/hub_ee_namespace/tests/test.yml | 2 +- roles/hub_ee_registry/README.md | 28 +-- roles/hub_ee_registry/defaults/main.yml | 12 +- roles/hub_ee_registry/meta/argument_specs.yml | 38 ++-- roles/hub_ee_registry/tasks/main.yml | 14 +- roles/hub_ee_registry/tests/test.yml | 2 +- roles/hub_ee_registry_index/README.md | 28 +-- roles/hub_ee_registry_index/defaults/main.yml | 12 +- .../meta/argument_specs.yml | 38 ++-- roles/hub_ee_registry_index/tasks/main.yml | 14 +- roles/hub_ee_registry_index/tests/test.yml | 2 +- roles/hub_ee_registry_sync/README.md | 28 +-- roles/hub_ee_registry_sync/defaults/main.yml | 12 +- .../meta/argument_specs.yml | 38 ++-- roles/hub_ee_registry_sync/tasks/main.yml | 14 +- roles/hub_ee_registry_sync/tests/test.yml | 2 +- roles/hub_ee_repository/README.md | 28 +-- roles/hub_ee_repository/defaults/main.yml | 12 +- .../hub_ee_repository/meta/argument_specs.yml | 38 ++-- roles/hub_ee_repository/tasks/main.yml | 14 +- roles/hub_ee_repository/tests/test.yml | 2 +- roles/hub_ee_repository_sync/README.md | 28 +-- .../hub_ee_repository_sync/defaults/main.yml | 12 +- .../meta/argument_specs.yml | 38 ++-- roles/hub_ee_repository_sync/tasks/main.yml | 14 +- roles/hub_ee_repository_sync/tests/test.yml | 2 +- roles/hub_group/README.md | 24 +-- roles/hub_group/defaults/main.yml | 12 +- roles/hub_group/meta/argument_specs.yml | 38 ++-- roles/hub_group/tasks/main.yml | 26 +-- roles/hub_group/tests/test.yml | 2 +- roles/hub_group_roles/README.md | 28 +-- roles/hub_group_roles/defaults/main.yml | 12 +- roles/hub_group_roles/meta/argument_specs.yml | 38 ++-- roles/hub_group_roles/tasks/main.yml | 14 +- roles/hub_group_roles/tests/test.yml | 2 +- roles/hub_namespace/README.md | 28 +-- roles/hub_namespace/defaults/main.yml | 12 +- roles/hub_namespace/meta/argument_specs.yml | 43 ++-- roles/hub_namespace/tasks/main.yml | 26 +-- roles/hub_namespace/tests/test.yml | 2 +- roles/hub_publish/README.md | 28 +-- roles/hub_publish/defaults/main.yml | 12 +- roles/hub_publish/meta/argument_specs.yml | 38 ++-- roles/hub_publish/tasks/main.yml | 38 ++-- roles/hub_publish/tests/test.yml | 2 +- roles/hub_role/README.md | 28 +-- roles/hub_role/defaults/main.yml | 12 +- roles/hub_role/meta/argument_specs.yml | 38 ++-- roles/hub_role/tasks/main.yml | 14 +- roles/hub_role/tests/test.yml | 2 +- roles/hub_user/README.md | 28 +-- roles/hub_user/defaults/main.yml | 12 +- roles/hub_user/meta/argument_specs.yml | 38 ++-- roles/hub_user/tasks/main.yml | 14 +- roles/hub_user/tests/test.yml | 2 +- .../config-controller-filetree.yml | 1 + tests/automatetheautomation/drop_diff.yml | 1 + ...ontroller_credential_types_aap_monitor.yml | 22 +++ .../controller_credential_types_acme_key.yml | 16 ++ ...controller_credential_types_cloudforms.yml | 35 ++++ .../controller_credential_types_multiple.yml | 22 +++ ...controller_credential_types_servicenow.yml | 27 +++ .../controller_credential_types.yml | 3 + .../controller_groups.d/controller_groups.yml | 3 + .../controller_instance_groups_otlc.yml | 20 ++ .../controller_instance_groups.yml | 3 + .../controller_inventories_localhost.yml | 6 + .../controller_inventories_excel.yml | 6 + .../controller_inventories_smart_org1.yml | 32 +++ .../controller_inventories_smart_org2.yml | 26 +++ .../controller_inventories.yml | 3 + .../controller_job_templates_casc.yml | 62 ++++++ ...troller_job_templates_container_groups.yml | 16 ++ .../controller_job_templates_demo_push.yml | 46 +++++ .../controller_job_templates.yml | 3 + .../controller_organizations_Global.yml | 10 + .../controller_organizations_ExampleOrg.yml | 10 + ...controller_organizations_OrgCrossTeams.yml | 5 + ...troller_organizations_Organizations1-2.yml | 11 ++ .../controller_organizations.yml | 3 + .../app-casc/controller_projects_casc.yml | 15 ++ .../controller_projects_container_groups.yml | 14 ++ .../controller_projects.yml | 3 + ...troller_projects_inventory_sourcea_dev.yml | 16 ++ ...roller_projects_inventory_sourcea_prod.yml | 16 ++ ...troller_projects_inventory_sourceb_dev.yml | 16 ++ ...roller_projects_inventory_sourceb_prod.yml | 16 ++ .../controller_roles_cmdb_approvals.yml | 7 + .../controller_roles_inventories.yml | 48 +++++ .../controller_roles_inventory_wf_update.yml | 7 + .../app-example/controller_roles_teams.yml | 8 + .../app-example/controller_roles_users.yml | 50 +++++ .../controller_roles.d/controller_roles.yml | 4 + .../app-casc/controller_schedules_casc.yml | 30 +++ .../controller_schedules_example.yml | 3 + .../controller_schedules.yml | 3 + .../app-demo/controller_teams_org1.yml | 10 + .../app-demo/controller_teams_org2.yml | 10 + .../controller_teams.d/controller_teams.yml | 10 + ...controller_workflow_job_templates_casc.yml | 32 +++ ...workflow_job_templates_InventoryUpdate.yml | 72 +++++++ .../controller_workflow_job_templates.yml | 3 + .../controller_credentials_aap.yml | 12 ++ .../controller_credentials_galaxy.yml | 26 +++ .../controller_credentials_machine.yml | 10 + .../controller_credentials_ocp.yml | 11 ++ .../controller_credentials_registry.yml | 12 ++ .../controller_credentials_scm.yml | 19 ++ .../controller_credentials_vault.yml | 9 + ...troller_execution_environments_ee-casc.yml | 7 + ...troller_execution_environments_ee-xlsx.yml | 12 ++ .../controller_execution_environments.yml | 3 + .../app-casc/controller_hosts_localhost.yml | 6 + .../controller_hosts.d/controller_hosts.yml | 3 + ...ntroller_inventory_sources_sourcea_dev.yml | 12 ++ ...troller_inventory_sources_sourcea_prod.yml | 12 ++ ...ntroller_inventory_sources_sourceb_dev.yml | 12 ++ ...troller_inventory_sources_sourceb_prod.yml | 12 ++ .../controller_inventory_sources.yml | 3 + .../app-examples/controller_settings_jobs.yml | 13 ++ .../app-examples/controller_settings_ldap.yml | 113 +++++++++++ .../controller_settings_system.yml | 18 ++ .../controller_settings_user_interface.yml | 5 + .../controller_settings.yml | 4 + .../controller_user_accounts_org1.yml | 15 ++ .../controller_user_accounts_org2.yml | 15 ++ .../controller_user_accounts.yml | 11 ++ .../controller_credentials_aap.yml | 12 ++ .../controller_credentials_galaxy.yml | 26 +++ .../controller_credentials_machine.yml | 10 + .../controller_credentials_ocp.yml | 11 ++ .../controller_credentials_registry.yml | 12 ++ .../controller_credentials_scm.yml | 19 ++ .../controller_credentials_vault.yml | 9 + ...troller_execution_environments_ee-casc.yml | 7 + ...troller_execution_environments_ee-xlsx.yml | 12 ++ .../controller_execution_environments.yml | 3 + .../controller_hosts.d/controller_hosts.yml | 6 + ...ntroller_inventory_sources_sourcea_dev.yml | 12 ++ ...troller_inventory_sources_sourcea_prod.yml | 12 ++ ...ntroller_inventory_sources_sourceb_dev.yml | 12 ++ ...troller_inventory_sources_sourceb_prod.yml | 12 ++ .../controller_inventory_sources.yml | 3 + .../app-examples/controller_settings_jobs.yml | 13 ++ .../app-examples/controller_settings_ldap.yml | 113 +++++++++++ .../controller_settings_system.yml | 18 ++ .../controller_settings_user_interface.yml | 5 + .../controller_settings.yml | 3 + .../controller_user_accounts_org1.yml | 15 ++ .../controller_user_accounts_org2.yml | 15 ++ .../controller_user_accounts.yml | 11 ++ ...gure_connection_controller_credentials.yml | 6 + ...gure_connection_controller_credentials.yml | 6 + .../pictures/AAP_CasC_Worflow.png | Bin 0 -> 563916 bytes tests/configs/controller_auth.yml | 11 +- tests/configs/credentials.yml | 21 +- tests/configs/settings.yml | 45 ++++- tests/configs/teams.yml | 2 +- tests/configs/user_accounts.yml | 2 +- tests/configure_platform.yml | 187 ------------------ tests/playbooks/README.md | 139 +++++++++++++ tests/playbooks/cd_gitlab_webhook_trigger.yml | 69 +++++++ tests/playbooks/configure_awx.yml | 106 ++++++++++ tests/playbooks/configure_controller.yml | 106 ++++++++++ tests/playbooks/tasks/ad_hoc_cancel.yml | 16 ++ 452 files changed, 5271 insertions(+), 3461 deletions(-) delete mode 100644 changelogs/fragments/Rewrite.yml create mode 100644 changelogs/fragments/filetree_node_schedule_survey.yml rename roles/{ansible_config => hub_ansible_config}/README.md (79%) rename roles/{ansible_config => hub_ansible_config}/defaults/main.yml (81%) rename roles/{ansible_config => hub_ansible_config}/meta/argument_specs.yml (92%) rename roles/{ansible_config => hub_ansible_config}/meta/main.yml (95%) rename roles/{ansible_config => hub_ansible_config}/tasks/main.yml (82%) rename roles/{ansible_config => hub_ansible_config}/templates/ansible.cfg.j2 (100%) rename roles/{ansible_config => hub_ansible_config}/tests/test.yml (77%) rename roles/{ansible_config => hub_ansible_config}/tests/vars/config.yml (100%) create mode 120000 tests/automatetheautomation/config-controller-filetree.yml create mode 120000 tests/automatetheautomation/drop_diff.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_aap_monitor.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_acme_key.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_cloudforms.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_multiple.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_servicenow.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/controller_credential_types.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_groups.d/controller_groups.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/app-example/controller_instance_groups_otlc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/controller_instance_groups.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-casc/controller_inventories_localhost.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_excel.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org1.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org2.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/controller_inventories.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-casc/controller_job_templates_casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_container_groups.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_demo_push.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/controller_job_templates.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-casc/controller_organizations_Global.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_ExampleOrg.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_OrgCrossTeams.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_Organizations1-2.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/controller_organizations.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-casc/controller_projects_casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-ocp/controller_projects_container_groups.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/controller_projects.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_cmdb_approvals.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventories.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventory_wf_update.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_teams.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_users.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/controller_roles.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-casc/controller_schedules_casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-example/controller_schedules_example.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/controller_schedules.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org1.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org2.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/controller_teams.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-casc/controller_workflow_job_templates_casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-examples/controller_workflow_job_templates_InventoryUpdate.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/controller_workflow_job_templates.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_aap.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_galaxy.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_machine.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_ocp.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_registry.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_scm.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_vault.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/controller_execution_environments.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/app-casc/controller_hosts_localhost.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/controller_hosts.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/controller_inventory_sources.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_jobs.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_ldap.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_system.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_user_interface.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/controller_settings.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org1.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org2.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/controller_user_accounts.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_aap.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_galaxy.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_machine.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_ocp.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_registry.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_scm.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_vault.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/controller_execution_environments.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_hosts.d/controller_hosts.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/controller_inventory_sources.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_jobs.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_ldap.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_system.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_user_interface.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/controller_settings.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org1.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org2.yml create mode 100644 tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/controller_user_accounts.yml create mode 100644 tests/automatetheautomation/orgs_vars/env/dev/configure_connection_controller_credentials.yml create mode 100644 tests/automatetheautomation/orgs_vars/env/prod/configure_connection_controller_credentials.yml create mode 100644 tests/automatetheautomation/pictures/AAP_CasC_Worflow.png delete mode 100644 tests/configure_platform.yml create mode 100644 tests/playbooks/README.md create mode 100644 tests/playbooks/cd_gitlab_webhook_trigger.yml create mode 100644 tests/playbooks/configure_awx.yml create mode 100644 tests/playbooks/configure_controller.yml create mode 100644 tests/playbooks/tasks/ad_hoc_cancel.yml diff --git a/.github/files/ansible.cfg b/.github/files/ansible.cfg index 258181399..34cfbf901 100644 --- a/.github/files/ansible.cfg +++ b/.github/files/ansible.cfg @@ -1,4 +1,4 @@ [defaults] -collections_path=/home/runner/collections +collections_paths=/home/runner/collections roles_path=roles/ lookup_plugins=plugins/lookup/ diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 7c6958d78..d2bd83dc8 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -24,7 +24,7 @@ jobs: with: collection_namespace: infra collection_name: controller_configuration - collection_version: 1.0.0 + collection_version: 2.10.0 collection_repo: https://github.com/redhat-cop/aap_configuration/ collection_dependencies: awx.awx ... diff --git a/changelogs/fragments/Rewrite.yml b/changelogs/fragments/Rewrite.yml deleted file mode 100644 index a221ca4e6..000000000 --- a/changelogs/fragments/Rewrite.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -breaking_changes: - - Major overhaul to all code completed, variables have changed, role names have changed, please see the tranition guide for more details. diff --git a/changelogs/fragments/filetree_node_schedule_survey.yml b/changelogs/fragments/filetree_node_schedule_survey.yml new file mode 100644 index 000000000..5b35a2883 --- /dev/null +++ b/changelogs/fragments/filetree_node_schedule_survey.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - filetree_create able export WF nodes and schedules without encrypted value in survey diff --git a/galaxy.yml b/galaxy.yml index 0899a2995..608a360a3 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: infra name: aap_configuration -version: 1.0.0 +version: 3.0.0 description: A collection of roles to manage Ansible Controller readme: README.md authors: @@ -18,7 +18,6 @@ build_ignore: - release.yml - .github - '*.tar.gz' - - tests/* license: - GPL-3.0-or-later tags: diff --git a/roles/controller_ad_hoc_command/README.md b/roles/controller_ad_hoc_command/README.md index 4779d6bb5..bdd0bf125 100644 --- a/roles/controller_ad_hoc_command/README.md +++ b/roles/controller_ad_hoc_command/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_ad_hoc_commands`|`see below`|yes|Data structure describing your ad hoc commands to run Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ad hoc commands task does not include sensitive information. -controller_configuration_ad_hoc_command_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_ad_hoc_command_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_ad_hoc_command_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -83,12 +83,12 @@ controller_ad_hoc_commands: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_ad_hoc_command/defaults/main.yml b/roles/controller_ad_hoc_command/defaults/main.yml index f59c60c36..0eaba3172 100644 --- a/roles/controller_ad_hoc_command/defaults/main.yml +++ b/roles/controller_ad_hoc_command/defaults/main.yml @@ -1,4 +1,4 @@ --- # These are the default variables specific to the ad_hoc_command role -controller_configuration_ad_hoc_command_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_ad_hoc_command_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" ... diff --git a/roles/controller_ad_hoc_command/meta/argument_specs.yml b/roles/controller_ad_hoc_command/meta/argument_specs.yml index 34c198915..c2260a2d9 100644 --- a/roles/controller_ad_hoc_command/meta/argument_specs.yml +++ b/roles/controller_ad_hoc_command/meta/argument_specs.yml @@ -76,45 +76,45 @@ argument_specs: # No_log variables controller_configuration_ad_hoc_command_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_ad_hoc_command/tasks/main.yml b/roles/controller_ad_hoc_command/tasks/main.yml index 5e19a9ae9..e8901266b 100644 --- a/roles/controller_ad_hoc_command/tasks/main.yml +++ b/roles/controller_ad_hoc_command/tasks/main.yml @@ -19,12 +19,13 @@ timeout: "{{ __ad_hoc_command_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_ad_hoc_commands }}" loop_control: loop_var: "__ad_hoc_command_item" diff --git a/roles/controller_ad_hoc_command/tests/test.yml b/roles/controller_ad_hoc_command/tests/test.yml index 44b66edb3..9bcad1c09 100644 --- a/roles/controller_ad_hoc_command/tests/test.yml +++ b/roles/controller_ad_hoc_command/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_ad_hoc_command_cancel/README.md b/roles/controller_ad_hoc_command_cancel/README.md index 2434d5118..69c2766f6 100644 --- a/roles/controller_ad_hoc_command_cancel/README.md +++ b/roles/controller_ad_hoc_command_cancel/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_ad_hoc_commands_cancel`|`see below`|yes|Data structure describing your ad hoc jobs to cancel Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ad hoc commands cancel task does not include sensitive information. -controller_configuration_ad_hoc_command_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_ad_hoc_command_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_ad_hoc_command_cancel_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command_cancel role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -75,12 +75,12 @@ controller_ad_hoc_commands_cancel: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_ad_hoc_command_cancel/defaults/main.yml b/roles/controller_ad_hoc_command_cancel/defaults/main.yml index 87010500b..41f05e285 100644 --- a/roles/controller_ad_hoc_command_cancel/defaults/main.yml +++ b/roles/controller_ad_hoc_command_cancel/defaults/main.yml @@ -1,4 +1,4 @@ --- # These are the default variables specific to the ad_hoc_command_cancel role -controller_configuration_ad_hoc_command_cancel_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_ad_hoc_command_cancel_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" ... diff --git a/roles/controller_ad_hoc_command_cancel/meta/argument_specs.yml b/roles/controller_ad_hoc_command_cancel/meta/argument_specs.yml index ad82f9e93..55d0d6abc 100644 --- a/roles/controller_ad_hoc_command_cancel/meta/argument_specs.yml +++ b/roles/controller_ad_hoc_command_cancel/meta/argument_specs.yml @@ -30,45 +30,45 @@ argument_specs: # No_log variables controller_configuration_ad_hoc_command_cancel_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_ad_hoc_command_cancel/tasks/main.yml b/roles/controller_ad_hoc_command_cancel/tasks/main.yml index 4cf880995..18e4f0c1f 100644 --- a/roles/controller_ad_hoc_command_cancel/tasks/main.yml +++ b/roles/controller_ad_hoc_command_cancel/tasks/main.yml @@ -8,12 +8,13 @@ timeout: "{{ __ad_hoc_command_cancel_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_ad_hoc_commands_cancel }}" loop_control: loop_var: "__ad_hoc_command_cancel_item" diff --git a/roles/controller_ad_hoc_command_cancel/tests/test.yml b/roles/controller_ad_hoc_command_cancel/tests/test.yml index 64e204205..3802c9362 100644 --- a/roles/controller_ad_hoc_command_cancel/tests/test.yml +++ b/roles/controller_ad_hoc_command_cancel/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_applications/README.md b/roles/controller_applications/README.md index 191346438..7316ab725 100644 --- a/roles/controller_applications/README.md +++ b/roles/controller_applications/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_applications`|`see below`|yes|Data structure describing your applications, described below. Alias: applications || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add application task does not include sensitive information. -controller_configuration_applications_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_applications_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_applications_secure_logging`|`False`|no|Whether or not to include the sensitive Application role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_applications_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_applications_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_applications_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_applications_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_applications_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -126,12 +126,12 @@ controller_applications: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_applications/defaults/main.yml b/roles/controller_applications/defaults/main.yml index 79048539f..073efbeb7 100644 --- a/roles/controller_applications/defaults/main.yml +++ b/roles/controller_applications/defaults/main.yml @@ -1,10 +1,10 @@ --- # a list of dictionaries describing the Controller applications controller_applications: [] -controller_configuration_applications_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_applications_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_applications_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_applications_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_applications_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_applications_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_applications_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_applications_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_applications/meta/argument_specs.yml b/roles/controller_applications/meta/argument_specs.yml index 9d6956237..3da902379 100644 --- a/roles/controller_applications/meta/argument_specs.yml +++ b/roles/controller_applications/meta/argument_specs.yml @@ -47,22 +47,22 @@ argument_specs: # Async variables controller_configuration_applications_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_applications_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -70,45 +70,45 @@ argument_specs: # No_log variables controller_configuration_applications_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_applications/tasks/main.yml b/roles/controller_applications/tasks/main.yml index a97c0a731..fef5950c7 100644 --- a/roles/controller_applications/tasks/main.yml +++ b/roles/controller_applications/tasks/main.yml @@ -10,15 +10,16 @@ client_type: "{{ __application_item.client_type | default('public') }}" redirect_uris: "{{ __application_item.redirect_uris | default([]) }}" skip_authorization: "{{ __application_item.skip_authorization | default((false if controller_configuration_applications_enforce_defaults else omit), true) }}" - state: "{{ __application_item.state | default(platform_state | default('present')) }}" + state: "{{ __application_item.state | default(controller_state | default('present')) }}" # Role specific options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ applications if applications is defined else controller_applications }}" loop_control: loop_var: "__application_item" @@ -30,8 +31,8 @@ register: __applications_job_async changed_when: "(__applications_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__application_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__application_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -52,6 +53,6 @@ when: not ansible_check_mode and __applications_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_applications_secure_logging }}" vars: - __operation: "{{ operation_translate[__applications_job_async_results_item.__application_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__applications_job_async_results_item.__application_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_applications/tests/test.yml b/roles/controller_applications/tests/test.yml index 9711d480b..eea09d7bd 100644 --- a/roles/controller_applications/tests/test.yml +++ b/roles/controller_applications/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_bulk_host_create/README.md b/roles/controller_bulk_host_create/README.md index 1999ae041..9bae686c1 100644 --- a/roles/controller_bulk_host_create/README.md +++ b/roles/controller_bulk_host_create/README.md @@ -18,7 +18,7 @@ Currently: |:---|:---:|:---:|:---|:---| |`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| |`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| |`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| |`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| |`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| @@ -29,12 +29,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ******* task does not include sensitive information. -controller_configuration_*******_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_*******_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_bulk_hosts_secure_logging`|`False`|no|Whether or not to include the sensitive ******* role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -45,13 +45,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_bulk_hosts_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_bulk_hosts_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_bulk_hosts_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_bulk_hosts_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_bulk_hosts_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -121,12 +121,12 @@ controller_bulk_hosts: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_bulk_host_create/defaults/main.yml b/roles/controller_bulk_host_create/defaults/main.yml index 0dba5f3a9..8bed33b42 100644 --- a/roles/controller_bulk_host_create/defaults/main.yml +++ b/roles/controller_bulk_host_create/defaults/main.yml @@ -1,7 +1,7 @@ --- -controller_configuration_bulk_hosts_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_bulk_hosts_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_bulk_hosts_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_bulk_hosts_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_bulk_hosts_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_bulk_hosts_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_bulk_hosts_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null ... diff --git a/roles/controller_bulk_host_create/meta/argument_specs.yml b/roles/controller_bulk_host_create/meta/argument_specs.yml index dcb40940d..a609ad810 100644 --- a/roles/controller_bulk_host_create/meta/argument_specs.yml +++ b/roles/controller_bulk_host_create/meta/argument_specs.yml @@ -9,18 +9,18 @@ argument_specs: elements: dict # Async variables - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables controller_configuration_bulk_hosts_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool @@ -37,7 +37,7 @@ argument_specs: required: false description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. diff --git a/roles/controller_bulk_host_create/tasks/main.yml b/roles/controller_bulk_host_create/tasks/main.yml index e99c95f4a..ec4707a50 100644 --- a/roles/controller_bulk_host_create/tasks/main.yml +++ b/roles/controller_bulk_host_create/tasks/main.yml @@ -6,12 +6,13 @@ inventory: "{{ __controller_bulk_hosts_item.inventory }}" # Role Standard options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_bulk_hosts }}" loop_control: loop_var: __controller_bulk_hosts_item @@ -22,7 +23,7 @@ register: __controller_bulk_hosts_job_async changed_when: "(__controller_bulk_hosts_job_async.changed if ansible_check_mode else false)" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -42,5 +43,5 @@ when: not ansible_check_mode and __controller_bulk_hosts_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_bulk_hosts_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_bulk_job_launch/README.md b/roles/controller_bulk_job_launch/README.md index aea72b3d1..f11ed0ff6 100644 --- a/roles/controller_bulk_job_launch/README.md +++ b/roles/controller_bulk_job_launch/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_bulk_launch_jobs`|`see below`|yes|Data structure describing your organization or organizations Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ******* task does not include sensitive information. -controller_configuration_*******_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_*******_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_bulk_job_launch_secure_logging`|`False`|no|Whether or not to include the sensitive bulk_job_launch role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -46,10 +46,10 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_bulk_job_launch_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_bulk_job_launch_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_bulk_job_launch_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_bulk_job_launch_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_bulk_job_launch_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| @@ -119,12 +119,12 @@ This also speeds up the overall role. - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_bulk_job_launch/defaults/main.yml b/roles/controller_bulk_job_launch/defaults/main.yml index 1a6a9aa19..618e9b564 100644 --- a/roles/controller_bulk_job_launch/defaults/main.yml +++ b/roles/controller_bulk_job_launch/defaults/main.yml @@ -1,6 +1,6 @@ --- -controller_configuration_bulk_job_launch_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_bulk_job_launch_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_bulk_job_launch_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_bulk_job_launch_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_bulk_job_launch_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_bulk_job_launch_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_bulk_job_launch_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" ... diff --git a/roles/controller_bulk_job_launch/meta/argument_specs.yml b/roles/controller_bulk_job_launch/meta/argument_specs.yml index 0c98eef37..f85ee8b3e 100644 --- a/roles/controller_bulk_job_launch/meta/argument_specs.yml +++ b/roles/controller_bulk_job_launch/meta/argument_specs.yml @@ -10,45 +10,45 @@ argument_specs: # No_log variables controller_configuration_bulk_job_launch_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_bulk_job_launch/tasks/main.yml b/roles/controller_bulk_job_launch/tasks/main.yml index 5efa1032c..7207e909c 100644 --- a/roles/controller_bulk_job_launch/tasks/main.yml +++ b/roles/controller_bulk_job_launch/tasks/main.yml @@ -16,12 +16,13 @@ interval: "{{ __bulk_job_launch_item.interval | default(omit) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_bulk_launch_jobs }}" loop_control: loop_var: "__bulk_job_launch_item" diff --git a/roles/controller_credential_input_sources/README.md b/roles/controller_credential_input_sources/README.md index f20489091..96ad61940 100644 --- a/roles/controller_credential_input_sources/README.md +++ b/roles/controller_credential_input_sources/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_credential_input_sources`|`see below`|yes|Data structure describing your credential input sources Described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add credential input source task does not include sensitive information. -controller_configuration_credential_input_sources_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_credential_input_sources_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_credential_input_sources_secure_logging`|`False`|no|Whether or not to include the sensitive credential_input_source role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_credential_input_sources_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_credential_input_sources_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_credential_input_sources_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_credential_input_sources_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_credential_input_sources_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -152,12 +152,12 @@ controller_credential_input_sources: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_credential_input_sources/defaults/main.yml b/roles/controller_credential_input_sources/defaults/main.yml index 264034132..a05fa2057 100644 --- a/roles/controller_credential_input_sources/defaults/main.yml +++ b/roles/controller_credential_input_sources/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dicts describing Controller credential input sources controller_credential_input_sources: [] -controller_configuration_credential_input_sources_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_credential_input_sources_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_credential_input_sources_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_credential_input_sources_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_credential_input_sources_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_credential_input_sources_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_credential_input_sources_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_credential_input_sources_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_credential_input_sources/meta/argument_specs.yml b/roles/controller_credential_input_sources/meta/argument_specs.yml index 86474c438..c03c9c848 100644 --- a/roles/controller_credential_input_sources/meta/argument_specs.yml +++ b/roles/controller_credential_input_sources/meta/argument_specs.yml @@ -36,22 +36,22 @@ argument_specs: # Async variables controller_configuration_credential_input_sources_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_credential_input_sources_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -59,45 +59,45 @@ argument_specs: # No_log variables controller_configuration_credential_input_sources_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_credential_input_sources/tasks/main.yml b/roles/controller_credential_input_sources/tasks/main.yml index 5663e15fe..857dbeb08 100644 --- a/roles/controller_credential_input_sources/tasks/main.yml +++ b/roles/controller_credential_input_sources/tasks/main.yml @@ -6,15 +6,16 @@ source_credential: "{{ __cred_input_src_item.source_credential | default(omit, true) }}" description: "{{ __cred_input_src_item.description | default(('' if controller_configuration_credential_input_sources_enforce_defaults else omit), true) }}" metadata: "{{ __cred_input_src_item.metadata | default(({} if controller_configuration_credential_input_sources_enforce_defaults else omit), true) }}" - state: "{{ __cred_input_src_item.state | default(platform_state | default('present')) }}" + state: "{{ __cred_input_src_item.state | default(controller_state | default('present')) }}" # Role specific options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_credential_input_sources }}" loop_control: loop_var: "__cred_input_src_item" @@ -26,8 +27,8 @@ register: __credential_input_sources_job_async changed_when: "(__credential_input_sources_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__cred_input_src_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__cred_input_src_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -48,6 +49,6 @@ when: not ansible_check_mode and __credential_input_sources_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_credential_input_sources_secure_logging }}" vars: - __operation: "{{ operation_translate[__credential_input_sources_job_async_results_item.__cred_input_src_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__credential_input_sources_job_async_results_item.__cred_input_src_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_credential_input_sources/tests/test.yml b/roles/controller_credential_input_sources/tests/test.yml index f2f7c2faa..38b597cf0 100644 --- a/roles/controller_credential_input_sources/tests/test.yml +++ b/roles/controller_credential_input_sources/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_credential_types/README.md b/roles/controller_credential_types/README.md index fd433c855..932c589da 100644 --- a/roles/controller_credential_types/README.md +++ b/roles/controller_credential_types/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_credential_types`|`see below`|yes|Data structure describing your credential types Described below. Alias: credential_types || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add credential type task does not include sensitive information. -controller_configuration_credential_types_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_credential_types_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_credential_types_secure_logging`|`False`|no|Whether or not to include the sensitive Credential Type role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_credential_types_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_credential_types_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_credential_types_async_retries`|`controller_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_credential_types_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_credential_types_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -227,12 +227,12 @@ controller_credential_types: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_credential_types/defaults/main.yml b/roles/controller_credential_types/defaults/main.yml index 7732ff6ad..baab1021a 100644 --- a/roles/controller_credential_types/defaults/main.yml +++ b/roles/controller_credential_types/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict to define Controller credential types controller_credential_types: [] -controller_configuration_credential_types_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_credential_types_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_credential_types_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_credential_types_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_credential_types_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_credential_types_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_credential_types_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_credential_types_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_credential_types/meta/argument_specs.yml b/roles/controller_credential_types/meta/argument_specs.yml index db2457c53..94580d0a7 100644 --- a/roles/controller_credential_types/meta/argument_specs.yml +++ b/roles/controller_credential_types/meta/argument_specs.yml @@ -44,22 +44,22 @@ argument_specs: # Async variables controller_configuration_credential_types_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_credential_types_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -67,45 +67,45 @@ argument_specs: # No_log variables controller_configuration_credential_types_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_credential_types/tasks/main.yml b/roles/controller_credential_types/tasks/main.yml index 7bebe7acd..941635de1 100644 --- a/roles/controller_credential_types/tasks/main.yml +++ b/roles/controller_credential_types/tasks/main.yml @@ -7,15 +7,16 @@ injectors: "{{ __controller_credential_type_item.injectors | default(({} if controller_configuration_credential_types_enforce_defaults else omit), true) | regex_replace('{ {', '{_~~remove~~_{') | regex_replace('_~~remove~~_', '') }}" inputs: "{{ __controller_credential_type_item.inputs | default(({} if controller_configuration_credential_types_enforce_defaults else omit), true) }}" kind: "{{ __controller_credential_type_item.kind | default('cloud') }}" - state: "{{ __controller_credential_type_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_credential_type_item.state | default(controller_state | default('present')) }}" # Role specific options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ credential_types if credential_types is defined else controller_credential_types }}" loop_control: loop_var: __controller_credential_type_item @@ -27,8 +28,8 @@ register: __credentialtypes_job_async changed_when: "(__credentialtypes_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_credential_type_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_credential_type_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -49,6 +50,6 @@ when: not ansible_check_mode and __credentialtypes_job_async_result_item.ansible_job_id is defined no_log: "{{ controller_configuration_credential_types_secure_logging }}" vars: - __operation: "{{ operation_translate[__credentialtypes_job_async_result_item.__controller_credential_type_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__credentialtypes_job_async_result_item.__controller_credential_type_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_credential_types/tests/test.yml b/roles/controller_credential_types/tests/test.yml index f6e420390..76e89cb06 100644 --- a/roles/controller_credential_types/tests/test.yml +++ b/roles/controller_credential_types/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_credentials/README.md b/roles/controller_credentials/README.md index 405ebbc55..22c136f74 100644 --- a/roles/controller_credentials/README.md +++ b/roles/controller_credentials/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_credentials`|`see below`|yes|Data structure describing your credentials Described below. Alias: credentials || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add credentials task does not include sensitive information. -controller_configuration_credentials_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_credentials_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_credentials_secure_logging`|`False`|no|Whether or not to include the sensitive Credential role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_credentials_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_credentials_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_credentials_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_credentials_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_credentials_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -153,12 +153,12 @@ controller_credentials: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_credentials/defaults/main.yml b/roles/controller_credentials/defaults/main.yml index 6fdb5c562..34ba6a682 100644 --- a/roles/controller_credentials/defaults/main.yml +++ b/roles/controller_credentials/defaults/main.yml @@ -1,10 +1,10 @@ --- # a list of dicts describing Controller credentials controller_credentials: [] -controller_configuration_credentials_secure_logging: "{{ platform_configuration_secure_logging | default(true) }}" -controller_configuration_credentials_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_credentials_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_credentials_secure_logging: "{{ controller_configuration_secure_logging | default(true) }}" +controller_configuration_credentials_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_credentials_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_credentials_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_credentials_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_credentials/meta/argument_specs.yml b/roles/controller_credentials/meta/argument_specs.yml index c0d47bef2..f8b5f8a1e 100644 --- a/roles/controller_credentials/meta/argument_specs.yml +++ b/roles/controller_credentials/meta/argument_specs.yml @@ -57,22 +57,22 @@ argument_specs: # Async variables controller_configuration_credentials_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_credentials_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -80,45 +80,45 @@ argument_specs: # No_log variables controller_configuration_credentials_secure_logging: - default: "{{ platform_configuration_secure_logging | default(true) }}" + default: "{{ controller_configuration_secure_logging | default(true) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_credentials/tasks/main.yml b/roles/controller_credentials/tasks/main.yml index b4baf45ee..fd9ac9f40 100644 --- a/roles/controller_credentials/tasks/main.yml +++ b/roles/controller_credentials/tasks/main.yml @@ -11,14 +11,15 @@ user: "{{ __controller_credentials_item.user.username | default(__controller_credentials_item.user | default(omit, true)) }}" team: "{{ __controller_credentials_item.team.name | default(__controller_credentials_item.team | default(omit, true)) }}" update_secrets: "{{ __controller_credentials_item.update_secrets | default(true if controller_configuration_credentials_enforce_defaults else omit) }}" - state: "{{ __controller_credentials_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_credentials_item.state | default(controller_state | default('present')) }}" # Role specific options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ credentials if credentials is defined else controller_credentials }}" loop_control: loop_var: __controller_credentials_item @@ -30,8 +31,8 @@ register: __credentials_job_async changed_when: "(__credentials_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_credentials_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_credentials_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -52,6 +53,6 @@ when: not ansible_check_mode and __credentials_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_credentials_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_credentials_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_credentials_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_credentials/tests/test.yml b/roles/controller_credentials/tests/test.yml index 2ca4ab29e..42409f5a2 100644 --- a/roles/controller_credentials/tests/test.yml +++ b/roles/controller_credentials/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_execution_environments/README.md b/roles/controller_execution_environments/README.md index 4a09898a7..dacdb3f87 100644 --- a/roles/controller_execution_environments/README.md +++ b/roles/controller_execution_environments/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_execution_environments`|`see below`|yes|Data structure describing your organization or organizations Described below. Alias: execution_environments || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add execution_environments task does not include sensitive information. -controller_configuration_execution_environments_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_execution_environments_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_execution_environments_secure_logging`|`False`|no|Whether or not to include the sensitive execution_environments role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_execution_environments_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_execution_environments_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_execution_environments_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_execution_environments_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_execution_environments_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure diff --git a/roles/controller_execution_environments/defaults/main.yml b/roles/controller_execution_environments/defaults/main.yml index e8312e30e..a299af938 100644 --- a/roles/controller_execution_environments/defaults/main.yml +++ b/roles/controller_execution_environments/defaults/main.yml @@ -1,9 +1,9 @@ --- # These are the default variables specific to the execution_environments role -controller_configuration_execution_environments_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_execution_environments_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_execution_environments_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_execution_environments_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_execution_environments_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_execution_environments_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_execution_environments_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_execution_environments_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_execution_environments/meta/argument_specs.yml b/roles/controller_execution_environments/meta/argument_specs.yml index 47387aa17..10aa99f4f 100644 --- a/roles/controller_execution_environments/meta/argument_specs.yml +++ b/roles/controller_execution_environments/meta/argument_specs.yml @@ -45,22 +45,22 @@ argument_specs: # Async variables controller_configuration_execution_environments_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_execution_environments_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -68,45 +68,45 @@ argument_specs: # No_log variables controller_configuration_execution_environments_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_execution_environments/tasks/main.yml b/roles/controller_execution_environments/tasks/main.yml index e74cdf220..85f931344 100644 --- a/roles/controller_execution_environments/tasks/main.yml +++ b/roles/controller_execution_environments/tasks/main.yml @@ -9,15 +9,16 @@ organization: "{{ __execution_environments_item.organization.name | default(__execution_environments_item.organization | default(('' if controller_configuration_execution_environments_enforce_defaults else omit), true)) }}" credential: "{{ __execution_environments_item.credential | default(('' if controller_configuration_execution_environments_enforce_defaults else omit), true) }}" pull: "{{ __execution_environments_item.pull | default(('missing' if controller_configuration_execution_environments_enforce_defaults else omit), true) }}" - state: "{{ __execution_environments_item.state | default(platform_state | default('present')) }}" + state: "{{ __execution_environments_item.state | default(controller_state | default('present')) }}" # Role specific options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ execution_environments if execution_environments is defined else controller_execution_environments }}" loop_control: loop_var: "__execution_environments_item" @@ -30,8 +31,8 @@ register: __execution_environments_job_async changed_when: "(__execution_environments_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__execution_environments_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__execution_environments_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -52,6 +53,6 @@ when: not ansible_check_mode and __execution_environments_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_execution_environments_secure_logging }}" vars: - __operation: "{{ operation_translate[__execution_environments_job_async_results_item.__execution_environments_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__execution_environments_job_async_results_item.__execution_environments_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_execution_environments/tests/test.yml b/roles/controller_execution_environments/tests/test.yml index ecd83eef7..cedbc88d5 100644 --- a/roles/controller_execution_environments/tests/test.yml +++ b/roles/controller_execution_environments/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_host_groups/README.md b/roles/controller_host_groups/README.md index 9afa62889..dd7cd2eb7 100644 --- a/roles/controller_host_groups/README.md +++ b/roles/controller_host_groups/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_groups`|`see below`|yes|Data structure describing your group or groups Described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add groups task does not include sensitive information. -controller_configuration_groups_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_groups_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_groups_secure_logging`|`False`|no|Whether or not to include the sensitive Group role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_groups_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_groups_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_groups_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_groups_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_group_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ### Formating Variables @@ -155,12 +155,12 @@ controller_groups: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_host_groups/defaults/main.yml b/roles/controller_host_groups/defaults/main.yml index ed94aa30c..edf5a8618 100644 --- a/roles/controller_host_groups/defaults/main.yml +++ b/roles/controller_host_groups/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dicts to describe Controller inventory groups controller_groups: [] -controller_configuration_group_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_group_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_group_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_group_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_group_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_group_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_group_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_groups_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_host_groups/meta/argument_specs.yml b/roles/controller_host_groups/meta/argument_specs.yml index 89b190fad..8ff25e66f 100644 --- a/roles/controller_host_groups/meta/argument_specs.yml +++ b/roles/controller_host_groups/meta/argument_specs.yml @@ -56,22 +56,22 @@ argument_specs: # Async variables controller_configuration_groups_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_groups_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -79,45 +79,45 @@ argument_specs: # No_log variables controller_configuration_groups_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_host_groups/tasks/main.yml b/roles/controller_host_groups/tasks/main.yml index 5d67a7963..6cf0a3efa 100644 --- a/roles/controller_host_groups/tasks/main.yml +++ b/roles/controller_host_groups/tasks/main.yml @@ -12,15 +12,16 @@ children: "{{ __controller_groups_item.children | default(([] if controller_configuration_groups_enforce_defaults else omit), true) }}" preserve_existing_hosts: "{{ __controller_groups_item.preserve_existing_hosts | default((false if controller_configuration_groups_enforce_defaults else omit)) }}" preserve_existing_children: "{{ __controller_groups_item.preserve_existing_children | default((false if controller_configuration_groups_enforce_defaults else omit)) }}" - state: "{{ __controller_groups_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_groups_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_groups }}" loop_control: loop_var: __controller_groups_item @@ -32,8 +33,8 @@ register: __group_job_async changed_when: "(__group_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_groups_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_groups_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -54,6 +55,6 @@ when: not ansible_check_mode and __group_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_group_secure_logging }}" vars: - __operation: "{{ operation_translate[__group_job_async_results_item.__controller_groups_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__group_job_async_results_item.__controller_groups_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_host_groups/tests/test.yml b/roles/controller_host_groups/tests/test.yml index ee671c900..d13500f63 100644 --- a/roles/controller_host_groups/tests/test.yml +++ b/roles/controller_host_groups/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_hosts/README.md b/roles/controller_hosts/README.md index 624a4cd69..cc7792eb7 100644 --- a/roles/controller_hosts/README.md +++ b/roles/controller_hosts/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_hosts`|`see below`|yes|Data structure describing your host entries described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add host task does not include sensitive information. -`controller_configuration_host_secure_logging` defaults to the value of `platform_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +`controller_configuration_host_secure_logging` defaults to the value of `controller_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_host_secure_logging`|`False`|no|Whether or not to include the sensitive host role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_host_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_host_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_host_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_host_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_hosts_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ### Formating Variables @@ -143,12 +143,12 @@ controller_hosts: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_hosts/defaults/main.yml b/roles/controller_hosts/defaults/main.yml index bf14337a0..5318abd32 100644 --- a/roles/controller_hosts/defaults/main.yml +++ b/roles/controller_hosts/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dicts to describe Controller inventory hosts controller_hosts: [] -controller_configuration_hosts_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_hosts_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_hosts_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_hosts_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_hosts_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_hosts_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_hosts_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_host_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_hosts/meta/argument_specs.yml b/roles/controller_hosts/meta/argument_specs.yml index ad38db4fb..0cfa2ef60 100644 --- a/roles/controller_hosts/meta/argument_specs.yml +++ b/roles/controller_hosts/meta/argument_specs.yml @@ -41,22 +41,22 @@ argument_specs: # Async variables controller_configuration_hosts_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_hosts_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -64,45 +64,45 @@ argument_specs: # No_log variables controller_configuration_hosts_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_hosts/tasks/main.yml b/roles/controller_hosts/tasks/main.yml index bcb4694d9..bb2a7e3bb 100644 --- a/roles/controller_hosts/tasks/main.yml +++ b/roles/controller_hosts/tasks/main.yml @@ -6,16 +6,17 @@ description: "{{ __controller_host_item.description | default(('' if controller_configuration_host_enforce_defaults else omit), true) }}" inventory: "{{ __controller_host_item.inventory | mandatory }}" enabled: "{{ __controller_host_item.enabled | default((false if controller_configuration_host_enforce_defaults else omit), true) }}" - state: "{{ __controller_host_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_host_item.state | default(controller_state | default('present')) }}" variables: "{{ __controller_host_item.variables | default(({} if controller_configuration_host_enforce_defaults else omit), true) | regex_replace('{ {', '{_~~remove~~_{') | regex_replace('_~~remove~~_', '') }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_hosts }}" loop_control: loop_var: __controller_host_item @@ -27,8 +28,8 @@ register: __host_job_async changed_when: "(__host_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_host_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_host_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -49,6 +50,6 @@ when: not ansible_check_mode and __host_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_hosts_secure_logging }}" vars: - __operation: "{{ operation_translate[__host_job_async_results_item.__controller_host_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__host_job_async_results_item.__controller_host_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_hosts/tests/test.yml b/roles/controller_hosts/tests/test.yml index 4ba1b985f..e99a56994 100644 --- a/roles/controller_hosts/tests/test.yml +++ b/roles/controller_hosts/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_instance_groups/README.md b/roles/controller_instance_groups/README.md index 181c19c5e..54373a3fa 100644 --- a/roles/controller_instance_groups/README.md +++ b/roles/controller_instance_groups/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_instance_groups`|`see below`|yes|Data structure describing your instance groups Described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add instance groups task does not include sensitive information. -controller_configuration_instance_groups_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_instance_groups_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_instance_groups_secure_logging`|`False`|no|Whether or not to include the sensitive instance groups role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_instance_groups_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_instance_groups_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_instance_groups_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_instance_groups_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_instance_groups_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -108,12 +108,12 @@ controller_instance_groups: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_instance_groups/defaults/main.yml b/roles/controller_instance_groups/defaults/main.yml index 0d0708a62..9f0e0af55 100644 --- a/roles/controller_instance_groups/defaults/main.yml +++ b/roles/controller_instance_groups/defaults/main.yml @@ -1,9 +1,9 @@ --- controller_instance_groups: [] -controller_configuration_instance_groups_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_instance_groups_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_instance_groups_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_instance_groups_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_instance_groups_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_instance_groups_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_instance_groups_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_instance_groups_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_instance_groups/meta/argument_specs.yml b/roles/controller_instance_groups/meta/argument_specs.yml index 29b77451e..17ddba3e8 100644 --- a/roles/controller_instance_groups/meta/argument_specs.yml +++ b/roles/controller_instance_groups/meta/argument_specs.yml @@ -65,22 +65,22 @@ argument_specs: # Async variables controller_configuration_instance_groups_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_instance_groups_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -88,45 +88,45 @@ argument_specs: # No_log variables controller_configuration_instance_groups_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_instance_groups/tasks/main.yml b/roles/controller_instance_groups/tasks/main.yml index a57b1a579..3093d7d88 100644 --- a/roles/controller_instance_groups/tasks/main.yml +++ b/roles/controller_instance_groups/tasks/main.yml @@ -12,15 +12,16 @@ max_forks: "{{ __controller_instance_group_item.max_forks | default(0, true) if __controller_instance_group_item.max_forks is defined or controller_configuration_instance_groups_enforce_defaults else omit }}" pod_spec_override: "{{ __controller_instance_group_item.pod_spec_override | default(('' if controller_configuration_instance_groups_enforce_defaults else omit), true) }}" instances: "{{ __controller_instance_group_item.instances | default(([] if controller_configuration_instance_groups_enforce_defaults else omit), true) }}" - state: "{{ __controller_instance_group_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_instance_group_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_instance_groups }}" loop_control: loop_var: __controller_instance_group_item @@ -33,8 +34,8 @@ register: __instance_groups_job_async changed_when: "(__instance_groups_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_instance_group_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_instance_group_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -55,6 +56,6 @@ when: not ansible_check_mode and __instance_groups_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_instance_groups_secure_logging }}" vars: - __operation: "{{ operation_translate[__instance_groups_job_async_results_item.__controller_instance_group_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__instance_groups_job_async_results_item.__controller_instance_group_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_instance_groups/tests/test.yml b/roles/controller_instance_groups/tests/test.yml index 92ab980be..640b8f963 100644 --- a/roles/controller_instance_groups/tests/test.yml +++ b/roles/controller_instance_groups/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_instances/README.md b/roles/controller_instances/README.md index 97464c8ce..f988cca7f 100644 --- a/roles/controller_instances/README.md +++ b/roles/controller_instances/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_instances`|`see below`|yes|Data structure describing your instances Described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add instances task does not include sensitive information. -controller_configuration_instances_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_instances_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_instances_secure_logging`|`False`|no|Whether or not to include the sensitive instance groups role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_instances_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_instances_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_instances_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_instances_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_instances_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -107,12 +107,12 @@ controller_instances: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_instances/defaults/main.yml b/roles/controller_instances/defaults/main.yml index 1c5777a5e..b1b5e9b7e 100644 --- a/roles/controller_instances/defaults/main.yml +++ b/roles/controller_instances/defaults/main.yml @@ -1,9 +1,9 @@ --- controller_instances: [] -controller_configuration_instances_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_instances_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_instances_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_instances_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_instances_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_instances_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_instances_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_instances_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_instances/meta/argument_specs.yml b/roles/controller_instances/meta/argument_specs.yml index c035d16a5..13c47503f 100644 --- a/roles/controller_instances/meta/argument_specs.yml +++ b/roles/controller_instances/meta/argument_specs.yml @@ -41,22 +41,22 @@ argument_specs: # Async variables controller_configuration_instances_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_instances_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -64,45 +64,45 @@ argument_specs: # No_log variables controller_configuration_instances_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_instances/tasks/main.yml b/roles/controller_instances/tasks/main.yml index a5c187ce3..0f424ea45 100644 --- a/roles/controller_instances/tasks/main.yml +++ b/roles/controller_instances/tasks/main.yml @@ -13,12 +13,13 @@ peers_from_control_nodes: "{{ __controller_instance_item.peers_from_control_nodes | default((false if controller_configuration_instances_enforce_defaults else omit), true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_instances }}" loop_control: loop_var: __controller_instance_item @@ -31,7 +32,7 @@ register: __instance_job_async changed_when: "(__instance_job_async.changed if ansible_check_mode else false)" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -51,5 +52,5 @@ when: not ansible_check_mode and __instance_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_instances_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_instances/tests/test.yml b/roles/controller_instances/tests/test.yml index ee2ab0102..6c37843aa 100644 --- a/roles/controller_instances/tests/test.yml +++ b/roles/controller_instances/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_inventories/README.md b/roles/controller_inventories/README.md index 96d4a7716..ce83cf62f 100644 --- a/roles/controller_inventories/README.md +++ b/roles/controller_inventories/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_inventories`|`see below`|yes|Data structure describing your inventories described below. Alias: inventory || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add inventories task does not include sensitive information. -controller_configuration_inventories_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_inventories_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_inventories_secure_logging`|`False`|no|Whether or not to include the sensitive Inventory role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_inventories_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_inventories_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_inventories_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_inventories_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_inventories_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ### Formating Variables @@ -158,12 +158,12 @@ controller_inventories: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_inventories/defaults/main.yml b/roles/controller_inventories/defaults/main.yml index 313f9cee2..5e7f0a83d 100644 --- a/roles/controller_inventories/defaults/main.yml +++ b/roles/controller_inventories/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dicts to describe Controller inventories controller_inventories: [] -controller_configuration_inventories_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_inventories_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_inventories_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_inventories_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_inventories_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_inventories_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_inventories_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_inventories_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_inventories/meta/argument_specs.yml b/roles/controller_inventories/meta/argument_specs.yml index b887dd487..35c58df6b 100644 --- a/roles/controller_inventories/meta/argument_specs.yml +++ b/roles/controller_inventories/meta/argument_specs.yml @@ -59,22 +59,22 @@ argument_specs: # Async variables controller_configuration_inventories_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_inventories_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -82,45 +82,45 @@ argument_specs: # No_log variables controller_configuration_inventories_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_inventories/tasks/main.yml b/roles/controller_inventories/tasks/main.yml index 9bbe1fa28..913a2a9d3 100644 --- a/roles/controller_inventories/tasks/main.yml +++ b/roles/controller_inventories/tasks/main.yml @@ -12,15 +12,16 @@ kind: "{{ __controller_inventory_item.kind | default(('' if controller_configuration_inventories_enforce_defaults else omit), true) }}" host_filter: "{{ __controller_inventory_item.host_filter | default(('' if controller_configuration_inventories_enforce_defaults else omit), true) }}" prevent_instance_group_fallback: "{{ __controller_inventory_item.prevent_instance_group_fallback | default((false if controller_configuration_inventories_enforce_defaults else omit), true) }}" - state: "{{ __controller_inventory_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_inventory_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ inventory if inventory is defined else controller_inventories }}" loop_control: loop_var: __controller_inventory_item @@ -32,8 +33,8 @@ register: __inventories_job_async changed_when: "(__inventories_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_inventory_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_inventory_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -54,6 +55,6 @@ when: not ansible_check_mode and __inventories_job_async_result_item.ansible_job_id is defined no_log: "{{ controller_configuration_inventories_secure_logging }}" vars: - __operation: "{{ operation_translate[__inventories_job_async_result_item.__controller_inventory_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__inventories_job_async_result_item.__controller_inventory_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_inventories/tests/test.yml b/roles/controller_inventories/tests/test.yml index 3b9d9aea8..c78f4c92c 100644 --- a/roles/controller_inventories/tests/test.yml +++ b/roles/controller_inventories/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_inventory_source_update/README.md b/roles/controller_inventory_source_update/README.md index 4b2c3607a..aafb5df37 100644 --- a/roles/controller_inventory_source_update/README.md +++ b/roles/controller_inventory_source_update/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_inventory_sources`|`see below`|yes|Data structure describing controller inventory sources to update Described below. Alias: inventory_sources || ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the inventory source update task does not include sensitive information. -controller_configuration_inventory_source_update_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_inventory_source_update_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_inventory_source_update_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -46,13 +46,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_inventory_source_update_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_inventory_source_update_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_inventory_source_update_async_retries`|`controller_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_inventory_source_update_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_inventory_source_update_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -97,12 +97,12 @@ controller_inventory_sources: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_inventory_source_update/defaults/main.yml b/roles/controller_inventory_source_update/defaults/main.yml index 59088f36b..b04590415 100644 --- a/roles/controller_inventory_source_update/defaults/main.yml +++ b/roles/controller_inventory_source_update/defaults/main.yml @@ -1,7 +1,7 @@ --- -controller_configuration_inventory_source_update_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_inventory_source_update_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_inventory_source_update_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_inventory_source_update_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_inventory_source_update_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_inventory_source_update_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_inventory_source_update_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null ... diff --git a/roles/controller_inventory_source_update/meta/argument_specs.yml b/roles/controller_inventory_source_update/meta/argument_specs.yml index 8979130ad..0c81ed4d7 100644 --- a/roles/controller_inventory_source_update/meta/argument_specs.yml +++ b/roles/controller_inventory_source_update/meta/argument_specs.yml @@ -25,7 +25,7 @@ argument_specs: # type: bool # description: Wait for the job to complete. # interval: - # default: "{{ controller_configuration_inventory_source_update_async_delay | default(platform_configuration_async_retries | default(30)) }}" + # default: "{{ controller_configuration_inventory_source_update_async_delay | default(controller_configuration_async_retries | default(30)) }}" # required: false # type: int # description: The interval to request an update from controller. @@ -135,22 +135,22 @@ argument_specs: # Async variables controller_configuration_inventory_source_updates_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_inventory_source_updates_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -158,45 +158,45 @@ argument_specs: # No_log variables controller_configuration_inventory_source_updates_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_inventory_source_update/tasks/main.yml b/roles/controller_inventory_source_update/tasks/main.yml index 4646e0111..8a8f84120 100644 --- a/roles/controller_inventory_source_update/tasks/main.yml +++ b/roles/controller_inventory_source_update/tasks/main.yml @@ -10,12 +10,13 @@ timeout: "{{ __inventory_source_update_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ inventory_sources if inventory_sources is defined else controller_inventory_sources }}" loop_control: loop_var: "__inventory_source_update_item" @@ -30,7 +31,7 @@ register: __inventory_source_update_async changed_when: not __inventory_source_update_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -50,5 +51,5 @@ when: not ansible_check_mode and __inventory_source_update_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_inventory_source_update_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_inventory_source_update/tests/test.yml b/roles/controller_inventory_source_update/tests/test.yml index 61106f389..e8ad47f16 100644 --- a/roles/controller_inventory_source_update/tests/test.yml +++ b/roles/controller_inventory_source_update/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_inventory_sources/README.md b/roles/controller_inventory_sources/README.md index 33c6fa906..9ef1f049b 100644 --- a/roles/controller_inventory_sources/README.md +++ b/roles/controller_inventory_sources/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_inventory_sources`|`see below`|yes|Data structure describing your inventory sources Described below. Alias: inventory_sources || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add inventory_source task does not include sensitive information. -controller_configuration_inventory_sources_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_inventory_sources_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_inventory_sources_secure_logging`|`False`|no|Whether or not to include the sensitive Inventory Sources role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_inventory_sources_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_inventory_sources_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_inventory_sources_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_inventory_sources_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_inventory_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ### Formating Variables @@ -171,12 +171,12 @@ controller_inventory_sources: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_inventory_sources/defaults/main.yml b/roles/controller_inventory_sources/defaults/main.yml index 7b09dd4bc..8cd3c8864 100644 --- a/roles/controller_inventory_sources/defaults/main.yml +++ b/roles/controller_inventory_sources/defaults/main.yml @@ -1,9 +1,9 @@ --- controller_inventory_sources: [] -controller_configuration_inventory_sources_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_inventory_sources_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_inventory_sources_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_inventory_sources_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_inventory_sources_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_inventory_sources_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_inventory_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_inventory_sources_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_inventory_sources/meta/argument_specs.yml b/roles/controller_inventory_sources/meta/argument_specs.yml index 65939e030..022819924 100644 --- a/roles/controller_inventory_sources/meta/argument_specs.yml +++ b/roles/controller_inventory_sources/meta/argument_specs.yml @@ -135,22 +135,22 @@ argument_specs: # Async variables controller_configuration_inventory_sources_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_inventory_sources_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -158,45 +158,45 @@ argument_specs: # No_log variables controller_configuration_inventory_sources_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_inventory_sources/tasks/main.yml b/roles/controller_inventory_sources/tasks/main.yml index 8e5ee9342..b75869b28 100644 --- a/roles/controller_inventory_sources/tasks/main.yml +++ b/roles/controller_inventory_sources/tasks/main.yml @@ -24,18 +24,19 @@ update_cache_timeout: "{{ __controller_source_item.update_cache_timeout | default(0, true) if __controller_source_item.update_cache_timeout is defined or controller_configuration_inventory_sources_enforce_defaults else omit }}" source_project: "{{ __controller_source_item.source_project.name | default(__controller_source_item.source_project | default(('' if controller_configuration_inventory_sources_enforce_defaults else omit), true)) }}" scm_branch: "{{ __controller_source_item.scm_branch | default(('' if controller_configuration_inventory_sources_enforce_defaults else omit), true) }}" - state: "{{ __controller_source_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_source_item.state | default(controller_state | default('present')) }}" notification_templates_started: "{{ (__controller_source_item.related.notification_templates_started | map(attribute='name') | list if __controller_source_item.related.notification_templates_started is defined) | default(__controller_source_item.notification_templates_started) | default(([] if controller_configuration_inventory_sources_enforce_defaults else omit), true) }}" notification_templates_success: "{{ (__controller_source_item.related.notification_templates_success | map(attribute='name') | list if __controller_source_item.related.notification_templates_success is defined) | default(__controller_source_item.notification_templates_success) | default(([] if controller_configuration_inventory_sources_enforce_defaults else omit), true) }}" notification_templates_error: "{{ (__controller_source_item.related.notification_templates_error | map(attribute='name') | list if __controller_source_item.related.notification_templates_error is defined) | default(__controller_source_item.notification_templates_error) | default(([] if controller_configuration_inventory_sources_enforce_defaults else omit), true) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ inventory_sources if inventory_sources is defined else controller_inventory_sources }}" loop_control: loop_var: __controller_source_item @@ -48,8 +49,8 @@ changed_when: "(__inventory_source_job_async.changed if ansible_check_mode else false)" when: (__controller_source_item.source | default(('scm' if controller_configuration_inventory_sources_enforce_defaults else omit), true)) != "constructed" vars: - __operation: "{{ operation_translate[__controller_source_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_source_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -70,6 +71,6 @@ when: not ansible_check_mode and __inventory_source_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_inventory_sources_secure_logging }}" vars: - __operation: "{{ operation_translate[__inventory_source_job_async_results_item.__controller_source_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__inventory_source_job_async_results_item.__controller_source_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_inventory_sources/tests/test.yml b/roles/controller_inventory_sources/tests/test.yml index c4ce74ec1..b71721ddb 100644 --- a/roles/controller_inventory_sources/tests/test.yml +++ b/roles/controller_inventory_sources/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_job_launch/README.md b/roles/controller_job_launch/README.md index ba466f919..0d6b2199c 100644 --- a/roles/controller_job_launch/README.md +++ b/roles/controller_job_launch/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_launch_jobs`|`see below`|yes|Data structure describing the jobs to launch Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the job launch task does not include sensitive information. -controller_configuration_job_launch_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_job_launch_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_job_launch_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -86,12 +86,12 @@ controller_launch_jobs: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_job_launch/defaults/main.yml b/roles/controller_job_launch/defaults/main.yml index eecd1773e..822c2d9f8 100644 --- a/roles/controller_job_launch/defaults/main.yml +++ b/roles/controller_job_launch/defaults/main.yml @@ -1,3 +1,3 @@ --- -controller_configuration_job_launch_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_job_launch_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" ... diff --git a/roles/controller_job_launch/meta/argument_specs.yml b/roles/controller_job_launch/meta/argument_specs.yml index 2a32a6c82..182c528a5 100644 --- a/roles/controller_job_launch/meta/argument_specs.yml +++ b/roles/controller_job_launch/meta/argument_specs.yml @@ -103,45 +103,45 @@ argument_specs: # No_log variables controller_configuration_groups_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_job_launch/tasks/main.yml b/roles/controller_job_launch/tasks/main.yml index 39ac2a0ae..d8e48afdf 100644 --- a/roles/controller_job_launch/tasks/main.yml +++ b/roles/controller_job_launch/tasks/main.yml @@ -26,12 +26,13 @@ timeout: "{{ __job_launch_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_launch_jobs }}" loop_control: loop_var: "__job_launch_item" diff --git a/roles/controller_job_launch/tests/test.yml b/roles/controller_job_launch/tests/test.yml index 7b8a951d8..69cf2cee4 100644 --- a/roles/controller_job_launch/tests/test.yml +++ b/roles/controller_job_launch/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_job_templates/README.md b/roles/controller_job_templates/README.md index e83b6a857..17db7ee50 100644 --- a/roles/controller_job_templates/README.md +++ b/roles/controller_job_templates/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_templates`|`see below`|yes|Data structure describing your job template or job templates Described below. Alias: job_templates || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add job_template task does not include sensitive information. -controller_configuration_job_templates_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_job_templates_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_job_templates_secure_logging`|`False`|no|Whether or not to include the sensitive Job Template role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_job_templates_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_job_templates_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_job_templates_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_job_templates_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_job_templates_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -126,7 +126,7 @@ This also speeds up the overall role. |`webhook_service`|""|no|str|Service that webhook requests will be accepted from (github, gitlab)| |`webhook_credential`|""|no|str|Personal Access Token for posting back the status to the service API| |`scm_branch`|""|no|str|Branch to use in job run. Project default used if blank. Only allowed if project allow_override field is set to true.| -|`labels`|""|no|list|The labels applied to this job template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/controller_labels) role first, an error will occur if the label supplied to this role does not exist.| +|`labels`|""|no|list|The labels applied to this job template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/labels) role first, an error will occur if the label supplied to this role does not exist.| |`custom_virtualenv`|""|no|str|Local absolute file path containing a custom Python virtualenv to use.| |`notification_templates_started`|""|no|list|The notifications on started to use for this organization in a list.| |`notification_templates_success`|""|no|list|The notifications on success to use for this organization in a list.| @@ -284,12 +284,12 @@ controller_templates: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_job_templates/defaults/main.yml b/roles/controller_job_templates/defaults/main.yml index 0e7dfa09f..ce071feba 100644 --- a/roles/controller_job_templates/defaults/main.yml +++ b/roles/controller_job_templates/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict describing Controller job templates: controller_templates: [] -controller_configuration_job_templates_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_job_templates_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_job_templates_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_job_templates_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_job_templates_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_job_templates_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_job_templates_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_job_templates_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_job_templates/meta/argument_specs.yml b/roles/controller_job_templates/meta/argument_specs.yml index 839d5e4d5..69744c6f6 100644 --- a/roles/controller_job_templates/meta/argument_specs.yml +++ b/roles/controller_job_templates/meta/argument_specs.yml @@ -250,22 +250,22 @@ argument_specs: # Async variables controller_configuration_job_templates_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_job_templates_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -273,45 +273,45 @@ argument_specs: # No_log variables controller_configuration_job_templates_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_job_templates/tasks/main.yml b/roles/controller_job_templates/tasks/main.yml index 66742bfd0..7dc8ed990 100644 --- a/roles/controller_job_templates/tasks/main.yml +++ b/roles/controller_job_templates/tasks/main.yml @@ -52,18 +52,19 @@ webhook_credential: "{{ __controller_template_item.webhook_credential | default(omit, true) }}" scm_branch: "{{ __controller_template_item.scm_branch | default(('' if controller_configuration_job_templates_enforce_defaults else omit), true) }}" labels: "{{ (__controller_template_item.related.labels | map(attribute='name') | list if __controller_template_item.related.labels is defined) | default(__controller_template_item.labels) | default(([] if controller_configuration_job_templates_enforce_defaults else omit), true) }}" - state: "{{ __controller_template_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_template_item.state | default(controller_state | default('present')) }}" notification_templates_started: "{{ (__controller_template_item.related.notification_templates_started | map(attribute='name') | list if __controller_template_item.related.notification_templates_started is defined) | default(__controller_template_item.notification_templates_started) | default(([] if controller_configuration_job_templates_enforce_defaults else omit), true) }}" notification_templates_success: "{{ (__controller_template_item.related.notification_templates_success | map(attribute='name') | list if __controller_template_item.related.notification_templates_success is defined) | default(__controller_template_item.notification_templates_success) | default(([] if controller_configuration_job_templates_enforce_defaults else omit), true) }}" notification_templates_error: "{{ (__controller_template_item.related.notification_templates_error | map(attribute='name') | list if __controller_template_item.related.notification_templates_error is defined) | default(__controller_template_item.notification_templates_error) | default(([] if controller_configuration_job_templates_enforce_defaults else omit), true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ job_templates if job_templates is defined else controller_templates }}" loop_control: loop_var: __controller_template_item @@ -75,8 +76,8 @@ register: __job_templates_job_async changed_when: "(__job_templates_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_template_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_template_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -92,8 +93,8 @@ when: not ansible_check_mode and __job_templates_job_async_result_item.ansible_job_id is defined no_log: "{{ controller_configuration_job_templates_secure_logging }}" vars: - __operation: "{{ operation_translate[__job_templates_job_asycn_result_item.__controller_template_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__job_templates_job_asycn_result_item.__controller_template_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: Set Job Templates error artifact when: __templates_error_list is defined diff --git a/roles/controller_job_templates/tests/test.yml b/roles/controller_job_templates/tests/test.yml index 294f63364..ff7a743bb 100644 --- a/roles/controller_job_templates/tests/test.yml +++ b/roles/controller_job_templates/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_jobs_cancel/README.md b/roles/controller_jobs_cancel/README.md index 819557d9c..94de87751 100644 --- a/roles/controller_jobs_cancel/README.md +++ b/roles/controller_jobs_cancel/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_cancel_jobs`|`see below`|yes|Data structure describing jobs to cancel Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the task to cancel jobs does not include sensitive information. -controller_configuration_jobs_cancel_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_jobs_cancel_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_jobs_cancel_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -66,12 +66,12 @@ controller_cancel_jobs: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_jobs_cancel/defaults/main.yml b/roles/controller_jobs_cancel/defaults/main.yml index f79103701..0b11f28fc 100644 --- a/roles/controller_jobs_cancel/defaults/main.yml +++ b/roles/controller_jobs_cancel/defaults/main.yml @@ -1,3 +1,3 @@ --- -controller_configuration_jobs_cancel_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_jobs_cancel_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" ... diff --git a/roles/controller_jobs_cancel/meta/argument_specs.yml b/roles/controller_jobs_cancel/meta/argument_specs.yml index 51f0afcbc..6fa4c903b 100644 --- a/roles/controller_jobs_cancel/meta/argument_specs.yml +++ b/roles/controller_jobs_cancel/meta/argument_specs.yml @@ -20,45 +20,45 @@ argument_specs: # No_log variables controller_configuration_ad_hoc_command_cancel_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_jobs_cancel/tasks/main.yml b/roles/controller_jobs_cancel/tasks/main.yml index ca666b715..e41abb5a7 100644 --- a/roles/controller_jobs_cancel/tasks/main.yml +++ b/roles/controller_jobs_cancel/tasks/main.yml @@ -6,12 +6,13 @@ fail_if_not_running: "{{ __controller_jobs_cancel_item.fail_if_not_running | default(omit) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_cancel_jobs }}" loop_control: loop_var: "__controller_jobs_cancel_item" diff --git a/roles/controller_jobs_cancel/tests/test.yml b/roles/controller_jobs_cancel/tests/test.yml index 842a58ff1..1cbbbdea3 100644 --- a/roles/controller_jobs_cancel/tests/test.yml +++ b/roles/controller_jobs_cancel/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_labels/README.md b/roles/controller_labels/README.md index a18a12a73..5301bfd35 100644 --- a/roles/controller_labels/README.md +++ b/roles/controller_labels/README.md @@ -14,13 +14,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_labels`|`see below`|yes|Data structure describing your label or labels Described below.|| ### Secure Logging Variables @@ -28,12 +28,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add labels task does not include sensitive information. -controller_configuration_labels_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_labels_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_labels_secure_logging`|`False`|no|Whether or not to include the sensitive Label role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -44,13 +44,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_labels_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_labels_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_labels_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_labels_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_labels_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -104,12 +104,12 @@ controller_labels: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_labels/defaults/main.yml b/roles/controller_labels/defaults/main.yml index 9ce1ac505..b1be8a4c7 100644 --- a/roles/controller_labels/defaults/main.yml +++ b/roles/controller_labels/defaults/main.yml @@ -1,8 +1,8 @@ --- controller_labels: [] -controller_configuration_labels_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_labels_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_labels_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_labels_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_labels_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_labels_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_labels_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null ... diff --git a/roles/controller_labels/meta/argument_specs.yml b/roles/controller_labels/meta/argument_specs.yml index 7487cdd95..a057cf09c 100644 --- a/roles/controller_labels/meta/argument_specs.yml +++ b/roles/controller_labels/meta/argument_specs.yml @@ -28,22 +28,22 @@ argument_specs: # Async variables controller_configuration_labels_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_labels_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -51,45 +51,45 @@ argument_specs: # No_log variables controller_configuration_labels_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_labels/tasks/main.yml b/roles/controller_labels/tasks/main.yml index 561b0ee53..a77a97ab8 100644 --- a/roles/controller_labels/tasks/main.yml +++ b/roles/controller_labels/tasks/main.yml @@ -4,15 +4,16 @@ name: "{{ __controller_label_item.name | mandatory }}" new_name: "{{ __controller_label_item.new_name | default(omit, true) }}" organization: "{{ __controller_label_item.organization | mandatory }}" - state: "{{ __controller_label_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_label_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_labels }}" loop_control: loop_var: __controller_label_item @@ -24,8 +25,8 @@ register: __controller_label_job_async changed_when: "(__controller_label_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_label_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_label_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -46,6 +47,6 @@ when: not ansible_check_mode and __controller_label_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_labels_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_label_job_async_results_item.__controller_label_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_label_job_async_results_item.__controller_label_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_labels/tests/test.yml b/roles/controller_labels/tests/test.yml index 51a051083..776d50623 100644 --- a/roles/controller_labels/tests/test.yml +++ b/roles/controller_labels/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_license/README.md b/roles/controller_license/README.md index 3959ef50f..ea1b56bea 100644 --- a/roles/controller_license/README.md +++ b/roles/controller_license/README.md @@ -18,13 +18,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_license`|`see below`|yes|Data structure describing your license for controller, described below.|| |`redhat_subscription_username`|""|no|Red Hat or Red Hat Satellite username to get available subscriptions. Used only for Subscription lookup implementation.|| |`redhat_subscription_password`|""|no|Red Hat or Red Hat Satellite password to get available subscriptions. Used only for Subscription lookup implementation.|| @@ -34,12 +34,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add license task does not include sensitive information. -controller_configuration_license_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_license_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_license_secure_logging`|`False`|no|Whether or not to include the sensitive license role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -107,12 +107,12 @@ controller_license: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] @@ -131,7 +131,7 @@ controller_license: vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme redhat_subscription_username: changeme redhat_subscription_password: changeme diff --git a/roles/controller_license/defaults/main.yml b/roles/controller_license/defaults/main.yml index 2b9e94002..fbb93ef3b 100644 --- a/roles/controller_license/defaults/main.yml +++ b/roles/controller_license/defaults/main.yml @@ -1,5 +1,5 @@ --- -controller_configuration_license_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_license_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" _redhat_cop_license_filters: product_name: Red Hat Ansible Automation Platform support_level: Self-Support diff --git a/roles/controller_license/meta/argument_specs.yml b/roles/controller_license/meta/argument_specs.yml index 26adf4a2c..3040dd82f 100644 --- a/roles/controller_license/meta/argument_specs.yml +++ b/roles/controller_license/meta/argument_specs.yml @@ -65,45 +65,45 @@ argument_specs: # No_log variables controller_configuration_labels_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_license/tasks/manifest.yml b/roles/controller_license/tasks/manifest.yml index 81199f421..0f80a40d5 100644 --- a/roles/controller_license/tasks/manifest.yml +++ b/roles/controller_license/tasks/manifest.yml @@ -46,12 +46,13 @@ state: "{{ controller_license.state | default(omit) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" no_log: "{{ controller_configuration_license_secure_logging }}" when: controller_license is defined ... diff --git a/roles/controller_license/tasks/subscription.yml b/roles/controller_license/tasks/subscription.yml index 79c2e7e2f..e1d8ab1ac 100644 --- a/roles/controller_license/tasks/subscription.yml +++ b/roles/controller_license/tasks/subscription.yml @@ -7,12 +7,13 @@ password: "{{ redhat_subscription_password }}" filters: "{{ controller_license.filters | default(_redhat_cop_license_filters) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" register: subscription when: - "'use_lookup' in controller_license" @@ -25,12 +26,13 @@ state: "{{ controller_license.state | default(omit) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" no_log: "{{ controller_configuration_license_secure_logging }}" when: controller_license is defined ... diff --git a/roles/controller_license/tests/test.yml b/roles/controller_license/tests/test.yml index 76f945a75..5d94b1388 100644 --- a/roles/controller_license/tests/test.yml +++ b/roles/controller_license/tests/test.yml @@ -6,7 +6,7 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme redhat_subscription_username: changeme redhat_subscription_password: changeme @@ -15,7 +15,7 @@ - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./config extensions: ["yml"] diff --git a/roles/controller_notification_templates/README.md b/roles/controller_notification_templates/README.md index 161b586e5..a6b79deb0 100644 --- a/roles/controller_notification_templates/README.md +++ b/roles/controller_notification_templates/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_notifications`|`see below`|yes|Data structure describing your notification entries described below. Alias: notification_templates || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add notification task does not include sensitive information. -`controller_configuration_notification_secure_logging` defaults to the value of `platform_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +`controller_configuration_notification_secure_logging` defaults to the value of `controller_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_notification_secure_logging`|`False`|no|Whether or not to include the sensitive notification role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_notification_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_notification_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_notification_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_notification_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_notifications_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -180,12 +180,12 @@ controller_notifications: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_notification_templates/defaults/main.yml b/roles/controller_notification_templates/defaults/main.yml index e4f930b31..85add535b 100644 --- a/roles/controller_notification_templates/defaults/main.yml +++ b/roles/controller_notification_templates/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict to describe Controller notification templates controller_notifications: [] -controller_configuration_notifications_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_notifications_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_notifications_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_notifications_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_notifications_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_notifications_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_notifications_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_notifications_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_notification_templates/meta/argument_specs.yml b/roles/controller_notification_templates/meta/argument_specs.yml index ce7f74756..4a2408034 100644 --- a/roles/controller_notification_templates/meta/argument_specs.yml +++ b/roles/controller_notification_templates/meta/argument_specs.yml @@ -49,67 +49,67 @@ argument_specs: # Async variables controller_configuration_notification_templates_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_notification_templates_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables controller_configuration_notification_templates_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_notification_templates/tasks/main.yml b/roles/controller_notification_templates/tasks/main.yml index 66b47a729..bccad9920 100644 --- a/roles/controller_notification_templates/tasks/main.yml +++ b/roles/controller_notification_templates/tasks/main.yml @@ -9,15 +9,16 @@ notification_type: "{{ __controller_notification_item.notification_type | default(omit, true) | mandatory }}" notification_configuration: "{{ __controller_notification_item.notification_configuration | default(({} if controller_configuration_notifications_enforce_defaults else omit), true) }}" messages: "{{ __controller_notification_item.messages | default(({} if controller_configuration_notifications_enforce_defaults else omit), true) | regex_replace('{ {', '{_~~remove~~_{') | regex_replace('_~~remove~~_', '') }}" - state: "{{ __controller_notification_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_notification_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ notification_templates if notification_templates is defined else controller_notifications }}" loop_control: loop_var: __controller_notification_item @@ -29,8 +30,8 @@ register: __controller_notification_job_async changed_when: "(__controller_notification_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_notification_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_notification_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -51,6 +52,6 @@ when: not ansible_check_mode and __controller_notification_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_notifications_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_notification_job_async_results_item.__controller_notification_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_notification_job_async_results_item.__controller_notification_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_notification_templates/tests/test.yml b/roles/controller_notification_templates/tests/test.yml index 2f2a0772f..2e1df99b9 100644 --- a/roles/controller_notification_templates/tests/test.yml +++ b/roles/controller_notification_templates/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_organizations/README.md b/roles/controller_organizations/README.md index 8f62f3d67..1b2ea7090 100644 --- a/roles/controller_organizations/README.md +++ b/roles/controller_organizations/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`true`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_organizations`|`see below`|yes|Data structure describing your organization or organizations Described below. Alias: organizations || |`assign_galaxy_credentials_to_org`|`true`|no|Boolean to indicate whether credentials should be assigned or not. It should be noted that credentials must exist before adding it. The dispatch role will set this to `false`, before re-running the role with it set to `true`. || |`assign_default_ee_to_org`|`true`|no|Boolean to indicate whether default execution environment should be assigned or not. It should be noted that execution environment must exist before adding it. The dispatch role will set this to `false`, before re-running the role with it set to `true`. || @@ -50,12 +50,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add organization task does not include sensitive information. -controller_configuration_organizations_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_organizations_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_organizations_secure_logging`|`False`|no|Whether or not to include the sensitive Organization role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -66,13 +66,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_organizations_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_organizations_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_organizations_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_organizations_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_organizations_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Organization Data Structure @@ -173,12 +173,12 @@ controller_organizations: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_organizations/defaults/main.yml b/roles/controller_organizations/defaults/main.yml index d40a2a272..5538411e8 100644 --- a/roles/controller_organizations/defaults/main.yml +++ b/roles/controller_organizations/defaults/main.yml @@ -1,10 +1,10 @@ --- controller_organizations: [] -controller_configuration_organizations_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_organizations_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_organizations_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_organizations_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_organizations_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_organizations_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_organizations_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_organizations_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" assign_galaxy_credentials_to_org: true assign_default_ee_to_org: true diff --git a/roles/controller_organizations/meta/argument_specs.yml b/roles/controller_organizations/meta/argument_specs.yml index e98217f02..a68168caa 100644 --- a/roles/controller_organizations/meta/argument_specs.yml +++ b/roles/controller_organizations/meta/argument_specs.yml @@ -82,22 +82,22 @@ argument_specs: # Async variables controller_configuration_organizations_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_organizations_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -105,45 +105,45 @@ argument_specs: # No_log variables controller_configuration_organizations_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_organizations/tasks/main.yml b/roles/controller_organizations/tasks/main.yml index b2a422fd0..650af22cb 100644 --- a/roles/controller_organizations/tasks/main.yml +++ b/roles/controller_organizations/tasks/main.yml @@ -13,15 +13,16 @@ notification_templates_started: "{{ (__controller_organizations_item.related.notification_templates_started | map(attribute='name') | list if __controller_organizations_item.related.notification_templates_started is defined) | default(__controller_organizations_item.notification_templates_started) | default(([] if controller_configuration_organizations_enforce_defaults else omit), true) if (assign_notification_templates_to_org is defined and assign_notification_templates_to_org) else omit }}" notification_templates_success: "{{ (__controller_organizations_item.related.notification_templates_success | map(attribute='name') | list if __controller_organizations_item.related.notification_templates_success is defined) | default(__controller_organizations_item.notification_templates_success) | default(([] if controller_configuration_organizations_enforce_defaults else omit), true) if (assign_notification_templates_to_org is defined and assign_notification_templates_to_org) else omit }}" notification_templates_error: "{{ (__controller_organizations_item.related.notification_templates_error | map(attribute='name') | list if __controller_organizations_item.related.notification_templates_error is defined) | default(__controller_organizations_item.notification_templates_error) | default(([] if controller_configuration_organizations_enforce_defaults else omit), true) if (assign_notification_templates_to_org is defined and assign_notification_templates_to_org) else omit }}" - state: "{{ __controller_organizations_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_organizations_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ organizations if organizations is defined else controller_organizations }}" loop_control: loop_var: __controller_organizations_item @@ -33,8 +34,8 @@ register: __organizations_job_async changed_when: "(__organizations_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_organizations_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_organizations_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -55,6 +56,6 @@ when: not ansible_check_mode and __organizations_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_organizations_secure_logging }}" vars: - __operation: "{{ operation_translate[__organizations_job_async_results_item.__controller_organizations_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__organizations_job_async_results_item.__controller_organizations_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_organizations/tests/test.yml b/roles/controller_organizations/tests/test.yml index 26022cd16..9bdc016f9 100644 --- a/roles/controller_organizations/tests/test.yml +++ b/roles/controller_organizations/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_project_update/README.md b/roles/controller_project_update/README.md index 77ec0620b..73d60c83d 100644 --- a/roles/controller_project_update/README.md +++ b/roles/controller_project_update/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_projects`|`see below`|yes|Data structure describing the project to update Described below. Alias: projects || ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the project update task does not include sensitive information. -controller_configuration_project_update_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_project_update_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_project_update_secure_logging`|`False`|no|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -46,13 +46,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|60|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_async_retries`|60|no|This variable sets the number of retries to attempt for the role globally.| |`controller_configuration_project_update_async_retries`|60|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|10|no|This sets the delay between retries for the role globally.| +|`controller_configuration_async_delay`|10|no|This sets the delay between retries for the role globally.| |`controller_configuration_project_update_async_delay`|10|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_project_update_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -106,12 +106,12 @@ controller_projects: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_project_update/defaults/main.yml b/roles/controller_project_update/defaults/main.yml index 25ef31705..f6142a67b 100644 --- a/roles/controller_project_update/defaults/main.yml +++ b/roles/controller_project_update/defaults/main.yml @@ -1,7 +1,7 @@ --- -controller_configuration_project_update_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_project_update_async_retries: "{{ platform_configuration_async_retries | default(60) }}" -controller_configuration_project_update_async_delay: "{{ platform_configuration_async_delay | default(10) }}" +controller_configuration_project_update_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_project_update_async_retries: "{{ controller_configuration_async_retries | default(60) }}" +controller_configuration_project_update_async_delay: "{{ controller_configuration_async_delay | default(10) }}" controller_configuration_project_update_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null ... diff --git a/roles/controller_project_update/meta/argument_specs.yml b/roles/controller_project_update/meta/argument_specs.yml index 6ff52ed68..1c3ffa3c4 100644 --- a/roles/controller_project_update/meta/argument_specs.yml +++ b/roles/controller_project_update/meta/argument_specs.yml @@ -124,67 +124,67 @@ argument_specs: # Async variables controller_configuration_project_update_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_project_update_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables controller_configuration_groups_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_project_update/tasks/main.yml b/roles/controller_project_update/tasks/main.yml index 7cc37efcf..69bdfcf5e 100644 --- a/roles/controller_project_update/tasks/main.yml +++ b/roles/controller_project_update/tasks/main.yml @@ -9,12 +9,13 @@ timeout: "{{ __project_update_update_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ projects if projects is defined else controller_projects }}" loop_control: loop_var: "__project_update_update_item" @@ -30,7 +31,7 @@ register: __project_update_job_async changed_when: "(__project_update_job_async.changed if ansible_check_mode else false)" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -50,5 +51,5 @@ when: not ansible_check_mode and __project_update_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_project_update_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_project_update/tests/test.yml b/roles/controller_project_update/tests/test.yml index 6cc05ba8f..8c771034b 100644 --- a/roles/controller_project_update/tests/test.yml +++ b/roles/controller_project_update/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_projects/README.md b/roles/controller_projects/README.md index 0a1f020b5..8a166e551 100644 --- a/roles/controller_projects/README.md +++ b/roles/controller_projects/README.md @@ -19,7 +19,7 @@ Currently: |`controller_state`|"present"|no|str|The state all objects will take unless overridden by object default|'absent'| |`controller_hostname`|""|yes|str|URL to the Ansible Controller Server.|127.0.0.1| |`controller_validate_certs`|`True`|no|str|Whether or not to validate the Ansible Controller Server's SSL certificate.|| -|`platform_username`|""|no|str|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_username`|""|no|str|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| |`controller_password`|""|no|str|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| |`controller_oauthtoken`|""|no|str|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| |`controller_request_timeout`|`10`|no|int|Specify the timeout in seconds Ansible should use in requests to the controller host.|| @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add projects task does not include sensitive information. -controller_configuration_projects_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_projects_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Type|Description| |:---:|:---:|:---:|:---:|:---| |`controller_configuration_projects_secure_logging`|`False`|no|str|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|str|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|str|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Type|Description| |:---:|:---:|:---:|:---:|:---| -|`platform_configuration_async_retries`|30|no|str|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_projects_async_retries`|`{{ platform_configuration_async_retries }}`|no|str|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|str|This sets the delay between retries for the role globally.| -|`controller_configuration_projects_async_delay`|`platform_configuration_async_delay`|no|str|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|str|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_projects_async_retries`|`{{ controller_configuration_async_retries }}`|no|str|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|str|This sets the delay between retries for the role globally.| +|`controller_configuration_projects_async_delay`|`controller_configuration_async_delay`|no|str|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|int|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_projects_loop_delay`|`controller_configuration_loop_delay`|no|int|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|bool|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|bool|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -157,12 +157,12 @@ controller_projects: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_projects/defaults/main.yml b/roles/controller_projects/defaults/main.yml index 28dd22dd8..233e9d2b1 100644 --- a/roles/controller_projects/defaults/main.yml +++ b/roles/controller_projects/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict describing Controller projects controller_projects: [] -controller_configuration_projects_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_projects_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_projects_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_projects_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_projects_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_projects_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_projects_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_projects_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_projects/meta/argument_specs.yml b/roles/controller_projects/meta/argument_specs.yml index 35f6bbb99..8951ac329 100644 --- a/roles/controller_projects/meta/argument_specs.yml +++ b/roles/controller_projects/meta/argument_specs.yml @@ -132,22 +132,22 @@ argument_specs: # Async variables controller_configuration_projects_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_projects_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -155,45 +155,45 @@ argument_specs: # No_log variables controller_configuration_projects_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_projects/tasks/main.yml b/roles/controller_projects/tasks/main.yml index 192dd1c62..66de7c405 100644 --- a/roles/controller_projects/tasks/main.yml +++ b/roles/controller_projects/tasks/main.yml @@ -22,7 +22,7 @@ timeout: "{{ __controller_project_item.job_timeout | default(__controller_project_item.timeout | default(0, true) if __controller_project_item.timeout is defined or __controller_project_item.job_timeout is defined or controller_configuration_projects_enforce_defaults else omit) }}" custom_virtualenv: "{{ __controller_project_item.custom_virtualenv | default(('' if controller_configuration_projects_enforce_defaults else omit), true) }}" organization: "{{ __controller_project_item.organization.name | default(__controller_project_item.organization | default(('' if controller_configuration_projects_enforce_defaults else omit))) }}" - state: "{{ __controller_project_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_project_item.state | default(controller_state | default('present')) }}" wait: "{{ __controller_project_item.wait | default((true if controller_configuration_projects_enforce_defaults else omit)) }}" update_project: "{{ __controller_project_item.update_project | default((false if controller_configuration_projects_enforce_defaults else omit)) }}" interval: "{{ __controller_project_item.interval | default(controller_configuration_projects_async_delay) }}" @@ -31,12 +31,13 @@ notification_templates_error: "{{ (__controller_project_item.related.notification_templates_error | map(attribute='name') | list if __controller_project_item.related.notification_templates_error is defined) | default(__controller_project_item.notification_templates_error) | default(([] if controller_configuration_projects_enforce_defaults else omit), true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ projects if projects is defined else controller_projects }}" loop_control: loop_var: __controller_project_item @@ -48,8 +49,8 @@ register: __projects_job_async changed_when: "(__projects_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_project_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_project_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -70,6 +71,6 @@ when: not ansible_check_mode and __projects_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_projects_secure_logging }}" vars: - __operation: "{{ operation_translate[__projects_job_async_results_item.__controller_project_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__projects_job_async_results_item.__controller_project_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_projects/tests/test.yml b/roles/controller_projects/tests/test.yml index fcd1beb8d..8c877ea54 100644 --- a/roles/controller_projects/tests/test.yml +++ b/roles/controller_projects/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_roles/README.md b/roles/controller_roles/README.md index 8feabf7ea..204d1cfc3 100644 --- a/roles/controller_roles/README.md +++ b/roles/controller_roles/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_roles`|`see below`|yes|Data structure describing your RBAC entries described below.|| ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add rbac task does not include sensitive information. -`controller_configuration_role_secure_logging` defaults to the value of `platform_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +`controller_configuration_role_secure_logging` defaults to the value of `controller_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_role_secure_logging`|`False`|no|Whether or not to include the sensitive rbac role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_role_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_role_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_role_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_role_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_role_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -174,12 +174,12 @@ controller_roles: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_roles/defaults/main.yml b/roles/controller_roles/defaults/main.yml index daa949d05..ccd2a6879 100644 --- a/roles/controller_roles/defaults/main.yml +++ b/roles/controller_roles/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict describing a Controller access control rule controller_roles: [] -controller_configuration_role_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_role_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_role_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_role_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_role_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_role_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_role_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_role_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_roles/meta/argument_specs.yml b/roles/controller_roles/meta/argument_specs.yml index e408ed7d0..5471b7491 100644 --- a/roles/controller_roles/meta/argument_specs.yml +++ b/roles/controller_roles/meta/argument_specs.yml @@ -95,22 +95,22 @@ argument_specs: # Async variables controller_configuration_role_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_role_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -118,45 +118,45 @@ argument_specs: # No_log variables controller_configuration_role_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_roles/tasks/main.yml b/roles/controller_roles/tasks/main.yml index f49e00d7d..d47d738b0 100644 --- a/roles/controller_roles/tasks/main.yml +++ b/roles/controller_roles/tasks/main.yml @@ -22,15 +22,16 @@ project: "{{ __controller_role_item.0.project | default(__controller_role_item.project) | default(omit, true) }}" projects: "{{ __controller_role_item.0.projects | default(__controller_role_item.projects) | default(([] if controller_configuration_role_enforce_defaults else omit), true) }}" instance_groups: "{{ __controller_role_item.0.instance_groups | default(__controller_role_item.instance_groups) | default(([] if controller_configuration_role_enforce_defaults else omit), true) }}" - state: "{{ __controller_role_item.0.state | default(__controller_role_item.state) | default(platform_state | default('present')) }}" + state: "{{ __controller_role_item.0.state | default(__controller_role_item.state) | default(controller_state | default('present')) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ (controller_roles | subelements(['roles'], skip_missing=true)) + controller_roles | selectattr('roles', 'undefined') }}" loop_control: loop_var: __controller_role_item @@ -42,8 +43,8 @@ register: __controller_role_job_async changed_when: "(__controller_role_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_role_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_role_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -64,6 +65,6 @@ when: not ansible_check_mode and __controller_role_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_role_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_role_job_async_results_item.__controller_role_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_role_job_async_results_item.__controller_role_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_roles/tests/test.yml b/roles/controller_roles/tests/test.yml index 09758755b..b36acf8a1 100644 --- a/roles/controller_roles/tests/test.yml +++ b/roles/controller_roles/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_schedules/README.md b/roles/controller_schedules/README.md index 905a9fe59..7e17af87e 100644 --- a/roles/controller_schedules/README.md +++ b/roles/controller_schedules/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_schedules`|`see below`|yes|Data structure describing your schedule or schedules Described below. Alias: schedules || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add schedules task does not include sensitive information. -controller_configuration_schedules_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_schedules_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_schedules_secure_logging`|`False`|no|Whether or not to include the sensitive Schedules role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_schedules_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_schedules_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_schedules_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_schedules_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_schedules_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -149,12 +149,12 @@ controller_schedules: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_schedules/defaults/main.yml b/roles/controller_schedules/defaults/main.yml index 27720e95e..b95ffc31d 100644 --- a/roles/controller_schedules/defaults/main.yml +++ b/roles/controller_schedules/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dict describing Controller schedules: controller_schedules: [] -controller_configuration_schedules_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_schedules_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_schedules_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_schedules_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_schedules_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_schedules_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_schedules_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_schedules_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_schedules/meta/argument_specs.yml b/roles/controller_schedules/meta/argument_specs.yml index 522ae81a0..4b7979cf4 100644 --- a/roles/controller_schedules/meta/argument_specs.yml +++ b/roles/controller_schedules/meta/argument_specs.yml @@ -117,22 +117,22 @@ argument_specs: # Async variables controller_configuration_schedules_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_schedules_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -140,45 +140,45 @@ argument_specs: # No_log variables controller_configuration_schedules_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_schedules/tasks/main.yml b/roles/controller_schedules/tasks/main.yml index 1b4d386dd..f471277d6 100644 --- a/roles/controller_schedules/tasks/main.yml +++ b/roles/controller_schedules/tasks/main.yml @@ -24,15 +24,16 @@ organization: "{{ __controller_schedule_item.organization | default(('' if controller_configuration_schedules_enforce_defaults else omit), true) }}" unified_job_template: "{{ __controller_schedule_item.unified_job_template | default(omit, true) }}" enabled: "{{ __controller_schedule_item.enabled | default((true if controller_configuration_schedules_enforce_defaults else omit)) }}" - state: "{{ __controller_schedule_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_schedule_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ schedules if schedules is defined else controller_schedules }}" loop_control: loop_var: "__controller_schedule_item" @@ -44,8 +45,8 @@ register: __controller_schedule_job_async changed_when: "(__controller_schedule_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_schedule_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_schedule_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -66,6 +67,6 @@ when: not ansible_check_mode and __controller_schedule_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_schedules_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_schedule_job_async_results_item.__controller_schedule_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_schedule_job_async_results_item.__controller_schedule_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_schedules/tests/test.yml b/roles/controller_schedules/tests/test.yml index c9dc0387a..f62efd482 100644 --- a/roles/controller_schedules/tests/test.yml +++ b/roles/controller_schedules/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_settings/README.md b/roles/controller_settings/README.md index db188d195..cf38dde26 100644 --- a/roles/controller_settings/README.md +++ b/roles/controller_settings/README.md @@ -14,13 +14,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_settings`|`see below`|yes|Data structure describing your settings described below.|| ### Secure Logging Variables @@ -28,12 +28,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add settings task does not include sensitive information. -controller_configuration_settings_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_settings_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_settings_secure_logging`|`False`|no|Whether or not to include the sensitive Settings role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -44,13 +44,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_settings_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_settings_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_settings_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_settings_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_settings_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -131,12 +131,12 @@ controller_settings: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_settings/defaults/main.yml b/roles/controller_settings/defaults/main.yml index 329946685..a2a5aa90c 100644 --- a/roles/controller_settings/defaults/main.yml +++ b/roles/controller_settings/defaults/main.yml @@ -1,9 +1,9 @@ --- # list of dicts (or a single dict) describing the Controller settings controller_settings: [] -controller_configuration_settings_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_settings_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_settings_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_settings_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_settings_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_settings_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_settings_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null ... diff --git a/roles/controller_settings/meta/argument_specs.yml b/roles/controller_settings/meta/argument_specs.yml index 94972b245..968024db1 100644 --- a/roles/controller_settings/meta/argument_specs.yml +++ b/roles/controller_settings/meta/argument_specs.yml @@ -23,22 +23,22 @@ argument_specs: # Async variables controller_configuration_settings_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_settings_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -46,45 +46,45 @@ argument_specs: # No_log variables controller_configuration_settings_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_settings/tasks/main.yml b/roles/controller_settings/tasks/main.yml index cd756a81c..5b4a46b4c 100644 --- a/roles/controller_settings/tasks/main.yml +++ b/roles/controller_settings/tasks/main.yml @@ -7,12 +7,13 @@ value: "{{ __controller_setting_item.value | default(omit) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" # controller_settings must be either a dictionary/mapping or a list of dictionaries loop: "{{ controller_settings is mapping | ternary([controller_settings], controller_settings) }}" loop_control: @@ -25,7 +26,7 @@ register: __controller_setting_job_async changed_when: "(__controller_setting_job_async.changed if ansible_check_mode else false)" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -45,5 +46,5 @@ when: not ansible_check_mode and __controller_setting_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_settings_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_settings/tests/test.yml b/roles/controller_settings/tests/test.yml index 8f38363e1..4b44866ed 100644 --- a/roles/controller_settings/tests/test.yml +++ b/roles/controller_settings/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_teams/README.md b/roles/controller_teams/README.md index a5f260a3c..182383edb 100644 --- a/roles/controller_teams/README.md +++ b/roles/controller_teams/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_teams`|`see below`|yes|Data structure describing your Teams described below. Alias: teams || ### Enforcing defaults @@ -34,11 +34,11 @@ This should be enabled to enforce configuration and prevent configuration drift. Enabling this will enforce configurtion without specifying every option in the configuration files. -'controller_configuration_platform_teams_enforce_defaults' defaults to the value of 'controller_configuration_enforce_defaults' if it is not explicitly called. This allows for enforced defaults to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +'controller_configuration_teams_enforce_defaults' defaults to the value of 'controller_configuration_enforce_defaults' if it is not explicitly called. This allows for enforced defaults to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`controller_configuration_platform_teams_enforce_defaults`|`False`|no|Whether or not to enforce default option values on only the applications role| +|`controller_configuration_teams_enforce_defaults`|`False`|no|Whether or not to enforce default option values on only the applications role| |`controller_configuration_enforce_defaults`|`False`|no|This variable enables enforced default values as well, but is shared across multiple roles, see above.| ### Secure Logging Variables @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add teams task does not include sensitive information. -`controller_configuration_platform_teams_secure_logging` defaults to the value of `platform_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +`controller_configuration_teams_secure_logging` defaults to the value of `controller_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`controller_configuration_platform_teams_secure_logging`|`False`|no|Whether or not to include the sensitive teams role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_teams_secure_logging`|`False`|no|Whether or not to include the sensitive teams role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_platform_teams_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_platform_teams_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_teams_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_teams_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_teams_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ### Data structure `controller_teams:` should include following vars @@ -89,12 +89,12 @@ This also speeds up the overall role. - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_teams/defaults/main.yml b/roles/controller_teams/defaults/main.yml index 9707eb70f..f3bea7bf0 100644 --- a/roles/controller_teams/defaults/main.yml +++ b/roles/controller_teams/defaults/main.yml @@ -1,10 +1,10 @@ --- # These are the default variables specific to the teams role controller_teams: [] -controller_configuration_platform_teams_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_platform_teams_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_platform_teams_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_teams_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_teams_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_teams_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_teams_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null -controller_configuration_platform_teams_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" +controller_configuration_async_dir: null +controller_configuration_teams_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_teams/meta/argument_specs.yml b/roles/controller_teams/meta/argument_specs.yml index 842d45b72..7bcf6818e 100644 --- a/roles/controller_teams/meta/argument_specs.yml +++ b/roles/controller_teams/meta/argument_specs.yml @@ -31,69 +31,69 @@ argument_specs: # description: Desired state of the resource. # Async variables - controller_configuration_platform_teams_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + controller_configuration_teams_async_retries: + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. - controller_configuration_platform_teams_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + controller_configuration_teams_async_delay: + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables - controller_configuration_platform_teams_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + controller_configuration_teams_secure_logging: + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_teams/tasks/main.yml b/roles/controller_teams/tasks/main.yml index d685947c2..9c6546925 100644 --- a/roles/controller_teams/tasks/main.yml +++ b/roles/controller_teams/tasks/main.yml @@ -3,30 +3,31 @@ team: name: "{{ __controller_team_item.name | mandatory }}" new_name: "{{ __controller_team_item.new_name | default(omit, true) }}" - description: "{{ __controller_team_item.description | default(('' if controller_configuration_platform_teams_enforce_defaults else omit), true) }}" + description: "{{ __controller_team_item.description | default(('' if controller_configuration_teams_enforce_defaults else omit), true) }}" organization: "{{ __controller_team_item.organization.name | default(__controller_team_item.organization) | mandatory }}" - state: "{{ __controller_team_item.state | default(platform_state | default('present')) }}" + state: "{{ __controller_team_item.state | default(controller_state | default('present')) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ teams if teams is defined else controller_teams }}" loop_control: loop_var: __controller_team_item label: "{{ __operation.verb }} Ansible Controller Team {{ __controller_team_item.name }}" pause: "{{ controller_configuration_teams_loop_delay }}" - no_log: "{{ controller_configuration_platform_teams_secure_logging }}" + no_log: "{{ controller_configuration_teams_secure_logging }}" async: "{{ ansible_check_mode | ternary(0, 1000) }}" poll: 0 register: __controller_team_job_async changed_when: "(__controller_team_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_team_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_team_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -38,15 +39,15 @@ jid: "{{ __controller_team_job_async_results_item.ansible_job_id }}" register: __controller_team_job_async_result until: __controller_team_job_async_result.finished - retries: "{{ controller_configuration_platform_teams_async_retries }}" - delay: "{{ controller_configuration_platform_teams_async_delay }}" + retries: "{{ controller_configuration_teams_async_retries }}" + delay: "{{ controller_configuration_teams_async_delay }}" loop: "{{ __controller_team_job_async.results }}" loop_control: loop_var: __controller_team_job_async_results_item label: "{{ __operation.verb }} Teams | Wait for finish the Teams {{ __operation.action }}" when: not ansible_check_mode and __controller_team_job_async_results_item.ansible_job_id is defined - no_log: "{{ controller_configuration_platform_teams_secure_logging }}" + no_log: "{{ controller_configuration_teams_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_team_job_asycn_results_item.__controller_team_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_team_job_asycn_results_item.__controller_team_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_teams/tests/test.yml b/roles/controller_teams/tests/test.yml index 049c55dc2..c06f49f27 100644 --- a/roles/controller_teams/tests/test.yml +++ b/roles/controller_teams/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_users/README.md b/roles/controller_users/README.md index 36e8c07f2..f94492d11 100644 --- a/roles/controller_users/README.md +++ b/roles/controller_users/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_user_accounts`|`see below`|yes|Data structure describing your user entries described below. Alias: users || |`controller_user_default_password`|""|no|Global variable to set the password for all users.|| @@ -47,12 +47,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add user task does not include sensitive information. -`controller_configuration_user_secure_logging` defaults to the value of `platform_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. +`controller_configuration_user_secure_logging` defaults to the value of `controller_configuration_secure_logging` if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_user_secure_logging`|`False`|no|Whether or not to include the sensitive user role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -63,13 +63,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_users_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_users_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_users_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_users_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_users_loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -125,12 +125,12 @@ controller_user_accounts: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_users/defaults/main.yml b/roles/controller_users/defaults/main.yml index 3ad782a9b..d06c411e7 100644 --- a/roles/controller_users/defaults/main.yml +++ b/roles/controller_users/defaults/main.yml @@ -5,10 +5,10 @@ controller_user_accounts: [] # set this variable to something false and there won't be a default password controller_user_default_password: "change_me" -controller_configuration_users_secure_logging: "{{ platform_configuration_secure_logging | default('true') }}" -controller_configuration_users_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_users_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +controller_configuration_users_secure_logging: "{{ controller_configuration_secure_logging | default('true') }}" +controller_configuration_users_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_users_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_users_loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_users_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_users/meta/argument_specs.yml b/roles/controller_users/meta/argument_specs.yml index a32f666ee..c539646d8 100644 --- a/roles/controller_users/meta/argument_specs.yml +++ b/roles/controller_users/meta/argument_specs.yml @@ -61,22 +61,22 @@ argument_specs: # Async variables controller_configuration_users_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_users_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -84,45 +84,45 @@ argument_specs: # No_log variables controller_configuration_users_secure_logging: - default: "{{ platform_configuration_secure_logging | default(true) }}" + default: "{{ controller_configuration_secure_logging | default(true) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_users/tasks/main.yml b/roles/controller_users/tasks/main.yml index 4719eae59..f214c453a 100644 --- a/roles/controller_users/tasks/main.yml +++ b/roles/controller_users/tasks/main.yml @@ -14,15 +14,16 @@ is_system_auditor: "{{ __controller_user_accounts_item.is_auditor | default(__controller_user_accounts_item.is_system_auditor | default((false if controller_configuration_users_enforce_defaults else omit))) }}" update_secrets: "{{ __controller_user_accounts_item.update_secrets | default((false if controller_configuration_users_enforce_defaults else omit)) }}" organization: "{{ __controller_user_accounts_item.organization | default(omit) }}" - state: "{{ __controller_user_accounts_item.state | default(platform_state | default(omit, true)) }}" + state: "{{ __controller_user_accounts_item.state | default(controller_state | default(omit, true)) }}" # Role Standard Options - controller_host: "{{ platform_hostname | default(omit, true) }}" - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" loop: "{{ users if users is defined else controller_user_accounts }}" loop_control: loop_var: __controller_user_accounts_item @@ -34,8 +35,8 @@ register: __controller_user_accounts_job_async changed_when: "(__controller_user_accounts_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__controller_user_accounts_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_user_accounts_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -56,6 +57,6 @@ when: not ansible_check_mode and __controller_user_accounts_job_async_results_item.ansible_job_id is defined no_log: "{{ controller_configuration_users_secure_logging }}" vars: - __operation: "{{ operation_translate[__controller_user_accounts_job_async_results_item.__controller_user_accounts_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__controller_user_accounts_job_async_results_item.__controller_user_accounts_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_users/tests/test.yml b/roles/controller_users/tests/test.yml index d58a2b6a5..cc3110b28 100644 --- a/roles/controller_users/tests/test.yml +++ b/roles/controller_users/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_workflow_job_templates/README.md b/roles/controller_workflow_job_templates/README.md index 87f04cc46..5e375b807 100644 --- a/roles/controller_workflow_job_templates/README.md +++ b/roles/controller_workflow_job_templates/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_workflows`|`see below`|yes|Data structure describing your workflow job templates described below. Alias: workflow_job_templates || ### Enforcing defaults @@ -46,12 +46,12 @@ Enabling this will enforce configurtion without specifying every option in the c The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add Workflow Job Templates task does not include sensitive information. -workflow_job_templates_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of genie roles with a single variable, or for the user to selectively use it. +workflow_job_templates_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of genie roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`workflow_job_templates_secure_logging`|`False`|no|Whether or not to include the sensitive Workflow Job Templates role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -62,13 +62,13 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| -|`controller_configuration_workflow_async_retries`|`{{ platform_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`controller_configuration_workflow_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`controller_configuration_async_retries`|30|no|This variable sets the number of retries to attempt for the role globally.| +|`controller_configuration_workflow_async_retries`|`{{ controller_configuration_async_retries }}`|no|This variable sets the number of retries to attempt for the role.| +|`controller_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`controller_configuration_workflow_async_delay`|`controller_configuration_async_delay`|no|This sets the delay between retries for the role.| |`controller_configuration_loop_delay`|0|no|This sets the pause between each item in the loop for the roles globally. To help when API is getting overloaded.| |`controller_configuration_workflow__loop_delay`|`controller_configuration_loop_delay`|no|This sets the pause between each item in the loop for the role. To help when API is getting overloaded.| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| +|`controller_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.| ## Data Structure @@ -89,7 +89,7 @@ This also speeds up the overall role. |`allow_simultaneous`|""|no|bool|Allow simultaneous runs of the workflow job template.| |`inventory`|""|no|str|Inventory applied as a prompt, assuming job template prompts for inventory| |`limit`|""|no|str|Limit applied as a prompt, assuming job template prompts for limit| -|`labels`|""|no|str|The labels applied to this job template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/controller_labels) role first, an error will occur if the label supplied to this role does not exist.| +|`labels`|""|no|str|The labels applied to this job template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/labels) role first, an error will occur if the label supplied to this role does not exist.| |`ask_labels_on_launch`|""|no|bool|Prompt user for labels on launch.| |`job_tags`|""|no|str|Comma separated list of the tags to use for the workflow job template.| |`skip_tags`|""|no|str|Comma separated list of the tags to skip for the workflow job template.| @@ -121,7 +121,7 @@ This also speeds up the overall role. |`forks`|Job Template default|no|str|Forks applied as a prompt. Job Template default used if not set. Only allowed if `ask_forks_on_launch` set to true on Job Template| |`instance_groups`|Job Template default|no|str| List of Instance Groups applied as a prompt. Job Template default used if not set. Only allowed if `ask_instance_groups_on_launch` set to true on Job Template| |`job_slice_count`|Job Template default|no|str|Job Slice Count to use in the job run. Job Template default used if not set. Only allowed if `ask_job_slice_count_on_launch` set to true on Job Template| -|`labels`|Job Template default|no|list|List of labels to use in the job run. Job Template default used if not set. Only allowed if `ask_labels_on_launch` set to true on Job Template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/controller_labels) role first, an error will occur if the label supplied to this role does not exist.| +|`labels`|Job Template default|no|list|List of labels to use in the job run. Job Template default used if not set. Only allowed if `ask_labels_on_launch` set to true on Job Template. NOTE: Labels must be created with the [labels](https://github.com/redhat-cop/aap_configuration/tree/devel/roles/labels) role first, an error will occur if the label supplied to this role does not exist.| |`timeout`|Job Template default|no|str|Timeout to use in the job run. Job Template default used if not set. Only allowed if `ask_timeout_on_launch` set to true on Job Template| |`approval_node`|""|no|str|A dictionary of Name, description, and timeout values for the approval node. This parameter is mutually exclusive with unified_job_template.| |`organization`|""|no|str|The organization of the workflow job template the node exists in. Used for looking up the workflow, not a direct model field.| @@ -409,12 +409,12 @@ controller_workflows: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_workflow_job_templates/defaults/main.yml b/roles/controller_workflow_job_templates/defaults/main.yml index c7887f595..df6c1ed34 100644 --- a/roles/controller_workflow_job_templates/defaults/main.yml +++ b/roles/controller_workflow_job_templates/defaults/main.yml @@ -1,10 +1,10 @@ --- # list of dicts describing Controller workflow templates controller_workflows: [] -workflow_job_templates_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -controller_configuration_workflow_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -controller_configuration_workflow_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +workflow_job_templates_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" +controller_configuration_workflow_async_retries: "{{ controller_configuration_async_retries | default(30) }}" +controller_configuration_workflow_async_delay: "{{ controller_configuration_async_delay | default(1) }}" controller_configuration_workflow__loop_delay: "{{ controller_configuration_loop_delay | default(0) }}" -platform_configuration_async_dir: null +controller_configuration_async_dir: null controller_configuration_workflows_enforce_defaults: "{{ controller_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/controller_workflow_job_templates/meta/argument_specs.yml b/roles/controller_workflow_job_templates/meta/argument_specs.yml index e6a07236b..b8cb25949 100644 --- a/roles/controller_workflow_job_templates/meta/argument_specs.yml +++ b/roles/controller_workflow_job_templates/meta/argument_specs.yml @@ -278,22 +278,22 @@ argument_specs: # Async variables controller_configuration_workflow_job_templates_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_workflow_job_templates_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + controller_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. @@ -301,45 +301,45 @@ argument_specs: # No_log variables controller_configuration_workflow_job_templates_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_workflow_job_templates/tasks/add_workflows_schema.yml b/roles/controller_workflow_job_templates/tasks/add_workflows_schema.yml index c7afbec33..0a22c16a8 100644 --- a/roles/controller_workflow_job_templates/tasks/add_workflows_schema.yml +++ b/roles/controller_workflow_job_templates/tasks/add_workflows_schema.yml @@ -24,17 +24,18 @@ timeout: "{{ __workflow_loop_node_item.timeout | default(omit, true) }}" approval_node: "{{ __workflow_loop_node_item.approval_node | default(omit, true) }}" workflow: "{{ __workflow_loop_item.name | mandatory }}" # Workflow job template name to associate with - state: "{{ __workflow_loop_node_item.state | default(platform_state | default('present')) }}" + state: "{{ __workflow_loop_node_item.state | default(controller_state | default('present')) }}" all_parents_must_converge: "{{ __workflow_loop_node_item.all_parents_must_converge | default('false') }}" organization: "{{ __workflow_loop_item.organization.name | default(__workflow_loop_item.organization) }}" # Workflow job template organization # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ __workflow_loop_item.simplified_workflow_nodes }}" loop_control: loop_var: __workflow_loop_node_item @@ -46,7 +47,7 @@ register: __workflows_node_async changed_when: not __workflows_node_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -65,7 +66,7 @@ when: not ansible_check_mode and __workflows_node_async_results_item.ansible_job_id is defined no_log: "{{ workflow_job_templates_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' # Create links between workflow node - name: Create links between Workflow Nodes @@ -75,14 +76,15 @@ always_nodes: "{{ __workflow_loop_node_item.always_nodes | default(__workflow_loop_node_item.related.always_nodes | default([], true) | selectattr('identifier', 'defined') | map(attribute='identifier')) | list }}" # Nodes to advance on always (blue links) success_nodes: "{{ __workflow_loop_node_item.success_nodes | default(__workflow_loop_node_item.related.success_nodes | default([], true) | selectattr('identifier', 'defined') | map(attribute='identifier')) | list }}" # Nodes to advance on success (green links) failure_nodes: "{{ __workflow_loop_node_item.failure_nodes | default(__workflow_loop_node_item.related.failure_nodes | default([], true) | selectattr('identifier', 'defined') | map(attribute='identifier')) | list }}" # Nodes to advance on failure (red links) - state: "{{ __workflow_loop_node_item.state | default(platform_state | default('present')) }}" + state: "{{ __workflow_loop_node_item.state | default(controller_state | default('present')) }}" organization: "{{ __workflow_loop_item.organization.name | default(__workflow_loop_item.organization) }}" # Workflow job template organization - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ __workflow_loop_item.simplified_workflow_nodes }}" loop_control: loop_var: __workflow_loop_node_item @@ -96,7 +98,7 @@ poll: 0 register: __workflows_link_async vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -116,5 +118,5 @@ when: not ansible_check_mode and __workflows_link_async_results_item.ansible_job_id is defined no_log: "{{ workflow_job_templates_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ controller_configuration_async_dir }}' ... diff --git a/roles/controller_workflow_job_templates/tasks/main.yml b/roles/controller_workflow_job_templates/tasks/main.yml index 6d2ae7a22..ddee92aa6 100644 --- a/roles/controller_workflow_job_templates/tasks/main.yml +++ b/roles/controller_workflow_job_templates/tasks/main.yml @@ -27,19 +27,20 @@ ask_skip_tags_on_launch: "{{ __workflow_loop_item.ask_skip_tags | default(__workflow_loop_item.ask_skip_tags_on_launch | default((false if controller_configuration_workflows_enforce_defaults else omit))) }}" workflow_nodes: "{{ __workflow_loop_item.related.workflow_nodes | default(__workflow_loop_item.workflow_nodes | default(([] if controller_configuration_workflows_enforce_defaults else omit), true)) }}" destroy_current_nodes: "{{ __workflow_loop_item.destroy_current_nodes | default(__workflow_loop_item.destroy_current_schema | default((false if controller_configuration_workflows_enforce_defaults else omit))) }}" - state: "{{ __workflow_loop_item.state | default(platform_state | default('present')) }}" + state: "{{ __workflow_loop_item.state | default(controller_state | default('present')) }}" notification_templates_started: "{{ (__workflow_loop_item.related.notification_templates_started | map(attribute='name') | list if __workflow_loop_item.related.notification_templates_started is defined) | default(__workflow_loop_item.notification_templates_started) | default(([] if controller_configuration_workflows_enforce_defaults else omit), true) }}" notification_templates_success: "{{ (__workflow_loop_item.related.notification_templates_success | map(attribute='name') | list if __workflow_loop_item.related.notification_templates_success is defined) | default(__workflow_loop_item.notification_templates_success) | default(([] if controller_configuration_workflows_enforce_defaults else omit), true) }}" notification_templates_error: "{{ (__workflow_loop_item.related.notification_templates_error | map(attribute='name') | list if __workflow_loop_item.related.notification_templates_error is defined) | default(__workflow_loop_item.notification_templates_error) | default(([] if controller_configuration_workflows_enforce_defaults else omit), true) }}" notification_templates_approvals: "{{ (__workflow_loop_item.related.notification_templates_approvals | map(attribute='name') | list if __workflow_loop_item.related.notification_templates_approvals is defined) | default(__workflow_loop_item.notification_templates_approvals) | default(([] if controller_configuration_workflows_enforce_defaults else omit), true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ workflow_job_templates if workflow_job_templates is defined else controller_workflows }}" loop_control: loop_var: __workflow_loop_item @@ -50,8 +51,8 @@ register: __workflows_job_async changed_when: "(__workflows_job_async.changed if ansible_check_mode else false)" vars: - __operation: "{{ operation_translate[__workflow_loop_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__workflow_loop_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' - name: "Flag for errors (check mode only)" ansible.builtin.set_fact: @@ -72,8 +73,8 @@ when: not ansible_check_mode and __workflows_job_async_results_item.ansible_job_id is defined no_log: "{{ workflow_job_templates_secure_logging }}" vars: - __operation: "{{ operation_translate[__workflows_job_async_results_item.__workflow_loop_item.state | default(platform_state) | default('present')] }}" - ansible_async_dir: '{{ platform_configuration_async_dir }}' + __operation: "{{ operation_translate[__workflows_job_async_results_item.__workflow_loop_item.state | default(controller_state) | default('present')] }}" + ansible_async_dir: '{{ controller_configuration_async_dir }}' # Create links between workflow node - name: Loop over nodes in schema to add to workflow templates diff --git a/roles/controller_workflow_job_templates/tests/test.yaml b/roles/controller_workflow_job_templates/tests/test.yaml index 1603dd274..bb0048b70 100644 --- a/roles/controller_workflow_job_templates/tests/test.yaml +++ b/roles/controller_workflow_job_templates/tests/test.yaml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/controller_workflow_launch/README.md b/roles/controller_workflow_launch/README.md index 2a92ed65e..0b88f16d4 100644 --- a/roles/controller_workflow_launch/README.md +++ b/roles/controller_workflow_launch/README.md @@ -16,13 +16,13 @@ Currently: |Variable Name|Default Value|Required|Description|Example| |:---|:---:|:---:|:---|:---| -|`platform_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| -|`platform_hostname`|""|yes|URL to the Ansible Automation Platform Server.|127.0.0.1| -|`platform_validate_certs`|`True`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_username`|""|no|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|no|Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_token`|""|no|Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| -|`platform_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| +|`controller_state`|"present"|no|The state all objects will take unless overridden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|no|Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified.|| +|`controller_password`|""|no|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_oauthtoken`|""|no|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified.|| +|`controller_request_timeout`|`10`|no|Specify the timeout in seconds Ansible should use in requests to the controller host.|| |`controller_workflow_launch_jobs`|`see below`|yes|Data structure describing workflow or workflows to launch Described below.|| ### Secure Logging Variables @@ -30,12 +30,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the workflow launch task does not include sensitive information. -controller_configuration_workflow_launch_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. +controller_configuration_workflow_launch_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`controller_configuration_workflow_launch_secure_logging`|`False`|no|Whether or not to include the sensitive ad_hoc_command role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -73,12 +73,12 @@ controller_workflow_launch_jobs: - name: Playbook to configure ansible controller post installation hosts: localhost connection: local - # Define following vars here, or in platform_configs/controller_auth.yml + # Define following vars here, or in controller_configs/controller_auth.yml # controller_hostname: ansible-controller-web-svc-test-project.example.com - # platform_username: admin + # controller_username: admin # controller_password: changeme pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./yaml ignore_files: [controller_config.yml.template] diff --git a/roles/controller_workflow_launch/defaults/main.yml b/roles/controller_workflow_launch/defaults/main.yml index a639d686a..0a7ce9e57 100644 --- a/roles/controller_workflow_launch/defaults/main.yml +++ b/roles/controller_workflow_launch/defaults/main.yml @@ -1,3 +1,3 @@ --- -controller_configuration_workflow_launch_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" +controller_configuration_workflow_launch_secure_logging: "{{ controller_configuration_secure_logging | default('false') }}" ... diff --git a/roles/controller_workflow_launch/meta/argument_specs.yml b/roles/controller_workflow_launch/meta/argument_specs.yml index 8f51e0114..7c0444990 100644 --- a/roles/controller_workflow_launch/meta/argument_specs.yml +++ b/roles/controller_workflow_launch/meta/argument_specs.yml @@ -48,63 +48,63 @@ argument_specs: # Async variables controller_configuration_workflow_launch_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ controller_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + controller_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. controller_configuration_workflow_launch_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ controller_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + controller_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. # No_log variables controller_configuration_groups_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ controller_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + controller_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + controller_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + controller_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Ansible Controller Server. type: str - platform_validate_certs: + controller_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Ansible Controller Server's SSL certificate. type: str - platform_username: + controller_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: Admin User on the Ansible Controller Server. Either username / password or oauthtoken need to be specified. type: str - platform_password: + controller_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str - platform_token: + controller_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/controller_workflow_launch/tasks/main.yml b/roles/controller_workflow_launch/tasks/main.yml index 1753c88ef..d48e74e7c 100644 --- a/roles/controller_workflow_launch/tasks/main.yml +++ b/roles/controller_workflow_launch/tasks/main.yml @@ -13,12 +13,13 @@ timeout: "{{ __workflow_launch_item.timeout | default(omit, true) }}" # Role Standard Options - controller_username: "{{ platform_username | default(omit, true) }}" - controller_password: "{{ platform_password | default(omit, true) }}" - controller_oauthtoken: "{{ platform_token | default(omit, true) }}" - request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - controller_host: "{{ platform_hostname | default(omit, true) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + controller_username: "{{ controller_username | default(omit, true) }}" + controller_password: "{{ controller_password | default(omit, true) }}" + controller_oauthtoken: "{{ controller_oauthtoken | default(omit, true) }}" + request_timeout: "{{ controller_request_timeout | default(omit, true) }}" + controller_host: "{{ controller_hostname | default(omit, true) }}" + controller_config_file: "{{ controller_config_file | default(omit, true) }}" + validate_certs: "{{ controller_validate_certs | default(omit) }}" loop: "{{ controller_workflow_launch_jobs }}" loop_control: loop_var: "__workflow_launch_item" diff --git a/roles/controller_workflow_launch/tests/test.yml b/roles/controller_workflow_launch/tests/test.yml index 93b7565fd..adb835e04 100644 --- a/roles/controller_workflow_launch/tests/test.yml +++ b/roles/controller_workflow_launch/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/dispatch/README.md b/roles/dispatch/README.md index ceb259642..b02607150 100644 --- a/roles/dispatch/README.md +++ b/roles/dispatch/README.md @@ -16,7 +16,7 @@ gateway_dispatch_roles: - {role: authenticator_maps, var: authenticator_maps_list, tags: authenticator_maps} - {role: http_ports, var: http_ports_list, tags: http_ports} - {role: organizations, var: organizations_list, tags: organizations} - - {role: teams, var: platform_teams, tags: teams} + - {role: teams, var: teams_list, tags: teams} - {role: service_clusters, var: service_clusters_list, tags: service_clusters} - {role: service_keys, var: service_keys_list, tags: service_keys} - {role: service_nodes, var: service_nodes_list, tags: service_nodes} @@ -38,4 +38,4 @@ For more information about roles, see each roles' README (also linked in the top ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/dispatch/defaults/main.yml b/roles/dispatch/defaults/main.yml index 60a51a9db..9f4b324ac 100644 --- a/roles/dispatch/defaults/main.yml +++ b/roles/dispatch/defaults/main.yml @@ -7,7 +7,7 @@ gateway_configuration_dispatcher_roles: var: authenticator_maps_list tags: authenticator_maps - role: gateway_settings - var: gateway_settings + var: settings_list tags: settings - role: gateway_http_ports var: http_ports_list @@ -34,7 +34,7 @@ gateway_configuration_dispatcher_roles: var: routes_list tags: routes - role: gateway_teams - var: platform_teams + var: teams_list tags: teams ah_configuration_dispatcher_roles: - role: hub_namespace diff --git a/roles/dispatch/meta/argument_specs.yml b/roles/dispatch/meta/argument_specs.yml index e5e80832a..4f908e779 100644 --- a/roles/dispatch/meta/argument_specs.yml +++ b/roles/dispatch/meta/argument_specs.yml @@ -39,7 +39,7 @@ argument_specs: var: routes_list tags: routes - role: gateway_teams - var: platform_teams + var: teams_list tags: teams controller_configuration_dispatcher_roles: default: @@ -181,52 +181,58 @@ argument_specs: tags: rulebook_activation # Async variables - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. # No_log variables - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/dispatch/tests/test.yml b/roles/dispatch/tests/test.yml index 892ded06b..a67723b48 100644 --- a/roles/dispatch/tests/test.yml +++ b/roles/dispatch/tests/test.yml @@ -6,14 +6,14 @@ vars: controller_validate_certs: false controller_hostname: controller.example.com - platform_username: admin + controller_username: admin controller_password: changeme collections: - awx.awx pre_tasks: - - name: Include vars from platform_configs directory + - name: Include vars from controller_configs directory ansible.builtin.include_vars: dir: ./configs extensions: ["yml"] diff --git a/roles/eda_controller_tokens/README.md b/roles/eda_controller_tokens/README.md index f7c38f69c..fb73a20ec 100644 --- a/roles/eda_controller_tokens/README.md +++ b/roles/eda_controller_tokens/README.md @@ -2,7 +2,7 @@ ## Description -An Ansible Role to create User Tokens in EDA Controller. Note that tokens may only be applied to the user account accessing the API (ie. platform_username) +An Ansible Role to create User Tokens in EDA Controller. Note that tokens may only be applied to the user account accessing the API (ie. eda_username) Note that tokens cannot be updated, only created. ## Variables @@ -10,12 +10,11 @@ Note that tokens cannot be updated, only created. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_controller_tokens`|`see below`|yes|Data structure describing your user tokens, described below.|| ### Secure Logging Variables @@ -23,12 +22,12 @@ Note that tokens cannot be updated, only created. The following Variables complement each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add project task does not include sensitive information. -eda_configuration_user_token_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_user_token_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_user_token_secure_logging`|`False`|no|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -39,8 +38,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_user_token_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_user_token_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_user_token_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_controller_tokens/defaults/main.yml b/roles/eda_controller_tokens/defaults/main.yml index 28a3fcab8..bddbfe72d 100644 --- a/roles/eda_controller_tokens/defaults/main.yml +++ b/roles/eda_controller_tokens/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_controller_tokens: [] -eda_configuration_user_token_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -eda_configuration_user_token_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_user_token_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_user_token_secure_logging: "{{ eda_configuration_secure_logging | default(false) }}" +eda_configuration_user_token_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_user_token_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_controller_tokens/meta/argument_specs.yml b/roles/eda_controller_tokens/meta/argument_specs.yml index b728ba569..1bef96685 100644 --- a/roles/eda_controller_tokens/meta/argument_specs.yml +++ b/roles/eda_controller_tokens/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_user_token_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_user_token_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_user_token_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ eda_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_controller_tokens/tasks/main.yml b/roles/eda_controller_tokens/tasks/main.yml index 7dbaaf32a..e45866fff 100644 --- a/roles/eda_controller_tokens/tasks/main.yml +++ b/roles/eda_controller_tokens/tasks/main.yml @@ -6,11 +6,11 @@ name: "{{ __token_item.name }}" description: "{{ __token_item.description | default(omit) }}" token: "{{ __token_item.token | default(omit) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ platform_username| default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_controller_tokens }}" loop_control: loop_var: "__token_item" @@ -20,7 +20,7 @@ register: __controller_tokens_job_async changed_when: not __controller_tokens_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create controller_token | Wait for finish the controller_token creation" ansible.builtin.async_status: @@ -35,5 +35,5 @@ when: __controller_tokens_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_user_token_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/eda_credentials/README.md b/roles/eda_credentials/README.md index 1117c6dc8..3e466276d 100644 --- a/roles/eda_credentials/README.md +++ b/roles/eda_credentials/README.md @@ -9,12 +9,11 @@ An Ansible Role to create Credentials in EDA Controller. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_credentials`|`see below`|yes|Data structure describing your credentials, described below.|| ### Secure Logging Variables @@ -22,12 +21,12 @@ An Ansible Role to create Credentials in EDA Controller. The following Variables complement each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add credential task does not include sensitive information. -eda_configuration_credential_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_credential_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_credential_secure_logging`|`True`|no|Whether or not to include the sensitive credential role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,8 +37,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_credential_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_credential_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_credential_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_credentials/defaults/main.yml b/roles/eda_credentials/defaults/main.yml index cd5e245f1..1b37c9165 100644 --- a/roles/eda_credentials/defaults/main.yml +++ b/roles/eda_credentials/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_credentials: [] -eda_configuration_credential_secure_logging: "{{ platform_configuration_secure_logging | default(true) }}" -eda_configuration_credential_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_credential_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_credential_secure_logging: "{{ eda_configuration_secure_logging | default(true) }}" +eda_configuration_credential_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_credential_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_credentials/meta/argument_specs.yml b/roles/eda_credentials/meta/argument_specs.yml index b25dde4e2..521a8b01c 100644 --- a/roles/eda_credentials/meta/argument_specs.yml +++ b/roles/eda_credentials/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_credential_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_credential_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_credential_secure_logging: - default: "{{ platform_configuration_secure_logging | default(true) }}" + default: "{{ eda_configuration_secure_logging | default(true) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_credentials/tasks/main.yml b/roles/eda_credentials/tasks/main.yml index 86566671a..f88552664 100644 --- a/roles/eda_credentials/tasks/main.yml +++ b/roles/eda_credentials/tasks/main.yml @@ -10,11 +10,11 @@ credential_type_name: "{{ __credential_item.credential_type | default('GitHub Personal Access Token') }}" inputs: "{{ __credential_item.inputs | default(omit) }}" state: "{{ __credential_item.state | default(eda_state | default('present')) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ eda_username | default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_credentials }}" loop_control: loop_var: "__credential_item" @@ -24,7 +24,7 @@ register: __credentials_job_async changed_when: not __credentials_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create credential | Wait for finish the credential creation" ansible.builtin.async_status: @@ -39,5 +39,5 @@ when: __credentials_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_credential_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/eda_decision_environments/README.md b/roles/eda_decision_environments/README.md index 548d0910f..ef665b149 100644 --- a/roles/eda_decision_environments/README.md +++ b/roles/eda_decision_environments/README.md @@ -9,12 +9,11 @@ An Ansible Role to create Decision Environments in EDA Controller. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_decision_environments`|`see below`|yes|Data structure describing your decision environments, described below.|| ### Secure Logging Variables @@ -22,12 +21,12 @@ An Ansible Role to create Decision Environments in EDA Controller. The following Variables complement each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add project task does not include sensitive information. -eda_configuration_project_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_project_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_project_secure_logging`|`False`|no|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,8 +37,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_project_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_project_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_project_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_decision_environments/defaults/main.yml b/roles/eda_decision_environments/defaults/main.yml index 641e07e58..2b8369f46 100644 --- a/roles/eda_decision_environments/defaults/main.yml +++ b/roles/eda_decision_environments/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_decision_environments: [] -eda_configuration_decision_environment_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -eda_configuration_decision_environment_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_decision_environment_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_decision_environment_secure_logging: "{{ eda_configuration_secure_logging | default(false) }}" +eda_configuration_decision_environment_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_decision_environment_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_decision_environments/meta/argument_specs.yml b/roles/eda_decision_environments/meta/argument_specs.yml index f86106a99..bd3c91097 100644 --- a/roles/eda_decision_environments/meta/argument_specs.yml +++ b/roles/eda_decision_environments/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_decision_environment_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_decision_environment_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_decision_environment_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ eda_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_decision_environments/tasks/main.yml b/roles/eda_decision_environments/tasks/main.yml index 65307acf7..7483933eb 100644 --- a/roles/eda_decision_environments/tasks/main.yml +++ b/roles/eda_decision_environments/tasks/main.yml @@ -10,11 +10,11 @@ credential: "{{ __de_item.credential | default(omit) }}" organization_name: "{{ __de_item.organization | default(omit) }}" state: "{{ __de_item.state | default(eda_state | default('present')) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ platform_username| default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_decision_environments }}" loop_control: loop_var: "__de_item" @@ -24,7 +24,7 @@ register: __decision_environments_job_async changed_when: not __decision_environments_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create decision_environment | Wait for finish the decision_environment creation" ansible.builtin.async_status: @@ -39,5 +39,5 @@ when: __decision_environments_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_decision_environment_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/eda_projects/README.md b/roles/eda_projects/README.md index c9e8d8b2b..57edec823 100644 --- a/roles/eda_projects/README.md +++ b/roles/eda_projects/README.md @@ -9,12 +9,11 @@ An Ansible Role to create Projects in EDA Controller. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_projects`|`see below`|yes|Data structure describing your projects, described below.|| ### Secure Logging Variables @@ -22,12 +21,12 @@ An Ansible Role to create Projects in EDA Controller. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add project task does not include sensitive information. -eda_configuration_project_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_project_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_project_secure_logging`|`False`|no|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,8 +37,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_project_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_project_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_project_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_projects/defaults/main.yml b/roles/eda_projects/defaults/main.yml index d6badbda9..db0d3dc15 100644 --- a/roles/eda_projects/defaults/main.yml +++ b/roles/eda_projects/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_projects: [] -eda_configuration_project_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -eda_configuration_project_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_project_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_project_secure_logging: "{{ eda_configuration_secure_logging | default(false) }}" +eda_configuration_project_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_project_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_projects/meta/argument_specs.yml b/roles/eda_projects/meta/argument_specs.yml index 044c87150..c4872814d 100644 --- a/roles/eda_projects/meta/argument_specs.yml +++ b/roles/eda_projects/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_project_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_project_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_project_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ eda_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_projects/tasks/main.yml b/roles/eda_projects/tasks/main.yml index 44c9ead1a..ca03b0c98 100644 --- a/roles/eda_projects/tasks/main.yml +++ b/roles/eda_projects/tasks/main.yml @@ -11,11 +11,11 @@ credential: "{{ __project_item.credential | default(omit) }}" organization_name: "{{ __project_item.organization | default(omit) }}" state: "{{ __project_item.state | default(eda_state | default('present')) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ platform_username| default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_projects }}" loop_control: loop_var: "__project_item" @@ -25,7 +25,7 @@ register: __projects_job_async changed_when: not __projects_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create project | Wait for finish the project creation" ansible.builtin.async_status: @@ -40,5 +40,5 @@ when: __projects_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_project_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/eda_rulebook_activations/README.md b/roles/eda_rulebook_activations/README.md index ff389b02c..aa8792a87 100644 --- a/roles/eda_rulebook_activations/README.md +++ b/roles/eda_rulebook_activations/README.md @@ -9,12 +9,11 @@ An Ansible Role to create rulebook activations in EDA Controller. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_rulebook_activations`|`see below`|yes|Data structure describing your rulebook activations, described below.|| ### Secure Logging Variables @@ -22,12 +21,12 @@ An Ansible Role to create rulebook activations in EDA Controller. The following Variables complement each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add project task does not include sensitive information. -eda_configuration_project_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_project_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_project_secure_logging`|`False`|no|Whether or not to include the sensitive Project role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,8 +37,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_project_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_project_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_project_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_rulebook_activations/defaults/main.yml b/roles/eda_rulebook_activations/defaults/main.yml index 301614c01..107413d6d 100644 --- a/roles/eda_rulebook_activations/defaults/main.yml +++ b/roles/eda_rulebook_activations/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_rulebook_activations: [] -eda_configuration_rulebook_activation_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -eda_configuration_rulebook_activation_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_rulebook_activation_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_rulebook_activation_secure_logging: "{{ eda_configuration_secure_logging | default(false) }}" +eda_configuration_rulebook_activation_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_rulebook_activation_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_rulebook_activations/meta/argument_specs.yml b/roles/eda_rulebook_activations/meta/argument_specs.yml index e91452b82..19ed5d389 100644 --- a/roles/eda_rulebook_activations/meta/argument_specs.yml +++ b/roles/eda_rulebook_activations/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_rulebook_activation_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_rulebook_activation_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_rulebook_activation_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ eda_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_rulebook_activations/tasks/main.yml b/roles/eda_rulebook_activations/tasks/main.yml index 73f67450a..f92ea53c3 100644 --- a/roles/eda_rulebook_activations/tasks/main.yml +++ b/roles/eda_rulebook_activations/tasks/main.yml @@ -19,11 +19,11 @@ event_streams: "{{ __ra_item.event_streams | default(omit) }}" log_level: "{{ __ra_item.log_level | default(omit) }}" state: "{{ __ra_item.state | default(eda_state | default('present')) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ eda_username | default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_rulebook_activations }}" loop_control: loop_var: "__ra_item" @@ -33,7 +33,7 @@ register: __rulebook_activations_job_async changed_when: not __rulebook_activations_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create rulebook_activation | Wait for finish the rulebook_activation creation" ansible.builtin.async_status: @@ -48,5 +48,5 @@ when: __rulebook_activations_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_rulebook_activation_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/eda_users/README.md b/roles/eda_users/README.md index 569749070..a0c07f2ea 100644 --- a/roles/eda_users/README.md +++ b/roles/eda_users/README.md @@ -9,12 +9,11 @@ An Ansible Role to create users in EDA Controller. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`eda_host`|""|yes|URL to the EDA Controller (alias: `eda_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified.|| -|`platform_password`|""|yes|Platform Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| - -|`platform_validate_certs`|`False`|no|Whether or not to validate the Ansible Automation Platform Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Automation Platform host.|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`eda_username`|""|yes|Admin User on the EDA Controller || +|`eda_password`|""|yes|EDA Controller Admin User's password on the EDA Controller Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`eda_validate_certs`|`False`|no|Whether or not to validate the Ansible EDA Controller Server's SSL certificate.|| +|`eda_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the EDA Controller host.|| +|`eda_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`eda_users`|`see below`|yes|Data structure describing your users, described below.|| ### Secure Logging Variables @@ -22,12 +21,12 @@ An Ansible Role to create users in EDA Controller. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add user task does not include sensitive information. -eda_configuration_user_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. +eda_configuration_user_secure_logging defaults to the value of eda_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of EDA Controller configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`eda_configuration_user_secure_logging`|`False`|no|Whether or not to include the sensitive user role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`eda_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,8 +37,8 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`eda_configuration_user_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`eda_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`eda_configuration_user_async_retries`|`eda_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| |`eda_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| |`eda_configuration_user_async_delay`|`eda_configuration_async_delay`|no|This sets the delay between retries for the role.| diff --git a/roles/eda_users/defaults/main.yml b/roles/eda_users/defaults/main.yml index b9d00cc2d..3526c87c4 100644 --- a/roles/eda_users/defaults/main.yml +++ b/roles/eda_users/defaults/main.yml @@ -1,8 +1,8 @@ --- eda_users: [] -eda_configuration_user_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -eda_configuration_user_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -eda_configuration_user_async_delay: "{{ platform_configuration_async_delay| default(1) }}" -platform_configuration_async_dir: null +eda_configuration_user_secure_logging: "{{ eda_configuration_secure_logging | default(false) }}" +eda_configuration_user_async_retries: "{{ eda_configuration_async_retries | default(50) }}" +eda_configuration_user_async_delay: "{{ eda_configuration_async_delay | default(1) }}" +eda_configuration_async_dir: null ... diff --git a/roles/eda_users/meta/argument_specs.yml b/roles/eda_users/meta/argument_specs.yml index 954622a27..761e50fa3 100644 --- a/roles/eda_users/meta/argument_specs.yml +++ b/roles/eda_users/meta/argument_specs.yml @@ -12,67 +12,59 @@ argument_specs: # Async variables eda_configuration_user_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ eda_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + eda_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. eda_configuration_user_async_delay: - default: "{{ platform_configuration_async_delay| default(1) }}" + default: "{{ eda_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. eda_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + eda_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables eda_configuration_user_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ eda_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + eda_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: - default: present + controller_host: required: false - description: The state all objects will take unless overridden by object default + description: URL to the EDA Controller Server. type: str - platform_hostname: - default: None - required: false - description: URL to the Ansible Automation Platform Server. - type: str - platform_validate_certs: + eda_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the EDA Controller Server's SSL certificate. type: str - platform_username: - default: None + eda_request_timeout: + default: 10 required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. - type: str - platform_password: - default: None + description: Specify the timeout Ansible should use in requests to the EDA Controller host. + type: float + controller_username: required: false - description: Platform Admin User's password on the Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook. + description: User for authentication on EDA Controller type: str - platform_token: - default: None + controller_password: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For EDA Controller type: str ... diff --git a/roles/eda_users/tasks/main.yml b/roles/eda_users/tasks/main.yml index 12814bb75..23e540b76 100644 --- a/roles/eda_users/tasks/main.yml +++ b/roles/eda_users/tasks/main.yml @@ -13,11 +13,11 @@ is_superuser: "{{ __user_item.is_superuser | default(omit) }}" roles: "{{ __user_item.roles | default(omit) }}" state: "{{ __user_item.state | default(eda_state | default('present')) }}" - controller_host: "{{ platform_hostname}}" - eda_username: "{{ platform_username| default(omit) }}" - controller_password: "{{ platform_password | default(omit) }}" - validate_certs: "{{ platform_validate_certs| default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + controller_host: "{{ eda_host | default(eda_hostname) }}" + controller_username: "{{ eda_username | default(omit) }}" + controller_password: "{{ eda_password | default(omit) }}" + validate_certs: "{{ eda_validate_certs | default(omit) }}" + request_timeout: "{{ eda_request_timeout | default(omit) }}" loop: "{{ eda_users }}" loop_control: loop_var: "__user_item" @@ -27,7 +27,7 @@ register: __users_job_async changed_when: not __users_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' - name: "Create user | Wait for finish the user creation" ansible.builtin.async_status: @@ -42,5 +42,5 @@ when: __users_job_async_result_item.ansible_job_id is defined no_log: "{{ eda_configuration_user_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ eda_configuration_async_dir }}' ... diff --git a/roles/gateway_applications/README.md b/roles/gateway_applications/README.md index 014a6b02d..b9d7152ff 100644 --- a/roles/gateway_applications/README.md +++ b/roles/gateway_applications/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:------------------------------------------------------|:---------------------------------------------------:|:--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------:| | `applications_list` (Alias: `applications`) | [below](#application-arguments) | yes | Data structure describing your applications entries described below. Alias: applications | [more](../../README.md#data-variables) | -| `applications_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive Application role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | -| `applications_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the applications role | -| `applications_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | -| `applications_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | +| `applications_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive Application role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | +| `applications_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the applications role | +| `applications_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | +| `applications_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | ## Data Structure @@ -84,4 +84,4 @@ ansible-playbook manage_data.yml -e @data/gateway_applications.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_applications/defaults/main.yml b/roles/gateway_applications/defaults/main.yml index 5249633cb..815ae0321 100644 --- a/roles/gateway_applications/defaults/main.yml +++ b/roles/gateway_applications/defaults/main.yml @@ -1,8 +1,8 @@ --- # a list of dictionaries describing the gateway applications applications_list: [] -applications_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -applications_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -applications_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -applications_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +applications_secure_logging: "{{ gateway_configuration_secure_logging | default('false') }}" +applications_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +applications_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +applications_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_applications/meta/argument_specs.yml b/roles/gateway_applications/meta/argument_specs.yml index 64681b114..b3a4351b7 100644 --- a/roles/gateway_applications/meta/argument_specs.yml +++ b/roles/gateway_applications/meta/argument_specs.yml @@ -63,22 +63,22 @@ argument_specs: # Async variables applications_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. applications_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -87,13 +87,13 @@ argument_specs: # No_log variables applications_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: false required: false type: bool diff --git a/roles/gateway_applications/tasks/main.yml b/roles/gateway_applications/tasks/main.yml index d75d79665..cb10a181b 100644 --- a/roles/gateway_applications/tasks/main.yml +++ b/roles/gateway_applications/tasks/main.yml @@ -17,12 +17,12 @@ state: "{{ __application_item.state | default(gateway_state | default(omit, true)) }}" # Role specific options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, true) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ applications if applications is defined else applications_list }}" loop_control: loop_var: __application_item @@ -32,7 +32,7 @@ register: __gateway_applications_job_async changed_when: not __gateway_applications_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Applications | Wait for finish the configuration ansible.builtin.async_status: @@ -47,5 +47,5 @@ when: __gateway_applications_job_async_results_item.ansible_job_id is defined no_log: "{{ applications_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_authenticator_maps/README.md b/roles/gateway_authenticator_maps/README.md index b77d0951c..235de7245 100644 --- a/roles/gateway_authenticator_maps/README.md +++ b/roles/gateway_authenticator_maps/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:------------------------------------------------------------|:---------------------------------------------------:|:--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `authenticator_maps_list` (Alias: `authenticator_maps`) | [below](#organization-arguments) | yes | Data structure describing your authenticator_map entries described below. | [more](../../README.md#data-variables) | -| `authenticator_maps_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive authenticator_map role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `authenticator_maps_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the authenticator_map role. | [more](../../README.md#enforcing-defaults) | -| `authenticator_maps_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `authenticator_maps_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `authenticator_maps_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive authenticator_map role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `authenticator_maps_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the authenticator_map role. | [more](../../README.md#enforcing-defaults) | +| `authenticator_maps_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `authenticator_maps_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -133,4 +133,4 @@ ansible-playbook manage_data.yml -e @data/gateway_authenticator_maps.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_authenticator_maps/defaults/main.yml b/roles/gateway_authenticator_maps/defaults/main.yml index 5e4ecf2d4..35ffd997b 100644 --- a/roles/gateway_authenticator_maps/defaults/main.yml +++ b/roles/gateway_authenticator_maps/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the authenticator maps authenticator_maps_list: [] -authenticator_maps_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -authenticator_maps_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -authenticator_maps_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -authenticator_maps_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +authenticator_maps_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +authenticator_maps_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +authenticator_maps_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +authenticator_maps_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_authenticator_maps/meta/argument_specs.yml b/roles/gateway_authenticator_maps/meta/argument_specs.yml index a5309d2a3..a839146b8 100644 --- a/roles/gateway_authenticator_maps/meta/argument_specs.yml +++ b/roles/gateway_authenticator_maps/meta/argument_specs.yml @@ -64,22 +64,22 @@ argument_specs: # Async variables authenticator_maps_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. authenticator_maps_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -89,47 +89,53 @@ argument_specs: # No_log variables authenticator_maps_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_authenticator_maps/tasks/main.yml b/roles/gateway_authenticator_maps/tasks/main.yml index 3aeea6b4d..cf118a609 100644 --- a/roles/gateway_authenticator_maps/tasks/main.yml +++ b/roles/gateway_authenticator_maps/tasks/main.yml @@ -15,12 +15,12 @@ state: "{{ __gateway_authenticator_maps_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ authenticator_maps if authenticator_maps is defined else authenticator_maps_list }}" loop_control: loop_var: __gateway_authenticator_maps_item @@ -30,7 +30,7 @@ register: __gateway_authenticator_maps_job_async changed_when: not __gateway_authenticator_maps_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Authenticator Map | Wait for finish the configuration ansible.builtin.async_status: @@ -45,5 +45,5 @@ when: __gateway_authenticator_maps_job_async_results_item.ansible_job_id is defined no_log: "{{ authenticator_maps_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_authenticators/README.md b/roles/gateway_authenticators/README.md index dd99cd277..dc8e96876 100644 --- a/roles/gateway_authenticators/README.md +++ b/roles/gateway_authenticators/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:--------------------------------------------------------|:---------------------------------------------------:|:--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `authenticators_list` (Alias: `authenticators`) | [below](#authenticator-arguments) | yes | Data structure describing your organization entries described below. | [more](../../README.md#data-variables) | -| `authenticators_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive organizations role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `authenticators_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the organizations role. | [more](../../README.md#enforcing-defaults) | -| `authenticators_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `authenticators_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `authenticators_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive organizations role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `authenticators_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the organizations role. | [more](../../README.md#enforcing-defaults) | +| `authenticators_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `authenticators_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -100,4 +100,4 @@ ansible-playbook manage_data.yml -e @data/gateway_authenticators.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_authenticators/defaults/main.yml b/roles/gateway_authenticators/defaults/main.yml index 4199c14cc..233cecdea 100644 --- a/roles/gateway_authenticators/defaults/main.yml +++ b/roles/gateway_authenticators/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the authenticators authenticators_list: [] -authenticators_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -authenticators_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -authenticators_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -authenticators_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +authenticators_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +authenticators_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +authenticators_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +authenticators_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_authenticators/meta/argument_specs.yml b/roles/gateway_authenticators/meta/argument_specs.yml index 61bcc1e47..d38dd6eb3 100644 --- a/roles/gateway_authenticators/meta/argument_specs.yml +++ b/roles/gateway_authenticators/meta/argument_specs.yml @@ -51,22 +51,22 @@ argument_specs: # Async variables authenticators_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. authenticators_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -76,47 +76,53 @@ argument_specs: # No_log variables authenticators_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_authenticators/tasks/main.yml b/roles/gateway_authenticators/tasks/main.yml index 945538ba4..27eb9b1b6 100644 --- a/roles/gateway_authenticators/tasks/main.yml +++ b/roles/gateway_authenticators/tasks/main.yml @@ -13,12 +13,12 @@ state: "{{ __gateway_authenticators_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ authenticators if authenticators is defined else authenticators_list }}" loop_control: loop_var: __gateway_authenticators_item @@ -28,7 +28,7 @@ register: __gateway_authenticators_job_async changed_when: not __gateway_authenticators_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Authenticators | Wait for finish the configuration ansible.builtin.async_status: @@ -43,5 +43,5 @@ when: __gateway_authenticators_job_async_results_item.ansible_job_id is defined no_log: "{{ authenticators_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_http_ports/README.md b/roles/gateway_http_ports/README.md index 4b9150e9a..25d64c0f8 100644 --- a/roles/gateway_http_ports/README.md +++ b/roles/gateway_http_ports/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:----------------------------------------------------|:---------------------------------------------------:|:--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `http_ports_list` (Alias: `http_ports`) | [below](#http-port-arguments) | yes | Data structure describing your http port entries described below. | [more](../../README.md#data-variables) | -| `http_ports_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive http_ports role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `http_ports_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the http port role. | [more](../../README.md#enforcing-defaults) | -| `http_ports_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `http_ports_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `http_ports_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive http_ports role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `http_ports_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the http port role. | [more](../../README.md#enforcing-defaults) | +| `http_ports_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `http_ports_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -89,4 +89,4 @@ ansible-playbook manage_data.yml -e @data/gateway_http_ports.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_http_ports/defaults/main.yml b/roles/gateway_http_ports/defaults/main.yml index ea6317aa1..a7578cd69 100644 --- a/roles/gateway_http_ports/defaults/main.yml +++ b/roles/gateway_http_ports/defaults/main.yml @@ -15,8 +15,8 @@ http_ports_list: [] # - use_https # - is_api_port # - state -http_ports_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -http_ports_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -http_ports_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -http_ports_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +http_ports_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +http_ports_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +http_ports_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +http_ports_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_http_ports/meta/argument_specs.yml b/roles/gateway_http_ports/meta/argument_specs.yml index aeacc6459..34638fc41 100644 --- a/roles/gateway_http_ports/meta/argument_specs.yml +++ b/roles/gateway_http_ports/meta/argument_specs.yml @@ -37,22 +37,22 @@ argument_specs: # Async variables http_ports_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. http_ports_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -62,47 +62,53 @@ argument_specs: # No_log variables http_ports_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_http_ports/tasks/main.yml b/roles/gateway_http_ports/tasks/main.yml index 01c8892aa..0c878df56 100644 --- a/roles/gateway_http_ports/tasks/main.yml +++ b/roles/gateway_http_ports/tasks/main.yml @@ -9,12 +9,12 @@ state: "{{ __gateway_http_ports_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, true) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ http_ports if http_ports is defined else http_ports_list }}" loop_control: loop_var: __gateway_http_ports_item @@ -24,7 +24,7 @@ register: __gateway_http_ports_job_async changed_when: not __gateway_http_ports_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Http Ports | Wait for finish the configuration ansible.builtin.async_status: @@ -39,5 +39,5 @@ when: __gateway_http_ports_job_async_results_item.ansible_job_id is defined no_log: "{{ http_ports_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_organizations/README.md b/roles/gateway_organizations/README.md index f6d2a56b8..5649ff0b5 100644 --- a/roles/gateway_organizations/README.md +++ b/roles/gateway_organizations/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:-------------------------------------------------------|:---------------------------------------------------:|:--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `organizations_list` (Alias: `organizations`) | [below](#organization-arguments) | yes | Data structure describing your organization entries described below. | [more](../../README.md#data-variables) | -| `organizations_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive organizations role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `organizations_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the organizations role. | [more](../../README.md#enforcing-defaults) | -| `organizations_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `organizations_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `organizations_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive organizations role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `organizations_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the organizations role. | [more](../../README.md#enforcing-defaults) | +| `organizations_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `organizations_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -86,4 +86,4 @@ ansible-playbook manage_data.yml -e @data/gateway_organizations.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_organizations/defaults/main.yml b/roles/gateway_organizations/defaults/main.yml index 096977881..9a1b8a090 100644 --- a/roles/gateway_organizations/defaults/main.yml +++ b/roles/gateway_organizations/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the organizations organizations_list: [] -organizations_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -organizations_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -organizations_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -organizations_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +organizations_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +organizations_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +organizations_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +organizations_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_organizations/meta/argument_specs.yml b/roles/gateway_organizations/meta/argument_specs.yml index c64eb7586..99479f38d 100644 --- a/roles/gateway_organizations/meta/argument_specs.yml +++ b/roles/gateway_organizations/meta/argument_specs.yml @@ -27,22 +27,22 @@ argument_specs: # Async variables organizations_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. organizations_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -52,47 +52,53 @@ argument_specs: # No_log variables organizations_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_organizations/tasks/main.yml b/roles/gateway_organizations/tasks/main.yml index 34e252503..aeb66f96e 100644 --- a/roles/gateway_organizations/tasks/main.yml +++ b/roles/gateway_organizations/tasks/main.yml @@ -7,12 +7,12 @@ state: "{{ __gateway_organizations_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ organizations if organizations is defined else controller_organizations }}" loop_control: loop_var: __gateway_organizations_item @@ -22,7 +22,7 @@ register: __gateway_organizations_job_async changed_when: not __gateway_organizations_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Organizations | Wait for finish the configuration ansible.builtin.async_status: @@ -37,5 +37,5 @@ when: __gateway_organizations_job_async_results_item.ansible_job_id is defined no_log: "{{ organizations_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_role_user_assignments/README.md b/roles/gateway_role_user_assignments/README.md index 1376c571d..72991ee8e 100644 --- a/roles/gateway_role_user_assignments/README.md +++ b/roles/gateway_role_user_assignments/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:-----------------------------------------------------------------|:---------------------------------------------------:|:--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `role_user_assignments_list` (Alias: `role_user_assignments`) | [below](#role-user-assignments-arguments) | yes | Data structure describing your organization entries described below. | [more](../../README.md#data-variables) | -| `role_user_assignments_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive role_user_assignments role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `role_user_assignments_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the role_user_assignments role. | [more](../../README.md#enforcing-defaults) | -| `role_user_assignments_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `role_user_assignments_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `role_user_assignments_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive role_user_assignments role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `role_user_assignments_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the role_user_assignments role. | [more](../../README.md#enforcing-defaults) | +| `role_user_assignments_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `role_user_assignments_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -79,4 +79,4 @@ ansible-playbook manage_data.yml -e @data/gateway_role_user_assignments.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_role_user_assignments/defaults/main.yml b/roles/gateway_role_user_assignments/defaults/main.yml index 4525d860b..53d8176ee 100644 --- a/roles/gateway_role_user_assignments/defaults/main.yml +++ b/roles/gateway_role_user_assignments/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the role_user_assignments role_user_assignments_list: [] -role_user_assignments_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -role_user_assignments_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -role_user_assignments_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -role_user_assignments_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +role_user_assignments_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +role_user_assignments_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +role_user_assignments_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +role_user_assignments_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_role_user_assignments/meta/argument_specs.yml b/roles/gateway_role_user_assignments/meta/argument_specs.yml index 7fa54c27e..540dccc03 100644 --- a/roles/gateway_role_user_assignments/meta/argument_specs.yml +++ b/roles/gateway_role_user_assignments/meta/argument_specs.yml @@ -42,22 +42,22 @@ argument_specs: # Async variables role_user_assignments_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. role_user_assignments_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -67,47 +67,53 @@ argument_specs: # No_log variables role_user_assignments_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_role_user_assignments/tasks/main.yml b/roles/gateway_role_user_assignments/tasks/main.yml index 0475f5743..6dcfb697e 100644 --- a/roles/gateway_role_user_assignments/tasks/main.yml +++ b/roles/gateway_role_user_assignments/tasks/main.yml @@ -9,12 +9,12 @@ state: "{{ __gateway_role_user_assignments_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ role_user_assignments if role_user_assignments is defined else role_user_assignments_list }}" loop_control: loop_var: __gateway_role_user_assignments_item @@ -24,7 +24,7 @@ register: __gateway_role_user_assignments_job_async changed_when: not __gateway_role_user_assignments_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Role User Assignments | Wait for finish the configuration ansible.builtin.async_status: @@ -39,5 +39,5 @@ when: __gateway_role_user_assignments_job_async_results_item.ansible_job_id is defined no_log: "{{ role_user_assignments_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_routes/README.md b/roles/gateway_routes/README.md index 91ef14fbd..8005df413 100644 --- a/roles/gateway_routes/README.md +++ b/roles/gateway_routes/README.md @@ -15,10 +15,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:------------------------------------------------|:---------------------------------------------------:|:--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `routes_list` (Alias: routes) | [below](#service-arguments) | yes | Data structure describing your route entries described below. | [more](../../README.md#data-variables) | -| `routes_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive route role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `routes_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the route role. | [more](../../README.md#enforcing-defaults) | -| `routes_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `routes_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `routes_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive route role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `routes_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the route role. | [more](../../README.md#enforcing-defaults) | +| `routes_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `routes_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -110,4 +110,4 @@ ansible-playbook manage_data.yml -e @data/gateway_routes.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_routes/defaults/main.yml b/roles/gateway_routes/defaults/main.yml index aada47b62..2d1e98df8 100644 --- a/roles/gateway_routes/defaults/main.yml +++ b/roles/gateway_routes/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the service nodes routes_list: [] -routes_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -routes_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -routes_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -routes_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +routes_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +routes_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +routes_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +routes_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_routes/meta/argument_specs.yml b/roles/gateway_routes/meta/argument_specs.yml index 53d9a01fc..755871feb 100644 --- a/roles/gateway_routes/meta/argument_specs.yml +++ b/roles/gateway_routes/meta/argument_specs.yml @@ -64,22 +64,22 @@ argument_specs: # Async variables routes_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. routes_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -89,47 +89,53 @@ argument_specs: # No_log variables routes_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_routes/tasks/main.yml b/roles/gateway_routes/tasks/main.yml index 48bb88f62..054ba42c0 100644 --- a/roles/gateway_routes/tasks/main.yml +++ b/roles/gateway_routes/tasks/main.yml @@ -15,12 +15,12 @@ state: "{{ __gateway_routes_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ routes if routes is defined else routes_list }}" loop_control: loop_var: __gateway_routes_item @@ -30,7 +30,7 @@ register: __gateway_routes_job_async changed_when: not __gateway_routes_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Routes | Wait for finish the configuration ansible.builtin.async_status: @@ -45,5 +45,5 @@ when: __gateway_routes_job_async_results_item.ansible_job_id is defined no_log: "{{ routes_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_service_clusters/README.md b/roles/gateway_service_clusters/README.md index f5e9ace90..2eb9201c3 100644 --- a/roles/gateway_service_clusters/README.md +++ b/roles/gateway_service_clusters/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:----------------------------------------------------------|:---------------------------------------------------:|:--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `service_clusters_list` (Alias: service_clusters) | [below](#service-cluster-arguments) | yes | Data structure describing your service_cluster entries described below. | [more](../../README.md#data-variables) | -| `service_clusters_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_cluster role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `service_clusters_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service cluster role. | [more](../../README.md#enforcing-defaults) | -| `service_clusters_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `service_clusters_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_clusters_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_cluster role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `service_clusters_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service cluster role. | [more](../../README.md#enforcing-defaults) | +| `service_clusters_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_clusters_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -91,4 +91,4 @@ ansible-playbook manage_data.yml -e @data/gateway_service_clusters.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_service_clusters/defaults/main.yml b/roles/gateway_service_clusters/defaults/main.yml index 9553c70a7..614530bc9 100644 --- a/roles/gateway_service_clusters/defaults/main.yml +++ b/roles/gateway_service_clusters/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the service clusters service_clusters_list: [] -service_clusters_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -service_clusters_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -service_clusters_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -service_clusters_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +service_clusters_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +service_clusters_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +service_clusters_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +service_clusters_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_service_clusters/meta/argument_specs.yml b/roles/gateway_service_clusters/meta/argument_specs.yml index 452e34614..1220f2c45 100644 --- a/roles/gateway_service_clusters/meta/argument_specs.yml +++ b/roles/gateway_service_clusters/meta/argument_specs.yml @@ -59,22 +59,22 @@ argument_specs: # Async variables service_clusters_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. service_clusters_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -84,47 +84,53 @@ argument_specs: # No_log variables service_clusters_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_service_clusters/tasks/main.yml b/roles/gateway_service_clusters/tasks/main.yml index 949339e2b..a83f9970d 100644 --- a/roles/gateway_service_clusters/tasks/main.yml +++ b/roles/gateway_service_clusters/tasks/main.yml @@ -17,12 +17,12 @@ health_check_healthy_threshold: "{{ __gateway_service_clusters_item.health_check_healthy_threshold | default(omit) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ service_clusters if service_clusters is defined else service_clusters_list }}" loop_control: loop_var: __gateway_service_clusters_item @@ -32,7 +32,7 @@ register: __gateway_service_clusters_job_async changed_when: not __gateway_service_clusters_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Service Clusters | Wait for finish the configuration ansible.builtin.async_status: @@ -47,5 +47,5 @@ when: __gateway_service_clusters_job_async_results_item.ansible_job_id is defined no_log: "{{ service_clusters_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_service_keys/README.md b/roles/gateway_service_keys/README.md index 4f0861310..38600ae88 100644 --- a/roles/gateway_service_keys/README.md +++ b/roles/gateway_service_keys/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:------------------------------------------------------|:---------------------------------------------------:|:--------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `service_keys_list` (Alias: `service_keys`) | [below](#service-key-arguments) | yes | Data structure describing your service_key entries described below. | [more](../../README.md#data-variables) | -| `service_keys_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_key role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `service_keys_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service key role. | [more](../../README.md#enforcing-defaults) | -| `service_keys_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `service_keys_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_keys_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_key role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `service_keys_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service key role. | [more](../../README.md#enforcing-defaults) | +| `service_keys_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_keys_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -92,4 +92,4 @@ ansible-playbook manage_data.yml -e @data/gateway_service_keys.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_service_keys/defaults/main.yml b/roles/gateway_service_keys/defaults/main.yml index 5ecbbddd1..c81343ca2 100644 --- a/roles/gateway_service_keys/defaults/main.yml +++ b/roles/gateway_service_keys/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the service keys service_keys_list: [] -service_keys_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -service_keys_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -service_keys_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -service_keys_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +service_keys_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +service_keys_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +service_keys_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +service_keys_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_service_keys/meta/argument_specs.yml b/roles/gateway_service_keys/meta/argument_specs.yml index e4c7b1f05..057b27a71 100644 --- a/roles/gateway_service_keys/meta/argument_specs.yml +++ b/roles/gateway_service_keys/meta/argument_specs.yml @@ -47,22 +47,22 @@ argument_specs: # Async variables service_keys_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. service_keys_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -72,47 +72,53 @@ argument_specs: # No_log variables service_keys_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_service_keys/tasks/main.yml b/roles/gateway_service_keys/tasks/main.yml index a5db04fd1..4c2abbaca 100644 --- a/roles/gateway_service_keys/tasks/main.yml +++ b/roles/gateway_service_keys/tasks/main.yml @@ -12,12 +12,12 @@ state: "{{ __gateway_service_keys_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ service_keys if service_keys is defined else service_keys_list }}" loop_control: loop_var: __gateway_service_keys_item @@ -27,7 +27,7 @@ register: __gateway_service_keys_job_async changed_when: not __gateway_service_keys_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Service Keys | Wait for finish the configuration ansible.builtin.async_status: @@ -42,5 +42,5 @@ when: __gateway_service_keys_job_async_results_item.ansible_job_id is defined no_log: "{{ service_keys_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_service_nodes/README.md b/roles/gateway_service_nodes/README.md index 4a2e6ab90..0e0c20f84 100644 --- a/roles/gateway_service_nodes/README.md +++ b/roles/gateway_service_nodes/README.md @@ -13,10 +13,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:-------------------------------------------------------|:---------------------------------------------------:|:--------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `service_nodes_list` (Alias: `service_nodes`) | [below](#service-node-arguments) | yes | Data structure describing your service_node entries described below. | [more](../../README.md#data-variables) | -| `service_nodes_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_node role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `service_nodes_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service node role. | [more](../../README.md#enforcing-defaults) | -| `service_nodes_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `service_nodes_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_nodes_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service_node role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `service_nodes_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service node role. | [more](../../README.md#enforcing-defaults) | +| `service_nodes_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `service_nodes_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -87,4 +87,4 @@ ansible-playbook manage_data.yml -e @data/gateway_service_nodes.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_service_nodes/defaults/main.yml b/roles/gateway_service_nodes/defaults/main.yml index c1f69a122..3f3671dff 100644 --- a/roles/gateway_service_nodes/defaults/main.yml +++ b/roles/gateway_service_nodes/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the service nodes service_nodes_list: [] -service_nodes_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -service_nodes_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -service_nodes_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -service_nodes_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +service_nodes_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +service_nodes_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +service_nodes_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +service_nodes_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_service_nodes/meta/argument_specs.yml b/roles/gateway_service_nodes/meta/argument_specs.yml index b96f824c3..9455153b7 100644 --- a/roles/gateway_service_nodes/meta/argument_specs.yml +++ b/roles/gateway_service_nodes/meta/argument_specs.yml @@ -35,22 +35,22 @@ argument_specs: # Async variables service_nodes_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. service_nodes_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -60,47 +60,53 @@ argument_specs: # No_log variables service_nodes_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_service_nodes/tasks/main.yml b/roles/gateway_service_nodes/tasks/main.yml index 08a65a1fc..319d2c523 100644 --- a/roles/gateway_service_nodes/tasks/main.yml +++ b/roles/gateway_service_nodes/tasks/main.yml @@ -9,12 +9,12 @@ state: "{{ __gateway_service_nodes_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ service_nodes if service_nodes is defined else service_nodes_list }}" loop_control: loop_var: __gateway_service_nodes_item @@ -24,7 +24,7 @@ register: __gateway_service_nodes_job_async changed_when: not __gateway_service_nodes_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Service Nodes | Wait for finish the configuration ansible.builtin.async_status: @@ -39,5 +39,5 @@ when: __gateway_service_nodes_job_async_results_item.ansible_job_id is defined no_log: "{{ service_nodes_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_services/README.md b/roles/gateway_services/README.md index 1b74429b1..5cb81bff4 100644 --- a/roles/gateway_services/README.md +++ b/roles/gateway_services/README.md @@ -15,10 +15,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:--------------------------------------------------|:---------------------------------------------------:|:--------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `services_list` (Alias: services) | [below](#service-arguments) | yes | Data structure describing your service entries described below. | [more](../../README.md#data-variables) | -| `services_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `services_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service role. | [more](../../README.md#enforcing-defaults) | -| `services_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `services_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `services_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive service role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `services_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the service role. | [more](../../README.md#enforcing-defaults) | +| `services_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `services_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -32,8 +32,8 @@ Options for the `services_list` variable: | `new_name` | N/A | no | str | Setting this option will change the existing name (looked up via the name field) | | `description` | "" | no | str | Description of the service | | `api_slug` | "" | no | str | URL slug for the gateway API path for the Controller, Hub and EDA services (gateway API route requires value "gateway", but the slug is not used) | -| `http_port` | N/A | no | str | ID or name referencing the [Http Port](../gateway_http_ports/README.md) | -| `service_cluster` | N/A | no | str | ID or name referencing the [Service Cluster](../gateway_service_clusters/README.md) | +| `http_port` | N/A | no | str | ID or name referencing the [Http Port](../http_ports/README.md) | +| `service_cluster` | N/A | no | str | ID or name referencing the [Service Cluster](../service_clusters/README.md) | | `is_service_https` | `false` | no | bool | Flag whether or not the service cluster uses https | | `enable_gateway_auth` | N/A (`true` by API) | no | bool | If false, the AAP gateway will not insert a gateway token into the proxied request | | `service_path` | "" | no | str | URL path on the AAP Service cluster to route traffic to | @@ -112,4 +112,4 @@ ansible-playbook manage_data.yml -e @data/gateway_services.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_services/defaults/main.yml b/roles/gateway_services/defaults/main.yml index 307053d0c..0ca764656 100644 --- a/roles/gateway_services/defaults/main.yml +++ b/roles/gateway_services/defaults/main.yml @@ -10,8 +10,8 @@ # a list of dictionaries describing the services services_list: [] -services_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -services_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -services_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -services_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +services_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +services_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +services_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +services_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_services/meta/argument_specs.yml b/roles/gateway_services/meta/argument_specs.yml index 1597c0b11..ced7b49e6 100644 --- a/roles/gateway_services/meta/argument_specs.yml +++ b/roles/gateway_services/meta/argument_specs.yml @@ -67,22 +67,22 @@ argument_specs: # Async variables services_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. services_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -92,47 +92,53 @@ argument_specs: # No_log variables services_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_services/tasks/main.yml b/roles/gateway_services/tasks/main.yml index 3d90b50c9..2966e7b0c 100644 --- a/roles/gateway_services/tasks/main.yml +++ b/roles/gateway_services/tasks/main.yml @@ -16,12 +16,12 @@ state: "{{ __gateway_services_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ services if services is defined else services_list }}" loop_control: loop_var: __gateway_services_item @@ -31,7 +31,7 @@ register: __gateway_services_job_async changed_when: not __gateway_services_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Services | Wait for finish the configuration ansible.builtin.async_status: @@ -46,5 +46,5 @@ when: __gateway_services_job_async_results_item.ansible_job_id is defined no_log: "{{ services_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_settings/README.md b/roles/gateway_settings/README.md index 922a72ed7..e60a5540d 100644 --- a/roles/gateway_settings/README.md +++ b/roles/gateway_settings/README.md @@ -1,6 +1,6 @@ # Ansible Role infra.platform_configuration.settings -An Ansible role to alter Settings on Ansible Automation Gateway. +An Ansible role to alter Settings on Ansible Automation gateway settings. ## Variables @@ -11,10 +11,10 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:------------------------------------------------|:--------------------------------------------------:|:--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| -| `gateway_settings` | [below](#settings-arguments) | yes | Data structure describing your setting entries described below. | [more](../../README.md#data-variables) | -| `gateway_settings_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive settings role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `gateway_settings_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `gateway_settings_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `settings_list` (Alias: `settings`) | [below](#settings-arguments) | yes | Data structure describing your setting entries described below. | [more](../../README.md#data-variables) | +| `settings_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive settings role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `settings_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `settings_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | **Note**: Secure Logging defaults to `True` if both variables are not set @@ -30,7 +30,7 @@ Provide settings as a single dict under `settings_list`. ```json { - "gateway_settings": { + "settings_list": { "gateway_token_name": "X-DAB-JW-TOKEN", "gateway_access_token_expiration": 600, "gateway_basic_auth_enabled": true, @@ -52,7 +52,7 @@ File name: `data/gateway_settings.yml` ```yaml --- -gateway_settings: +settings_list: gateway_token_name: X-DAB-JW-TOKEN gateway_access_token_expiration: 600 gateway_basic_auth_enabled: true @@ -77,4 +77,4 @@ ansible-playbook manage_data.yml -e @data/gateway_settings.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_settings/defaults/main.yml b/roles/gateway_settings/defaults/main.yml index 42c07f28d..bd962657b 100644 --- a/roles/gateway_settings/defaults/main.yml +++ b/roles/gateway_settings/defaults/main.yml @@ -1,7 +1,7 @@ --- # list of dicts (or a single dict) describing the gateway settings -gateway_settings: {} -gateway_settings_secure_logging: "{{ platform_configuration_secure_logging | default('false') }}" -gateway_settings_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -gateway_settings_async_delay: "{{ platform_configuration_async_delay | default(1) }}" +settings_list: [] +settings_secure_logging: "{{ gateway_configuration_secure_logging | default('false') }}" +settings_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +settings_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" ... diff --git a/roles/gateway_settings/meta/argument_specs.yml b/roles/gateway_settings/meta/argument_specs.yml index 6c6fd80ff..0bd10a9f4 100644 --- a/roles/gateway_settings/meta/argument_specs.yml +++ b/roles/gateway_settings/meta/argument_specs.yml @@ -3,7 +3,7 @@ argument_specs: main: short_description: An Ansible Role to create settings on automation platform gateway. options: - gateway_settings: + settings_list: description: >- Data structure describing your settings. Type is list if providing name/value and type dict if providing settings. @@ -11,22 +11,22 @@ argument_specs: type: raw # Async variables settings_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. settings_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -36,47 +36,53 @@ argument_specs: # No_log variables settings_secure_logging: - default: "{{ platform_configuration_secure_logging | default(true) }}" + default: "{{ gateway_configuration_secure_logging | default(true) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_settings/tasks/main.yml b/roles/gateway_settings/tasks/main.yml index 1fcdbfa15..653e47793 100644 --- a/roles/gateway_settings/tasks/main.yml +++ b/roles/gateway_settings/tasks/main.yml @@ -2,15 +2,15 @@ # tasks file for gateway_settings - name: Update automation platform gateway Settings ansible.platform.settings: - settings: "{{ gateway_settings | default(omit, true) }}" + settings: "{{ settings_list | default(omit, true) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" - no_log: "{{ gateway_settings_secure_logging }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, true) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" + no_log: "{{ settings_secure_logging }}" register: __gateway_setting_job ... diff --git a/roles/gateway_teams/README.md b/roles/gateway_teams/README.md index 62f6964a9..68a1dc04f 100644 --- a/roles/gateway_teams/README.md +++ b/roles/gateway_teams/README.md @@ -12,11 +12,11 @@ Variables specific for this role are following: | Variable Name | Default Value | Required | Description | | |:-----------------------------------------------|:---------------------------------------------------:|:--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| -| `platform_teams` (Alias: `teams`) | [below](#organization-arguments) | yes | Data structure describing your team entries described below. | [more](../../README.md#data-variables) | -| `platform_teams_secure_logging` | `platform_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive team role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `platform_teams_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the team role. | [more](../../README.md#enforcing-defaults) | -| `platform_teams_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `platform_teams_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `teams_list` (Alias: `teams`) | [below](#organization-arguments) | yes | Data structure describing your team entries described below. | [more](../../README.md#data-variables) | +| `teams_secure_logging` | `gateway_configuration_secure_logging` OR `false` | no | Whether or not to include the sensitive team role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `teams_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the team role. | [more](../../README.md#enforcing-defaults) | +| `teams_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `teams_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | ## Data Structure @@ -92,4 +92,4 @@ ansible-playbook manage_data.yml -e @data/gateway_teams.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_teams/defaults/main.yml b/roles/gateway_teams/defaults/main.yml index b635945fd..169f763a0 100644 --- a/roles/gateway_teams/defaults/main.yml +++ b/roles/gateway_teams/defaults/main.yml @@ -9,9 +9,9 @@ # These are the default variables specific to the license role # a list of dictionaries describing the teams -platform_teams: [] -platform_teams_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -platform_teams_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -platform_teams_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_teams_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +teams_list: [] +teams_secure_logging: "{{ gateway_configuration_secure_logging | default(false) }}" +teams_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +teams_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +teams_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_teams/meta/argument_specs.yml b/roles/gateway_teams/meta/argument_specs.yml index 78fc685fc..5b3207683 100644 --- a/roles/gateway_teams/meta/argument_specs.yml +++ b/roles/gateway_teams/meta/argument_specs.yml @@ -3,7 +3,7 @@ argument_specs: main: short_description: An Ansible Role to create teams on automation platform gateway. options: - platform_teams: + teams_list: description: Data structure describing your teams type: list required: true @@ -33,23 +33,23 @@ argument_specs: description: Desired state of the resource. # Async variables - platform_teams_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + teams_async_retries: + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. - platform_teams_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + teams_async_delay: + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -58,48 +58,54 @@ argument_specs: # No_log variables - platform_teams_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + teams_secure_logging: + default: "{{ gateway_configuration_secure_logging | default(false) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: user on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_teams/tasks/main.yml b/roles/gateway_teams/tasks/main.yml index af688d8a3..ad6553bec 100644 --- a/roles/gateway_teams/tasks/main.yml +++ b/roles/gateway_teams/tasks/main.yml @@ -9,35 +9,35 @@ state: "{{ __gateway_teams_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, 10) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" - loop: "{{ platform_teams }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, 10) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" + loop: "{{ teams if teams is defined else teams_list }}" loop_control: loop_var: __gateway_teams_item - no_log: "{{ platform_teams_secure_logging }}" + no_log: "{{ teams_secure_logging }}" async: 1000 poll: 0 register: __gateway_teams_job_async changed_when: not __gateway_teams_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Teams | Wait for finish the configuration ansible.builtin.async_status: jid: "{{ __gateway_teams_job_async_results_item.ansible_job_id }}" register: __gateway_teams_job_async_result until: __gateway_teams_job_async_result.finished - retries: "{{ platform_teams_async_retries }}" - delay: "{{ platform_teams_async_delay }}" + retries: "{{ teams_async_retries }}" + delay: "{{ teams_async_delay }}" loop: "{{ __gateway_teams_job_async.results }}" loop_control: loop_var: __gateway_teams_job_async_results_item when: __gateway_teams_job_async_results_item.ansible_job_id is defined - no_log: "{{ platform_teams_secure_logging }}" + no_log: "{{ teams_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/gateway_users/README.md b/roles/gateway_users/README.md index 36227794b..175311a6f 100644 --- a/roles/gateway_users/README.md +++ b/roles/gateway_users/README.md @@ -9,10 +9,10 @@ An Ansible Role to configure users on Ansible Automation gateway. | Variable Name | Default Value | Required | Description | | |:--------------------------------------------------|:---------------------------------------------------:|:--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------:| | `users_list` (Alias: `users`) | [below](#user-arguments) | yes | Data structure describing your user entries described below. | [more](../../README.md#data-variables) | -| `users_secure_logging` | `platform_configuration_secure_logging` OR `true` | no | Whether or not to include the sensitive user role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | -| `users_enforce_defaults` | `platform_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the user role. | [more](../../README.md#enforcing-defaults) | -| `users_async_retries` | `platform_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | -| `users_async_delay` | `platform_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `users_secure_logging` | `gateway_configuration_secure_logging` OR `true` | no | Whether or not to include the sensitive user role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere. | [more](../../README.md#secure-logging-variables) | +| `users_enforce_defaults` | `gateway_configuration_enforce_defaults` OR `false` | no | Whether or not to enforce default option values on only the user role. | [more](../../README.md#enforcing-defaults) | +| `users_async_retries` | `gateway_configuration_async_retries` OR `30` | no | This variable sets the number of retries to attempt for the role. | [more](../../README.md#asynchronous-retry-variables) | +| `users_async_delay` | `gateway_configuration_async_delay` OR `1` | no | This sets the delay between retries for the role. | [more](../../README.md#asynchronous-retry-variables) | | `users_default_password` | "" | no | Global variable to set the password for all users. | | **Note**: Secure Logging defaults to True if both variables are not set @@ -89,4 +89,4 @@ ansible-playbook manage_data.yml -e @data/gateway_users.yml ## License -[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) +[GPLv3](https://github.com/ansible/aap-gateway/gateway_configuration_collection/COPYING) diff --git a/roles/gateway_users/defaults/main.yml b/roles/gateway_users/defaults/main.yml index 4542ed07f..a522c6935 100644 --- a/roles/gateway_users/defaults/main.yml +++ b/roles/gateway_users/defaults/main.yml @@ -25,8 +25,8 @@ users_list: [] users_default_password: change_me -users_secure_logging: "{{ platform_configuration_secure_logging | default('true') }}" -users_async_retries: "{{ platform_configuration_async_retries | default(30) }}" -users_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -users_enforce_defaults: "{{ platform_configuration_enforce_defaults | default(false) }}" +users_secure_logging: "{{ gateway_configuration_secure_logging | default('true') }}" +users_async_retries: "{{ gateway_configuration_async_retries | default(30) }}" +users_async_delay: "{{ gateway_configuration_async_delay | default(1) }}" +users_enforce_defaults: "{{ gateway_configuration_enforce_defaults | default(false) }}" ... diff --git a/roles/gateway_users/meta/argument_specs.yml b/roles/gateway_users/meta/argument_specs.yml index 1a38794c2..eb42cddfd 100644 --- a/roles/gateway_users/meta/argument_specs.yml +++ b/roles/gateway_users/meta/argument_specs.yml @@ -67,22 +67,22 @@ argument_specs: # Async variables users_async_retries: - default: "{{ platform_configuration_async_retries | default(30) }}" + default: "{{ gateway_configuration_async_retries | default(30) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + gateway_configuration_async_retries: default: 30 required: false description: This variable sets number of retries across all roles as a default. users_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ gateway_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + gateway_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + gateway_configuration_async_dir: default: null required: false description: > @@ -92,47 +92,53 @@ argument_specs: # No_log variables users_secure_logging: - default: "{{ platform_configuration_secure_logging | default(true) }}" + default: "{{ gateway_configuration_secure_logging | default(true) }}" required: false type: bool description: > Whether or not to include the sensitive tasks from this role in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + gateway_configuration_secure_logging: default: true required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_state: + gateway_state: default: present required: false description: The state all objects will take unless overridden by object default type: str - platform_hostname: + gateway_hostname: default: None required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the automation platform gateway. type: str - platform_validate_certs: + gateway_validate_certs: default: true required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the automation platform gateway's SSL certificate. type: str - platform_username: + gateway_username: default: None required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User on the automation platform gateway. Either username / password or oauthtoken need to be specified. type: str - platform_password: + gateway_password: default: None required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's password on the automation platform gateway. + This should be stored in an Ansible Vault at vars/gateway-secrets.yml or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str - platform_token: + gateway_oauthtoken: default: None required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: > + Gateway user's token on the automation platform gateway. + This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. + Either username / password or oauthtoken need to be specified. type: str ... diff --git a/roles/gateway_users/tasks/main.yml b/roles/gateway_users/tasks/main.yml index 335c7f2ea..649650ca5 100644 --- a/roles/gateway_users/tasks/main.yml +++ b/roles/gateway_users/tasks/main.yml @@ -15,12 +15,12 @@ state: "{{ __gateway_user_accounts_item.state | default(gateway_state | default(omit, true)) }}" # Role Standard Options - gateway_hostname: "{{ platform_hostname | default(omit, true) }}" - gateway_username: "{{ platform_username | default(omit, true) }}" - gateway_password: "{{ platform_password | default(omit, true) }}" - gateway_token: "{{ platform_token | default(omit, true) }}" - gateway_request_timeout: "{{ platform_request_timeout | default(omit, true) }}" - gateway_validate_certs: "{{ platform_validate_certs | default(omit) }}" + gateway_hostname: "{{ gateway_hostname | default(omit, true) }}" + gateway_username: "{{ gateway_username | default(omit, true) }}" + gateway_password: "{{ gateway_password | default(omit, true) }}" + gateway_token: "{{ gateway_oauthtoken | default(omit, true) }}" + gateway_request_timeout: "{{ gateway_request_timeout | default(omit, true) }}" + gateway_validate_certs: "{{ gateway_validate_certs | default(omit) }}" loop: "{{ users if users is defined else users_list }}" loop_control: loop_var: __gateway_user_accounts_item @@ -30,7 +30,7 @@ register: __gateway_user_accounts_job_async changed_when: not __gateway_user_accounts_job_async.changed vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" - name: Users | Wait for finish the configuration ansible.builtin.async_status: @@ -45,5 +45,5 @@ when: __gateway_user_accounts_job_async_results_item.ansible_job_id is defined no_log: "{{ users_secure_logging }}" vars: - ansible_async_dir: "{{ platform_configuration_async_dir | default(omit) }}" + ansible_async_dir: "{{ gateway_configuration_async_dir | default(omit) }}" ... diff --git a/roles/ansible_config/README.md b/roles/hub_ansible_config/README.md similarity index 79% rename from roles/ansible_config/README.md rename to roles/hub_ansible_config/README.md index 2aab59bda..80f770d91 100644 --- a/roles/ansible_config/README.md +++ b/roles/hub_ansible_config/README.md @@ -19,7 +19,7 @@ Currently: |`ansible_config_group`|""|no|str|The group the resulting ansible config file or directory should have.| |`ah_configuration_working_dir`|"/var/tmp"|no|path|Location to render the ansible config file to.| |`automation_hub_list`|`[]`|no|list|A list of Automation hubs and galaxies to put in the ansible config, see below for details.| -|`ansible_config_list`|`[{"header":"galaxy","keypairs":[{"key":"ignore_certs","value":"{{ not (platform_validate_certs \| bool) }}"}]}]`|no|list|A set of ansible config settings, a default is set, but can be overridden, see below for details.| +|`ansible_config_list`|`[{"header":"galaxy","keypairs":[{"key":"ignore_certs","value":"{{ not (ah_validate_certs \| bool) }}"}]}]`|no|list|A set of ansible config settings, a default is set, but can be overridden, see below for details.| |`ah_token`|""|no|Tower Admin User's token on the Automation Hub Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook.|| |`ah_path_prefix`|`galaxy`|no|Tower Admin User's token on the Automation Hub Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook.|| @@ -28,12 +28,12 @@ Currently: The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the ansible config task does not by default include sensitive information, we highly recommend the use of ansible vault for passwords and tokens. -platform_configuration_ansible_config_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ansible_config_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_ansible_config_secure_logging`|`False`|no|Whether or not to include the sensitive ansible config role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_ansible_config_secure_logging`|`False`|no|Whether or not to include the sensitive ansible config role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structures @@ -70,7 +70,7 @@ ansible_config_list: - header: galaxy keypairs: - key: ignore_certs - value: "{{ not (platform_validate_certs | bool) }}" + value: "{{ not (ah_validate_certs | bool) }}" - key: server_list value: "{{ automation_hub_list | map(attribute='name') | join(',') }}" @@ -92,7 +92,7 @@ automation_hub_list: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/ansible_config/defaults/main.yml b/roles/hub_ansible_config/defaults/main.yml similarity index 81% rename from roles/ansible_config/defaults/main.yml rename to roles/hub_ansible_config/defaults/main.yml index 50223b9f1..de89f5f0c 100644 --- a/roles/ansible_config/defaults/main.yml +++ b/roles/hub_ansible_config/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the ansible config role # ansible_config_owner: # optional @@ -27,9 +27,9 @@ ansible_config_list: - header: galaxy keypairs: - key: ignore_certs - value: "{{ not (platform_validate_certs | default(true) | bool) }}" + value: "{{ not (ah_validate_certs | default(true) | bool) }}" # - key: server_list # value: "{{ automation_hub_list | map(attribute="name") | join(",") }}" -platform_configuration_ansible_config_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" +ah_configuration_ansible_config_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" ... diff --git a/roles/ansible_config/meta/argument_specs.yml b/roles/hub_ansible_config/meta/argument_specs.yml similarity index 92% rename from roles/ansible_config/meta/argument_specs.yml rename to roles/hub_ansible_config/meta/argument_specs.yml index d9fe86d18..dd8998472 100644 --- a/roles/ansible_config/meta/argument_specs.yml +++ b/roles/hub_ansible_config/meta/argument_specs.yml @@ -59,7 +59,7 @@ argument_specs: - header: galaxy keypairs: - key: ignore_certs - value: "{{ not (platform_validate_certs | default(true) | bool) }}" + value: "{{ not (ah_validate_certs | default(true) | bool) }}" required: false type: list description: A set of ansible config settings, a default is set, but can be overridden. @@ -86,12 +86,12 @@ argument_specs: description: Value for entry for the corresponding key. # No_log variables - platform_configuration_ansible_config_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + ah_configuration_ansible_config_secure_logging: + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool diff --git a/roles/ansible_config/meta/main.yml b/roles/hub_ansible_config/meta/main.yml similarity index 95% rename from roles/ansible_config/meta/main.yml rename to roles/hub_ansible_config/meta/main.yml index 768a65e75..06f4bda5b 100644 --- a/roles/ansible_config/meta/main.yml +++ b/roles/hub_ansible_config/meta/main.yml @@ -1,6 +1,6 @@ --- galaxy_info: - role_name: "ansible_config" + role_name: "namespace" author: "Sean Sullivan" description: "An Ansible Role to create namespace in Automation Hub." company: "Red Hat" @@ -33,8 +33,8 @@ galaxy_info: - "automationhub" - "galaxy" - "configuration" - - "ansible" - - "config" + - "namespace" + - "namespaces" dependencies: [] # List your role dependencies here, one per line. Be sure to remove the '[]' above, diff --git a/roles/ansible_config/tasks/main.yml b/roles/hub_ansible_config/tasks/main.yml similarity index 82% rename from roles/ansible_config/tasks/main.yml rename to roles/hub_ansible_config/tasks/main.yml index 7a31100af..710c0a446 100644 --- a/roles/ansible_config/tasks/main.yml +++ b/roles/hub_ansible_config/tasks/main.yml @@ -7,5 +7,5 @@ owner: "{{ ansible_config_owner | default(omit) }}" group: "{{ ansible_config_group | default(omit) }}" mode: "{{ ansible_config_mode }}" - no_log: "{{ platform_configuration_ansible_config_secure_logging }}" + no_log: "{{ ah_configuration_ansible_config_secure_logging }}" ... diff --git a/roles/ansible_config/templates/ansible.cfg.j2 b/roles/hub_ansible_config/templates/ansible.cfg.j2 similarity index 100% rename from roles/ansible_config/templates/ansible.cfg.j2 rename to roles/hub_ansible_config/templates/ansible.cfg.j2 diff --git a/roles/ansible_config/tests/test.yml b/roles/hub_ansible_config/tests/test.yml similarity index 77% rename from roles/ansible_config/tests/test.yml rename to roles/hub_ansible_config/tests/test.yml index 72a6e1472..182db9446 100644 --- a/roles/ansible_config/tests/test.yml +++ b/roles/hub_ansible_config/tests/test.yml @@ -1,10 +1,10 @@ --- -- name: Create ansible config to Automation Platform +- name: Add namespace to Automation Hub hosts: localhost connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme @@ -16,5 +16,5 @@ tags: - always roles: - - ../../ansible_config + - ../../namespace ... diff --git a/roles/ansible_config/tests/vars/config.yml b/roles/hub_ansible_config/tests/vars/config.yml similarity index 100% rename from roles/ansible_config/tests/vars/config.yml rename to roles/hub_ansible_config/tests/vars/config.yml diff --git a/roles/hub_collection/README.md b/roles/hub_collection/README.md index e366377e2..4a57fce34 100644 --- a/roles/hub_collection/README.md +++ b/roles/hub_collection/README.md @@ -9,12 +9,12 @@ An Ansible Role to update, or destroy Automation Hub Collections. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_collections`|`see below`|yes|Data structure describing your collections, described below.|| These are the sub options for the vars `ah_collections` which are dictionaries with the options you want. See examples for details. @@ -31,7 +31,7 @@ These are the sub options for the vars `ah_collections` which are dictionaries w |`overwrite_existing`|"false"|no|Overwrites an existing collection and requires version to be set.|| |`state`|"present"|no|Desired state of the resource|| -The `platform_configuration_async_dir` variable sets the directory to write the results file for async tasks. +The `ah_configuration_async_dir` variable sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. ### Asynchronous Retry Variables @@ -43,24 +43,24 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_collection_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_collection_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_collection_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_collection_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_collection_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_collection_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ### Secure Logging Variables The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add repository task does not include sensitive information. -ah_configuration_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_collection_secure_logging`|`False`|no|Whether or not to include the sensitive collection role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ## Data Structure @@ -93,7 +93,7 @@ ah_collections: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_collection/defaults/main.yml b/roles/hub_collection/defaults/main.yml index 9b6e91c55..66541d296 100644 --- a/roles/hub_collection/defaults/main.yml +++ b/roles/hub_collection/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the collection role ah_collections: [] @@ -18,9 +18,9 @@ ah_collections: [] # - overwrite_existing # - state -ah_configuration_collection_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_collection_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_collection_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_collection_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_collection_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_collection_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_collection_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_collection_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_collection/meta/argument_specs.yml b/roles/hub_collection/meta/argument_specs.yml index 99be3d3c4..f9895cc5a 100644 --- a/roles/hub_collection/meta/argument_specs.yml +++ b/roles/hub_collection/meta/argument_specs.yml @@ -12,70 +12,65 @@ argument_specs: # Async variables ah_configuration_collection_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_collection_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_collection_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str - platform_token: - default: None + ah_token: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Automation Hub token for authentication. type: str ... diff --git a/roles/hub_collection/tasks/main.yml b/roles/hub_collection/tasks/main.yml index edc8bd269..838547d20 100644 --- a/roles/hub_collection/tasks/main.yml +++ b/roles/hub_collection/tasks/main.yml @@ -1,18 +1,17 @@ # Update or destroy Automation Hub Collection --- -# Test if this is still needed -# - name: Get token -# ansible.hub.ah_token: -# ah_host: "{{ platform_hostname | default(omit) }}" -# ah_hostname: "{{ platform_username | default(omit) }}" -# ah_password: "{{ platform_password | default(omit) }}" -# ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" -# validate_certs: "{{ platform_validate_certs | default(omit) }}" -# request_timeout: "{{ platform_request_timeout | default(omit) }}" -# when: -# - ah_token is not defined -# - lookup("ansible.builtin.env", "AH_API_TOKEN") == "" -# - ah_collections | length > 1 +- name: Get token + ansible.hub.ah_token: + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" + ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" + when: + - ah_token is not defined + - lookup("ansible.builtin.env", "AH_API_TOKEN") == "" + - ah_collections | length > 1 - name: Update or destroy Automation Hub Collection ansible.hub.ah_collection: @@ -27,13 +26,13 @@ interval: "{{ __collection.interval | default(omit) }}" overwrite_existing: "{{ __collection.overwrite_existing | default(omit) }}" state: "{{ __collection.state | default('present') }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" - ah_token: "{{ platform_token | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" + ah_token: "{{ ah_token | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collections }}" loop_control: loop_var: "__collection" @@ -43,7 +42,7 @@ register: __collections_job_async changed_when: not __collections_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: Sleep for 10 seconds and continue with play ansible.builtin.wait_for: @@ -62,5 +61,5 @@ when: __collections_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_collection_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_collection/tests/test.yml b/roles/hub_collection/tests/test.yml index e9be8c933..dbd972fc3 100644 --- a/roles/hub_collection/tests/test.yml +++ b/roles/hub_collection/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_collection_remote/README.md b/roles/hub_collection_remote/README.md index 8f5ebe460..6adf27dc1 100644 --- a/roles/hub_collection_remote/README.md +++ b/roles/hub_collection_remote/README.md @@ -9,15 +9,15 @@ An Ansible Role to create a Collection Remote Repository. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_collection_remotes`|`see below`|yes|Data structure describing your collection remote repository, described below.|| -The `platform_configuration_async_dir` variable sets the directory to write the results file for async tasks. +The `ah_configuration_async_dir` variable sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. ### Secure Logging Variables @@ -25,12 +25,12 @@ The default value is set to `null` which uses the Ansible Default of `/root/.an The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add repository task does not include sensitive information. -ah_configuration_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_collection_remote_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -41,12 +41,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_collection_remote_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_collection_remote_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_collection_remote_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_collection_remote_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_collection_remote_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_collection_remote_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -106,7 +106,7 @@ ah_collection_remotes: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_collection_remote/defaults/main.yml b/roles/hub_collection_remote/defaults/main.yml index e70fce53a..c1f02ff10 100644 --- a/roles/hub_collection_remote/defaults/main.yml +++ b/roles/hub_collection_remote/defaults/main.yml @@ -4,12 +4,12 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role -ah_configuration_collection_remote_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_collection_remote_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_collection_remote_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_collection_remote_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_collection_remote_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_collection_remote_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_collection_remote_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_collection_remote_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_collection_remote/meta/argument_specs.yml b/roles/hub_collection_remote/meta/argument_specs.yml index 56c68abd8..59559d752 100644 --- a/roles/hub_collection_remote/meta/argument_specs.yml +++ b/roles/hub_collection_remote/meta/argument_specs.yml @@ -23,55 +23,50 @@ argument_specs: description: Information regarding the proxy that AH will use to communicate to the Red Hat repositories. Can be left empty if no proxy used. # Async variables - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_collection_remote_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str - platform_token: - default: None + ah_token: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Automation Hub token for authentication. type: str ... diff --git a/roles/hub_collection_remote/tasks/main.yml b/roles/hub_collection_remote/tasks/main.yml index 9c1b28a91..bac66d1e5 100644 --- a/roles/hub_collection_remote/tasks/main.yml +++ b/roles/hub_collection_remote/tasks/main.yml @@ -27,12 +27,12 @@ proxy_username: "{{ __collection_remote_item.proxy_username | default(proxy_username | default(omit)) }}" proxy_password: "{{ __collection_remote_item.proxy_password | default(proxy_password | default(omit)) }}" state: "{{ __collection_remote_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collection_remotes }}" loop_control: loop_var: "__collection_remote_item" @@ -42,7 +42,7 @@ register: __collection_remote_job_async changed_when: not __collection_remote_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Repository | Wait for finish the repository creation" ansible.builtin.async_status: @@ -57,6 +57,6 @@ when: __collection_remote_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_collection_remote_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_collection_remote/tests/test.yml b/roles/hub_collection_remote/tests/test.yml index 8b9b86383..57f6dab55 100644 --- a/roles/hub_collection_remote/tests/test.yml +++ b/roles/hub_collection_remote/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_collection_repository/README.md b/roles/hub_collection_repository/README.md index aa58ff172..656f22510 100644 --- a/roles/hub_collection_repository/README.md +++ b/roles/hub_collection_repository/README.md @@ -9,15 +9,15 @@ An Ansible Role to create a Collection Repository. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_collection_repositories`|`see below`|yes|Data structure describing your collection remote repository, described below.|| -The `platform_configuration_async_dir` variable sets the directory to write the results file for async tasks. +The `ah_configuration_async_dir` variable sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. ### Secure Logging Variables @@ -25,12 +25,12 @@ The default value is set to `null` which uses the Ansible Default of `/root/.an The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add repository task does not include sensitive information. -ah_configuration_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_collection_repository_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -41,12 +41,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_collection_repository_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_collection_repository_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_collection_repository_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_collection_repository_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_collection_repository_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_collection_repository_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -114,7 +114,7 @@ ah_collection_repositories: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_collection_repository/defaults/main.yml b/roles/hub_collection_repository/defaults/main.yml index 8763dc388..8b7153cc7 100644 --- a/roles/hub_collection_repository/defaults/main.yml +++ b/roles/hub_collection_repository/defaults/main.yml @@ -4,12 +4,12 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role -ah_configuration_collection_repository_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_collection_repository_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_collection_repository_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_collection_repository_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_collection_repository_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_collection_repository_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_collection_repository_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_collection_repository_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_collection_repository/meta/argument_specs.yml b/roles/hub_collection_repository/meta/argument_specs.yml index e10567cb1..95dbdbaa1 100644 --- a/roles/hub_collection_repository/meta/argument_specs.yml +++ b/roles/hub_collection_repository/meta/argument_specs.yml @@ -11,55 +11,50 @@ argument_specs: elements: dict # Async variables - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_collection_repository_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str - platform_token: - default: None + ah_token: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Automation Hub token for authentication. type: str ... diff --git a/roles/hub_collection_repository/tasks/main.yml b/roles/hub_collection_repository/tasks/main.yml index 6a3d87eae..0a7164151 100644 --- a/roles/hub_collection_repository/tasks/main.yml +++ b/roles/hub_collection_repository/tasks/main.yml @@ -14,12 +14,12 @@ interval: "{{ __collection_repository_item.interval | default(1) }}" timeout: "{{ __collection_repository_item.timeout | default(omit) }}" state: "{{ __collection_repository_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collection_repositories }}" loop_control: loop_var: "__collection_repository_item" @@ -29,7 +29,7 @@ register: __collection_repository_job_async changed_when: not __collection_repository_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Repository | Wait for finish the repository creation" ansible.builtin.async_status: @@ -44,6 +44,6 @@ when: __collection_repository_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_collection_repository_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_collection_repository/tests/test.yml b/roles/hub_collection_repository/tests/test.yml index 4c26a6d6d..99d0ada63 100644 --- a/roles/hub_collection_repository/tests/test.yml +++ b/roles/hub_collection_repository/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_collection_repository_sync/README.md b/roles/hub_collection_repository_sync/README.md index 890f0a353..fc077db57 100644 --- a/roles/hub_collection_repository_sync/README.md +++ b/roles/hub_collection_repository_sync/README.md @@ -9,15 +9,15 @@ An Ansible Role to sync a Collection Repository. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_collection_repositories`|`see below`|yes|Data structure describing your collection remote repository, described below.|| -The `platform_configuration_async_dir` variable sets the directory to write the results file for async tasks. +The `ah_configuration_async_dir` variable sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. ### Secure Logging Variables @@ -25,12 +25,12 @@ The default value is set to `null` which uses the Ansible Default of `/root/.an The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add repository task does not include sensitive information. -ah_configuration_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_collection_repository_sync_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -41,12 +41,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_collection_repository_sync_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_collection_repository_sync_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_collection_repository_sync_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_collection_repository_sync_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_collection_repository_sync_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_collection_repository_sync_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -85,7 +85,7 @@ ah_collection_repositories: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_collection_repository_sync/defaults/main.yml b/roles/hub_collection_repository_sync/defaults/main.yml index 5af19d54c..8ca8ff22f 100644 --- a/roles/hub_collection_repository_sync/defaults/main.yml +++ b/roles/hub_collection_repository_sync/defaults/main.yml @@ -4,12 +4,12 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role -ah_configuration_collection_repository_sync_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_collection_repository_sync_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_collection_repository_sync_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_collection_repository_sync_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_collection_repository_sync_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_collection_repository_sync_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_collection_repository_sync_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_collection_repository_sync_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_collection_repository_sync/meta/argument_specs.yml b/roles/hub_collection_repository_sync/meta/argument_specs.yml index e10567cb1..95dbdbaa1 100644 --- a/roles/hub_collection_repository_sync/meta/argument_specs.yml +++ b/roles/hub_collection_repository_sync/meta/argument_specs.yml @@ -11,55 +11,50 @@ argument_specs: elements: dict # Async variables - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_collection_repository_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str - platform_token: - default: None + ah_token: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Automation Hub token for authentication. type: str ... diff --git a/roles/hub_collection_repository_sync/tasks/main.yml b/roles/hub_collection_repository_sync/tasks/main.yml index 2004abc41..d1c3efa62 100644 --- a/roles/hub_collection_repository_sync/tasks/main.yml +++ b/roles/hub_collection_repository_sync/tasks/main.yml @@ -6,12 +6,12 @@ wait: "{{ __collection_repository_sync_item.wait | default(omit) }}" interval: "{{ __collection_repository_sync_item.interval | default(1) }}" timeout: "{{ __collection_repository_sync_item.timeout | default(omit) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collection_repositories }}" loop_control: loop_var: "__collection_repository_sync_item" @@ -21,7 +21,7 @@ register: __collection_repository_sync_job_async changed_when: not __collection_repository_sync_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Sync Repository | Wait for finish the repository sync" ansible.builtin.async_status: @@ -36,6 +36,6 @@ when: __collection_repository_sync_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_collection_repository_sync_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_collection_repository_sync/tests/test.yml b/roles/hub_collection_repository_sync/tests/test.yml index 4c26a6d6d..99d0ada63 100644 --- a/roles/hub_collection_repository_sync/tests/test.yml +++ b/roles/hub_collection_repository_sync/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_image/README.md b/roles/hub_ee_image/README.md index 4729e2cf8..ac6ee411e 100644 --- a/roles/hub_ee_image/README.md +++ b/roles/hub_ee_image/README.md @@ -9,12 +9,12 @@ An Ansible Role to create execution environment images in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_images`|`see below`|yes|Data structure describing your execution environment images, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to create execution environment images in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_image task does not include sensitive information. -ah_configuration_ee_image_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_image_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_image_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_image_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_image_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_image_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_image_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_image_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_image_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -83,7 +83,7 @@ ah_ee_images: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_image/defaults/main.yml b/roles/hub_ee_image/defaults/main.yml index 1f4444967..27eafcbd6 100644 --- a/roles/hub_ee_image/defaults/main.yml +++ b/roles/hub_ee_image/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -19,9 +19,9 @@ ah_ee_images: [] # - "2.0" # - prod1 -ah_configuration_ee_image_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_image_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_image_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_image_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_image_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_image_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_image_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_image_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_image/meta/argument_specs.yml b/roles/hub_ee_image/meta/argument_specs.yml index 50941660f..7c9480b7a 100644 --- a/roles/hub_ee_image/meta/argument_specs.yml +++ b/roles/hub_ee_image/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_image_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_image_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_image_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_image/tasks/main.yml b/roles/hub_ee_image/tasks/main.yml index e42825924..c07ade827 100644 --- a/roles/hub_ee_image/tasks/main.yml +++ b/roles/hub_ee_image/tasks/main.yml @@ -8,12 +8,12 @@ append: "{{ __ee_image_item.append | default(omit) }}" tags: "{{ __ee_image_item.tags | default(omit) }}" state: "{{ __ee_image_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_images }}" loop_control: loop_var: "__ee_image_item" @@ -23,7 +23,7 @@ register: __ee_images_job_async changed_when: not __ee_images_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create EE Image | Wait for finish the ee_image creation" ansible.builtin.async_status: @@ -38,5 +38,5 @@ when: __ee_images_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_image_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_image/tests/test.yml b/roles/hub_ee_image/tests/test.yml index c6ba1ba62..13909ba2a 100644 --- a/roles/hub_ee_image/tests/test.yml +++ b/roles/hub_ee_image/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_namespace/README.md b/roles/hub_ee_namespace/README.md index 42b041118..7d8fe15d2 100644 --- a/roles/hub_ee_namespace/README.md +++ b/roles/hub_ee_namespace/README.md @@ -10,12 +10,12 @@ This was depreciated with AAP 2.4 and Galaxy NG 4.6.3+, and removed from the API |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_namespaces`|`see below`|yes|Data structure describing your ee_namespaces, described below.|| ### Secure Logging Variables @@ -23,12 +23,12 @@ This was depreciated with AAP 2.4 and Galaxy NG 4.6.3+, and removed from the API The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_namespace task does not include sensitive information. -ah_configuration_ee_namespace_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_namespace_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_namespace_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -39,12 +39,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_namespace_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_namespace_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_namespace_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_namespace_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_namespace_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_namespace_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -82,7 +82,7 @@ ah_ee_namespaces: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_namespace/defaults/main.yml b/roles/hub_ee_namespace/defaults/main.yml index 958b366a0..f0bd3edb4 100644 --- a/roles/hub_ee_namespace/defaults/main.yml +++ b/roles/hub_ee_namespace/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -17,9 +17,9 @@ ah_ee_namespaces: [] # - "group1" # - "group2" -ah_configuration_ee_namespace_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_namespace_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_namespace_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_namespace_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_namespace_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_namespace_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_namespace_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_namespace_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_namespace/meta/argument_specs.yml b/roles/hub_ee_namespace/meta/argument_specs.yml index c1cd8e38c..6c842a7c4 100644 --- a/roles/hub_ee_namespace/meta/argument_specs.yml +++ b/roles/hub_ee_namespace/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_namespace_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_namespace_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_namespace_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_namespace/tasks/main.yml b/roles/hub_ee_namespace/tasks/main.yml index 300d24ec2..bd9fb6f2e 100644 --- a/roles/hub_ee_namespace/tasks/main.yml +++ b/roles/hub_ee_namespace/tasks/main.yml @@ -8,12 +8,12 @@ append: "{{ __ee_namespace_item.append | default(omit) }}" groups: "{{ __ee_namespace_item.groups | default([]) }}" state: "{{ __ee_namespace_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_namespaces }}" loop_control: loop_var: "__ee_namespace_item" @@ -23,7 +23,7 @@ register: __ee_namespaces_job_async changed_when: not __ee_namespaces_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create EE Namespace | Wait for finish the ee_namespace creation" ansible.builtin.async_status: @@ -38,5 +38,5 @@ when: __ee_namespaces_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_namespace_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_namespace/tests/test.yml b/roles/hub_ee_namespace/tests/test.yml index a9fc20ae3..5f512fee8 100644 --- a/roles/hub_ee_namespace/tests/test.yml +++ b/roles/hub_ee_namespace/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_registry/README.md b/roles/hub_ee_registry/README.md index f848c671e..01bea0d1e 100644 --- a/roles/hub_ee_registry/README.md +++ b/roles/hub_ee_registry/README.md @@ -9,12 +9,12 @@ An Ansible Role to create EE Registries in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`proxy_url`|""|no|str|The URL for the proxy. Defaults to global `proxy_url` variable.| |`proxy_username`|""|no|str|The username for the proxy authentication. Defaults to global `proxy_username` variable.| |`proxy_password`|""|no|str|The password for the proxy authentication. Defaults to global `proxy_password` variable.| @@ -25,12 +25,12 @@ An Ansible Role to create EE Registries in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_registry task does not include sensitive information. -ah_configuration_ee_registry_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_registry_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_registry_secure_logging`|`False`|no|Whether or not to include the sensitive Registry role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -41,12 +41,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_registry_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_registry_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_registry_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_registry_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_registry_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_registry_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -86,7 +86,7 @@ ah_ee_registries: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_registry/defaults/main.yml b/roles/hub_ee_registry/defaults/main.yml index e15d4b0b0..82e97ded0 100644 --- a/roles/hub_ee_registry/defaults/main.yml +++ b/roles/hub_ee_registry/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -23,9 +23,9 @@ ah_ee_registries: [] # rate_limit: 5 # state: present -ah_configuration_ee_registry_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_registry_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_registry_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_registry_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_registry_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_registry_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_registry_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_registry_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_registry/meta/argument_specs.yml b/roles/hub_ee_registry/meta/argument_specs.yml index a4487bd4c..d964d58dd 100644 --- a/roles/hub_ee_registry/meta/argument_specs.yml +++ b/roles/hub_ee_registry/meta/argument_specs.yml @@ -24,65 +24,61 @@ argument_specs: # Async variables ah_configuration_ee_registry_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_registry_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_registry_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_registry/tasks/main.yml b/roles/hub_ee_registry/tasks/main.yml index 6b06d966d..fad19d411 100644 --- a/roles/hub_ee_registry/tasks/main.yml +++ b/roles/hub_ee_registry/tasks/main.yml @@ -11,12 +11,12 @@ download_concurrency: "{{ __ee_registry_item.download_concurrency | default(omit) }}" rate_limit: "{{ __ee_registry_item.rate_limit | default(omit) }}" state: "{{ __ee_registry_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" proxy_url: "{{ __ee_registry_item.proxy_url | default(proxy_url | default(omit)) }}" proxy_username: "{{ __ee_registry_item.proxy_username | default(proxy_username | default(omit)) }}" proxy_password: "{{ __ee_registry_item.proxy_password | default(proxy_password | default(omit)) }}" @@ -29,7 +29,7 @@ register: __ee_registries_job_async changed_when: not __ee_registries_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create EE Registry | Wait for finish the ee_registry creation" ansible.builtin.async_status: @@ -44,5 +44,5 @@ when: __ee_registries_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_registry_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_registry/tests/test.yml b/roles/hub_ee_registry/tests/test.yml index c72892695..9bb24ee57 100644 --- a/roles/hub_ee_registry/tests/test.yml +++ b/roles/hub_ee_registry/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_registry_index/README.md b/roles/hub_ee_registry_index/README.md index 08675354a..34f267f21 100644 --- a/roles/hub_ee_registry_index/README.md +++ b/roles/hub_ee_registry_index/README.md @@ -9,12 +9,12 @@ An Ansible Role to index EE Registries in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_registries`|`see below`|yes|Data structure describing your ee_registries, described below. (Note this is the same as for the `ee_registries` role and the variable can be combined). Note that this role will only do anything if the `index` suboption of this variable is set to true.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to index EE Registries in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_registry task does not include sensitive information. -ah_configuration_ee_registry_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_registry_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_registry_secure_logging`|`False`|no|Whether or not to include the sensitive Registry role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_registry_index_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_registry_index_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_registry_index_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_registry_index_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_registry_index_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_registry_index_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -82,7 +82,7 @@ ah_ee_registries: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_registry_index/defaults/main.yml b/roles/hub_ee_registry_index/defaults/main.yml index 59813682f..4c68a045c 100644 --- a/roles/hub_ee_registry_index/defaults/main.yml +++ b/roles/hub_ee_registry_index/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -16,9 +16,9 @@ ah_ee_registries: [] # wait: true # timeout: -ah_configuration_ee_registry_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_registry_index_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_registry_index_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_registry_index_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_registry_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_registry_index_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_registry_index_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_registry_index_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_registry_index/meta/argument_specs.yml b/roles/hub_ee_registry_index/meta/argument_specs.yml index 40c89027f..07e71dba8 100644 --- a/roles/hub_ee_registry_index/meta/argument_specs.yml +++ b/roles/hub_ee_registry_index/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_registry_index_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_registry_index_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_registry_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_registry_index/tasks/main.yml b/roles/hub_ee_registry_index/tasks/main.yml index b781b9e95..c67a33ab7 100644 --- a/roles/hub_ee_registry_index/tasks/main.yml +++ b/roles/hub_ee_registry_index/tasks/main.yml @@ -7,12 +7,12 @@ wait: "{{ __ee_registry_item.wait | default(omit) }}" interval: "{{ __ee_registry_item.interval | default(ah_configuration_ee_registry_index_async_delay) }}" timeout: "{{ __ee_registry_item.timeout | default(omit) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_registries }}" loop_control: loop_var: "__ee_registry_item" @@ -23,7 +23,7 @@ register: __ee_registry_indexes_job_async changed_when: not __ee_registry_indexes_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Index EE Registry | Wait for finish the ee_registry_index creation" ansible.builtin.async_status: @@ -38,5 +38,5 @@ when: __ee_registry_indexes_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_registry_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_registry_index/tests/test.yml b/roles/hub_ee_registry_index/tests/test.yml index 3eabea1f8..e6135eb3b 100644 --- a/roles/hub_ee_registry_index/tests/test.yml +++ b/roles/hub_ee_registry_index/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_registry_sync/README.md b/roles/hub_ee_registry_sync/README.md index b88db7d18..28048498f 100644 --- a/roles/hub_ee_registry_sync/README.md +++ b/roles/hub_ee_registry_sync/README.md @@ -9,12 +9,12 @@ An Ansible Role to sync EE Registries in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_registries`|`see below`|yes|Data structure describing your ee_registries, described below. (Note this is the same as for the `ee_registries` role and the variable can be combined. Note that this role will only do anything if the `sync` suboption of this variable is set to true.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to sync EE Registries in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_registry task does not include sensitive information. -ah_configuration_ee_registry_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_registry_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_registry_secure_logging`|`False`|no|Whether or not to include the sensitive Registry role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_repository_sync_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_registry_sync_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_registry_sync_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_repository_sync_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_registry_sync_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_registry_sync_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -82,7 +82,7 @@ ah_ee_registries: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_registry_sync/defaults/main.yml b/roles/hub_ee_registry_sync/defaults/main.yml index 16b466c7f..1f6601903 100644 --- a/roles/hub_ee_registry_sync/defaults/main.yml +++ b/roles/hub_ee_registry_sync/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -16,9 +16,9 @@ ah_ee_registries: [] # wait: true # timeout: -ah_configuration_ee_registry_sync_async_timeout: "{{ platform_configuration_async_timeout }}" -ah_configuration_ee_registry_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_registry_sync_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_registry_sync_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_registry_sync_async_timeout: "{{ ah_configuration_async_timeout }}" +ah_configuration_ee_registry_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_registry_sync_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_registry_sync_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_registry_sync/meta/argument_specs.yml b/roles/hub_ee_registry_sync/meta/argument_specs.yml index ffad01f83..0aefcdc53 100644 --- a/roles/hub_ee_registry_sync/meta/argument_specs.yml +++ b/roles/hub_ee_registry_sync/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_registry_sync_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_registry_sync_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_registry_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_registry_sync/tasks/main.yml b/roles/hub_ee_registry_sync/tasks/main.yml index b682f1cc2..01179325a 100644 --- a/roles/hub_ee_registry_sync/tasks/main.yml +++ b/roles/hub_ee_registry_sync/tasks/main.yml @@ -7,12 +7,12 @@ wait: "{{ __ee_registry_item.wait | default(omit) }}" interval: "{{ __ee_registry_item.interval | default(ah_configuration_ee_registry_sync_async_delay) }}" timeout: "{{ __ee_registry_item.timeout | default(omit) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_registries }}" loop_control: loop_var: "__ee_registry_item" @@ -23,7 +23,7 @@ register: __ee_registry_syncs_job_async changed_when: not __ee_registry_syncs_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "EE Registry Sync | Wait for finish the ee_registry_sync to complete" ansible.builtin.async_status: @@ -38,5 +38,5 @@ when: __ee_registry_syncs_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_registry_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_registry_sync/tests/test.yml b/roles/hub_ee_registry_sync/tests/test.yml index 1acf9b8d4..5fb6a129b 100644 --- a/roles/hub_ee_registry_sync/tests/test.yml +++ b/roles/hub_ee_registry_sync/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_repository/README.md b/roles/hub_ee_repository/README.md index 2dcc7110c..788add483 100644 --- a/roles/hub_ee_repository/README.md +++ b/roles/hub_ee_repository/README.md @@ -9,12 +9,12 @@ An Ansible Role to create Repositories in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_repositories`|`see below`|yes|Data structure describing your ee_repositories, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to create Repositories in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_repository task does not include sensitive information. -ah_configuration_ee_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_repository_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_repository_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_repository_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_repository_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_repository_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_repository_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_repository_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -84,7 +84,7 @@ ah_ee_repositories: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_repository/defaults/main.yml b/roles/hub_ee_repository/defaults/main.yml index 3adc1e601..777760ed1 100644 --- a/roles/hub_ee_repository/defaults/main.yml +++ b/roles/hub_ee_repository/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -16,9 +16,9 @@ ah_ee_repositories: [] # readme: "The contents of a readme will go here" # readme_file: "readme.md" -ah_configuration_ee_repository_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_repository_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_repository_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_repository_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_repository_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_repository_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_repository_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_repository_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_repository/meta/argument_specs.yml b/roles/hub_ee_repository/meta/argument_specs.yml index c6830e79b..422ca3953 100644 --- a/roles/hub_ee_repository/meta/argument_specs.yml +++ b/roles/hub_ee_repository/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_repository_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_repository_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_repository_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_repository/tasks/main.yml b/roles/hub_ee_repository/tasks/main.yml index f786a933a..733577a4f 100644 --- a/roles/hub_ee_repository/tasks/main.yml +++ b/roles/hub_ee_repository/tasks/main.yml @@ -12,12 +12,12 @@ include_tags: "{{ __ee_repository_item.include_tags | default(omit) }}" exclude_tags: "{{ __ee_repository_item.exclude_tags | default(omit) }}" state: "{{ __ee_repository_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_repositories }}" loop_control: loop_var: "__ee_repository_item" @@ -27,7 +27,7 @@ register: __ee_repositories_job_async changed_when: not __ee_repositories_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create EE Repository | Wait for finish the ee_repository creation" ansible.builtin.async_status: @@ -42,5 +42,5 @@ when: __ee_repositories_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_repository_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_repository/tests/test.yml b/roles/hub_ee_repository/tests/test.yml index 319b922bb..206aedae8 100644 --- a/roles/hub_ee_repository/tests/test.yml +++ b/roles/hub_ee_repository/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_ee_repository_sync/README.md b/roles/hub_ee_repository_sync/README.md index 4339b0d08..4a551dd7a 100644 --- a/roles/hub_ee_repository_sync/README.md +++ b/roles/hub_ee_repository_sync/README.md @@ -9,12 +9,12 @@ An Ansible Role to sync EE Repositories in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_ee_repositories`|`see below`|yes|Data structure describing your ee_repositories, described below. (Note this is the same as for the `ee_repository` role and the variable can be combined. Note that this role will only do anything if the `sync` suboption of this variable is set to true.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to sync EE Repositories in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add ee_repository task does not include sensitive information. -ah_configuration_ee_repository_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_ee_repository_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_ee_repository_secure_logging`|`False`|no|Whether or not to include the sensitive Repository role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_ee_repository_sync_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_ee_repository_sync_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_ee_repository_sync_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_ee_repository_sync_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_ee_repository_sync_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_ee_repository_sync_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -82,7 +82,7 @@ ah_ee_repositories: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_ee_repository_sync/defaults/main.yml b/roles/hub_ee_repository_sync/defaults/main.yml index 75e9ae96e..0ba48b74c 100644 --- a/roles/hub_ee_repository_sync/defaults/main.yml +++ b/roles/hub_ee_repository_sync/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -16,9 +16,9 @@ ah_ee_repositories: [] # wait: true # timeout: -ah_configuration_ee_repository_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_ee_repository_sync_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_ee_repository_sync_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_ee_repository_sync_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_ee_repository_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_ee_repository_sync_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_ee_repository_sync_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_ee_repository_sync_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_ee_repository_sync/meta/argument_specs.yml b/roles/hub_ee_repository_sync/meta/argument_specs.yml index 5d5a8402c..d3eaead9f 100644 --- a/roles/hub_ee_repository_sync/meta/argument_specs.yml +++ b/roles/hub_ee_repository_sync/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_ee_repository_sync_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_ee_repository_sync_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_ee_repository_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_ee_repository_sync/tasks/main.yml b/roles/hub_ee_repository_sync/tasks/main.yml index 1af85fbd6..c4e1363ba 100644 --- a/roles/hub_ee_repository_sync/tasks/main.yml +++ b/roles/hub_ee_repository_sync/tasks/main.yml @@ -7,12 +7,12 @@ wait: "{{ __ee_repository_item.wait | default(omit) }}" interval: "{{ __ee_repository_item.interval | default(ah_configuration_ee_repository_sync_async_delay) }}" timeout: "{{ __ee_repository_item.timeout | default(omit) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_ee_repositories }}" loop_control: loop_var: "__ee_repository_item" @@ -23,7 +23,7 @@ register: __ee_repository_syncs_job_async changed_when: not __ee_repository_syncs_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "EE Repository Sync | Wait for finish the ee_repository_sync to finish" ansible.builtin.async_status: @@ -38,5 +38,5 @@ when: __ee_repository_syncs_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_ee_repository_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_ee_repository_sync/tests/test.yml b/roles/hub_ee_repository_sync/tests/test.yml index 60dd5d106..1ae33b886 100644 --- a/roles/hub_ee_repository_sync/tests/test.yml +++ b/roles/hub_ee_repository_sync/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_group/README.md b/roles/hub_group/README.md index eec192593..9c5aff789 100644 --- a/roles/hub_group/README.md +++ b/roles/hub_group/README.md @@ -9,12 +9,12 @@ An Ansible Role to create groups in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_groups`|`see below`|yes|Data structure describing your groups, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to create groups in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add group task does not include sensitive information. -ah_configuration_group_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_group_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_group_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,10 +38,10 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_group_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_group_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_group_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_group_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -90,7 +90,7 @@ ah_groups: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_group/defaults/main.yml b/roles/hub_group/defaults/main.yml index 7aef7c44f..b67bac599 100644 --- a/roles/hub_group/defaults/main.yml +++ b/roles/hub_group/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -14,9 +14,9 @@ ah_groups: [] # - name # - perms # - state -ah_configuration_group_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_group_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_group_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_group_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_group_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_group_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_group_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_group_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_group/meta/argument_specs.yml b/roles/hub_group/meta/argument_specs.yml index 15b104807..674e39ed6 100644 --- a/roles/hub_group/meta/argument_specs.yml +++ b/roles/hub_group/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_group_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_group_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_group_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_group/tasks/main.yml b/roles/hub_group/tasks/main.yml index 1f311d58c..00b64fa3e 100644 --- a/roles/hub_group/tasks/main.yml +++ b/roles/hub_group/tasks/main.yml @@ -6,12 +6,12 @@ name: "{{ __group.name | default(omit) }}" # new_name: "{{ __group.new_name | default(omit) }}" <-- Needs adding once new_name option added to module state: "{{ __group.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_groups }}" loop_control: loop_var: "__group" @@ -21,7 +21,7 @@ register: __groups_job_async changed_when: not __groups_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Group | Wait for finish the group creation" ansible.builtin.async_status: @@ -36,18 +36,18 @@ when: __groups_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_group_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: Add Automation Hub group permissions ah_group_perm: name: "{{ __group.new_name | default(__group.name | default(omit)) }}" perms: "{{ __group.perms }}" state: "{{ __group.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" loop: "{{ ah_groups }}" loop_control: loop_var: "__group" @@ -58,7 +58,7 @@ register: __group_perms_job_async changed_when: not __group_perms_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Group | Wait for finish the group creation" ansible.builtin.async_status: @@ -73,5 +73,5 @@ when: __group_perms_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_group_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_group/tests/test.yml b/roles/hub_group/tests/test.yml index fb9a81b27..1ad1dc582 100644 --- a/roles/hub_group/tests/test.yml +++ b/roles/hub_group/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_group_roles/README.md b/roles/hub_group_roles/README.md index d7ffe4505..cd6e09111 100644 --- a/roles/hub_group_roles/README.md +++ b/roles/hub_group_roles/README.md @@ -9,12 +9,12 @@ An Ansible Role to add roles to groups in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_group_roles`|`see below`|yes|Data structure describing the roles which are applied to groups, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to add roles to groups in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add group task does not include sensitive information. -ah_configuration_group_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_group_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_group_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_group_roles_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_group_roles_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_group_roles_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_group_roles_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_group_roles_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_group_roles_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -132,7 +132,7 @@ ah_group_roles: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_group_roles/defaults/main.yml b/roles/hub_group_roles/defaults/main.yml index 105ed3a3a..5f871cf9e 100644 --- a/roles/hub_group_roles/defaults/main.yml +++ b/roles/hub_group_roles/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -13,9 +13,9 @@ ah_group_roles: [] # - groups # - role_list -ah_configuration_group_roles_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_group_roles_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_group_roles_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_group_roles_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_group_roles_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_group_roles_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_group_roles_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_group_roles_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_group_roles/meta/argument_specs.yml b/roles/hub_group_roles/meta/argument_specs.yml index a42369a77..9540af453 100644 --- a/roles/hub_group_roles/meta/argument_specs.yml +++ b/roles/hub_group_roles/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_group_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_group_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_group_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_group_roles/tasks/main.yml b/roles/hub_group_roles/tasks/main.yml index 672a6f5e9..e97dde3c7 100644 --- a/roles/hub_group_roles/tasks/main.yml +++ b/roles/hub_group_roles/tasks/main.yml @@ -5,12 +5,12 @@ groups: "{{ __group_role.groups | default(omit) }}" role_list: "{{ __group_role.role_list | default(omit) }}" state: "{{ __group_role.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_group_roles }}" loop_control: loop_var: "__group_role" @@ -20,7 +20,7 @@ register: __group_roles_job_async changed_when: not __group_roles_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Add Roles to Groups | Wait for finish the group creation" ansible.builtin.async_status: @@ -35,5 +35,5 @@ when: __group_roles_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_group_roles_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_group_roles/tests/test.yml b/roles/hub_group_roles/tests/test.yml index 9f9a207cf..c47bcf19e 100644 --- a/roles/hub_group_roles/tests/test.yml +++ b/roles/hub_group_roles/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_namespace/README.md b/roles/hub_namespace/README.md index a60f5ae57..aaf617037 100644 --- a/roles/hub_namespace/README.md +++ b/roles/hub_namespace/README.md @@ -9,13 +9,13 @@ An Ansible Role to create Namespaces in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| |`ah_token`|""|yes|Tower Admin User's token on the Automation Hub Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_namespaces`|`see below`|yes|Data structure describing your namespaces, described below.|| ### Secure Logging Variables @@ -23,12 +23,12 @@ An Ansible Role to create Namespaces in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add namespace task does not include sensitive information. -ah_configuration_namespace_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_namespace_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_namespace_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -39,12 +39,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_namespace_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_namespace_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_namespace_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_namespace_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_namespace_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_namespace_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -104,7 +104,7 @@ ah_namespaces: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_namespace/defaults/main.yml b/roles/hub_namespace/defaults/main.yml index 42b493e21..489921dda 100644 --- a/roles/hub_namespace/defaults/main.yml +++ b/roles/hub_namespace/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -25,9 +25,9 @@ ah_namespaces: [] # object_roles: #Possible options below # - # mandatory, choices: change_namespace, upload_to_namespace -ah_configuration_namespace_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_namespace_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_namespace_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_namespace_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_namespace_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_namespace_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_namespace_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_namespace_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_namespace/meta/argument_specs.yml b/roles/hub_namespace/meta/argument_specs.yml index f7166f0ce..9fecf1ce9 100644 --- a/roles/hub_namespace/meta/argument_specs.yml +++ b/roles/hub_namespace/meta/argument_specs.yml @@ -12,70 +12,65 @@ argument_specs: # Async variables ah_configuration_namespace_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_namespace_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_namespace_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str - platform_token: - default: None + ah_token: required: false - description: Controller Admin User's token on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: Automation Hub token for authentication. type: str ... diff --git a/roles/hub_namespace/tasks/main.yml b/roles/hub_namespace/tasks/main.yml index 6112fc5e8..5300dd488 100644 --- a/roles/hub_namespace/tasks/main.yml +++ b/roles/hub_namespace/tasks/main.yml @@ -2,12 +2,12 @@ # Create AH Namespace - name: Get token ansible.hub.ah_token: - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" when: - ah_token is not defined - lookup("ansible.builtin.env", "AH_API_TOKEN") == "" @@ -25,13 +25,13 @@ links: "{{ __namespace_item.links | default([]) }}" groups: "{{ __namespace_item.groups | default([]) }}" state: "{{ __namespace_item.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" - ah_token: "{{ platform_token | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" + ah_token: "{{ ah_token | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_namespaces }}" loop_control: loop_var: "__namespace_item" @@ -41,7 +41,7 @@ register: __namespaces_job_async changed_when: not __namespaces_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Namespace | Wait for finish the namespace creation" ansible.builtin.async_status: @@ -56,5 +56,5 @@ when: __namespaces_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_namespace_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_namespace/tests/test.yml b/roles/hub_namespace/tests/test.yml index 0ba14aab0..182db9446 100644 --- a/roles/hub_namespace/tests/test.yml +++ b/roles/hub_namespace/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_publish/README.md b/roles/hub_publish/README.md index 482632413..0bac087fd 100644 --- a/roles/hub_publish/README.md +++ b/roles/hub_publish/README.md @@ -9,13 +9,13 @@ An Ansible Role to publish collections to Automation Hub or Galaxies. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| |`ah_token`|""|no|Admin User's token on the Automation Hub Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_configuration_working_dir`|`/var/tmp`|no|The working directory where the built artifacts live, or where the artifacts will be built.|| |`ah_auto_approve`|`False`|no|Whether the collection will be automatically approved in Automation Hub. This will only work if the account being used has correct privileges.|| |`ah_overwrite_existing`|`False`|no|Whether the collection will be automatically overwrite an existing collection in Automation Hub. This will only work if the account being used has correct privileges.|| @@ -27,12 +27,12 @@ An Ansible Role to publish collections to Automation Hub or Galaxies. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add publish collections task does not include sensitive information. -ah_configuration_publish_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_publish_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_publish_secure_logging`|`False`|no|Whether or not to include the sensitive publish collections role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -43,12 +43,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_publish_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_publish_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_publish_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_publish_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_publish_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_publish_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -87,7 +87,7 @@ ah_auto_approve: true connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_publish/defaults/main.yml b/roles/hub_publish/defaults/main.yml index f8429cd8e..921191e6f 100644 --- a/roles/hub_publish/defaults/main.yml +++ b/roles/hub_publish/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -22,9 +22,9 @@ ah_configuration_working_dir: "/var/tmp" ah_auto_approve: false ah_overwrite_existing: false -ah_configuration_publish_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_publish_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_publish_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_publish_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_publish_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_publish_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_publish_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_publish_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_publish/meta/argument_specs.yml b/roles/hub_publish/meta/argument_specs.yml index 81b72421e..57eb3f8e9 100644 --- a/roles/hub_publish/meta/argument_specs.yml +++ b/roles/hub_publish/meta/argument_specs.yml @@ -33,65 +33,61 @@ argument_specs: # Async variables ah_configuration_publish_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_publish_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_publish_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_publish/tasks/main.yml b/roles/hub_publish/tasks/main.yml index fb5e33304..d8315ce31 100644 --- a/roles/hub_publish/tasks/main.yml +++ b/roles/hub_publish/tasks/main.yml @@ -70,12 +70,12 @@ - name: Get token ansible.hub.ah_token: - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" when: - ah_token is not defined - lookup("ansible.builtin.env", "AH_API_TOKEN") == "" @@ -89,13 +89,13 @@ path: "{{ __ah_collection_file }}" auto_approve: "{{ ah_auto_approve }}" overwrite_existing: "{{ ah_overwrite_existing }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" - ah_token: "{{ platform_token | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" + ah_token: "{{ ah_token | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collection_list }}" loop_control: loop_var: "__ah_collection_file" @@ -105,7 +105,7 @@ register: __publish_job_async changed_when: not __publish_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Publish Collection | Wait for finish the publish creation" ansible.builtin.async_status: @@ -120,20 +120,20 @@ when: __publish_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_publish_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: Approve Collections ansible.hub.ah_approval: namespace: "{{ (__ah_collection_file | basename).split('-')[0] }}" name: "{{ (__ah_collection_file | basename).split('-')[1] }}" version: "{{ (__ah_collection_file | basename).split('-')[2:] | join('-') | splitext | first | splitext | first }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" - ah_token: "{{ platform_token | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" + ah_token: "{{ ah_token | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_collection_list }}" loop_control: loop_var: "__ah_collection_file" diff --git a/roles/hub_publish/tests/test.yml b/roles/hub_publish/tests/test.yml index 2c0ad172b..e5ed7fcf7 100644 --- a/roles/hub_publish/tests/test.yml +++ b/roles/hub_publish/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_role/README.md b/roles/hub_role/README.md index 6ba4a83e3..73f805af7 100644 --- a/roles/hub_role/README.md +++ b/roles/hub_role/README.md @@ -9,12 +9,12 @@ An Ansible Role to create role permissions in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_roles`|`see below`|yes|Data structure describing your role permissions, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to create role permissions in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add group task does not include sensitive information. -ah_configuration_group_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_group_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_role_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_role_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_role_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_role_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_role_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_role_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_role_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -104,7 +104,7 @@ ah_roles: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_role/defaults/main.yml b/roles/hub_role/defaults/main.yml index f289cf83a..1f9e1f9c6 100644 --- a/roles/hub_role/defaults/main.yml +++ b/roles/hub_role/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -15,9 +15,9 @@ ah_roles: [] # - perms # - state -ah_configuration_role_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_role_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_role_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_role_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_role_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_role_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_role_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_role_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_role/meta/argument_specs.yml b/roles/hub_role/meta/argument_specs.yml index 657e51163..701a411b9 100644 --- a/roles/hub_role/meta/argument_specs.yml +++ b/roles/hub_role/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_role_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_role_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_role_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_role/tasks/main.yml b/roles/hub_role/tasks/main.yml index 80344b020..24403269f 100644 --- a/roles/hub_role/tasks/main.yml +++ b/roles/hub_role/tasks/main.yml @@ -7,12 +7,12 @@ description: "{{ __role.description | default(omit) }}" perms: "{{ __role.perms | default(omit) }}" state: "{{ __role.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_roles }}" loop_control: loop_var: "__role" @@ -22,7 +22,7 @@ register: __roles_job_async changed_when: not __roles_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create Role | Wait for finish the role creation" ansible.builtin.async_status: @@ -37,5 +37,5 @@ when: __roles_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_role_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_role/tests/test.yml b/roles/hub_role/tests/test.yml index f45d8e5f7..ed8f67326 100644 --- a/roles/hub_role/tests/test.yml +++ b/roles/hub_role/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/roles/hub_user/README.md b/roles/hub_user/README.md index 33c51631b..192ba636c 100644 --- a/roles/hub_user/README.md +++ b/roles/hub_user/README.md @@ -9,12 +9,12 @@ An Ansible Role to create users in Automation Hub. |Variable Name|Default Value|Required|Description|Example| |:---:|:---:|:---:|:---:|:---:| |`ah_host`|""|yes|URL to the Automation Hub or Galaxy Server. (alias: `ah_hostname`)|127.0.0.1| -|`platform_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| -|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/platform-secrets.yml or elsewhere and called from a parent playbook.|| -|`platform_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| -|`platform_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| +|`ah_username`|""|yes|Admin User on the Automation Hub or Galaxy Server.|| +|`ah_password`|""|yes|Automation Hub Admin User's password on the Automation Hub Server. This should be stored in an Ansible Vault at vars/tower-secrets.yml or elsewhere and called from a parent playbook.|| +|`ah_validate_certs`|`true`|no|Whether or not to validate the Ansible Automation Hub Server's SSL certificate.|| +|`ah_request_timeout`|`10`|no|Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host.|| |`ah_path_prefix`|""|no|API path used to access the api. Either galaxy, automation-hub, or custom|| -|`platform_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| +|`ah_configuration_async_dir`|`null`|no|Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`.|| |`ah_users`|`see below`|yes|Data structure describing your execution environment images, described below.|| ### Secure Logging Variables @@ -22,12 +22,12 @@ An Ansible Role to create users in Automation Hub. The following Variables compliment each other. If Both variables are not set, secure logging defaults to false. The role defaults to False as normally the add user task does not include sensitive information. -ah_configuration_user_secure_logging defaults to the value of platform_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. +ah_configuration_user_secure_logging defaults to the value of ah_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of automation hub configuration roles with a single variable, or for the user to selectively use it. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| |`ah_configuration_user_secure_logging`|`False`|no|Whether or not to include the sensitive Namespace role tasks in the log. Set this value to `True` if you will be providing your sensitive values from elsewhere.| -|`platform_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| +|`ah_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared across multiple roles, see above.| ### Asynchronous Retry Variables @@ -38,12 +38,12 @@ This also speeds up the overall role. |Variable Name|Default Value|Required|Description| |:---:|:---:|:---:|:---:| -|`platform_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| -|`ah_configuration_user_async_timeout`|`platform_configuration_async_timeout`|no|This variable sets the async timeout for the role.| -|`platform_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| -|`ah_configuration_user_async_retries`|`platform_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| -|`platform_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| -|`ah_configuration_user_async_delay`|`platform_configuration_async_delay`|no|This sets the delay between retries for the role.| +|`ah_configuration_async_timeout`|1000|no|This variable sets the async timeout for the role globally.| +|`ah_configuration_user_async_timeout`|`ah_configuration_async_timeout`|no|This variable sets the async timeout for the role.| +|`ah_configuration_async_retries`|50|no|This variable sets the number of retries to attempt for the role globally.| +|`ah_configuration_user_async_retries`|`ah_configuration_async_retries`|no|This variable sets the number of retries to attempt for the role.| +|`ah_configuration_async_delay`|1|no|This sets the delay between retries for the role globally.| +|`ah_configuration_user_async_delay`|`ah_configuration_async_delay`|no|This sets the delay between retries for the role.| ## Data Structure @@ -92,7 +92,7 @@ ah_users: connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com pre_tasks: diff --git a/roles/hub_user/defaults/main.yml b/roles/hub_user/defaults/main.yml index b920b092d..1349c3efd 100644 --- a/roles/hub_user/defaults/main.yml +++ b/roles/hub_user/defaults/main.yml @@ -4,7 +4,7 @@ # You shouldn't need to define them again and again but they should be defined # ah_hostname: "{{ inventory_hostname }}" # ah_oauthtoken: "" -# platform_validate_certs: false +# ah_validate_certs: false # These are the default variables specific to the license role @@ -21,9 +21,9 @@ ah_users: [] # - password # - state -ah_configuration_user_secure_logging: "{{ platform_configuration_secure_logging | default(false) }}" -ah_configuration_user_async_timeout: "{{ platform_configuration_async_timeout | default(1000) }}" -ah_configuration_user_async_retries: "{{ platform_configuration_async_retries | default(50) }}" -ah_configuration_user_async_delay: "{{ platform_configuration_async_delay | default(1) }}" -platform_configuration_async_dir: null +ah_configuration_user_secure_logging: "{{ ah_configuration_secure_logging | default(false) }}" +ah_configuration_user_async_timeout: "{{ ah_configuration_async_timeout | default(1000) }}" +ah_configuration_user_async_retries: "{{ ah_configuration_async_retries | default(50) }}" +ah_configuration_user_async_delay: "{{ ah_configuration_async_delay | default(1) }}" +ah_configuration_async_dir: null ... diff --git a/roles/hub_user/meta/argument_specs.yml b/roles/hub_user/meta/argument_specs.yml index 2f4a60301..4c542ed9c 100644 --- a/roles/hub_user/meta/argument_specs.yml +++ b/roles/hub_user/meta/argument_specs.yml @@ -12,65 +12,61 @@ argument_specs: # Async variables ah_configuration_user_async_retries: - default: "{{ platform_configuration_async_retries | default(50) }}" + default: "{{ ah_configuration_async_retries | default(50) }}" required: false description: This variable sets the number of retries to attempt for the role. - platform_configuration_async_retries: + ah_configuration_async_retries: default: 50 required: false description: This variable sets number of retries across all roles as a default. ah_configuration_user_async_delay: - default: "{{ platform_configuration_async_delay | default(1) }}" + default: "{{ ah_configuration_async_delay | default(1) }}" required: false description: This variable sets delay between retries for the role. - platform_configuration_async_delay: + ah_configuration_async_delay: default: 1 required: false description: This variable sets delay between retries across all roles as a default. - platform_configuration_async_dir: + ah_configuration_async_dir: default: null required: false description: Sets the directory to write the results file for async tasks. The default value is set to `null` which uses the Ansible Default of `/root/.ansible_async/`. # No_log variables ah_configuration_user_secure_logging: - default: "{{ platform_configuration_secure_logging | default(false) }}" + default: "{{ ah_configuration_secure_logging | default(false) }}" required: false type: bool description: Whether or not to include the sensitive role tasks in the log. Set this value to `true` if you will be providing your sensitive values from elsewhere. - platform_configuration_secure_logging: + ah_configuration_secure_logging: default: false required: false type: bool description: This variable enables secure logging across all roles as a default. # Generic across all roles - platform_hostname: - default: None + ah_host: required: false - description: URL to the Ansible Automation Platform Server. + description: URL to the Automation Hub Server. type: str ah_path_prefix: required: false description: The path for the Automation Hub API. Usually galaxy or automation-hub unless custom set in AH settings. - platform_validate_certs: - default: true + ah_validate_certs: required: false - description: Whether or not to validate the Ansible Automation Platform Server's SSL certificate. + description: Whether or not to validate the Automation Hub Server's SSL certificate. type: str - platform_request_timeout: + ah_request_timeout: default: 10 required: false - description: Specify the timeout Ansible should use in requests to the Ansible Automation Platform Server. + description: Specify the timeout Ansible should use in requests to the Galaxy or Automation Hub host. type: float - platform_username: - default: None + ah_username: required: false - description: Admin User on the Ansible Automation Platform Server. Either username / password or oauthtoken need to be specified. + description: User for authentication on Automation Hub type: str - platform_password: - default: None + ah_password: required: false - description: Controller Admin User's password on the Ansible Automation Platform Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook. Either username / password or oauthtoken need to be specified. + description: User's password For Automation Hub type: str ... diff --git a/roles/hub_user/tasks/main.yml b/roles/hub_user/tasks/main.yml index 9e89a8ae8..677883238 100644 --- a/roles/hub_user/tasks/main.yml +++ b/roles/hub_user/tasks/main.yml @@ -13,12 +13,12 @@ is_superuser: "{{ __user.is_superuser | default(omit) }}" password: "{{ __user.password | default(omit) }}" state: "{{ __user.state | default(ah_state | default('present')) }}" - ah_host: "{{ platform_hostname | default(omit) }}" - ah_hostname: "{{ platform_username | default(omit) }}" - ah_password: "{{ platform_password | default(omit) }}" + ah_host: "{{ ah_host | default(ah_hostname) | default(omit) }}" + ah_username: "{{ ah_username | default(omit) }}" + ah_password: "{{ ah_password | default(omit) }}" ah_path_prefix: "{{ ah_path_prefix | default(omit) }}" - validate_certs: "{{ platform_validate_certs | default(omit) }}" - request_timeout: "{{ platform_request_timeout | default(omit) }}" + validate_certs: "{{ ah_validate_certs | default(omit) }}" + request_timeout: "{{ ah_request_timeout | default(omit) }}" loop: "{{ ah_users }}" loop_control: loop_var: "__user" @@ -28,7 +28,7 @@ register: __users_job_async changed_when: not __users_job_async.changed vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' - name: "Create User | Wait for finish the user creation" ansible.builtin.async_status: @@ -43,5 +43,5 @@ when: __users_job_async_result_item.ansible_job_id is defined no_log: "{{ ah_configuration_user_secure_logging }}" vars: - ansible_async_dir: '{{ platform_configuration_async_dir }}' + ansible_async_dir: '{{ ah_configuration_async_dir }}' ... diff --git a/roles/hub_user/tests/test.yml b/roles/hub_user/tests/test.yml index 717089a2c..fee0955c7 100644 --- a/roles/hub_user/tests/test.yml +++ b/roles/hub_user/tests/test.yml @@ -4,7 +4,7 @@ connection: local gather_facts: false vars: - platform_validate_certs: false + ah_validate_certs: false # Define following vars here, or in ah_configs/ah_auth.yml # ah_host: ansible-ah-web-svc-test-project.example.com # ah_token: changeme diff --git a/tests/automatetheautomation/config-controller-filetree.yml b/tests/automatetheautomation/config-controller-filetree.yml new file mode 120000 index 000000000..a945067bb --- /dev/null +++ b/tests/automatetheautomation/config-controller-filetree.yml @@ -0,0 +1 @@ +../../roles/filetree_read/tests/config-controller-filetree.yml \ No newline at end of file diff --git a/tests/automatetheautomation/drop_diff.yml b/tests/automatetheautomation/drop_diff.yml new file mode 120000 index 000000000..ec2eedefb --- /dev/null +++ b/tests/automatetheautomation/drop_diff.yml @@ -0,0 +1 @@ +../../roles/object_diff/tests/drop_diff.yml \ No newline at end of file diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_aap_monitor.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_aap_monitor.yml new file mode 100644 index 000000000..33ed2079c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_aap_monitor.yml @@ -0,0 +1,22 @@ +--- +controller_credential_types: + - name: "AAP_Monitor" + description: "Monitor Ansible Automation Platform credential" + kind: "cloud" + inputs: + fields: + - id: controller_url + label: Controller + type: string + - id: oauthtoken + label: Token + secret: true + type: string + required: + - controller_url + - oauthtoken + injectors: + extra_vars: + local_users_controller_api_token: !unsafe '{{ oauthtoken }}' + local_users_controller_api_url: !unsafe '{{ controller_url }}' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_acme_key.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_acme_key.yml new file mode 100644 index 000000000..ae04404d2 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_acme_key.yml @@ -0,0 +1,16 @@ +--- +controller_credential_types: + - name: "ACME Account Key" + description: "Account Key for Sectigo CA ACME API" + kind: "cloud" + inputs: + fields: + - id: key + label: ACME Account Key + type: string + required: + - key + injectors: + extra_vars: + acme_account_key: !unsafe '{{ key }}' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_cloudforms.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_cloudforms.yml new file mode 100644 index 000000000..eeda7623b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_cloudforms.yml @@ -0,0 +1,35 @@ +--- +controller_credential_types: + - name: "Credential Type for CloudForms" + description: "Credential Type for CloudForms" + kind: "cloud" + inputs: + fields: + - id: host + type: string + label: CloudForms URL + help_text: >- + Enter the URL for the virtual machine that corresponds to your CloudForms + instance. For example, https://cloudforms.example.org + - id: username + type: string + label: Username + - id: password + type: string + label: Password + secret: true + - id: ssl_verify + type: string + label: SSL Verify + default: 'True' + required: + - username + - password + - host + injectors: + env: + CLOUDFORMS_URL: !unsafe '{{ host }}' + CLOUDFORMS_USERNAME: !unsafe '{{ username }}' + CLOUDFORMS_PASSWORD: !unsafe '{{ password }}' + CLOUDFORMS_SSL_VERIFY: !unsafe '{{ ssl_verify }}' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_multiple.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_multiple.yml new file mode 100644 index 000000000..f6968618b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_multiple.yml @@ -0,0 +1,22 @@ +--- +controller_credential_types: + - name: "Machine Credential Dual" + description: "Multiple Machine Credentials" + kind: "cloud" + inputs: + fields: + - type: string + id: my_user + label: Username + - secret: true + type: string + id: my_pass + label: Password + required: + - my_user + - my_pass + injectors: + extra_vars: + my_pass: !unsafe '{{my_pass}}' + my_user: !unsafe '{{my_user}}' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_servicenow.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_servicenow.yml new file mode 100644 index 000000000..86fcd6536 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/app-example/controller_credential_types_servicenow.yml @@ -0,0 +1,27 @@ +--- +controller_credential_types: + - name: "ServiceNow" + description: "Credential Type for ServiceNow" + kind: "cloud" + inputs: + fields: + - id: SN_USERNAME + type: string + label: Username + - id: SN_PASSWORD + type: string + label: Password + secret: true + - id: SN_INSTANCE + type: string + label: Snow Instance + required: + - SN_USERNAME + - SN_PASSWORD + - SN_INSTANCE + injectors: + env: + SN_INSTANCE: !unsafe '{{ SN_INSTANCE }}' + SN_PASSWORD: !unsafe '{{ SN_PASSWORD }}' + SN_USERNAME: !unsafe '{{ SN_USERNAME }}' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/controller_credential_types.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/controller_credential_types.yml new file mode 100644 index 000000000..e8d39b81b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_credential_types.d/controller_credential_types.yml @@ -0,0 +1,3 @@ +--- +controller_credential_types: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_groups.d/controller_groups.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_groups.d/controller_groups.yml new file mode 100644 index 000000000..65297e073 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_groups.d/controller_groups.yml @@ -0,0 +1,3 @@ +--- +controller_groups: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/app-example/controller_instance_groups_otlc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/app-example/controller_instance_groups_otlc.yml new file mode 100644 index 000000000..4becb5882 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/app-example/controller_instance_groups_otlc.yml @@ -0,0 +1,20 @@ +--- +configure_controller_instance_groups: + - name: Container_Groups_Instance + is_container_group: true + credential: "{{ orgs }} {{ env }} OCP_OPENTLC" + pod_spec_override: | + apiVersion: v1 + kind: Pod + metadata: + namespace: controller-container-group + spec: + containers: + - image: >- + registry.redhat.io/ansible-automation-platform-22/ee-supported-rhel8:latest + name: worker + args: + - ansible-runner + - worker + - '--private-data-dir=/runner' +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/controller_instance_groups.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/controller_instance_groups.yml new file mode 100644 index 000000000..9392c9c6f --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_instance_groups.d/controller_instance_groups.yml @@ -0,0 +1,3 @@ +--- +configure_controller_instance_groups: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-casc/controller_inventories_localhost.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-casc/controller_inventories_localhost.yml new file mode 100644 index 000000000..4eb612ef4 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-casc/controller_inventories_localhost.yml @@ -0,0 +1,6 @@ +--- +controller_inventories: + - name: "{{ orgs }} Localhost" + description: "Inventory for the Localhost" + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_excel.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_excel.yml new file mode 100644 index 000000000..fd1955803 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_excel.yml @@ -0,0 +1,6 @@ +--- +controller_inventories: + - name: "InventaryExcel" + description: "Inventory Taken from excel file" + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org1.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org1.yml new file mode 100644 index 000000000..d37eba26c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org1.yml @@ -0,0 +1,32 @@ +--- +controller_inventories: + - name: "SmartInventory URGENT CHANGES CPD BCN Org1" + description: "SmartInventory CPD BCN Org1" + host_filter: "groups__name=Patching_cpd_bcn and groups__name=Patching_os_entorno_{{ env }} and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org01 and groups__name=Patching_parcheo_ch_planif_ch00001" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD BCN Org1 dev" + description: "SmartInventory CPD BCN Org1" + host_filter: "groups__name=Patching_cpd_bcn and groups__name=Patching_os_entorno_dev and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org01" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD MAD Org1 dev" + description: "SmartInventory CPD MAD Org1" + host_filter: "groups__name=Patching_cpd_mad and groups__name=Patching_os_entorno_dev and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org01" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD BCN Org1 prod" + description: "SmartInventory CPD BCN Org1" + host_filter: "groups__name=Patching_cpd_bcn and groups__name=Patching_os_entorno_prod and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org01" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD MAD Org1 prod" + description: "SmartInventory CPD MAD Org1" + host_filter: "groups__name=Patching_cpd_mad and groups__name=Patching_os_entorno_prod and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org01" + kind: smart + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org2.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org2.yml new file mode 100644 index 000000000..1dc3b34ae --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/app-example/controller_inventories_smart_org2.yml @@ -0,0 +1,26 @@ +--- +controller_inventories: + - name: "SmartInventory CPD BCN Org2 dev" + description: "SmartInventory CPD BCN Org2" + host_filter: "groups__name=Patching_cpd_bcn and groups__name=Patching_os_entorno_dev and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org02" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD MAD Org2 dev" + description: "SmartInventory CPD MAD Org2" + host_filter: "groups__name=Patching_cpd_mad and groups__name=Patching_os_entorno_dev and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org02" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD BCN Org2 prod" + description: "SmartInventory CPD BCN Org2" + host_filter: "groups__name=Patching_cpd_bcn and groups__name=Patching_os_entorno_prod and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org02" + kind: smart + organization: "{{ orgs }}" + + - name: "SmartInventory CPD MAD Org2 prod" + description: "SmartInventory CPD MAD Org2" + host_filter: "groups__name=Patching_cpd_mad and groups__name=Patching_os_entorno_prod and groups__name=Patching_os_vendor_redhat and groups__name=Patching_area_org02" + kind: smart + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/controller_inventories.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/controller_inventories.yml new file mode 100644 index 000000000..059d77c02 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_inventories.d/controller_inventories.yml @@ -0,0 +1,3 @@ +--- +controller_inventories: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-casc/controller_job_templates_casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-casc/controller_job_templates_casc.yml new file mode 100644 index 000000000..137c2ba5b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-casc/controller_job_templates_casc.yml @@ -0,0 +1,62 @@ +--- +controller_templates: + - name: "{{ orgs }} CasC_JobTemplates_AAP_CI_Webhook" + description: "Template to attend AAP CasC webhook" + organization: "{{ orgs }}" + project: "{{ orgs }} CasC_Data" + inventory: "{{ orgs }} Localhost" + playbook: "config-controller.yml" + job_tags: ci_webhook_trigger + job_type: run + fact_caching_enabled: false + credentials: + - "{{ orgs }} {{ env }} aap_credentials" + concurrent_jobs_enabled: true + ask_scm_branch_on_launch: true + extra_vars: + ansible_python_interpreter: /usr/bin/python3 + ansible_async_dir: /home/runner/.ansible_async/ + execution_environment: "ee-casc" + + - name: "{{ orgs }} CasC_JobTemplates_AAP_CI_Config_Controller" + description: "Template to deploy AAP Orgs" + organization: "{{ orgs }}" + project: "{{ orgs }} CasC_Data" + inventory: "{{ orgs }} Localhost" + playbook: "config-controller.yml" + job_type: run + fact_caching_enabled: false + credentials: + - "{{ orgs }} {{ env }} aap_credentials" + - "{{ orgs }} {{ env }} aap_vault_credentials" + concurrent_jobs_enabled: true + ask_scm_branch_on_launch: true + ask_tags_on_launch: true + ask_verbosity_on_launch: true + ask_variables_on_launch: true + extra_vars: + ansible_python_interpreter: /usr/bin/python3 + ansible_async_dir: /home/runner/.ansible_async/ + execution_environment: "ee-casc" + + - name: "{{ orgs }} CasC_JobTemplates_AAP_Desired_State" + description: "Template to assure Desired State" + organization: "{{ orgs }}" + project: "{{ orgs }} CasC_Data" + inventory: "{{ orgs }} Localhost" + playbook: "desired-state.yml" + job_type: run + fact_caching_enabled: false + credentials: + - "{{ orgs }} {{ env }} aap_credentials" + - "{{ orgs }} {{ env }} aap_vault_credentials" + concurrent_jobs_enabled: true + ask_scm_branch_on_launch: true + ask_tags_on_launch: true + ask_verbosity_on_launch: true + ask_variables_on_launch: true + extra_vars: + ansible_python_interpreter: /usr/bin/python3 + ansible_async_dir: /home/runner/.ansible_async/ + execution_environment: "ee-casc" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_container_groups.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_container_groups.yml new file mode 100644 index 000000000..734b6d59f --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_container_groups.yml @@ -0,0 +1,16 @@ +--- +controller_templates: + - name: "{{ orgs }} JT_Container_Group" + description: "Template to test Container Groups" + organization: "{{ orgs }}" + project: "{{ orgs }} Container_Group" + inventory: "{{ orgs }} Localhost" + playbook: "helloworld.yml" + job_type: run + concurrent_jobs_enabled: true + credentials: + - "{{ orgs }} {{ env }} aap_vault_credentials" + execution_environment: "Default execution environment" + instance_groups: + - Container_Groups_Instance +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_demo_push.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_demo_push.yml new file mode 100644 index 000000000..42675006c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/app-example/controller_job_templates_demo_push.yml @@ -0,0 +1,46 @@ +--- +controller_templates: + - name: "{{ orgs }} JT_Container_Group TEST DEMO First Push" + description: "Template to test Container Groups" + organization: "{{ orgs }}" + project: "{{ orgs }} Container_Group" + inventory: "{{ orgs }} Localhost" + playbook: "helloworld.yml" + job_type: run + concurrent_jobs_enabled: true + credentials: + - "{{ orgs }} {{ env }} aap_vault_credentials" + execution_environment: "Default execution environment" + instance_groups: + - Container_Groups_Instance + + - name: "{{ orgs }} JT_Container_Group TEST DEMO - Second Push" + description: "Template to test Container Groups" + organization: "{{ orgs }}" + project: "{{ orgs }} Container_Group" + inventory: "{{ orgs }} Localhost" + playbook: "helloworld.yml" + job_type: run + concurrent_jobs_enabled: true + credentials: + - "{{ orgs }} {{ env }} aap_vault_credentials" + execution_environment: "Default execution environment" + instance_groups: + - Container_Groups_Instance + survey_enabled: true + survey_spec: + name: 'TEST' + description: 'Test' + spec: + - question_name: Target Host + question_description: target host is required for playbook to work, this host + needs to exist in the inventory + required: true + type: text + variable: target_hosts + min: 0 + max: 1024 + default: Localhost + choices: '' + new_question: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/controller_job_templates.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/controller_job_templates.yml new file mode 100644 index 000000000..b04efcaad --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_job_templates.d/controller_job_templates.yml @@ -0,0 +1,3 @@ +--- +controller_templates: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-casc/controller_organizations_Global.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-casc/controller_organizations_Global.yml new file mode 100644 index 000000000..9c52cfb56 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-casc/controller_organizations_Global.yml @@ -0,0 +1,10 @@ +--- +controller_organizations: + - name: "{{ orgs }}" + description: "Organization for globally available objects" + galaxy_credentials: + - "Ansible Galaxy" + - "{{ orgs }} {{ env }} Automation Hub Community Repository" + - "{{ orgs }} {{ env }} Automation Hub Published Repository" + - "{{ orgs }} {{ env }} Automation Hub RH Certified Repository" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_ExampleOrg.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_ExampleOrg.yml new file mode 100644 index 000000000..04212af8f --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_ExampleOrg.yml @@ -0,0 +1,10 @@ +--- +controller_organizations: + - name: "ExampleOrg" + description: "Organization Example" + galaxy_credentials: + - "Ansible Galaxy" + - "{{ orgs }} {{ env }} Automation Hub Community Repository" + - "{{ orgs }} {{ env }} Automation Hub Published Repository" + - "{{ orgs }} {{ env }} Automation Hub RH Certified Repository" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_OrgCrossTeams.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_OrgCrossTeams.yml new file mode 100644 index 000000000..d69036184 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_OrgCrossTeams.yml @@ -0,0 +1,5 @@ +--- +controller_organizations: + - name: "OrgCrossTeams" + description: "Organization to run playbooks Cross Teams" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_Organizations1-2.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_Organizations1-2.yml new file mode 100644 index 000000000..1fe8e3cf9 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/app-example/controller_organizations_Organizations1-2.yml @@ -0,0 +1,11 @@ +--- +controller_organizations: + - name: "Organization1" + description: "Organization 1 to tests" + galaxy_credentials: "{{ common_galaxy_credentials }}" + - name: "Organization2" + description: "Organization 2 to tests" + galaxy_credentials: "{{ common_galaxy_credentials }}" +common_galaxy_credentials: + - "Ansible Galaxy" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/controller_organizations.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/controller_organizations.yml new file mode 100644 index 000000000..65f88a496 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_organizations.d/controller_organizations.yml @@ -0,0 +1,3 @@ +--- +controller_organizations: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-casc/controller_projects_casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-casc/controller_projects_casc.yml new file mode 100644 index 000000000..539fb858c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-casc/controller_projects_casc.yml @@ -0,0 +1,15 @@ +--- +controller_projects: + - name: "{{ orgs }} CasC_Data" + description: "Project to include the vars values of the {{ orgs }} Org" + organization: "{{ orgs }}" + scm_type: git + scm_url: "git@gitlab.com:automationiberia.com/global.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_branch: "{{ env }}" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-ocp/controller_projects_container_groups.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-ocp/controller_projects_container_groups.yml new file mode 100644 index 000000000..3e29f19f9 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/app-ocp/controller_projects_container_groups.yml @@ -0,0 +1,14 @@ +--- +controller_projects: + - name: "{{ orgs }} Container_Group" + description: "Project to run Container_Groups example" + organization: "{{ orgs }}" + scm_type: git + scm_url: "git@gitlab.automationiberia.com:aap-demo/readonly-playbooks.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/controller_projects.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/controller_projects.yml new file mode 100644 index 000000000..ac64afac4 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/controller_projects.yml @@ -0,0 +1,3 @@ +--- +controller_projects: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_dev.yml new file mode 100644 index 000000000..4cd6985d8 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_dev.yml @@ -0,0 +1,16 @@ +--- +controller_projects: + - name: "{{ orgs }} InventorySource SourceA dev" + description: "InventorySource SourceA dev from XLSX" + organization: "{{ orgs }}" + scm_type: git + scm_branch: "sourcea-dev" + scm_url: "git@gitlab.automationiberia.com:aap-demo/inventario_ansible_xlsx.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true + +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_prod.yml new file mode 100644 index 000000000..448c76816 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourcea_prod.yml @@ -0,0 +1,16 @@ +--- +controller_projects: + - name: "{{ orgs }} InventorySource SourceA prod" + description: "InventorySource SourceA prod from XLSX" + organization: "{{ orgs }}" + scm_type: git + scm_branch: "sourcea-prod" + scm_url: "git@gitlab.automationiberia.com:aap-demo/inventario_ansible_xlsx.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true + +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_dev.yml new file mode 100644 index 000000000..2591007bf --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_dev.yml @@ -0,0 +1,16 @@ +--- +controller_projects: + - name: "{{ orgs }} InventorySource SourceB dev" + description: "InventorySource SourceB dev from XLSX" + organization: "{{ orgs }}" + scm_type: git + scm_branch: "sourceb-dev" + scm_url: "git@gitlab.automationiberia.com:aap-demo/inventario_ansible_xlsx.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true + +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_prod.yml new file mode 100644 index 000000000..be8bd29f5 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_projects.d/inventories/controller_projects_inventory_sourceb_prod.yml @@ -0,0 +1,16 @@ +--- +controller_projects: + - name: "{{ orgs }} InventorySource SourceB prod" + description: "InventorySource SourceB prod from XLSX" + organization: "{{ orgs }}" + scm_type: git + scm_branch: "sourceb-prod" + scm_url: "git@gitlab.automationiberia.com:aap-demo/inventario_ansible_xlsx.git" + scm_credential: "{{ orgs }} {{ env }} Gitlab Credential" + scm_clean: false + scm_delete_on_update: false + scm_update_on_launch: false + scm_update_cache_timeout: 86400 + allow_override: true + +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_cmdb_approvals.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_cmdb_approvals.yml new file mode 100644 index 000000000..5295dee6e --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_cmdb_approvals.yml @@ -0,0 +1,7 @@ +--- +controller_roles: + - workflows: + - "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + team: "ldap-users-cmdb" + role: approval +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventories.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventories.yml new file mode 100644 index 000000000..a4ef3c082 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventories.yml @@ -0,0 +1,48 @@ +--- +controller_roles: + - inventory: InventaryExcel + user: userorg1 + role: read + + - team: "ldap-org01-users" + inventories: + - "SmartInventory CPD BCN Org1 dev" + - "SmartInventory CPD MAD Org1 dev" + role: use + + - team: "ldap-org01-devs" + inventories: + - "SmartInventory CPD BCN Org1 dev" + - "SmartInventory CPD MAD Org1 dev" + role: use + + - team: "ldap-org01-admins" + inventories: + - "{{ orgs }} Localhost" + - "SmartInventory CPD BCN Org1 prod" + - "SmartInventory CPD MAD Org1 prod" + - "SmartInventory CPD BCN Org1 dev" + - "SmartInventory CPD MAD Org1 dev" + role: use + + - team: "ldap-org02-users" + inventories: + - "SmartInventory CPD BCN Org2 dev" + - "SmartInventory CPD MAD Org2 dev" + role: use + + - team: "ldap-org02-devs" + inventories: + - "SmartInventory CPD BCN Org2 dev" + - "SmartInventory CPD MAD Org2 dev" + role: use + + - team: "ldap-org02-admins" + inventories: + - "{{ orgs }} Localhost" + - "SmartInventory CPD BCN Org2 prod" + - "SmartInventory CPD MAD Org2 prod" + - "SmartInventory CPD BCN Org2 dev" + - "SmartInventory CPD MAD Org2 dev" + role: use +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventory_wf_update.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventory_wf_update.yml new file mode 100644 index 000000000..eeeb04cd0 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_inventory_wf_update.yml @@ -0,0 +1,7 @@ +--- +controller_roles: + - workflows: + - "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + team: "ldap-org01-users" + role: execute +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_teams.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_teams.yml new file mode 100644 index 000000000..086b7d48a --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_teams.yml @@ -0,0 +1,8 @@ +--- +controller_roles: + - team: "Organization1 admins-team" + role: admin + + - team: "Organization2 admins-team" + role: admin +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_users.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_users.yml new file mode 100644 index 000000000..abce8c6ee --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/app-example/controller_roles_users.yml @@ -0,0 +1,50 @@ +--- +controller_roles: + - user: "adminorg1" + organizations: + - "Organization1" + role: member + + - user: "adminorg1" + organizations: + - "Organization1" + role: member + target_teams: + - "Organization1 admins-team" + + - user: "adminorg2" + organizations: + - "Organization2" + role: member + + - user: "adminorg2" + organizations: + - "Organization2" + role: admin + target_teams: + - "Organization2 admins-team" + + - user: "userorg1" + organizations: + - "Organization1" + role: member + + - user: "userorg1" + organizations: + - "Organization1" + role: member + target_teams: + - "Organization1 users-team" + + - user: "userorg2" + organizations: + - "Organization2" + role: member + + - user: "userorg2" + organizations: + - "Organization2" + role: member + target_teams: + - "Organization2 users-team" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/controller_roles.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/controller_roles.yml new file mode 100644 index 000000000..c27de4fb5 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_roles.d/controller_roles.yml @@ -0,0 +1,4 @@ +--- +## available roles: admin_role, execute_role, project_admin_role, inventory_admin_role, credential_admin_role, workflow_admin_role, notification_admin_role, job_template_admin_role, execution_environment_admin_role, auditor_role, member_role, read_role, approval_role +controller_roles: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-casc/controller_schedules_casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-casc/controller_schedules_casc.yml new file mode 100644 index 000000000..64499c99e --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-casc/controller_schedules_casc.yml @@ -0,0 +1,30 @@ +--- +controller_schedules: + - name: "{{ orgs }} CasC_Objects_Cleanup" + description: CasC_Ojbects_Cleanup + unified_job_template: "{{ orgs }} CasC_JobTemplates_AAP_Desired_State" + rrule: DTSTART;TZID=Europe/Madrid:20220127T163000 RRULE:INTERVAL=1;FREQ=DAILY + job_tags: desired_state + enabled: false + extra_data: + ansible_python_interpreter: /usr/bin/python3 + ansible_async_dir: /home/runner/.ansible_async/ + env: "{{ env }}" + dir_orgs_vars: orgs_vars + orgs: "{{ orgs }}" + organization: "{{ orgs }}" + + - name: "{{ orgs }} CasC_Objects_Creation" + description: CasC_Ojbects_Cleanup + unified_job_template: "{{ orgs }} CasC_JobTemplates_AAP_CI_Config_Controller" + rrule: DTSTART;TZID=Europe/Madrid:20220127T000000 RRULE:INTERVAL=1;FREQ=DAILY + enabled: false + extra_data: + ansible_python_interpreter: /usr/bin/python3 + ansible_async_dir: /home/runner/.ansible_async/ + env: "{{ env }}" + dir_orgs_vars: orgs_vars + orgs: "{{ orgs }}" + organization: "{{ orgs }}" + +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-example/controller_schedules_example.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-example/controller_schedules_example.yml new file mode 100644 index 000000000..4845926bc --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/app-example/controller_schedules_example.yml @@ -0,0 +1,3 @@ +--- +controller_schedules: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/controller_schedules.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/controller_schedules.yml new file mode 100644 index 000000000..4845926bc --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_schedules.d/controller_schedules.yml @@ -0,0 +1,3 @@ +--- +controller_schedules: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org1.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org1.yml new file mode 100644 index 000000000..0e5548b1e --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org1.yml @@ -0,0 +1,10 @@ +--- +controller_teams: + - name: "Organization1 admins-team" + description: "Team for Admin Organization1 Org" + organization: "Organization1" + + - name: "Organization1 users-team" + description: "Team for Normal Organization1 Org" + organization: "Organization1" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org2.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org2.yml new file mode 100644 index 000000000..5f2686421 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/app-demo/controller_teams_org2.yml @@ -0,0 +1,10 @@ +--- +controller_teams: + - name: "Organization2 admins-team" + description: "Team for Admin Organization2 Org" + organization: "Organization2" + + - name: "Organization2 users-team" + description: "Team for Normal Organization2 Org" + organization: "Organization2" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/controller_teams.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/controller_teams.yml new file mode 100644 index 000000000..8710e6f70 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_teams.d/controller_teams.yml @@ -0,0 +1,10 @@ +--- +controller_teams: + - name: "{{ orgs }} {{ orgs }}-team" + description: "Team for {{ orgs }} Org" + organization: "{{ orgs }}" + + - name: "{{ orgs }} test-group" + description: "test-group" + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-casc/controller_workflow_job_templates_casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-casc/controller_workflow_job_templates_casc.yml new file mode 100644 index 000000000..461f60d9f --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-casc/controller_workflow_job_templates_casc.yml @@ -0,0 +1,32 @@ +--- +controller_workflows: + - name: "{{ orgs }} CasC_AAP_Workflow" + state: present + description: "workflow for CasC on AAP" + survey_enabled: false + ask_variables_on_launch: true + allow_simultaneous: true + scm_branch: "{{ env }}" + webhook_service: "gitlab" + organization: "{{ orgs }}" + simplified_workflow_nodes: + - identifier: "LAUNCH_CI_{{ orgs }}" + workflow_job_template: "{{ orgs }} CasC_AAP_Workflow" + unified_job_template: "{{ orgs }} CasC_JobTemplates_AAP_CI_Webhook" + job_type: run + organization: "{{ orgs }}" + workflow: "{{ orgs }} CasC_AAP_Workflow" + + - identifier: "PROJECT_SYNC_{{ orgs }}" + workflow_job_template: "{{ orgs }} CasC_AAP_Workflow" + unified_job_template: "{{ orgs }} CasC_Data" + organization: "{{ orgs }}" + workflow: "{{ orgs }} CasC_AAP_Workflow" + success_nodes: + - "LAUNCH_CI_{{ orgs }}" + notification_templates_started: [] + notification_templates_success: [] + notification_templates_error: [] + notification_templates_approvals: [] + survey_spec: {} +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-examples/controller_workflow_job_templates_InventoryUpdate.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-examples/controller_workflow_job_templates_InventoryUpdate.yml new file mode 100644 index 000000000..d996c1883 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/app-examples/controller_workflow_job_templates_InventoryUpdate.yml @@ -0,0 +1,72 @@ +--- +controller_workflows: + - name: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + state: present + description: "workflow for update the sources of the inventory" + survey_enabled: false + ask_variables_on_launch: true + allow_simultaneous: true + scm_branch: "{{ env }}" + organization: "{{ orgs }}" + simplified_workflow_nodes: + - identifier: APPROVAL_WF_INV + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + organization: "{{ orgs }}" + success_nodes: + - SYNC_SRC_A_DEV + - SYNC_SRC_B_DEV + - SYNC_SRC_A_PROD + - SYNC_SRC_B_PROD + approval_node: + description: "First step to update the Inventory Sources, Approval from CMDB Admins" + name: APPROVAL_WF_INVENTORY_UPDATE + timeout: 3600 + + - identifier: SYNC_SRC_A_DEV + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "{{ orgs }} InventorySource SourceA dev" + organization: "{{ orgs }}" + success_nodes: + - INVENTORY_SOURCE_A_DEV + + - identifier: SYNC_SRC_B_DEV + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "{{ orgs }} InventorySource SourceB dev" + organization: "{{ orgs }}" + success_nodes: + - INVENTORY_SOURCE_B_DEV + + - identifier: SYNC_SRC_A_PROD + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "{{ orgs }} InventorySource SourceA prod" + organization: "{{ orgs }}" + success_nodes: + - INVENTORY_SOURCE_A_PROD + + - identifier: SYNC_SRC_B_PROD + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "{{ orgs }} InventorySource SourceB prod" + organization: "{{ orgs }}" + success_nodes: + - INVENTORY_SOURCE_B_PROD + + - identifier: INVENTORY_SOURCE_A_DEV + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "Inventory Source A Dev" + organization: "{{ orgs }}" + + - identifier: INVENTORY_SOURCE_B_DEV + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "Inventory Source B Dev" + organization: "{{ orgs }}" + + - identifier: INVENTORY_SOURCE_A_PROD + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "Inventory Source A Prod" + organization: "{{ orgs }}" + + - identifier: INVENTORY_SOURCE_B_PROD + workflow_job_template: "{{ orgs }} WF_INVENTORY_SOURCE_UPDATE" + unified_job_template: "Inventory Source B Prod" + organization: "{{ orgs }}" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/controller_workflow_job_templates.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/controller_workflow_job_templates.yml new file mode 100644 index 000000000..e85617417 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/common/controller_workflow_job_templates.d/controller_workflow_job_templates.yml @@ -0,0 +1,3 @@ +--- +controller_workflows: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_aap.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_aap.yml new file mode 100644 index 000000000..f0a92b143 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_aap.yml @@ -0,0 +1,12 @@ +--- +controller_credentials: + - name: "AAP Credentials Example" + description: "Ansible Automation Platform Credentials Example" + credential_type: "Red Hat Ansible Automation Platform" + organization: "ExampleOrg" + inputs: + host: "controller.lab.example.com" + username: "controller-user" + password: "controller-password" + verify_ssl: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_galaxy.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_galaxy.yml new file mode 100644 index 000000000..6774f8068 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_galaxy.yml @@ -0,0 +1,26 @@ +--- +controller_credentials: + - name: "Automation Hub Community Repository Example" + description: "Automation Hub Community Repository Example" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/community/" + token: "AddToken" + + - name: "Automation Hub Published Repository Example" + description: "Automation Hub Published Repository Example" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/published/" + token: "AddToken" + + - name: "Automation Hub RH Certified Repository Example" + description: "" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/rh-certified/" + token: "AddToken" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_machine.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_machine.yml new file mode 100644 index 000000000..971594944 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_machine.yml @@ -0,0 +1,10 @@ +--- +controller_credentials: + - name: "Machine Credentials Example" + description: "Machine Credentials Example" + credential_type: "Machine" + organization: "ExampleOrg" + inputs: + username: "user-ansible" + password: "password" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_ocp.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_ocp.yml new file mode 100644 index 000000000..05bc7ed7d --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_ocp.yml @@ -0,0 +1,11 @@ +--- +controller_credentials: + - name: "Credentials OCP Example" + description: "OCP SA to run Container Groups Example" + credential_type: "OpenShift or Kubernetes API Bearer Token" + organization: "ExampleOrg" + inputs: + host: "https://api.cluster.lab.example.com:6443" + verify_ssl: false + bearer_token: "Addbearer_token" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_registry.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_registry.yml new file mode 100644 index 000000000..2af2e6a65 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_registry.yml @@ -0,0 +1,12 @@ +--- +controller_credentials: + - name: "Automation Private Hub Container Registry Example" + description: "Credential to connect to Container Registry at AtomationHub Private Example" + credential_type: "Container Registry" + organization: "ExampleOrg" + inputs: + username: "registry-user" + password: "password" + host: automationhub.lab.example.com + verify_ssl: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_scm.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_scm.yml new file mode 100644 index 000000000..0cdfe7200 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_scm.yml @@ -0,0 +1,19 @@ +--- +controller_credentials: + - name: "Gitlab Credential Example" + description: "Gitlab Credential Example" + credential_type: "Source Control" + organization: "ExampleOrg" + inputs: + username: 'scm-user' + ssh_key_data: | + -----BEGIN RSA PRIVATE KEY----- + MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu + KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm + o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k + TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7 + 9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy + v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs + /5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 + -----END RSA PRIVATE KEY----- +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_vault.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_vault.yml new file mode 100644 index 000000000..e74f3e1f8 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_credentials.d/app-examples/controller_credentials_vault.yml @@ -0,0 +1,9 @@ +--- +controller_credentials: + - name: "Vault Credentials Example" + description: "Vault Credentials Example" + credential_type: "Vault" + organization: "ExampleOrg" + inputs: + vault_password: "password" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml new file mode 100644 index 000000000..b98fae314 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml @@ -0,0 +1,7 @@ +--- +controller_execution_environments: + - name: "ee-casc" + image: automationhub.automationiberia.com/ee-casc:latest + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml new file mode 100644 index 000000000..de9e3526b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml @@ -0,0 +1,12 @@ +--- +controller_execution_environments: + - name: "ee-xlsx" + image: automationhub.automationiberia.com/ee-xlsx:latest + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" + + - name: "test-ee-xlsx" + image: automationhub.automationiberia.com/test-ee-xlsx:0.2 + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/controller_execution_environments.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/controller_execution_environments.yml new file mode 100644 index 000000000..28041d44c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_execution_environments.d/controller_execution_environments.yml @@ -0,0 +1,3 @@ +--- +controller_execution_environments: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/app-casc/controller_hosts_localhost.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/app-casc/controller_hosts_localhost.yml new file mode 100644 index 000000000..4b9e5a998 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/app-casc/controller_hosts_localhost.yml @@ -0,0 +1,6 @@ +--- +controller_hosts: + - name: localhost + description: localhost + inventory: "{{ orgs }} Localhost" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/controller_hosts.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/controller_hosts.yml new file mode 100644 index 000000000..5fd4d8140 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_hosts.d/controller_hosts.yml @@ -0,0 +1,3 @@ +--- +controller_hosts: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml new file mode 100644 index 000000000..3ac123303 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source A Dev" + description: "Source Inventory from Excel file SourceA dev" + source: scm + source_project: "{{ orgs }} InventorySource SourceA dev" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml new file mode 100644 index 000000000..dd3242be2 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source A Prod" + description: "Source Inventory from Excel file SourceA prod" + source: scm + source_project: "{{ orgs }} InventorySource SourceA prod" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml new file mode 100644 index 000000000..2024f92fb --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source B Dev" + description: "Source Inventory from Excel file SourceB dev" + source: scm + source_project: "{{ orgs }} InventorySource SourceB dev" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml new file mode 100644 index 000000000..67ad9c1d1 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source B Prod" + description: "Source Inventory from Excel file SourceB prod" + source: scm + source_project: "{{ orgs }} InventorySource SourceB prod" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/controller_inventory_sources.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/controller_inventory_sources.yml new file mode 100644 index 000000000..cd9fc77bf --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_inventory_sources.d/controller_inventory_sources.yml @@ -0,0 +1,3 @@ +--- +controller_inventory_sources: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_jobs.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_jobs.yml new file mode 100644 index 000000000..43cf1a8a5 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_jobs.yml @@ -0,0 +1,13 @@ +--- +controller_settings: + # - name: AWX_ISOLATION_SHOW_PATHS + # value: "['/tmp', '/mnt/backup']" + - name: DEFAULT_PROJECT_UPDATE_TIMEOUT + value: 0 + - name: DEFAULT_INVENTORY_UPDATE_TIMEOUT + value: 0 + - name: DEFAULT_JOB_TIMEOUT + value: 0 + - name: MAX_FORKS + value: 200 +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_ldap.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_ldap.yml new file mode 100644 index 000000000..9d9f4c760 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_ldap.yml @@ -0,0 +1,113 @@ +--- +controller_settings: + - name: AUTH_LDAP_SERVER_URI + value: "ldap://idm.automationiberia.com" + - name: AUTH_LDAP_BIND_DN + value: "{{ vault_ldap_bind_dn | default('uid=controller-binddn,cn=sysaccounts,cn=etc,dc=automationiberia,dc=com') }}" + - name: AUTH_LDAP_BIND_PASSWORD + value: "{{ vault_ldap_bind_password | default('password') }}" + - name: AUTH_LDAP_START_TLS + value: false + - name: AUTH_LDAP_USER_DN_TEMPLATE + value: "" + - name: AUTH_LDAP_CONNECTION_OPTIONS + value: + OPT_REFERRALS: 0 + OPT_NETWORK_TIMEOUT: 30 + - name: AUTH_LDAP_USER_SEARCH + value: ["cn=users,cn=accounts,dc=bcnconsulting,dc=com", "SCOPE_SUBTREE", "(uid=%(user)s)"] + - name: AUTH_LDAP_USER_DN_TEMPLATE + value: "" + - name: AUTH_LDAP_USER_ATTR_MAP + value: {"first_name": "givenName", "last_name": "sn", "email": "mail"} + - name: AUTH_LDAP_GROUP_SEARCH + value: ["cn=groups,cn=accounts,dc=bcnconsulting,dc=com", "SCOPE_SUBTREE", "(objectClass=posixgroup)"] + - name: AUTH_LDAP_GROUP_TYPE + value: "MemberDNGroupType" + - name: AUTH_LDAP_GROUP_TYPE_PARAMS + value: {"name_attr": "cn", "member_attr": "member"} + - name: AUTH_LDAP_REQUIRE_GROUP + value: "" + - name: AUTH_LDAP_DENY_GROUP + value: "" + - name: AUTH_LDAP_USER_FLAGS_BY_GROUP + value: {"is_superuser": ["cn=controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com"], "is_system_auditor": ["cn=team-ldap-auditor,cn=groups,cn=accounts,dc=bcnconsulting,dc=com"]} + - name: AUTH_LDAP_ORGANIZATION_MAP + value: { + "{{ orgs }}": { + "admins": "cn=controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove_users": true, + "remove_admins": true + }, + "Organization1": { + "admins": [ + "cn=team-ldap-org01-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "users": [ + "cn=team-ldap-org01-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "cn=team-ldap-org01-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "remove_users": true, + "remove_admins": true + }, + "Organization2": { + "admins": [ + "cn=team-ldap-org02-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "users": [ + "cn=team-ldap-org02-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "cn=team-ldap-org02-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "remove_users": true, + "remove_admins": true + } + } + - name: AUTH_LDAP_TEAM_MAP + value: { + "ldap-controller-admins": { + "organization": "{{ orgs }}", + "users": "cn=team-ldap-controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-users-cmdb": { + "organization": "{{ orgs }}", + "users": "cn=team-ldap-cmdb-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-users-crossteam": { + "organization": "CrossTeamOrg", + "users": "cn=team-ldap-users-crossteam,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-admins": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-users": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-devs": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-admins": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-users": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-devs": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + } + } +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_system.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_system.yml new file mode 100644 index 000000000..5f9ae2381 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_system.yml @@ -0,0 +1,18 @@ +--- +controller_settings: + # - name: ACTIVITY_STREAM_ENABLED + # value: true + # - name: ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC + # value: false + # - name: SESSION_COOKIE_AGE + # value: 1800 + # - name: SESSIONS_PER_USER + # value: 10 + # - name: MANAGE_ORGANIZATION_AUTH + # value: true + # https://access.redhat.com/solutions/6613291 - External users are not able to create token on Ansible Tower. + - name: ALLOW_OAUTH2_FOR_EXTERNAL_USERS + value: true + - name: ORG_ADMINS_CAN_SEE_ALL_USERS + value: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_user_interface.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_user_interface.yml new file mode 100644 index 000000000..f465d180d --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/app-examples/controller_settings_user_interface.yml @@ -0,0 +1,5 @@ +--- +controller_settings: + - name: CUSTOM_LOGIN_INFO + value: "This is a custom message provided by Customer - Consulting Barcelona" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/controller_settings.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/controller_settings.yml new file mode 100644 index 000000000..7e6d3c65d --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_settings.d/controller_settings.yml @@ -0,0 +1,4 @@ +--- +# tower-manage print_settings +controller_settings: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org1.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org1.yml new file mode 100644 index 000000000..fb71e0616 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org1.yml @@ -0,0 +1,15 @@ +--- +controller_user_accounts: + - username: "adminorg1" + password: "password" + email: "adminorg1@example.com" + firstname: "adminorg1" + lastname: "adminorg1" + is_auditor: false + is_superuser: false + + - username: "userorg1" + password: "password" + email: "userorg1@example.com" + is_superuser: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org2.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org2.yml new file mode 100644 index 000000000..688dfca19 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/app-demo/controller_user_accounts_org2.yml @@ -0,0 +1,15 @@ +--- +controller_user_accounts: + - username: "adminorg2" + password: "password" + email: "adminorg2@example.com" + firstname: "adminorg2" + lastname: "adminorg2" + is_auditor: false + is_superuser: false + + - username: "userorg2" + password: "password" + email: "userorg2@example.com" + is_superuser: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/controller_user_accounts.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/controller_user_accounts.yml new file mode 100644 index 000000000..06dd02b0b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/dev/controller_users.d/controller_user_accounts.yml @@ -0,0 +1,11 @@ +--- +controller_user_accounts: + - username: "admin" + password: "password" + email: "admin@example.com" + firstname: "admin" + lastname: "admin" + is_auditor: false + is_superuser: true + update_secrets: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_aap.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_aap.yml new file mode 100644 index 000000000..f0a92b143 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_aap.yml @@ -0,0 +1,12 @@ +--- +controller_credentials: + - name: "AAP Credentials Example" + description: "Ansible Automation Platform Credentials Example" + credential_type: "Red Hat Ansible Automation Platform" + organization: "ExampleOrg" + inputs: + host: "controller.lab.example.com" + username: "controller-user" + password: "controller-password" + verify_ssl: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_galaxy.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_galaxy.yml new file mode 100644 index 000000000..6774f8068 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_galaxy.yml @@ -0,0 +1,26 @@ +--- +controller_credentials: + - name: "Automation Hub Community Repository Example" + description: "Automation Hub Community Repository Example" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/community/" + token: "AddToken" + + - name: "Automation Hub Published Repository Example" + description: "Automation Hub Published Repository Example" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/published/" + token: "AddToken" + + - name: "Automation Hub RH Certified Repository Example" + description: "" + credential_type: "Ansible Galaxy/Automation Hub API Token" + organization: "ExampleOrg" + inputs: + url: "https://automationhub.lab.example.com/api/galaxy/content/rh-certified/" + token: "AddToken" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_machine.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_machine.yml new file mode 100644 index 000000000..971594944 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_machine.yml @@ -0,0 +1,10 @@ +--- +controller_credentials: + - name: "Machine Credentials Example" + description: "Machine Credentials Example" + credential_type: "Machine" + organization: "ExampleOrg" + inputs: + username: "user-ansible" + password: "password" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_ocp.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_ocp.yml new file mode 100644 index 000000000..05bc7ed7d --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_ocp.yml @@ -0,0 +1,11 @@ +--- +controller_credentials: + - name: "Credentials OCP Example" + description: "OCP SA to run Container Groups Example" + credential_type: "OpenShift or Kubernetes API Bearer Token" + organization: "ExampleOrg" + inputs: + host: "https://api.cluster.lab.example.com:6443" + verify_ssl: false + bearer_token: "Addbearer_token" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_registry.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_registry.yml new file mode 100644 index 000000000..2af2e6a65 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_registry.yml @@ -0,0 +1,12 @@ +--- +controller_credentials: + - name: "Automation Private Hub Container Registry Example" + description: "Credential to connect to Container Registry at AtomationHub Private Example" + credential_type: "Container Registry" + organization: "ExampleOrg" + inputs: + username: "registry-user" + password: "password" + host: automationhub.lab.example.com + verify_ssl: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_scm.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_scm.yml new file mode 100644 index 000000000..0cdfe7200 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_scm.yml @@ -0,0 +1,19 @@ +--- +controller_credentials: + - name: "Gitlab Credential Example" + description: "Gitlab Credential Example" + credential_type: "Source Control" + organization: "ExampleOrg" + inputs: + username: 'scm-user' + ssh_key_data: | + -----BEGIN RSA PRIVATE KEY----- + MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu + KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm + o3qGy0t6z09AIJtH+5OeRV1be+N4cDYJKffGzDa88vQENZiRm0GRq6a+HPGQMd2k + TQIhAKMSvzIBnni7ot/OSie2TmJLY4SwTQAevXysE2RbFDYdAiEBCUEaRQnMnbp7 + 9mxDXDf6AU0cN/RPBjb9qSHDcWZHGzUCIG2Es59z8ugGrDY+pxLQnwfotadxd+Uy + v/Ow5T0q5gIJAiEAyS4RaI9YG8EWx/2w0T67ZUVAw8eOMB6BIUg0Xcu+3okCIBOs + /5OiPgoTdSy7bcF9IGpSE8ZgGKzgYQVZeN97YE00 + -----END RSA PRIVATE KEY----- +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_vault.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_vault.yml new file mode 100644 index 000000000..e74f3e1f8 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_credentials.d/app-examples/controller_credentials_vault.yml @@ -0,0 +1,9 @@ +--- +controller_credentials: + - name: "Vault Credentials Example" + description: "Vault Credentials Example" + credential_type: "Vault" + organization: "ExampleOrg" + inputs: + vault_password: "password" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml new file mode 100644 index 000000000..b98fae314 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-casc/controller_execution_environments_ee-casc.yml @@ -0,0 +1,7 @@ +--- +controller_execution_environments: + - name: "ee-casc" + image: automationhub.automationiberia.com/ee-casc:latest + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml new file mode 100644 index 000000000..de9e3526b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/app-examples/controller_execution_environments_ee-xlsx.yml @@ -0,0 +1,12 @@ +--- +controller_execution_environments: + - name: "ee-xlsx" + image: automationhub.automationiberia.com/ee-xlsx:latest + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" + + - name: "test-ee-xlsx" + image: automationhub.automationiberia.com/test-ee-xlsx:0.2 + pull: always + credential: "{{ orgs }} {{ env }} Automation Private Hub Container Registry" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/controller_execution_environments.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/controller_execution_environments.yml new file mode 100644 index 000000000..28041d44c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_execution_environments.d/controller_execution_environments.yml @@ -0,0 +1,3 @@ +--- +controller_execution_environments: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_hosts.d/controller_hosts.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_hosts.d/controller_hosts.yml new file mode 100644 index 000000000..4b9e5a998 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_hosts.d/controller_hosts.yml @@ -0,0 +1,6 @@ +--- +controller_hosts: + - name: localhost + description: localhost + inventory: "{{ orgs }} Localhost" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml new file mode 100644 index 000000000..3ac123303 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_dev.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source A Dev" + description: "Source Inventory from Excel file SourceA dev" + source: scm + source_project: "{{ orgs }} InventorySource SourceA dev" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml new file mode 100644 index 000000000..dd3242be2 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourcea_prod.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source A Prod" + description: "Source Inventory from Excel file SourceA prod" + source: scm + source_project: "{{ orgs }} InventorySource SourceA prod" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml new file mode 100644 index 000000000..2024f92fb --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_dev.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source B Dev" + description: "Source Inventory from Excel file SourceB dev" + source: scm + source_project: "{{ orgs }} InventorySource SourceB dev" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml new file mode 100644 index 000000000..67ad9c1d1 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/app-examples/controller_inventory_sources_sourceb_prod.yml @@ -0,0 +1,12 @@ +--- +controller_inventory_sources: + - name: "Inventory Source B Prod" + description: "Source Inventory from Excel file SourceB prod" + source: scm + source_project: "{{ orgs }} InventorySource SourceB prod" + execution_environment: ee-xlsx + source_path: "xlsx_inventory.py" + inventory: "InventaryExcel" + update_on_launch: false + overwrite: true +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/controller_inventory_sources.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/controller_inventory_sources.yml new file mode 100644 index 000000000..cd9fc77bf --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_inventory_sources.d/controller_inventory_sources.yml @@ -0,0 +1,3 @@ +--- +controller_inventory_sources: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_jobs.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_jobs.yml new file mode 100644 index 000000000..43cf1a8a5 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_jobs.yml @@ -0,0 +1,13 @@ +--- +controller_settings: + # - name: AWX_ISOLATION_SHOW_PATHS + # value: "['/tmp', '/mnt/backup']" + - name: DEFAULT_PROJECT_UPDATE_TIMEOUT + value: 0 + - name: DEFAULT_INVENTORY_UPDATE_TIMEOUT + value: 0 + - name: DEFAULT_JOB_TIMEOUT + value: 0 + - name: MAX_FORKS + value: 200 +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_ldap.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_ldap.yml new file mode 100644 index 000000000..b6d14c45c --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_ldap.yml @@ -0,0 +1,113 @@ +--- +controller_settings: + - name: AUTH_LDAP_SERVER_URI + value: "ldap://idm.automationiberia.com" + - name: AUTH_LDAP_BIND_DN + value: "{{ vault_ldap_bind_dn | default('uid=controller-binddn,cn=sysaccounts,cn=etc,dc=automationiberia,dc=com') }}" + - name: AUTH_LDAP_BIND_PASSWORD + value: "{{ vault_ldap_bind_password | default('password') }}" + - name: AUTH_LDAP_START_TLS + value: false + - name: AUTH_LDAP_USER_DN_TEMPLATE + value: "" + - name: AUTH_LDAP_CONNECTION_OPTIONS + value: + OPT_REFERRALS: 0 + OPT_NETWORK_TIMEOUT: 30 + - name: AUTH_LDAP_USER_SEARCH + value: ["cn=users,cn=accounts,dc=bcnconsulting,dc=com", "SCOPE_SUBTREE", "(uid=%(user)s)"] + - name: AUTH_LDAP_USER_DN_TEMPLATE + value: "" + - name: AUTH_LDAP_USER_ATTR_MAP + value: {"first_name": "givenName", "last_name": "sn", "email": "mail"} + - name: AUTH_LDAP_GROUP_SEARCH + value: ["cn=groups, cn=accounts, dc=bcnconsulting,dc=com", "SCOPE_SUBTREE", "(objectClass=posixgroup)"] + - name: AUTH_LDAP_GROUP_TYPE + value: "MemberDNGroupType" + - name: AUTH_LDAP_GROUP_TYPE_PARAMS + value: {"name_attr": "cn", "member_attr": "member"} + - name: AUTH_LDAP_REQUIRE_GROUP + value: "" + - name: AUTH_LDAP_DENY_GROUP + value: "" + - name: AUTH_LDAP_USER_FLAGS_BY_GROUP + value: {"is_superuser": ["cn=controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com"], "is_system_auditor": ["cn=team-ldap-auditor,cn=groups,cn=accounts,dc=bcnconsulting,dc=com"]} + - name: AUTH_LDAP_ORGANIZATION_MAP + value: { + "{{ orgs }}": { + "admins": "cn=controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove_users": true, + "remove_admins": true + }, + "Organization1": { + "admins": [ + "cn=team-ldap-org01-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "users": [ + "cn=team-ldap-org01-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "cn=team-ldap-org01-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "remove_users": true, + "remove_admins": true + }, + "Organization2": { + "admins": [ + "cn=team-ldap-org02-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "users": [ + "cn=team-ldap-org02-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "cn=team-ldap-org02-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com" + ], + "remove_users": true, + "remove_admins": true + } + } + - name: AUTH_LDAP_TEAM_MAP + value: { + "ldap-controller-admins": { + "organization": "{{ orgs }}", + "users": "cn=team-ldap-controller-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-users-cmdb": { + "organization": "{{ orgs }}", + "users": "cn=team-ldap-cmdb-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-users-crossteam": { + "organization": "CrossTeamOrg", + "users": "cn=team-ldap-users-crossteam,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-admins": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-users": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org01-devs": { + "organization": "Organization1", + "users": "cn=team-ldap-org01-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-admins": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-admins,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-users": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-users,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + }, + "ldap-org02-devs": { + "organization": "Organization2", + "users": "cn=team-ldap-org02-devs,cn=groups,cn=accounts,dc=bcnconsulting,dc=com", + "remove": true + } + } +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_system.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_system.yml new file mode 100644 index 000000000..5f9ae2381 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_system.yml @@ -0,0 +1,18 @@ +--- +controller_settings: + # - name: ACTIVITY_STREAM_ENABLED + # value: true + # - name: ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC + # value: false + # - name: SESSION_COOKIE_AGE + # value: 1800 + # - name: SESSIONS_PER_USER + # value: 10 + # - name: MANAGE_ORGANIZATION_AUTH + # value: true + # https://access.redhat.com/solutions/6613291 - External users are not able to create token on Ansible Tower. + - name: ALLOW_OAUTH2_FOR_EXTERNAL_USERS + value: true + - name: ORG_ADMINS_CAN_SEE_ALL_USERS + value: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_user_interface.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_user_interface.yml new file mode 100644 index 000000000..f465d180d --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/app-examples/controller_settings_user_interface.yml @@ -0,0 +1,5 @@ +--- +controller_settings: + - name: CUSTOM_LOGIN_INFO + value: "This is a custom message provided by Customer - Consulting Barcelona" +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/controller_settings.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/controller_settings.yml new file mode 100644 index 000000000..40aea26d2 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_settings.d/controller_settings.yml @@ -0,0 +1,3 @@ +--- +controller_settings: [] +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org1.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org1.yml new file mode 100644 index 000000000..fb71e0616 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org1.yml @@ -0,0 +1,15 @@ +--- +controller_user_accounts: + - username: "adminorg1" + password: "password" + email: "adminorg1@example.com" + firstname: "adminorg1" + lastname: "adminorg1" + is_auditor: false + is_superuser: false + + - username: "userorg1" + password: "password" + email: "userorg1@example.com" + is_superuser: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org2.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org2.yml new file mode 100644 index 000000000..688dfca19 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/app-demo/controller_user_accounts_org2.yml @@ -0,0 +1,15 @@ +--- +controller_user_accounts: + - username: "adminorg2" + password: "password" + email: "adminorg2@example.com" + firstname: "adminorg2" + lastname: "adminorg2" + is_auditor: false + is_superuser: false + + - username: "userorg2" + password: "password" + email: "userorg2@example.com" + is_superuser: false +... diff --git a/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/controller_user_accounts.yml b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/controller_user_accounts.yml new file mode 100644 index 000000000..06dd02b0b --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/ExampleOrg/env/prod/controller_users.d/controller_user_accounts.yml @@ -0,0 +1,11 @@ +--- +controller_user_accounts: + - username: "admin" + password: "password" + email: "admin@example.com" + firstname: "admin" + lastname: "admin" + is_auditor: false + is_superuser: true + update_secrets: false +... diff --git a/tests/automatetheautomation/orgs_vars/env/dev/configure_connection_controller_credentials.yml b/tests/automatetheautomation/orgs_vars/env/dev/configure_connection_controller_credentials.yml new file mode 100644 index 000000000..efe524d21 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/env/dev/configure_connection_controller_credentials.yml @@ -0,0 +1,6 @@ +--- +vault_controller_username: 'admin' +vault_controller_password: 'password' +vault_controller_hostname: controller-dev.lab.example.com +vault_controller_validate_certs: false +... diff --git a/tests/automatetheautomation/orgs_vars/env/prod/configure_connection_controller_credentials.yml b/tests/automatetheautomation/orgs_vars/env/prod/configure_connection_controller_credentials.yml new file mode 100644 index 000000000..aee1768c9 --- /dev/null +++ b/tests/automatetheautomation/orgs_vars/env/prod/configure_connection_controller_credentials.yml @@ -0,0 +1,6 @@ +--- +vault_controller_username: 'admin' +vault_controller_password: 'password' +vault_controller_hostname: controller-prod.lab.example.com +vault_controller_validate_certs: false +... diff --git a/tests/automatetheautomation/pictures/AAP_CasC_Worflow.png b/tests/automatetheautomation/pictures/AAP_CasC_Worflow.png new file mode 100644 index 0000000000000000000000000000000000000000..3f9aeb908e1cffdf3d6cd428a573765332e884e9 GIT binary patch literal 563916 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�$FB?D#f9Udr*euv*}{*# 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

rl%{4w)39xREu8= zM6~G1MZO0OIw2{`_Lrd-Kf>uo^2E7#do`tRb}Zbw5T_tYN-oWuctIXq)LC z0`6HwR~L9`darpbC+RAK1p?~nE4RkHXl^!RoGtYSBni%W|Q2;^ZZVS=~ zHs!1{y7jej_m(g?FDrma@q??&5Oa7TL)iy7cvx=P0GEue63cjfYddG%8-ESqi2m+t z>eBS{j__9HC?XFCZ;7~ycn}iQ0kLFiHp&POpzZ99q~?3k(qcNYUWrTsQXTU;`reH^ zI6}8C490+2eF?7F5Rfh#vLm2|)(1FFYJaRy{2J6}ftZ$AB^e!eaNrHw8yxayONPVL zKXWiV%mn+y1Ilq2(B5Gy(pC=d%pIGUz#xjyAoZE3z~HM*dBfl;;L1EOKjDYpo@aWF zD0x7ps6>j3Wao;oNQe?G*x+YiG(;+0a!5fA=FSdW4Ja^jtw6jLPI;&P@RUW!^OM!QIc0QK#^|7m@)h$uBHa5I-1>>4Q??HAtk9 zC4rcpQc%DGz6kL|DW;F>d_WH-5%w-pN^e}cydAsOa(c|m!@~qPXJl;bDwUDj6T}3; z!mUBK(c}2%1ZHwF6-r_~Pz(Kx!|>Z5+%PhS0P*_({IZm6_9fpiMD%tekoAIEo;AP> z-UnZeKyLI+Z3zcBmITOfF=BhOSHPbj;kk$4dM0CrpeyD4-tw>lLlP7gFur>quQzXF zV*HLQ5uMfR$gklEAx>uXX9%i80nGU1A2FzpS;L(s#BDUpAD5sFDiy&{U`W8LP>S4F z^Z=wo&A^ZXse%-g21Q^|!QlgY^R1Jgrl(a$UbP@02y%o~kY6G`#%J}P`8Y@o)xi)D z*Ko4e!Zi;v!r(fgkeG;2HIzR-_J$pbIAoBGO%a8Yl*RfI;tLlr$d(6Gx9F9Hyc^=u z08o++?pnFIX#f=GL1y`3)^+f6<#1pn?D07iO4r~KlOQuvf{hE|4+$6dHt*QGx~4GV zTbY?jLPUX=zdaKEFguHeb-Wak1M<(xDk>2mq6s4AJAh95054q29)!S&cqsTn#)iBCs%Nv&;u?ghs*yeAQ>3y*-D|!9;-OT|Hv_;wEtF8j_hVbz4 zoq0{Rys+4#=|=;_V2UZm#jl~50|kuUHA8RT``4DwobCtJ!oM6D3O9W zzVk)7?5A%FU4~X#vXj7JxnAO2MgE@Ix|l9|@cke2#_)|uwHBI#oxShXfpVGX!S{Si zwx(6(?V=Hf7OnNFk*$$=%_3Yi`*~9@arQTKY)~#;c2{049SLup*IC^7@cwD~EA3N> zp%;J8TmD)CbXVz0J8p3N$1?t!$2B33fIfkF1)fBil1gHzny(X_v< zy8rq4m}%Ilrk1Jg=KuGG;&4{koIHm#@c#Gvp72&4MgM0Qe}4W`cd;dD?1Bv2>HmET z6F)aC3HFA(UZ4N*7SJilwcL_67IWz!ee&-C>VH1s;JxJQVM0!`s#h(|M`vY 0 - # fail_msg: "No errors found, validate test example" - # success_msg: "Errors found, proceeding" - # vars: - # job_templates_errors: __job_templates_errors_set_stats.ansible_stats.data.job_templates_errors - - # - name: Add Controller Settings Individually - # ansible.builtin.include_role: - # name: settings - # vars: - # controller_settings: "{{ controller_settings_individuale }}" - - # - name: Run ad hoc commands - # ansible.builtin.include_role: - # name: ad_hoc_command - # when: controller_ad_hoc_commands is defined - - # - name: Cancel Ad hoc commands - # ansible.builtin.include_tasks: "./tasks/ad_hoc_cancel.yml" - # when: controller_ad_hoc_commands is defined - - # - name: Launch Controller Bulk Hosts - # ansible.builtin.include_role: - # name: bulk_host_create - # vars: - # controller_bulk_hosts: "{{ temp_controller_bulk_hosts }}" - # when: - # - controller_bulk_launch_jobs is defined - - # - name: Launch Controller Jobs - # ansible.builtin.include_role: - # name: job_launch - # when: controller_launch_jobs is defined - - # - name: Show launched Controller jobs - # ansible.builtin.debug: - # var: launched_controller_jobs - - # - name: Combine id output with defaults temp - # ansible.builtin.set_fact: - # tmp_job: "{{ {'id': item.id} }}" - # with_items: "{{ launched_controller_jobs.results }}" - # register: tmp_jobs - - # - name: Cancel Controller Jobs - # ansible.builtin.include_role: - # name: jobs_cancel - # vars: - # controller_cancel_jobs: "{{ tmp_jobs.results | map(attribute='ansible_facts.tmp_job') | list }}" - # when: launched_controller_jobs is defined - - # - name: Find Job ID's - # ansible.builtin.debug: - # var: __job_templates_job_async_result - - # - name: Launch Controller Bulk Jobs - # ansible.builtin.include_role: - # name: bulk_job_launch - # vars: - # controller_bulk_hosts: "{{ temp_controller_bulk_hosts }}" - # controller_bulk_launch_jobs: - # - name: My Bulk Job Launch - # jobs: - # - unified_job_template: "{{ __job_templates_job_async_result.results[0].id }}" - # - unified_job_template: "{{ __job_templates_job_async_result.results[1].id }}" - # organization: Default - # wait: false - # when: - # - controller_bulk_launch_jobs is defined - - # - name: Launch Controller workflows - # ansible.builtin.include_role: - # name: workflow_launch - # when: controller_workflow_launch_jobs is defined - - # - name: Launched Workflows - # ansible.builtin.debug: - # var: launched_controller_workflows - - # - name: Wait for workflow to finish - # job_wait: - # job_id: "{{ launched_controller_workflows.results[0].id }}" - # job_type: workflow_jobs - # timeout: 180 - # controller_username: "{{ controller_username }}" - # controller_password: "{{ controller_password }}" - # controller_host: "{{ controller_hostname }}" - # validate_certs: "{{ controller_validate_certs }}" - # ignore_errors: true # noqa ignore-errors -... diff --git a/tests/playbooks/README.md b/tests/playbooks/README.md new file mode 100644 index 000000000..4e85123a1 --- /dev/null +++ b/tests/playbooks/README.md @@ -0,0 +1,139 @@ +# controller_configuration.configure_controller.yml playbook + +## Description + +An Ansible playbook to run any defined configurations on Ansible Controller. + +## Requirements + +ansible-galaxy collection install -r tests/collections/requirements.yml to be installed +Currently: + awx.awx + or + ansible.controller + +## Usage + +The following command will invoke the playbook with the ansible.controller collection + +```console +ansible-playbook infra.controller_configuration.configure_controller.yml +``` + +## Examples + +Examples of the playbooks in use can be found in the examples folder. + +## Variables + +### Standard Controller Variables + +|Variable Name|Default Value|Required|Description|Example| +|:---|:---:|:---:|:---|:---| +|`controller_state`|"present"|no|The state all objects will take unless overriden by object default|'absent'| +|`controller_hostname`|""|yes|URL to the Ansible Controller Server.|127.0.0.1| +|`controller_validate_certs`|`True`|no|Whether or not to validate the Ansible Controller Server's SSL certificate.|| +|`controller_username`|""|yes|Admin User on the Ansible Controller Server.|| +|`controller_password`|""|yes|Controller Admin User's password on the Ansible Controller Server. This should be stored in an Ansible Vault at vars/controller-secrets.yml or elsewhere and called from a parent playbook.|| +|`controller_oauthtoken`|""|yes|Controller Admin User's token on the Ansible Controller Server. This should be stored in an Ansible Vault at or elsewhere and called from a parent playbook.|| +|`controller_configs_dir`|`see role`|no|.|Directory with Controller configs. Falls back to env CONTROLLER_CONFIGS_DIR. Defaults to $PWD/configs| + +### Secure Logging Variables + +The following Variables compliment each other. +If Both variables are not set, secure logging defaults to false. +The role defaults to False as normally the add ad hoc commands task does not include sensitive information. +controller_configuration_ad_hoc_command_secure_logging defaults to the value of controller_configuration_secure_logging if it is not explicitly called. This allows for secure logging to be toggled for the entire suite of controller configuration roles with a single variable, or for the user to selectively use it. + +|Variable Name|Default Value|Required|Description| +|:---:|:---:|:---:|:---:| +|`controller_configuration_secure_logging`|`False`|no|This variable enables secure logging as well, but is shared accross multiple roles, see above.| + +## Data Structure + +### Config Top Level Vars + +|Variable Name|Default Value|Description| +|:---:|:---:|:---:| +|`controller_ad_hoc_commands`|`see role`|Data structure describing your ad hoc commands to run . Described in role.| +|`controller_ad_hoc_commands_cancel`|`see role`|Data structure describing your ad hoc jobs to cancel . Described in role.| +|`controller_applications`|`see role`|Data structure describing your applications. Described in role.| +|`controller_credential_input_sources`|`see role`|Data structure describing your credential input sources . Described in role.| +|`controller_credential_types`|`see role`|Data structure describing your credential types . Described in role.| +|`controller_credentials`|`see role`|Data structure describing your credentials . Described in role.| +|`controller_execution_environments`|`see role`|Data structure describing your organization or organizations . Described in role.| +|`controller_groups`|`see role`|Data structure describing your group or groups . Described in role.| +|`controller_hosts`|`see role`|Data structure describing your host entries . Described in role.| +|`controller_instance_groups`|`see role`|Data structure describing your instance groups . Described in role.| +|`controller_inventories`|`see role`|Data structure describing your inventories . Described in role.| +|`controller_inventory_sources`|`see role`|Data structure describing your inventory sources . Described in role.| +|`controller_launch_jobs`|`see role`|Data structure describing the jobs to launch . Described in role.| +|`controller_templates`|`see role`|Data structure describing your job template or job templates . Described in role.| +|`controller_cancel_jobs`|`see role`|Data structure describing jobs to cancel . Described in role.| +|`controller_labels`|`see role`|Data structure describing your label or labels . Described in role.| +|`controller_license`|`see role`|Data structure describing your license for controller, . Described in role.| +|`controller_notifications`|`see role`|Data structure describing your notification entries . Described in role.| +|`controller_organizations`|`see role`|Data structure describing your organization or organizations . Described in role.| +|`controller_projects`|`see role`|Data structure describing your project or projects . Described in role.| +|`controller_roles`|`see role`|Data structure describing your RBAC entries . Described in role.| +|`controller_schedules`|`see role`|Data structure describing your schedule or schedules . Described in role.| +|`controller_settings`|`see role`|Data structure describing your settings . Described in role.| +|`controller_teams`|`see role`|Data structure describing your Teams . Described in role.| +|`controller_user_accounts`|`see role`|Data structure describing your user entries . Described in role.| +|`workflow_job_templates`|`see role`|Data structure describing your workflow job templates . Described in role.| +|`controller_workflow_launch_jobs`|`see role`|Data structure describing workflow or workflows to launch . Described in role.| + +### Standard Configs Folder Data Structure + +```yaml +--- +└── configs + ├── ad_hoc_command_cancel_defaults.yml + ├── ad_hoc_commands.yml + ├── applications.yml + ├── controller_auth.yml + ├── credential_input_sources.yml + ├── credentials.yml + ├── credential_types.yml + ├── execution_environments.yml + ├── groups.yml + ├── hosts.yml + ├── instance_groups.yml + ├── inventories.yml + ├── inventory_sources.yml + ├── labels.yml + ├── launch_jobs.yml + ├── notifications.yml + ├── organizations.yml + ├── projects.yml + ├── roles.yml + ├── schedule.yml + ├── settings_individuale.yml + ├── settings.yml + ├── ssh_private_key.yml + ├── teams.yml + ├── templates.yml + ├── user_accounts.yml + ├── workflows.yml + └── workflows_launch.yml +``` + +## Configuring Continuous Deployment + +This section explains how to setup the Continuous Deployment (CD) of the defined configurations on Ansible controller when a event occurs(usually a merge event) in the git repository where the definitions are kept. + +This procedure has been tested with **gitlab** git server + +You have make the following configurations in order to configure CD integration: + +1. Configure a Project and a job template with [webhook](https://docs.ansible.com/automation-controller/latest/html/userguide/webhooks.html#id2) property enabled in the Controller pointing to the playbook in charge of CD, you can find an example [here](https://github.com/redhat-cop/aap_configuration/blob/devel/tests/playbooks/cd_gitlab_webhook_trigger.yml). + +2. Configure [project webhook](https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html) on the project where defined configurations are hosted. + +## License + +[GPL-3.0](https://github.com/redhat-cop/aap_configuration#licensing) + +## Author + +[Sean Sullivan](https://github.com/sean-m-sullivan/) diff --git a/tests/playbooks/cd_gitlab_webhook_trigger.yml b/tests/playbooks/cd_gitlab_webhook_trigger.yml new file mode 100644 index 000000000..824cf231c --- /dev/null +++ b/tests/playbooks/cd_gitlab_webhook_trigger.yml @@ -0,0 +1,69 @@ +--- +- name: Gitlab Webhook Trigger Playbook + hosts: all + connection: local + gather_facts: false + tasks: + - name: "Get the modified files over the dirs from all the received commits" + ansible.builtin.set_fact: + env: "{{ awx_webhook_payload.ref.split('/')[2] if awx_webhook_payload.ref.split('/')[1] == 'heads' else awx_webhook_payload.project.default_branch }}" + gitlab_scm_branch: "{{ awx_webhook_payload.ref.split('/')[2] }}" + orgs: "{{ awx_webhook_payload.project.name }}" + list_of_dirs: "{{ ((awx_webhook_payload.commits | map(attribute='added') | list) + + (awx_webhook_payload.commits | map(attribute='modified') | list) + + (awx_webhook_payload.commits | map(attribute='removed') | list)) + | flatten }}" + - name: "Set regular expression to filter files list from repository" + ansible.builtin.set_fact: + regexpression: "/([^/]*)/env/(common|{{ env }})/controller_(.*).d/" + + - name: "Get the Organization and the tags to run the CasC" + ansible.builtin.set_fact: + org_dirs_dict: "{{ (org_dirs_dict | default({})) | combine({input_var[0]: (((org_dirs_dict[input_var[0]] | default([])) + [input_var[1]] + (['projects', 'schedules'] if awx_webhook_payload.ref.split('/')[1] == 'tags' else [''])) | unique | reject('match', '^$'))}) }}" + vars: + input_var: "{{ item | regex_search(regexpression, '\\1', '\\3') }}" + loop: "{{ list_of_dirs }}" + when: input_var | type_debug is match('list') + + - name: Configure Controller Job Launch | Launch launch_jobs Drop Diff (Delete) + ansible.builtin.include_role: + name: infra.controller_configuration.job_launch + vars: + controller_launch_jobs: + - name: "{{ org_tags.key }} CasC_JobTemplates_AAP_Drop_Diff" + scm_branch: "{{ gitlab_scm_branch }}" + extra_vars: + orgs: "{{ org_tags.key }}" + dir_orgs_vars: 'orgs_vars' + ansible_python_interpreter: "/usr/bin/python3" + env: "{{ env }}" + gitlab_scm_branch: "{{ gitlab_scm_branch }}" + tags: "{{ org_tags.value }}" + wait: true + verbosity: 0 + with_dict: "{{ org_dirs_dict }}" + loop_control: + loop_var: org_tags + when: org_dirs_dict is defined + + - name: Configure Controller Job Launch | Launch launch_jobs creation + ansible.builtin.include_role: + name: infra.controller_configuration.job_launch + vars: + controller_launch_jobs: + - name: "{{ org_tags.key }} CasC_JobTemplates_AAP_CD_Config_Controller" + scm_branch: "{{ gitlab_scm_branch }}" + extra_vars: + orgs: "{{ org_tags.key }}" + dir_orgs_vars: 'orgs_vars' + ansible_python_interpreter: "/usr/bin/python3" + env: "{{ env }}" + gitlab_scm_branch: "{{ gitlab_scm_branch }}" + tags: "{{ org_tags.value }}" + wait: true + verbosity: 0 + with_dict: "{{ org_dirs_dict }}" + loop_control: + loop_var: org_tags + when: org_dirs_dict is defined +... diff --git a/tests/playbooks/configure_awx.yml b/tests/playbooks/configure_awx.yml new file mode 100644 index 000000000..31bbae543 --- /dev/null +++ b/tests/playbooks/configure_awx.yml @@ -0,0 +1,106 @@ +--- +### Variables +# +# Set the following variables on host_vars/localhost or group_vars/all +# +# - controller_validate_certs: +# description: | +# Wether to trust self-signed or invalid certificates +# Falls back to env CONTROLLER_VERIFY_SSL and then to awx-cli config. +# +# - controller_hostname: +# description: | +# Hostname of AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_HOST and then to awx-cli config. +# +# - controller_username: +# description: | +# Username for AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_USERNAME and then to awx-cli config. +# +# - controller_password: +# description: | +# Password for AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_PASSWORD and then to awx-cli config. +# +# - controller_configs_dir: +# description: | +# Directory with Controller configs. +# Falls back to env CONTROLLER_CONFIGS_DIR. +# Defaults to $PWD/configs +# + + +- name: Playbook to configure ansible Controller post installation + hosts: localhost + connection: local + collections: + - awx.awx + - infra.controller_configuration + pre_tasks: + + - name: Include vars from configs directory + ansible.builtin.include_vars: + dir: "{{ controller_configs_dir | default((lookup('env', 'CONTROLLER_CONFIGS_DIR') == '') | ternary('./configs', lookup('env', 'CONTROLLER_CONFIGS_DIR'))) }}" + ignore_files: [controller_config.yml.template] + extensions: ["yml"] + tags: + - always + + roles: + - {role: settings, when: controller_settings is defined, tags: settings} + - {role: organizations, when: controller_organizations is defined, tags: organizations} + - {role: labels, when: controller_labels is defined, tags: labels} + - {role: users, when: controller_user_accounts is defined, tags: users} + - {role: teams, when: controller_teams is defined, tags: teams} + - {role: credential_types, when: controller_credential_types is defined, tags: credential_types} + - {role: credentials, when: controller_credentials is defined, tags: credentials} + - {role: credential_input_sources, when: controller_credential_input_sources is defined, tags: credential_input_sources} + - {role: notification_templates, when: controller_notifications is defined, tags: notification_templates} + - {role: projects, when: controller_projects is defined, tags: projects} + - {role: execution_environments, when: controller_execution_environments is defined, tags: execution_environments} + - {role: applications, when: controller_applications is defined, tags: applications} + - {role: inventories, when: controller_inventories is defined, tags: inventories} + - {role: instance_groups, when: controller_instance_groups is defined, tags: instance_groups} + - {role: project_update, when: controller_projects is defined, tags: projects} + - {role: inventory_sources, when: controller_inventory_sources is defined, tags: inventory_sources} + - {role: inventory_source_update, when: controller_inventory_sources is defined, tags: inventory_sources} + - {role: hosts, when: controller_hosts is defined, tags: hosts} + - {role: groups, when: controller_groups is defined, tags: inventories} + - {role: job_templates, when: controller_templates is defined, tags: job_templates} + - {role: workflow_job_templates, when: controller_workflows is defined, tags: workflow_job_templates} + - {role: schedules, when: controller_schedules is defined, tags: schedules} + - {role: roles, when: controller_roles is defined, tags: roles} + + tasks: + + - name: Add Controller Settings Individually + ansible.builtin.include_role: + name: settings + vars: + controller_settings: "{{ controller_settings_individuale }}" + when: controller_settings_individuale is defined + + - name: Run ad hoc commands + ansible.builtin.include_role: + name: ad_hoc_command + when: controller_ad_hoc_commands is defined + + - name: Cancel Ad hoc commands + ansible.builtin.include_tasks: "./tasks/ad_hoc_cancel.yml" + when: controller_ad_hoc_commands is defined + + - name: Launch Controller Jobs + ansible.builtin.include_role: + name: job_launch + when: controller_launch_jobs is defined + + - name: Show launched Controller jobs + ansible.builtin.debug: + var: launched_controller_jobs + + - name: Launch Controller workflows + ansible.builtin.include_role: + name: workflow_launch + when: controller_workflow_launch_jobs is defined +... diff --git a/tests/playbooks/configure_controller.yml b/tests/playbooks/configure_controller.yml new file mode 100644 index 000000000..a41ed4e64 --- /dev/null +++ b/tests/playbooks/configure_controller.yml @@ -0,0 +1,106 @@ +--- +### Variables +# +# Set the following variables on host_vars/localhost or group_vars/all +# +# - controller_validate_certs: +# description: | +# Wether to trust self-signed or invalid certificates +# Falls back to env CONTROLLER_VERIFY_SSL and then to awx-cli config. +# +# - controller_hostname: +# description: | +# Hostname of AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_HOST and then to awx-cli config. +# +# - controller_username: +# description: | +# Username for AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_USERNAME and then to awx-cli config. +# +# - controller_password: +# description: | +# Password for AWX or Red Hat Ansible Automation Platform Controller. +# Falls back to env CONTROLLER_PASSWORD and then to awx-cli config. +# +# - controller_configs_dir: +# description: | +# Directory with Controller configs. +# Falls back to env CONTROLLER_CONFIGS_DIR. +# Defaults to $PWD/configs +# + + +- name: Playbook to configure ansible Controller post installation + hosts: localhost + connection: local + collections: + - ansible.controller + - infra.controller_configuration + pre_tasks: + + - name: Include vars from configs directory + ansible.builtin.include_vars: + dir: "{{ controller_configs_dir | default((lookup('env', 'CONTROLLER_CONFIGS_DIR') == '') | ternary('./configs', lookup('env', 'CONTROLLER_CONFIGS_DIR'))) }}" + ignore_files: [controller_config.yml.template] + extensions: ["yml"] + tags: + - always + + roles: + - {role: settings, when: controller_settings is defined, tags: settings} + - {role: organizations, when: controller_organizations is defined, tags: organizations} + - {role: labels, when: controller_labels is defined, tags: labels} + - {role: users, when: controller_user_accounts is defined, tags: users} + - {role: teams, when: controller_teams is defined, tags: teams} + - {role: credential_types, when: controller_credential_types is defined, tags: credential_types} + - {role: credentials, when: controller_credentials is defined, tags: credentials} + - {role: credential_input_sources, when: controller_credential_input_sources is defined, tags: credential_input_sources} + - {role: notification_templates, when: controller_notifications is defined, tags: notification_templates} + - {role: projects, when: controller_projects is defined, tags: projects} + - {role: execution_environments, when: controller_execution_environments is defined, tags: execution_environments} + - {role: applications, when: controller_applications is defined, tags: applications} + - {role: inventories, when: controller_inventories is defined, tags: inventories} + - {role: instance_groups, when: controller_instance_groups is defined, tags: instance_groups} + - {role: project_update, when: controller_projects is defined, tags: projects} + - {role: inventory_sources, when: controller_inventory_sources is defined, tags: inventory_sources} + - {role: inventory_source_update, when: controller_inventory_sources is defined, tags: inventory_sources} + - {role: hosts, when: controller_hosts is defined, tags: hosts} + - {role: groups, when: controller_groups is defined, tags: inventories} + - {role: job_templates, when: controller_templates is defined, tags: job_templates} + - {role: workflow_job_templates, when: controller_workflows is defined, tags: workflow_job_templates} + - {role: schedules, when: controller_schedules is defined, tags: schedules} + - {role: roles, when: controller_roles is defined, tags: roles} + + tasks: + + - name: Add Controller Settings Individually + ansible.builtin.include_role: + name: settings + vars: + controller_settings: "{{ controller_settings_individuale }}" + when: controller_settings_individuale is defined + + - name: Run ad hoc commands + ansible.builtin.include_role: + name: ad_hoc_command + when: controller_ad_hoc_commands is defined + + - name: Cancel Ad hoc commands + ansible.builtin.include_tasks: "./tasks/ad_hoc_cancel.yml" + when: controller_ad_hoc_commands is defined + + - name: Launch Controller Jobs + ansible.builtin.include_role: + name: job_launch + when: controller_launch_jobs is defined + + - name: Show launched Controller jobs + ansible.builtin.debug: + var: launched_controller_jobs + + - name: Launch Controller workflows + ansible.builtin.include_role: + name: workflow_launch + when: controller_workflow_launch_jobs is defined +... diff --git a/tests/playbooks/tasks/ad_hoc_cancel.yml b/tests/playbooks/tasks/ad_hoc_cancel.yml new file mode 100644 index 000000000..47ec7916a --- /dev/null +++ b/tests/playbooks/tasks/ad_hoc_cancel.yml @@ -0,0 +1,16 @@ +--- +- name: Combine id output with defaults temp + ansible.builtin.set_fact: + tmp_ad_hoc: "{{ item | combine(controller_ad_hoc_command_defaults) }}" + with_items: "{{ controller_ad_hoc_commands_output.results }}" + register: tmp_ad_hocs + +- name: Combine id output with defaults + ansible.builtin.set_fact: + controller_ad_hoc_commands_cancel: "{{ tmp_ad_hocs.results | map(attribute='ansible_facts.tmp_ad_hoc') | list }}" + +- name: Cancel ad hoc commands + ansible.builtin.include_role: + name: ad_hoc_command_cancel + when: controller_ad_hoc_commands is defined +...