def _update_total_meters_count(request, filters): ''' Temporarily stores total_meters_count into session for speeding up queries Result expires after 1000 seconds or filter criteria has changed. :param request: Django request object criteria: :return: (int) total meters' count ''' if 'limit' in filters: filters.pop('limit') if 'skip' in filters: filters.pop('skip') if 'total_meters_count' in request.session: refreshed_time = request.session['refreshed_time'] delta = time.time() - refreshed_time if delta < 1000 and request.session['criteria_hash'] == filters: return request.session['refreshed_time'] = time.time() request.session['criteria_hash'] = filters # TODO: Error handling for hashing meter_list # Resend the request purged of limit and skip to get total record number token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: meter_list = new_ceilometer_api.get_meters(**filters) request.session['total_meters_count'] = len(meter_list) except (err.ClientSideError, err.ServerSideError), e: request.session['total_meters_count'] = 0 return _report_error(e.message)
def get_alarms(request): ''' Fetch alarms for a query. Filter options supported by Ceilometer includes: name: alarm name, user: user_id, project: project_id, meter: meter_name enabled, state, alarm_id, alarm_type Additional filter enabled by editing pymongo_base: resource: resource_id :param request: :return: ''' arrays, filters = _request_GET_to_dict(request.GET) filters = sanitize_arguments(filters, capabilities.ALARM_LIST_CAPABILITIES) token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: result = {} result['status'] = 'success' result['data'] = new_ceilometer_api.get_alarms(**filters) result['recordsTotal'] = len(result['data']) result['recordsFiltered'] = len(result['data']) print 'success' return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: print 'fail' return _report_error(e.message)
def post_alarm(request): ''' Post new alarms through ceilometer API. Notice: This api is protected by csrf_protect. 'X-csrf-token' should be added to request headers . :param request: :return: (JSON) Result of posting new alarm. Return state: 'success' or 'error' ''' token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) if request.method == 'POST': kwargs = sanitize_arguments(_request_GET_to_dict(request.POST, False), capabilities.ALARM_CAPABILITIES) q = [] try: q[0] = {} q[0]['value'] = kwargs.pop('resource_id') q[0]['field'] = 'resource_id' q[0]['op'] = 'eq' except NameError: q[0] = {} finally: kwargs['q'] = q result = {} try: new_ceilometer_api.post_threshold_alarm(**kwargs) result['status'] = 'success' return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def get_samples(request): ''' Get samples of every meter through ceilometer_api In a correctly constructed request, all arrays are treated as meters, while all independent values are treated as url parameters. Example: /api/meters/get-samples?limit=10&cpu_util[]=computer001&cpu_util[]=computer002 &cpu[]=computer001&skip=2 Resolved as: url_parameters = {'limit': 10, 'skip': 2} meters = {'cpu_util': ['computer001', 'computer002'], 'cpu':['computer001']} :param request: :return: ''' # TODO(pwwp): # Apply token management method instead of requesting one each time token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) meters, kwargs = _request_GET_to_dict(request.GET) result = [] try: for meter_name, resource_ids in meters.iteritems(): for i in range(len(resource_ids)): resource_id = resource_ids[i] result.append({ 'meter_name': meter_name, 'resource_id': resource_id, 'data': new_ceilometer_api.get_samples(meter_name, resource_id=resource_id, **kwargs) }) return HttpResponse(json.dumps({'data': result}), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def get_alarm_count(request): alarm_count = {'alarm': 0, 'ok': 0, 'insufficient_data': 0} token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: alarm_count['alarm'] = len(new_ceilometer_api.get_alarms(state='alarm')) alarm_count['ok'] = len(new_ceilometer_api.get_alarms(state='ok')) alarm_count['insufficient_data'] = len(new_ceilometer_api.get_alarms( state='insufficient+data')) return HttpResponse(json.dumps(alarm_count), content_type='application/json') except KeyError, e: return _report_error('ServerSideError: Alarm counting failed')
def get_alarm_detail(request): arrays = _request_GET_to_dict(request.GET, seperate_args_and_list=False) if 'alarm_id' not in arrays: return _report_error('KeyError: alarm_id not provided') alarm_id = arrays['alarm_id'] #filters = sanitize_arguments(filters, capabilities.ALARM_LIST_CAPABILITIES) token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: result = new_ceilometer_api.get_alarm_detail(alarm_id) return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def resource_detail(request, resource_id): ''' Get resource list through Ceilometer API :param request: Django request object :return: ''' arrays, filters = _request_GET_to_dict(request.GET) token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: result = new_ceilometer_api.get_resources(resource_id=resource_id) return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def delete_alarm(request, alarm_id): ''' Delete a given alarm :param request: Django request object :param alarm_id: id of an alarm :return: HTTPResponse (application/json) ''' token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: new_ceilometer_api.delete_alarm(alarm_id) result = {'data': 'Alarm ' + alarm_id + ' has been deleted.'} return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def get_alarm_count(request): alarm_count = {'alarm': 0, 'ok': 0, 'insufficient_data': 0} token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: alarm_count['alarm'] = len( new_ceilometer_api.get_alarms(state='alarm')) alarm_count['ok'] = len(new_ceilometer_api.get_alarms(state='ok')) alarm_count['insufficient_data'] = len( new_ceilometer_api.get_alarms(state='insufficient+data')) return HttpResponse(json.dumps(alarm_count), content_type='application/json') except KeyError, e: return _report_error('ServerSideError: Alarm counting failed')
def update_alarm_enabled(request, alarm_id): ''' Update the 'enabled' field of a given alarm :param request: (Django request) :param alarm_id: (string) id of an alarm :return: HTTPResponse (application/json) ''' # First fetch alarm data token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: alarm_data = new_ceilometer_api.get_alarm_detail(alarm_id) alarm_data['enabled'] = string_to_bool(request.GET['enabled']) result = new_ceilometer_api.update_threshold_alarm(alarm_id, alarm_data) return HttpResponse(json.dumps(result), content_type='application/json') except KeyError, e: return _report_error(str(e) + 'shall be provided')
def copy_alarm_to_resources(request): ''' # TODO:(pwwp) Not yet finished! :param request: :return: ''' # Fetch alarm data token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) if 'alarm_id' not in request.GET: return _report_error('"alarm_id" should be provided.') alarm_id = request.GET['alarm_id'] alarm_data = None try: alarm_data = new_ceilometer_api.get_alarm_detail(alarm_id) except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def update_alarm_enabled(request, alarm_id): ''' Update the 'enabled' field of a given alarm :param request: (Django request) :param alarm_id: (string) id of an alarm :return: HTTPResponse (application/json) ''' # First fetch alarm data token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: alarm_data = new_ceilometer_api.get_alarm_detail(alarm_id) alarm_data['enabled'] = string_to_bool(request.GET['enabled']) result = new_ceilometer_api.update_threshold_alarm( alarm_id, alarm_data) return HttpResponse(json.dumps(result), content_type='application/json') except KeyError, e: return _report_error(str(e) + 'shall be provided')
def get_resources(request): ''' Get resource list through Ceilometer API :param request: Django request object :return: ''' arrays, filters = _request_GET_to_dict(request.GET) filters = sanitize_arguments(filters, capabilities.RESOURCE_LIST_CAPABILITIES) token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) try: result = ceilometer_api.get_resources(token_id, **filters) return HttpResponse(json.dumps(result), content_type='application/json') except (err.ClientSideError, err.ServerSideError), e: return _report_error(e.message)
def get_meters(request): ''' :param request: :return: ''' # TODO(pwwp): # Enhance error handling for token and result # TODO(pwwp): # Apply token management method instead of requesting one each time token_id = request.session['token'].id new_ceilometer_api = CeilometerApi(token_id) arrays = {} filters = {} if request.method == 'GET': arrays, filters = _request_GET_to_dict(request.GET) # Deal with special parameters in filters = _rename_parameters(filters) elif request.method == 'POST': # POST method at /api/meter-list is triggered by datatables. # So I just deal with some special parameters in this POST request. args = json.loads(request.body) filters['limit'] = 0 if 'length' not in args else args['length'] filters['skip'] = 0 if 'start' not in args else args['start'] # argument 'q' is designed for supporting complex query, which have not # been implement on the back-end side. Thus, we unpack 'q' into # simple query form. # Example: q: {'resource_id': 'computer001'} # Output: filter['resource_id'] = 'computer001' try: if 'q' in args: for query_item in args['q']: filters[query_item['field']] = query_item['value'] except KeyError, e: # Currently malformated query objects(q) are ignored. pass