def checkpoints_index(self, req, provider_id): """Returns a list of checkpoints, transformed through view builder.""" context = req.environ['karbor.context'] LOG.info(_LI("Show checkpoints list. " "provider_id:%s"), provider_id) params = req.params.copy() marker, limit, offset = common.get_pagination_params(params) sort_keys, sort_dirs = common.get_sort_params(params) filters = params utils.remove_invalid_filter_options( context, filters, self._get_checkpoint_filter_options()) utils.check_filters(filters) checkpoints = self._checkpoints_get_all( context, provider_id, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset) retval_checkpoints = self._checkpoint_view_builder.detail_list( req, checkpoints) LOG.info(_LI("Show checkpoints list request issued successfully.")) return retval_checkpoints
def show(self, req, id): """Return data about the given protectable_type.""" context = req.environ['karbor.context'] protectable_type = id LOG.info( _LI("Show the information of a given" " protectable type: %s"), protectable_type) protectable_types = self._get_all(context) if protectable_type not in protectable_types: msg = _("Invalid protectable type provided.") raise exception.InvalidInput(reason=msg) check_policy(context, 'get') try: retval_protectable_type = self.protection_api.\ show_protectable_type(context, protectable_type) except exception.ProtectableTypeNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) LOG.info( _LI("Show the protectable type information" " issued successfully.")) return self._view_builder.show(req, retval_protectable_type)
def index(self, req): """Returns a list of restores, transformed through view builder.""" context = req.environ['karbor.context'] LOG.info(_LI("Show restore list"), context=context) params = req.params.copy() marker, limit, offset = common.get_pagination_params(params) sort_keys, sort_dirs = common.get_sort_params(params) filters = params utils.remove_invalid_filter_options( context, filters, self._get_restore_filter_options()) utils.check_filters(filters) restores = self._get_all(context, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset) retval_restores = self._view_builder.detail_list(req, restores) LOG.info(_LI("Show restore list request issued successfully.")) return retval_restores
def _sync_status(self, checkpoint, status_getters): statuses = set() for s in status_getters: resource_id = s.get('resource_id') get_resource_stats = s.get('get_resource_stats') statuses.add(get_resource_stats(checkpoint, resource_id)) LOG.info( _LI("Start sync checkpoint status,checkpoint_id:" "%(checkpoint_id)s, resource_status:" "%(resource_status)s") % { "checkpoint_id": checkpoint.id, "resource_status": statuses }) if constants.RESOURCE_STATUS_ERROR in statuses: checkpoint.status = constants.CHECKPOINT_STATUS_ERROR_DELETING checkpoint.commit() raise loopingcall.LoopingCallDone() elif statuses == { constants.RESOURCE_STATUS_DELETED, }: checkpoint.delete() LOG.info( _LI("Stop sync checkpoint status,checkpoint_id: " "%(checkpoint_id)s,checkpoint status: " "%(checkpoint_status)s"), { "checkpoint_id": checkpoint.id, "checkpoint_status": checkpoint.status }) raise loopingcall.LoopingCallDone()
def __exit__(self, ex_type, ex_value, ex_traceback): if not ex_value: return True if isinstance(ex_value, exception.NotAuthorized): raise Fault(webob.exc.HTTPForbidden(explanation=ex_value.msg)) elif isinstance(ex_value, exception.Invalid): raise Fault( exception.ConvertedException(code=ex_value.code, explanation=ex_value.msg)) elif isinstance(ex_value, TypeError): exc_info = (ex_type, ex_value, ex_traceback) LOG.error(_LE('Exception handling resource: %s'), ex_value, exc_info=exc_info) raise Fault(webob.exc.HTTPBadRequest()) elif isinstance(ex_value, Fault): LOG.info(_LI("Fault thrown: %s"), ex_value) raise ex_value elif isinstance(ex_value, webob.exc.HTTPException): LOG.info(_LI("HTTP exception thrown: %s"), ex_value) raise Fault(ex_value) # We didn't handle the exception return False
def show(self, req, id): """Return data about the given provider id.""" context = req.environ['karbor.context'] LOG.info(_LI("Show provider with id: %s"), id) try: provider = self._provider_get(context, id) except exception.ProviderNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) LOG.info(_LI("Show provider request issued successfully."), resource={'id': provider.get("id")}) return self._view_builder.detail(req, provider)
def delete(self, req, id): """Delete a plan.""" context = req.environ['karbor.context'] LOG.info(_LI("Delete plan with id: %s"), id, context=context) try: plan = self._plan_get(context, id) except exception.PlanNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) check_policy(context, 'delete', plan) plan.destroy() LOG.info(_LI("Delete plan request issued successfully."), resource={'id': plan.id})
def index(self, req): """Returns a list of protectable_types, transformed through view builder. """ context = req.environ['karbor.context'] LOG.info(_LI("Show protectable type list"), context=context) protectable_types = self._get_all(context) retval_protectable_types = {"protectable_type": protectable_types} LOG.info( _LI("Show protectable type list request issued" " successfully.")) return retval_protectable_types
def _plan_update(self, context, plan, fields): if plan['status'] != constants.PLAN_STATUS_SUSPENDED: LOG.info(_LI("Unable to update plan, " "because it is in %s state."), plan['status']) msg = _("The plan can be only updated in suspended status.") raise exception.InvalidPlan(reason=msg) # TODO(chenying) replication scene: need call rpc API when # the status of the plan is changed. if isinstance(plan, objects_base.KarborObject): plan.update(fields) plan.save() LOG.info(_LI("Plan updated successfully."), resource=plan) else: msg = _("The parameter plan must be a object of " "KarborObject class.") raise exception.InvalidInput(reason=msg)
def create(context, conf): register_opts(conf) if hasattr(conf.swift_client, 'swift_auth_url') and \ conf.swift_client.swift_auth_url: connection = swift.Connection( authurl=conf.swift_client.swift_auth_url, auth_version=conf.swift_client.swift_auth_version, tenant_name=conf.swift_client.swift_tenant_name, user=conf.swift_client.swift_user, key=conf.swift_client.swift_key, retries=conf.swift_client.swift_retry_attempts, starting_backoff=conf.swift_client.swift_retry_backoff, insecure=conf.swift_client.swift_auth_insecure, cacert=conf.swift_client.swift_ca_cert_file) else: try: url = utils.get_url(SERVICE, context, conf, append_project_fmt='%(url)s/AUTH_%(project)s') except Exception: LOG.error(_LE("Get swift service endpoint url failed")) raise LOG.info(_LI("Creating swift client with url %s."), url) connection = swift.Connection( preauthurl=url, preauthtoken=context.auth_token, retries=conf.swift_client.swift_retry_attempts, starting_backoff=conf.swift_client.swift_retry_backoff, insecure=conf.swift_client.swift_auth_insecure, cacert=conf.swift_client.swift_ca_cert_file) return connection
def sync_status(self): for resource_id, resource_info in self.protection_resource_map.items(): backup_id = resource_info["backup_id"] bank_section = resource_info["bank_section"] cinder_client = resource_info["cinder_client"] operation = resource_info["operation"] try: backup = cinder_client.backups.get(backup_id) if backup.status == "available": bank_section.update_object( "status", constants.RESOURCE_STATUS_AVAILABLE) self.protection_resource_map.pop(resource_id) elif backup.status in ["error", "error-deleting"]: bank_section.update_object( "status", constants.RESOURCE_STATUS_ERROR) self.protection_resource_map.pop(resource_id) else: continue except Exception as exc: if operation == "delete" and type(exc) == NotFound: bank_section.update_object( "status", constants.RESOURCE_STATUS_DELETED) LOG.info(_LI("deleting volume backup finished, " "backup id: %s"), backup_id) else: LOG.error(_LE("deleting volume backup error.exc: %s"), six.text_type(exc)) self.protection_resource_map.pop(resource_id)
def delete_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") resource_id = resource_node.value.id bank_section = checkpoint.get_resource_bank_section(resource_id) cinder_client = self._cinder_client(cntxt) LOG.info(_LI("deleting volume backup, volume_id: %s."), resource_id) try: bank_section.update_object("status", constants.RESOURCE_STATUS_DELETING) resource_definition = bank_section.get_object("metadata") backup_id = resource_definition["backup_id"] cinder_client.backups.delete(backup_id) bank_section.delete_object("metadata") self.protection_resource_map[resource_id] = { "bank_section": bank_section, "backup_id": backup_id, "cinder_client": cinder_client, "operation": "delete" } except Exception as e: LOG.error(_LE("delete volume backup failed, volume_id: %s."), resource_id) bank_section.update_object("status", constants.CHECKPOINT_STATUS_ERROR) raise exception.DeleteBackupFailed( reason=six.text_type(e), resource_id=resource_id, resource_type=constants.VOLUME_RESOURCE_TYPE )
def _sync_status(self, checkpoint, status_getters): statuses = set() for s in status_getters: resource_id = s.get('resource_id') get_resource_stats = s.get('get_resource_stats') statuses.add(get_resource_stats(checkpoint, resource_id)) if constants.RESOURCE_STATUS_ERROR in statuses: checkpoint.status = constants.CHECKPOINT_STATUS_ERROR checkpoint.commit() elif constants.RESOURCE_STATUS_PROTECTING in statuses: checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() elif constants.RESOURCE_STATUS_UNDEFINED in statuses: checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() else: checkpoint.status = constants.CHECKPOINT_STATUS_AVAILABLE checkpoint.commit() LOG.info( _LI("Stop sync checkpoint status,checkpoint_id: " "%(checkpoint_id)s,checkpoint status: " "%(checkpoint_status)s"), { "checkpoint_id": checkpoint.id, "checkpoint_status": checkpoint.status }) raise loopingcall.LoopingCallDone()
def delete(self, context, provider_id, checkpoint_id): LOG.info(_LI("Starting protection service:delete action")) LOG.debug('provider_id :%s checkpoint_id:%s', provider_id, checkpoint_id) provider = self.provider_registry.show_provider(provider_id) try: checkpoint_collection = provider.get_checkpoint_collection() checkpoint = checkpoint_collection.get(checkpoint_id) except Exception: LOG.error(_LE("get checkpoint failed, checkpoint_id:%s"), checkpoint_id) raise exception.InvalidInput( reason=_("Invalid checkpoint_id or provider_id")) if checkpoint.status not in [ constants.CHECKPOINT_STATUS_AVAILABLE, constants.CHECKPOINT_STATUS_ERROR, ]: raise exception.CheckpointNotBeDeleted(checkpoint_id=checkpoint_id) checkpoint.status = constants.CHECKPOINT_STATUS_DELETING checkpoint.commit() try: delete_checkpoint_flow = self.worker.get_delete_checkpoint_flow( context, constants.OPERATION_DELETE, checkpoint, provider) except Exception: LOG.exception( _LE("Failed to create delete checkpoint flow, checkpoint:%s."), checkpoint_id) raise exception.KarborException( _("Failed to create delete checkpoint flow.")) self._spawn(self.worker.run_flow, delete_checkpoint_flow)
def create_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") image_id = resource_node.value.id bank_section = checkpoint.get_resource_bank_section(image_id) resource_definition = {"resource_id": image_id} glance_client = self._glance_client(cntxt) LOG.info(_LI("creating image backup, image_id: %s."), image_id) try: bank_section.create_object("status", constants.RESOURCE_STATUS_PROTECTING) image_info = glance_client.images.get(image_id) image_metadata = { "disk_format": image_info.disk_format, "container_format": image_info.container_format } resource_definition["image_metadata"] = image_metadata resource_definition["backup_id"] = image_id bank_section.create_object("metadata", resource_definition) except Exception as err: LOG.error(_LE("create image backup failed, image_id: %s."), image_id) bank_section.update_object("status", constants.RESOURCE_STATUS_ERROR) raise exception.CreateBackupFailed( reason=err, resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE) self._add_to_threadpool(self._create_backup, glance_client, bank_section, image_id)
def _get_all(self, context): check_policy(context, 'get_all') protectable_types = self.protection_api.list_protectable_types(context) LOG.info(_LI("Get all protectable types completed successfully.")) return protectable_types
def create(context, conf): conf.register_opts(nova_client_opts, group=SERVICE + '_client') try: url = utils.get_url(SERVICE, context, conf, append_project_fmt='%(url)s/%(project)s') except Exception: LOG.error(_LE("Get nova service endpoint url failed.")) raise LOG.info(_LI('Creating nova client with url %s.'), url) extensions = nc.discover_extensions(NOVACLIENT_VERSION) args = { 'project_id': context.project_id, 'auth_token': context.auth_token, 'extensions': extensions, 'cacert': conf.nova_client.nova_ca_cert_file, 'insecure': conf.nova_client.nova_auth_insecure, } client = nc.Client(NOVACLIENT_VERSION, **args) client.client.set_management_url(url) return client
def restore(self, context, restore, restore_auth): LOG.info(_LI("Starting restore service:restore action")) checkpoint_id = restore["checkpoint_id"] provider_id = restore["provider_id"] provider = self.provider_registry.show_provider(provider_id) if not provider: raise exception.ProviderNotFound(provider_id=provider_id) checkpoint_collection = provider.get_checkpoint_collection() checkpoint = checkpoint_collection.get(checkpoint_id) if checkpoint.status != constants.CHECKPOINT_STATUS_AVAILABLE: raise exception.CheckpointNotAvailable( checkpoint_id=checkpoint_id) try: restoration_flow = self.worker.get_restoration_flow( context, constants.OPERATION_RESTORE, checkpoint, provider, restore, restore_auth) except Exception: LOG.exception( _LE("Failed to create restoration flow checkpoint: %s"), checkpoint_id) raise exception.FlowError( flow="restore", error=_("Failed to create flow")) self._spawn(self.worker.run_flow, restoration_flow)
def list_protectable_instances(self, context, protectable_type=None, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None, parameters=None): LOG.info(_LI("Start to list protectable instances of type: %s"), protectable_type) try: resource_instances = self.protectable_registry.list_resources( context, protectable_type, parameters) except exception.ListProtectableResourceFailed as err: LOG.error(_LE("List resources of type %(type)s failed: %(err)s"), {'type': protectable_type, 'err': six.text_type(err)}) raise result = [] for resource in resource_instances: result.append(dict(id=resource.id, name=resource.name)) return result
def show_protectable_instance(self, context, protectable_type, protectable_id, parameters=None): LOG.info(_LI("Start to show protectable instance of type: %s"), protectable_type) try: resource_instance = \ self.protectable_registry.show_resource(context, protectable_type, protectable_id, parameters=parameters) except exception.ListProtectableResourceFailed as err: LOG.error( _LE("Show resources of type %(type)s id %(id)s " "failed: %(err)s"), { 'type': protectable_type, 'id': protectable_id, 'err': six.text_type(err) }) raise return dict(id=resource_instance.id, name=resource_instance.name, type=resource_instance.type)
def list_protectable_dependents(self, context, protectable_id, protectable_type): LOG.info( _LI("Start to list dependents of resource " "(type:%(type)s, id:%(id)s)"), { 'type': protectable_type, 'id': protectable_id }) parent_resource = Resource(type=protectable_type, id=protectable_id, name="") try: dependent_resources = \ self.protectable_registry.fetch_dependent_resources( context, parent_resource) except exception.ListProtectableResourceFailed as err: LOG.error( _LE("List dependent resources of (%(res)s) " "failed: %(err)s"), { 'res': parent_resource, 'err': six.text_type(err) }) raise result = [] for resource in dependent_resources: result.append( dict(type=resource.type, id=resource.id, name=resource.name)) return result
def list_protectable_instances(self, context, protectable_type=None, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None, parameters=None): LOG.info(_LI("Start to list protectable instances of type: %s"), protectable_type) try: resource_instances = self.protectable_registry.list_resources( context, protectable_type, parameters) except exception.ListProtectableResourceFailed as err: LOG.error(_LE("List resources of type %(type)s failed: %(err)s"), { 'type': protectable_type, 'err': six.text_type(err) }) raise result = [] for resource in resource_instances: result.append(dict(id=resource.id, name=resource.name)) return result
def list_checkpoints(self, context, provider_id, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None): LOG.info(_LI("Starting list checkpoints. " "provider_id:%s"), provider_id) plan_id = filters.get("plan_id", None) start_date = None end_date = None if filters.get("start_date", None): start_date = datetime.strptime(filters.get("start_date"), "%Y-%m-%d") if filters.get("end_date", None): end_date = datetime.strptime(filters.get("end_date"), "%Y-%m-%d") sort_dir = None if sort_dirs is None else sort_dirs[0] provider = self.provider_registry.show_provider(provider_id) checkpoint_ids = provider.list_checkpoints(limit=limit, marker=marker, plan_id=plan_id, start_date=start_date, end_date=end_date, sort_dir=sort_dir) checkpoints = [] for checkpoint_id in checkpoint_ids: checkpoint = provider.get_checkpoint(checkpoint_id) checkpoints.append(checkpoint.to_dict()) return checkpoints
def restore(self, context, restore, restore_auth): LOG.info(_LI("Starting restore service:restore action")) checkpoint_id = restore["checkpoint_id"] provider_id = restore["provider_id"] provider = self.provider_registry.show_provider(provider_id) try: checkpoint_collection = provider.get_checkpoint_collection() checkpoint = checkpoint_collection.get(checkpoint_id) except Exception: LOG.error(_LE("Invalid checkpoint id: %s"), checkpoint_id) raise exception.InvalidInput(reason=_("Invalid checkpoint id")) if checkpoint.status != constants.CHECKPOINT_STATUS_AVAILABLE: raise exception.CheckpointNotAvailable(checkpoint_id=checkpoint_id) try: restoration_flow = self.worker.get_restoration_flow( context, constants.OPERATION_RESTORE, checkpoint, provider, restore, restore_auth) except Exception: LOG.exception( _LE("Failed to create restoration flow checkpoint: %s"), checkpoint_id) raise exception.FlowError(flow="restore", error=_("Failed to create flow")) try: self.worker.run_flow(restoration_flow) except Exception: LOG.exception(_LE("Failed to run restoration flow checkpoint: %s"), checkpoint_id) raise exception.FlowError(flow="restore", error=_("Failed to run flow"))
def list_protectable_dependents(self, context, protectable_id, protectable_type): LOG.info(_LI("Start to list dependents of resource " "(type:%(type)s, id:%(id)s)"), {'type': protectable_type, 'id': protectable_id}) parent_resource = Resource(type=protectable_type, id=protectable_id, name="") try: dependent_resources = \ self.protectable_registry.fetch_dependent_resources( context, parent_resource) except exception.ListProtectableResourceFailed as err: LOG.error(_LE("List dependent resources of (%(res)s) " "failed: %(err)s"), {'res': parent_resource, 'err': six.text_type(err)}) raise result = [] for resource in dependent_resources: result.append(dict(type=resource.type, id=resource.id, name=resource.name)) return result
def instances_show(self, req, protectable_type, protectable_id): """Return a instance about the given protectable_type and id.""" context = req.environ['karbor.context'] params = req.params.copy() utils.check_filters(params) parameters = params.get("parameters", None) LOG.info(_LI("Show the instance of a given protectable" " type: %s"), protectable_type) if parameters is not None: if not isinstance(parameters, dict): msg = _("The parameters must be a dict.") raise exception.InvalidInput(reason=msg) protectable_types = self._get_all(context) if protectable_type not in protectable_types: msg = _("Invalid protectable type provided.") raise exception.InvalidInput(reason=msg) instance = self.protection_api.\ show_protectable_instance(context, protectable_type, protectable_id, parameters=parameters) if instance is None: raise exception.InvalidProtectableInstance() dependents = self.protection_api.\ list_protectable_dependents(context, protectable_id, protectable_type) instance["dependent_resources"] = dependents retval_instance = self._view_builder.detail(req, instance) return retval_instance
def delete_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") image_id = resource_node.value.id bank_section = checkpoint.get_resource_bank_section(image_id) LOG.info(_LI("deleting image backup failed, image_id: %s."), image_id) try: bank_section.update_object("status", constants.RESOURCE_STATUS_DELETING) objects = bank_section.list_objects() for obj in objects: if obj == "status": continue bank_section.delete_object(obj) bank_section.update_object("status", constants.RESOURCE_STATUS_DELETED) except Exception as err: LOG.error(_LE("delete image backup failed, image_id: %s."), image_id) bank_section.update_object("status", constants.RESOURCE_STATUS_ERROR) raise exception.DeleteBackupFailed( reason=err, resource_id=image_id, resource_type=constants.IMAGE_RESOURCE_TYPE)
def _instances_get_all(self, context, protectable_type, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None, offset=None, parameters=None): check_policy(context, 'get_all') if filters is None: filters = {} try: if limit is not None: limit = int(limit) if limit <= 0: msg = _('limit param must be positive') raise exception.InvalidInput(reason=msg) except ValueError: msg = _('limit param must be an integer') raise exception.InvalidInput(reason=msg) if filters: LOG.debug("Searching by: %s.", six.text_type(filters)) instances = self.protection_api.list_protectable_instances( context, protectable_type, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset, parameters=parameters) LOG.info(_LI("Get all instances completed successfully.")) return instances
def delete_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get("node") resource_id = resource_node.value.id bank_section = checkpoint.get_resource_bank_section(resource_id) cinder_client = self._cinder_client(cntxt) LOG.info(_LI("deleting volume backup, volume_id: %s."), resource_id) try: bank_section.update_object("status", constants.RESOURCE_STATUS_DELETING) resource_definition = bank_section.get_object("metadata") backup_id = resource_definition["backup_id"] cinder_client.backups.delete(backup_id) bank_section.delete_object("metadata") self.protection_resource_map[resource_id] = { "bank_section": bank_section, "backup_id": backup_id, "cinder_client": cinder_client, "operation": "delete" } except Exception as e: LOG.error(_LE("delete volume backup failed, volume_id: %s."), resource_id) bank_section.update_object("status", constants.CHECKPOINT_STATUS_ERROR) raise exception.DeleteBackupFailed( reason=six.text_type(e), resource_id=resource_id, resource_type=constants.VOLUME_RESOURCE_TYPE)
def create_heat_client_with_tenant(context, conf): cacert = conf.heat_client.heat_ca_cert_file insecure = conf.heat_client.heat_auth_insecure conf.register_opts(heat_client_opts, group=SERVICE + '_client') try: url = utils.get_url(SERVICE, context, conf, append_project_fmt='%(url)s/%(project)s') except Exception: LOG.error(_LE("Get heat service endpoint url failed.")) raise try: LOG.info(_LI('Creating heat client with url %s.'), url) heat = hc.Client(HEATCLIENT_VERSION, endpoint=url, token=context.auth_token, cacert=cacert, insecure=insecure) return heat except Exception: LOG.error(_LE('Creating heat client with endpoint fails.')) raise
def sync_status(self): for resource_id, resource_info in self.protection_resource_map.items(): backup_id = resource_info["backup_id"] bank_section = resource_info["bank_section"] cinder_client = resource_info["cinder_client"] operation = resource_info["operation"] try: backup = cinder_client.backups.get(backup_id) if backup.status == "available": bank_section.update_object( "status", constants.RESOURCE_STATUS_AVAILABLE) self.protection_resource_map.pop(resource_id) elif backup.status in ["error", "error-deleting"]: bank_section.update_object("status", constants.RESOURCE_STATUS_ERROR) self.protection_resource_map.pop(resource_id) else: continue except Exception as exc: if operation == "delete" and type(exc) == NotFound: bank_section.update_object( "status", constants.RESOURCE_STATUS_DELETED) LOG.info( _LI("deleting volume backup finished, " "backup id: %s"), backup_id) else: LOG.error(_LE("deleting volume backup error.exc: %s"), six.text_type(exc)) self.protection_resource_map.pop(resource_id)
def create_heat_client_with_auth_url(context, conf, **kwargs): auth_url = kwargs["auth_url"] username = kwargs["username"] password = kwargs["password"] tenant_name = context.project_name cacert = conf.heat_client.heat_ca_cert_file insecure = conf.heat_client.heat_auth_insecure LOG.info(_LI('Creating heat client with auth url %s.'), auth_url) try: keystone = kc_v3.Client(version=KEYSTONECLIENT_VERSION, username=username, tenant_name=tenant_name, password=password, auth_url=auth_url) auth_token = keystone.auth_token heat_endpoint = '' services = keystone.service_catalog.catalog['catalog'] for service in services: if service['name'] == 'heat': endpoints = service['endpoints'] for endpoint in endpoints: if endpoint['interface'] == 'public': heat_endpoint = endpoint['url'] heat = hc.Client(HEATCLIENT_VERSION, endpoint=heat_endpoint, token=auth_token, cacert=cacert, insecure=insecure) return heat except Exception: LOG.error(_LE('Creating heat client with url %s.'), auth_url) raise
def _checkpoints_get_all(self, context, provider_id, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None, offset=None): check_policy(context, 'checkpoint_get_all') if filters is None: filters = {} try: if limit is not None: limit = int(limit) if limit <= 0: msg = _('limit param must be positive') raise exception.InvalidInput(reason=msg) except ValueError: msg = _('limit param must be an integer') raise exception.InvalidInput(reason=msg) if filters: LOG.debug("Searching by: %s.", six.text_type(filters)) checkpoints = self.protection_api.list_checkpoints( context, provider_id, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset) LOG.info(_LI("Get all checkpoints completed successfully.")) return checkpoints
def index(self, req): """Returns a list of protectable_types, transformed through view builder. """ context = req.environ['karbor.context'] LOG.info(_LI("Show protectable type list"), context=context) protectable_types = self._get_all(context) retval_protectable_types = { "protectable_type": protectable_types } LOG.info(_LI("Show protectable type list request issued" " successfully.")) return retval_protectable_types
def _sync_status(self, heat_client, stack_id): try: stack = heat_client.stacks.get(stack_id) except Exception: LOG.debug('Heat error getting stack, stack_id: %s', stack_id) raise stack_status = getattr(stack, 'stack_status') if stack_status == 'CREATE_IN_PROGRESS': LOG.debug('Heat stack status: in progress, stack_id: %s', stack_id) return if stack_status == 'CREATE_COMPLETE': LOG.info(_LI('Heat stack status: complete, stack_id: %s'), stack_id) else: LOG.info(_LI('Heat stack status: failure, stack_id: %s'), stack_id) raise raise loopingcall.LoopingCallDone()
def _plan_update(self, context, plan, fields): if plan['status'] != constants.PLAN_STATUS_SUSPENDED: LOG.info( _LI("Unable to update plan, " "because it is in %s state."), plan['status']) msg = _("The plan can be only updated in suspended status.") raise exception.InvalidPlan(reason=msg) # TODO(chenying) replication scene: need call rpc API when # the status of the plan is changed. if isinstance(plan, objects_base.KarborObject): plan.update(fields) plan.save() LOG.info(_LI("Plan updated successfully."), resource=plan) else: msg = _("The parameter plan must be a object of " "KarborObject class.") raise exception.InvalidInput(reason=msg)
def show(self, req, id): """Return data about the given restore.""" context = req.environ['karbor.context'] LOG.info(_LI("Show restore with id: %s"), id, context=context) if not uuidutils.is_uuid_like(id): msg = _("Invalid restore id provided.") raise exc.HTTPBadRequest(explanation=msg) try: restore = self._restore_get(context, id) except exception.RestoreNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) LOG.info(_LI("Show restore request issued successfully."), resource={'id': restore.id}) return self._view_builder.detail(req, restore)
def checkpoints_show(self, req, provider_id, checkpoint_id): """Return data about the given checkpoint id.""" context = req.environ['karbor.context'] LOG.info(_LI("Show checkpoint with id: %s."), checkpoint_id) LOG.info(_LI("provider_id: %s."), provider_id) try: checkpoint = self._checkpoint_get(context, provider_id, checkpoint_id) except exception.CheckpointNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) LOG.info(_LI("Show checkpoint request issued successfully.")) LOG.info(_LI("checkpoint: %s"), checkpoint) retval = self._checkpoint_view_builder.detail(req, checkpoint) LOG.info(_LI("retval: %s"), retval) return retval
def execute(self, context, heat_conf): LOG.info(_LI('Creating Heat template. Target: "%s"') % heat_conf.get('auth_url', '(None)')) heat_client = client_factory.ClientFactory.create_client( 'heat', context=context, **heat_conf) heat_template = restore_heat.HeatTemplate() return (heat_client, heat_template)
def execute(self, heat_client, heat_template): stack_name = "restore_%s" % uuidutils.generate_uuid() LOG.info(_LI('Creating Heat stack, stack_name: %s'), stack_name) try: body = heat_client.stacks.create( stack_name=stack_name, template=heat_template.to_dict()) LOG.debug('Created stack with id: %s', body['stack']['id']) return body['stack']['id'] except Exception: LOG.error(_LE("use heat to create stack failed")) raise
def build_resource_flow(operation_type, context, workflow_engine, plugins, resource_graph, parameters): LOG.info(_LI("Build resource flow for operation %s"), operation_type) resource_graph_flow = workflow_engine.build_flow("ResourceGraphFlow_{}".format(operation_type), "graph") resource_walker = ResourceFlowGraphWalkerListener( resource_graph_flow, operation_type, context, parameters, plugins, workflow_engine ) walker = graph.GraphWalker() walker.register_listener(resource_walker) LOG.debug("Starting resource graph walk (operation %s)", operation_type) walker.walk_graph(resource_graph) LOG.debug("Finished resource graph walk (operation %s)", operation_type) return resource_graph_flow
def _plan_get(self, context, plan_id): if not uuidutils.is_uuid_like(plan_id): msg = _("Invalid plan id provided.") raise exc.HTTPBadRequest(explanation=msg) plan = objects.Plan.get_by_id(context, plan_id) try: check_policy(context, 'get', plan) except exception.PolicyNotAuthorized: # raise PlanNotFound instead to make sure karbor behaves # as it used to raise exception.PlanNotFound(plan_id=plan_id) LOG.info(_LI("Plan info retrieved successfully."), resource=plan) return plan
def checkpoints_delete(self, req, provider_id, checkpoint_id): """Delete a checkpoint.""" context = req.environ['karbor.context'] LOG.info(_LI("Delete checkpoint with id: %s."), checkpoint_id) LOG.info(_LI("provider_id: %s."), provider_id) if not uuidutils.is_uuid_like(provider_id): msg = _("Invalid provider id provided.") raise exc.HTTPBadRequest(explanation=msg) if not uuidutils.is_uuid_like(checkpoint_id): msg = _("Invalid checkpoint id provided.") raise exc.HTTPBadRequest(explanation=msg) check_policy(context, 'checkpoint_delete') self.protection_api.delete(context, provider_id, checkpoint_id) LOG.info(_LI("Delete checkpoint request issued successfully.")) return {}
def wait(self): """Block, until the server has stopped. Waits on the server's eventlet to finish, then returns. :returns: None """ try: if self._server is not None: self._pool.waitall() self._server.wait() except greenlet.GreenletExit: LOG.info(_LI("WSGI server has stopped."))
def stop(self): """Stop this server. This is not a very nice action, as currently the method by which a server is stopped is by killing its eventlet. :returns: None """ LOG.info(_LI("Stopping WSGI server.")) if self._server is not None: # Resize pool to stop new requests from being processed self._pool.resize(0) self._server.kill()
def _restore_get(self, context, restore_id): if not uuidutils.is_uuid_like(restore_id): msg = _("Invalid restore id provided.") raise exc.HTTPBadRequest(explanation=msg) restore = objects.Restore.get_by_id(context, restore_id) try: check_policy(context, 'get', restore) except exception.PolicyNotAuthorized: # raise RestoreNotFound instead to make sure karbor behaves # as it used to raise exception.RestoreNotFound(restore_id=restore_id) LOG.info(_LI("Restore info retrieved successfully.")) return restore
def restore_backup(self, cntxt, checkpoint, **kwargs): resource_node = kwargs.get('node') original_image_id = resource_node.value.id heat_template = kwargs.get("heat_template") name = kwargs.get("restore_name", "karbor-restore-image") LOG.info(_LI("restoring image backup, image_id: %s."), original_image_id) glance_client = self._glance_client(cntxt) bank_section = checkpoint.get_resource_bank_section(original_image_id) try: resource_definition = bank_section.get_object('metadata') image_metadata = resource_definition['image_metadata'] objects = [key.split("/")[-1] for key in bank_section.list_objects()] # get image_data image_data = BytesIO() for obj in objects: if obj.find("data_") == 0: data = bank_section.get_object(obj) image_data.write(data) image_data.seek(0, os.SEEK_SET) disk_format = image_metadata["disk_format"] container_format = image_metadata["container_format"] image = glance_client.images.create( disk_format=disk_format, container_format=container_format, name=name) glance_client.images.upload(image.id, image_data) image_info = glance_client.images.get(image.id) retry_attempts = CONF.retry_attempts while image_info.status != "active" and retry_attempts != 0: sleep(60) image_info = glance_client.images.get(image.id) retry_attempts -= 1 if retry_attempts == 0: raise Exception heat_template.put_parameter(original_image_id, image.id) except Exception as e: LOG.error(_LE("restore image backup failed, image_id: %s."), original_image_id) raise exception.RestoreBackupFailed( reason=e, resource_id=original_image_id, resource_type=constants.IMAGE_RESOURCE_TYPE )
def __exit__(self, ex_type, ex_value, ex_traceback): if not ex_value: return True if isinstance(ex_value, exception.NotAuthorized): raise Fault(webob.exc.HTTPForbidden(explanation=ex_value.msg)) elif isinstance(ex_value, exception.Invalid): raise Fault(exception.ConvertedException( code=ex_value.code, explanation=ex_value.msg)) elif isinstance(ex_value, TypeError): exc_info = (ex_type, ex_value, ex_traceback) LOG.error(_LE( 'Exception handling resource: %s'), ex_value, exc_info=exc_info) raise Fault(webob.exc.HTTPBadRequest()) elif isinstance(ex_value, Fault): LOG.info(_LI("Fault thrown: %s"), ex_value) raise ex_value elif isinstance(ex_value, webob.exc.HTTPException): LOG.info(_LI("HTTP exception thrown: %s"), ex_value) raise Fault(ex_value) # We didn't handle the exception return False