def create_pks_compute_profile(request_data, op_ctx: ctx.OperationContext,
                               pks_context):
    ovdc_id = request_data.get(RequestKey.OVDC_ID)
    org_name = request_data.get(RequestKey.ORG_NAME)
    ovdc_name = request_data.get(RequestKey.OVDC_NAME)
    # Compute profile creation
    pks_compute_profile_name = _construct_pks_compute_profile_name(
        op_ctx.sysadmin_client, ovdc_id)
    pks_compute_profile_description = f"{org_name}--{ovdc_name}--{ovdc_id}"
    pks_az_name = f"az-{ovdc_name}"
    ovdc_rp_name = f"{ovdc_name} ({ovdc_id})"

    compute_profile_params = PksComputeProfileParams(
        pks_compute_profile_name, pks_az_name, pks_compute_profile_description,
        pks_context.get('cpi'), pks_context.get('datacenter'),
        pks_context.get('cluster'), ovdc_rp_name).to_dict()

    LOGGER.debug(f"Creating PKS Compute Profile with name:"
                 f"{pks_compute_profile_name}")

    pksbroker = PksBroker(pks_context, op_ctx)
    try:
        pksbroker.create_compute_profile(**compute_profile_params)
    except e.PksServerError as err:
        if err.status == requests.codes.conflict:
            LOGGER.debug(f"Compute profile name {pks_compute_profile_name}"
                         f" already exists\n{str(err)}")
        else:
            raise
Example #2
0
    def get_compute_profile(self, cp_name):
        """Get the details of compute profile.

        :param str cp_name: Name of the compute profile
        :return: Details of the compute profile as body of the result

        :rtype: dict
        """
        result = {
            'body': [],
            'status_code': requests.codes.ok,
        }
        profile_api = ProfileApi(api_client=self.pks_client)

        self.pks_wire_logger.debug(f"Sending request to"
                                   f" PKS:{self.pks_host_uri} to get the"
                                   f" compute profile: {cp_name}")

        try:
            compute_profile = \
                profile_api.get_compute_profile(profile_name=cp_name)
        except ApiException as err:
            SERVER_LOGGER.debug(f"Creating compute-profile {cp_name}"
                                f" in PKS failed with error:\n {err}")
            raise PksServerError(err.status, err.body)

        self.pks_wire_logger.debug(f"Received response from"
                                   f" PKS: {self.pks_host_uri} on"
                                   f" compute-profile: {cp_name} with"
                                   f" details: {compute_profile.to_dict()}")

        result['body'] = compute_profile.to_dict()
        return result
Example #3
0
    def _list_clusters(self, data):
        """."""
        result = []
        try:
            cluster_api = ClusterApi(api_client=self.pks_client)

            self.pks_wire_logger.debug(
                f"Sending request to PKS: {self.pks_host_uri} "
                "to list all clusters")
            pks_clusters = cluster_api.list_clusters()
            self.pks_wire_logger.debug(
                f"Received response from PKS: {self.pks_host_uri} "
                f"on the list of clusters: {pks_clusters}")

            for pks_cluster in pks_clusters:
                cluster_info = pks_cluster.to_dict()
                cluster_info[K8S_PROVIDER_KEY] = K8sProvider.PKS
                self._restore_original_name(cluster_info)
                # Flatten the nested 'parameters' dict
                cluster_params_dict = cluster_info.pop('parameters')
                cluster_info.update(cluster_params_dict)
                self.update_cluster_with_vcd_info(cluster_info)
                result.append(cluster_info)
        except ApiException as err:
            SERVER_LOGGER.debug(
                f"Listing PKS clusters failed with error:\n {err}"
            )  # noqa: E501
            raise PksServerError(err.status, err.body)

        return self._filter_clusters(result, **data)
