def get_validated_config(config_file_name): """Gets the config file as a dictionary and checks for validity. Ensures that all properties exist and all values are the expected type. Checks that AMQP connection is available, and vCD/VCs are valid. Does not guarantee that CSE has been installed according to this config file. :param str config_file_name: path to config file. :return: CSE config. :rtype: dict :raises KeyError: if config file has missing or extra properties. :raises ValueError: if the value type for a config file property is incorrect. :raises AmqpConnectionError: if AMQP connection failed. """ check_file_permissions(config_file_name) with open(config_file_name) as config_file: config = yaml.safe_load(config_file) click.secho(f"Validating config file '{config_file_name}'", fg='yellow') check_keys_and_value_types(config, SAMPLE_CONFIG, location='config file') validate_amqp_config(config['amqp']) validate_vcd_and_vcs_config(config['vcd'], config['vcs']) validate_broker_config(config['broker']) check_keys_and_value_types(config['service'], SAMPLE_SERVICE_CONFIG['service'], location="config file 'service' section") click.secho(f"Config file '{config_file_name}' is valid", fg='green') return config
def get_validated_config(config_file_name, pks_config_file_name=None, skip_config_decryption=False, decryption_password=None, log_wire_file=None, logger_debug=NULL_LOGGER, msg_update_callback=NullPrinter()): """Get the config file as a dictionary and check for validity. Ensures that all properties exist and all values are the expected type. Checks that AMQP connection is available, and vCD/VCs are valid. Does not guarantee that CSE has been installed according to this config file. :param str config_file_name: path to config file. :param str pks_config_file_name: path to PKS config file. :param bool skip_config_decryption: do not decrypt the config file. :param str decryption_password: password to decrypt the config file. :param str log_wire_file: log_wire_file to use if needed to wire log pyvcloud requests and responses :param logging.Logger logger: logger to log with. :param utils.ConsoleMessagePrinter msg_update_callback: Callback object. :return: CSE config :rtype: dict :raises KeyError: if config file has missing or extra properties. :raises TypeError: if the value type for a config file property is incorrect. :raises container_service_extension.exceptions.AmqpConnectionError: if AMQP connection failed (host, password, port, username, vhost is invalid). :raises pyvcloud.vcd.exceptions.NotAcceptableException: if 'vcd' 'api_version' is unsupported. :raises requests.exceptions.ConnectionError: if 'vcd' 'host' is invalid. :raises pyvcloud.vcd.exceptions.VcdException: if 'vcd' 'username' or 'password' is invalid. :raises pyVmomi.vim.fault.InvalidLogin: if 'vcs' 'username' or 'password' is invalid. """ check_file_permissions(config_file_name, msg_update_callback=msg_update_callback) if skip_config_decryption: with open(config_file_name) as config_file: config = yaml.safe_load(config_file) or {} else: msg_update_callback.info( f"Decrypting '{config_file_name}'") config = yaml.safe_load( get_decrypted_file_contents(config_file_name, decryption_password)) or {} msg_update_callback.info( f"Validating config file '{config_file_name}'") # This allows us to compare top-level config keys and value types sample_config = { **SAMPLE_AMQP_CONFIG, **SAMPLE_VCD_CONFIG, **SAMPLE_VCS_CONFIG, **SAMPLE_SERVICE_CONFIG, **SAMPLE_BROKER_CONFIG } log_wire = str_to_bool(config.get('service', {}).get('log_wire')) nsxt_wire_logger = NULL_LOGGER if not log_wire: log_wire_file = None nsxt_wire_logger = SERVER_NSXT_WIRE_LOGGER check_keys_and_value_types(config, sample_config, location='config file', msg_update_callback=msg_update_callback) _validate_amqp_config(config['amqp'], msg_update_callback) _validate_vcd_and_vcs_config(config['vcd'], config['vcs'], msg_update_callback, log_file=log_wire_file, log_wire=log_wire) _validate_broker_config(config['broker'], msg_update_callback, logger_debug) check_keys_and_value_types(config['service'], SAMPLE_SERVICE_CONFIG['service'], location="config file 'service' section", excluded_keys=['log_wire'], msg_update_callback=msg_update_callback) check_keys_and_value_types(config['service']['telemetry'], SAMPLE_SERVICE_CONFIG['service']['telemetry'], location="config file 'service->telemetry' " "section", msg_update_callback=msg_update_callback) msg_update_callback.general( f"Config file '{config_file_name}' is valid") if pks_config_file_name: check_file_permissions(pks_config_file_name, msg_update_callback=msg_update_callback) if skip_config_decryption: with open(pks_config_file_name) as f: pks_config = yaml.safe_load(f) or {} else: msg_update_callback.info( f"Decrypting '{pks_config_file_name}'") pks_config = yaml.safe_load( get_decrypted_file_contents(pks_config_file_name, decryption_password)) or {} msg_update_callback.info( f"Validating PKS config file '{pks_config_file_name}'") _validate_pks_config_structure(pks_config, msg_update_callback) _validate_pks_config_data_integrity(pks_config, msg_update_callback, logger_debug=logger_debug, logger_wire=nsxt_wire_logger) msg_update_callback.general( f"PKS Config file '{pks_config_file_name}' is valid") config['pks_config'] = pks_config else: config['pks_config'] = None # Store telemetry instance id, url and collector id in config store_telemetry_settings(config) return config
def get_validated_config(config_file_name, msg_update_callback=None): """Get the config file as a dictionary and check for validity. Ensures that all properties exist and all values are the expected type. Checks that AMQP connection is available, and vCD/VCs are valid. Does not guarantee that CSE has been installed according to this config file. :param str config_file_name: path to config file. :param utils.ConsoleMessagePrinter msg_update_callback: Callback object that writes messages onto console. :return: CSE config :rtype: dict :raises KeyError: if config file has missing or extra properties. :raises TypeError: if the value type for a config file property is incorrect. :raises container_service_extension.exceptions.AmqpConnectionError: if AMQP connection failed (host, password, port, username, vhost is invalid). :raises pyvcloud.vcd.exceptions.NotAcceptableException: if 'vcd' 'api_version' is unsupported. :raises requests.exceptions.ConnectionError: if 'vcd' 'host' is invalid. :raises pyvcloud.vcd.exceptions.VcdException: if 'vcd' 'username' or 'password' is invalid. :raises pyVmomi.vim.fault.InvalidLogin: if 'vcs' 'username' or 'password' is invalid. """ check_file_permissions(config_file_name, msg_update_callback=msg_update_callback) with open(config_file_name) as config_file: config = yaml.safe_load(config_file) or {} pks_config_location = config.get('pks_config') if msg_update_callback: msg_update_callback.info( f"Validating config file '{config_file_name}'") # This allows us to compare top-level config keys and value types sample_config = { **SAMPLE_AMQP_CONFIG, **SAMPLE_VCD_CONFIG, **SAMPLE_VCS_CONFIG, **SAMPLE_SERVICE_CONFIG, **SAMPLE_BROKER_CONFIG } check_keys_and_value_types(config, sample_config, location='config file', msg_update_callback=msg_update_callback) _validate_amqp_config(config['amqp'], msg_update_callback) _validate_vcd_and_vcs_config(config['vcd'], config['vcs'], msg_update_callback) _validate_broker_config(config['broker'], msg_update_callback) check_keys_and_value_types(config['service'], SAMPLE_SERVICE_CONFIG['service'], location="config file 'service' section", excluded_keys=['log_wire'], msg_update_callback=msg_update_callback) if msg_update_callback: msg_update_callback.general( f"Config file '{config_file_name}' is valid") if isinstance(pks_config_location, str) and pks_config_location: check_file_permissions(pks_config_location, msg_update_callback=msg_update_callback) with open(pks_config_location) as f: pks_config = yaml.safe_load(f) or {} if msg_update_callback: msg_update_callback.info( f"Validating PKS config file '{pks_config_location}'") _validate_pks_config_structure(pks_config, msg_update_callback) _validate_pks_config_data_integrity(pks_config, msg_update_callback) if msg_update_callback: msg_update_callback.general( f"PKS Config file '{pks_config_location}' is valid") config['pks_config'] = pks_config else: config['pks_config'] = None return config