def index(self, req): """Return a list of all agent builds. Filter by hypervisor.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) hypervisor = None agents = [] if 'hypervisor' in req.GET: hypervisor = req.GET['hypervisor'] builds = objects.AgentList.get_all(context, hypervisor=hypervisor) for agent_build in builds: agents.append({ 'hypervisor': agent_build.hypervisor, 'os': agent_build.os, 'architecture': agent_build.architecture, 'version': agent_build.version, 'md5hash': agent_build.md5hash, 'agent_id': agent_build.id, 'url': agent_build.url }) return {'agents': agents}
def index(self, req): """Returns a dict in the format: | {'hosts': [{'host_name': 'some.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.other.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.celly.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'console1.host.com', | 'service': 'consoleauth', | 'zone': 'internal'}, | {'host_name': 'network1.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'netwwork2.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'compute1.host.com', | 'service': 'compute', | 'zone': 'patron'}, | {'host_name': 'compute2.host.com', | 'service': 'compute', | 'zone': 'patron'}, | {'host_name': 'sched1.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'sched2.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'vol1.host.com', | 'service': 'volume', | 'zone': 'internal'}]} """ context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) filters = {'disabled': False} zone = req.GET.get('zone', None) if zone: filters['availability_zone'] = zone services = self.api.service_get_all(context, filters=filters, set_zones=True) hosts = [] for service in services: hosts.append({ 'host_name': service['host'], 'service': service['topic'], 'zone': service['availability_zone'] }) return {'hosts': hosts}
def detail(self, req): """Returns a detailed list of availability zone.""" context = req.environ['patron.context'] authorize_detail(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) return self._describe_availability_zones_verbose(context)
def index(self, req): """Return all migrations in progress.""" context = req.environ["patron.context"] authorize(context, "index") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) migrations = self.compute_api.get_migrations(context, req.GET) return {"migrations": output(migrations)}
def index(self, req): """Return all migrations in progress.""" context = req.environ['patron.context'] authorize(context, "index") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) migrations = self.compute_api.get_migrations(context, req.GET) return {'migrations': output(migrations)}
def index(self, req): """Returns a dict in the format: | {'hosts': [{'host_name': 'some.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.other.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'some.celly.host.name', | 'service': 'cells', | 'zone': 'internal'}, | {'host_name': 'console1.host.com', | 'service': 'consoleauth', | 'zone': 'internal'}, | {'host_name': 'network1.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'netwwork2.host.com', | 'service': 'network', | 'zone': 'internal'}, | {'host_name': 'compute1.host.com', | 'service': 'compute', | 'zone': 'patron'}, | {'host_name': 'compute2.host.com', | 'service': 'compute', | 'zone': 'patron'}, | {'host_name': 'sched1.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'sched2.host.com', | 'service': 'scheduler', | 'zone': 'internal'}, | {'host_name': 'vol1.host.com', | 'service': 'volume', | 'zone': 'internal'}]} """ context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) filters = {'disabled': False} zone = req.GET.get('zone', None) if zone: filters['availability_zone'] = zone services = self.api.service_get_all(context, filters=filters, set_zones=True) hosts = [] for service in services: hosts.append({'host_name': service['host'], 'service': service['topic'], 'zone': service['availability_zone']}) return {'hosts': hosts}
def update(self, req, id, body): """Enable/Disable scheduling for a service.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) ext_loaded = self.ext_mgr.is_loaded('os-extended-services') if id == "enable": disabled = False status = "enabled" elif (id == "disable" or (id == "disable-log-reason" and ext_loaded)): disabled = True status = "disabled" else: msg = _("Unknown action") raise webob.exc.HTTPNotFound(explanation=msg) try: host = body['host'] binary = body['binary'] ret_value = { 'service': { 'host': host, 'binary': binary, 'status': status, }, } status_detail = { 'disabled': disabled, 'disabled_reason': None, } if id == "disable-log-reason": reason = body['disabled_reason'] if not self._is_valid_as_reason(reason): msg = _('The string containing the reason for disabling ' 'the service contains invalid characters or is ' 'too long.') raise webob.exc.HTTPBadRequest(explanation=msg) status_detail['disabled_reason'] = reason ret_value['service']['disabled_reason'] = reason except (TypeError, KeyError): msg = _('Invalid attribute in the request') if 'host' in body and 'binary' in body: msg = _('Missing disabled reason field') raise webob.exc.HTTPBadRequest(explanation=msg) try: self.host_api.service_update(context, host, binary, status_detail) except exception.HostBinaryNotFound as e: raise webob.exc.HTTPNotFound(explanation=e.format_message()) return ret_value
def delete(self, req, id): """Deletes an existing agent build.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) try: agent = objects.Agent(context=context, id=id) agent.destroy() except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message())
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) try: para = body['para'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except (TypeError, KeyError) as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) try: utils.check_string_length(url, 'url', max_length=255) utils.check_string_length(md5hash, 'md5hash', max_length=255) utils.check_string_length(version, 'version', max_length=255) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) try: agent = objects.Agent(context=context, id=id) agent.obj_reset_changes() agent.version = version agent.url = url agent.md5hash = md5hash agent.save() except ValueError as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message()) # NOTE(alex_xu): The agent_id should be integer that consistent with # create/index actions. But parameter 'id' is string type that parsed # from url. This is a bug, but because back-compatibility, it can't be # fixed for v2 API. This will be fixed after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return { "agent": { 'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash } }
def delete(self, req, id): """Deletes the specified service.""" if not self.ext_mgr.is_loaded('os-extended-services-delete'): raise webob.exc.HTTPMethodNotAllowed() context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) try: self.host_api.service_delete(context, id) except exception.ServiceNotFound: explanation = _("Service %s not found.") % id raise webob.exc.HTTPNotFound(explanation=explanation)
def create(self, req, body): """Creates a new agent build.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) try: agent = body['agent'] hypervisor = agent['hypervisor'] os = agent['os'] architecture = agent['architecture'] version = agent['version'] url = agent['url'] md5hash = agent['md5hash'] except (TypeError, KeyError) as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) try: utils.check_string_length(hypervisor, 'hypervisor', max_length=255) utils.check_string_length(os, 'os', max_length=255) utils.check_string_length(architecture, 'architecture', max_length=255) utils.check_string_length(version, 'version', max_length=255) utils.check_string_length(url, 'url', max_length=255) utils.check_string_length(md5hash, 'md5hash', max_length=255) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) try: agent_obj = objects.Agent(context=context) agent_obj.hypervisor = hypervisor agent_obj.os = os agent_obj.architecture = architecture agent_obj.version = version agent_obj.url = url agent_obj.md5hash = md5hash agent_obj.create() agent['agent_id'] = agent_obj.id except exception.AgentBuildExists as ex: raise webob.exc.HTTPConflict(explanation=ex.format_message()) return {'agent': agent}
def index(self, req, flavor_id): context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) try: flavor = objects.Flavor.get_by_flavor_id(context, flavor_id) except exception.FlavorNotFound: explanation = _("Flavor not found.") raise webob.exc.HTTPNotFound(explanation=explanation) # public flavor to all projects if flavor.is_public: explanation = _("Access list not available for public flavors.") raise webob.exc.HTTPNotFound(explanation=explanation) # private flavor to listed projects only return _marshall_flavor_access(flavor)
def update(self, req, id, body): """Update an existing agent build.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) try: para = body['para'] url = para['url'] md5hash = para['md5hash'] version = para['version'] except (TypeError, KeyError) as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) try: utils.check_string_length(url, 'url', max_length=255) utils.check_string_length(md5hash, 'md5hash', max_length=255) utils.check_string_length(version, 'version', max_length=255) except exception.InvalidInput as exc: raise webob.exc.HTTPBadRequest(explanation=exc.format_message()) try: agent = objects.Agent(context=context, id=id) agent.obj_reset_changes() agent.version = version agent.url = url agent.md5hash = md5hash agent.save() except ValueError as ex: msg = _("Invalid request body: %s") % ex raise webob.exc.HTTPBadRequest(explanation=msg) except exception.AgentBuildNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.format_message()) # NOTE(alex_xu): The agent_id should be integer that consistent with # create/index actions. But parameter 'id' is string type that parsed # from url. This is a bug, but because back-compatibility, it can't be # fixed for v2 API. This will be fixed after v3 API feature exposed by # micro-version in the future. lp bug #1333494 return {"agent": {'agent_id': id, 'version': version, 'url': url, 'md5hash': md5hash}}
def _get_services(self, req): context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) services = self.host_api.service_get_all(context, set_zones=True) host = '' if 'host' in req.GET: host = req.GET['host'] binary = '' if 'binary' in req.GET: binary = req.GET['binary'] if host: services = [s for s in services if s['host'] == host] if binary: services = [s for s in services if s['binary'] == binary] return services
def _removeTenantAccess(self, req, id, body): context = req.environ['patron.context'] authorize(context, action="removeTenantAccess") # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) self._check_body(body) vals = body['removeTenantAccess'] tenant = vals.get('tenant') if not tenant: msg = _("Missing tenant parameter") raise webob.exc.HTTPBadRequest(explanation=msg) flavor = objects.Flavor(context=context, flavorid=id) try: flavor.remove_access(tenant) except (exception.FlavorNotFound, exception.FlavorAccessNotFound) as err: raise webob.exc.HTTPNotFound(explanation=err.format_message()) return _marshall_flavor_access(flavor)
def index(self, req): """Return a list of all agent builds. Filter by hypervisor.""" context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) hypervisor = None agents = [] if 'hypervisor' in req.GET: hypervisor = req.GET['hypervisor'] builds = objects.AgentList.get_all(context, hypervisor=hypervisor) for agent_build in builds: agents.append({'hypervisor': agent_build.hypervisor, 'os': agent_build.os, 'architecture': agent_build.architecture, 'version': agent_build.version, 'md5hash': agent_build.md5hash, 'agent_id': agent_build.id, 'url': agent_build.url}) return {'agents': agents}
def _get_services(self, req): context = req.environ['patron.context'] authorize(context) # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks patron_context.require_admin_context(context) services = self.host_api.service_get_all( context, set_zones=True) host = '' if 'host' in req.GET: host = req.GET['host'] binary = '' if 'binary' in req.GET: binary = req.GET['binary'] if host: services = [s for s in services if s['host'] == host] if binary: services = [s for s in services if s['binary'] == binary] return services
def _get_audit_task_logs(self, context, begin=None, end=None, before=None): """Returns a full log for all instance usage audit tasks on all computes. :param begin: datetime beginning of audit period to get logs for, Defaults to the beginning of the most recently completed audit period prior to the 'before' date. :param end: datetime ending of audit period to get logs for, Defaults to the ending of the most recently completed audit period prior to the 'before' date. :param before: By default we look for the audit period most recently completed before this datetime. Has no effect if both begin and end are specified. """ # NOTE(alex_xu): back-compatible with db layer hard-code admin # permission checks. patron_context.require_admin_context(context) defbegin, defend = utils.last_completed_audit_period(before=before) if begin is None: begin = defbegin if end is None: end = defend task_logs = self.host_api.task_log_get_all(context, "instance_usage_audit", begin, end) # We do this this way to include disabled compute services, # which can have instances on them. (mdragon) filters = {'topic': CONF.compute_topic} services = self.host_api.service_get_all(context, filters=filters) hosts = set(serv['host'] for serv in services) seen_hosts = set() done_hosts = set() running_hosts = set() total_errors = 0 total_items = 0 for tlog in task_logs: seen_hosts.add(tlog['host']) if tlog['state'] == "DONE": done_hosts.add(tlog['host']) if tlog['state'] == "RUNNING": running_hosts.add(tlog['host']) total_errors += tlog['errors'] total_items += tlog['task_items'] log = {tl['host']: dict(state=tl['state'], instances=tl['task_items'], errors=tl['errors'], message=tl['message']) for tl in task_logs} missing_hosts = hosts - seen_hosts overall_status = "%s hosts done. %s errors." % ( 'ALL' if len(done_hosts) == len(hosts) else "%s of %s" % (len(done_hosts), len(hosts)), total_errors) return dict(period_beginning=str(begin), period_ending=str(end), num_hosts=len(hosts), num_hosts_done=len(done_hosts), num_hosts_running=len(running_hosts), num_hosts_not_run=len(missing_hosts), hosts_not_run=list(missing_hosts), total_instances=total_items, total_errors=total_errors, overall_status=overall_status, log=log)