def test_validate_publish_volume_request(self, validate_capabilities,
                                             validate_secrets):
        request = Mock()
        request.readonly = True

        with self.assertRaises(ValidationException) as ex:
            utils.validate_publish_volume_request(request)
            self.assertTrue("readonly" in ex.message)

        request.readonly = False
        validate_capabilities.side_effect = [ValidationException("msg1")]

        with self.assertRaises(ValidationException) as ex:
            utils.validate_publish_volume_request(request)
            self.assertTrue("msg1" in ex.message)

        validate_capabilities.side_effect = None
        request.secrets = []

        with self.assertRaises(ValidationException) as ex:
            utils.validate_publish_volume_request(request)
            self.assertTrue("secrets" in ex.message)

        request.secrets = ["secret"]
        validate_secrets.side_effect = [ValidationException("msg2")]

        with self.assertRaises(ValidationException) as ex:
            utils.validate_publish_volume_request(request)
            self.assertTrue("msg2" in ex.message)

        validate_secrets.side_effect = None

        utils.validate_publish_volume_request(request)
    def ControllerPublishVolume(self, request, context):
        set_current_thread_name(request.volume_id)
        logger.info("ControllerPublishVolume")
        try:
            utils.validate_publish_volume_request(request)

            array_type, vol_id = utils.get_volume_id_info(request.volume_id)

            node_id_info = NodeIdInfo(request.node_id)
            node_name = node_id_info.node_name
            initiators = node_id_info.initiators

            logger.debug("node name for this publish operation is : {0}".format(node_name))

            user, password, array_addresses = utils.get_array_connection_info_from_secret(request.secrets)
            lun, connectivity_type, array_initiators = map_volume(user, password, array_addresses, array_type, vol_id, initiators)

            logger.info("finished ControllerPublishVolume")
            res = utils.generate_csi_publish_volume_response(lun,
                                                         connectivity_type,
                                                         self.cfg,
                                                         array_initiators)
            return res

        except controller_errors.VolumeMappedToMultipleHostsError as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.FAILED_PRECONDITION)
            return csi_pb2.ControllerPublishVolumeResponse()

        except controller_errors.PermissionDeniedError as ex:
            context.set_code(grpc.StatusCode.PERMISSION_DENIED)
            context.set_details(ex)
            return csi_pb2.ControllerPublishVolumeResponse()

        except (controller_errors.LunAlreadyInUseError, controller_errors.NoAvailableLunError) as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED)
            return csi_pb2.ControllerPublishVolumeResponse()

        except (controller_errors.HostNotFoundError, controller_errors.VolumeNotFoundError, controller_errors.BadNodeIdError) as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.NOT_FOUND)
            return csi_pb2.ControllerPublishVolumeResponse()

        except ValidationException as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
            return csi_pb2.ControllerPublishVolumeResponse()

        except Exception as ex:
            logger.debug("an internal exception occurred")
            logger.exception(ex)
            context.set_code(grpc.StatusCode.INTERNAL)
            context.set_details('an internal exception occurred : {}'.format(ex))
            return csi_pb2.ControllerPublishVolumeResponse()
    def ControllerPublishVolume(self, request, context):
        set_current_thread_name(request.volume_id)
        logger.info("ControllerPublishVolume")
        utils.validate_publish_volume_request(request)
        try:
            volume_id_info = utils.get_volume_id_info(request.volume_id)
            system_id = volume_id_info.system_id
            array_type = volume_id_info.array_type
            volume_id = volume_id_info.object_id
            node_id_info = NodeIdInfo(request.node_id)
            node_name = node_id_info.node_name
            initiators = node_id_info.initiators

            logger.debug(
                "node name for this publish operation is : {0}".format(
                    node_name))

            array_connection_info = utils.get_array_connection_info_from_secrets(
                request.secrets, system_id=system_id)
            with get_agent(array_connection_info,
                           array_type).get_mediator() as array_mediator:
                lun, connectivity_type, array_initiators = array_mediator.map_volume_by_initiators(
                    volume_id, initiators)
            logger.info("finished ControllerPublishVolume")
            res = utils.generate_csi_publish_volume_response(
                lun, connectivity_type, self.cfg, array_initiators)
            return res

        except array_errors.VolumeMappedToMultipleHostsError as ex:
            return handle_exception(ex, context,
                                    grpc.StatusCode.FAILED_PRECONDITION,
                                    csi_pb2.ControllerPublishVolumeResponse)
        except (array_errors.LunAlreadyInUseError,
                array_errors.NoAvailableLunError) as ex:
            return handle_exception(ex, context,
                                    grpc.StatusCode.RESOURCE_EXHAUSTED,
                                    csi_pb2.ControllerPublishVolumeResponse)
        except (array_errors.NoIscsiTargetsFoundError, ObjectIdError) as ex:
            return handle_exception(ex, context, grpc.StatusCode.NOT_FOUND,
                                    csi_pb2.ControllerPublishVolumeResponse)
        except array_errors.UnsupportedConnectivityTypeError as ex:
            return handle_exception(ex, context,
                                    grpc.StatusCode.INVALID_ARGUMENT,
                                    csi_pb2.ControllerPublishVolumeResponse)
    def ControllerPublishVolume(self, request, context):
        set_current_thread_name(request.volume_id)
        logger.info("ControllerPublishVolume")
        try:
            utils.validate_publish_volume_request(request)

            volume_id_info = utils.get_volume_id_info(request.volume_id)
            system_id = volume_id_info.system_id
            array_type = volume_id_info.array_type
            volume_id = volume_id_info.object_id
            node_id_info = NodeIdInfo(request.node_id)
            node_name = node_id_info.node_name
            initiators = node_id_info.initiators

            logger.debug(
                "node name for this publish operation is : {0}".format(
                    node_name))

            array_connection_info = utils.get_array_connection_info_from_secrets(
                request.secrets, system_id=system_id)
            with get_agent(array_connection_info,
                           array_type).get_mediator() as array_mediator:
                lun, connectivity_type, array_initiators = array_mediator.map_volume_by_initiators(
                    volume_id, initiators)
            logger.info("finished ControllerPublishVolume")
            res = utils.generate_csi_publish_volume_response(
                lun, connectivity_type, self.cfg, array_initiators)
            return res

        except array_errors.VolumeMappedToMultipleHostsError as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.FAILED_PRECONDITION)
            return csi_pb2.ControllerPublishVolumeResponse()

        except array_errors.PermissionDeniedError as ex:
            context.set_code(grpc.StatusCode.PERMISSION_DENIED)
            context.set_details(ex.message)
            return csi_pb2.ControllerPublishVolumeResponse()

        except (array_errors.LunAlreadyInUseError,
                array_errors.NoAvailableLunError) as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED)
            return csi_pb2.ControllerPublishVolumeResponse()

        except (array_errors.HostNotFoundError,
                array_errors.ObjectNotFoundError,
                array_errors.NoIscsiTargetsFoundError, ObjectIdError) as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.NOT_FOUND)
            return csi_pb2.ControllerPublishVolumeResponse()

        except (ValidationException, array_errors.IllegalObjectID,
                array_errors.UnsupportedConnectivityTypeError) as ex:
            logger.exception(ex)
            context.set_details(ex.message)
            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
            return csi_pb2.ControllerPublishVolumeResponse()

        except Exception as ex:
            logger.debug("an internal exception occurred")
            logger.exception(ex)
            context.set_code(grpc.StatusCode.INTERNAL)
            context.set_details(
                'an internal exception occurred : {}'.format(ex))
            return csi_pb2.ControllerPublishVolumeResponse()