Example #1
0
def cluster_config(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster config operation.

    Required data: cluster_id

    :return: Dict
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    telemetry_handler.record_user_action_details(
        cse_operation=telemetry_constants.CseOperation.V36_CLUSTER_CONFIG,
        cse_params={
            server_constants.CLUSTER_ENTITY:
            def_entity,
            telemetry_constants.PayloadKey.SOURCE_DESCRIPTION:
            thread_local_data.get_thread_local_data(
                ThreadLocalData.USER_AGENT)  # noqa: E501
        })

    op_ctx.entity_id = cluster_id  # hack for passing entity id
    svc = cluster_service_factory.ClusterServiceFactory(
        _get_request_context(op_ctx)).get_cluster_service()  # noqa: E501
    config_dict = svc.get_cluster_config(cluster_id)

    config: str = config_dict.get(
        server_constants.BEHAVIOR_TASK_RESPONSE_RESULT_MESSAGE_KEY, {}).get(
            server_constants.BEHAVIOR_TASK_RESPONSE_RESULT_CONTENT_MESSAGE_KEY
        )  # noqa: E501
    return_dict = {"message": config}
    return return_dict
Example #2
0
    def upgrade_cluster(self,
                        cluster_name,
                        template_name,
                        template_revision,
                        org_name=None,
                        ovdc_name=None):
        """Get the upgrade plan for given cluster.

        :param str cluster_name: name of the cluster
        :param str template_name: Name of the template the cluster should be
        upgraded to.
        :param str template_revision: Revision of the template the cluster
        should be upgraded to.
        :param org_name: name of the org
        :param ovdc_name: name of the vdc
        :return: string containing upgrade cluster task href
        :rtype: str
        """
        filters = client_utils.construct_filters(org=org_name, vdc=ovdc_name)
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        current_entity = entity_svc.get_native_rde_by_name_and_rde_version(
            cluster_name, self._server_rde_version, filters=filters)
        if current_entity:
            current_entity.entity.spec.k8_distribution.template_name = template_name  # noqa: E501
            current_entity.entity.spec.k8_distribution.template_revision = template_revision  # noqa: E501
            return self.upgrade_cluster_by_cluster_id(
                current_entity.id,
                cluster_def_entity=asdict(current_entity))  # noqa: E501
        raise cse_exceptions.ClusterNotFoundError(
            f"Cluster '{cluster_name}' not found.")  # noqa: E501
Example #3
0
def nfs_node_delete(data, op_ctx: ctx.OperationContext):
    """Request handler for node delete operation.

    Required data: cluster_name, node_names_list
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    node_name = data[RequestKey.NODE_NAME]
    behavior_svc = BehaviorService(cloudapi_client=op_ctx.cloudapi_client)
    telemetry_handler.record_user_action_details(
        cse_operation=telemetry_constants.CseOperation.V36_NODE_DELETE,
        cse_params={
            telemetry_constants.PayloadKey.CLUSTER_ID:
            cluster_id,
            telemetry_constants.PayloadKey.NODE_NAME:
            node_name,
            telemetry_constants.PayloadKey.SOURCE_DESCRIPTION:
            thread_local_data.get_thread_local_data(
                server_constants.ThreadLocalData.USER_AGENT)  # noqa: E501
        })
    delete_nfs_node_task = behavior_svc.invoke_behavior(
        entity_id=cluster_id,
        behavior_interface_id=DELETE_NFS_NODE_BEHAVIOR_ID,
        arguments={RequestKey.NODE_NAME.value: node_name})
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    cluster_def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    cluster_def_entity.entity.status.task_href = delete_nfs_node_task

    return cluster_def_entity.to_dict()
Example #4
0
    def get_cluster_info(self,
                         cluster_name,
                         cluster_id=None,
                         org=None,
                         vdc=None,
                         **kwargs):
        """Get cluster information using DEF API.

        :param str cluster_name: name of the cluster
        :param str vdc: name of vdc
        :param str org: name of org
        :param kwargs: *filter (dict): keys,values for DEF API query filter

        :return: cluster information
        :rtype: dict
        """
        if cluster_id:
            return self.get_cluster_info_by_id(cluster_id)
        filters = client_utils.construct_filters(org=org, vdc=vdc)
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        def_entity = \
            entity_svc.get_native_rde_by_name_and_rde_version(
                cluster_name, self._server_rde_version, filters=filters)  # noqa: E501
        logger.CLIENT_LOGGER.debug(
            f"Defined entity info from server:{def_entity}")  # noqa: E501
        if not def_entity:
            logger.CLIENT_LOGGER.error(
                f"Cannot find native cluster with name {cluster_name}"
            )  # noqa: E501
            raise cse_exceptions.ClusterNotFoundError(
                f"Cluster '{cluster_name}' not found.")  # noqa: E501
        # TODO() relevant output
        if def_entity:
            return yaml.dump(asdict(def_entity.entity))
Example #5
0
    def apply(self, cluster_config, cluster_id=None, **kwargs):
        """Apply the configuration either to create or update the cluster.

        :param dict cluster_config: cluster configuration information
        :return: dictionary containing the apply operation task
        :rtype: dict
        """
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        cluster_spec = rde_1_0_0.NativeEntity(**cluster_config)
        cluster_name = cluster_spec.metadata.cluster_name
        if cluster_id:
            # If cluster id doesn't exist, an exception will be raised
            def_entity = entity_svc.get_entity(cluster_id)
        else:
            def_entity = entity_svc.get_native_rde_by_name_and_rde_version(
                cluster_name, self._server_rde_version)
        if not def_entity:
            cluster_entity = self._native_cluster_api.create_cluster(
                cluster_spec)  # noqa: E501
        else:
            cluster_id = def_entity.id
            cluster_entity = \
                self._native_cluster_api.update_cluster_by_cluster_id(cluster_id, cluster_spec)  # noqa: E501
        return client_utils.construct_task_console_message(
            cluster_entity.entity.status.task_href)  # noqa: E501
    def apply(self, cluster_apply_spec: dict, cluster_id: str = None, **kwargs):  # noqa: E501
        """Apply the configuration either to create or update the cluster.

        :param dict cluster_config: cluster configuration information
        :return: dictionary containing the apply operation task
        :rtype: dict
        """
        cluster_name = \
            self._get_cluster_name_from_cluster_apply_specification(cluster_apply_spec)  # noqa: E501
        # cluster name should not be missing from the apply specification
        if not cluster_name:
            raise Exception('Cluster name missing in the cluster apply specification')  # noqa: E501
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        if cluster_id:
            # If cluster id doesn't exist, an exception will be raised
            def_entity = entity_svc.get_entity(cluster_id)
        else:
            def_entity = entity_svc.get_native_rde_by_name_and_rde_version(
                cluster_name, self._server_rde_version)
        if not def_entity:
            cluster_def_entity = self._native_cluster_api.create_cluster(
                cluster_apply_spec)
        else:
            cluster_id = def_entity.id
            cluster_def_entity = \
                self._native_cluster_api.update_cluster_by_cluster_id(
                    cluster_id, cluster_apply_spec)
        task_href = cluster_def_entity.entity.status.task_href
        return client_utils.construct_task_console_message(task_href)
Example #7
0
def cluster_acl_info(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster acl list operation."""
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity = def_entity_service.get_entity(cluster_id)
    rde_utils.raise_error_if_tkgm_cluster_operation(
        def_entity.entity.kind)  # noqa: E501
    query = data.get(RequestKey.QUERY_PARAMS, {})
    page = int(
        query.get(PaginationKey.PAGE_NUMBER,
                  CSE_PAGINATION_FIRST_PAGE_NUMBER))  # noqa: E501
    page_size = int(
        query.get(PaginationKey.PAGE_SIZE,
                  CSE_PAGINATION_DEFAULT_PAGE_SIZE))  # noqa: E501
    op_ctx.entity_id = data[
        RequestKey.CLUSTER_ID]  # hack for passing entity id  # noqa: E501
    svc = cluster_service_factory.ClusterServiceFactory(
        _get_request_context(op_ctx)).get_cluster_service()  # noqa: E501
    result: dict = svc.get_cluster_acl_info(cluster_id, page, page_size)

    # remove duplicate /api path while forming the endpoint url
    uri = f"{op_ctx.client.get_api_uri().strip('/api')}{data['url']}"
    return server_utils.create_links_and_construct_paginated_result(
        base_uri=uri,
        values=result.get(PaginationKey.VALUES, []),
        result_total=result.get(PaginationKey.RESULT_TOTAL, 0),
        page_number=page,
        page_size=page_size)
Example #8
0
    def get_cluster_service(self,
                            rde_version_in_use=None,
                            skip_tkgm_check=False):  # noqa: E501
        """Get the right instance of backend cluster service.

        Factory method to return the ClusterService based on the RDE version in use.
        :param rde_version_in_use (str)
        :param bool skip_tkgm_check: flag specifying not to use TKGm cluster service

        :rtype cluster_service (container_service_extension.server.abstract_broker.AbstractBroker)  # noqa: E501
        """
        if rde_version_in_use is None:
            rde_version_in_use = server_utils.get_rde_version_in_use()
        rde_version: semantic_version.Version = semantic_version.Version(
            rde_version_in_use)  # noqa: E501
        if rde_version.major == 1:
            return ClusterService1X(op_ctx=self.req_ctx)
        elif rde_version.major == 2:
            entity = self.req_ctx.entity
            if not skip_tkgm_check and entity is None:
                def_entity_svc = entity_service.DefEntityService(
                    self.req_ctx.op_ctx.cloudapi_client)  # noqa: E501
                def_entity = def_entity_svc.get_entity(
                    self.req_ctx.op_ctx.entity_id)  # noqa: E501
                entity = def_entity.entity.to_dict()
            if not skip_tkgm_check and entity.get(
                    'kind') == ClusterEntityKind.TKG_M.value:  # noqa: E501
                return ClusterService2XTKGm(self.req_ctx)
            else:
                return ClusterService2X(self.req_ctx)
Example #9
0
def cluster_delete(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster delete operation.

    Required data: cluster_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    telemetry_handler.record_user_action_details(
        cse_operation=telemetry_constants.CseOperation.V36_CLUSTER_DELETE,
        cse_params={
            server_constants.CLUSTER_ENTITY:
            def_entity,
            telemetry_constants.PayloadKey.SOURCE_DESCRIPTION:
            thread_local_data.get_thread_local_data(
                ThreadLocalData.USER_AGENT)  # noqa: E501
        })
    _, task_href = def_entity_service.delete_entity(
        cluster_id, invoke_hooks=True, is_request_async=True)  # noqa: E501
    def_entity.entity.status.task_href = task_href
    return def_entity.to_dict()
Example #10
0
 def get_cluster_id_by_name(self, cluster_name, org=None, vdc=None):
     filters = client_utils.construct_filters(org=org, vdc=vdc)
     entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
     def_entity = entity_svc.get_native_rde_by_name_and_rde_version(
         cluster_name, self._server_rde_version, filters=filters)
     if not def_entity:
         raise cse_exceptions.ClusterNotFoundError(
             f"Cluster '{cluster_name}' not found.")  # noqa: E501
     return def_entity.id
Example #11
0
def cluster_create(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster create operation.

    :return: Defined entity of the native cluster
    :rtype: container_service_extension.def_.models.DefEntity
    """
    input_entity: dict = data[RequestKey.INPUT_SPEC]
    payload_version = input_entity.get(
        rde_constants.PayloadKey.PAYLOAD_VERSION)  # noqa: E501
    rde_utils.raise_error_if_unsupported_payload_version(payload_version)

    # Validate the Input payload based on the (Operation, payload_version).
    # Get the validator based on the payload_version
    # ToDo : Don't use default cloudapi_client. Use the specific versioned one
    rde_validator_factory.get_validator(
        rde_version=rde_constants.
        MAP_INPUT_PAYLOAD_VERSION_TO_RDE_VERSION[payload_version]).validate(
            cloudapi_client=op_ctx.cloudapi_client,
            sysadmin_client=op_ctx.sysadmin_client,
            entity=input_entity)

    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    entity_type = server_utils.get_registered_def_entity_type()
    converted_entity: AbstractNativeEntity = rde_utils.convert_input_rde_to_runtime_rde_format(
        input_entity)  # noqa: E501
    def_entity = common_models.DefEntity(
        entity=converted_entity, entityType=entity_type.id)  # noqa: E501

    # No need to set org context for non sysadmin users
    org_context = None
    if op_ctx.client.is_sysadmin():
        org_resource = pyvcloud_utils.get_org(
            op_ctx.client,
            org_name=converted_entity.metadata.org_name)  # noqa: E501
        org_context = org_resource.href.split('/')[-1]

    _, task_href = def_entity_service.create_entity(
        entity_type_id=entity_type.id,
        entity=def_entity,
        tenant_org_context=org_context,
        is_request_async=True)

    task_resource = op_ctx.sysadmin_client.get_resource(task_href)
    entity_id = task_resource.Owner.get('id')
    def_entity = def_entity_service.get_entity(entity_id)
    def_entity.entity.status.task_href = task_href
    telemetry_handler.record_user_action_details(
        cse_operation=telemetry_constants.CseOperation.V36_CLUSTER_APPLY,
        cse_params={
            server_constants.CLUSTER_ENTITY:
            def_entity,
            telemetry_constants.PayloadKey.SOURCE_DESCRIPTION:
            thread_local_data.get_thread_local_data(
                ThreadLocalData.USER_AGENT)  # noqa: E501
        })
    return def_entity.to_dict()
Example #12
0
    def get_cluster_config_by_id(self, cluster_id, org=None):
        """Fetch kube config of the cluster using cluster ID.

        :param str cluster_id:
        :param str org:
        """
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        if entity_svc.is_native_entity(cluster_id):
            return self._nativeCluster.get_cluster_config_by_id(cluster_id)
        return self._tkgCluster.get_cluster_config_by_id(cluster_id, org=org)
    def get_cluster_info_by_id(self, cluster_id, **kwargs):
        """Get cluster information by cluster ID.

        :param str cluster_id: ID of the cluster
        :return: cluster information in yaml format
        :rtype: str
        """
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        def_entity = entity_svc.get_entity(cluster_id)
        logger.CLIENT_LOGGER.debug(f"Defined entity info from server: {def_entity}")  # noqa: E501
        return yaml.dump(def_entity.entity.to_dict())
    def get_cluster_info_by_id(self, cluster_id, org=None):
        """Obtain cluster information using cluster ID.

        :param str cluster_id
        :return: yaml representation of the cluster information
        :rtype: str
        """
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        if entity_svc.is_native_entity(cluster_id):
            return self._nativeCluster.get_cluster_info_by_id(cluster_id=cluster_id)  # noqa: E501
        return self._tkgCluster.get_cluster_info_by_id(cluster_id, org=org)  # noqa: E501
Example #15
0
def cluster_update(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster resize operation.

    :return: Defined entity of the native cluster
    :rtype: container_service_extension.def_.models.DefEntity
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    input_entity: dict = data[RequestKey.INPUT_SPEC]
    payload_version = input_entity.get(
        rde_constants.PayloadKey.PAYLOAD_VERSION)  # noqa: E501
    rde_utils.raise_error_if_unsupported_payload_version(payload_version)

    # Validate the Input payload based on the (Operation, payload_version).
    # Get the validator based on the payload_version
    # ToDo : Don't use default cloudapi_client. Use the specific versioned one
    kind = input_entity['kind']
    is_tkgm_cluster = (kind == ClusterEntityKind.TKG_M.value)
    sysadmin_client = op_ctx.sysadmin_client
    rde_validator_factory.get_validator(
        rde_version=rde_constants.MAP_INPUT_PAYLOAD_VERSION_TO_RDE_VERSION[
            payload_version]). \
        validate(cloudapi_client=op_ctx.cloudapi_client,
                 sysadmin_client=sysadmin_client, entity_id=cluster_id,
                 entity=input_entity,
                 operation=BehaviorOperation.UPDATE_CLUSTER,
                 is_tkgm_cluster=is_tkgm_cluster)

    # Convert the input entity to runtime rde format.
    # Based on the runtime rde, call the appropriate backend method.
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    converted_native_entity: AbstractNativeEntity = rde_utils.convert_input_rde_to_runtime_rde_format(
        input_entity)  # noqa: E501

    changes = {'entity.spec': converted_native_entity.spec}
    updated_def_entity, task_href = def_entity_service.update_entity(
        entity_id=cluster_id,
        invoke_hooks=True,
        is_request_async=True,
        changes=changes)
    updated_def_entity.entity.status.task_href = task_href
    telemetry_handler.record_user_action_details(
        cse_operation=telemetry_constants.CseOperation.V36_CLUSTER_APPLY,
        cse_params={
            server_constants.CLUSTER_ENTITY:
            updated_def_entity,
            telemetry_constants.PayloadKey.SOURCE_DESCRIPTION:
            thread_local_data.get_thread_local_data(
                ThreadLocalData.USER_AGENT)  # noqa: E501
        })
    # TODO: Response RDE must be compatible with the request RDE.
    #  Conversions may be needed especially if there is a major version
    #  difference in the input RDE and runtime RDE.
    return updated_def_entity.to_dict()
Example #16
0
    def delete_cluster_by_id(self, cluster_id, org=None):
        """Delete cluster using cluster id.

        :param str cluster_id: id of the cluster to be deleted
        :return: deleted cluster information
        :rtype: str
        :raises: ClusterNotFoundError
        """
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        if entity_svc.is_native_entity(cluster_id):
            return self._nativeCluster.delete_cluster_by_id(cluster_id)
        return self._tkgCluster.delete_cluster_by_id(cluster_id, org=org)
Example #17
0
def cluster_acl_update(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster acl update operation."""
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity = def_entity_service.get_entity(cluster_id)
    rde_utils.raise_error_if_tkgm_cluster_operation(
        def_entity.entity.kind)  # noqa: E501
    op_ctx.entity_id = data[
        RequestKey.CLUSTER_ID]  # hack for passing entity id  # noqa: E501
    svc = cluster_service_factory.ClusterServiceFactory(
        _get_request_context(op_ctx)).get_cluster_service()  # noqa: E501
    update_acl_entries = data.get(RequestKey.INPUT_SPEC, {}).get(
        ClusterAclKey.ACCESS_SETTING)  # noqa: E501
    svc.update_cluster_acl(cluster_id, update_acl_entries)
    def unshare_cluster(self, cluster_id, cluster_name, users: list, org=None,
                        vdc=None):
        if cluster_id:
            entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
            is_native_cluster = entity_svc.is_native_entity(cluster_id)
        else:
            _, _, is_native_cluster = \
                self._get_tkg_native_clusters_by_name(cluster_name, org=org,
                                                      vdc=vdc)

        if is_native_cluster:
            self._nativeCluster.unshare_cluster(cluster_id, cluster_name,
                                                users, org, vdc)
        else:
            self._tkgCluster.unshare_cluster(cluster_id, cluster_name, users,
                                             org, vdc)
Example #19
0
    def list_share_entries(self, cluster_id, cluster_name, org=None, vdc=None):
        # Find cluster type
        if cluster_id:
            entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
            is_native_cluster = entity_svc.is_native_entity(cluster_id)
        else:
            _, _, is_native_cluster = \
                self._get_tkg_native_clusters_by_name(cluster_name, org=org,
                                                      vdc=vdc)

        if is_native_cluster:
            return self._nativeCluster.list_share_entries(
                cluster_id, cluster_name, org, vdc)
        else:
            return self._tkgCluster.list_share_entries(cluster_id,
                                                       cluster_name, org, vdc)
Example #20
0
    def get_upgrade_plan(self, cluster_name, org=None, vdc=None):
        """Get the upgrade plan for given cluster.

        :param cluster_name: name of the cluster
        :param org: name of the org
        :param vdc: name of the vdc
        :return: upgrade plan info
        :rtype: dict
        """
        filters = client_utils.construct_filters(org=org, vdc=vdc)
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        def_entity = entity_svc.get_native_rde_by_name_and_rde_version(
            cluster_name, self._server_rde_version, filters=filters)
        if def_entity:
            return self.get_upgrade_plan_by_cluster_id(def_entity.id)
        raise cse_exceptions.ClusterNotFoundError(
            f"Cluster '{cluster_name}' not found.")  # noqa: E501
Example #21
0
    def delete_nfs_node(self, cluster_name, node_name, org=None, vdc=None):
        """Delete nfs node given the cluster name and node name.

        :param str cluster_name: native cluster name
        :param str node_name: nfs-node name
        :param str org: name of the org
        :param str vdc: name of the vdc
        :return: string containing delete operation task href
        :rtype: str
        :raises ClusterNotFoundError
        """
        filters = client_utils.construct_filters(org=org, vdc=vdc)
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        def_entity = entity_svc.get_native_rde_by_name_and_rde_version(
            cluster_name, self._server_rde_version, filters=filters)
        if def_entity:
            return self.delete_nfs_by_cluster_id(def_entity.id, node_name)
        raise cse_exceptions.ClusterNotFoundError(
            f"Cluster '{cluster_name}' not found.")  # noqa: E501
def cluster_delete(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster delete operation.

    Required data: cluster_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    _, task_href = def_entity_service.delete_entity(
        cluster_id, invoke_hooks=True, is_request_async=True)  # noqa: E501
    def_entity.entity.status.task_href = task_href
    return def_entity.to_dict()
def cluster_update(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for cluster resize operation.

    :return: Defined entity of the native cluster
    :rtype: container_service_extension.def_.models.DefEntity
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    input_entity: dict = data[RequestKey.INPUT_SPEC]
    payload_version = input_entity.get(
        rde_constants.PayloadKey.PAYLOAD_VERSION)  # noqa: E501
    rde_utils.raise_error_if_unsupported_payload_version(payload_version)

    # Validate the Input payload based on the (Operation, payload_version).
    # Get the validator based on the payload_version
    # ToDo : Don't use default cloudapi_client. Use the specific versioned one
    rde_validator_factory.get_validator(
        rde_version=rde_constants.MAP_INPUT_PAYLOAD_VERSION_TO_RDE_VERSION[
            payload_version]). \
        validate(cloudapi_client=op_ctx.cloudapi_client, entity_id=cluster_id,
                 entity=input_entity,
                 operation=BehaviorOperation.UPDATE_CLUSTER)

    # Convert the input entity to runtime rde format.
    # Based on the runtime rde, call the appropriate backend method.
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    converted_native_entity: AbstractNativeEntity = rde_utils.convert_input_rde_to_runtime_rde_format(
        input_entity)  # noqa: E501
    cluster_def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    cluster_def_entity.entity.spec = converted_native_entity.spec
    updated_def_entity, task_href = def_entity_service.update_entity(
        entity_id=cluster_id,
        entity=cluster_def_entity,
        invoke_hooks=True,
        is_request_async=True)
    updated_def_entity.entity.status.task_href = task_href
    # TODO: Response RDE must be compatible with the request RDE.
    #  Conversions may be needed especially if there is a major version
    #  difference in the input RDE and runtime RDE.
    return updated_def_entity.to_dict()
Example #24
0
def cluster_force_delete(data: dict, op_ctx: ctx.OperationContext):
    """Request handler for force cluster delete operation.

    Required data: cluster_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    cluster_id = data[RequestKey.CLUSTER_ID]
    def_entity_service = entity_service.DefEntityService(
        op_ctx.cloudapi_client)  # noqa: E501
    def_entity: common_models.DefEntity = def_entity_service.get_entity(
        cluster_id)  # noqa: E501
    op_ctx.entity_id = cluster_id
    svc = cluster_service_factory.ClusterServiceFactory(
        _get_request_context(op_ctx)).get_cluster_service()  # noqa: E501
    task_href = svc.force_delete_cluster(cluster_id)
    def_entity.entity.status.task_href = task_href
    return def_entity.to_dict()
Example #25
0
    def share_cluster(self,
                      cluster_id,
                      cluster_name,
                      users: list,
                      access_level_id,
                      org=None,
                      vdc=None):
        # Find cluster type
        if cluster_id:
            entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
            is_native_cluster = entity_svc.is_native_entity(cluster_id)
        else:
            _, _, is_native_cluster = \
                self._get_tkg_s_and_native_clusters_by_name(
                    cluster_name, org=org, vdc=vdc
                )

        if is_native_cluster:
            self._nativeCluster.share_cluster(cluster_id, cluster_name, users,
                                              access_level_id, org, vdc)
        else:
            self._tkgCluster.share_cluster(cluster_id, cluster_name, users,
                                           access_level_id, org, vdc)
Example #26
0
    def list_clusters(self, vdc=None, org=None, **kwargs):
        """Get collection of clusters using DEF API.

        :param str vdc: name of vdc
        :param str org: name of org
        :param kwargs: *filter (dict): keys,values for DEF API query filter

        :return: cluster list information
        :rtype: list(dict)
        """
        clusters = []
        if client_utils.is_cli_for_tkg_only():
            try:
                for clusters, has_more_results in \
                        self._tkgCluster.list_tkg_clusters(vdc=vdc, org=org):
                    yield clusters, has_more_results
            except tkg_rest.ApiException as e:
                if e.status not in [
                        requests.codes.FORBIDDEN, requests.codes.UNAUTHORIZED
                ]:  # noqa: E501
                    server_message = json.loads(
                        e.body).get('message') or e.reason  # noqa: E501
                    msg = cli_constants.TKG_RESPONSE_MESSAGES_BY_STATUS_CODE.get(
                        e.status, f"{server_message}")  # noqa: E501
                    logger.CLIENT_LOGGER.error(msg)
                    raise Exception(msg)
                msg = f"User not authorized to fetch TKG clusters: {e}"
                logger.CLIENT_LOGGER.debug(msg)
                raise e
        else:
            # display all clusters
            filters = client_utils.construct_filters(self._server_rde_version,
                                                     org=org,
                                                     vdc=vdc)
            entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
            has_more_results = True
            page_number = CSE_PAGINATION_FIRST_PAGE_NUMBER
            page_size = CSE_PAGINATION_DEFAULT_PAGE_SIZE
            try:
                while has_more_results:
                    clusters_page_results = entity_svc.get_all_entities_per_page_by_interface(  # noqa: E501
                        vendor=common_models.K8Interface.VCD_INTERFACE.value.
                        vendor,  # noqa: E501
                        nss=common_models.K8Interface.VCD_INTERFACE.value.nss,
                        version=common_models.K8Interface.VCD_INTERFACE.value.
                        version,  # noqa: E501
                        filters=filters,
                        page_number=page_number,
                        page_size=page_size)
                    # Get the list of cluster defined entities
                    entities: List[
                        common_models.
                        GenericClusterEntity] = clusters_page_results[
                            PaginationKey.VALUES]  # noqa: E501
                    clusters = []
                    for de in entities:
                        entity = de.entity
                        logger.CLIENT_LOGGER.debug(
                            f"Native Defined entity list from server: {entity}"
                        )  # noqa: E501
                        cluster = {
                            cli_constants.CLIOutputKey.CLUSTER_NAME.value:
                            de.name,  # noqa: E501
                            cli_constants.CLIOutputKey.ORG.value:
                            de.org.name,  # noqa: E501
                            cli_constants.CLIOutputKey.OWNER.value:
                            de.owner.name  # noqa: E501
                        }
                        if isinstance(entity, AbstractNativeEntity):
                            # TODO remove if-else logic once model classes
                            #   start using snake_case
                            if hasattr(entity.metadata, 'ovdc_name'):
                                cluster[cli_constants.CLIOutputKey.VDC.value] = \
                                    entity.metadata.ovdc_name  # noqa: E501
                            elif hasattr(entity.metadata, 'ovdcName'):
                                cluster[cli_constants.CLIOutputKey.VDC.value] = \
                                    entity.metadata.ovdcName  # noqa: E501
                            cluster[cli_constants.CLIOutputKey.K8S_RUNTIME.
                                    value] = entity.kind  # noqa: E501
                            cluster[
                                cli_constants.CLIOutputKey.K8S_VERSION.
                                value] = entity.status.kubernetes  # noqa: E501
                            cluster[cli_constants.CLIOutputKey.STATUS.
                                    value] = entity.status.phase  # noqa: E501
                        elif isinstance(entity, common_models.TKGEntity):
                            cluster[cli_constants.CLIOutputKey.VDC.value] = \
                                entity.metadata.virtualDataCenterName
                            cluster[cli_constants.CLIOutputKey.K8S_RUNTIME.
                                    value] = entity.kind  # noqa: E501
                            cluster[
                                cli_constants.CLIOutputKey.K8S_VERSION.
                                value] = entity.spec.distribution.version  # noqa: E501
                            cluster[cli_constants.CLIOutputKey.STATUS.value] = \
                                entity.status.phase if entity.status else 'N/A'  # noqa: E501
                        clusters.append(cluster)
                    has_more_results = page_number * page_size < \
                        clusters_page_results[PaginationKey.RESULT_TOTAL]
                    yield clusters, has_more_results
                    page_number += 1
            except requests.exceptions.HTTPError as e:
                msg = f"Failed to fetch clusters: {e}"
                logger.CLIENT_LOGGER.debug(msg)
                raise e
Example #27
0
 def def_entity(self):
     if self._def_entity is None:
         entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
         self._def_entity = entity_svc.get_tkg_or_def_entity(
             self._cluster_id)  # noqa: E501
     return self._def_entity
Example #28
0
    def _get_tkg_native_clusters_by_name(self,
                                         cluster_name: str,
                                         org=None,
                                         vdc=None):
        """Get native and TKG clusters by name.

        Assumption: Native clusters cannot have name collision among them.
        But there can be multiple TKG clusters with the same name and 2 or
        more TKG clusters can also have the same name.

        :param str cluster_name: Cluster name to search for
        :param str org: Org to filter by
        :param str vdc: VDC to filter by
        :returns: tkg entity or native def entity with entity properties and
            boolean indicating cluster type
        :rtype: (cluster, dict,  bool)
        """
        filters = client_utils.construct_filters(self._server_rde_version,
                                                 org=org,
                                                 vdc=vdc)
        entity_svc = def_entity_svc.DefEntityService(self._cloudapi_client)
        has_native_rights = True
        has_tkg_rights = True
        native_def_entity = None
        additional_entity_properties = None
        # NOTE: The following can throw error if invoked by users who
        # doesn't have the necessary rights.
        try:
            native_def_entity = \
                entity_svc.get_native_rde_by_name_and_rde_version(
                    cluster_name, self._server_rde_version,
                    filters=filters)
        except cse_exceptions.DefSchemaServiceError:
            # NOTE: 500 status code is returned which is not ideal
            # when user doesn't have native rights
            has_native_rights = False

        tkg_entity = []
        tkg_def_entity = []
        # NOTE: The following can throw error if invoked by users who
        # doesn't have the necessary rights.
        try:
            tkg_entity, tkg_def_entity = \
                self._tkgCluster.get_tkg_clusters_by_name(cluster_name,
                                                          vdc=vdc, org=org)
        except tkg_rest.ApiException as e:
            if e.status not in [
                    requests.codes.FORBIDDEN, requests.codes.UNAUTHORIZED
            ]:  # noqa: E501
                raise
            has_tkg_rights = False
        except cse_exceptions.ClusterNotFoundError:
            logger.CLIENT_LOGGER.debug(
                f"No TKG cluster with name {cluster_name}")  # noqa: E501
        if not (has_native_rights or has_tkg_rights):
            raise Exception("User cannot access native or TKG clusters."
                            " Please contact administrator")
        msg = "Multiple clusters with the same name found."
        if len(tkg_entity) > 0 and native_def_entity:
            # If org filter is not provided, ask the user to provide org
            # filter
            if not org:
                # handles the case where there is are TKG clusters and native
                # clusters with the same name in different organizations
                raise Exception(f"{msg} Please specify the org to use "
                                "using --org flag.")
            # handles the case where there is a TKG cluster and a native
            # native cluster with the same name in the same organization
            raise Exception(f"{msg} Please specify the k8-runtime to use using"
                            " --k8-runtime flag.")
        if not native_def_entity and len(tkg_entity) == 0:
            # handles the case where no clusters are found
            msg = f"Cluster '{cluster_name}' not found."
            logger.CLIENT_LOGGER.error(msg)
            raise cse_exceptions.ClusterNotFoundError(msg)
        if native_def_entity:
            cluster = native_def_entity
            is_native_cluster = True
        else:
            additional_entity_properties = tkg_def_entity[0]
            cluster = tkg_entity[0]
            is_native_cluster = False

        return cluster, additional_entity_properties, is_native_cluster