예제 #1
0
    def _verify_request(self):
        if len(self) == 0:
            raise InvalidBllRequestException('No request')

        # txn_id is required when requesting a job status update
        if self.is_job_status_request() and not self.get(api.TXN_ID):
            raise InvalidBllRequestException('No txn_id')
    def _add_users_op(self):

        user = self.data.get('username')
        password = self.data.get('password')
        email = self.data.get('email')
        project_name = self.data.get('project_name')

        projects = self.client.projects.list()

        for project in projects:
            if project.name == project_name:
                project_id = project.id
                break
        else:
            raise InvalidBllRequestException(
                self._("Invalid project: {}").format(project_name))

        keystone_user = self.client.users.create(name=user,
                                                 password=password,
                                                 email=email,
                                                 project_id=project_id)

        self._add_role_to_user(keystone_user, ADMIN, project_id)
        # Monasca user required for dashboard stats
        self._add_role_to_user(keystone_user, MONASCA, project_id)

        return copy.copy(keystone_user.id.encode('ascii', 'ignore'))
예제 #3
0
    def _get_alarm_count(self):

        data = self.request.get_data()

        # Was there a dimension_name_filter given?
        dim_name_filter_str = data.pop('dimension_name_filter', None)
        if dim_name_filter_str:
            dim_name_filters = [
                str.strip() for str in dim_name_filter_str.split(',')
            ]
            # make sure dimension dimension_name is in group_by
            if 'group_by' not in data.keys() \
                    or 'dimension_name' not in data['group_by']:
                raise InvalidBllRequestException(
                    self._('cannot filter on dimension_name_filter: {} '
                           'without a group_by on dimension_name').format(
                               dim_name_filter_str))
        else:
            dim_name_filters = None

        # Monasca has a 10K limit from alarm-count and we want all of them, so
        # page thru all of them
        limit = 10000
        offset = 0
        all_counts = []
        while True:
            data['limit'] = limit
            data['offset'] = offset
            alarm_counts = self.client.alarms.count(**data)
            columns = alarm_counts['columns']
            counts = alarm_counts['counts']

            # Handle the situation where we hit a page boundary (i.e. have no
            # more items at all
            # This happens when the next page returns something like
            # counts = [[0, None, None, .....] where the first entry is
            # 0 and subsequent elements are all 'None'
            if len(counts) == 1 and \
                len(counts[0]) > 1 and \
                counts[0][1] is None:
                break

            all_counts.extend(counts)
            if len(counts) < limit:
                # we got it all, so no need to get any more
                break
            offset += limit

        # Do we need to do any filtering?
        if dim_name_filters:
            dim_idx = columns.index('dimension_name')
            filtered_counts = [
                c for c in all_counts if c[dim_idx] in dim_name_filters
            ]
            all_counts = filtered_counts

        return {'columns': columns, 'counts': all_counts}
예제 #4
0
    def handle(self):
        """
        Handle the request by dispatching the request to the appropriate
        method.  Override this method if desired, to implement your own
        dispatching and execution of short-running work.
        """
        if not self.operation and not self.action:
            raise InvalidBllRequestException(
                self._("Operation and action missing"))

        method = self._get_method(self.operation, self.action)
        if method is None:
            raise InvalidBllRequestException(
                self._("Unsupported operation: {}").format(self.operation))

        if getattr(method, 'is_long', False):
            self.response[api.PROGRESS] = dict(percentComplete=0)
            self.response[api.STATUS] = api.STATUS_INPROGRESS
            polling_interval = 10

            if method.im_func.func_code.co_argcount > 1:
                # If the long-running method expects an argument, call it
                # set to True and expect a polling interval in return
                polling_interval = method(True) or polling_interval

            self.response[api.POLLING_INTERVAL] = \
                getattr(self, api.POLLING_INTERVAL, 10)

            self.update_job_status(percentage_complete=0)
            return self.response

        data = method()

        # In cases where we don't have the data in the response, it
        # had better be in the return value.
        #    i.e. compute_summary_service: resource_history()
        if not self.response[api.DATA]:
            self.response[api.DATA] = data

        self.response[api.PROGRESS] = dict(percentComplete=100)
        self.response.complete()
        return self.response