Example #4
0
    def delete_compute_profile(self, cp_name):
        """Delete the compute profile with a given name.

        :param str cp_name: Name of the compute profile
        :return: result

        :rtype: dict
        """
        result = {
            'body': [],
            'status_code': requests.codes.ok,
        }
        profile_api = ProfileApi(api_client=self.pks_client)

        self.pks_wire_logger.debug(f"Sending request to PKS:"
                                   f"{self.pks_host_uri} to delete"
                                   f" the compute profile: {cp_name}")
        try:
            profile_api.delete_compute_profile(profile_name=cp_name)
        except ApiException as err:
            SERVER_LOGGER.debug(f"Deleting compute-profile {cp_name}"
                                f" in PKS failed with error:\n {err}")
            raise PksServerError(err.status, err.body)

        self.pks_wire_logger.debug(f"Received response from PKS:"
                                   f" {self.pks_host_uri} that it deleted"
                                   f" the compute profile: {cp_name}")

        return result
Example #5
0
    def list_compute_profiles(self):
        """Get the list of compute profiles.

        :return: List of compute profile details as body of the result

        :rtype: dict
        """
        result = {
            'body': [],
            'status_code': requests.codes.ok,
        }
        profile_api = ProfileApi(api_client=self.pks_client)

        self.pks_wire_logger.debug(f"Sending request to PKS:"
                                   f" {self.pks_host_uri} to get the"
                                   f" list of compute profiles")
        try:
            cp_list = profile_api.list_compute_profiles()
        except ApiException as err:
            SERVER_LOGGER.debug(f"Listing compute-profiles in PKS failed "
                                f"with error:\n {err}")
            raise PksServerError(err.status, err.body)

        list_of_cp_dicts = [cp.to_dict() for cp in cp_list]
        self.pks_wire_logger.debug(f"Received response from PKS:"
                                   f" {self.pks_host_uri} on list of"
                                   f" compute profiles: {list_of_cp_dicts}")

        result['body'] = list_of_cp_dicts
        return result
Example #6
0
def record_user_action(cse_operation,
                       status=OperationStatus.SUCCESS,
                       message=None,
                       telemetry_settings=None):
    """Record CSE user action information in telemetry server.

    No exceptions should be leaked. Catch all exceptions and log them.

    :param CseOperation cse_operation:
    :param OperationStatus status: SUCCESS/FAILURE of the user action
    :param str message: any information about failure or custom message
    :param dict telemetry_settings: telemetry section CSE config->service
    """
    try:
        if not telemetry_settings:
            server_config = get_server_runtime_config()
            telemetry_settings = None if not server_config else \
                server_config.get_value_at('service.telemetry')

        if telemetry_settings:
            if telemetry_settings.get('enable'):
                payload = get_payload_for_user_action(cse_operation, status,
                                                      message)  # noqa: E501
                _send_data_to_telemetry_server(payload, telemetry_settings)
        else:
            LOGGER.debug('No telemetry settings found.')
    except Exception as err:
        LOGGER.warning(
            f"Error in recording user action information:{str(err)}",
            exc_info=True)  # noqa: E501
