示例#1
0
 def _load_placement_policy_details(
         self, msg_update_callback=utils.NullPrinter()):
     msg = "Loading kubernetes runtime placement policies."
     logger.SERVER_LOGGER.info(msg)
     msg_update_callback.general(msg)
     try:
         sysadmin_client = vcd_utils.get_sys_admin_client(api_version=None)
         if float(sysadmin_client.get_api_version()) < compute_policy_manager.GLOBAL_PVDC_COMPUTE_POLICY_MIN_VERSION:  # noqa: E501
             msg = "Placement policies for kubernetes runtimes not " \
                   " supported in api version " \
                   f"{sysadmin_client.get_api_version()}"  # noqa: E501
             logger.SERVER_LOGGER.debug(msg)
             msg_update_callback.info(msg)
             return
         placement_policy_name_to_href = {}
         cpm = compute_policy_manager.ComputePolicyManager(sysadmin_client,
                                                           log_wire=self.config['service'].get('log_wire'))  # noqa: E501
         for runtime_policy in shared_constants.CLUSTER_RUNTIME_PLACEMENT_POLICIES:  # noqa: E501
             k8_runtime = shared_constants.RUNTIME_INTERNAL_NAME_TO_DISPLAY_NAME_MAP[runtime_policy]  # noqa: E501
             try:
                 placement_policy_name_to_href[k8_runtime] = \
                     compute_policy_manager.get_cse_vdc_compute_policy(
                         cpm,
                         runtime_policy,
                         is_placement_policy=True)['href']
             except EntityNotFoundException:
                 pass
         self.config['placement_policy_hrefs'] = placement_policy_name_to_href  # noqa: E501
     except Exception as e:
         msg = f"Failed to load placement policies to server runtime configuration: {str(e)}"  # noqa: E501
         msg_update_callback.error(msg)
         logger.SERVER_LOGGER.error(msg)
         raise
def get_all_ovdc_with_metadata():
    client = None
    try:
        client = vcd_utils.get_sys_admin_client(api_version=None)
        q = client.get_typed_query(
            vcd_client.ResourceType.ADMIN_ORG_VDC.value,
            query_result_format=vcd_client.QueryResultFormat.RECORDS,
            fields='metadata@SYSTEM:k8s_provider')
        ovdc_records = q.execute()
        return ovdc_records
    finally:
        if client is not None:
            client.logout()
    def _update_sysadmin_user_context_map(self, api_version: Optional[str]):
        _sysadmin_client = vcd_utils.get_sys_admin_client(
            api_version=api_version)

        log_wire = server_utils.get_server_runtime_config() \
            .get('service', {}).get('log_wire', False)
        logger_wire = logger.NULL_LOGGER
        if log_wire:
            logger_wire = logger.SERVER_CLOUDAPI_WIRE_LOGGER
        _sysadmin_cloudapi_client = \
            vcd_utils.get_cloudapi_client_from_vcd_client(
                _sysadmin_client,
                logger.SERVER_LOGGER,
                logger_wire)

        _sysadmin_user_context = user_context.UserContext(
            client=_sysadmin_client,
            cloud_api_client=_sysadmin_cloudapi_client)
        self._sysadmin_user_context_map[api_version] = _sysadmin_user_context
示例#4
0
 def sysadmin_client(self):
     if self._sysadmin_client is None:
         self._sysadmin_client = vcd_utils.get_sys_admin_client()
     return self._sysadmin_client
