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'))
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}
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
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
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)