Example #7
0
 def on_queue_declareok(self, method_frame):
     LOGGER.debug(f"Binding ({self.exchange}) to ({self.queue}) with "
                  f"({self.routing_key})")
     self._channel.queue_bind(self.queue,
                              self.exchange,
                              routing_key=self.routing_key,
                              callback=self.on_bindok)
    def create_compute_profile(self, cp_name, az_name, description, cpi,
                               datacenter_name, cluster_name, ovdc_rp_name):
        """Create a PKS compute profile that maps to a given oVdc in vCD.

        :param str cp_name: Name of the compute profile
        :param str az_name: Name of the PKS availability zone to be defined
        :param str description: Description of the compute profile
        :param str cpi: Unique identifier provided by BOSH
        :param str datacenter_name: Name of the datacenter
        :param str cluster_name: Name of the cluster
        :param str ovdc_rp_name: Name of the oVdc resource pool

        :return: result

        :rtype: dict
        """
        result = {
            'body': [],
            'status_code': requests.codes.ok,
        }
        profile_api = ProfileApi(api_client=self.pks_client)

        resource_pool = {
            'resource_pool': ovdc_rp_name
        }

        cloud_properties = {
            'datacenters': [
                {
                    'name': datacenter_name,
                    'clusters': [
                        {
                            cluster_name: resource_pool
                        }
                    ]
                }
            ]
        }

        az = AZ(name=az_name, cpi=cpi, cloud_properties=cloud_properties)
        cp_params = ComputeProfileParameters(azs=[az])
        cp_request = ComputeProfileRequest(name=cp_name,
                                           description=description,
                                           parameters=cp_params)

        self.pks_wire_logger.debug(f"Sending request to"
                                   f" PKS:{self.pks_host_uri} to create the"
                                   f" compute profile: {cp_name}"
                                   f" for ovdc {ovdc_rp_name}")
        try:
            profile_api.add_compute_profile(body=cp_request)
        except ApiException as err:
            SERVER_LOGGER.debug(f"Creating compute-profile {cp_name} in PKS"
                                f" failed with error:\n {err}")
            raise PksServerError(err.status, err.body)

        self.pks_wire_logger.debug(f"PKS: {self.pks_host_uri} created the"
                                   f" compute profile: {cp_name}"
                                   f" for ovdc {ovdc_rp_name}")
        return result
Example #9
0
        def decorator_wrapper(*args, **kwargs):
            server_config = server_utils.get_server_runtime_config()

            if (server_config.get_value_at('service.enforce_authorization')
                    and required_rights is not None
                    and len(required_rights) > 0):
                class_instance: abstract_broker.AbstractBroker = args[0]
                user_rights = class_instance.context.user.rights

                missing_rights = []
                for right_name in required_rights:
                    right_name_with_namespace = \
                        f"{{{CSE_SERVICE_NAMESPACE}}}:{right_name}"
                    if right_name_with_namespace not in user_rights:
                        missing_rights.append(right_name_with_namespace)

                if len(missing_rights) > 0:
                    LOGGER.debug(f"Authorization failed for user "
                                 f"'{class_instance.context.user.name}'. "
                                 f"Missing required rights: "
                                 f"{missing_rights}")
                    raise Exception(f'Access forbidden. Missing required '
                                    f'rights: {missing_rights}')

            return func(*args, **kwargs)
Example #10
0
 def setup_exchange(self, exchange_name):
     LOGGER.debug(f"Declaring exchange {exchange_name}")
     self._channel.exchange_declare(exchange_name,
                                    exchange_type=EXCHANGE_TYPE,
                                    passive=True,
                                    durable=True,
                                    auto_delete=False,
                                    callback=self.on_exchange_declareok)
 def send_too_many_requests_response(self, properties, body):
     if properties.reply_to is not None:
         body_json = utils.str_to_json(body, self.fsencoding)[0]
         reply_msg = self.form_response_json(
             request_id=body_json['id'],
             status_code=requests.codes.too_many_requests,
             reply_body_str=constants.TOO_MANY_REQUESTS_BODY)
         LOGGER.debug(f"reply: ({ constants.TOO_MANY_REQUESTS_BODY})")
         self.send_response(reply_msg, properties)
 def _does_cluster_belong_to_vdc(self, cluster_info, vdc_name):
     # Returns True if the cluster backed by given vdc
     # Else False (this also includes missing compute profile name)
     compute_profile_name = cluster_info.get('compute_profile_name')
     if compute_profile_name is None:
         SERVER_LOGGER.debug("compute-profile-name of"
                             f" {cluster_info.get('name')} is not found")
         return False
     return vdc_name == self._extract_vdc_name_from_pks_compute_profile_name(compute_profile_name) # noqa: E501
