def get(self, project_id, target_project_id=None, action=None): """Get quota for a specified tenant. :param project_id: It's UUID of the project. :param target_project_id: It's UUID of the project. Note: In v1.0 it can be defaults sometimes. Only specified tenant quota is retrieved from database using this param. :param action: Optional. If provided, it can be 'detail' detail - Gets detail quota usage for the specified tenant. """ context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) if not uuidutils.is_uuid_like(target_project_id)\ and target_project_id != 'defaults': pecan.abort(400, _('Invalid request URL')) quota = collections.defaultdict(dict) try: if context.is_admin or (project_id == target_project_id)\ or (target_project_id == 'defaults'): result = self.get_quota(context, target_project_id, action) quota['quota_set'] = result return quota else: pecan.abort(403, _('Admin required ')) except exceptions.InternalError: pecan.abort(400, _('Error while requesting usage'))
def delete(self, project, job_id): """Delete the database entries of a given job_id. :param project: It's UUID of the project. :param job_id: ID of the job for which the database entries have to be deleted. """ context = restcomm.extract_context_from_environ() if not uuidutils.is_uuid_like(project) or project != context.project: pecan.abort(400, _('Invalid request URL')) if uuidutils.is_uuid_like(job_id): try: status = db_api.sync_job_status(context, job_id) except exceptions.JobNotFound: pecan.abort(404, _('Job not found')) if status == consts.JOB_PROGRESS: pecan.abort( 406, _('action not supported' ' while sync is in progress')) try: db_api.sync_job_delete(context, job_id) except exceptions.JobNotFound: pecan.abort(404, _('Job not found')) return 'job %s deleted from the database.' % job_id else: pecan.abort(400, _('Bad request'))
def delete(self, project_id, target_project_id): """Delete quota for a specified tenant. Resources for a specific tenant can also be deleted. :param project_id: It's UUID of the project. :param target_project_id: It's UUID of the project. Note: In v1.0 it can be defaults sometimes. Only specified tenant quota is retrieved from database using this param. #NOTE: Support to delete quota for a specific resource is through CURL request in V1.0. """ context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) if not uuidutils.is_uuid_like(target_project_id): pecan.abort(400, _('Invalid request URL')) if not context.is_admin: pecan.abort(403, _('Admin required')) if request.body: payload = eval(request.body).get('quota_set') if not payload: pecan.abort(400, _('quota_set in body required')) self.delete_quota_resources(context, target_project_id, payload) return {'Deleted quota limits': payload} else: self.delete_quota(context, target_project_id) return "Deleted all quota limits for the given project"
def put(self, project_id, target_project_id, action=None): """Update quota limits for a project. If it fails, Then creates a new entry in DB for that project. :param project_id: It's UUID of the project. :param target_project_id: It's UUID of the project. Note: In v1.0 it can be defaults sometimes. Only specified tenant quota is retrieved from database using this param. :param action: Optional. If provided, it can be 'detail' detail - Gets detail quota usage for the specified tenant. """ context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not context.is_admin: pecan.abort(403, _('Admin required')) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) if not uuidutils.is_uuid_like(target_project_id): pecan.abort(400, _('Invalid request URL')) if action and action != 'sync': pecan.abort(404, 'Invalid action, only sync is allowed') elif action == 'sync': return self.sync(context, target_project_id) quota = self.update_quota(context, request, target_project_id) return quota
def put(self, class_name): """Update a class.""" context = restcomm.extract_context_from_environ() LOG.info("Update quota class [class_name=%s]" % class_name) if not context.is_admin: pecan.abort(403, _('Admin required')) if not request.body: pecan.abort(400, _('Body required')) quota_class_set = eval(request.body).get('quota_class_set') if not quota_class_set: pecan.abort(400, _('Missing quota_class_set in the body')) utils.validate_quota_limits(quota_class_set) for key, value in six.iteritems(quota_class_set): try: db_api.quota_class_update(context, class_name, key, value) except exceptions.QuotaClassNotFound: db_api.quota_class_create(context, class_name, key, value) values = db_api.quota_class_get_all_by_name(context, class_name) return self._format_quota_set(class_name, values)
def get(self, project_id, action=None): """Get quota of a tenant. :param project_id: It's UUID of the project. Only specified quota details can be viewed using this param. :param action: Optional. If provided, it can be 'defaults' or 'detail' defaults - returns the quotas limits from the conf file. detail - returns the current quota usages of the tenant """ context = restcomm.extract_context_from_environ() quota = collections.defaultdict(dict) result = collections.defaultdict(dict) if not uuidutils.is_uuid_like(project_id): pecan.abort(400) enforce = enf.enforce('kingbird:get_all_quota', context) try: if enforce or (project_id == context.project)\ or (action == 'defaults'): result = self.get_quota(context, project_id, action) quota['quota_set'] = result return quota else: pecan.abort(403, _('Admin required ')) except exceptions.InternalError: pecan.abort(400, _('Error while requesting usage'))
def get(self, project_id, action=None): quota = collections.defaultdict(dict) context = restcomm.extract_context_from_environ() result = collections.defaultdict(dict) try: if project_id == 'defaults': # Get default quota limits from conf file result = self._get_defaults(context, CONF.kingbird_global_limit) else: if action and action != 'detail': pecan.abort(404, _('Invalid request URL')) elif action == 'detail': # Get the current quota usages for a project result = self.rpc_client.get_total_usage_for_tenant( context, project_id) else: # Get quota limits for all the resources for a project result = db_api.quota_get_all_by_project( context, project_id) quota['quota_set'] = result return quota # Could be raised by get total usage call except exceptions.InternalError: pecan.abort(400, _('Error while requesting usage'))
def put(self, project_id, class_name): """Update a class.""" context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) LOG.info("Update quota class [class_name=%s]" % class_name) if not context.is_admin: pecan.abort(403, _('Admin required')) if not request.body: pecan.abort(400, _('Body required')) quota_class_set = eval(request.body).get('quota_class_set') if not quota_class_set: pecan.abort(400, _('Missing quota_class_set in the body')) utils.validate_quota_limits(quota_class_set) for key, value in quota_class_set.items(): try: db_api.quota_class_update(context, class_name, key, value) except exceptions.QuotaClassNotFound: db_api.quota_class_create(context, class_name, key, value) values = db_api.quota_class_get_all_by_name(context, class_name) return self._format_quota_set(context, class_name, values)
def sync(self, project_id, context): if pecan.request.method != 'PUT': pecan.abort(405, _('Bad method. Use PUT instead')) if not context.is_admin: pecan.abort(403, _('Admin required')) self.rpc_client.quota_sync_for_project( context, project_id) return 'triggered quota sync for ' + project_id
def delete(self, class_name): context = restcomm.extract_context_from_environ() if not context.is_admin: pecan.abort(403, _('Admin required')) LOG.info("Delete quota class [class_name=%s]" % class_name) try: db_api.quota_class_destroy_all(context, class_name) except exceptions.QuotaClassNotFound: pecan.abort(404, _('Quota class not found'))
def get(self, project_id, class_name): context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) LOG.info("Fetch quotas for [class_name=%s]" % class_name) values = db_api.quota_class_get_all_by_name(context, class_name) return self._format_quota_set(context, class_name, values)
def delete(self, project_id, class_name): context = restcomm.extract_context_from_environ() valid_project_id = uuidutils.is_uuid_like(project_id) if not valid_project_id: pecan.abort(400, _('Invalid request URL')) if project_id != context.project and not context.is_admin: pecan.abort(400, _('Invalid request URL')) if not context.is_admin: pecan.abort(403, _('Admin required')) LOG.info("Delete quota class [class_name=%s]" % class_name) try: db_api.quota_class_destroy_all(context, class_name) except exceptions.QuotaClassNotFound: pecan.abort(404, _('Quota class not found'))
def _get_defaults(context, config_defaults): """Get default quota values. If the default class is defined, use the values defined in the class, otherwise use the values from the config. :param context: :param config_defaults: :return: """ quotas = {} default_quotas = {} if CONF.use_default_quota_class: default_quotas = db_api.quota_class_get_default(context) for resource, default in six.iteritems(config_defaults): # get rid of the 'quota_' prefix resource_name = resource[6:] if default_quotas: if resource_name not in default_quotas: versionutils.report_deprecated_feature(LOG, _( "Default quota for resource: %(res)s is set " "by the default quota flag: quota_%(res)s, " "it is now deprecated. Please use the " "default quota class for default " "quota.") % {'res': resource_name}) quotas[resource_name] = default_quotas.get(resource_name, default) return quotas
def is_admin_context(context): """Indicate if the request context is an administrator.""" if not context: LOG.warning(_('Use of empty request context is deprecated'), DeprecationWarning) raise Exception('die') return context.is_admin
class KingbirdException(Exception): """Base Kingbird Exception. To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") def __init__(self, **kwargs): try: super(KingbirdException, self).__init__(self.message % kwargs) self.msg = self.message % kwargs except Exception: with excutils.save_and_reraise_exception() as ctxt: if not self.use_fatal_exceptions(): ctxt.reraise = False # at least get the core message out if something happened super(KingbirdException, self).__init__(self.message) if six.PY2: def __unicode__(self): return unicode(self.msg) def use_fatal_exceptions(self): return False
def __init__(self, *args, **kwargs): LOG.debug(_('QuotaManager initialization...')) super(QuotaManager, self).__init__(service_name="quota_manager", *args, **kwargs) self.context = context.get_admin_context() self.endpoints = endpoint_cache.EndpointCache()
def is_admin_context(context): """Indicates if the request context is an administrator.""" if not context: LOG.warning(_('Use of empty request context is deprecated'), DeprecationWarning) raise Exception('die') return context.is_admin
def get_defaults(self, context, config_defaults): """Get default quota values. If the default class is defined, use the values defined in the class, otherwise use the values from the config. :param context: :param config_defaults: :return: """ quotas = {} default_quotas = {} if CONF.use_default_quota_class: default_quotas = db_api.quota_class_get_default(context) for resource, default in config_defaults.items(): # get rid of the 'quota_' prefix resource_name = resource[6:] if default_quotas: if resource_name not in default_quotas: versionutils.report_deprecated_feature( LOG, _("Default quota for resource: %(res)s is set " "by the default quota flag: quota_%(res)s, " "it is now deprecated. Please use the " "default quota class for default " "quota.") % {'res': resource_name}) quotas[resource_name] = default_quotas.get(resource_name, default) return quotas
def get_quota(self, context, project_id, action=None): """Get quota for a specified tenant. :param context: context object. :param project_id: It's UUID of the project. Note: In v1.0 it can be defaults sometimes. Only specified tenant quota is retrieved from database using this param. :param action: Optional. If provided, it can be 'detail' action - Gets details quota for the specified tenant. """ result = collections.defaultdict(dict) if project_id == 'defaults' or action == 'defaults': # Get default quota limits from conf file result = self.get_defaults(context, CONF.kingbird_global_limit) else: if action and action != 'detail': pecan.abort(404, _('Invalid request URL')) elif action == 'detail': # Get the current quota usages for a project result = self.rpc_client.get_total_usage_for_tenant( context, project_id) else: # Get quota limits for all the resources for a project result = db_api.quota_get_all_by_project(context, project_id) return result
def _entries_to_database(self, context, target_regions, source_region, resources, resource_type, job_id): """Manage the entries to database for both Keypair and image.""" # Insert into the parent table try: result = db_api.sync_job_create(context, job_id=job_id) except exceptions.InternalError: pecan.abort(500, _('Internal Server Error.')) # Insert into the child table for region in target_regions: for resource in resources: try: db_api.resource_sync_create(context, result, region, source_region, resource, resource_type) except exceptions.JobNotFound: pecan.abort(404, _('Job not found')) return result
def _stop_rpc_server(self): # Stop RPC connection to prevent new requests LOG.debug(_("Attempting to stop engine service...")) try: self._rpc_server.stop() self._rpc_server.wait() LOG.info('Engine service stopped successfully') except Exception as ex: LOG.error('Failed to stop engine service: %s', six.text_type(ex))
def _stop_rpc_server(self): # Stop RPC connection to prevent new requests LOG.debug(_("Attempting to stop engine service...")) try: self._rpc_server.stop() self._rpc_server.wait() LOG.info(_LI('Engine service stopped successfully')) except Exception as ex: LOG.error(_LE('Failed to stop engine service: %s'), six.text_type(ex))
def post(self, project): """Sync resources present in one region to another region. :param project: It's UUID of the project. """ context = restcomm.extract_context_from_environ() if not uuidutils.is_uuid_like(project) or project != context.project: pecan.abort(400, _('Invalid request URL')) payload = eval(request.body) if not payload: pecan.abort(400, _('Body required')) payload = payload.get('resource_set') if not payload: pecan.abort(400, _('resource_set required')) resource_type = payload.get('resource_type') target_regions = payload.get('target') if not target_regions or not isinstance(target_regions, list): pecan.abort(400, _('Target regions required')) source_region = payload.get('source') if not source_region or not isinstance(source_region, str): pecan.abort(400, _('Source region required')) source_resources = payload.get('resources') if not source_resources: pecan.abort(400, _('Source resources required')) job_id = uuidutils.generate_uuid() if resource_type == consts.KEYPAIR: session = EndpointCache().get_session_from_token( context.auth_token, context.project) # Create Source Region object source_nova_client = NovaClient(source_region, session) # Check for keypairs in Source Region for source_keypair in source_resources: source_keypair = source_nova_client.\ get_keypairs(source_keypair) if not source_keypair: pecan.abort(404) result = self._entries_to_database(context, target_regions, source_region, source_resources, resource_type, job_id) return self._keypair_sync(job_id, payload, context, result) elif resource_type == consts.IMAGE: # Create Source Region glance_object glance_driver = GlanceClient(source_region, context) # Check for images in Source Region for image in source_resources: source_image = glance_driver.check_image(image) if image != source_image: pecan.abort(404) result = self._entries_to_database(context, target_regions, source_region, source_resources, resource_type, job_id) return self._image_sync(job_id, payload, context, result) else: pecan.abort(400, _('Bad resource_type'))
def delete(self, project_id, **args): """Delete quota of a tenant. :param project_id: It's UUID of the project. Only specified tenant quota is deleted using this param. """ context = restcomm.extract_context_from_environ() if not uuidutils.is_uuid_like(project_id): pecan.abort(400) enforce = enf.enforce('kingbird:delete_quota', context) if not enforce: pecan.abort(403, _('Admin required')) if args: payload = args.keys() if not payload: pecan.abort(400, _('quota_set in body required')) self.delete_quota_resources(context, project_id, payload) return {'Deleted quota limits': payload} else: # Delete all quota limits for the project self.delete_quota(context, project_id) return "Deleted all quota limits for the given project"
def delete_quota_resources(self, context, project_id, payload): """Delete quota for a specified resource of a tenant. :param context: context object. :param project_id: It's UUID of the project. Only specified tenant quota is retrieved from database using this param. :param payload: Deletes quota of specified resources for a tenant. Note:- Support only through CURL request for V1.0. """ try: # Delete the mentioned quota limit for the project utils.validate_quota_limits(payload) for resource in payload: db_api.quota_destroy(context, project_id, resource) return {'Deleted quota limits': payload} except exceptions.ProjectQuotaNotFound: pecan.abort(404, _('Project quota not found')) except exceptions.InvalidInputError: pecan.abort(400, _('Invalid input for quota'))
def put(self, project_id, action=None): quota = collections.defaultdict(dict) quota[project_id] = collections.defaultdict(dict) context = restcomm.extract_context_from_environ() if action and action != 'sync': pecan.abort(404, 'Invalid action, only sync is allowed') elif action == 'sync': return self.sync(project_id, context) if not context.is_admin: pecan.abort(403, _('Admin required')) if not request.body: pecan.abort(400, _('Body required')) payload = eval(request.body) payload = payload.get('quota_set') if not payload: pecan.abort(400, _('quota_set in body is required')) try: utils.validate_quota_limits(payload) for resource, limit in payload.iteritems(): try: # Update quota limit in DB result = db_api.quota_update( context, project_id=project_id, resource=resource, limit=limit) except exceptions.ProjectQuotaNotFound: # If update fails due to project/quota not found # then create the quota limit result = db_api.quota_create( context, project_id=project_id, resource=resource, limit=limit) quota[project_id][result.resource] = result.hard_limit return quota except exceptions.InvalidInputError: pecan.abort(400, _('Invalid input for quota limits'))
def update_quota(self, context, request, project_id): """Update quota for specified tenant. :param context: context object. :param request: request object. :param project_id: It's UUID of the project. Only specified tenant quota is updated in database using this param. """ quota = collections.defaultdict(dict) quota[project_id] = collections.defaultdict(dict) if not request.body: pecan.abort(400, _('Body required')) payload = eval(request.body).get('quota_set') if not payload: pecan.abort(400, _('quota_set in body is required')) try: utils.validate_quota_limits(payload) for resource, limit in payload.iteritems(): try: # Update quota limit in DB result = db_api.quota_update(context, project_id=project_id, resource=resource, limit=limit) except exceptions.ProjectQuotaNotFound: # If update fails due to project/quota not found # then create the quota limit result = db_api.quota_create(context, project_id=project_id, resource=resource, limit=limit) quota[project_id][result.resource] = result.hard_limit return quota except exceptions.InvalidInputError: pecan.abort(400, _('Invalid input for quota limits'))
def get(self, project, action=None): """Get details about Sync Job. :param project: It's UUID of the project. :param action: Optional. If provided, it can be 'active' to get the list of active jobs. 'job-id' to get the details of a job. """ context = restcomm.extract_context_from_environ() if not uuidutils.is_uuid_like(project) or project != context.project: pecan.abort(400, _('Invalid request URL')) result = collections.defaultdict(dict) if not action or action == 'active': result['job_set'] = db_api.sync_job_list(context, action) elif uuidutils.is_uuid_like(action): try: result['job_set'] = db_api.resource_sync_list_by_job( context, action) except exceptions.JobNotFound: pecan.abort(404, _('Job not found')) else: pecan.abort(400, _('Invalid request URL')) return result
def delete_quota(self, context, project_id): """Delete entire quota for a specified tenant. :param context: context object. :param project_id: It's UUID of the project. Only specified tenant quota is retrieved from database using this param. """ try: db_api.quota_destroy_all(context, project_id) return "Deleted all quota limits for the given project" except exceptions.ProjectQuotaNotFound: pecan.abort(404, _('Project quota not found'))
def delete(self, project_id): context = restcomm.extract_context_from_environ() if not context.is_admin: pecan.abort(403, _('Admin required')) try: if request.body: # Delete the mentioned quota limit for the project payload = eval(request.body) payload = payload.get('quota_set') if not payload: pecan.abort(400, _('quota_set in body required')) utils.validate_quota_limits(payload) for resource in payload: db_api.quota_destroy(context, project_id, resource) return {'Deleted quota limits': payload} else: # Delete all quota limits for the project db_api.quota_destroy_all(context, project_id) return "Deleted all quota limits for the given project" except exceptions.ProjectQuotaNotFound: pecan.abort(404, _('Project quota not found')) except exceptions.InvalidInputError: pecan.abort(400, _('Invalid input for quota'))
def sync(self, context, project_id): """Sync quota of a tenant. Private method called by put method for on demand quota sync :param context: context object. :param project_id: It's UUID of the project. On demand quota sync is triggered only for specified tenant using this param. """ if pecan.request.method != 'PUT': pecan.abort(405, _('Bad method. Use PUT instead')) self.rpc_client.quota_sync_for_project(context, project_id) return 'triggered quota sync for ' + project_id
def __init__(self, region_name=None): # Check if objects are cached and try to use those self.region_name = region_name if 'keystone' in OpenStackDriver.os_clients_dict and \ self._is_token_valid(): self.keystone_client = OpenStackDriver.os_clients_dict['keystone'] else: self.keystone_client = KeystoneClient() OpenStackDriver.os_clients_dict['keystone'] = self.keystone_client self.disabled_quotas = self._get_disabled_quotas(region_name) if region_name in OpenStackDriver.os_clients_dict and \ self._is_token_valid(): LOG.info('Using cached OS client objects') self.nova_client = OpenStackDriver.os_clients_dict[region_name][ 'nova'] self.cinder_client = OpenStackDriver.os_clients_dict[region_name][ 'cinder'] self.neutron_client = OpenStackDriver.os_clients_dict[region_name][ 'neutron'] else: # Create new objects and cache them LOG.info(_("Creating fresh OS Clients objects")) self.neutron_client = NeutronClient(region_name, self.disabled_quotas, self.keystone_client.session) self.nova_client = NovaClient(region_name, self.keystone_client.session, self.disabled_quotas) self.cinder_client = CinderClient(region_name, self.disabled_quotas, self.keystone_client.session) OpenStackDriver.os_clients_dict[ region_name] = collections.defaultdict(dict) OpenStackDriver.os_clients_dict[region_name][ 'nova'] = self.nova_client OpenStackDriver.os_clients_dict[region_name][ 'cinder'] = self.cinder_client OpenStackDriver.os_clients_dict[region_name][ 'neutron'] = self.neutron_client
def put(self, project_id, action=None): """Update quota of a tenant. :param project_id: It's UUID of the project. Only specified tenant quota is updated using this param. :param action: Optional. If provided, it can be 'sync' action - syncs quota for the specified tenant based on the kingbird magic. """ context = restcomm.extract_context_from_environ() quota = collections.defaultdict(dict) quota[project_id] = collections.defaultdict(dict) if not uuidutils.is_uuid_like(project_id): pecan.abort(400) enforce = enf.enforce('kingbird:update_quota', context) if not enforce: pecan.abort(403, _('Admin required')) if action not in ('sync', None): pecan.abort(404, 'Invalid action, only sync is allowed') elif action == 'sync': return self.sync(context, project_id) quota = self.update_quota(context, request, project_id) return quota
# License for the specific language governing permissions and limitations # under the License. from oslo_config import cfg from oslo_log import log as logging from kingbird.common.i18n import _ from kingbird.db import api as db_api from kingbird.engine import scheduler LOG = logging.getLogger(__name__) lock_opts = [ cfg.IntOpt('lock_retry_times', default=3, help=_('Number of times trying to grab a lock.')), cfg.IntOpt('lock_retry_interval', default=10, help=_('Number of seconds between lock retries.')) ] lock_opts_group = cfg.OptGroup('locks') cfg.CONF.register_group(lock_opts_group) cfg.CONF.register_opts(lock_opts, group=lock_opts_group) def sync_lock_acquire(context, engine_id, task_type, forced=False): """Try to lock with specified engine_id. :param engine: ID of the engine which wants to lock the projects. :returns: True if lock is acquired, or False otherwise.
from oslo_config import cfg from oslo_log import log as logging from kingbird.common.i18n import _ # from kingbird import policy from kingbird.common import version LOG = logging.getLogger(__name__) common_opts = [ cfg.StrOpt('bind_host', default='0.0.0.0', help=_("The host IP to bind to")), cfg.IntOpt('bind_port', default=8118, help=_("The port to bind to")), cfg.IntOpt('api_workers', default=2, help=_("number of api workers")), cfg.StrOpt('state_path', default=os.path.join(os.path.dirname(__file__), '../'), help='Top-level directory for maintaining kingbird state'), cfg.StrOpt('api_extensions_path', default="", help=_("The path for API extensions")), cfg.StrOpt('auth_strategy', default='keystone', help=_("The type of authentication to use")), cfg.BoolOpt('allow_bulk', default=True, help=_("Allow the usage of the bulk API")), cfg.BoolOpt('allow_pagination', default=False, help=_("Allow the usage of the pagination")),
class JobNotFound(NotFound): message = _("Job doesn't exist.")
def serve(api_service, conf, workers=1): global _launcher if _launcher: raise RuntimeError(_('serve() can only be called once')) _launcher = service.launch(conf, api_service, workers=workers)
class InUse(KingbirdException): message = _("The resource is inuse")
# under the License. from oslo_config import cfg from oslo_log import log as logging from kingbird.common.i18n import _, _LE, _LI from kingbird.db import api as db_api from kingbird.engine import scheduler LOG = logging.getLogger(__name__) lock_opts = [ cfg.IntOpt('lock_retry_times', default=3, help=_('Number of times trying to grab a lock.')), cfg.IntOpt('lock_retry_interval', default=10, help=_('Number of seconds between lock retries.')) ] lock_opts_group = cfg.OptGroup('locks') cfg.CONF.register_group(lock_opts_group) cfg.CONF.register_opts(lock_opts, group=lock_opts_group) def sync_lock_acquire(context, engine_id, task_type, forced=False): """Try to lock with specified engine_id. :param engine: ID of the engine which wants to lock the projects. :returns: True if lock is acquired, or False otherwise.
class ProjectQuotaNotFound(NotFound): message = _("Quota for project %(project_id) doesn't exist.")
class QuotaClassNotFound(NotFound): message = _("Quota class %(class_name) doesn't exist.")
class InvalidConfigurationOption(KingbirdException): message = _("An invalid value was provided for %(opt_name)s: " "%(opt_value)s")
from oslo_config import cfg from oslo_log import log as logging from kingbird.common.i18n import _, _LI # from kingbird import policy from kingbird.common import version LOG = logging.getLogger(__name__) common_opts = [ cfg.StrOpt('bind_host', default='0.0.0.0', help=_("The host IP to bind to")), cfg.IntOpt('bind_port', default=8118, help=_("The port to bind to")), cfg.IntOpt('api_workers', default=2, help=_("number of api workers")), cfg.StrOpt('state_path', default=os.path.join(os.path.dirname(__file__), '../'), help='Top-level directory for maintaining kingbird state'), cfg.StrOpt('api_extensions_path', default="", help=_("The path for API extensions")), cfg.StrOpt('auth_strategy', default='keystone', help=_("The type of authentication to use")), cfg.BoolOpt('allow_bulk', default=True, help=_("Allow the usage of the bulk API")), cfg.BoolOpt('allow_pagination', default=False, help=_("Allow the usage of the pagination")),