def check_string_length(value, name, min_length=0, max_length=None): """Check the length of specified string. :param value: the value of the string :param name: the name of the string :param min_length: the min_length of the string :param max_length: the max_length of the string """ if not isinstance(value, six.string_types): msg = _("%s is not a string or unicode") % name raise exception.InvalidInput(message=msg) if len(value) < min_length: msg = _("%(name)s has a minimum character requirement of " "%(min_length)s.") % { 'name': name, 'min_length': min_length } raise exception.InvalidInput(message=msg) if max_length and len(value) > max_length: msg = _("%(name)s has more than %(max_length)s " "characters.") % { 'name': name, 'max_length': max_length } raise exception.InvalidInput(message=msg)
def validate_integer(value, name, min_value=None, max_value=None): """Make sure that value is a valid integer, potentially within range. :param value: the value of the integer :param name: the name of the integer :param min_length: the min_length of the integer :param max_length: the max_length of the integer :returns: integer """ try: value = int(value) except (TypeError, ValueError, UnicodeEncodeError): raise webob.exc.HTTPBadRequest( explanation=(_('%s must be an integer.') % name)) if min_value is not None and value < min_value: raise webob.exc.HTTPBadRequest( explanation=(_('%(value_name)s must be >= %(min_value)d') % { 'value_name': name, 'min_value': min_value })) if max_value is not None and value > max_value: raise webob.exc.HTTPBadRequest( explanation=(_('%(value_name)s must be <= %(max_value)d') % { 'value_name': name, 'max_value': max_value })) return value
def create(self, req, body): """Creates a new restore.""" if not self.is_valid_body(body, 'restore'): raise exc.HTTPUnprocessableEntity() LOG.debug('Create restore request body: %s', body) context = req.environ['smaug.context'] check_policy(context, 'create') restore = body['restore'] LOG.debug('Create restore request : %s', restore) if not restore.get("provider_id"): msg = _("provider_id must be provided when creating " "a restore.") raise exception.InvalidInput(reason=msg) if not restore.get("checkpoint_id"): msg = _("checkpoint_id must be provided when creating " "a restore.") raise exception.InvalidInput(reason=msg) parameters = restore.get("parameters") if not isinstance(parameters, dict): msg = _("parameters must be a dict when creating" " a restore.") raise exception.InvalidInput(reason=msg) restore_properties = { 'project_id': context.project_id, 'provider_id': restore.get('provider_id'), 'checkpoint_id': restore.get('checkpoint_id'), 'restore_target': restore.get('restore_target'), 'parameters': jsonutils.dumps(parameters), 'status': 'started', } restoreobj = objects.Restore(context=context, **restore_properties) restoreobj.create() LOG.debug('call restore RPC : restoreobj:%s', restoreobj) # call restore rpc API of protection service result = self.protection_api.restore(context, restoreobj) if result is True: status_update = "success" else: status_update = "failed" # update the status of restore update_dict = { "status": status_update } check_policy(context, 'update', restoreobj) self._restore_update(context, restoreobj.get("id"), update_dict) restoreobj.update(update_dict) retval = self._view_builder.detail(req, restoreobj) return retval
def validate_integer(value, name, min_value=None, max_value=None): """Make sure that value is a valid integer, potentially within range. :param value: the value of the integer :param name: the name of the integer :param min_length: the min_length of the integer :param max_length: the max_length of the integer :returns: integer """ try: value = int(value) except (TypeError, ValueError, UnicodeEncodeError): raise webob.exc.HTTPBadRequest(explanation=( _('%s must be an integer.') % name)) if min_value is not None and value < min_value: raise webob.exc.HTTPBadRequest( explanation=(_('%(value_name)s must be >= %(min_value)d') % {'value_name': name, 'min_value': min_value})) if max_value is not None and value > max_value: raise webob.exc.HTTPBadRequest( explanation=(_('%(value_name)s must be <= %(max_value)d') % {'value_name': name, 'max_value': max_value})) return value
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 create_trigger(self, context, trigger): if trigger.type not in ['time']: msg = (_("Invalid trigger type:%s") % trigger.type) raise exception.InvalidInput(msg) if trigger.properties['format'] not in ['crontab']: msg = (_("Invalid trigger time format type")) raise exception.InvalidInput(msg)
def check_time_format(cls, pattern): if not pattern: msg = (_("The trigger pattern is None")) raise exception.InvalidInput(msg) try: croniter(pattern) except Exception: msg = (_("The trigger pattern(%s) is invalid") % pattern) raise exception.InvalidInput(msg)
def checkpoints_create(self, req, provider_id, body): """Creates a new checkpoint.""" if not self.is_valid_body(body, 'checkpoint'): raise exc.HTTPUnprocessableEntity() context = req.environ['smaug.context'] LOG.debug('Create checkpoint request ' 'body: %s provider_id:%s', body, provider_id) check_policy(context, 'checkpoint_create') checkpoint = body['checkpoint'] LOG.debug('Create checkpoint request checkpoint: %s', checkpoint) if not provider_id: msg = _("provider_id must be provided when creating " "a checkpoint.") raise exception.InvalidInput(reason=msg) plan_id = checkpoint.get("plan_id") if not plan_id: msg = _("plan_id must be provided when creating " "a checkpoint.") raise exception.InvalidInput(reason=msg) 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) if not plan: raise exception.PlanNotFound(plan_id=plan_id) checkpoint_properties = { 'project_id': context.project_id, 'status': 'protecting', 'provider_id': provider_id, "protection_plan": { "id": plan.get("id"), "name": plan.get("name"), "resources": plan.get("resources"), } } checkpoint = self.protection_api.protect(context, plan) if checkpoint is not None: checkpoint_properties['id'] = checkpoint.get('checkpoint_id') else: msg = _("Get checkpoint failed.") raise exc.HTTPNotFound(explanation=msg) returnval = self._checkpoint_view_builder.detail( req, checkpoint_properties) return returnval
def create(self, req, body): """Creates a new restore.""" if not self.is_valid_body(body, 'restore'): raise exc.HTTPUnprocessableEntity() LOG.debug('Create restore request body: %s', body) context = req.environ['smaug.context'] check_policy(context, 'create') restore = body['restore'] LOG.debug('Create restore request : %s', restore) if not restore.get("provider_id"): msg = _("provider_id must be provided when creating " "a restore.") raise exception.InvalidInput(reason=msg) if not restore.get("checkpoint_id"): msg = _("checkpoint_id must be provided when creating " "a restore.") raise exception.InvalidInput(reason=msg) parameters = restore.get("parameters") if not isinstance(parameters, dict): msg = _("parameters must be a dict when creating" " a restore.") raise exception.InvalidInput(reason=msg) restore_properties = { 'project_id': context.project_id, 'provider_id': restore.get('provider_id'), 'checkpoint_id': restore.get('checkpoint_id'), 'restore_target': restore.get('restore_target'), 'parameters': parameters, 'status': 'started', } restoreobj = objects.Restore(context=context, **restore_properties) restoreobj.create() LOG.debug('call restore RPC : restoreobj:%s', restoreobj) # call restore rpc API of protection service result = self.protection_api.restore(context, restoreobj) if result is True: status_update = "success" else: status_update = "failed" # update the status of restore update_dict = {"status": status_update} check_policy(context, 'update', restoreobj) self._restore_update(context, restoreobj.get("id"), update_dict) restoreobj.update(update_dict) retval = self._view_builder.detail(req, restoreobj) return retval
def _get_offset_param(params): """Extract offset id from request's dictionary (defaults to 0) or fail.""" try: offset = int(params.pop('offset', 0)) except ValueError: msg = _('offset param must be an integer') raise webob.exc.HTTPBadRequest(explanation=msg) if offset < 0: msg = _('offset param must be positive') raise webob.exc.HTTPBadRequest(explanation=msg) return offset
def _get_all(self, context, marker=None, limit=None, sort_keys=None, sort_dirs=None, filters=None, offset=None): check_policy(context, 'get_all') if filters is None: filters = {} all_tenants = utils.get_bool_param('all_tenants', 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)) if context.is_admin and all_tenants: # Need to remove all_tenants to pass the filtering below. del filters['all_tenants'] restores = objects.RestoreList.get_all(context, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset) else: restores = objects.RestoreList.get_all_by_project( context, context.project_id, marker, limit, sort_keys=sort_keys, sort_dirs=sort_dirs, filters=filters, offset=offset) LOG.info(_LI("Get all restores completed successfully.")) return restores
def validate_plan_resources(self, plan): resources_list = plan["resources"] if (isinstance(resources_list, list)) and (len(resources_list) > 0): for resource in resources_list: if (isinstance(resource, dict) and (len(resource) == 3) and {"id", "type", 'name'}.issubset(resource)): pass else: msg = _("Resource in list must be a dict when creating a " "plan.The keys of resource are id,type and name.") raise exception.InvalidInput(reason=msg) else: msg = _("list resources must be provided when creating " "a plan.") raise exception.InvalidInput(reason=msg)
def _get_trigger_class(self, trigger_type): cls = self._trigger_cls_map.get(trigger_type, None) if not cls: msg = (_("Invalid trigger type:%s") % trigger_type) raise exception.InvalidInput(msg) return cls
def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason=_('already created')) updates = self.smaug_obj_get_changes() db_service = db.service_create(self._context, updates) self._from_db_object(self._context, self, db_service)
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(_("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 __init__(self, name, loader=None): """Initialize, but do not start the WSGI server. :param name: The name of the WSGI server given to the loader. :param loader: Loads the WSGI application using the given name. :returns: None """ self.name = name self.manager = self._get_manager() self.loader = loader or wsgi_common.Loader() self.app = self.loader.load_app(name) self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0") self.port = getattr(CONF, '%s_listen_port' % name, 0) self.workers = (getattr(CONF, '%s_workers' % name, None) or processutils.get_worker_count()) if self.workers and self.workers < 1: worker_name = '%s_workers' % name msg = (_("%(worker_name)s value of %(workers)d is invalid, " "must be greater than 0.") % {'worker_name': worker_name, 'workers': self.workers}) raise exception.InvalidInput(msg) self.server = wsgi.Server(name, self.app, host=self.host, port=self.port)
def _sync_status(self, checkpoint, status_getters): status = {} for s in status_getters: resource_id = s.get('resource_id') get_resource_stats = s.get('get_resource_stats') status[resource_id] = get_resource_stats(checkpoint, resource_id) if constants.RESOURCE_STATUS_ERROR in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_ERROR checkpoint.commit() elif constants.RESOURCE_STATUS_PROTECTING in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() elif constants.RESOURCE_STATUS_UNDEFINED in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() else: checkpoint.status = constants.CHECKPOINT_STATUS_AVAILABLE checkpoint.commit() LOG.info(_("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 instances_show(self, req, protectable_type, protectable_id): """Return a instance about the given protectable_type and id.""" context = req.environ['smaug.context'] LOG.info(_LI("Show the instance 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) instance = self.protection_api.\ show_protectable_instance(context, protectable_type, protectable_id) if instance is None: raise exception.InvalidProtectableInstance( protectable_id=instance.get('id')) 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 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(_("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 __call__(self, environ, start_response): """Subclasses will probably want to implement __call__ like this: @webob.dec.wsgify(RequestClass=Request) def __call__(self, req): # Any of the following objects work as responses: # Option 1: simple string res = 'message\n' # Option 2: a nicely formatted HTTP exception page res = exc.HTTPForbidden(explanation='Nice try') # Option 3: a webob Response object (in case you need to play with # headers, or you want to be treated like an iterable) res = Response(); res.app_iter = open('somefile') # Option 4: any wsgi app to be run next res = self.application # Option 5: you can get a Response object for a wsgi app, too, to # play with headers etc res = req.get_response(self.application) # You can then just return your response... return res # ... or set req.response and return None. req.response = res See the end of http://pythonpaste.org/webob/modules/dec.html for more info. """ raise NotImplementedError(_('You must implement __call__'))
def _sync_status(self, checkpoint, status_getters): status = {} for s in status_getters: resource_id = s.get('resource_id') get_resource_stats = s.get('get_resource_stats') status[resource_id] = get_resource_stats(checkpoint, resource_id) if constants.RESOURCE_STATUS_ERROR in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_ERROR checkpoint.commit() elif constants.RESOURCE_STATUS_PROTECTING in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() elif constants.RESOURCE_STATUS_UNDEFINED in status.values(): checkpoint.status = constants.CHECKPOINT_STATUS_PROTECTING checkpoint.commit() else: checkpoint.status = constants.CHECKPOINT_STATUS_AVAILABLE checkpoint.commit() LOG.info( _("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 action_peek_json(body): """Determine action to invoke.""" try: decoded = jsonutils.loads(body) except ValueError: msg = _("cannot understand JSON") raise exception.MalformedRequestBody(reason=msg) # Make sure there's exactly one key... if len(decoded) != 1: msg = _("too many body keys") raise exception.MalformedRequestBody(reason=msg) # Return the action and the decoded body... return list(decoded.keys())[0]
def delete(self, req, id): """Delete a trigger.""" LOG.debug('Delete trigger(%s) start', id) context = req.environ['smaug.context'] trigger = self._get_trigger_by_id(context, id) check_policy(context, 'delete', trigger) try: operations = objects.ScheduledOperationList.get_by_filters( context, {"trigger_id": id}, limit=1) except Exception as ex: self._raise_unknown_exception(ex) if operations: msg = _("There are more than one scheduled operations binded " "with this trigger, please delete them first") raise exc.HTTPMethodNotAllowed(explanation=msg) try: self.operationengine_api.delete_trigger(context, id) except exception.TriggerNotFound as ex: pass except (exception.DeleteTriggerNotAllowed, Exception) as ex: self._raise_unknown_exception(ex) trigger.destroy()
def _parse_service_catalog_info(config, context): try: service_type, service_name, endpoint_type = config.split(':') except ValueError: msg = _("Failed to parse the catalog info option %s, " "must be in the form: " "<service_type>:<service_name>:<endpoint_type>") % config raise exception.SmaugException(msg) for entry in context.service_catalog: if entry.get('type') == service_type: return entry.get('endpoints')[0].get(endpoint_type) raise exception.SmaugException( _("Couldn't find the endpoint of service type %s " "from service catalog") % service_type)
def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason=_('already created')) updates = self.smaug_obj_get_changes() db_operation_log = db.operation_log_create(self._context, updates) self._from_db_object(self._context, self, db_operation_log)
def show(self, req, id): """Return data about the given protectable_type.""" context = req.environ['smaug.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 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(_("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", resource_definition) 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 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(_("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", resource_definition) 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 model_query(context, *args, **kwargs): """Query helper that accounts for context's `read_deleted` field. :param context: context to query under :param session: if present, the session to use :param read_deleted: if present, overrides context's read_deleted field. :param project_only: if present and context is user-type, then restrict query to match the context's project_id. """ session = kwargs.get('session') or get_session() read_deleted = kwargs.get('read_deleted') or context.read_deleted project_only = kwargs.get('project_only') query = session.query(*args) if read_deleted == 'no': query = query.filter_by(deleted=False) elif read_deleted == 'yes': pass # omit the filter to include deleted and active elif read_deleted == 'only': query = query.filter_by(deleted=True) else: raise Exception( _("Unrecognized read_deleted value '%s'") % read_deleted) if project_only and is_user_context(context): query = query.filter_by(project_id=context.project_id) return query
def protect(self, context, plan): """create protection for the given plan :param plan: Define that protection plan should be done """ LOG.info(_LI("Starting protection service:protect action")) LOG.debug('protecting :%s tpye:%s', plan, type(plan)) if not plan: raise exception.InvalidPlan(reason='the protection plan is None') provider_id = plan.get('provider_id', None) plan_id = plan.get('id', None) provider = self.provider_registry.show_provider(provider_id) if not provider: raise exception.ProviderNotFound(provider_id=provider_id) try: protection_flow = self.worker.get_flow(context, constants.OPERATION_PROTECT, plan=plan, provider=provider) except Exception: LOG.exception(_LE("Failed to create protection flow,plan:%s"), plan_id) raise exception.SmaugException( _("Failed to create protection flow")) try: self.worker.run_flow(protection_flow) except Exception: LOG.exception(_LE("Failed to run protection flow")) raise finally: checkpoint = self.worker.flow_outputs(protection_flow, target='checkpoint') return {'checkpoint_id': checkpoint.id}
def update(self, req, id, body): """Update a plan.""" context = req.environ['smaug.context'] if not body: msg = _("Missing request body") raise exc.HTTPBadRequest(explanation=msg) if 'plan' not in body: msg = _("Missing required element '%s' in request body") % 'plan' raise exc.HTTPBadRequest(explanation=msg) if not uuidutils.is_uuid_like(id): msg = _("Invalid plan id provided.") raise exc.HTTPBadRequest(explanation=msg) plan = body['plan'] update_dict = {} valid_update_keys = { 'name', 'resources', 'status', } for key in valid_update_keys.intersection(plan): update_dict[key] = plan[key] if update_dict is None: msg = _("Missing updated parameters in request body.") raise exc.HTTPBadRequest(explanation=msg) self.validate_name_and_description(update_dict) if update_dict.get("resources"): self.validate_plan_resources(update_dict) try: plan = self._plan_get(context, id) except exception.PlanNotFound as error: raise exc.HTTPNotFound(explanation=error.msg) check_policy(context, 'update', plan) self._plan_update(context, plan, update_dict) plan.update(update_dict) retval = self._view_builder.detail(req, plan) return retval
def get_bool_param(param_string, params): param = params.get(param_string, False) if not is_valid_boolstr(param): msg = _('Value %(param)s for %(param_string)s is not a ' 'boolean.') % {'param': param, 'param_string': param_string} raise exception.InvalidParameterValue(err=msg) return strutils.bool_from_string(param, strict=True)
def _raise_unknown_exception(self, exception_instance): value = exception_instance.msg if isinstance( exception_instance, exception.SmaugException) else type( exception_instance) msg = (_('Unexpected API Error. Please report this at ' 'http://bugs.launchpad.net/smaug/ and attach the ' 'Smaug API log if possible.\n%s') % value) raise exc.HTTPInternalServerError(explanation=msg)
def _plan_update(self, context, plan, fields): if 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.SmaugObject): plan.update(fields) plan.save() LOG.info(_LI("Plan updated successfully."), resource=plan) else: msg = _("The parameter plan must be a object of " "SmaugObject class.") raise exception.InvalidInput(reason=msg)
def _prepend_prefix(self, key): if not key: raise RuntimeError(_("No key specified")) if not key.startswith("/"): key = "/" + key return "%s%s" % (self._prefix, key)
def add_trigger(self, trigger_id, trigger_type, trigger_property): if trigger_id in self._trigger_obj_map: msg = (_("Trigger id %s is exist") % trigger_id) raise exception.InvalidInput(msg) trigger_cls = self._get_trigger_class(trigger_type) trigger = trigger_cls(trigger_id, trigger_property, self._executor) self._trigger_obj_map[trigger_id] = trigger
def check_trigger_definition(cls, trigger_definition): """Check trigger definition All the time instances of trigger_definition are in UTC, including start_time, end_time """ trigger_format = trigger_definition.get("format", None) pattern = trigger_definition.get("pattern", None) cls.TIME_FORMAT_MANAGER.check_time_format(trigger_format, pattern) interval = int( cls.TIME_FORMAT_MANAGER.get_interval(trigger_format, pattern)) if interval < CONF.min_interval: msg = (_("The interval of two adjacent time points " "is less than %d") % CONF.min_interval) raise exception.InvalidInput(msg) window = trigger_definition.get("window", CONF.window_time) if not isinstance(window, int): try: window = int(window) except Exception: msg = (_("The trigger windows(%s) is not integer") % window) raise exception.InvalidInput(msg) if window <= 0: msg = (_("The trigger windows(%d) must be positive") % window) raise exception.InvalidInput(msg) if (window * 2) > interval: msg = (_("The trigger windows%(window)d must be less " "than %(interval)d") % { "window": window, "interval": interval / 2 }) raise exception.InvalidInput(msg) end_time = trigger_definition.get("end_time", None) end_time = cls._check_and_get_datetime(end_time, "end_time") start_time = trigger_definition.get("start_time", None) start_time = cls._check_and_get_datetime(start_time, "start_time") valid_trigger_property = trigger_definition.copy() valid_trigger_property['start_time'] = start_time valid_trigger_property['end_time'] = end_time return valid_trigger_property
def _get_limit_param(params, max_limit=None): """Extract integer limit from request's dictionary or fail. Defaults to max_limit if not present and returns max_limit if present 'limit' is greater than max_limit. """ max_limit = max_limit or CONF.osapi_max_limit try: limit = int(params.pop('limit', max_limit)) except ValueError: msg = _('limit param must be an integer') raise webob.exc.HTTPBadRequest(explanation=msg) if limit <= 0: msg = _('limit param must be positive') raise webob.exc.HTTPBadRequest(explanation=msg) limit = min(limit, max_limit) return limit
def _check_and_get_datetime(cls, time, time_name): if not time or isinstance(time, datetime): return time if not isinstance(time, six.string_types): msg = (_("The trigger %(name)s(type = %(vtype)s) is not an " "instance of string") % {"name": time_name, "vtype": type(time)}) raise exception.InvalidInput(msg) try: time = timeutils.parse_strtime(time, fmt='%Y-%m-%d %H:%M:%S') except Exception: msg = (_("The format of trigger %s is not correct") % time_name) raise exception.InvalidInput(msg) return time
def _parse_service_catalog_info(config, context): try: service_type, service_name, endpoint_type = config.split(':') except ValueError: msg = _("Failed to parse the catalog info option %s, " "must be in the form: " "<service_type>:<service_name>:<endpoint_type>" ) % config raise exception.SmaugException(msg) for entry in context.service_catalog: if entry.get('type') == service_type: return entry.get('endpoints')[0].get(endpoint_type) raise exception.SmaugException(_( "Couldn't find the endpoint of service type %s " "from service catalog") % service_type)
def check_trigger_definition(cls, trigger_definition): """Check trigger definition All the time instances of trigger_definition are in UTC, including start_time, end_time """ trigger_format = trigger_definition.get("format", None) pattern = trigger_definition.get("pattern", None) cls.TIME_FORMAT_MANAGER.check_time_format( trigger_format, pattern) interval = int(cls.TIME_FORMAT_MANAGER.get_interval( trigger_format, pattern)) if interval < CONF.min_interval: msg = (_("The interval of two adjacent time points " "is less than %d") % CONF.min_interval) raise exception.InvalidInput(msg) window = trigger_definition.get("window", CONF.window_time) if not isinstance(window, int): try: window = int(window) except Exception: msg = (_("The trigger windows(%s) is not integer") % window) raise exception.InvalidInput(msg) if window <= 0: msg = (_("The trigger windows(%d) must be positive") % window) raise exception.InvalidInput(msg) if (window * 2) > interval: msg = (_("The trigger windows%(window)d must be less " "than %(interval)d") % {"window": window, "interval": interval / 2}) raise exception.InvalidInput(msg) end_time = trigger_definition.get("end_time", None) end_time = cls._check_and_get_datetime(end_time, "end_time") start_time = trigger_definition.get("start_time", None) start_time = cls._check_and_get_datetime(start_time, "start_time") valid_trigger_property = trigger_definition.copy() valid_trigger_property['start_time'] = start_time valid_trigger_property['end_time'] = end_time return valid_trigger_property
def create(self): if self.obj_attr_is_set('id'): raise exception.ObjectActionError(action='create', reason=_('already created')) updates = self.smaug_obj_get_changes() self._convert_operation_definition_to_db_format(updates) db_op = db.scheduled_operation_create(self._context, updates) self._from_db_object(self._context, self, db_op)
def on_node_exit(self, node): resource = node.value resource_type = resource.type LOG.info(_("on_node_exit, node resource_type:%s"), resource_type) protection_plugin = self._get_protection_plugin(resource_type) # get node context context = self.context.get_node_context(node) # do something in protection_plugin protection_plugin.on_resource_end(context)
def restore(self, context, restore=None): 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 in [constants.CHECKPOINT_STATUS_ERROR, constants.CHECKPOINT_STATUS_PROTECTING]: raise exception.CheckpointNotAvailable( checkpoint_id=checkpoint_id) try: restoration_flow = self.worker.get_restoration_flow( context, constants.OPERATION_RESTORE, checkpoint, provider, restore) 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) return True 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 _check_and_get_datetime(cls, time, time_name): if not time or isinstance(time, datetime): return time if not isinstance(time, six.string_types): msg = (_("The trigger %(name)s(type = %(vtype)s) is not an " "instance of string") % { "name": time_name, "vtype": type(time) }) raise exception.InvalidInput(msg) try: time = timeutils.parse_strtime(time, fmt='%Y-%m-%d %H:%M:%S') except Exception: msg = (_("The format of trigger %s is not correct") % time_name) raise exception.InvalidInput(msg) return time