Example #13
0
 def close_channel(self):
     LOGGER.debug(f"Closing channel ({self._channel})")
     if self._channel.is_closed or self._channel.is_closing:
         LOGGER.warning(f"Channel ({self._channel}) is already closed")
         return
     try:
         self._channel.close()
     except pika.exceptions.ConnectionWrongStateError as cwse:
         LOGGER.warn(
             f"Trying to close channel with unexpected state: [{cwse}]")
Example #14
0
 def send_too_many_requests_response(self, msg):
     payload_json = utils.str_to_json(msg.payload, self.fsencoding)
     request_id = payload_json["headers"]["requestId"]
     LOGGER.debug(f"Replying with 'too many requests response' for "
                  f"request_id: {request_id} and msg id: {msg.mid}")
     response_json = self._mqtt_publisher.construct_response_json(
         request_id=request_id,
         status_code=requests.codes.too_many_requests,
         reply_body_str=constants.TOO_MANY_REQUESTS_BODY)
     self._mqtt_publisher.send_response(response_json)
Example #15
0
 def send_response(self, response_json):
     self._publish_lock.acquire()
     try:
         pub_ret = self.mqtt_client.publish(topic=self.respond_topic,
                                            payload=json.dumps(
                                                response_json),
                                            qos=constants.QOS_LEVEL,
                                            retain=False)
     finally:
         self._publish_lock.release()
     LOGGER.debug(f"publish return (rc, msg_id): {pub_ret}")
Example #16
0
 def process_behavior_message(self, msg_json):
     status, payload = behavior_dispatcher.process_behavior_request(
         msg_json)  # noqa: E501
     task_id: str = msg_json['headers']['taskId']
     entity_id: str = msg_json['headers']['entityId']
     response_json = self.form_behavior_response_json(task_id=task_id,
                                                      entity_id=entity_id,
                                                      payload=payload,
                                                      status=status)
     self.send_response(response_json)
     LOGGER.debug(f'MQTT response: {response_json}')
Example #17
0
    def _does_cluster_belong_to_org(self, cluster_info, org_name):
        # Returns True if the cluster belongs to the given org
        # Else False (this also includes missing compute profile name)

        compute_profile_name = cluster_info.get('compute_profile_name')
        if compute_profile_name is None:
            SERVER_LOGGER.debug("compute-profile-name of"
                                f" {cluster_info.get('name')} is not found")
            return False
        vdc_id = self._extract_vdc_id_from_pks_compute_profile_name(
            compute_profile_name)
        return org_name == get_org_name_from_ovdc_id(
            self.context.sysadmin_client, vdc_id)
Example #18
0
    def resize_cluster(self, **kwargs):
        """Resize the cluster of a given name to given number of worker nodes.

        System administrator can resize the given cluster regardless of
        who is the owner of the cluster. Other users can only resize
        the cluster they own.


        :return: response status

        :rtype: dict

        """
        data = kwargs[KwargKey.DATA]
        cluster_name = data[RequestKey.CLUSTER_NAME]
        num_workers = data[RequestKey.NUM_WORKERS]

        qualified_cluster_name = self._append_user_id(cluster_name)
        if (self.context.client.is_sysadmin()
                or self.context.user.has_org_admin_rights):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']

        self._check_cluster_isolation(cluster_name, qualified_cluster_name)

        result = {}
        cluster_api = ClusterApi(api_client=self.pks_client)
        self.pks_wire_logger.debug(f"Sending request to"
                                   f" PKS:{self.pks_host_uri} to resize"
                                   f" the cluster with name:"
                                   f"{qualified_cluster_name} to"
                                   f" {num_workers} worker nodes")
        resize_params = \
            UpdateClusterParameters(kubernetes_worker_instances=num_workers)
        try:
            cluster_api.update_cluster(qualified_cluster_name,
                                       body=resize_params)
        except ApiException as err:
            SERVER_LOGGER.debug(f"Resizing cluster {qualified_cluster_name}"
                                f" failed with error:\n {err}")
            raise PksServerError(err.status, err.body)
        self.pks_wire_logger.debug(f"PKS: {self.pks_host_uri} accepted the"
                                   f" request to resize the cluster: "
                                   f" {qualified_cluster_name}")

        result['name'] = qualified_cluster_name
        result['task_status'] = 'in progress'
        self._restore_original_name(result)
        if not self.context.client.is_sysadmin():
            self._filter_sensitive_pks_properties(result)
        return result
    def _isolate_cluster(self, cluster_name, qualified_cluster_name,
                         cluster_id):
        if not cluster_id:
            raise ValueError(f"Invalid cluster_id for cluster "
                             f"'{cluster_name}'")

        SERVER_LOGGER.debug(f"Isolating network of cluster {qualified_cluster_name}.") # noqa: E501
        try:
            cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client)
            cluster_network_isolater.isolate_cluster(qualified_cluster_name,
                                                     cluster_id)
        except Exception as err:
            raise ClusterNetworkIsolationError(
                f"Cluster : '{cluster_name}' is in an unusable state. Failed "
                "to isolate cluster network") from err
