def is_cse_registered_as_mqtt_ext(logger=NULL_LOGGER): try: mqtt_ext_manager = MQTTExtensionManager(CLIENT, debug_logger=logger) return mqtt_ext_manager.check_extension_exists( server_constants.MQTT_EXTENSION_URN) except MissingRecordException as e: logger.error(f"Error occurred when checking if CSE is registered: {e}") return False
def get_telemetry_instance_id(vcd_host: str, vcd_username: str, vcd_password: str, verify_ssl: bool, is_mqtt_exchange: bool, logger_debug=NULL_LOGGER, msg_update_callback=NullPrinter()): """Get CSE AMQP or MQTT extension id which is used as instance id. Any exception is logged as error. No exception is leaked out of this method and does not affect the server startup. :param str vcd_host: :param str vcd_username: :param str vcd_password: :param bool verify_ssl: :param bool is_mqtt_exchange: :param logging.logger logger_debug: logger instance to log any error in retrieving CSE extension id. :param utils.ConsoleMessagePrinter msg_update_callback: Callback object. :return instance id to use for sending data to Vmware telemetry server :rtype str (unless no instance id found) """ client = None try: client = Client(vcd_host, verify_ssl_certs=verify_ssl) client.set_credentials( BasicLoginCredentials(vcd_username, SYSTEM_ORG_NAME, vcd_password)) if is_mqtt_exchange: # Get MQTT extension uuid mqtt_ext_manager = MQTTExtensionManager(client) ext_info = mqtt_ext_manager.get_extension_info( ext_name=CSE_SERVICE_NAME, ext_version=MQTT_EXTENSION_VERSION, ext_vendor=MQTT_EXTENSION_VENDOR) if not ext_info: logger_debug.debug("Failed to retrieve telemetry instance id") return None logger_debug.debug("Retrieved telemetry instance id") return mqtt_ext_manager.get_extension_uuid( ext_info[MQTTExtKey.EXT_URN_ID]) else: # Get AMQP extension id ext = APIExtension(client) cse_info = ext.get_extension_info(CSE_SERVICE_NAME, namespace=CSE_SERVICE_NAMESPACE) logger_debug.debug("Retrieved telemetry instance id") return cse_info.get('id') except Exception as err: msg = f"Cannot retrieve telemetry instance id:{err}" msg_update_callback.general(msg) logger_debug.error(msg, exc_info=True) finally: if client is not None: client.logout()
def check_cse_registration_as_mqtt_extension(logger=NULL_LOGGER): mqtt_ext_manager = MQTTExtensionManager(CLIENT, debug_logger=logger) is_cse_registered_bool = mqtt_ext_manager.check_extension_exists( server_constants.MQTT_EXTENSION_URN) assert is_cse_registered_bool, \ 'CSE is not registered as an extension when it should be.' if is_cse_registered_bool: assert mqtt_ext_manager.is_extension_enabled( server_constants.MQTT_EXTENSION_URN), "CSE is registered as an " \ "extension but the extension is not enabled"
def unregister_cse_in_mqtt(logger=NULL_LOGGER): logger.debug("Unregistering CSE as MQTT extension") try: mqtt_ext_manager = MQTTExtensionManager(CLIENT) mqtt_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 = mqtt_ext_info[server_constants.MQTTExtKey.EXT_URN_ID] mqtt_ext_manager.delete_extension( 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) logger.debug("Successfully unregistered CSE as MQTT extension") except Exception as e: logger.warning(f"Failed to unregister CSE from MQTT: {e}")
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")