def get_endpoint_destination_minion_pool_options(self, ctxt, platform_name, connection_info, env, option_names): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_DESTINATION_MINION_POOL, None, raise_if_not_found=False) if not provider: raise exception.InvalidInput( "Provider plugin for platform '%s' does not support " "destination minion pool creation or management." % (platform_name)) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) options = provider.get_minion_pool_options(ctxt, secret_connection_info, env=env, option_names=option_names) # NOTE: the structure of option values is the same for minion pools: schemas.validate_value( options, schemas.CORIOLIS_DESTINATION_ENVIRONMENT_OPTIONS_SCHEMA) return options
def run(self, ctxt, instance, origin, destination, task_info, event_handler): target_environment = destination.get("target_environment") or {} export_info = task_info["export_info"] provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_REPLICA_IMPORT, event_handler) connection_info = base.get_connection_info(ctxt, destination) volumes_info = task_info.get("volumes_info", []) if volumes_info is None: # In case Replica disks were deleted: volumes_info = [] volumes_info = provider.deploy_replica_disks(ctxt, connection_info, target_environment, instance, export_info, volumes_info) schemas.validate_value(volumes_info, schemas.CORIOLIS_VOLUMES_INFO_SCHEMA) volumes_info = _check_ensure_volumes_info_ordering( export_info, volumes_info) task_info["volumes_info"] = volumes_info return task_info
def validate_endpoint_connection(self, ctxt, platform_name, connection_info): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) is_valid = True message = None try: schemas.validate_value(secret_connection_info, provider.get_connection_info_schema()) provider.validate_connection(ctxt, secret_connection_info) except exception.SchemaValidationException as ex: LOG.debug("Connection info schema validation failed: %s", ex) is_valid = False message = ( "Schema validation for the provided connection parameters has " "failed. Please ensure that you have included all the " "necessary connection parameters and they are all properly " "formatted for the '%s' Coriolis plugin in use." % (platform_name)) except exception.ConnectionValidationException as ex: LOG.warn(utils.get_exception_details()) is_valid = False message = str(ex) except Exception as ex: LOG.warn(utils.get_exception_details()) is_valid = False message = ("An unexpected connection validation exception " "ocurred: %s" % str(ex)) return (is_valid, message)
def run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_REPLICA_EXPORT, event_handler) connection_info = base.get_connection_info(ctxt, origin) source_environment = origin.get('source_environment') or {} replica_resources_info = provider.deploy_replica_source_resources( ctxt, connection_info, source_environment) task_info["migr_source_resources"] = replica_resources_info[ "migr_resources"] migr_connection_info = replica_resources_info.get("connection_info") if migr_connection_info: migr_connection_info = base.marshal_migr_conn_info( migr_connection_info) schemas.validate_value( migr_connection_info, schemas.CORIOLIS_DISK_SYNC_RESOURCES_CONN_INFO_SCHEMA, # NOTE: we avoid raising so that the cleanup task # can [try] to deal with the temporary resources. raise_on_error=False) task_info["migr_source_connection_info"] = migr_connection_info return task_info
def run_os_detect(origin_provider, destination_provider, worker_connection, os_type, os_root_dir, osmorphing_info, tools_environment={}): custom_export_os_detect_tools = ( origin_provider.get_custom_os_detect_tools(os_type, osmorphing_info)) custom_import_os_detect_tools = ( destination_provider.get_custom_os_detect_tools( os_type, osmorphing_info)) detected_info = osdetect_manager.detect_os( worker_connection, os_type, os_root_dir, CONF.default_osmorphing_operation_timeout, tools_environment=tools_environment, custom_os_detect_tools=list( itertools.chain(custom_export_os_detect_tools, custom_import_os_detect_tools))) schemas.validate_value(detected_info, schemas.CORIOLIS_DETECTED_OS_MORPHING_INFO_SCHEMA) return detected_info
def test_validate_value(self, mock_validate): test_value = mock.sentinel.test_value test_schema = mock.sentinel.test_schema schemas.validate_value(test_value, test_schema) mock_validate.assert_called_once_with(test_value, test_schema)
def run(self, ctxt, instance, origin, destination, task_info, event_handler): event_manager = events.EventManager(event_handler) destination_connection_info = base.get_connection_info( ctxt, destination) destination_type = destination["type"] export_info = task_info["export_info"] # validate Export info: schemas.validate_value(export_info, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) # validate destination params: destination_provider = providers_factory.get_provider( destination_type, constants.PROVIDER_TYPE_VALIDATE_REPLICA_IMPORT, event_handler, raise_if_not_found=False) if not destination_provider: event_manager.progress_update( "Replica Deployment Provider for platform '%s' does not " "support Replica Deployment input validation" % (destination_type)) return task_info # NOTE: the target environment JSON schema should have been validated # upon accepting the Replica API creation request. target_environment = destination.get("target_environment", {}) destination_provider.validate_replica_deployment_input( ctxt, destination_connection_info, target_environment, export_info) return task_info
def validate_storage_mappings(storage_mappings): """ Validates the JSON schema for the storage_mappings. """ try: schemas.validate_value( storage_mappings, schemas.CORIOLIS_STORAGE_MAPPINGS_SCHEMA) except exception.SchemaValidationException as ex: raise exc.HTTPBadRequest( explanation="Invalid storage_mappings: %s" % str(ex))
def validate_network_map(network_map): """ Validates the JSON schema for the network_map. """ try: schemas.validate_value( network_map, schemas.CORIOLIS_NETWORK_MAP_SCHEMA) except exception.SchemaValidationException as ex: raise exc.HTTPBadRequest( explanation="Invalid network_map: %s" % str(ex))
def _handle_post_task_actions(self, ctxt, task, execution, task_info): task_type = task.task_type updated_task_info = None if task_type == constants.TASK_TYPE_RESTORE_REPLICA_DISK_SNAPSHOTS: # When restoring a snapshot in some import providers (OpenStack), # a new volume_id is generated. This needs to be updated in the # Replica instance as well. volumes_info = task_info.get("volumes_info") if volumes_info: updated_task_info = {"volumes_info": volumes_info} elif task_type == constants.TASK_TYPE_DELETE_REPLICA_DISK_SNAPSHOTS: if not task_info.get("clone_disks"): # The migration completed. If the replica is executed again, # new volumes need to be deployed in place of the migrated # ones. updated_task_info = {"volumes_info": None} elif task_type in ( constants.TASK_TYPE_FINALIZE_IMPORT_INSTANCE, constants.TASK_TYPE_FINALIZE_REPLICA_INSTANCE_DEPLOYMENT): # set 'transfer_result' in the 'base_transfer_action' # table if the task returned a result. if "transfer_result" in task_info: transfer_result = task_info.get("transfer_result") try: schemas.validate_value( transfer_result, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) LOG.debug("Setting result for transfer action '%s': %s", execution.action_id, transfer_result) db_api.set_transfer_action_result(ctxt, execution.action_id, task.instance, transfer_result) except exception.SchemaValidationException as ex: LOG.warn( "Could not validate transfer result '%s' against the " "VM export info schema. NOT saving value in Database. " "Exception details: %s", transfer_result, utils.get_exception_details()) else: LOG.debug( "No 'transfer_result' was returned for task type '%s' " "for transfer action '%s'", task_type, execution.action_id) elif task_type == constants.TASK_TYPE_UPDATE_REPLICA: # perform the actual db update db_api.update_replica(ctxt, execution.action_id, task_info) # update volumes info volumes_info = task_info.get("volumes_info") if volumes_info: updated_task_info = {"volumes_info": volumes_info} if updated_task_info: self._update_replica_volumes_info(ctxt, execution.action_id, task.instance, updated_task_info)
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): event_manager = events.EventManager(event_handler) volumes_info = task_info.get("volumes_info", []) new_destination_env = task_info.get('target_environment', {}) # NOTE: the `target_environment` in the `destination` is the one # set in the dedicated DB column of the Replica and thus stores # the previous value of it: old_destination_env = destination.get('target_environment', {}) if not new_destination_env: event_manager.progress_update( "No new destination environment options provided") return { "target_environment": old_destination_env, "volumes_info": volumes_info } destination_provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_DESTINATION_REPLICA_UPDATE, event_handler, raise_if_not_found=False) if not destination_provider: raise exception.InvalidActionTasksExecutionState( "Replica destination provider plugin for '%s' does not " "support updating Replicas" % destination["type"]) destination_connection_info = base.get_connection_info( ctxt, destination) export_info = task_info.get("export_info", {}) LOG.info("Checking destination provider environment params") volumes_info = ( destination_provider.check_update_destination_environment_params( ctxt, destination_connection_info, export_info, volumes_info, old_destination_env, new_destination_env)) if volumes_info: schemas.validate_value(volumes_info, schemas.CORIOLIS_VOLUMES_INFO_SCHEMA) volumes_info = _check_ensure_volumes_info_ordering( export_info, volumes_info) else: LOG.warn( "Destination update method for '%s' dest provider did NOT " "return any volumes info. Defaulting to old value.", destination["type"]) volumes_info = task_info.get("volumes_info", []) return { "volumes_info": volumes_info, "target_environment": new_destination_env }
def run(self, ctxt, instance, origin, destination, task_info, event_handler): destination_provider = None source_provider = None dest_volumes_info = {} new_source_environment = task_info.get('source_environment') new_destination_environment = task_info.get('destination_environment') if new_source_environment: source_provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_REPLICA_EXPORT, event_handler) source_environment_schema = ( source_provider.get_source_environment_schema()) schemas.validate_value(new_source_environment, source_environment_schema) if new_destination_environment: destination_provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_REPLICA_IMPORT, event_handler) destination_environment_schema = ( destination_provider.get_target_environment_schema) schemas.validate_value(new_destination_environment, destination_environment_schema) connection_info = base.get_connection_info(ctxt, destination) export_info = task_info.get("export_info", {}) volumes_info = task_info.get("volumes_info", {}) old_source_environment = origin.get('source_environment', {}) new_source_environment = task_info.get('source_environment', {}) if source_provider: LOG.info("Checking source provider environment params") source_provider.check_update_environment_params( ctxt, connection_info, export_info, volumes_info, old_source_environment, new_source_environment) if destination_provider: LOG.info("Checking destination provider environment params") old_destination_environment = destination.get( 'target_environment', {}) new_destination_environment = task_info.get( 'target_environment', {}) dest_volumes_info = ( destination_provider.check_update_environment_params( ctxt, connection_info, export_info, volumes_info, old_destination_environment, new_destination_environment)) task_info['volumes_info'] = dest_volumes_info return task_info
def __init__(self, name, description, schedule, enabled, expires, on_success, on_error, job_callable, *args, **kw): # param: name: string: unique ID that describes this job # param: description: string: a short description of the job # param: schedule: dict: cron job schedule. This is of the form: # { # "minute": 1, # "hour": 0, # "dom": 20, # "month": 11, # "dow": 1 # } # param: enabled: bool: Whether or not this cron job is enabled # param: expires: datetime: expiration date for this cronjob # param: on_success: callable: a function that gets called if the # job is successful. This function must accept the result returned # by the scheduled function # # param: on_error: callable: If the function scheduled to run raises # an exception, this function will run. on_error MUST accept the # exception info raised by the scheduled function, as the only # parameter. Any exception thrown by this callback will be logged and # ignored. # # param: job_callable: callable: The function we are scheduling to run, # Every other *arg or **kw following this parameter will be passed in # directly to this function. self.name = name if not callable(job_callable): raise exception.CoriolisException("Invalid job function") schema = schemas.SCHEDULE_API_BODY_SCHEMA["properties"]["schedule"] schemas.validate_value(schedule, schema) if on_success and not callable(on_success): raise ValueError("on_success must be callable") if on_error and not callable(on_error): raise ValueError("on_error must be callable") self._on_success = on_success self._on_error = on_error self.schedule = schedule self._func = job_callable self._description = description self._args = args self._kw = kw self._enabled = enabled if expires: if not isinstance(expires, datetime.datetime): raise exception.CoriolisException("Invalid expires") self._expires = expires self._last_run = None
def get_endpoint_storage(self, ctxt, platform_name, connection_info, env): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT_STORAGE, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) storage = provider.get_storage(ctxt, secret_connection_info, env) schemas.validate_value(storage, schemas.CORIOLIS_VM_STORAGE_SCHEMA) return storage
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_REPLICA_EXPORT, event_handler) connection_info = base.get_connection_info(ctxt, origin) source_environment = task_info['source_environment'] or {} export_info = task_info['export_info'] replica_resources_info = provider.deploy_replica_source_resources( ctxt, connection_info, export_info, source_environment) migr_connection_info = replica_resources_info.get( "connection_info", {}) if 'connection_info' not in replica_resources_info: LOG.warn( "Replica source provider for '%s' did NOT return any " "'connection_info'. Defaulting to '%s'", origin["type"], migr_connection_info) else: migr_connection_info = replica_resources_info['connection_info'] if migr_connection_info: migr_connection_info = base.marshal_migr_conn_info( migr_connection_info) schemas.validate_value( migr_connection_info, schemas.CORIOLIS_REPLICATION_WORKER_CONN_INFO_SCHEMA, # NOTE: we avoid raising so that the cleanup task # can [try] to deal with the temporary resources. raise_on_error=False) else: LOG.warn( "Replica source provider for '%s' returned empty " "'connection_info' in source resources deployment: %s", origin["type"], migr_connection_info) migr_resources = {} if 'migr_resources' not in replica_resources_info: LOG.warn( "Replica source provider for '%s' did NOT return any " "'migr_resources'. Defaulting to %s", origin["type"], migr_resources) else: migr_resources = replica_resources_info['migr_resources'] return { "source_resources": migr_resources, "source_resources_connection_info": migr_connection_info }
def validate_endpoint_source_environment(self, ctxt, platform_name, source_env): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_EXPORT, None) source_env_schema = provider.get_source_environment_schema() is_valid = True message = None try: schemas.validate_value(source_env, source_env_schema) except exception.SchemaValidationException as ex: is_valid = False message = str(ex) return (is_valid, message)
def get_endpoint_destination_options(self, ctxt, platform_name, connection_info, env, option_names): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT_OPTIONS, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) options = provider.get_target_environment_options( ctxt, secret_connection_info, env=env, option_names=option_names) schemas.validate_value(options, schemas.CORIOLIS_DESTINATION_ENVIRONMENT) return options
def get_endpoint_networks(self, ctxt, platform_name, connection_info, env): env = env or {} provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT_NETWORKS, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) networks_info = provider.get_networks(ctxt, secret_connection_info, env) for network_info in networks_info: schemas.validate_value(network_info, schemas.CORIOLIS_VM_NETWORK_SCHEMA) return networks_info
def get_endpoint_instance(self, ctxt, platform_name, connection_info, instance_name): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT_INSTANCES, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) instance_info = provider.get_instance(ctxt, secret_connection_info, instance_name) schemas.validate_value(instance_info, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) return instance_info
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): event_manager = events.EventManager(event_handler) volumes_info = task_info.get("volumes_info", []) new_source_env = task_info.get('source_environment', {}) # NOTE: the `source_environment` in the `origin` is the one set # in the dedicated DB column of the Replica and thus stores # the previous value of it: old_source_env = origin.get('source_environment') if not new_source_env: event_manager.progress_update( "No new source environment options provided") return { 'volumes_info': volumes_info, 'source_environment': old_source_env } source_provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_SOURCE_REPLICA_UPDATE, event_handler, raise_if_not_found=False) if not source_provider: raise exception.InvalidActionTasksExecutionState( "Replica source provider plugin for '%s' does not support" " updating Replicas" % origin["type"]) origin_connection_info = base.get_connection_info(ctxt, origin) LOG.info("Checking source provider environment params") volumes_info = (source_provider.check_update_source_environment_params( ctxt, origin_connection_info, instance, volumes_info, old_source_env, new_source_env)) if volumes_info: schemas.validate_value(volumes_info, schemas.CORIOLIS_VOLUMES_INFO_SCHEMA) else: LOG.warn( "Source update method for '%s' source provider did NOT " "return any volumes info. Defaulting to old value.", origin["type"]) volumes_info = task_info.get("volumes_info", []) return { "volumes_info": volumes_info, "source_environment": new_source_env }
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_REPLICA_EXPORT, event_handler) connection_info = base.get_connection_info(ctxt, origin) source_environment = task_info['source_environment'] export_info = provider.get_replica_instance_info( ctxt, connection_info, source_environment, instance) # Validate the output schemas.validate_value(export_info, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) return {'export_info': export_info}
def validate_endpoint_target_environment(self, ctxt, platform_name, target_env): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_OS_MORPHING, None) target_env_schema = provider.get_target_environment_schema() is_valid = True message = None try: schemas.validate_value(target_env, target_env_schema) except exception.SchemaValidationException as ex: LOG.warn(utils.get_exception_details()) is_valid = False message = str(ex) return (is_valid, message)
def _validate_create_body(self, body): schedule = body.get("schedule") if schedule is None: raise exception.InvalidInput( "schedule is required") schedule = self._validate_schedule(schedule) schemas.validate_value( body, schemas.SCHEDULE_API_BODY_SCHEMA, format_checker=jsonschema.FormatChecker()) enabled = body.get("enabled", True) exp = body.get("expiration_date", None) if exp is not None: exp = self._validate_expiration_date(exp) shutdown = body.get("shutdown_instance", False) return (schedule, enabled, exp, shutdown)
def validate_endpoint_source_minion_pool_options(self, ctxt, platform_name, pool_environment): provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_SOURCE_MINION_POOL, None) pool_options_schema = provider.get_minion_pool_environment_schema() is_valid = True message = None try: schemas.validate_value(pool_environment, pool_options_schema) except exception.SchemaValidationException as ex: LOG.warn(utils.get_exception_details()) is_valid = False message = str(ex) return (is_valid, message)
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_OS_MORPHING, event_handler) connection_info = base.get_connection_info(ctxt, destination) target_environment = task_info["target_environment"] instance_deployment_info = task_info["instance_deployment_info"] import_info = provider.deploy_os_morphing_resources( ctxt, connection_info, target_environment, instance_deployment_info) schemas.validate_value( import_info, schemas.CORIOLIS_OS_MORPHING_RESOURCES_SCHEMA, # NOTE: we avoid raising so that the cleanup task # can [try] to deal with the temporary resources. raise_on_error=False) os_morphing_resources = import_info.get('os_morphing_resources') if not os_morphing_resources: raise exception.InvalidTaskResult( "Target provider for '%s' did NOT return any " "'os_morphing_resources'." % (destination["type"])) osmorphing_connection_info = import_info.get( 'osmorphing_connection_info') if not osmorphing_connection_info: raise exception.InvalidTaskResult( "Target provider '%s' did NOT return any " "'osmorphing_connection_info'." % (destination["type"])) osmorphing_connection_info = base.marshal_migr_conn_info( osmorphing_connection_info) os_morphing_info = import_info.get("osmorphing_info", {}) if not os_morphing_info: LOG.warn( "Target provider for '%s' did NOT return any " "'osmorphing_info'. Defaulting to %s", destination["type"], os_morphing_info) return { "os_morphing_resources": os_morphing_resources, "osmorphing_connection_info": osmorphing_connection_info, "osmorphing_info": os_morphing_info }
def run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( origin["type"], constants.PROVIDER_TYPE_EXPORT, event_handler) connection_info = base.get_connection_info(ctxt, origin) export_path = task_info["export_path"] export_info = provider.export_instance(ctxt, connection_info, instance, export_path) # Validate the output schemas.validate_value(export_info, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) task_info["export_info"] = export_info task_info["retain_export_path"] = True return task_info
def run(self, ctxt, instance, origin, destination, task_info, event_handler): event_manager = events.EventManager(event_handler) origin_connection_info = base.get_connection_info(ctxt, origin) origin_type = origin["type"] source_provider = providers_factory.get_provider( origin_type, constants.PROVIDER_TYPE_VALIDATE_MIGRATION_EXPORT, event_handler, raise_if_not_found=False) export_info = None if source_provider: export_info = source_provider.validate_migration_export_input( ctxt, origin_connection_info, instance, source_environment=origin.get("source_environment", {})) else: event_manager.progress_update( "Migration Export Provider for platform '%s' does not " "support Migration input validation" % origin_type) if export_info is None: source_endpoint_provider = providers_factory.get_provider( origin_type, constants.PROVIDER_TYPE_ENDPOINT_INSTANCES, event_handler, raise_if_not_found=False) if not source_endpoint_provider: event_manager.progress_update( "Migration Export Provider for platform '%s' does not " "support querying instance export info" % origin_type) return task_info export_info = source_endpoint_provider.get_instance( ctxt, origin_connection_info, instance) # validate Export info: schemas.validate_value(export_info, schemas.CORIOLIS_VM_EXPORT_INFO_SCHEMA) # NOTE: this export info will get overridden with updated values # and disk paths after the ExportInstanceTask. task_info["export_info"] = export_info return task_info
def get_endpoint_instances(self, ctxt, platform_name, connection_info, source_environment, marker, limit, instance_name_pattern): export_provider = providers_factory.get_provider( platform_name, constants.PROVIDER_TYPE_ENDPOINT_INSTANCES, None) secret_connection_info = utils.get_secret_connection_info( ctxt, connection_info) instances_info = export_provider.get_instances( ctxt, secret_connection_info, source_environment, last_seen_id=marker, limit=limit, instance_name_pattern=instance_name_pattern) for instance_info in instances_info: schemas.validate_value( instance_info, schemas.CORIOLIS_VM_INSTANCE_INFO_SCHEMA) return instances_info
def _run(self, ctxt, instance, origin, destination, task_info, event_handler): provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_REPLICA_IMPORT, event_handler) connection_info = base.get_connection_info(ctxt, destination) export_info = task_info['export_info'] volumes_info = _get_volumes_info(task_info) volumes_info = provider.restore_replica_disk_snapshots( ctxt, connection_info, volumes_info) schemas.validate_value(volumes_info, schemas.CORIOLIS_VOLUMES_INFO_SCHEMA) volumes_info = _check_ensure_volumes_info_ordering( export_info, volumes_info) return {"volumes_info": volumes_info}
def run(self, ctxt, instance, origin, destination, task_info, event_handler): event_manager = events.EventManager(event_handler) new_destination_env = task_info.get('destination_environment', {}) if not new_destination_env: event_manager.progress_update( "No new destination environment options provided") return task_info destination_provider = providers_factory.get_provider( destination["type"], constants.PROVIDER_TYPE_DESTINATION_REPLICA_UPDATE, event_handler, raise_if_not_found=False) if not destination_provider: raise exception.CoriolisException( "Replica destination provider plugin for '%s' does not " "support updating Replicas" % destination["type"]) destination_connection_info = base.get_connection_info( ctxt, destination) export_info = task_info.get("export_info", {}) volumes_info = task_info.get("volumes_info", {}) LOG.info("Checking destination provider environment params") # NOTE: the `target_environment` in the `destination` is the one # set in the dedicated DB column of the Replica and thus stores # the previous value of it: old_destination_env = destination.get('target_environment', {}) volumes_info = ( destination_provider.check_update_destination_environment_params( ctxt, destination_connection_info, export_info, volumes_info, old_destination_env, new_destination_env)) schemas.validate_value(volumes_info, schemas.CORIOLIS_VOLUMES_INFO_SCHEMA) volumes_info = _check_ensure_volumes_info_ordering( export_info, volumes_info) task_info['volumes_info'] = volumes_info return task_info