Example #20
0
    def process_behavior_message(self, msg_json):
        task_id: str = msg_json['headers']['taskId']
        entity_id: str = msg_json['headers']['entityId']
        behavior_id: str = msg_json['headers']['behaviorId']
        payload: dict = json.loads(msg_json['payload'])
        request_id: str = payload['_metadata']['requestId']
        LOGGER.debug(f"Received behavior invocation: {behavior_id} on "
                     f"entityId:{entity_id} with requestId: {request_id}")
        payload = behavior_dispatcher.process_behavior_request(
            msg_json, self._mqtt_publisher)

        response_json = self._mqtt_publisher.construct_behavior_response_json(
            task_id=task_id, entity_id=entity_id, payload=payload)
        self._mqtt_publisher.send_response(response_json)
        LOGGER.debug(f'MQTT response: {response_json}')
Example #21
0
    def process_mqtt_message(self, msg):
        msg_json, reply_body, status_code, req_id = utils.get_response_fields(
            request_msg=msg, fsencoding=self.fsencoding, is_mqtt=True)

        LOGGER.debug(f"Received message with request_id: {req_id}, mid: "
                     f"{msg.mid}, and msg json: {msg_json}")

        task_path = utils.get_task_path_from_reply_body(reply_body)
        reply_body_str = json.dumps(reply_body)
        response_json = self.form_response_json(request_id=req_id,
                                                status_code=status_code,
                                                reply_body_str=reply_body_str,
                                                task_path=task_path)

        self.send_response(response_json)
        LOGGER.debug(f'MQTT response: {response_json}')
    def _create_cluster(self, *args,
                        cluster_name, num_workers, pks_plan_name,
                        pks_ext_host):
        """Create cluster in PKS environment.

        Creates Distributed Firewall rules in NSX-T to isolate the cluster
        network from other clusters.

        :param str cluster_name: Name of the cluster
        :param str plan: PKS plan. It should be one of the three plans
        that PKS supports.
        :param str external_host_name: User-preferred external hostname
         of the K8 cluster

        :return: Details of the cluster

        :rtype: dict
        """
        cluster_api = ClusterApi(api_client=self.pks_client)
        cluster_params = \
            ClusterParameters(kubernetes_master_host=pks_ext_host,
                              kubernetes_worker_instances=num_workers)
        cluster_request = \
            ClusterRequest(name=cluster_name,
                           plan_name=pks_plan_name,
                           parameters=cluster_params,
                           compute_profile_name=self.compute_profile)
        try:
            self.pks_wire_logger.debug(
                f"Sending request to PKS: {self.pks_host_uri} to create " # noqa: E501
                f"cluster of name: {cluster_name}")
            cluster = cluster_api.add_cluster(cluster_request)
            self.pks_wire_logger.debug(
                f"PKS: {self.pks_host_uri} accepted the request to create"
                f" cluster: {cluster_name}")
        except ApiException as err:
            SERVER_LOGGER.debug(f"Creating cluster {cluster_name}"
                                f" in PKS failed with error:\n {err}")
            raise PksServerError(err.status, err.body)

        cluster_info = cluster.to_dict()
        # Flattening the dictionary
        cluster_params_dict = cluster_info.pop('parameters')
        cluster_info.update(cluster_params_dict)

        return cluster_info