예제 #5
0
    def run_playbook(self, validate):
        """
        Performs an ansible playbook operation.

        Request format::

            "target": "ardana",
            "operation": "run_playbook",
            "data": {
                "playbook_name": "MYPLAYBOOK",    # REQUIRED
                "playbook_PARAM1": "MYVALUE",     # OPTIONAL
                ...
            }
        """

        if validate:
            playbook_name = self.data.pop('playbook_name', None)
            if not playbook_name:
                raise InvalidBllRequestException('unspecified playbook '
                                                 'to run')

            # Initiate the request and get its reference
            req_path = 'playbooks/' + playbook_name
            resp = self._request(req_path, body=self.data, action='POST')
            self.ref_id = resp['id']
            self.status_path = 'plays/' + self.ref_id
            self.update_job_status(resp, 25)
            return
        else:
            still_alive = True
            try:
                while still_alive:
                    poll_resp = self._request(self.status_path)
                    still_alive = poll_resp.get('alive', False)
                    if still_alive:
                        self.update_job_status(poll_resp, 50)
                        time.sleep(self.TASK_POLL_INTERVAL)
                    # We have no idea how long a playbook is going to take
                return poll_resp
            except Exception as e:
                LOG.exception(e)
                self.response.error(
                    self.
                    _('Unknown error occurred, please refer to the following '
                      'ardana log: {}').format(self.ref_id))
                return self.response
예제 #6
0
    def __init__(self, bll_request=None):
        super(SvcBase, self).__init__()

        # Extract common fields into attributes
        if not isinstance(bll_request, BllRequest):
            raise InvalidBllRequestException('Invalid request class')
        self.request = bll_request
        self.response = BllResponse(self.request)
        if api.AUTH_TOKEN in self.request:
            self.token_helper = TokenHelpers(self.request.get(api.AUTH_TOKEN))
            self.token = self.request.get(api.AUTH_TOKEN)

        request_data = self.request.get(api.DATA, {})
        self.action = self.request.get(api.ACTION)

        self.api_version = None
        self.operation = None
        self.data = {}
        self.txn_id = self.request.txn_id
        self.region = self.request.get(api.REGION)

        # Assign _ as a member variable in this plugin class for localizing
        # messages
        self._ = i18n.get_(self.request.get(api.LANGUAGE, 'en'))

        # Extract request data, filtering out known keys
        for k, v in request_data.iteritems():
            if k == api.OPERATION:
                self.operation = v
            elif k == 'suggest_sync':
                # Omit the obsolete, poorly-supported suggest_sync flag
                pass
            elif k == api.VERSION:
                self.api_version = v
            else:
                self.data[k] = v
    def edit_vcenter(self, validate):
        """
        Edit the vCenter in eon

        Request format::

            "target": "vcenters",
            "action": "PUT",
            "operation": "edit_vcenter",
            "data": {
                "data" : {
                    "id": "39587235",
                    "name": "vcenter1",
                    "username": "******",
                    "password": "******",
                    "ip_address": "192.168.10.40"
                }
            }
        """
        datadata = self.data[api.DATA]

        if validate:
            if not datadata or 'id' not in datadata:
                raise InvalidBllRequestException(
                    self._("Invalid or incomplete vCenter id passed"))

            if self.eon_client:
                eon_vcenter = self.eon_client.get_resource_mgr(datadata['id'])
                if not eon_vcenter:
                    raise InvalidBllRequestException(
                        self._("vCenter is not registered"))
            return

        vcenter_id = datadata.pop('id')

        update_vcenter_cache(vcenter_id, UPDATING_STATE)

        # Remove type if present
        datadata.pop('type', None)

        eon_updated = False
        try:
            if self.eon_client:
                self.eon_client.update_resource_mgr(vcenter_id, datadata)
                eon_response = self.eon_client.get_resource_mgr(vcenter_id)
                while eon_response['meta_data'][0]['value'] == "updating":
                    time.sleep(10)
                    eon_response = self.eon_client.get_resource_mgr(vcenter_id)
                    self.update_job_status(percentage_complete=10)
                self.update_job_status(percentage_complete=50)
                eon_updated = True

                self.update_job_status(percentage_complete=75)

            return self.response

        except Exception as e:
            if eon_updated:
                raise Exception(
                    self._("{0}. vCenter {1} is partially "
                           "updated").format(e, datadata['name']))
            raise e

        finally:
            remove_vcenter_cache(vcenter_id)