Esempio n. 1
0
    def _handle_update_eipInfo(self, prop_diff):
        eip_update = prop_diff.get(self.EIP)
        allocation_id_update = prop_diff.get(self.ALLOCATION_ID)
        instance_id = self.properties[self.INSTANCE_ID]
        ni_id = self.properties[self.NETWORK_INTERFACE_ID]
        if eip_update:
            server = self._floatingIp_detach(neutron_ignore_not_found=True)
            if server:
                # then to attach the eip_update to the instance
                server.add_floating_ip(eip_update)
                self.resource_id_set(eip_update)
        elif allocation_id_update:
            self._floatingIp_detach(nova_ignore_not_found=True)
            port_id, port_rsrc = self._get_port_info(ni_id, instance_id)
            if not port_id or not port_rsrc:
                LOG.error(_LE('Port not specified.'))
                raise exception.NotFound(
                    _('Failed to update, can not found '
                      'port info.'))

            network_id = port_rsrc['network_id']
            self._neutron_add_gateway_router(allocation_id_update, network_id)
            self._neutron_update_floating_ip(allocation_id_update, port_id)
            self.resource_id_set(allocation_id_update)
Esempio n. 2
0
 def refresh(self):
     db_stack = db_api.stack_get(self._context, self.id, show_deleted=True)
     if db_stack is None:
         message = _('No stack exists with id "%s"') % str(self.id)
         raise exception.NotFound(message)
     return self.__class__._from_db_object(self._context, self, db_stack)
Esempio n. 3
0
def resource_get_all(context):
    results = model_query(context, models.Resource).all()

    if not results:
        raise exception.NotFound(_('no resources were found'))
    return results
Esempio n. 4
0
    def handle_signal(self, details=None):
        # Template author can use scaling policy with any of the actions
        # of an alarm (i.e alarm_actions, insufficient_data_actions) and
        # it would be actioned irrespective of the alarm state. It's
        # fair to assume that the alarm state would be the appropriate one.
        # The responsibility of using a scaling policy with desired actions
        # lies with the template author, though this is normally expected to
        # be used with 'alarm_actions'.
        #
        # We also assume that the alarm state is 'alarm' when 'details' is None
        # or no 'current'/'state' key in 'details'. Watchrule has upper case
        # states, so we lower() them. This is only used for logging the alarm
        # state.

        if details is None:
            alarm_state = 'alarm'
        else:
            alarm_state = details.get('current', details.get('state',
                                                             'alarm')).lower()

        LOG.info('Alarm %(name)s, new state %(state)s', {
            'name': self.name,
            'state': alarm_state
        })

        asgn_id = self.properties[self.AUTO_SCALING_GROUP_NAME]
        group = self.stack.resource_by_refid(asgn_id)

        if group is None:
            raise exception.NotFound(
                _('Alarm %(alarm)s could not find '
                  'scaling group named "%(group)s"') % {
                      'alarm': self.name,
                      'group': asgn_id
                  })

        self._check_scaling_allowed(self.properties[self.COOLDOWN])

        LOG.info(
            '%(name)s alarm, adjusting group %(group)s with id '
            '%(asgn_id)s by %(filter)s', {
                'name': self.name,
                'group': group.name,
                'asgn_id': asgn_id,
                'filter': self.properties[self.SCALING_ADJUSTMENT]
            })

        size_changed = False
        try:
            with group.frozen_properties():
                group.adjust(self.properties[self.SCALING_ADJUSTMENT],
                             self.properties[self.ADJUSTMENT_TYPE],
                             self.properties[self.MIN_ADJUSTMENT_STEP])
            size_changed = True
        except resource.NoActionRequired:
            raise
        except Exception:
            LOG.error(
                "Error in performing scaling adjustment with "
                "%(name)s alarm for group %(group)s.", {
                    'name': self.name,
                    'group': group.name
                })
            raise
        finally:
            self._finished_scaling(self.properties[self.COOLDOWN],
                                   "%s : %s" %
                                   (self.properties[self.ADJUSTMENT_TYPE],
                                    self.properties[self.SCALING_ADJUSTMENT]),
                                   size_changed=size_changed)