Example #23
0
    def _get_cluster_info(self, data):
        """Get the details of a cluster with a given name in PKS environment.

        System administrator gets the given cluster information regardless of
        who is the owner of the cluster. Other users get info only on
        the cluster they own.

        :param **data dict
            :str cluster_name: Name of the cluster
        :return: Details of the cluster.

        :rtype: dict
        """
        cluster_name = data[RequestKey.CLUSTER_NAME]
        # The structure of info returned by list_cluster and get_cluster is
        # identical, hence using list_cluster and filtering by name in memory
        # to retrieve info of the requested cluster.
        cluster_info_list = self._list_clusters(data)
        if (self.context.client.is_sysadmin()
                or self.context.user.has_org_admin_rights
                or data.get('is_org_admin_search')):
            filtered_cluster_info_list = []
            for cluster_info in cluster_info_list:
                if cluster_info['name'] == cluster_name:
                    filtered_cluster_info_list.append(cluster_info)
            SERVER_LOGGER.debug(
                f"Filtered list of clusters:{filtered_cluster_info_list}")
            if len(filtered_cluster_info_list) > 1:
                raise PksDuplicateClusterError(
                    requests.codes.bad_request,
                    f"Multiple clusters with name '{cluster_name}' exists.")
            if len(filtered_cluster_info_list) == 0:
                raise PksServerError(requests.codes.not_found,
                                     f"cluster {cluster_name} not found.")
            return filtered_cluster_info_list[0]

        qualified_cluster_name = self._append_user_id(cluster_name)
        for cluster_info in cluster_info_list:
            if cluster_info['pks_cluster_name'] == qualified_cluster_name:
                return cluster_info

        raise PksServerError(requests.codes.not_found,
                             f"cluster {cluster_name} not found.")
    def list_plans(self):
        """Get list of available PKS plans in the system.

        :return: a list of pks-plans if available.

        :rtype: list
        """
        plan_api = PlansApi(api_client=self.pks_client)
        self.pks_wire_logger.debug(f"Sending request to PKS: {self.pks_host_uri} " # noqa: E501
                                   f"to list all available plans")
        try:
            pks_plans = plan_api.list_plans()
        except ApiException as err:
            SERVER_LOGGER.debug(f"Listing PKS plans failed with error:\n {err}") # noqa: E501
            raise PksServerError(err.status, err.body)

        result = []
        for pks_plan in pks_plans:
            result.append(pks_plan.to_dict())
        return result
Example #25
0
    def process_amqp_message(self, properties, body, basic_deliver):
        msg_json, reply_body, status_code, req_id = utils.get_response_fields(
            request_msg=body, fsencoding=self.fsencoding, is_mqtt=False)

        if properties.reply_to is not None:
            reply_body_str = json.dumps(reply_body)
            reply_msg = self.form_response_json(request_id=req_id,
                                                status_code=status_code,
                                                reply_body_str=reply_body_str)

            self.send_response(reply_msg, properties)
            LOGGER.debug(f"Sucessfully sent reply: {reply_msg} to AMQP.")

        global REQUESTS_BEING_PROCESSED, LRU_LOCK
        LRU_LOCK.acquire()
        try:
            if req_id in REQUESTS_BEING_PROCESSED:
                del REQUESTS_BEING_PROCESSED[req_id]
        finally:
            LRU_LOCK.release()