示例#5
0
    def _process_template_compute_policy_compliance(
        self, msg_update_callback=utils.NullPrinter()):  # noqa: E501
        msg = "Processing compute policy for k8s templates."
        logger.SERVER_LOGGER.info(msg)
        msg_update_callback.general_no_color(msg)

        org_name = self.config['broker']['org']
        catalog_name = self.config['broker']['catalog']
        sysadmin_client = None
        try:
            sysadmin_client = vcd_utils.get_sys_admin_client(api_version=None)
            cpm = compute_policy_manager.ComputePolicyManager(
                sysadmin_client,
                log_wire=self.config['service'].get('log_wire'))  # noqa: E501

            for template in self.config['broker']['templates']:
                policy_name = template[server_constants.LegacyLocalTemplateKey.
                                       COMPUTE_POLICY]  # noqa: E501
                catalog_item_name = template[
                    server_constants.LegacyLocalTemplateKey.
                    CATALOG_ITEM_NAME]  # noqa: E501
                # if policy name is not empty, stamp it on the template
                if policy_name:
                    try:
                        policy = \
                            compute_policy_manager.get_cse_vdc_compute_policy(
                                cpm, policy_name)  # noqa: E501
                    except EntityNotFoundException:
                        # create the policy if it does not exist
                        msg = f"Creating missing compute policy " \
                              f"'{policy_name}'."
                        msg_update_callback.info(msg)
                        logger.SERVER_LOGGER.debug(msg)
                        policy = \
                            compute_policy_manager.add_cse_vdc_compute_policy(
                                cpm,
                                policy_name)

                    msg = f"Assigning compute policy '{policy_name}' to " \
                          f"template '{catalog_item_name}'."
                    msg_update_callback.general(msg)
                    logger.SERVER_LOGGER.debug(msg)
                    cpm.assign_vdc_sizing_policy_to_vapp_template_vms(
                        compute_policy_href=policy['href'],
                        org_name=org_name,
                        catalog_name=catalog_name,
                        catalog_item_name=catalog_item_name)
                else:
                    # empty policy name means we should remove policy from
                    # template
                    msg = f"Removing compute policy from template " \
                          f"'{catalog_item_name}'."
                    msg_update_callback.general(msg)
                    logger.SERVER_LOGGER.debug(msg)

                    cpm.remove_all_vdc_compute_policies_from_vapp_template_vms(
                        org_name=org_name,
                        catalog_name=catalog_name,
                        catalog_item_name=catalog_item_name)
        except OperationNotSupportedException:
            msg = "Compute policy not supported by vCD. Skipping " \
                  "assigning/removing it to/from templates."
            msg_update_callback.info(msg)
            logger.SERVER_LOGGER.debug(msg)
        finally:
            if sysadmin_client is not None:
                sysadmin_client.logout()
示例#6
0
    def _load_def_schema(self, msg_update_callback=utils.NullPrinter()):
        """Load cluster interface and cluster entity type to global context.

        If defined entity framework is supported by vCD api version, load
        defined entity interface and defined entity type registered during
        server install

        :param utils.NullMessagePrinter msg_update_callback:
        """
        sysadmin_client = None
        try:
            sysadmin_client = vcd_utils.get_sys_admin_client(api_version=None)
            logger_wire = logger.NULL_LOGGER
            if utils.str_to_bool(
                    utils.str_to_bool(self.config['service'].get(
                        'log_wire', False))):  # noqa: E501
                logger_wire = logger.SERVER_CLOUDAPI_WIRE_LOGGER

            cloudapi_client = \
                vcd_utils.get_cloudapi_client_from_vcd_client(sysadmin_client,
                                                              logger.SERVER_LOGGER,  # noqa: E501
                                                              logger_wire)
            raise_error_if_def_not_supported(cloudapi_client)

            server_rde_version = server_utils.get_rde_version_in_use()
            msg_update_callback.general(
                f"Using RDE version: {server_rde_version}")  # noqa: E501

            schema_svc = def_schema_svc.DefSchemaService(cloudapi_client)
            def_metadata_dict: dict = def_utils.get_rde_metadata(
                server_rde_version)  # noqa: E501
            entity_type: common_models.DefEntityType = \
                def_metadata_dict[def_constants.RDEMetadataKey.ENTITY_TYPE]  # noqa: E501
            interfaces: List[common_models.DefInterface] = \
                def_metadata_dict[def_constants.RDEMetadataKey.INTERFACES]  # noqa: E501

            for interface in interfaces:
                # TODO change _kubernetesInterface to an array once additional
                # interface for CSE is added.
                self._kubernetesInterface = \
                    schema_svc.get_interface(interface.get_id())

            self._nativeEntityType = \
                schema_svc.get_entity_type(entity_type.get_id())

            msg = f"Successfully loaded defined entity schema " \
                  f"{entity_type.get_id()} to global context"
            msg_update_callback.general(msg)
            logger.SERVER_LOGGER.debug(msg)
        except cse_exception.DefNotSupportedException:
            msg = "Skipping initialization of defined entity type" \
                  " and defined entity interface"
            msg_update_callback.info(msg)
            logger.SERVER_LOGGER.debug(msg)
        except cse_exception.DefSchemaServiceError as e:
            msg = f"Error while loading defined entity schema: {e.error_message}"  # noqa: E501
            msg_update_callback.error(msg)
            logger.SERVER_LOGGER.debug(msg)
            raise
        except Exception as e:
            msg = f"Failed to load defined entity schema to global context: {str(e)}"  # noqa: E501
            msg_update_callback.error(msg)
            logger.SERVER_LOGGER.error(msg)
            raise
        finally:
            if sysadmin_client:
                sysadmin_client.logout()
