def check_single_action_is_allowed_on_object( action_display_name: str, adcm_object: AnyADCMObject, user_sdk: ADCMClient, business_role: Optional[BusinessRole] = None, ): """Check that only one action is allowed on object and the access to others is denied""" (allowed_object,) = as_user_objects(user_sdk, adcm_object) business_role = business_role or action_business_role(allowed_object, action_display_name) is_allowed(allowed_object, business_role).wait() for action_name in (a.display_name for a in adcm_object.action_list() if a.display_name != action_display_name): is_denied(allowed_object, action_business_role(allowed_object, action_name))
def test_action_on_host_available_with_cluster_parametrization(clients, actions_cluster, actions_provider, user): """Test that host owned action is still available""" admin_host = actions_provider.host() actions_cluster.host_add(admin_host) user_cluster, user_host = as_user_objects(clients.user, actions_cluster, admin_host) cluster_business_role, host_business_role = action_business_role( user_cluster, DO_NOTHING_ACTION ), action_business_role(user_host, DO_NOTHING_ACTION) policy = create_action_policy(clients.admin, user_cluster, cluster_business_role, host_business_role, user=user) is_allowed(user_cluster, cluster_business_role).wait() is_allowed(user_host, host_business_role).wait() delete_policy(policy) is_denied(user_cluster, cluster_business_role) is_denied(user_host, host_business_role)
def all_business_roles(self, old_cluster_objects): """Build roles for all actions on all objects both before and after the upgrade""" return [ action_business_role(adcm_object, action_display_name) for adcm_object in old_cluster_objects for action_display_name in ( *(a.display_name for a in adcm_object.action_list()), NEW_ACTION, CHANGED_ACTION_NAME, ) ]
def check_new_action_can_be_launched(self, clients, user, upgraded_cluster: Cluster): """Check that policy can be created to run new action from cluster bundle and action actually can be launched""" service = upgraded_cluster.service() component = service.component() for adcm_object in as_user_objects(clients.user, upgraded_cluster, service, component): business_role = action_business_role(adcm_object, NEW_ACTION) create_action_policy(clients.admin, adcm_object, business_role, user=user) is_allowed(adcm_object, business_role).wait()
def _test_config_change( action_owner_object: AnyADCMObject, objects_to_change: Tuple[AnyADCMObject, ...], admin_client: ADCMClient, user: User, ) -> None: """ Grant policy to user to run actions that change config of objects. Then try to change config of an object via adcm_config plugin without having explicit permission to change config. :param action_owner_object: Object on which to run action that changes config. :param objects_to_change: Plain collection of objects (e.g. tuple) containing objects which config should be changed by corresponding action on `action_owner_object`. These objects should be from user SDK. :param admin_client: Admin SDK to check config. :param user: User instance to apply policy to. """ owner_object_represent = get_object_represent(action_owner_object) action_names = [CHANGE_ACTION_NAME_TEMPLATE.format(object_type=obj.__class__.__name__) for obj in objects_to_change] business_roles = [action_business_role(action_owner_object, action_name) for action_name in action_names] object_role_map = tuple(zip(objects_to_change, business_roles)) with allure.step( f'Apply policy on "{owner_object_represent}" and check config change is allowed without explicit permission' ): policy = create_action_policy(admin_client, action_owner_object, *business_roles, user=user) for adcm_object, business_role in object_role_map: admin_object = as_user_objects(admin_client, adcm_object)[0] config_field_value = admin_object.config()[CONFIG_FIELD_TO_CHANGE] new_value = f'{config_field_value}_{adcm_object.__class__.__name__}' with allure.step(f'Try to change {get_object_represent(admin_object)} from {owner_object_represent}'): task = is_allowed(action_owner_object, business_role, config={ACTION_CONFIG_ARGUMENT: new_value}) assert task.wait() == 'success', 'Action should succeeded' assert ( admin_object.config()[CONFIG_FIELD_TO_CHANGE] == new_value ), f"Config of object {get_object_represent(admin_object)} should've been changed" with allure.step('Delete policy and check actions are denied and config stays the same'): delete_policy(policy) for adcm_object, business_role in object_role_map: admin_object = as_user_objects(admin_client, adcm_object)[0] with allure.step(f'Try to change {get_object_represent(admin_object)} from {owner_object_represent}'): config_val_before = admin_object.config()[CONFIG_FIELD_TO_CHANGE] is_denied(action_owner_object, business_role, config={ACTION_CONFIG_ARGUMENT: "This you seen't"}) config_val_after = admin_object.config()[CONFIG_FIELD_TO_CHANGE] assert ( config_val_before == config_val_after ), f'Config value should stay the same for object {get_object_represent(admin_object)}'
def test_host_actions(clients, actions_cluster, actions_cluster_bundle, actions_provider, user): """Test permissions on host actions""" host_action_template = '{object_type} ready for host' service_name, component_name = 'actions_service', 'single_component' actions_service = actions_cluster.service(name=service_name) single_component = actions_service.component(name=component_name) second_cluster = actions_cluster_bundle.cluster_create(name='Test Second Cluster') second_cluster.service_add(name=service_name) with allure.step('Add hosts to clusters'): first_host = actions_provider.host() second_host = actions_provider.host_create(fqdn='test-new-host') for cluster, host in ((actions_cluster, first_host), (second_cluster, second_host)): cluster.host_add(host) service = cluster.service(name=service_name) component = service.component(name=component_name) cluster.hostcomponent_set((host, component)) host, second_host = as_user_objects(clients.user, first_host, second_host) cluster, _, _ = user_cluster_objects = as_user_objects( clients.user, actions_cluster, actions_service, single_component ) with allure.step('Grant permission to run host actions on cluster, service and component'): business_roles = [ action_business_role(obj, host_action_template.format(object_type=obj.__class__.__name__)) for obj in user_cluster_objects ] policy = create_action_policy( clients.admin, cluster, *business_roles, user=user, ) with allure.step('Run host actions from cluster, service and component on host in and out of cluster'): for role in business_roles: is_allowed(host, role).wait() is_denied(second_host, role) with allure.step('Check policy deletion leads to denial of host action execution'): delete_policy(policy) for role in business_roles: is_denied(host, role) is_denied(second_host, role)
def _test_basic_action_run_permissions(adcm_object, admin_sdk, user_sdk, user, all_objects): """Check that granting and withdrawn of permission to run action works as expected""" with allure.step( f'Check that granting policy allows to run action "{DO_NOTHING_ACTION}" on {get_object_represent(adcm_object)}' ): (user_object,) = as_user_objects(user_sdk, adcm_object) business_role = action_business_role(adcm_object, DO_NOTHING_ACTION) policy = create_action_policy(admin_sdk, adcm_object, business_role, user=user) check_single_action_is_allowed_on_object(DO_NOTHING_ACTION, adcm_object, user_sdk, business_role) with allure.step(f"Check that granted permission doesn't allow running '{DO_NOTHING_ACTION}' on other objects"): with user_objects_map( user_sdk, [adcm_object], *all_objects, exclude_predicate=_do_nothing_action_not_presented, ) as objects_map: check_action_is_not_allowed_on_objects(DO_NOTHING_ACTION, objects_map) with allure.step('Check permission withdrawn'): delete_policy(policy) is_denied(user_object, business_role)
def check_action_is_not_allowed_on_objects(action_display_name: str, objects_to_deny: Dict[Type, Dict[int, object]]): """Check that provided action (by display name) is not allowed to run on any of provided objects""" for object_map in objects_to_deny.values(): for adcm_object in object_map.values(): is_denied(adcm_object, action_business_role(adcm_object, action_display_name))
def test_cluster_admin(self, clients, user, clusters): """ Test that granting "Cluster Admin" to one cluster doesn't lead to unauthorized access to another cluster's actions """ first_cluster, second_cluster, first_another_bundle_cluster, second_another_bundle_cluster = as_user_objects( clients.user, *clusters) # will create role for each cluster with same prototype same_display_role = action_business_role(first_cluster, SAME_DISPLAY_ACTION_NAME) do_nothing_role = action_business_role(second_cluster, DO_NOTHING_ACTION_NAME) clients.admin.policy_create( name="Cluster Admin for First Cluster", role=clients.admin.role( display_name=RbacRoles.ClusterAdministrator.value), objects=[first_cluster], user=[user], ) self.check_permissions( "Check that Cluster Admin grants permission only on one cluster", allowed=((first_cluster, same_display_role), (first_cluster, do_nothing_role)), denied=( (second_cluster, same_display_role), (second_cluster, do_nothing_role), (first_another_bundle_cluster, do_nothing_role), (second_another_bundle_cluster, do_nothing_role), ), ) create_action_policy(clients.admin, second_cluster, action_business_role(first_cluster, SAME_DISPLAY_ACTION_NAME), user=user) self.check_permissions( "Check that Cluster Admin and permission to run action works correctly", # we can reuse allowed and disallowed if init them as sets # so if you'll have time, make those sets and change them allowed=( (first_cluster, same_display_role), (first_cluster, do_nothing_role), (second_cluster, same_display_role), ), denied=( (second_cluster, do_nothing_role), (first_another_bundle_cluster, do_nothing_role), (second_another_bundle_cluster, do_nothing_role), ), ) create_action_policy( clients.admin, first_another_bundle_cluster, action_business_role(first_cluster, DO_NOTHING_ACTION_NAME), user=user, ) self.check_permissions( "Check that Cluster Admin does not grant access to another bundle's clusters actions", allowed=( (first_cluster, same_display_role), (first_cluster, do_nothing_role), (second_cluster, same_display_role), (first_another_bundle_cluster, do_nothing_role), ), denied=( (second_cluster, do_nothing_role), (first_another_bundle_cluster, same_display_role), (second_another_bundle_cluster, do_nothing_role), (second_another_bundle_cluster, same_display_role), ), )
def test_service_admin(self, clients, clusters_with_services, user): """Test that granting "Service Admin" role doesn't interfere""" first_cluster, second_cluster = clusters_with_services first_service, second_service = as_user_objects( clients.user, *first_cluster.service_list()) another_cluster_service, *_ = as_user_objects(clients.user, second_cluster.service()) # will create role for each cluster with same prototype same_display_role = action_business_role(first_service, SAME_DISPLAY_ACTION_NAME) do_nothing_role = action_business_role(second_service, DO_NOTHING_ACTION_NAME) clients.admin.policy_create( name="Service Admin for First Cluster", role=clients.admin.role( display_name=RbacRoles.ServiceAdministrator.value), objects=[first_service], user=[user], ) self.check_permissions( "Check that Service Admin role allows actions only on one service in one cluster", allowed=((first_service, do_nothing_role), (first_service, same_display_role)), denied=((second_service, do_nothing_role), (another_cluster_service, do_nothing_role)), ) create_action_policy( clients.admin, second_service, action_business_role(second_service, DO_NOTHING_ACTION_NAME), user=user, ) self.check_permissions( "Check that granting permission for a single action on another service in cluster " "doesn't allow full access to cluster's actions", allowed=( (first_service, do_nothing_role), (first_service, same_display_role), (second_service, do_nothing_role), ), denied=((second_service, same_display_role), (another_cluster_service, do_nothing_role)), ) create_action_policy( clients.admin, another_cluster_service, action_business_role(another_cluster_service, DO_NOTHING_ACTION_NAME), user=user, ) self.check_permissions( "Check that granting permission to run a single action on another cluster's service " "doesn't grant extra permissions", allowed=( (first_service, do_nothing_role), (first_service, same_display_role), (second_service, do_nothing_role), (another_cluster_service, do_nothing_role), ), denied=((second_service, same_display_role), (another_cluster_service, same_display_role)), )
def check_new_action_with_old_display_name(self, user_object_map): """Check that new action that have display_name of another action from old version can be launched""" cluster = user_object_map['Cluster'] business_role = action_business_role(cluster, MIMIC_NAME) is_allowed(cluster, business_role)