diff --git a/templates/ocata/policy.json b/templates/ocata/policy.json new file mode 100644 index 00000000..1053fd6a --- /dev/null +++ b/templates/ocata/policy.json @@ -0,0 +1,428 @@ +{% if api_version == 3 -%} +{ + "admin_required": "role:{{ admin_role }}", + "cloud_admin": "rule:admin_required and (is_admin_project:True or domain_id:{{ admin_domain_id }} or project_id:{{ service_tenant_id }})", + "service_role": "role:service", + "service_or_admin": "rule:admin_required or rule:service_role", + "owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s", + "admin_or_owner": "(rule:admin_required and domain_id:%(target.token.user.domain.id)s) or rule:owner", + "admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s", + "service_admin_or_owner": "rule:service_or_admin or rule:owner", + + "default": "rule:admin_required", + + "identity:get_region": "", + "identity:list_regions": "", + "identity:create_region": "rule:cloud_admin", + "identity:update_region": "rule:cloud_admin", + "identity:delete_region": "rule:cloud_admin", + + "identity:get_service": "rule:admin_required", + "identity:list_services": "rule:admin_required", + "identity:create_service": "rule:cloud_admin", + "identity:update_service": "rule:cloud_admin", + "identity:delete_service": "rule:cloud_admin", + + "identity:get_endpoint": "rule:admin_required", + "identity:list_endpoints": "rule:admin_required", + "identity:create_endpoint": "rule:cloud_admin", + "identity:update_endpoint": "rule:cloud_admin", + "identity:delete_endpoint": "rule:cloud_admin", + + "identity:get_domain": "rule:cloud_admin or rule:admin_and_matching_domain_id or token.project.domain.id:%(target.domain.id)s", + "identity:list_domains": "rule:cloud_admin", + "identity:create_domain": "rule:cloud_admin", + "identity:update_domain": "rule:cloud_admin", + "identity:delete_domain": "rule:cloud_admin", + + "admin_and_matching_target_project_domain_id": "rule:admin_required and domain_id:%(target.project.domain_id)s", + "admin_and_matching_project_domain_id": "rule:admin_required and domain_id:%(project.domain_id)s", + "identity:get_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id or project_id:%(target.project.id)s", + "identity:list_projects": "rule:cloud_admin or rule:admin_and_matching_domain_id", + "identity:list_user_projects": "rule:owner or rule:admin_and_matching_domain_id", + "identity:create_project": "rule:cloud_admin or rule:admin_and_matching_project_domain_id", + "identity:update_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id", + "identity:delete_project": "rule:cloud_admin or rule:admin_and_matching_target_project_domain_id", + + "admin_and_matching_target_user_domain_id": "rule:admin_required and domain_id:%(target.user.domain_id)s", + "admin_and_matching_user_domain_id": "rule:admin_required and domain_id:%(user.domain_id)s", + "identity:get_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id or rule:owner", + "identity:list_users": "rule:cloud_admin or rule:admin_and_matching_domain_id", + "identity:create_user": "rule:cloud_admin or rule:admin_and_matching_user_domain_id", + "identity:update_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id", + "identity:delete_user": "rule:cloud_admin or rule:admin_and_matching_target_user_domain_id", + + "admin_and_matching_target_group_domain_id": "rule:admin_required and domain_id:%(target.group.domain_id)s", + "admin_and_matching_group_domain_id": "rule:admin_required and domain_id:%(group.domain_id)s", + "identity:get_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:list_groups": "rule:cloud_admin or rule:admin_and_matching_domain_id", + "identity:list_groups_for_user": "rule:owner or rule:admin_and_matching_target_user_domain_id", + "identity:create_group": "rule:cloud_admin or rule:admin_and_matching_group_domain_id", + "identity:update_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:delete_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:list_users_in_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:remove_user_from_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:check_user_in_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + "identity:add_user_to_group": "rule:cloud_admin or rule:admin_and_matching_target_group_domain_id", + + "identity:get_credential": "rule:admin_required", + "identity:list_credentials": "rule:admin_required or user_id:%(user_id)s", + "identity:create_credential": "rule:admin_required", + "identity:update_credential": "rule:admin_required", + "identity:delete_credential": "rule:admin_required", + + "identity:ec2_get_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", + "identity:ec2_list_credentials": "rule:admin_required or rule:owner", + "identity:ec2_create_credential": "rule:admin_required or rule:owner", + "identity:ec2_delete_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", + + "identity:get_role": "rule:admin_required", + "identity:list_roles": "rule:admin_required", + "identity:create_role": "rule:cloud_admin", + "identity:update_role": "rule:cloud_admin", + "identity:delete_role": "rule:cloud_admin", + + "identity:get_domain_role": "rule:cloud_admin or rule:get_domain_roles", + "identity:list_domain_roles": "rule:cloud_admin or rule:list_domain_roles", + "identity:create_domain_role": "rule:cloud_admin or rule:domain_admin_matches_domain_role", + "identity:update_domain_role": "rule:cloud_admin or rule:domain_admin_matches_target_domain_role", + "identity:delete_domain_role": "rule:cloud_admin or rule:domain_admin_matches_target_domain_role", + "domain_admin_matches_domain_role": "rule:admin_required and domain_id:%(role.domain_id)s", + "get_domain_roles": "rule:domain_admin_matches_target_domain_role or rule:project_admin_matches_target_domain_role", + "domain_admin_matches_target_domain_role": "rule:admin_required and domain_id:%(target.role.domain_id)s", + "project_admin_matches_target_domain_role": "rule:admin_required and project_domain_id:%(target.role.domain_id)s", + "list_domain_roles": "rule:domain_admin_matches_filter_on_list_domain_roles or rule:project_admin_matches_filter_on_list_domain_roles", + "domain_admin_matches_filter_on_list_domain_roles": "rule:admin_required and domain_id:%(domain_id)s", + "project_admin_matches_filter_on_list_domain_roles": "rule:admin_required and project_domain_id:%(domain_id)s", + "admin_and_matching_prior_role_domain_id": "rule:admin_required and domain_id:%(target.prior_role.domain_id)s", + "implied_role_matches_prior_role_domain_or_global": "(domain_id:%(target.implied_role.domain_id)s or None:%(target.implied_role.domain_id)s)", + + "identity:get_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id", + "identity:list_implied_roles": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id", + "identity:create_implied_role": "rule:cloud_admin or (rule:admin_and_matching_prior_role_domain_id and rule:implied_role_matches_prior_role_domain_or_global)", + "identity:delete_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id", + "identity:list_role_inference_rules": "rule:cloud_admin", + "identity:check_implied_role": "rule:cloud_admin or rule:admin_and_matching_prior_role_domain_id", + + "identity:check_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants", + "identity:list_grants": "rule:cloud_admin or rule:domain_admin_for_list_grants or rule:project_admin_for_list_grants", + "identity:create_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants", + "identity:revoke_grant": "rule:cloud_admin or rule:domain_admin_for_grants or rule:project_admin_for_grants", + "domain_admin_for_grants": "rule:domain_admin_for_global_role_grants or rule:domain_admin_for_domain_role_grants", + "domain_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and rule:domain_admin_grant_match", + "domain_admin_for_domain_role_grants": "rule:admin_required and domain_id:%(target.role.domain_id)s and rule:domain_admin_grant_match", + "domain_admin_grant_match": "domain_id:%(domain_id)s or domain_id:%(target.project.domain_id)s", + "project_admin_for_grants": "rule:project_admin_for_global_role_grants or rule:project_admin_for_domain_role_grants", + "project_admin_for_global_role_grants": "rule:admin_required and None:%(target.role.domain_id)s and project_id:%(project_id)s", + "project_admin_for_domain_role_grants": "rule:admin_required and project_domain_id:%(target.role.domain_id)s and project_id:%(project_id)s", + "domain_admin_for_list_grants": "rule:admin_required and rule:domain_admin_grant_match", + "project_admin_for_list_grants": "rule:admin_required and project_id:%(project_id)s", + + "admin_on_domain_filter" : "rule:admin_required and domain_id:%(scope.domain.id)s", + "admin_on_project_filter" : "rule:admin_required and project_id:%(scope.project.id)s", + "admin_on_domain_of_project_filter" : "rule:admin_required and domain_id:%(target.project.domain_id)s", + "identity:list_role_assignments": "rule:cloud_admin or rule:admin_on_domain_filter or rule:admin_on_project_filter", + "identity:list_role_assignments_for_tree": "rule:cloud_admin or rule:admin_on_domain_of_project_filter", + "identity:get_policy": "rule:cloud_admin", + "identity:list_policies": "rule:cloud_admin", + "identity:create_policy": "rule:cloud_admin", + "identity:update_policy": "rule:cloud_admin", + "identity:delete_policy": "rule:cloud_admin", + + "identity:change_password": "rule:owner", + "identity:check_token": "rule:admin_or_owner", + "identity:validate_token": "rule:service_admin_or_owner", + "identity:validate_token_head": "rule:service_or_admin", + "identity:revocation_list": "rule:service_or_admin", + "identity:revoke_token": "rule:admin_or_owner", + + "identity:create_trust": "user_id:%(trust.trustor_user_id)s", + "identity:list_trusts": "", + "identity:list_roles_for_trust": "", + "identity:get_role_for_trust": "", + "identity:delete_trust": "", + + "identity:create_consumer": "rule:admin_required", + "identity:get_consumer": "rule:admin_required", + "identity:list_consumers": "rule:admin_required", + "identity:delete_consumer": "rule:admin_required", + "identity:update_consumer": "rule:admin_required", + + "identity:authorize_request_token": "rule:admin_required", + "identity:list_access_token_roles": "rule:admin_required", + "identity:get_access_token_role": "rule:admin_required", + "identity:list_access_tokens": "rule:admin_required", + "identity:get_access_token": "rule:admin_required", + "identity:delete_access_token": "rule:admin_required", + + "identity:list_projects_for_endpoint": "rule:admin_required", + "identity:add_endpoint_to_project": "rule:admin_required", + "identity:check_endpoint_in_project": "rule:admin_required", + "identity:list_endpoints_for_project": "rule:admin_required", + "identity:remove_endpoint_from_project": "rule:admin_required", + + "identity:create_endpoint_group": "rule:admin_required", + "identity:list_endpoint_groups": "rule:admin_required", + "identity:get_endpoint_group": "rule:admin_required", + "identity:update_endpoint_group": "rule:admin_required", + "identity:delete_endpoint_group": "rule:admin_required", + "identity:list_projects_associated_with_endpoint_group": "rule:admin_required", + "identity:list_endpoints_associated_with_endpoint_group": "rule:admin_required", + "identity:get_endpoint_group_in_project": "rule:admin_required", + "identity:list_endpoint_groups_for_project": "rule:admin_required", + "identity:add_endpoint_group_to_project": "rule:admin_required", + "identity:remove_endpoint_group_from_project": "rule:admin_required", + + "identity:create_identity_provider": "rule:cloud_admin", + "identity:list_identity_providers": "rule:cloud_admin", + "identity:get_identity_providers": "rule:cloud_admin", + "identity:update_identity_provider": "rule:cloud_admin", + "identity:delete_identity_provider": "rule:cloud_admin", + + "identity:create_protocol": "rule:cloud_admin", + "identity:update_protocol": "rule:cloud_admin", + "identity:get_protocol": "rule:cloud_admin", + "identity:list_protocols": "rule:cloud_admin", + "identity:delete_protocol": "rule:cloud_admin", + + "identity:create_mapping": "rule:cloud_admin", + "identity:get_mapping": "rule:cloud_admin", + "identity:list_mappings": "rule:cloud_admin", + "identity:delete_mapping": "rule:cloud_admin", + "identity:update_mapping": "rule:cloud_admin", + + "identity:create_service_provider": "rule:cloud_admin", + "identity:list_service_providers": "rule:cloud_admin", + "identity:get_service_provider": "rule:cloud_admin", + "identity:update_service_provider": "rule:cloud_admin", + "identity:delete_service_provider": "rule:cloud_admin", + + "identity:get_auth_catalog": "", + "identity:get_auth_projects": "", + "identity:get_auth_domains": "", + + "identity:list_projects_for_user": "", + "identity:list_domains_for_user": "", + + "identity:list_revoke_events": "rule:service_or_admin", + + "identity:create_policy_association_for_endpoint": "rule:cloud_admin", + "identity:check_policy_association_for_endpoint": "rule:cloud_admin", + "identity:delete_policy_association_for_endpoint": "rule:cloud_admin", + "identity:create_policy_association_for_service": "rule:cloud_admin", + "identity:check_policy_association_for_service": "rule:cloud_admin", + "identity:delete_policy_association_for_service": "rule:cloud_admin", + "identity:create_policy_association_for_region_and_service": "rule:cloud_admin", + "identity:check_policy_association_for_region_and_service": "rule:cloud_admin", + "identity:delete_policy_association_for_region_and_service": "rule:cloud_admin", + "identity:get_policy_for_endpoint": "rule:cloud_admin", + "identity:list_endpoints_for_policy": "rule:cloud_admin", + + "identity:create_domain_config": "rule:cloud_admin", + "identity:get_domain_config": "rule:cloud_admin", + "identity:get_security_compliance_domain_config": "", + "identity:update_domain_config": "rule:cloud_admin", + "identity:delete_domain_config": "rule:cloud_admin", + "identity:get_domain_config_default": "rule:cloud_admin" +} +{% else -%} +{ + "admin_required": "role:admin or is_admin:1", + "service_role": "role:service", + "service_or_admin": "rule:admin_required or rule:service_role", + "owner" : "user_id:%(user_id)s", + "admin_or_owner": "rule:admin_required or rule:owner", + "token_subject": "user_id:%(target.token.user_id)s", + "admin_or_token_subject": "rule:admin_required or rule:token_subject", + "service_admin_or_token_subject": "rule:service_or_admin or rule:token_subject", + + "default": "rule:admin_required", + + "identity:get_region": "", + "identity:list_regions": "", + "identity:create_region": "rule:admin_required", + "identity:update_region": "rule:admin_required", + "identity:delete_region": "rule:admin_required", + + "identity:get_service": "rule:admin_required", + "identity:list_services": "rule:admin_required", + "identity:create_service": "rule:admin_required", + "identity:update_service": "rule:admin_required", + "identity:delete_service": "rule:admin_required", + + "identity:get_endpoint": "rule:admin_required", + "identity:list_endpoints": "rule:admin_required", + "identity:create_endpoint": "rule:admin_required", + "identity:update_endpoint": "rule:admin_required", + "identity:delete_endpoint": "rule:admin_required", + + "identity:get_domain": "rule:admin_required or token.project.domain.id:%(target.domain.id)s", + "identity:list_domains": "rule:admin_required", + "identity:create_domain": "rule:admin_required", + "identity:update_domain": "rule:admin_required", + "identity:delete_domain": "rule:admin_required", + + "identity:get_project": "rule:admin_required or project_id:%(target.project.id)s", + "identity:list_projects": "rule:admin_required", + "identity:list_user_projects": "rule:admin_or_owner", + "identity:create_project": "rule:admin_required", + "identity:update_project": "rule:admin_required", + "identity:delete_project": "rule:admin_required", + + "identity:get_user": "rule:admin_or_owner", + "identity:list_users": "rule:admin_required", + "identity:create_user": "rule:admin_required", + "identity:update_user": "rule:admin_required", + "identity:delete_user": "rule:admin_required", + "identity:change_password": "rule:admin_or_owner", + + "identity:get_group": "rule:admin_required", + "identity:list_groups": "rule:admin_required", + "identity:list_groups_for_user": "rule:admin_or_owner", + "identity:create_group": "rule:admin_required", + "identity:update_group": "rule:admin_required", + "identity:delete_group": "rule:admin_required", + "identity:list_users_in_group": "rule:admin_required", + "identity:remove_user_from_group": "rule:admin_required", + "identity:check_user_in_group": "rule:admin_required", + "identity:add_user_to_group": "rule:admin_required", + + "identity:get_credential": "rule:admin_required", + "identity:list_credentials": "rule:admin_required", + "identity:create_credential": "rule:admin_required", + "identity:update_credential": "rule:admin_required", + "identity:delete_credential": "rule:admin_required", + + "identity:ec2_get_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", + "identity:ec2_list_credentials": "rule:admin_or_owner", + "identity:ec2_create_credential": "rule:admin_or_owner", + "identity:ec2_delete_credential": "rule:admin_required or (rule:owner and user_id:%(target.credential.user_id)s)", + + "identity:get_role": "rule:admin_required", + "identity:list_roles": "rule:admin_required", + "identity:create_role": "rule:admin_required", + "identity:update_role": "rule:admin_required", + "identity:delete_role": "rule:admin_required", + "identity:get_domain_role": "rule:admin_required", + "identity:list_domain_roles": "rule:admin_required", + "identity:create_domain_role": "rule:admin_required", + "identity:update_domain_role": "rule:admin_required", + "identity:delete_domain_role": "rule:admin_required", + + "identity:get_implied_role": "rule:admin_required ", + "identity:list_implied_roles": "rule:admin_required", + "identity:create_implied_role": "rule:admin_required", + "identity:delete_implied_role": "rule:admin_required", + "identity:list_role_inference_rules": "rule:admin_required", + "identity:check_implied_role": "rule:admin_required", + + "identity:check_grant": "rule:admin_required", + "identity:list_grants": "rule:admin_required", + "identity:create_grant": "rule:admin_required", + "identity:revoke_grant": "rule:admin_required", + + "identity:list_role_assignments": "rule:admin_required", + "identity:list_role_assignments_for_tree": "rule:admin_required", + + "identity:get_policy": "rule:admin_required", + "identity:list_policies": "rule:admin_required", + "identity:create_policy": "rule:admin_required", + "identity:update_policy": "rule:admin_required", + "identity:delete_policy": "rule:admin_required", + + "identity:check_token": "rule:admin_or_token_subject", + "identity:validate_token": "rule:service_admin_or_token_subject", + "identity:validate_token_head": "rule:service_or_admin", + "identity:revocation_list": "rule:service_or_admin", + "identity:revoke_token": "rule:admin_or_token_subject", + + "identity:create_trust": "user_id:%(trust.trustor_user_id)s", + "identity:list_trusts": "", + "identity:list_roles_for_trust": "", + "identity:get_role_for_trust": "", + "identity:delete_trust": "", + + "identity:create_consumer": "rule:admin_required", + "identity:get_consumer": "rule:admin_required", + "identity:list_consumers": "rule:admin_required", + "identity:delete_consumer": "rule:admin_required", + "identity:update_consumer": "rule:admin_required", + + "identity:authorize_request_token": "rule:admin_required", + "identity:list_access_token_roles": "rule:admin_required", + "identity:get_access_token_role": "rule:admin_required", + "identity:list_access_tokens": "rule:admin_required", + "identity:get_access_token": "rule:admin_required", + "identity:delete_access_token": "rule:admin_required", + + "identity:list_projects_for_endpoint": "rule:admin_required", + "identity:add_endpoint_to_project": "rule:admin_required", + "identity:check_endpoint_in_project": "rule:admin_required", + "identity:list_endpoints_for_project": "rule:admin_required", + "identity:remove_endpoint_from_project": "rule:admin_required", + + "identity:create_endpoint_group": "rule:admin_required", + "identity:list_endpoint_groups": "rule:admin_required", + "identity:get_endpoint_group": "rule:admin_required", + "identity:update_endpoint_group": "rule:admin_required", + "identity:delete_endpoint_group": "rule:admin_required", + "identity:list_projects_associated_with_endpoint_group": "rule:admin_required", + "identity:list_endpoints_associated_with_endpoint_group": "rule:admin_required", + "identity:get_endpoint_group_in_project": "rule:admin_required", + "identity:list_endpoint_groups_for_project": "rule:admin_required", + "identity:add_endpoint_group_to_project": "rule:admin_required", + "identity:remove_endpoint_group_from_project": "rule:admin_required", + + "identity:create_identity_provider": "rule:admin_required", + "identity:list_identity_providers": "rule:admin_required", + "identity:get_identity_providers": "rule:admin_required", + "identity:update_identity_provider": "rule:admin_required", + "identity:delete_identity_provider": "rule:admin_required", + + "identity:create_protocol": "rule:admin_required", + "identity:update_protocol": "rule:admin_required", + "identity:get_protocol": "rule:admin_required", + "identity:list_protocols": "rule:admin_required", + "identity:delete_protocol": "rule:admin_required", + + "identity:create_mapping": "rule:admin_required", + "identity:get_mapping": "rule:admin_required", + "identity:list_mappings": "rule:admin_required", + "identity:delete_mapping": "rule:admin_required", + "identity:update_mapping": "rule:admin_required", + + "identity:create_service_provider": "rule:admin_required", + "identity:list_service_providers": "rule:admin_required", + "identity:get_service_provider": "rule:admin_required", + "identity:update_service_provider": "rule:admin_required", + "identity:delete_service_provider": "rule:admin_required", + + "identity:get_auth_catalog": "", + "identity:get_auth_projects": "", + "identity:get_auth_domains": "", + + "identity:list_projects_for_user": "", + "identity:list_domains_for_user": "", + + "identity:list_revoke_events": "rule:service_or_admin", + + "identity:create_policy_association_for_endpoint": "rule:admin_required", + "identity:check_policy_association_for_endpoint": "rule:admin_required", + "identity:delete_policy_association_for_endpoint": "rule:admin_required", + "identity:create_policy_association_for_service": "rule:admin_required", + "identity:check_policy_association_for_service": "rule:admin_required", + "identity:delete_policy_association_for_service": "rule:admin_required", + "identity:create_policy_association_for_region_and_service": "rule:admin_required", + "identity:check_policy_association_for_region_and_service": "rule:admin_required", + "identity:delete_policy_association_for_region_and_service": "rule:admin_required", + "identity:get_policy_for_endpoint": "rule:admin_required", + "identity:list_endpoints_for_policy": "rule:admin_required", + + "identity:create_domain_config": "rule:admin_required", + "identity:get_domain_config": "rule:admin_required", + "identity:get_security_compliance_domain_config": "", + "identity:update_domain_config": "rule:admin_required", + "identity:delete_domain_config": "rule:admin_required", + "identity:get_domain_config_default": "rule:admin_required" +} +{% endif -%} diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index a871b623..da0b22a2 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -34,7 +34,6 @@ from charmhelpers.contrib.openstack.amulet.utils import ( ) import keystoneclient from keystoneauth1 import exceptions as ksauth1_exceptions -from charmhelpers.core.decorators import retry_on_exception # Use DEBUG to turn on debug logging u = OpenStackAmuletUtils(DEBUG) @@ -144,9 +143,10 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): 'root-password': 'ChangeMe123', 'sst-password': 'ChangeMe123', } - cinder_config = { - 'block-device': 'None', - } + cinder_config = {'block-device': 'vdb', + 'glance-api-version': '2', + 'overwrite': 'true', + 'ephemeral-unmount': '/mnt'} configs = { 'keystone': keystone_config, 'percona-cluster': pxc_config, @@ -154,38 +154,22 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): } super(KeystoneBasicDeployment, self)._configure_services(configs) - @retry_on_exception(5, base_delay=10) def set_api_version(self, api_version): - set_alternate = {'preferred-api-version': api_version} - - # Make config change, check for service restarts u.log.debug('Setting preferred-api-version={}'.format(api_version)) - self.d.configure('keystone', set_alternate) - self.keystone_api_version = api_version + se_rels = [] for i in range(0, self.keystone_num_units): - rel = self.keystone_sentries[i].relation('identity-service', - 'cinder:identity-service') - u.log.debug('keystone unit {} relation data: {}'.format(i, rel)) - if rel['api_version'] != str(api_version): - raise Exception("api_version not propagated through relation" - " data yet ('{}' != '{}')." - "".format(rel['api_version'], api_version)) - client = self.get_keystone_client(api_version=api_version, - keystone_ip=rel[ - 'private-address']) - # List an artefact that needs authorisation to check admin user - # has been setup on each Keystone unit. If that is still in progess - # keystoneclient.exceptions.Unauthorized will be thrown and caught - # by @retry_on_exception - if api_version == 2: - client.tenants.list() - else: - client.projects.list() + se_rels.append( + (self.keystone_sentries[i], 'cinder:identity-service'), + ) + # Make config change, wait for propagation + u.keystone_configure_api_version(se_rels, self, api_version) + # Success if we get here, get and store client. if api_version == 2: self.keystone_v2 = self.get_keystone_client(api_version=2) else: self.keystone_v3 = self.get_keystone_client(api_version=3) + self.keystone_api_version = api_version def get_keystone_client(self, api_version=None, keystone_ip=None): if keystone_ip is None: @@ -229,6 +213,7 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): # Create a demo tenant/role/user self.demo_project = 'demoProject' self.demo_user_v3 = 'demoUserV3' + self.demo_domain_admin = 'demoDomainAdminV3' self.demo_domain = 'demoDomain' try: domain = self.keystone_v3.domains.find(name=self.demo_domain) @@ -266,6 +251,31 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): description='Demo', enabled=True) + try: + self.keystone_v3.roles.find(name='Admin') + except keystoneclient.exceptions.NotFound: + self.keystone_v3.roles.create(name='Admin') + + if not self.find_keystone_v3_user(self.keystone_v3, + self.demo_domain_admin, + self.demo_domain): + user = self.keystone_v3.users.create( + self.demo_domain_admin, + domain=domain.id, + project=self.demo_project, + password='password', + email='demoadminv3@demo.com', + description='Demo Admin', + enabled=True) + + role = self.keystone_v3.roles.find(name='Admin') + u.log.debug("self.keystone_v3.roles.grant('{}', user='{}', " + "domain='{}')".format(role.id, user.id, domain.id)) + self.keystone_v3.roles.grant( + role.id, + user=user.id, + domain=domain.id) + def _initialize_tests(self): """Perform final initialization before tests get run.""" # Access the sentries for inspecting service units @@ -291,15 +301,20 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): """Verify the expected services are running on the corresponding service units.""" services = { - self.cinder_sentry: ['cinder-api', - 'cinder-scheduler', + self.cinder_sentry: ['cinder-scheduler', 'cinder-volume'] } + if self._get_openstack_release() >= self.xenial_ocata: + services.update({self.cinder_sentry: ['apache2']}) + else: + services.update({self.cinder_sentry: ['cinder-api']}) + if self.is_liberty_or_newer(): for i in range(0, self.keystone_num_units): services.update({self.keystone_sentries[i]: ['apache2']}) else: services.update({self.keystone_sentries[0]: ['keystone']}) + ret = u.validate_services_by_name(services) if ret: amulet.raise_status(amulet.FAIL, msg=ret) @@ -412,6 +427,14 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): u.log.info('Skipping test, {} < liberty'.format(os_release)) return False + def is_mitaka_or_newer(self): + os_release = self._get_openstack_release_string() + if os_release >= 'mitaka': + return True + else: + u.log.info('Skipping test, {} < mitaka'.format(os_release)) + return False + def test_112_keystone_tenants(self): if self.is_liberty_or_newer(): self.set_api_version(3) @@ -466,6 +489,64 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): ) assert expect[key] == getattr(actual_domain, key) + def test_121_keystone_demo_domain_admin_access(self): + """Verify that end-user domain admin does not have elevated + privileges. Catch regressions like LP#1651989""" + if self.is_mitaka_or_newer(): + u.log.debug('Checking keystone end-user domain admin access...') + self.set_api_version(3) + # Authenticate as end-user domain admin and verify that we have + # appropriate access. + client = u.authenticate_keystone( + self.keystone_sentries[0].info['public-address'], + username=self.demo_domain_admin, + password='password', + api_version=3, + user_domain_name=self.demo_domain, + domain_name=self.demo_domain, + ) + + try: + # Expect failure + client.domains.list() + except Exception as e: + message = ('Retrieve domain list as end-user domain admin ' + 'NOT allowed...OK ({})'.format(e)) + u.log.debug(message) + pass + else: + message = ('Retrieve domain list as end-user domain admin ' + 'allowed') + amulet.raise_status(amulet.FAIL, msg=message) + + def test_122_keystone_project_scoped_admin_access(self): + """Verify that user admin in domain admin_domain has access to + identity-calls guarded by rule:cloud_admin when using project + scoped token.""" + if self.is_mitaka_or_newer(): + u.log.debug('Checking keystone project scoped admin access...') + self.set_api_version(3) + # Authenticate as end-user domain admin and verify that we have + # appropriate access. + client = u.authenticate_keystone( + self.keystone_sentries[0].info['public-address'], + username='admin', + password='openstack', + api_version=3, + admin_port=True, + user_domain_name='admin_domain', + project_domain_name='admin_domain', + project_name='admin', + ) + + try: + client.domains.list() + u.log.debug('OK') + except Exception as e: + message = ('Retrieve domain list as admin with project scoped ' + 'token FAILED. ({})'.format(e)) + amulet.raise_status(amulet.FAIL, msg=message) + def test_138_service_catalog(self): """Verify that the service catalog endpoint data is valid.""" u.log.debug('Checking keystone service catalog...') @@ -678,7 +759,18 @@ class KeystoneBasicDeployment(OpenStackAmuletDeployment): ks_ci_rel = self.keystone_sentries[0].relation( 'identity-service', 'cinder:identity-service') - if self._get_openstack_release() >= self.trusty_mitaka: + if self._get_openstack_release() >= self.xenial_ocata: + expected = { + 'admin_required': 'role:Admin', + 'cloud_admin': + 'rule:admin_required and ' + '(is_admin_project:True or ' + 'domain_id:{admin_domain_id} or ' + 'project_id:{service_tenant_id})'.format( + admin_domain_id=ks_ci_rel['admin_domain_id'], + service_tenant_id=ks_ci_rel['service_tenant_id']), + } + elif self._get_openstack_release() >= self.trusty_mitaka: expected = { 'admin_required': 'role:Admin', 'cloud_admin': diff --git a/tests/gate-basic-xenial-ocata b/tests/gate-basic-xenial-ocata old mode 100644 new mode 100755