def _paginate_query(context, query, model, limit=None, sort_keys=None, marker=None, sort_dir=None): default_sort_keys = ['created_at'] if not sort_keys: sort_keys = default_sort_keys if not sort_dir: sort_dir = 'desc' # This assures the order of the stacks will always be the same # even for sort_key values that are not unique in the database sort_keys = sort_keys + ['id'] model_marker = None if marker: model_marker = model_query(context, model).get(marker) try: query = utils.paginate_query(query, model, limit, sort_keys, model_marker, sort_dir) except utils.InvalidSortKey as exc: raise exception.Invalid(reason=exc.message) return query
def _events_paginate_query(context, query, model, limit=None, sort_keys=None, marker=None, sort_dir=None): default_sort_keys = ['created_at'] if not sort_keys: sort_keys = default_sort_keys if not sort_dir: sort_dir = 'desc' # This assures the order of the stacks will always be the same # even for sort_key values that are not unique in the database sort_keys = sort_keys + ['id'] model_marker = None if marker: # not to use model_query(context, model).get(marker), because # user can only see the ID(column 'uuid') and the ID as the marker model_marker = model_query(context, model).filter_by(uuid=marker).first() try: query = utils.paginate_query(query, model, limit, sort_keys, model_marker, sort_dir) except utils.InvalidSortKey as exc: raise exception.Invalid(reason=exc.message) return query
def get_types(self, cnxt=None, support_status=None, type_name=None, version=None): """Return a list of valid resource types.""" # validate the support status if support_status is not None and not support.is_valid_status( support_status): msg = (_('Invalid support status and should be one of %s') % six.text_type(support.SUPPORT_STATUSES)) raise exception.Invalid(reason=msg) def is_resource(key): return isinstance(self._registry[key], (ClassResourceInfo, TemplateResourceInfo)) def status_matches(cls): return (support_status is None or cls.get_class().support_status.status == support_status) def is_available(cls): if cnxt is None: return True return cls.get_class().is_service_available(cnxt) def not_hidden_matches(cls): return cls.get_class().support_status.status != support.HIDDEN def is_allowed(enforcer, name): if cnxt is None: return True try: enforcer.enforce(cnxt, name) except enforcer.exc: return False else: return True enforcer = policy.ResourceEnforcer() def name_matches(name): try: return type_name is None or re.match(type_name, name) except: # noqa return False def version_matches(cls): return (version is None or cls.get_class().support_status.version == version) return [ name for name, cls in six.iteritems(self._registry) if (is_resource(name) and name_matches(name) and status_matches( cls) and is_available(cls) and is_allowed(enforcer, name) and not_hidden_matches(cls) and version_matches(cls)) ]
def __new__(cls, context): if cfg.CONF.cloud_backend == _default_backend: return OpenStackClients(context) else: try: return importutils.import_object(cfg.CONF.cloud_backend, context) except (ImportError, RuntimeError, cfg.NoSuchOptError) as err: msg = _('Invalid cloud_backend setting in heat.conf ' 'detected - %s') % six.text_type(err) LOG.error(msg) raise exception.Invalid(reason=msg)
def handle_update(self, json_snippet=None, tmpl_diff=None, prop_diff=None): # We don't currently handle server group metadata in the stack. # The stack "best_effort" and "group_size" properties actually map to # nova server group metadata. Don't get confused. :) metadata = {} if self.BEST_EFFORT in prop_diff: best_effort = prop_diff[self.BEST_EFFORT] metadata[BEST_EFFORT_METAKEY] = str(best_effort).lower() if self.GROUP_SIZE in prop_diff: group_size = prop_diff[self.GROUP_SIZE] server_group = self.nova().server_groups.get(self.resource_id) if len(server_group.members) > group_size: raise exception.Invalid( reason='Cannot update with a group size ' 'smaller than the current number of ' 'servers in the group') metadata[GROUP_SIZE_METAKEY] = str(group_size) self.nova().server_groups.set_metadata(self.resource_id, metadata)
def get_types(self, cnxt=None, support_status=None, type_name=None, version=None, with_description=False): """Return a list of valid resource types.""" # validate the support status if support_status is not None and not support.is_valid_status( support_status): msg = (_('Invalid support status and should be one of %s') % str(support.SUPPORT_STATUSES)) raise exception.Invalid(reason=msg) def is_resource(key): return isinstance(self._registry[key], (ClassResourceInfo, TemplateResourceInfo)) def status_matches(cls): return (support_status is None or cls.get_class().support_status.status == support_status) def is_available(cls): if cnxt is None: return True try: return cls.get_class().is_service_available(cnxt)[0] except Exception: return False def not_hidden_matches(cls): return cls.get_class().support_status.status != support.HIDDEN def is_allowed(enforcer, name): if cnxt is None: return True try: enforcer.enforce(cnxt, name, is_registered_policy=True) except enforcer.exc: return False else: return True enforcer = policy.ResourceEnforcer() def name_matches(name): try: return type_name is None or re.match(type_name, name) except: # noqa return False def version_matches(cls): return (version is None or cls.get_class().support_status.version == version) import heat.engine.resource def resource_description(name, info, with_description): if not with_description: return name rsrc_cls = info.get_class() if rsrc_cls is None: rsrc_cls = heat.engine.resource.Resource return { 'resource_type': name, 'description': rsrc_cls.getdoc(), } return [ resource_description(name, cls, with_description) for name, cls in self._registry.items() if (is_resource(name) and name_matches(name) and status_matches( cls) and is_available(cls) and is_allowed(enforcer, name) and not_hidden_matches(cls) and version_matches(cls)) ]
def _do_request(self, method, url, body, headers): """ Connects to the server and issues a request. Handles converting any returned HTTP error status codes to OpenStack/heat exceptions and closing the server connection. Returns the result data, or raises an appropriate exception. :param method: HTTP method ("GET", "POST", "PUT", etc...) :param url: urlparse.ParsedResult object with URL information :param body: data to send (as string, filelike or iterable), or None (default) :param headers: mapping of key/value pairs to add as headers :note If the body param has a read attribute, and method is either POST or PUT, this method will automatically conduct a chunked-transfer encoding and use the body as a file object or iterable, transferring chunks of data using the connection's send() method. This allows large objects to be transferred efficiently without buffering the entire body in memory. """ if url.query: path = url.path + "?" + url.query else: path = url.path try: connection_type = self.get_connection_type() headers = headers or {} if 'x-auth-token' not in headers and self.auth_tok: headers['x-auth-token'] = self.auth_tok c = connection_type(url.hostname, url.port, **self.connect_kwargs) def _pushing(method): return method.lower() in ('post', 'put') def _simple(body): return body is None or isinstance(body, basestring) def _filelike(body): return hasattr(body, 'read') def _sendbody(connection, iter): connection.endheaders() for sent in iter: # iterator has done the heavy lifting pass def _chunkbody(connection, iter): connection.putheader('Transfer-Encoding', 'chunked') connection.endheaders() for chunk in iter: connection.send('%x\r\n%s\r\n' % (len(chunk), chunk)) connection.send('0\r\n\r\n') # Do a simple request or a chunked request, depending # on whether the body param is file-like or iterable and # the method is PUT or POST # if not _pushing(method) or _simple(body): # Simple request... c.request(method, path, body, headers) elif _filelike(body) or self._iterable(body): c.putrequest(method, path) for header, value in headers.items(): c.putheader(header, value) iter = self.image_iterator(c, headers, body) _chunkbody(c, iter) else: raise TypeError('Unsupported image type: %s' % body.__class__) res = c.getresponse() def _retry(res): return res.getheader('Retry-After') status_code = self.get_status_code(res) if status_code in self.OK_RESPONSE_CODES: return res elif status_code in self.REDIRECT_RESPONSE_CODES: raise exception.RedirectException(res.getheader('Location')) elif status_code == httplib.UNAUTHORIZED: raise exception.NotAuthorized() elif status_code == httplib.FORBIDDEN: raise exception.NotAuthorized() elif status_code == httplib.NOT_FOUND: raise exception.NotFound(res.read()) elif status_code == httplib.CONFLICT: raise exception.Duplicate(res.read()) elif status_code == httplib.BAD_REQUEST: raise exception.Invalid(reason=res.read()) elif status_code == httplib.MULTIPLE_CHOICES: raise exception.MultipleChoices(body=res.read()) elif status_code == httplib.REQUEST_ENTITY_TOO_LARGE: raise exception.LimitExceeded(retry=_retry(res), body=res.read()) elif status_code == httplib.INTERNAL_SERVER_ERROR: raise Exception("Internal Server error: %s" % res.read()) elif status_code == httplib.SERVICE_UNAVAILABLE: raise exception.ServiceUnavailable(retry=_retry(res)) elif status_code == httplib.REQUEST_URI_TOO_LONG: raise exception.RequestUriTooLong(body=res.read()) else: raise Exception("Unknown error occurred! %s" % res.read()) except (socket.error, IOError), e: raise exception.ClientConnectionError(e)
def get_types(self, cnxt=None, support_status=None, type_name=None, version=None, with_description=False): """Return a list of valid resource types.""" # validate the support status if support_status is not None and not support.is_valid_status( support_status): msg = (_('Invalid support status and should be one of %s') % str(support.SUPPORT_STATUSES)) raise exception.Invalid(reason=msg) enforcer = policy.ResourceEnforcer() if type_name is not None: try: name_exp = re.compile(type_name) except Exception: return [] else: name_exp = None def matches(name, info): # Only return actual plugins or template resources, not aliases if not isinstance(info, (ClassResourceInfo, TemplateResourceInfo)): return False # If filtering by name, check for match if name_exp is not None and not name_exp.match(name): return False rsrc_cls = info.get_class_to_instantiate() # Never match hidden resource types if rsrc_cls.support_status.status == support.HIDDEN: return False # If filtering by version, check for match if (version is not None and rsrc_cls.support_status.version != version): return False # If filtering by support status, check for match if (support_status is not None and rsrc_cls.support_status.status != support_status): return False if cnxt is not None: # Check for resource policy try: enforcer.enforce(cnxt, name, is_registered_policy=True) except enforcer.exc: return False # Check for service availability try: avail, err = rsrc_cls.is_service_available(cnxt) except Exception: avail = False if not avail: return False return True import heat.engine.resource def resource_description(name, info): if not with_description: return name rsrc_cls = info.get_class() if rsrc_cls is None: rsrc_cls = heat.engine.resource.Resource return { 'resource_type': name, 'description': rsrc_cls.getdoc(), } return [ resource_description(name, info) for name, info in self._registry.items() if matches(name, info) ]