示例#7
0
    def run(self, msg_update_callback=utils.NullPrinter()):
        sysadmin_client = None
        try:
            sysadmin_client = vcd_utils.get_sys_admin_client(api_version=None)
            verify_version_compatibility(
                sysadmin_client,
                should_cse_run_in_legacy_mode=self.config['service']
                ['legacy_mode'],  # noqa: E501
                is_mqtt_extension=server_utils.should_use_mqtt_protocol(
                    self.config))  # noqa: E501
        except Exception as err:
            logger.SERVER_LOGGER.info(err)
            raise
        finally:
            if sysadmin_client:
                sysadmin_client.logout()

        if server_utils.should_use_mqtt_protocol(self.config):
            # Store/setup MQTT extension, api filter, and token info
            try:
                sysadmin_client = \
                    vcd_utils.get_sys_admin_client(api_version=None)
                mqtt_ext_manager = MQTTExtensionManager(sysadmin_client)
                ext_info = mqtt_ext_manager.get_extension_info(
                    ext_name=server_constants.CSE_SERVICE_NAME,
                    ext_version=server_constants.MQTT_EXTENSION_VERSION,
                    ext_vendor=server_constants.MQTT_EXTENSION_VENDOR)
                ext_urn_id = ext_info[server_constants.MQTTExtKey.EXT_URN_ID]
                ext_uuid = mqtt_ext_manager.get_extension_uuid(ext_urn_id)
                api_filters_status = mqtt_ext_manager.check_api_filters_setup(
                    ext_uuid, configure_cse.API_FILTER_PATTERNS)
                if not api_filters_status:
                    msg = 'MQTT Api filter is not set up'
                    logger.SERVER_LOGGER.error(msg)
                    raise cse_exception.MQTTExtensionError(msg)

                token_info = mqtt_ext_manager.setup_extension_token(
                    token_name=server_constants.MQTT_TOKEN_NAME,
                    ext_name=server_constants.CSE_SERVICE_NAME,
                    ext_version=server_constants.MQTT_EXTENSION_VERSION,
                    ext_vendor=server_constants.MQTT_EXTENSION_VENDOR,
                    ext_urn_id=ext_urn_id)

                self.config['mqtt'].update(ext_info)
                self.config['mqtt'].update(token_info)
                self.config['mqtt'][server_constants.MQTTExtKey.EXT_UUID] = \
                    ext_uuid
            except Exception as err:
                msg = f'MQTT extension setup error: {err}'
                logger.SERVER_LOGGER.error(msg)
                raise err
            finally:
                if sysadmin_client:
                    sysadmin_client.logout()

        populate_vsphere_list(self.config['vcs'])

        # Load def entity-type and interface
        self._load_def_schema(msg_update_callback=msg_update_callback)

        # Read k8s catalog definition from catalog item metadata and append
        # the same to to server run-time config
        self._load_template_definition_from_catalog(
            msg_update_callback=msg_update_callback)

        self._load_placement_policy_details(
            msg_update_callback=msg_update_callback)

        if self.config['service']['legacy_mode']:
            # Read templates rules from config and update template definition
            # in server run-time config
            self._process_template_rules(
                msg_update_callback=msg_update_callback)

            # Make sure that all vms in templates are compliant with the
            # compute policy specified in template definition (can be affected
            # by rules).
            self._process_template_compute_policy_compliance(
                msg_update_callback=msg_update_callback)
        else:
            msg = "Template rules are not supported by CSE for vCD api " \
                  "version 35.0 or above. Skipping template rule processing."
            msg_update_callback.info(msg)
            logger.SERVER_LOGGER.debug(msg)

        if self.should_check_config:
            configure_cse.check_cse_installation(
                self.config, msg_update_callback=msg_update_callback)

        if self.config.get('pks_config'):
            pks_config = self.config.get('pks_config')
            self.pks_cache = PksCache(
                pks_servers=pks_config.get('pks_api_servers', []),
                pks_accounts=pks_config.get('pks_accounts', []),
                pvdcs=pks_config.get('pvdcs', []),
                orgs=pks_config.get('orgs', []),
                nsxt_servers=pks_config.get('nsxt_servers', []))

        num_processors = self.config['service']['processors']
        name = server_constants.MESSAGE_CONSUMER_THREAD
        try:
            self.consumer = MessageConsumer(self.config, num_processors)
            consumer_thread = Thread(name=name,
                                     target=consumer_thread_run,
                                     args=(self.consumer, ))
            consumer_thread.daemon = True
            consumer_thread.start()
            self.consumer_thread = consumer_thread
            msg = f"Started thread '{name}' ({consumer_thread.ident})"
            msg_update_callback.general(msg)
            logger.SERVER_LOGGER.info(msg)
        except KeyboardInterrupt:
            if self.consumer:
                self.consumer.stop()
            interrupt_msg = f"\nKeyboard interrupt when starting thread " \
                            f"'{name}'"
            logger.SERVER_LOGGER.debug(interrupt_msg)
            raise Exception(interrupt_msg)
        except Exception:
            if self.consumer:
                self.consumer.stop()
            logger.SERVER_LOGGER.error(traceback.format_exc())

        # Updating state to Running before starting watchdog because watchdog
        # exits when server is not Running
        self._state = ServerState.RUNNING

        # Start consumer watchdog
        name = server_constants.WATCHDOG_THREAD
        consumer_watchdog = Thread(name=name,
                                   target=watchdog_thread_run,
                                   args=(self, num_processors))
        consumer_watchdog.daemon = True
        consumer_watchdog.start()
        self._consumer_watchdog = consumer_watchdog
        msg = f"Started thread '{name}' ({consumer_watchdog.ident})"
        msg_update_callback.general(msg)
        logger.SERVER_LOGGER.info(msg)

        message = f"Container Service Extension for vCloud Director" \
                  f"\nServer running using config file: {self.config_file}" \
                  f"\nLog files: {logger.SERVER_INFO_LOG_FILEPATH}, " \
                  f"{logger.SERVER_DEBUG_LOG_FILEPATH}" \
                  f"\nwaiting for requests (ctrl+c to close)"

        signal.signal(signal.SIGINT, signal_handler)
        msg_update_callback.general_no_color(message)
        logger.SERVER_LOGGER.info(message)

        # Record telemetry on user action and details of operation.
        cse_params = {
            PayloadKey.WAS_DECRYPTION_SKIPPED:
            bool(self.skip_config_decryption),  # noqa: E501
            PayloadKey.WAS_PKS_CONFIG_FILE_PROVIDED:
            bool(self.pks_config_file),  # noqa: E501
            PayloadKey.WAS_INSTALLATION_CHECK_SKIPPED:
            bool(self.should_check_config)  # noqa: E501
        }
        record_user_action_details(cse_operation=CseOperation.SERVICE_RUN,
                                   cse_params=cse_params)
        record_user_action(cse_operation=CseOperation.SERVICE_RUN)

        while True:
            try:
                time.sleep(1)
                if self._state == ServerState.STOPPING and \
                        self.active_requests_count() == 0:
                    break
            except KeyboardInterrupt:
                break
            except Exception:
                msg_update_callback.general_no_color(traceback.format_exc())
                logger.SERVER_LOGGER.error(traceback.format_exc())
                sys.exit(1)

        logger.SERVER_LOGGER.info("Stop detected")
        logger.SERVER_LOGGER.info("Closing connections...")
        self._state = ServerState.STOPPING
        try:
            self.consumer.stop()
        except Exception:
            logger.SERVER_LOGGER.error(traceback.format_exc())

        self._state = ServerState.STOPPED
        logger.SERVER_LOGGER.info("Done")