def update_ovdc_k8s_provider_metadata(sysadmin_client: vcd_client.Client,
                                      ovdc_id,
                                      k8s_provider_data=None,
                                      k8s_provider=None):
    """Set the k8s provider metadata for given ovdc.

    :param pyvcloud.vcd.client.Client sysadmin_client:
    :param str ovdc_id:
    :param dict k8s_provider_data:  k8s provider context details
    :param K8sProvider k8s_provider:
    :return:
    """
    vcd_utils.raise_error_if_user_not_from_system_org(sysadmin_client)

    ovdc = vcd_utils.get_vdc(sysadmin_client, vdc_id=ovdc_id)
    ovdc_name = ovdc.get_resource().get('name')
    metadata = {K8S_PROVIDER_KEY: k8s_provider or K8sProvider.NONE}

    if k8s_provider != K8sProvider.PKS:
        LOGGER.debug(f"Remove existing metadata for ovdc:{ovdc_name}")
        _remove_metadata_from_ovdc(ovdc, PksCache.get_pks_keys())
        LOGGER.debug(f"Updated metadata for {k8s_provider}:" f"{metadata}")
    else:
        k8s_provider_data.pop('username')
        k8s_provider_data.pop('secret')
        k8s_provider_data.pop('nsxt')
        metadata.update(k8s_provider_data)

    # set ovdc metadata into Vcd
    LOGGER.debug(f"On ovdc:{ovdc_name}, setting metadata:{metadata}")
    return ovdc.set_multiple_metadata(metadata,
                                      vcd_client.MetadataDomain.SYSTEM,
                                      vcd_client.MetadataVisibility.PRIVATE)
def construct_k8s_metadata_from_pks_cache(sysadmin_client: vcd_client.Client,
                                          ovdc_id, org_name, pks_plans,
                                          pks_cluster_domain, k8s_provider):
    vcd_utils.raise_error_if_user_not_from_system_org(sysadmin_client)

    ctr_prov_context = {
        K8S_PROVIDER_KEY: k8s_provider,
    }
    if k8s_provider == K8sProvider.PKS:
        if not server_utils.is_pks_enabled():
            raise e.CseServerError('CSE is not configured to work with PKS.')

        ovdc = vcd_utils.get_vdc(client=sysadmin_client,
                                 vdc_id=ovdc_id,
                                 is_admin_operation=True)
        pks_cache = server_utils.get_pks_cache()
        pvdc_id = vcd_utils.get_pvdc_id(ovdc)
        pvdc_info = pks_cache.get_pvdc_info(pvdc_id)
        if not pvdc_info:
            LOGGER.debug(f"pvdc '{pvdc_id}' is not backed "
                         f"by PKS-managed-vSphere resources")
            raise e.CseServerError(f"VDC '{ovdc.get_resource().get('name')}'"
                                   " is not eligible to provide resources"
                                   " for PKS clusters.")
        pks_account_info = pks_cache.get_pks_account_info(
            org_name, pvdc_info.vc)
        nsxt_info = pks_cache.get_nsxt_info(pvdc_info.vc)

        pks_compute_profile_name = _construct_pks_compute_profile_name(
            sysadmin_client, ovdc_id)
        ctr_prov_context = construct_pks_context(
            pks_account_info=pks_account_info,
            pvdc_info=pvdc_info,
            nsxt_info=nsxt_info,
            pks_compute_profile_name=pks_compute_profile_name,
            pks_plans=pks_plans,
            pks_cluster_domain=pks_cluster_domain,
            credentials_required=True)
    return ctr_prov_context
