Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
    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))
        ]
Beispiel #4
0
 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)
Beispiel #5
0
    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)
Beispiel #6
0
    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))
        ]
Beispiel #7
0
    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)
Beispiel #8
0
    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)
        ]