Esempio n. 5
0
    def get_attribute(self, key, *path):  # noqa: C901
        if key == self.CURRENT_SIZE:
            return grouputils.get_size(self)

        op_key = key
        op_path = path
        keycomponents = None
        if key == self.OUTPUTS_LIST:
            op_key = self.OUTPUTS
        elif key == self.REFS:
            op_key = self.REFS_MAP
        elif key.startswith("resource."):
            keycomponents = key.split('.', 2)
            if len(keycomponents) > 2:
                op_path = (keycomponents[2], ) + path
            op_key = self.OUTPUTS if op_path else self.REFS_MAP
        try:
            output = self.get_output(
                self._attribute_output_name(op_key, *op_path))
        except (exception.NotFound, exception.TemplateOutputError) as op_err:
            LOG.debug('Falling back to grouputils due to %s', op_err)

            if key == self.REFS:
                return grouputils.get_member_refids(self)
            if key == self.REFS_MAP:
                members = grouputils.get_members(self)
                return {m.name: m.resource_id for m in members}
            if path and key in {self.OUTPUTS, self.OUTPUTS_LIST}:
                members = grouputils.get_members(self)
                attrs = ((rsrc.name, rsrc.FnGetAtt(*path)) for rsrc in members)
                if key == self.OUTPUTS:
                    return dict(attrs)
                if key == self.OUTPUTS_LIST:
                    return [value for name, value in attrs]
            if keycomponents is not None:
                return grouputils.get_nested_attrs(self, key, True, *path)
        else:
            if key in {self.REFS, self.REFS_MAP}:
                names = self._group_data().member_names(False)
                if key == self.REFS:
                    return [output[n] for n in names if n in output]
                else:
                    return {n: output[n] for n in names if n in output}

            if path and key in {self.OUTPUTS_LIST, self.OUTPUTS}:
                names = self._group_data().member_names(False)
                if key == self.OUTPUTS_LIST:
                    return [output[n] for n in names if n in output]
                else:
                    return {n: output[n] for n in names if n in output}

            if keycomponents is not None:
                names = list(self._group_data().member_names(False))
                index = keycomponents[1]
                try:
                    resource_name = names[int(index)]
                    return output[resource_name]
                except (IndexError, KeyError):
                    raise exception.NotFound(
                        _("Member '%(mem)s' not found "
                          "in group resource '%(grp)s'.") % {
                              'mem': index,
                              'grp': self.name
                          })

        raise exception.InvalidTemplateAttribute(resource=self.name, key=key)
Esempio n. 6
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)
Esempio n. 7
0
    def handle_signal(self, details=None):
        # ceilometer sends details like this:
        # {u'alarm_id': ID, u'previous': u'ok', u'current': u'alarm',
        #  u'reason': u'...'})
        # in this policy we currently assume that this gets called
        # only when there is an alarm. But the template writer can
        # put the policy in all the alarm notifiers (nodata, and ok).
        #
        # our watchrule has upper case states so lower() them all.
        if details is None:
            alarm_state = 'alarm'
        else:
            alarm_state = details.get('current', details.get('state',
                                                             'alarm')).lower()

        LOG.info(_LI('Alarm %(name)s, new state %(state)s'), {
            'name': self.name,
            'state': alarm_state
        })

        if alarm_state != 'alarm':
            raise exception.NoActionRequired()

        asgn_id = self.properties[self.AUTO_SCALING_GROUP_NAME]
        group = self.stack.resource_by_refid(asgn_id)

        if group is None:
            raise exception.NotFound(
                _('Alarm %(alarm)s could not find '
                  'scaling group named "%(group)s"') % {
                      'alarm': self.name,
                      'group': asgn_id
                  })

        if not self._is_scaling_allowed():
            LOG.info(
                _LI("%(name)s NOT performing scaling action, "
                    "cooldown %(cooldown)s") % {
                        'name': self.name,
                        'cooldown': self.properties[self.COOLDOWN]
                    })
            raise exception.NoActionRequired()

        LOG.info(
            _LI('%(name)s alarm, adjusting group %(group)s with id '
                '%(asgn_id)s by %(filter)s') % {
                    'name': self.name,
                    'group': group.name,
                    'asgn_id': asgn_id,
                    'filter': self.properties[self.SCALING_ADJUSTMENT]
                })

        size_changed = False
        try:
            group.adjust(self.properties[self.SCALING_ADJUSTMENT],
                         self.properties[self.ADJUSTMENT_TYPE],
                         self.properties[self.MIN_ADJUSTMENT_STEP])
            size_changed = True
        except Exception as ex:
            if not isinstance(ex, exception.NoActionRequired):
                LOG.error(
                    _LE("Error in performing scaling adjustment with "
                        "%(name)s alarm for group %(group)s.") % {
                            'name': self.name,
                            'group': group.name
                        })
            raise
        finally:
            self._finished_scaling("%s : %s" %
                                   (self.properties[self.ADJUSTMENT_TYPE],
                                    self.properties[self.SCALING_ADJUSTMENT]),
                                   size_changed=size_changed)
Esempio n. 8
0
 def find_name_id(self, entity=None, src_value='far'):
     if check_error:
         raise exception.NotFound()
     if entity == 'rose':
         return 'pink'
     return 'yellow'