def check_controller_fabric(personality, fabric): """ Check controller Fabric configuration override (which essentially is only for debugging purposes or for people running Crossbar.io FX Service on-premise) :param fabric: The Fabric configuration to check. :type fabric: dict """ if not isinstance(fabric, Mapping): raise checkconfig.InvalidConfigException( "'fabric' in controller configuration must be a dictionary ({} encountered)\n\n" .format(type(fabric))) for k in fabric: if k not in ['transport', 'heartbeat']: raise checkconfig.InvalidConfigException( "encountered unknown attribute '{}' in 'fabric' in controller configuration" .format(k)) if 'transport' in fabric: checkconfig.check_connecting_transport(personality, fabric['transport']) if 'heartbeat' in fabric: heartbeat = fabric['heartbeat'] checkconfig.check_dict_args( { 'startup_delay': (False, [int, float]), 'heartbeat_period': (False, [int, float]), 'include_system_stats': (False, [bool]), 'send_workers_heartbeats': (False, [bool]), 'aggregate_workers_heartbeats': (False, [bool]), }, heartbeat, "heartbeat configuration: {}".format(pformat(heartbeat)))
def check_database(personality, database): checkconfig.check_dict_args( { 'type': (True, [six.text_type]), 'path': (True, [six.text_type]), 'maxsize': (False, six.integer_types), }, database, "database configuration") if database['type'] not in ['cfxdb']: raise checkconfig.InvalidConfigException( 'invalid type "{}" in database configuration'.format( database['type'])) if 'maxsize' in database: # maxsize must be between 1MB and 1TB if database['maxsize'] < 2**20 or database['maxsize'] > 2**40: raise checkconfig.InvalidConfigException( 'invalid maxsize {} in database configuration - must be between 1MB and 1TB' .format(database['maxsize']))
def check_connections(personality, connections): """ Connections can be present in controller, router and container processes. """ if not isinstance(connections, Sequence): raise checkconfig.InvalidConfigException("'connections' items must be lists ({} encountered)".format( type(connections))) for i, connection in enumerate(connections): personality.check_connection(personality, connection)
def check_connection(personality, connection, ignore=[]): """ Check a connection item (such as a PostgreSQL or Oracle database connection pool). """ if 'id' in connection: checkconfig.check_id(connection['id']) if 'type' not in connection: raise checkconfig.InvalidConfigException( "missing mandatory attribute 'type' in connection configuration" ) valid_types = ['postgres'] if connection['type'] not in valid_types: raise checkconfig.InvalidConfigException( "invalid type '{}' for connection type - must be one of {}". format(connection['type'], valid_types)) if connection['type'] == 'postgres': checkconfig.check_dict_args( { 'id': (False, [six.text_type]), 'type': (True, [six.text_type]), 'host': (False, [six.text_type]), 'port': (False, six.integer_types), 'database': (True, [six.text_type]), 'user': (True, [six.text_type]), 'password': (False, [six.text_type]), 'options': (False, [Mapping]), }, connection, "PostgreSQL connection configuration") if 'port' in connection: checkconfig.check_endpoint_port(connection['port']) if 'options' in connection: checkconfig.check_dict_args( { 'min_connections': (False, six.integer_types), 'max_connections': (False, six.integer_types), }, connection['options'], "PostgreSQL connection options") else: raise checkconfig.InvalidConfigException('logic error')
def check_hostmonitor_options(personality, options): checkconfig.check_native_worker_options(personality, options, ignore=['interval', 'monitors']) # polling interval of sensors in ms interval = options.get('interval', 500) if type(interval) not in six.integer_types: raise checkconfig.InvalidConfigException( 'invalid type "{}" for "interval" in host monitor configuration (must be an integer for ms)' .format(type(interval))) monitors = options.get('monitors', {}) if not isinstance(monitors, Mapping): raise checkconfig.InvalidConfigException( 'invalid type "{}" for "monitors" in host monitor configuration (must be a dict)' .format(type(monitors))) for monitor in monitors: # FIXME: check if we know the monitor, and monitor # specific configuration is valid pass
def check_controller(personality, controller, ignore=[]): res = checkconfig.check_controller( personality, controller, ['fabric', 'blockchain', 'enable_docker'] + ignore) if 'fabric' in controller: check_controller_fabric(personality, controller['fabric']) if 'blockchain' in controller: check_blockchain(personality, controller['blockchain']) if 'enable_docker' in controller: enable_docker = controller['enable_docker'] if type(enable_docker) != bool: raise checkconfig.InvalidConfigException( 'invalid type "{}" for "enable_docker" in controller'.format( type(enable_docker))) return res
def check_markets_worker(personality, config): for k in config: if k not in ['id', 'type', 'options', 'makers']: raise checkconfig.InvalidConfigException( 'encountered unknown attribute "{}" in XBR markets worker configuration' .format(k)) if 'id' in config: checkconfig.check_id(config['id']) if 'options' not in config: raise checkconfig.InvalidConfigException( 'missing attribute "database" in XBR markets worker configuration') check_markets_worker_options(personality, config['options']) if 'extra' not in config['options']: raise checkconfig.InvalidConfigException( 'missing attribute "options.extra" in XBR markets worker configuration' ) extra = config['options']['extra'] if 'database' not in extra: raise checkconfig.InvalidConfigException( 'missing attribute "options.extra.database" in XBR markets worker configuration' ) check_database(personality, extra['database']) if 'blockchain' not in extra: raise checkconfig.InvalidConfigException( 'missing attribute "options.extra.blockchain" in XBR markets worker configuration' ) check_blockchain(personality, extra['blockchain']) makers = config.get('makers', []) if not isinstance(makers, Sequence): raise checkconfig.InvalidConfigException( "'makers' items must be lists ({} encountered)\n\n{}".format( type(makers), pformat(config))) for maker in makers: check_market_maker(personality, maker)
def check_blockchain(personality, blockchain): # Examples: # # "blockchain": { # "type": "ethereum", # "gateway": { # "type": "auto" # } # } # # "blockchain": { # "type": "ethereum", # "gateway": { # "type": "user", # "http": "http://127.0.0.1:8545" # "websocket": "ws://127.0.0.1:8545" # }, # "from_block": 1, # "chain_id": 5777 # } # # "blockchain": { # "type": "ethereum", # "gateway": { # "type": "infura", # "network": "ropsten", # "key": "00000000000000000000000000000000", # "secret": "00000000000000000000000000000000" # }, # "from_block": 6350652, # "chain_id": 3 # } checkconfig.check_dict_args( { 'id': (False, [six.text_type]), 'type': (True, [six.text_type]), 'gateway': (True, [Mapping]), 'key': (False, [six.text_type]), 'from_block': (False, [int]), 'chain_id': (False, [int]), }, blockchain, "blockchain configuration item {}".format(pformat(blockchain))) if blockchain['type'] not in ['ethereum']: raise checkconfig.InvalidConfigException( 'invalid type "{}" in blockchain configuration'.format( blockchain['type'])) gateway = blockchain['gateway'] if 'type' not in gateway: raise checkconfig.InvalidConfigException( 'missing type in gateway item "{}" of blockchain configuration'. format(pformat(gateway))) if gateway['type'] not in ['infura', 'user', 'auto']: raise checkconfig.InvalidConfigException( 'invalid type "{}" in gateway item of blockchain configuration'. format(gateway['type'])) if gateway['type'] == 'infura': checkconfig.check_dict_args( { 'type': (True, [six.text_type]), 'network': (True, [six.text_type]), 'key': (True, [six.text_type]), 'secret': (True, [six.text_type]), }, gateway, "blockchain gateway configuration {}".format(pformat(gateway))) # allow to set value from environment variable gateway['key'] = checkconfig.maybe_from_env( 'blockchain.gateway["infura"].key', gateway['key'], hide_value=True) gateway['secret'] = checkconfig.maybe_from_env( 'blockchain.gateway["infura"].secret', gateway['secret'], hide_value=True) elif gateway['type'] == 'user': checkconfig.check_dict_args( { 'type': (True, [six.text_type]), 'http': (True, [six.text_type]), # 'websocket': (True, [six.text_type]), }, gateway, "blockchain gateway configuration {}".format(pformat(gateway))) elif gateway['type'] == 'auto': checkconfig.check_dict_args({ 'type': (True, [six.text_type]), }, gateway, "blockchain gateway configuration {}".format( pformat(gateway))) else: # should not arrive here raise Exception('logic error')
def check_controller_fabric_center(personality, config): if not isinstance(config, Mapping): raise checkconfig.InvalidConfigException( "'fabric-center' in controller configuration must be a dictionary ({} encountered)\n\n" .format(type(config))) for k in config: if k not in ['metering', 'auto_default_mrealm']: raise checkconfig.InvalidConfigException( "encountered unknown attribute '{}' in 'fabric-center' in controller configuration" .format(k)) if 'auto_default_mrealm' in config: auto_default_mrealm = config['auto_default_mrealm'] checkconfig.check_dict_args( { 'enabled': (False, [bool]), 'watch_to_pair': (False, [str]), 'watch_to_pair_pattern': (False, [str]), 'write_pairing_file': (False, [bool]), }, auto_default_mrealm, "auto_default_mrealm configuration: {}".format( pformat(auto_default_mrealm))) if 'metering' in config: # "metering": { # "period": 60, # "submit": { # "period": 120, # "url": "http://localhost:7000", # "timeout": 5, # "maxerrors": 10 # } # } # # also possible to read the URL from an env var: # # "url": "${crossbar_METERING_URL}" # metering = config['metering'] checkconfig.check_dict_args( { 'period': (False, [int, float]), 'submit': (False, [Mapping]), }, metering, "metering configuration: {}".format(pformat(metering))) if 'submit' in metering: checkconfig.check_dict_args( { 'period': (False, [int, float]), 'url': (False, [str]), 'timeout': (False, [int, float]), 'maxerrors': (False, [int]), }, metering['submit'], "metering submit configuration: {}".format( pformat(metering['submit']))) if 'url' in metering['submit']: # allow to set value from environment variable metering['submit']['url'] = checkconfig.maybe_from_env( 'metering.submit.url', metering['submit']['url'])