Example #28
0
    def process_mqtt_message(self, msg):
        msg_json = json.loads(msg.payload.decode(self.fsencoding))
        if msg_json.get('type', None) == 'BEHAVIOR_INVOCATION':   # noqa: E501
            self.process_behavior_message(msg_json=msg_json)
        else:
            msg_json, reply_body, status_code, req_id = utils.get_response_fields(  # noqa: E501
                request_msg=msg,
                fsencoding=self.fsencoding,
                is_mqtt=True)

            LOGGER.debug(f"Received message with request_id: {req_id}, mid: "
                         f"{msg.mid}, and msg json: {msg_json}")

            task_path = utils.get_task_path_from_reply_body(reply_body)
            reply_body_str = json.dumps(reply_body)
            response_json = self._mqtt_publisher.construct_response_json(
                request_id=req_id,
                status_code=status_code,
                reply_body_str=reply_body_str,
                task_path=task_path)

            self._mqtt_publisher.send_response(response_json)
            LOGGER.debug(f'MQTT response: {response_json}')
Example #29
0
def _get_cluster_and_broker(request_data, op_ctx, **kwargs):
    cluster_name = request_data[RequestKey.CLUSTER_NAME]

    pks_ctx_list = create_pks_context_for_all_accounts_in_org(op_ctx)
    for pks_ctx in pks_ctx_list:
        debug_msg = f"Get cluster info for cluster '{cluster_name}' " \
            f"failed on host '{pks_ctx['host']}' with error: "
        pks_broker = PksBroker(pks_ctx, op_ctx)
        try:
            return pks_broker.get_cluster_info(
                data=request_data, **kwargs), pks_broker  # noqa: E501
        except (PksClusterNotFoundError, PksServerError) as err:
            # continue searching using other PksBrokers
            LOGGER.debug(f"{debug_msg}{err}")
        except PksDuplicateClusterError as err:
            # fail because multiple clusters with same name exist
            LOGGER.debug(f"{debug_msg}{err}")
            raise
        except Exception as err:
            LOGGER.error(f"Unknown error: {err}", exc_info=True)
            raise

    # raised if cluster was not found in PksBrokers
    raise ClusterNotFoundError(f"Cluster '{cluster_name}' not found.")
    def delete_cluster(self, **kwargs):
        """Delete the cluster with a given name in PKS environment.

        System administrator can delete the given cluster regardless of
        who is the owner of the cluster. Other users can only delete
        the cluster they own.
        :param **data
            :param str cluster_name: Name of the cluster
        """
        data = kwargs[KwargKey.DATA]
        cluster_name = data[RequestKey.CLUSTER_NAME]

        qualified_cluster_name = self._append_user_id(cluster_name)
        if (self.context.client.is_sysadmin()
                or self.context.user.has_org_admin_rights):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']

        result = {}
        cluster_api = ClusterApi(api_client=self.pks_client)
        self.pks_wire_logger.debug(f"Sending request to"
                                   f" PKS: {self.pks_host_uri} to delete"
                                   f" the cluster with name:"
                                   f" {qualified_cluster_name}")
        try:
            cluster_api.delete_cluster(cluster_name=qualified_cluster_name)
            self.pks_wire_logger.debug(
                f"PKS: {self.pks_host_uri} accepted the request to delete"
                f" the cluster: {qualified_cluster_name}")
        except ApiException as err:
            SERVER_LOGGER.debug(f"Deleting cluster {qualified_cluster_name} "
                                f"failed with error:\n {err}")
            raise PksServerError(err.status, err.body)
        result['name'] = qualified_cluster_name
        result['task_status'] = 'in progress'

        # remove cluster network isolation
        SERVER_LOGGER.debug("Removing network isolation of cluster "
                            f"{qualified_cluster_name}.")
        try:
            cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client)
            cluster_network_isolater.remove_cluster_isolation(
                qualified_cluster_name)
        except Exception as err:
            # NSX-T oprations are idempotent so they should not cause erros
            # if say NSGroup is missing. But for any other exception, simply
            # catch them and ignore.
            SERVER_LOGGER.debug(f"Error {err} occured while deleting cluster "
                                "isolation rules for cluster "
                                f"{qualified_cluster_name}")

        return result