def setup(config): """Setup persistence to be used in cinderlib. By default memory persistance will be used, but there are other mechanisms available and other ways to use custom mechanisms: - Persistence plugins: Plugin mechanism uses Python entrypoints under namespace cinderlib.persistence.storage, and cinderlib comes with 3 different mechanisms, "memory", "dbms", and "memory_dbms". To use any of these one must pass the string name in the storage parameter and any other configuration as keyword arguments. - Passing a class that inherits from PersistenceDriverBase as storage parameter and initialization parameters as keyword arguments. - Passing an instance that inherits from PersistenceDriverBase as storage parameter. """ if config is None: config = {} else: config = config.copy() # Default configuration is using memory storage storage = config.pop('storage', None) or DEFAULT_STORAGE if isinstance(storage, base.PersistenceDriverBase): return storage if inspect.isclass(storage) and issubclass(storage, base.PersistenceDriverBase): return storage(**config) if not isinstance(storage, six.string_types): raise exception.InvalidPersistence(storage) persistence_driver = driver.DriverManager( namespace='cinderlib.persistence.storage', name=storage, invoke_on_load=True, invoke_kwds=config, ) return persistence_driver.driver
def _get_storage_pipeline(resource_name, conf): """Constructs and returns a storage resource pipeline. This is a helper function for any service supporting pipelines for the storage layer. The function returns a pipeline based on the `{resource_name}_pipeline` config option. Stages in the pipeline implement controller methods that they want to hook. A stage can halt the pipeline immediate by returning a value that is not None; otherwise, processing will continue to the next stage, ending with the actual storage controller. :param conf: Configuration instance. :type conf: `cfg.ConfigOpts` :returns: A pipeline to use. :rtype: `Pipeline` """ conf.register_opts(_PIPELINE_CONFIGS, group=_PIPELINE_GROUP) storage_conf = conf[_PIPELINE_GROUP] pipeline = [] for ns in storage_conf[resource_name + '_pipeline']: try: mgr = driver.DriverManager('marconi.queues.storage.stages', ns, invoke_on_load=True) pipeline.append(mgr.driver) except RuntimeError as exc: LOG.warning(_(u'Stage %(stage)d could not be imported: %(ex)s'), { 'stage': ns, 'ex': str(exc) }) continue return common.Pipeline(pipeline)
def fetch(name, conf, namespace=BACKEND_NAMESPACE, **kwargs): """Fetch a jobboard backend with the given configuration. This fetch method will look for the entrypoint name in the entrypoint namespace, and then attempt to instantiate that entrypoint using the provided name, configuration and any board specific kwargs. NOTE(harlowja): to aid in making it easy to specify configuration and options to a board the configuration (which is typical just a dictionary) can also be a uri string that identifies the entrypoint name and any configuration specific to that board. For example, given the following configuration uri: zookeeper://<not-used>/?a=b&c=d This will look for the entrypoint named 'zookeeper' and will provide a configuration object composed of the uris parameters, in this case that is {'a': 'b', 'c': 'd'} to the constructor of that board instance (also including the name specified). """ if isinstance(conf, six.string_types): conf = {'board': conf} board = conf['board'] try: uri = misc.parse_uri(board) except (TypeError, ValueError): pass else: board = uri.scheme conf = misc.merge_uri(uri, conf.copy()) LOG.debug('Looking for %r jobboard driver in %r', board, namespace) try: mgr = driver.DriverManager(namespace, board, invoke_on_load=True, invoke_args=(name, conf), invoke_kwds=kwargs) return mgr.driver except RuntimeError as e: raise exc.NotFound("Could not find jobboard %s" % (board), e)
def validate_availability_zone(self, availability_zone_dict): """Validates availability zone profile data. This will validate an availability zone profile dataset against the availability zone settings the amphora driver supports. :param availability_zone_dict: The availability zone dict to validate. :type availability_zone_dict: dict :return: None :raises DriverError: An unexpected error occurred. :raises UnsupportedOptionError: If the driver does not support one of the availability zone settings. """ try: validate( availability_zone_dict, availability_zone_schema.SUPPORTED_AVAILABILITY_ZONE_SCHEMA) except js_exceptions.ValidationError as e: error_object = '' if e.relative_path: error_object = '{} '.format(e.relative_path[0]) raise exceptions.UnsupportedOptionError( user_fault_string='{0}{1}'.format(error_object, e.message), operator_fault_string=str(e)) except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to validate the availability zone ' 'metadata due to: {}'.format(str(e)), operator_fault_string='Failed to validate the availability ' 'zone metadata due to: {}'.format(str(e))) compute_zone = availability_zone_dict.get(consts.COMPUTE_ZONE, None) if compute_zone: compute_driver = stevedore_driver.DriverManager( namespace='octavia.compute.drivers', name=CONF.controller_worker.compute_driver, invoke_on_load=True).driver # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. compute_driver.validate_availability_zone(compute_zone)
def __init__(self, transport, dispatcher, executor='blocking'): """Construct a message handling server. The dispatcher parameter is a callable which is invoked with context and message dictionaries each time a message is received. The executor parameter controls how incoming messages will be received and dispatched. By default, the most simple executor is used - the blocking executor. :param transport: the messaging transport :type transport: Transport :param dispatcher: a callable which is invoked for each method :type dispatcher: callable :param executor: name of message executor - for example 'eventlet', 'blocking' :type executor: str """ self.conf = transport.conf self.conf.register_opts(_pool_opts) self.transport = transport self.dispatcher = dispatcher self.executor_type = executor self.listener = None try: mgr = driver.DriverManager('oslo.messaging.executors', self.executor_type) except RuntimeError as ex: raise ExecutorLoadFailure(self.executor_type, ex) self._executor_cls = mgr.driver self._work_executor = None self._started = False super(MessageHandlingServer, self).__init__()
def __init__(self, global_conf): LOG.debug('initializing V2API in NotificationMethodDispatcher!') super(NotificationMethodDispatcher, self).__init__() self.doc_type = cfg.CONF.notificationmethods.doc_type self.size = cfg.CONF.notificationmethods.size # load index strategy if cfg.CONF.notificationmethods.index_strategy: self.index_strategy = driver.DriverManager( namespace.STRATEGY_NS, cfg.CONF.notificationmethods.index_strategy, invoke_on_load=True, invoke_kwds={}).driver LOG.debug(dir(self.index_strategy)) else: self.index_strategy = None self.index_prefix = cfg.CONF.notificationmethods.index_prefix self._es_conn = es_conn.ESConnection(self.doc_type, self.index_strategy, self.index_prefix)
def get_instance(cls, specific_driver=None, scope='default'): """Get an implementing driver instance. :param specific_driver: Loads a specific driver instead of using conf. Uses separate manager entry so that loading of default/other drivers is not affected. :param scope: Loads the driver in the given scope (if independent instances of a driver are required) """ alias = cls.ALIAS if specific_driver: driver_key = '{}:{}:{}'.format(alias, specific_driver, scope) else: driver_key = '{}:_from_cfg:{}'.format(alias, scope) try: manager = _DRIVER_MANAGERS[driver_key] except KeyError: driver_name = (specific_driver or config.CONF.kubernetes[alias + '_driver']) manager = stv_driver.DriverManager(namespace="%s.%s" % (_DRIVER_NAMESPACE_BASE, alias), name=driver_name, invoke_on_load=True) _DRIVER_MANAGERS[driver_key] = manager driver = manager.driver if not isinstance(driver, cls): raise TypeError( _("Invalid %(alias)r driver type: %(driver)s, " "must be a subclass of %(type)s") % { 'alias': alias, 'driver': driver.__class__.__name__, 'type': cls }) return driver
def __init__(self, global_conf): LOG.debug('Initializing AlarmDefinition V2API!') super(AlarmDefinitionDispatcher, self).__init__() self.doc_type = cfg.CONF.alarmdefinitions.doc_type self.size = cfg.CONF.alarmdefinitions.size # load index strategy if cfg.CONF.alarmdefinitions.index_strategy: self.index_strategy = driver.DriverManager( namespace.STRATEGY_NS, cfg.CONF.alarmdefinitions.index_strategy, invoke_on_load=True, invoke_kwds={}).driver LOG.debug(self.index_strategy) else: self.index_strategy = None self.index_prefix = cfg.CONF.alarmdefinitions.index_prefix self._es_conn = es_conn.ESConnection(self.doc_type, self.index_strategy, self.index_prefix)
def storage(self): """storage. :returns mgr driver """ LOG.debug((u'Loading storage driver')) # create the driver manager to load the appropriate drivers storage_type = 'poppy.storage' storage_name = self.driver_conf.storage args = [self.conf] try: mgr = driver.DriverManager(namespace=storage_type, name=storage_name, invoke_on_load=True, invoke_args=args) return mgr.driver except RuntimeError as exc: LOG.exception(exc)
def __init__(self, auth_plugin="token", verify=True, cert=None, timeout=None, *args, **kwargs): self.auth_plugin = driver.DriverManager( 'shadowfiend.client_auth_plugin', auth_plugin, invoke_on_load=True, invoke_args=args, invoke_kwds=kwargs) self.auth_plugin = self.auth_plugin.driver self.session = requests.Session() self.verify = verify self.cert = cert self.timeout = None if timeout is not None: self.timeout = float(timeout)
def _check_jobboard(self, persistence): try: jobboard_driver = stevedore_driver.DriverManager( namespace='octavia.worker.jobboard_driver', name=CONF.task_flow.jobboard_backend_driver, invoke_args=(persistence,), invoke_on_load=True).driver with jobboard_driver.job_board(persistence) as jb: if jb.connected: return upgradecheck.Result( upgradecheck.Code.SUCCESS, _('Persistence database and Jobboard backend for ' 'AmphoraV2 provider configured.')) except Exception: # Return FAILURE later pass return upgradecheck.Result( upgradecheck.Code.FAILURE, _('Failed to connect to jobboard backend for AmphoraV2 provider. ' 'Check jobboard configuration options in task_flow config ' 'section.'))
def make_renderer(name, metadata, file_path, url, assets_url, export_url): """Returns an instance of :class:`mfr.core.extension.BaseRenderer` :param str name: The name of the extension to instantiate. (.jpg, .docx, etc) :param :class:`mfr.core.provider.ProviderMetadata` metadata: :param str file_path: :param str url: :param str assets_url: :param str export_url: :rtype: :class:`mfr.core.extension.BaseRenderer` """ try: return driver.DriverManager( namespace='mfr.renderers', name=(name and name.lower()) or 'none', invoke_on_load=True, invoke_args=(metadata, file_path, url, assets_url, export_url), ).driver except RuntimeError: raise exceptions.RendererError(settings.UNSUPPORTED_RENDER_MSG, code=400)
def fetch(conf, namespace=BACKEND_NAMESPACE, **kwargs): """Fetch a persistence backend with the given configuration. This fetch method will look for the entrypoint name in the entrypoint namespace, and then attempt to instantiate that entrypoint using the provided configuration and any persistence backend specific kwargs. NOTE(harlowja): to aid in making it easy to specify configuration and options to a backend the configuration (which is typical just a dictionary) can also be a uri string that identifies the entrypoint name and any configuration specific to that backend. For example, given the following configuration uri: mysql://<not-used>/?a=b&c=d This will look for the entrypoint named 'mysql' and will provide a configuration object composed of the uris parameters, in this case that is {'a': 'b', 'c': 'd'} to the constructor of that persistence backend instance. """ backend_name = conf['connection'] try: pieces = misc.parse_uri(backend_name) except (TypeError, ValueError): pass else: backend_name = pieces['scheme'] conf = misc.merge_uri(pieces, conf.copy()) LOG.debug('Looking for %r backend driver in %r', backend_name, namespace) try: mgr = driver.DriverManager(namespace, backend_name, invoke_on_load=True, invoke_args=(conf, ), invoke_kwds=kwargs) return mgr.driver except RuntimeError as e: raise exc.NotFound("Could not find backend %s: %s" % (backend_name, e))
def __init__(self): self.fetcher = driver.DriverManager( FETCHERS_NAMESPACE, CONF.fetcher.backend, invoke_on_load=True, ).driver transformers = transformer.get_transformers() self.collector = collector.get_collector(transformers) self.storage = storage.get_storage() self._state = state.StateManager() # RPC self.server = None self._rating_endpoint = RatingEndpoint(self) self._init_messaging() # DLM self.coord = coordination.get_coordinator( CONF.orchestrator.coordination_url, uuidutils.generate_uuid().encode('ascii')) self.coord.start()
def _get_flow(self, task): try: task_input = script_utils.unpack_task_input(task) kwds = { 'task_id': task.task_id, 'task_type': task.type, 'context': self.context, 'task_repo': self.task_repo, 'image_repo': self.image_repo, 'image_factory': self.image_factory, 'backend': task_input.get('backend') } if self.admin_repo: kwds['admin_repo'] = self.admin_repo if task.type == "import": uri = script_utils.validate_location_uri( task_input.get('import_from')) kwds['uri'] = uri if task.type == 'api_image_import': kwds['image_id'] = task_input['image_id'] kwds['import_req'] = task_input['import_req'] return driver.DriverManager('glance.flows', task.type, invoke_on_load=True, invoke_kwds=kwds).driver except urllib.error.URLError as exc: raise exception.ImportTaskError(message=exc.reason) except (exception.BadStoreUri, exception.Invalid) as exc: raise exception.ImportTaskError(message=exc.msg) except exception.LimitExceeded as exc: raise exception.ImportTaskError(message=exc.msg) except RuntimeError: raise NotImplementedError() except Exception as e: LOG.exception(_LE('Task initialization failed: %s'), str(e)) raise
def validate_flavor(self, flavor_dict): """Validates flavor profile data. This will validate a flavor profile dataset against the flavor settings the amphora driver supports. :param flavor_dict: The flavor dictionary to validate. :type flavor: dict :return: None :raises DriverError: An unexpected error occurred. :raises UnsupportedOptionError: If the driver does not support one of the flavor settings. """ try: validate(flavor_dict, flavor_schema.SUPPORTED_FLAVOR_SCHEMA) except js_exceptions.ValidationError as e: error_object = '' if e.relative_path: error_object = '{} '.format(e.relative_path[0]) raise exceptions.UnsupportedOptionError( user_fault_string='{0}{1}'.format(error_object, e.message), operator_fault_string=str(e)) except Exception as e: raise exceptions.DriverError( user_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e)), operator_fault_string='Failed to validate the flavor metadata ' 'due to: {}'.format(str(e))) compute_flavor = flavor_dict.get(consts.COMPUTE_FLAVOR, None) if compute_flavor: compute_driver = stevedore_driver.DriverManager( namespace='octavia.compute.drivers', name=CONF.controller_worker.compute_driver, invoke_on_load=True ).driver # TODO(johnsom) Fix this to raise a NotFound error # when the octavia-lib supports it. compute_driver.validate_flavor(compute_flavor)
def manager(self): """manager. :returns mgr driver """ LOG.debug((u'Loading manager driver')) # create the driver manager to load the appropriate drivers manager_type = 'poppy.manager' manager_name = self.driver_conf.manager args = [self.conf, self.storage, self.provider, self.dns, self.distributed_task, self.notification, self.metrics] try: mgr = driver.DriverManager(namespace=manager_type, name=manager_name, invoke_on_load=True, invoke_args=args) return mgr.driver except RuntimeError as exc: LOG.exception(exc)
async def post(self): try: data = self.json['data'] except (TypeError, ValueError, KeyError): raise exceptions.MalformedData() if data.get('type') != 'users': raise exceptions.IncorrectParameter('data.type', 'users', data.get('type', 'null')) if not isinstance(data.get('attributes'), dict): raise exceptions.InvalidType('data.attributes', 'dict', type(data.get('type'))) try: provider = driver.DriverManager( namespace='jam.auth.providers', name=data['attributes'].pop('provider'), invoke_on_load=True, ).driver except (KeyError, driver.NoMatches): raise exceptions.BadRequest(detail='Unknown provider') user = await provider.authenticate(self.current_user, data['attributes']) self.write({ 'data': { 'id': user.uid, 'type': 'users', 'attributes': { 'id': user.id, 'type': user.type, 'provider': user.provider, 'token': user.token.decode(), # 'refreshable': provider.refreshable, #TODO Implement refreshing } } })
def _get_flow(self, task): try: task_input = script_utils.unpack_task_input(task) uri = script_utils.validate_location_uri( task_input.get('import_from')) kwds = { 'uri': uri, 'task_id': task.task_id, 'task_type': task.type, 'context': self.context, 'task_repo': self.task_repo, 'image_repo': self.image_repo, 'image_factory': self.image_factory } return driver.DriverManager('glance.flows', task.type, invoke_on_load=True, invoke_kwds=kwds).driver except RuntimeError: raise NotImplementedError()
def make_provider(name, auth, credentials, settings, **kwargs): """Returns an instance of :class:`waterbutler.core.provider.BaseProvider` :param str name: The name of the provider to instantiate. (s3, box, etc) :param dict auth: :param dict credentials: :param dict settings: :param dict \*\*kwargs: currently there to absorb ``callback_url`` :rtype: :class:`waterbutler.core.provider.BaseProvider` """ try: manager = driver.DriverManager( namespace='waterbutler.providers', name=name, invoke_on_load=True, invoke_args=(auth, credentials, settings), ) except RuntimeError: raise exceptions.ProviderNotFound(name) return manager.driver
def __init__(self, app, version, auth_plugin="token", verify=True, cert=None, timeout=None, *args, **kwargs): self.app = app self.version = '/%s' % version self.auth_plugin = driver.DriverManager('gringotts.client_auth_plugin', auth_plugin, invoke_on_load=True, invoke_args=args, invoke_kwds=kwargs) self.auth_plugin = self.auth_plugin.driver self.session = None self.verify = verify self.cert = cert self.timeout = float(timeout) if timeout else None
def update_distributor(self, distributor_id, distributor_updates): """Updates a distributor. :param distributor_id: ID of the distributor to update :param distributor_updates: Dict containing updated distributor :returns: None :raises DistributorlNotFound: The referenced distributor was not found """ distributor = self._distributor_repo.get(db_apis.get_session(), id=distributor_id) distributor_driver = stevedore_driver.DriverManager( namespace='octavia.distributor.drivers', name=distributor.distributor_driver, invoke_on_load=True).driver update_distributor_tf = self._taskflow_load( self._distributor_flows.get_update_distributor_flows( distributor_driver), store={ constants.DISTRIBUTOR: distributor, constants.UPDATE_DICT: distributor_updates }) with tf_logging.DynamicLoggingListener(update_distributor_tf, log=LOG): update_distributor_tf.run()
def get_instance(cls): """Get an implementing driver instance.""" alias = cls.ALIAS try: manager = _DRIVER_MANAGERS[alias] except KeyError: name = config.CONF.kubernetes[alias + '_driver'] manager = stv_driver.DriverManager( namespace="%s.%s" % (_DRIVER_NAMESPACE_BASE, alias), name=name, invoke_on_load=True) _DRIVER_MANAGERS[alias] = manager driver = manager.driver if not isinstance(driver, cls): raise TypeError(_LE("Invalid %(alias)r driver type: %(driver)s, " "must be a subclass of %(type)s") % { 'alias': alias, 'driver': driver.__class__.__name__, 'type': cls}) return driver
def _get_matchmaker(*args, **kwargs): global matchmaker mm_name = CONF.rpc_zmq_matchmaker # Back compatibility for old class names mm_mapping = { 'oslo_messaging._drivers.matchmaker_redis.MatchMakerRedis': 'redis', 'oslo_messaging._drivers.matchmaker_ring.MatchMakerRing': 'ring', 'oslo_messaging._drivers.matchmaker.MatchMakerLocalhost': 'local', 'oslo.messaging._drivers.matchmaker_redis.MatchMakerRedis': 'redis', 'oslo.messaging._drivers.matchmaker_ring.MatchMakerRing': 'ring', 'oslo.messaging._drivers.matchmaker.MatchMakerLocalhost': 'local'} if mm_name in mm_mapping: LOG.warn(_LW('rpc_zmq_matchmaker = %(old_val)s is deprecated. ' 'It is suggested to change the value to %(new_val)s.'), {'old_val': mm_name, 'new_val': mm_mapping[mm_name]}) mm_name = mm_mapping[mm_name] if not matchmaker: mgr = driver.DriverManager('oslo.messaging.zmq.matchmaker', mm_name) matchmaker = mgr.driver(*args, **kwargs) return matchmaker
def __init__(self, context, pmon, intf_driver, notifier, pd_update_cb, agent_conf): self.context = context self.pmon = pmon self.intf_driver = intf_driver self.notifier = notifier self.routers = {} self.pd_update_cb = pd_update_cb self.agent_conf = agent_conf self.pd_dhcp_driver = driver.DriverManager( namespace='neutron.agent.linux.pd_drivers', name=agent_conf.prefix_delegation_driver, ).driver registry.subscribe(add_router, resources.ROUTER, events.BEFORE_CREATE) registry.subscribe(update_router, resources.ROUTER, events.AFTER_UPDATE) registry.subscribe(remove_router, resources.ROUTER, events.AFTER_DELETE) self._get_sync_data()
def transport(self): """transport. :returns mgr driver """ LOG.debug("loading transport") # create the driver manager to load the appropriate drivers transport_type = 'poppy.transport' transport_name = self.driver_conf.transport args = [self.conf, self.manager] LOG.debug((u'Loading transport driver: %s'), transport_name) try: mgr = driver.DriverManager(namespace=transport_type, name=transport_name, invoke_on_load=True, invoke_args=args) return mgr.driver except RuntimeError as exc: LOG.exception(exc)
def __init__(self): super(VirtualMachineManager, self).__init__() # Must initialize nova api self._nova_client = clients.NovaAuth.get_nova_client( endpoint=CONF.nova.endpoint, region=CONF.nova.region_name, endpoint_type=CONF.nova.endpoint_type, insecure=CONF.nova.insecure, cacert=CONF.nova.ca_certificates_file) self._glance_client = clients.GlanceAuth.get_glance_client( service_name=CONF.glance.service_name, endpoint=CONF.glance.endpoint, region=CONF.glance.region_name, endpoint_type=CONF.glance.endpoint_type, insecure=CONF.glance.insecure, cacert=CONF.glance.ca_certificates_file) self.manager = self._nova_client.servers self.server_groups = self._nova_client.server_groups self.flavor_manager = self._nova_client.flavors self.volume_driver = stevedore_driver.DriverManager( namespace='octavia.volume.drivers', name=CONF.controller_worker.volume_driver, invoke_on_load=True).driver
def _get_transport(conf, url=None, allowed_remote_exmods=None, transport_cls=RPCTransport): allowed_remote_exmods = allowed_remote_exmods or [] conf.register_opts(_transport_opts) if not isinstance(url, TransportURL): url = TransportURL.parse(conf, url) kwargs = dict(default_exchange=conf.control_exchange, allowed_remote_exmods=allowed_remote_exmods) try: mgr = driver.DriverManager('oslo.messaging.drivers', url.transport.split('+')[0], invoke_on_load=True, invoke_args=[conf, url], invoke_kwds=kwargs) except RuntimeError as ex: raise DriverLoadFailure(url.transport, ex) return transport_cls(mgr.driver)
def __init__(self): # Tenant fetcher self.fetcher = driver.DriverManager(FETCHERS_NAMESPACE, CONF.tenant_fetcher.backend, invoke_on_load=True).driver self.transformers = transformer.get_transformers() self.collector = collector.get_collector(self.transformers) self.storage = storage.get_storage(self.collector) # RPC self.server = None self._rating_endpoint = RatingEndpoint(self) self._init_messaging() # DLM self.coord = coordination.get_coordinator( CONF.orchestrator.coordination_url, uuidutils.generate_uuid().encode('ascii')) self.coord.start() self._period = CONF.collect.period self._wait_time = CONF.collect.wait_periods * self._period
def __init__(self, taskinfo, conn): self.conn_mysql = conn self.task_id = taskinfo['task_id'] self.task_name = taskinfo['task_name'] self.task_type = taskinfo['task_type'] self.task_period = taskinfo['task_period'] # self.task_content = json.loads(taskinfo['task_content']) self.task_content = ast.literal_eval(taskinfo['task_content']) self.task_status = taskinfo['task_status'] self.task_time = taskinfo.get('task_time', '') self.file_language = taskinfo.get('task_language', "English") if self.file_language == 'Chinese': from report.i18n import _F as _ else: from report.i18n import _LI as _ self.i18n = _ # metadata = json.loads(taskinfo['task_metadata']) metadata = ast.literal_eval(taskinfo['task_metadata']) filetype = metadata.get('filetype', 'pdf') if filetype not in FILE_TYPE: self.filetype = 'pdf' else: self.filetype = filetype self.needmail = metadata.get('needmail', 'No') self.to_maillist = metadata.get('to_maillist', []) self.cc_maillist = metadata.get('cc_maillist', []) mgr = driver.DriverManager('report.file', self.filetype) self.filedriver = mgr.driver self.get_trigger()