diff options
author | Sloane Hertel <shertel@redhat.com> | 2020-06-10 00:38:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-10 00:38:57 +0200 |
commit | 51f6d129cbb30f42c445f7e2fecba68fe02d6f85 (patch) | |
tree | 11ff79f7cc1ef9fa8ac1134ccdc65d0217b6f297 /lib | |
parent | Deprecation revisited (#69926) (diff) | |
download | ansible-51f6d129cbb30f42c445f7e2fecba68fe02d6f85.tar.xz ansible-51f6d129cbb30f42c445f7e2fecba68fe02d6f85.zip |
support hard coded module_defaults.yml groups for collections (#69919)
* Only allow groups which were hardcoded in module_defaults.yml
only load action groups from the collection if module_defaults contains a potential group for the action
* Fix tests using modules that override those whitelisted in lib/ansible/config/module_defaults.yml
Third party modules should not be using group/ - use the action name instead
* add externalized module_defaults tests
add the missing group and collections
ci_complete
Co-authored-by: Matt Davis <mrd@redhat.com>
* changelog
ci_complete
* Fix import in tests
ci_complete
* Update with requested changes
ci_complete
* don't traceback since we don't validate the contents of module_defaults
ci_complete
Co-authored-by: Matt Davis <mrd@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ansible/config/manager.py | 14 | ||||
-rw-r--r-- | lib/ansible/config/module_defaults.yml | 1545 | ||||
-rw-r--r-- | lib/ansible/executor/module_common.py | 43 | ||||
-rw-r--r-- | lib/ansible/executor/task_executor.py | 4 | ||||
-rw-r--r-- | lib/ansible/parsing/mod_args.py | 24 | ||||
-rw-r--r-- | lib/ansible/playbook/task.py | 14 | ||||
-rw-r--r-- | lib/ansible/plugins/action/gather_facts.py | 2 | ||||
-rw-r--r-- | lib/ansible/plugins/action/package.py | 4 | ||||
-rw-r--r-- | lib/ansible/plugins/action/service.py | 4 | ||||
-rw-r--r-- | lib/ansible/plugins/loader.py | 4 | ||||
-rw-r--r-- | lib/ansible/utils/collection_loader/_collection_finder.py | 9 |
11 files changed, 95 insertions, 1572 deletions
diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py index 18d2d11c95..3cbfb38d44 100644 --- a/lib/ansible/config/manager.py +++ b/lib/ansible/config/manager.py @@ -289,12 +289,6 @@ class ConfigManager(object): # update constants self.update_config_data() - try: - self.update_module_defaults_groups() - except Exception as e: - # Since this is a 2.7 preview feature, we want to have it fail as gracefully as possible when there are issues. - sys.stderr.write('Could not load module_defaults_groups: %s: %s\n\n' % (type(e).__name__, e)) - self.module_defaults_groups = {} def _read_config_yaml_file(self, yml_file): # TODO: handle relative paths as relative to the directory containing the current playbook instead of CWD @@ -525,14 +519,6 @@ class ConfigManager(object): self._plugins[plugin_type][name] = defs - def update_module_defaults_groups(self): - defaults_config = self._read_config_yaml_file( - '%s/module_defaults.yml' % os.path.join(os.path.dirname(__file__)) - ) - if defaults_config.get('version') not in ('1', '1.0', 1, 1.0): - raise AnsibleError('module_defaults.yml has an invalid version "%s" for configuration. Could be a bad install.' % defaults_config.get('version')) - self.module_defaults_groups = defaults_config.get('groupings', {}) - def update_config_data(self, defs=None, configfile=None): ''' really: update constants ''' diff --git a/lib/ansible/config/module_defaults.yml b/lib/ansible/config/module_defaults.yml deleted file mode 100644 index aff04a7668..0000000000 --- a/lib/ansible/config/module_defaults.yml +++ /dev/null @@ -1,1545 +0,0 @@ ---- -version: '1.0' -groupings: - acme_account: - - acme - acme_account_info: - - acme - acme_account_facts: - - acme - acme_certificate: - - acme - acme_certificate_revoke: - - acme - acme_inspect: - - acme - aws_acm: - - aws - aws_acm_facts: - - aws - aws_acm_info: - - aws - aws_api_gateway: - - aws - aws_application_scaling_policy: - - aws - aws_az_facts: - - aws - aws_az_info: - - aws - aws_batch_compute_environment: - - aws - aws_batch_job_definition: - - aws - aws_batch_job_queue: - - aws - aws_caller_facts: - - aws - aws_caller_info: - - aws - aws_codebuild: - - aws - aws_codecommit: - - aws - aws_codepipeline: - - aws - aws_config_aggregation_authorization: - - aws - aws_config_aggregator: - - aws - aws_config_delivery_channel: - - aws - aws_config_recorder: - - aws - aws_config_rule: - - aws - aws_direct_connect_connection: - - aws - aws_direct_connect_gateway: - - aws - aws_direct_connect_link_aggregation_group: - - aws - aws_direct_connect_virtual_interface: - - aws - aws_eks_cluster: - - aws - aws_elasticbeanstalk_app: - - aws - aws_glue_connection: - - aws - aws_glue_job: - - aws - aws_inspector_target: - - aws - aws_kms: - - aws - aws_kms_facts: - - aws - aws_kms_info: - - aws - aws_region_facts: - - aws - aws_region_info: - - aws - aws_s3: - - aws - aws_s3_bucket_facts: - - aws - aws_s3_bucket_info: - - aws - aws_s3_cors: - - aws - aws_secret: - - aws - aws_ses_identity: - - aws - aws_ses_identity_policy: - - aws - aws_ses_rule_set: - - aws - aws_sgw_facts: - - aws - aws_sgw_info: - - aws - aws_ssm_parameter_store: - - aws - aws_step_functions_state_machine: - - aws - aws_step_functions_state_machine_execution: - - aws - aws_waf_condition: - - aws - aws_waf_facts: - - aws - aws_waf_info: - - aws - aws_waf_rule: - - aws - aws_waf_web_acl: - - aws - cloudformation: - - aws - cloudformation_exports_info: - - aws - cloudformation_facts: - - aws - cloudformation_info: - - aws - cloudformation_stack_set: - - aws - cloudfront_distribution: - - aws - cloudfront_facts: - - aws - cloudfront_info: - - aws - cloudfront_invalidation: - - aws - cloudfront_origin_access_identity: - - aws - cloudtrail: - - aws - cloudwatchevent_rule: - - aws - cloudwatchlogs_log_group: - - aws - cloudwatchlogs_log_group_facts: - - aws - cloudwatchlogs_log_group_info: - - aws - cloudwatchlogs_log_group_metric_filter: - - aws - cpm_plugconfig: - - cpm - cpm_plugcontrol: - - cpm - cpm_serial_port_config: - - cpm - cpm_serial_port_info: - - cpm - cpm_user: - - cpm - data_pipeline: - - aws - dms_endpoint: - - aws - dms_replication_subnet_group: - - aws - docker_compose: - - docker - docker_config: - - docker - docker_container_info: - - docker - docker_container: - - docker - docker_host_info: - - docker - docker_image_facts: - - docker - docker_image_info: - - docker - docker_image: - - docker - docker_login: - - docker - docker_network_info: - - docker - docker_network: - - docker - docker_node_info: - - docker - docker_node: - - docker - docker_prune: - - docker - docker_secret: - - docker - docker_service: - - docker - docker_swarm_info: - - docker - docker_swarm: - - docker - docker_swarm_service_info: - - docker - docker_swarm_service: - - docker - docker_volume_info: - - docker - docker_volume: - - docker - dynamodb_table: - - aws - dynamodb_ttl: - - aws - ec2: - - aws - ec2_ami: - - aws - ec2_ami_copy: - - aws - ec2_ami_facts: - - aws - ec2_ami_info: - - aws - ec2_asg: - - aws - ec2_asg_facts: - - aws - ec2_asg_info: - - aws - ec2_asg_lifecycle_hook: - - aws - ec2_customer_gateway: - - aws - ec2_customer_gateway_facts: - - aws - ec2_customer_gateway_info: - - aws - ec2_eip: - - aws - ec2_eip_facts: - - aws - ec2_eip_info: - - aws - ec2_elb: - - aws - ec2_elb_facts: - - aws - ec2_elb_info: - - aws - ec2_elb_lb: - - aws - ec2_eni: - - aws - ec2_eni_facts: - - aws - ec2_eni_info: - - aws - ec2_group: - - aws - ec2_group_facts: - - aws - ec2_group_info: - - aws - ec2_instance: - - aws - ec2_instance_facts: - - aws - ec2_instance_info: - - aws - ec2_key: - - aws - ec2_launch_template: - - aws - ec2_lc: - - aws - ec2_lc_facts: - - aws - ec2_lc_info: - - aws - ec2_lc_find: - - aws - ec2_metric_alarm: - - aws - ec2_placement_group: - - aws - ec2_placement_group_facts: - - aws - ec2_placement_group_info: - - aws - ec2_scaling_policy: - - aws - ec2_snapshot: - - aws - ec2_snapshot_copy: - - aws - ec2_snapshot_facts: - - aws - ec2_snapshot_info: - - aws - ec2_tag: - - aws - ec2_tag_info: - - aws - ec2_transit_gateway: - - aws - ec2_transit_gateway_info: - - aws - ec2_vol: - - aws - ec2_vol_facts: - - aws - ec2_vol_info: - - aws - ec2_vpc_dhcp_option: - - aws - ec2_vpc_dhcp_option_facts: - - aws - ec2_vpc_dhcp_option_info: - - aws - ec2_vpc_egress_igw: - - aws - ec2_vpc_endpoint: - - aws - ec2_vpc_endpoint_facts: - - aws - ec2_vpc_endpoint_info: - - aws - ec2_vpc_igw: - - aws - ec2_vpc_igw_facts: - - aws - ec2_vpc_igw_info: - - aws - ec2_vpc_nacl: - - aws - ec2_vpc_nacl_facts: - - aws - ec2_vpc_nacl_info: - - aws - ec2_vpc_nat_gateway: - - aws - ec2_vpc_nat_gateway_facts: - - aws - ec2_vpc_nat_gateway_info: - - aws - ec2_vpc_net: - - aws - ec2_vpc_net_facts: - - aws - ec2_vpc_net_info: - - aws - ec2_vpc_peer: - - aws - ec2_vpc_peering_facts: - - aws - ec2_vpc_peering_info: - - aws - ec2_vpc_route_table: - - aws - ec2_vpc_route_table_facts: - - aws - ec2_vpc_route_table_info: - - aws - ec2_vpc_subnet: - - aws - ec2_vpc_subnet_facts: - - aws - ec2_vpc_subnet_info: - - aws - ec2_vpc_vgw: - - aws - ec2_vpc_vgw_facts: - - aws - ec2_vpc_vgw_info: - - aws - ec2_vpc_vpn: - - aws - ec2_vpc_vpn_facts: - - aws - ec2_vpc_vpn_info: - - aws - ec2_win_password: - - aws - ecs_attribute: - - aws - ecs_cluster: - - aws - ecs_ecr: - - aws - ecs_service: - - aws - ecs_service_facts: - - aws - ecs_service_info: - - aws - ecs_tag: - - aws - ecs_task: - - aws - ecs_taskdefinition: - - aws - ecs_taskdefinition_facts: - - aws - ecs_taskdefinition_info: - - aws - efs: - - aws - efs_facts: - - aws - efs_info: - - aws - elasticache: - - aws - elasticache_facts: - - aws - elasticache_info: - - aws - elasticache_parameter_group: - - aws - elasticache_snapshot: - - aws - elasticache_subnet_group: - - aws - elb_application_lb: - - aws - elb_application_lb_facts: - - aws - elb_application_lb_info: - - aws - elb_classic_lb: - - aws - elb_classic_lb_facts: - - aws - elb_classic_lb_info: - - aws - elb_instance: - - aws - elb_network_lb: - - aws - elb_target: - - aws - elb_target_facts: - - aws - elb_target_group: - - aws - elb_target_group_facts: - - aws - elb_target_group_info: - - aws - elb_target_info: - - aws - execute_lambda: - - aws - iam: - - aws - iam_cert: - - aws - iam_group: - - aws - iam_managed_policy: - - aws - iam_mfa_device_facts: - - aws - iam_mfa_device_info: - - aws - iam_password_policy: - - aws - iam_policy: - - aws - iam_policy_info: - - aws - iam_role: - - aws - iam_role_facts: - - aws - iam_role_info: - - aws - iam_server_certificate_facts: - - aws - iam_saml_federation: - - aws - iam_server_certificate_info: - - aws - iam_user: - - aws - iam_user_info: - - aws - kinesis_stream: - - aws - lambda: - - aws - lambda_alias: - - aws - lambda_event: - - aws - lambda_facts: - - aws - lambda_info: - - aws - lambda_policy: - - aws - lightsail: - - aws - lightsail_keypair: - - aws - rds: - - aws - rds_instance: - - aws - rds_instance_facts: - - aws - rds_instance_info: - - aws - rds_param_group: - - aws - rds_snapshot_facts: - - aws - rds_snapshot_info: - - aws - rds_subnet_group: - - aws - redshift: - - aws - redshift_cross_region_snapshots: - - aws - redshift_facts: - - aws - redshift_info: - - aws - redshift_subnet_group: - - aws - route53: - - aws - route53_facts: - - aws - route53_info: - - aws - route53_health_check: - - aws - route53_zone: - - aws - s3_bucket: - - aws - s3_bucket_notification: - - aws - s3_lifecycle: - - aws - s3_logging: - - aws - s3_sync: - - aws - s3_website: - - aws - sns: - - aws - sns_topic: - - aws - sqs_queue: - - aws - sts_assume_role: - - aws - sts_session_token: - - aws - gcp_appengine_firewall_rule: - - gcp - gcp_appengine_firewall_rule_info: - - gcp - gcp_bigquery_dataset: - - gcp - gcp_bigquery_dataset_info: - - gcp - gcp_bigquery_table: - - gcp - gcp_bigquery_table_info: - - gcp - gcp_cloudbuild_trigger: - - gcp - gcp_cloudbuild_trigger_info: - - gcp - gcp_cloudfunctions_cloud_function: - - gcp - gcp_cloudfunctions_cloud_function_info: - - gcp - gcp_cloudscheduler_job: - - gcp - gcp_cloudscheduler_job_info: - - gcp - gcp_cloudtasks_queue: - - gcp - gcp_cloudtasks_queue_info: - - gcp - gcp_compute_address: - - gcp - gcp_compute_address_info: - - gcp - gcp_compute_autoscaler: - - gcp - gcp_compute_autoscaler_info: - - gcp - gcp_compute_backend_bucket: - - gcp - gcp_compute_backend_bucket_info: - - gcp - gcp_compute_backend_service: - - gcp - gcp_compute_backend_service_info: - - gcp - gcp_compute_disk: - - gcp - gcp_compute_disk_info: - - gcp - gcp_compute_firewall: - - gcp - gcp_compute_firewall_info: - - gcp - gcp_compute_forwarding_rule: - - gcp - gcp_compute_forwarding_rule_info: - - gcp - gcp_compute_global_address: - - gcp - gcp_compute_global_address_info: - - gcp - gcp_compute_global_forwarding_rule: - - gcp - gcp_compute_global_forwarding_rule_info: - - gcp - gcp_compute_health_check: - - gcp - gcp_compute_health_check_info: - - gcp - gcp_compute_http_health_check: - - gcp - gcp_compute_http_health_check_info: - - gcp - gcp_compute_https_health_check: - - gcp - gcp_compute_https_health_check_info: - - gcp - gcp_compute_image: - - gcp - gcp_compute_image_info: - - gcp - gcp_compute_instance: - - gcp - gcp_compute_instance_info: - - gcp - gcp_compute_instance_group: - - gcp - gcp_compute_instance_group_info: - - gcp - gcp_compute_instance_group_manager: - - gcp - gcp_compute_instance_group_manager_info: - - gcp - gcp_compute_instance_template: - - gcp - gcp_compute_instance_template_info: - - gcp - gcp_compute_interconnect_attachment: - - gcp - gcp_compute_interconnect_attachment_info: - - gcp - gcp_compute_network: - - gcp - gcp_compute_network_info: - - gcp - gcp_compute_network_endpoint_group: - - gcp - gcp_compute_network_endpoint_group_info: - - gcp - gcp_compute_node_group: - - gcp - gcp_compute_node_group_info: - - gcp - gcp_compute_node_template: - - gcp - gcp_compute_node_template_info: - - gcp - gcp_compute_region_backend_service: - - gcp - gcp_compute_region_backend_service_info: - - gcp - gcp_compute_region_disk: - - gcp - gcp_compute_region_disk_info: - - gcp - gcp_compute_reservation: - - gcp - gcp_compute_reservation_info: - - gcp - gcp_compute_route: - - gcp - gcp_compute_route_info: - - gcp - gcp_compute_router: - - gcp - gcp_compute_router_info: - - gcp - gcp_compute_snapshot: - - gcp - gcp_compute_snapshot_info: - - gcp - gcp_compute_ssl_certificate: - - gcp - gcp_compute_ssl_certificate_info: - - gcp - gcp_compute_ssl_policy: - - gcp - gcp_compute_ssl_policy_info: - - gcp - gcp_compute_subnetwork: - - gcp - gcp_compute_subnetwork_info: - - gcp - gcp_compute_target_http_proxy: - - gcp - gcp_compute_target_http_proxy_info: - - gcp - gcp_compute_target_https_proxy: - - gcp - gcp_compute_target_https_proxy_info: - - gcp - gcp_compute_target_instance: - - gcp - gcp_compute_target_instance_info: - - gcp - gcp_compute_target_pool: - - gcp - gcp_compute_target_pool_info: - - gcp - gcp_compute_target_ssl_proxy: - - gcp - gcp_compute_target_ssl_proxy_info: - - gcp - gcp_compute_target_tcp_proxy: - - gcp - gcp_compute_target_tcp_proxy_info: - - gcp - gcp_compute_target_vpn_gateway: - - gcp - gcp_compute_target_vpn_gateway_info: - - gcp - gcp_compute_url_map: - - gcp - gcp_compute_url_map_info: - - gcp - gcp_compute_vpn_tunnel: - - gcp - gcp_compute_vpn_tunnel_info: - - gcp - gcp_container_cluster: - - gcp - gcp_container_cluster_info: - - gcp - gcp_container_node_pool: - - gcp - gcp_container_node_pool_info: - - gcp - gcp_dns_managed_zone: - - gcp - gcp_dns_managed_zone_info: - - gcp - gcp_dns_resource_record_set: - - gcp - gcp_dns_resource_record_set_info: - - gcp - gcp_filestore_instance: - - gcp - gcp_filestore_instance_info: - - gcp - gcp_iam_role: - - gcp - gcp_iam_role_info: - - gcp - gcp_iam_service_account: - - gcp - gcp_iam_service_account_info: - - gcp - gcp_iam_service_account_key: - - gcp - gcp_kms_crypto_key: - - gcp - gcp_kms_crypto_key_info: - - gcp - gcp_kms_key_ring: - - gcp - gcp_kms_key_ring_info: - - gcp - gcp_logging_metric: - - gcp - gcp_logging_metric_info: - - gcp - gcp_mlengine_model: - - gcp - gcp_mlengine_model_info: - - gcp - gcp_mlengine_version: - - gcp - gcp_mlengine_version_info: - - gcp - gcp_pubsub_subscription: - - gcp - gcp_pubsub_subscription_info: - - gcp - gcp_pubsub_topic: - - gcp - gcp_pubsub_topic_info: - - gcp - gcp_redis_instance: - - gcp - gcp_redis_instance_info: - - gcp - gcp_resourcemanager_project: - - gcp - gcp_resourcemanager_project_info: - - gcp - gcp_runtimeconfig_config: - - gcp - gcp_runtimeconfig_config_info: - - gcp - gcp_runtimeconfig_variable: - - gcp - gcp_runtimeconfig_variable_info: - - gcp - gcp_serviceusage_service: - - gcp - gcp_serviceusage_service_info: - - gcp - gcp_sourcerepo_repository: - - gcp - gcp_sourcerepo_repository_info: - - gcp - gcp_spanner_database: - - gcp - gcp_spanner_database_info: - - gcp - gcp_spanner_instance: - - gcp - gcp_spanner_instance_info: - - gcp - gcp_sql_database: - - gcp - gcp_sql_database_info: - - gcp - gcp_sql_instance: - - gcp - gcp_sql_instance_info: - - gcp - gcp_sql_user: - - gcp - gcp_sql_user_info: - - gcp - gcp_storage_bucket: - - gcp - gcp_storage_bucket_access_control: - - gcp - gcp_storage_object: - - gcp - gcp_tpu_node: - - gcp - gcp_tpu_node_info: - - gcp - azure_rm_acs: - - azure - azure_rm_aks: - - azure - azure_rm_aks_facts: - - azure - azure_rm_appserviceplan: - - azure - azure_rm_appserviceplan_facts: - - azure - azure_rm_availabilityset: - - azure - azure_rm_availabilityset_facts: - - azure - azure_rm_containerinstance: - - azure - azure_rm_containerregistry: - - azure - azure_rm_deployment: - - azure - azure_rm_dnsrecordset: - - azure - azure_rm_dnsrecordset_facts: - - azure - azure_rm_dnszone: - - azure - azure_rm_dnszone_facts: - - azure - azure_rm_functionapp: - - azure - azure_rm_functionapp_facts: - - azure - azure_rm_image: - - azure - azure_rm_keyvault: - - azure - azure_rm_keyvaultkey: - - azure - azure_rm_keyvaultsecret: - - azure - azure_rm_loadbalancer: - - azure - azure_rm_loadbalancer_facts: - - azure - azure_rm_managed_disk: - - azure - azure_rm_manageddisk: - - azure - azure_rm_managed_disk_facts: - - azure - azure_rm_manageddisk_facts: - - azure - azure_rm_mysqldatabase: - - azure - azure_rm_mysqldatabase_facts: - - azure - azure_rm_mysqlserver: - - azure - azure_rm_mysqlserver_facts: - - azure - azure_rm_networkinterface: - - azure - azure_rm_networkinterface_facts: - - azure - azure_rm_postgresqldatabase: - - azure - azure_rm_postgresqldatabase_facts: - - azure - azure_rm_postgresqlserver: - - azure - azure_rm_publicipaddress: - - azure - azure_rm_publicipaddress_facts: - - azure - azure_rm_resource: - - azure - azure_rm_resource_facts: - - azure - azure_rm_resourcegroup: - - azure - azure_rm_resourcegroup_facts: - - azure - azure_rm_resourcegroup_info: - - azure - azure_rm_securitygroup: - - azure - azure_rm_securitygroup_facts: - - azure - azure_rm_sqldatabase: - - azure - azure_rm_sqlserver: - - azure - azure_rm_sqlserver_facts: - - azure - azure_rm_storageaccount: - - azure - azure_rm_storageaccount_facts: - - azure - azure_rm_storageblob: - - azure - azure_rm_subnet: - - azure - azure_rm_virtualmachine: - - azure - azure_rm_virtualmachine_extension: - - azure - azure_rm_virtualmachine_facts: - - azure - azure_rm_virtualmachineimage_facts: - - azure - azure_rm_virtualmachine_scaleset: - - azure - azure_rm_virtualmachine_scaleset_facts: - - azure - azure_rm_virtualnetwork: - - azure - azure_rm_virtualnetwork_facts: - - azure - azure_rm_webapp: - - azure - k8s: - - k8s - k8s_auth: - - k8s - k8s_facts: - - k8s - k8s_info: - - k8s - k8s_service: - - k8s - k8s_scale: - - k8s - kubevirt_cdi_upload: - - k8s - kubevirt_preset: - - k8s - kubevirt_pvc: - - k8s - kubevirt_rs: - - k8s - kubevirt_template: - - k8s - kubevirt_vm: - - k8s - os_auth: - - os - os_client_config: - - os - os_coe_cluster: - - os - os_coe_cluster_template: - - os - os_flavor_facts: - - os - os_flavor_info: - - os - os_floating_ip: - - os - os_group: - - os - os_image: - - os - os_image_facts: - - os - os_image_info: - - os - os_ironic: - - os - os_ironic_inspect: - - os - os_ironic_node: - - os - os_keypair: - - os - os_keystone_domain: - - os - os_keystone_domain_facts: - - os - os_keystone_domain_info: - - os - os_keystone_endpoint: - - os - os_keystone_role: - - os - os_keystone_service: - - os - os_listener: - - os - os_loadbalancer: - - os - os_member: - - os - os_network: - - os - os_networks_facts: - - os - os_networks_info: - - os - os_nova_flavor: - - os - os_nova_host_aggregate: - - os - os_object: - - os - os_pool: - - os - os_port: - - os - os_port_facts: - - os - os_port_info: - - os - os_project: - - os - os_project_access: - - os - os_project_facts: - - os - os_project_info: - - os - os_quota: - - os - os_recordset: - - os - os_router: - - os - os_security_group: - - os - os_security_group_rule: - - os - os_server: - - os - os_server_action: - - os - os_server_facts: - - os - os_server_info: - - os - os_server_group: - - os - os_server_metadata: - - os - os_server_volume: - - os - os_stack: - - os - os_subnet: - - os - os_subnets_facts: - - os - os_subnets_info: - - os - os_user: - - os - os_user_facts: - - os - os_user_info: - - os - os_user_group: - - os - os_user_role: - - os - os_volume: - - os - os_volume_snapshot: - - os - os_zone: - - os - ovirt_affinity_group: - - ovirt - ovirt_affinity_label_facts: - - ovirt - ovirt_affinity_label_info: - - ovirt - ovirt_affinity_label: - - ovirt - ovirt_api_facts: - - ovirt - ovirt_api_info: - - ovirt - ovirt_auth: - - ovirt - ovirt_cluster_facts: - - ovirt - ovirt_cluster_info: - - ovirt - ovirt_cluster: - - ovirt - ovirt_datacenter_facts: - - ovirt - ovirt_datacenter_info: - - ovirt - ovirt_datacenter: - - ovirt - ovirt_disk_facts: - - ovirt - ovirt_disk_info: - - ovirt - ovirt_disk: - - ovirt - ovirt_event_facts: - - ovirt - ovirt_event_info: - - ovirt - ovirt_event: - - ovirt - ovirt_external_provider_facts: - - ovirt - ovirt_external_provider_info: - - ovirt - ovirt_external_provider: - - ovirt - ovirt_group_facts: - - ovirt - ovirt_group_info: - - ovirt - ovirt_group: - - ovirt - ovirt_host_facts: - - ovirt - ovirt_host_info: - - ovirt - ovirt_host_network: - - ovirt - ovirt_host_pm: - - ovirt - ovirt_host: - - ovirt - ovirt_host_storage_facts: - - ovirt - ovirt_host_storage_info: - - ovirt - ovirt_instance_type: - - ovirt - ovirt_job: - - ovirt - ovirt_mac_pool: - - ovirt - ovirt_network_facts: - - ovirt - ovirt_network_info: - - ovirt - ovirt_network: - - ovirt - ovirt_nic_facts: - - ovirt - ovirt_nic_info: - - ovirt - ovirt_nic: - - ovirt - ovirt_permission_facts: - - ovirt - ovirt_permission_info: - - ovirt - ovirt_permission: - - ovirt - ovirt_quota_facts: - - ovirt - ovirt_quota_info: - - ovirt - ovirt_quota: - - ovirt - ovirt_role: - - ovirt - ovirt_scheduling_policy_facts: - - ovirt - ovirt_scheduling_policy_info: - - ovirt - ovirt_snapshot_facts: - - ovirt - ovirt_snapshot_info: - - ovirt - ovirt_snapshot: - - ovirt - ovirt_storage_connection: - - ovirt - ovirt_storage_domain_facts: - - ovirt - ovirt_storage_domain_info: - - ovirt - ovirt_storage_domain: - - ovirt - ovirt_storage_template_facts: - - ovirt - ovirt_storage_template_info: - - ovirt - ovirt_storage_vm_facts: - - ovirt - ovirt_storage_vm_info: - - ovirt - ovirt_tag_facts: - - ovirt - ovirt_tag_info: - - ovirt - ovirt_tag: - - ovirt - ovirt_template_facts: - - ovirt - ovirt_template_info: - - ovirt - ovirt_template: - - ovirt - ovirt_user_facts: - - ovirt - ovirt_user_info: - - ovirt - ovirt_user: - - ovirt - ovirt_vm_facts: - - ovirt - ovirt_vm_info: - - ovirt - ovirt_vmpool_facts: - - ovirt - ovirt_vmpool_info: - - ovirt - ovirt_vmpool: - - ovirt - ovirt_vm: - - ovirt - ovirt_vnic_profile_info: - - ovirt - ovirt_vnic_profile: - - ovirt - test_module_defaults: - - test - vcenter_extension: - - vmware - vcenter_extension_info: - - vmware - vcenter_folder: - - vmware - vcenter_license: - - vmware - vmware_about_info: - - vmware - vmware_category: - - vmware - vmware_category_info: - - vmware - vmware_cfg_backup: - - vmware - vmware_cluster: - - vmware - vmware_cluster_drs: - - vmware - vmware_cluster_ha: - - vmware - vmware_cluster_info: - - vmware - vmware_cluster_vsan: - - vmware - vmware_content_deploy_template: - - vmware - vmware_content_library_info: - - vmware - vmware_content_library_manager: - - vmware - vmware_datacenter: - - vmware - vmware_datastore_cluster: - - vmware - vmware_datastore_info: - - vmware - vmware_datastore_maintenancemode: - - vmware - vmware_deploy_ovf: - - vmware - vmware_dns_config: - - vmware - vmware_drs_group: - - vmware - vmware_drs_group_info: - - vmware - vmware_drs_rule_info: - - vmware - vmware_dvs_host: - - vmware - vmware_dvs_portgroup: - - vmware - vmware_dvs_portgroup_find: - - vmware - vmware_dvs_portgroup_info: - - vmware - vmware_dvswitch: - - vmware - vmware_dvswitch_lacp: - - vmware - vmware_dvswitch_nioc: - - vmware - vmware_dvswitch_pvlans: - - vmware - vmware_dvswitch_uplink_pg: - - vmware - vmware_evc_mode: - - vmware - vmware_export_ovf: - - vmware - vmware_folder_info: - - vmware - vmware_guest: - - vmware - vmware_guest_boot_info: - - vmware - vmware_guest_boot_manager: - - vmware - vmware_guest_controller: - - vmware - vmware_guest_custom_attribute_defs: - - vmware - vmware_guest_custom_attributes: - - vmware - vmware_guest_customization_info: - - vmware - vmware_guest_disk: - - vmware - vmware_guest_disk_info: - - vmware - vmware_guest_file_operation: - - vmware - vmware_guest_find: - - vmware - vmware_guest_info: - - vmware - vmware_guest_move: - - vmware - vmware_guest_network: - - vmware - vmware_guest_powerstate: - - vmware - vmware_guest_register_operation: - - vmware - vmware_guest_screenshot: - - vmware - vmware_guest_sendkey: - - vmware - vmware_guest_serial_port: - - vmware - vmware_guest_snapshot: - - vmware - vmware_guest_snapshot_info: - - vmware - vmware_guest_tools_info: - - vmware - vmware_guest_tools_upgrade: - - vmware - vmware_guest_tools_wait: - - vmware - vmware_guest_video: - - vmware - vmware_guest_vnc: - - vmware - vmware_host: - - vmware - vmware_host_acceptance: - - vmware - vmware_host_active_directory: - - vmware - vmware_host_auto_start: - - vmware - vmware_host_capability_info: - - vmware - vmware_host_config_info: - - vmware - vmware_host_config_manager: - - vmware - vmware_host_datastore: - - vmware - vmware_host_dns: - - vmware - vmware_host_dns_info: - - vmware - vmware_host_facts: - - vmware - vmware_host_feature_info: - - vmware - vmware_host_firewall_info: - - vmware - vmware_host_firewall_manager: - - vmware - vmware_host_hyperthreading: - - vmware - vmware_host_ipv6: - - vmware - vmware_host_kernel_manager: - - vmware - vmware_host_lockdown: - - vmware - vmware_host_ntp: - - vmware - vmware_host_ntp_info: - - vmware - vmware_host_package_info: - - vmware - vmware_host_powermgmt_policy: - - vmware - vmware_host_powerstate: - - vmware - vmware_host_scanhba: - - vmware - vmware_host_service_info: - - vmware - vmware_host_service_manager: - - vmware - vmware_host_snmp: - - vmware - vmware_host_ssl_info: - - vmware - vmware_host_vmhba_info: - - vmware - vmware_host_vmnic_info: - - vmware - vmware_local_role_info: - - vmware - vmware_local_role_manager: - - vmware - vmware_local_user_info: - - vmware - vmware_local_user_manager: - - vmware - vmware_maintenancemode: - - vmware - vmware_migrate_vmk: - - vmware - vmware_object_role_permission: - - vmware - vmware_portgroup: - - vmware - vmware_portgroup_info: - - vmware - vmware_resource_pool: - - vmware - vmware_resource_pool_info: - - vmware - vmware_tag: - - vmware - vmware_tag_info: - - vmware - vmware_tag_manager: - - vmware - vmware_target_canonical_info: - - vmware - vmware_vcenter_settings: - - vmware - vmware_vcenter_statistics: - - vmware - vmware_vm_host_drs_rule: - - vmware - vmware_vm_info: - - vmware - vmware_vm_shell: - - vmware - vmware_vm_storage_policy_info: - - vmware - vmware_vm_vm_drs_rule: - - vmware - vmware_vm_vss_dvs_migrate: - - vmware - vmware_vmkernel: - - vmware - vmware_vmkernel_info: - - vmware - vmware_vmkernel_ip_config: - - vmware - vmware_vmotion: - - vmware - vmware_vsan_cluster: - - vmware - vmware_vsan_health_info: - - vmware - vmware_vspan_session: - - vmware - vmware_vswitch: - - vmware - vmware_vswitch_info: - - vmware - vsphere_copy: - - vmware - vsphere_file: - - vmware diff --git a/lib/ansible/executor/module_common.py b/lib/ansible/executor/module_common.py index 05b1e8ab2f..429bfbb10e 100644 --- a/lib/ansible/executor/module_common.py +++ b/lib/ansible/executor/module_common.py @@ -38,7 +38,7 @@ from ansible.executor.interpreter_discovery import InterpreterDiscoveryRequiredE from ansible.executor.powershell import module_manifest as ps_manifest from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native from ansible.plugins.loader import module_utils_loader -from ansible.utils.collection_loader._collection_finder import _get_collection_metadata +from ansible.utils.collection_loader._collection_finder import _get_collection_metadata, AnsibleCollectionRef # Must import strategy and use write_locks from there # If we import write_locks directly then we end up binding a @@ -1319,7 +1319,23 @@ def modify_module(module_name, module_path, module_args, templar, task_vars=None return (b_module_data, module_style, shebang) -def get_action_args_with_defaults(action, args, defaults, templar): +def get_action_args_with_defaults(action, args, defaults, templar, redirected_names=None): + group_collection_map = { + 'acme': ['community.crypto'], + 'aws': ['amazon.aws', 'community.aws'], + 'azure': ['azure.azcollection'], + 'cpm': ['wti.remote'], + 'docker': ['community.general'], + 'gcp': ['google.cloud'], + 'k8s': ['community.kubernetes', 'community.general'], + 'os': ['openstack.cloud'], + 'ovirt': ['ovirt.ovirt', 'community.general'], + 'vmware': ['community.vmware'], + 'testgroup': ['testns.testcoll', 'testns.othercoll', 'testns.boguscoll'] + } + + if not redirected_names: + redirected_names = [action] tmp_args = {} module_defaults = {} @@ -1334,13 +1350,26 @@ def get_action_args_with_defaults(action, args, defaults, templar): module_defaults = templar.template(module_defaults) # deal with configured group defaults first - if action in C.config.module_defaults_groups: - for group in C.config.module_defaults_groups.get(action, []): - tmp_args.update((module_defaults.get('group/{0}'.format(group)) or {}).copy()) + for default in module_defaults: + if not default.startswith('group/'): + continue + + group_name = default.split('group/')[-1] + + for collection_name in group_collection_map.get(group_name, []): + try: + action_group = _get_collection_metadata(collection_name).get('action_groups', {}) + except ValueError: + # The collection may not be installed + continue + + if any(name for name in redirected_names if name in action_group): + tmp_args.update((module_defaults.get('group/%s' % group_name) or {}).copy()) # handle specific action defaults - if action in module_defaults: - tmp_args.update(module_defaults[action].copy()) + for action in redirected_names: + if action in module_defaults: + tmp_args.update(module_defaults[action].copy()) # direct args override all tmp_args.update(args) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 22f758e9ce..4bb9ea3141 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -631,7 +631,9 @@ class TaskExecutor: self._handler = self._get_action_handler(connection=self._connection, templar=templar) # Apply default params for action/module, if present - self._task.args = get_action_args_with_defaults(self._task.action, self._task.args, self._task.module_defaults, templar) + self._task.args = get_action_args_with_defaults( + self._task.action, self._task.args, self._task.module_defaults, templar, self._task._ansible_internal_redirect_list + ) # And filter out any fields which were set to default(omit), and got the omit token value omit_token = variables.get('omit') diff --git a/lib/ansible/parsing/mod_args.py b/lib/ansible/parsing/mod_args.py index 929d1add9e..a6906b909c 100644 --- a/lib/ansible/parsing/mod_args.py +++ b/lib/ansible/parsing/mod_args.py @@ -119,6 +119,8 @@ class ModuleArgsParser: self._task_attrs.update(['local_action', 'static']) self._task_attrs = frozenset(self._task_attrs) + self.internal_redirect_list = [] + def _split_module_string(self, module_string): ''' when module names are expressed like: @@ -266,6 +268,8 @@ class ModuleArgsParser: delegate_to = self._task_ds.get('delegate_to', Sentinel) args = dict() + self.internal_redirect_list = [] + # This is the standard YAML form for command-type modules. We grab # the args and pass them in as additional arguments, which can/will # be overwritten via dict updates from the other arg sources below @@ -294,8 +298,24 @@ class ModuleArgsParser: # walk the filtered input dictionary to see if we recognize a module name for item, value in iteritems(non_task_ds): - if item in BUILTIN_TASKS or skip_action_validation or action_loader.has_plugin(item, collection_list=self._collection_list) or \ - module_loader.has_plugin(item, collection_list=self._collection_list): + is_action_candidate = False + if item in BUILTIN_TASKS: + is_action_candidate = True + elif skip_action_validation: + is_action_candidate = True + else: + # If the plugin is resolved and redirected smuggle the list of candidate names via the task attribute 'internal_redirect_list' + context = action_loader.find_plugin_with_context(item, collection_list=self._collection_list) + if not context.resolved: + context = module_loader.find_plugin_with_context(item, collection_list=self._collection_list) + if context.resolved and context.redirect_list: + self.internal_redirect_list = context.redirect_list + elif context.redirect_list: + self.internal_redirect_list = context.redirect_list + + is_action_candidate = bool(self.internal_redirect_list) + + if is_action_candidate: # finding more than one module name is a problem if action is not None: raise AnsibleParserError("conflicting action statements: %s, %s" % (action, item), obj=self._task_ds) diff --git a/lib/ansible/playbook/task.py b/lib/ansible/playbook/task.py index 405316d3f8..80b7fd353f 100644 --- a/lib/ansible/playbook/task.py +++ b/lib/ansible/playbook/task.py @@ -91,6 +91,10 @@ class Task(Base, Conditional, Taggable, CollectionSearch): def __init__(self, block=None, role=None, task_include=None): ''' constructors a task, without the Task.load classmethod, it will be pretty blank ''' + # This is a reference of all the candidate action names for transparent execution of module_defaults with redirected content + # This isn't a FieldAttribute to prevent it from being set via the playbook + self._ansible_internal_redirect_list = [] + self._role = role self._parent = None @@ -220,6 +224,8 @@ class Task(Base, Conditional, Taggable, CollectionSearch): raise # But if it wasn't, we can add the yaml object now to get more detail raise AnsibleParserError(to_native(e), obj=ds, orig_exc=e) + else: + self._ansible_internal_redirect_list = args_parser.internal_redirect_list[:] # the command/shell/script modules used to support the `cmd` arg, # which corresponds to what we now call _raw_params, so move that @@ -394,6 +400,9 @@ class Task(Base, Conditional, Taggable, CollectionSearch): def copy(self, exclude_parent=False, exclude_tasks=False): new_me = super(Task, self).copy() + # if the task has an associated list of candidate names, copy it to the new object too + new_me._ansible_internal_redirect_list = self._ansible_internal_redirect_list[:] + new_me._parent = None if self._parent and not exclude_parent: new_me._parent = self._parent.copy(exclude_tasks=exclude_tasks) @@ -415,6 +424,9 @@ class Task(Base, Conditional, Taggable, CollectionSearch): if self._role: data['role'] = self._role.serialize() + if self._ansible_internal_redirect_list: + data['_ansible_internal_redirect_list'] = self._ansible_internal_redirect_list[:] + return data def deserialize(self, data): @@ -443,6 +455,8 @@ class Task(Base, Conditional, Taggable, CollectionSearch): self._role = r del data['role'] + self._ansible_internal_redirect_list = data.get('_ansible_internal_redirect_list', []) + super(Task, self).deserialize(data) def set_loader(self, loader): diff --git a/lib/ansible/plugins/action/gather_facts.py b/lib/ansible/plugins/action/gather_facts.py index d58e9dd6bc..cd181203b5 100644 --- a/lib/ansible/plugins/action/gather_facts.py +++ b/lib/ansible/plugins/action/gather_facts.py @@ -42,7 +42,7 @@ class ActionModule(ActionBase): mod_args = dict((k, v) for k, v in mod_args.items() if v is not None) # handle module defaults - mod_args = get_action_args_with_defaults(fact_module, mod_args, self._task.module_defaults, self._templar) + mod_args = get_action_args_with_defaults(fact_module, mod_args, self._task.module_defaults, self._templar, self._task._ansible_internal_redirect_list) return mod_args diff --git a/lib/ansible/plugins/action/package.py b/lib/ansible/plugins/action/package.py index 932acccb04..c4349ca4d7 100644 --- a/lib/ansible/plugins/action/package.py +++ b/lib/ansible/plugins/action/package.py @@ -66,7 +66,9 @@ class ActionModule(ActionBase): del new_module_args['use'] # get defaults for specific module - new_module_args = get_action_args_with_defaults(module, new_module_args, self._task.module_defaults, self._templar) + new_module_args = get_action_args_with_defaults( + module, new_module_args, self._task.module_defaults, self._templar, self._task._ansible_internal_redirect_list + ) display.vvvv("Running %s" % module) result.update(self._execute_module(module_name=module, module_args=new_module_args, task_vars=task_vars, wrap_async=self._task.async_val)) diff --git a/lib/ansible/plugins/action/service.py b/lib/ansible/plugins/action/service.py index 3ebd0ae17d..c6af6248e6 100644 --- a/lib/ansible/plugins/action/service.py +++ b/lib/ansible/plugins/action/service.py @@ -73,7 +73,9 @@ class ActionModule(ActionBase): self._display.warning('Ignoring "%s" as it is not used in "%s"' % (unused, module)) # get defaults for specific module - new_module_args = get_action_args_with_defaults(module, new_module_args, self._task.module_defaults, self._templar) + new_module_args = get_action_args_with_defaults( + module, new_module_args, self._task.module_defaults, self._templar, self._task._ansible_internal_redirect_list + ) self._display.vvvv("Running %s" % module) result.update(self._execute_module(module_name=module, module_args=new_module_args, task_vars=task_vars, wrap_async=self._task.async_val)) diff --git a/lib/ansible/plugins/loader.py b/lib/ansible/plugins/loader.py index 466dac066f..249aebd7dd 100644 --- a/lib/ansible/plugins/loader.py +++ b/lib/ansible/plugins/loader.py @@ -587,6 +587,10 @@ class PluginLoader: else: # 'ansible.builtin' should be handled here. This means only internal, or builtin, paths are searched. plugin_load_context = self._find_fq_plugin(candidate_name, suffix, plugin_load_context=plugin_load_context) + + if candidate_name != plugin_load_context.original_name and candidate_name not in plugin_load_context.redirect_list: + plugin_load_context.redirect_list.append(candidate_name) + if plugin_load_context.resolved or plugin_load_context.pending_redirect: # if we got an answer or need to chase down a redirect, return return plugin_load_context except (AnsiblePluginRemovedError, AnsiblePluginCircularRedirect, AnsibleCollectionUnsupportedVersionError): diff --git a/lib/ansible/utils/collection_loader/_collection_finder.py b/lib/ansible/utils/collection_loader/_collection_finder.py index 47b5782997..6aa3ca5ab4 100644 --- a/lib/ansible/utils/collection_loader/_collection_finder.py +++ b/lib/ansible/utils/collection_loader/_collection_finder.py @@ -531,6 +531,15 @@ class _AnsibleCollectionPkgLoader(_AnsibleCollectionPkgLoaderBase): # if redirect.startswith('..'): # redirect = redirect[2:] + action_groups = meta_dict.pop('action_groups', {}) + meta_dict['action_groups'] = {} + for group_name in action_groups: + for action_name in action_groups[group_name]: + if action_name in meta_dict['action_groups']: + meta_dict['action_groups'][action_name].append(group_name) + else: + meta_dict['action_groups'][action_name] = [group_name] + return meta_dict |