def get(self, name): result = database.get_computation_node_info(name) if not result: log.info('No such computation node %s', name) abort(404) log.info('Successfully get node %s info: %s', name, result) return result, 200
def get(self, name, device_id): result = database.get_power_limit_for_device(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info('Successfully get device %s:%s power limit info: %s', name, device_id, result) return result, 200
def get(self, name, device_id): result = database.get_stats_interval_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info('Successfully get device %s:%s statistics gathering interval info: %s', name, device_id, result) return result, 200
def delete(self, name, device_id): computation_node = abort_when_node_not_found(name) address = computation_node['address'] port = computation_node['port'] if not any(d['id'] == device_id for d in computation_node['backend_info']['devices']): log.error('There is no such device: %s', device_id) abort(404) [device_type] = [ d['Type'] for d in computation_node['backend_info']['devices'] if d['id'] == device_id ] result = database.delete_rule(name, device_id) try: resp = delete_power_limit(address, port, device_id, device_type) log.info('Power limit for device %s deletion info: %s', device_id, resp) except requests.exceptions.ConnectionError: log.error('Connection could not be established to node %s:%s', address, port) return 'Warning: power limit was deleted from database but could not be deleted from device!', 406 return result, 200
def post(self, name: str, device_id: str): rule = database.get_rule_for_device(name, device_id) if rule and rule.get('rule_type', "") == 'Withdrawable': rule['rule_params']['withdraw'] = True database.replace_rule_for_device(name, device_id, rule) return 'Rule successfully withdrawn', 201 log.info('Rule on the device was not Withdrawable') return 'Rule was not Withdrawable', 201
def get(self, name, device_id): result = database.get_rule_for_device(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info('Successfully get device %s:%s rule: %s', name, device_id, result) return result, 200
def abort_when_node_not_found(name): node_info = database.get_computation_node_info(name) if not node_info: log.info('No such computation node info %s', name) abort(404) return node_info
def get(self, name, device_id): computation_node, dev_type = get_com_node_and_dev_type(name, device_id) result = get_constraints(computation_node['address'], computation_node['port'], device_id, dev_type) log.info( 'Successfully get device %s:%s power limit constraints info: %s', name, device_id, result) return result.json(), 200
def get(self, name, device_id): result = database.get_stats_interval_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info( 'Successfully get device %s:%s statistics gathering interval info: %s', name, device_id, result) return result, 200
def end_request(response_class): response_class.headers.add('Access-Control-Allow-Origin', '*') response_class.headers.add('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE') response_class.headers.add('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept') request.end_time = time.time() request_processing_time = '{0:.6f}'.format(request.end_time - request.start_time) log.info('REQUEST FINISHED (took %s seconds): %s %s %s', request_processing_time, request.real_ip, request.method, request.url) return response_class
def delete(self, name, device_id): result = database.delete_soft_limit_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info( 'Successfully removed soft limit for device %s:%s soft limit info: %s', name, device_id, result) return result, 200
def delete(self, name, device_id): abort_when_node_not_found(name) result = database.delete_stats_interval_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info('Successfully removed statistics gathering interval \ for device %s:%s statistics gathering interval info: %s', name, device_id, result) return result, 200
def delete(self, name, device_id): abort_when_node_not_found(name) result = database.delete_stats_interval_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) log.info( 'Successfully removed statistics gathering interval \ for device %s:%s statistics gathering interval info: %s', name, device_id, result) return result, 200
def delete(self, name): result_node_info = database.delete_computation_node_info(name) result_power_limit_info = database.delete_power_limit_infos(name) if not result_node_info: log.info('No such computation node %s', name) abort(404) if not result_power_limit_info: log.info('No such power limit info for node %s', name) abort(404) address = result_node_info.get('address') port = result_node_info.get('port') abort_when_port_invalid(port) for device in result_node_info['backend_info']['devices']: try: response = delete_power_limit(address, port, device['id'], device['Type']) log.info('Device %s deletion info: %s', device['id'], response) except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', address, port) abort(406) log.info( 'Successfully deleted node %s info and its power limit: %s %s', name, result_node_info, result_power_limit_info) return 204
def statistics_data_plot(name, device_id): computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) result = database.get_stats_data(name, device_id) if not result: log.info('No stats for device %s:%s', name, device_id) abort(404) res_list = sorted([(datetime.datetime.strptime(k, '%Y-%m-%dT%H:%M'), v) for k, v in result.items()]) list_to_return = [{k.strftime('%Y-%m-%dT%H:%M'): v} for k, v in res_list] log.info('Successfully get device %s:%s stats data info: %s', name, device_id, list_to_return) values = [] labels = [] for element in list_to_return: [val] = element.values() [lab] = element.keys() values.append(val) labels.append(lab) ind = np.arange(len(list_to_return)) # the x locations for the groups width = 0.2 # the width of the bars fig, usagePlot = plt.subplots() rects1 = usagePlot.bar((ind + width) / 2, values, width, color='r') # add some text for labels, title and axes ticks usagePlot.set_ylabel('Power usage [W]') usagePlot.set_title('Power usage for device') usagePlot.set_xticks((ind + width) / 2) usagePlot.set_xticklabels(labels) # ax.legend(rects1[0], 'Device 1') def autolabel(rects): # attach some text labels for rect in rects: height = rect.get_height() usagePlot.text(rect.get_x() + rect.get_width() / 2., 1.02 * height, '%d' % int(height), ha='center', va='bottom') autolabel(rects1) # plt.show() fig.savefig('/tmp/plot.png') # save the figure to file plt.close(fig) # close the figure return send_file('/tmp/plot.png')
def get(self, name, device_id): beginning = request.args.get('date_time_begin') end = request.args.get('date_time_end') if beginning: try: beginning = datetime.datetime.strptime(beginning, '%Y-%m-%dT%H:%M') except ValueError: abort(400) if end: try: end = datetime.datetime.strptime(end, '%Y-%m-%dT%H:%M') except ValueError: abort(400) if beginning and end and beginning > end: abort(400) computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) result = database.get_stats_data(name, device_id) if not result: log.info('No statistics for device %s:%s', name, device_id) abort(404) res_list = sorted([(datetime.datetime.strptime(k, '%Y-%m-%dT%H:%M'), v) for k, v in result.items()]) if beginning: _, beg_index = self._find(lambda t: t[0] >= beginning, res_list) else: beg_index = 0 if beg_index is None: return 404 if end: _, end_index = self._find(lambda t: t[0] > end, res_list) else: end_index = None list_to_return = res_list[beg_index:end_index] list_to_return = [{ k.strftime('%Y-%m-%dT%H:%M'): v } for k, v in list_to_return] log.info('Successfully get device %s:%s statistics data info: %s', name, device_id, list_to_return) return list_to_return, 200
def get(self, name, device_id): computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) db_records = database.get_last_power_usage(name, device_id) if not db_records or len(db_records) <= 0: log.info('No last power usage for device %s:%s', name, device_id) abort(404) sorted_result = sorted(zip(db_records.keys(), db_records.values()), key=lambda usage: usage[0], reverse=True) sorted_result = [u[1] for u in sorted_result if isinstance(u[1], int)] result = {'last_power_usage': sorted_result[0]} log.info('Successfully get device %s:%s last power usage info: %s', name, device_id, result) return result, 200
def get(self, name, device_id): beginning = request.args.get('date_time_begin') end = request.args.get('date_time_end') if beginning: try: beginning = datetime.datetime.strptime(beginning, '%Y-%m-%dT%H:%M') except ValueError: abort(400) if end: try: end = datetime.datetime.strptime(end, '%Y-%m-%dT%H:%M') except ValueError: abort(400) if beginning and end and beginning > end: abort(400) computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) result = database.get_stats_data(name, device_id) if not result: log.info('No statistics for device %s:%s', name, device_id) abort(404) res_list = sorted([(datetime.datetime.strptime(k, '%Y-%m-%dT%H:%M'), v) for k, v in result.items()]) if beginning: _, beg_index = self._find(lambda t: t[0] >= beginning, res_list) else: beg_index = 0 if beg_index is None: return 404 if end: _, end_index = self._find(lambda t: t[0] > end, res_list) else: end_index = None list_to_return = res_list[beg_index:end_index] list_to_return = [{k.strftime('%Y-%m-%dT%H:%M'): v} for k, v in list_to_return] log.info('Successfully get device %s:%s statistics data info: %s', name, device_id, list_to_return) return list_to_return, 200
def get(self): sorting_order_param = request.args.get('sort') name_filter_param = request.args.get('filter') pagination_param = request.args.get('pagination') address_param = request.args.get('address') sorting_order = None name_filter = None pagination = None address = None if sorting_order_param: sorting_order = json.loads(sorting_order_param) if name_filter_param: name_filter = json.loads(name_filter_param) if pagination_param: pagination = json.loads(pagination_param) if address_param: address = address_param result = database.get_list_of_nodes(sorting_order, name_filter, pagination, address) log.info('Got all nodes fetched: %s', result) return result, 200
def put(self, name, device_id): soft_limit = request.args.get('soft_limit') abort_when_not_int(soft_limit) computation_node = abort_when_node_not_found(name) if int(soft_limit) < 0: log.error(str.format('Number is not positive: {}', soft_limit)) abort(400) if not any(d['id'] == device_id for d in computation_node['backend_info']['devices']): log.error('There is no such device: %s', device_id) abort(404) limit_info = { 'name': name, 'device_id': device_id, 'soft_limit': soft_limit } upsert_result = database.replace_soft_limit_for_device( name, device_id, limit_info) if upsert_result.modified_count: log.info( 'Power limit for device %s:%s was already set in a database to %s', name, device_id, soft_limit) log.info('Stored power limit info %s', limit_info) else: log.info('Stored power limit info %s on id %s', limit_info, upsert_result.upserted_id) return 'Soft limit successfully set', 201
def delete(self, name, device_id): node_info = abort_when_node_not_found(name) address = node_info['address'] port = node_info['port'] [device_type] = [ d['Type'] for d in node_info['backend_info']['devices'] if d['id'] == device_id ] result = database.delete_power_limit_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) try: response = delete_power_limit(address, port, device_id, device_type) log.info('Power limit for device %s deletion info: %s', device_id, response) except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', address, port) return 'Warning: power limit was deleted from database but could not be deleted from device', 406 log.info( 'Successfully removed power limit for device %s:%s power limit info: %s', name, device_id, result) return result, 200
def put(self, name): address = request.args.get('address') port = request.args.get('port') abort_when_port_invalid(port) node_by_ip = database.get_computation_node_info_by_address( address, port) if node_by_ip and node_by_ip.get('name') != name: log.warning('Node with IP: %s:%s is present in database: %s', address, port, node_by_ip) try: response = get_node_information(address, port) except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', address, port) abort(406) log.info('Response %s:', response.text) backend_info = json.loads(response.text) node_info = { 'name': name, 'address': address, 'port': port, 'backend_info': backend_info } upsert_result = database.replace_computation_node_info(name, node_info) if upsert_result.modified_count: log.info('Node %s was already present in a database', name) log.info('Stored Node info %s', node_info) else: log.info('Stored Node info %s on id %s', node_info, upsert_result.upserted_id) for device in backend_info['devices']: set_statistics_interval(name, device['id'], 1) return name, 201
def delete(self, name, device_id, date_time): try: datetime.datetime.strptime(date_time, '%Y-%m-%dT%H:%M') except ValueError: abort(400) computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) result = database.delete_stats_for_time(name, device_id, {date_time: ""}) if not result: log.info('No such statistic for device %s:%s', name, device_id) abort(404) if not result.matched_count: log.info('Did not manage to delete statistic for device %s:%s', name, device_id) abort(404) log.info('Successfully deleted device %s:%s statistics data info', name, device_id) return 204
def get(self, name, device_id, date_time): try: datetime.datetime.strptime(date_time, '%Y-%m-%dT%H:%M') except ValueError: abort(400) computation_node = abort_when_node_not_found(name) abort_when_device_not_found(device_id, computation_node) result = database.get_stats_data_for_time(name, device_id, date_time) if not result: log.info('No such statistic for device %s:%s', name, device_id) abort(404) if not result.get(date_time): log.info('No statistics for %s', date_time) abort(404) log.info('Successfully get device %s:%s statistics data info: %s', name, device_id, result) return result, 200
def delete(self, name, device_id): node_info = abort_when_node_not_found(name) address = node_info['address'] port = node_info['port'] [device_type] = [d['Type'] for d in node_info['backend_info']['devices'] if d['id'] == device_id] result = database.delete_power_limit_info(name, device_id) if not result: log.info('No such device %s:%s', name, device_id) abort(404) try: response = delete_power_limit(address, port, device_id, device_type) log.info('Power limit for device %s deletion info: %s', device_id, response) except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', address, port) return 'Warning: power limit was deleted from database but could not be deleted from device', 406 log.info('Successfully removed power limit for device %s:%s power limit info: %s', name, device_id, result) return result, 200
def set_statistics_interval(node_name, device_id, statistics_interval): current_interval_info = database.get_stats_interval_info( node_name, device_id) if current_interval_info: old_interval = datetime.timedelta( minutes=current_interval_info['interval']) old_next_measurement = datetime.datetime.strptime( current_interval_info['next_measurement'], '%Y-%m-%dT%H:%M') new_interval = datetime.timedelta(minutes=statistics_interval) new_next_measurement = (old_next_measurement - old_interval + new_interval) interval_info = current_interval_info interval_info['interval'] = statistics_interval new_next_measurement_str = new_next_measurement.strftime( '%Y-%m-%dT%H:%M') # pylint: disable=no-member interval_info['next_measurement'] = new_next_measurement_str else: interval_info = { 'name': node_name, 'device_id': device_id, 'interval': statistics_interval, 'next_measurement': (datetime.datetime.utcnow() + datetime.timedelta(minutes=statistics_interval)).strftime( '%Y-%m-%dT%H:%M') # pylint: disable=no-member } upsert_result = database.replace_stats_interval_info( node_name, device_id, interval_info) if upsert_result.modified_count: log.info( 'Statistics gathering interval for device %s:%s was already set in a database', node_name, device_id) log.info('Stored statistics gathering interval info %s', interval_info) else: log.info('Stored statistics gathering interval info %s on id %s', interval_info, upsert_result.upserted_id)
def put(self, name, device_id): statistics_interval = request.args.get('statistics_interval') abort_when_not_int(statistics_interval) statistics_interval = int(statistics_interval) computation_node = abort_when_node_not_found(name) if not any(d['id'] == device_id for d in computation_node['backend_info']['devices']): log.error('There is no such device: %s', device_id) abort(404) current_interval_info = database.get_stats_interval_info(name, device_id) if current_interval_info: old_interval = datetime.timedelta(minutes=current_interval_info['interval']) old_next_measurement = datetime.datetime.strptime(current_interval_info['next_measurement'], '%Y-%m-%dT%H:%M') new_interval = datetime.timedelta(minutes=statistics_interval) new_next_measurement = (old_next_measurement - old_interval + new_interval) interval_info = current_interval_info interval_info['interval'] = statistics_interval new_next_measurement_str = new_next_measurement.strftime('%Y-%m-%dT%H:%M') # pylint: disable=no-member interval_info['next_measurement'] = new_next_measurement_str else: interval_info = { 'name': name, 'device_id': device_id, 'interval': statistics_interval, 'next_measurement': (datetime.datetime.utcnow() + datetime.timedelta( minutes=statistics_interval)).strftime('%Y-%m-%dT%H:%M') # pylint: disable=no-member } upsert_result = database.replace_stats_interval_info(name, device_id, interval_info) if upsert_result.modified_count: log.info('Statistics gathering interval for device %s:%s was already set in a database', name, device_id) log.info('Stored statistics gathering interval info %s', interval_info) else: log.info('Stored statistics gathering interval info %s on id %s', interval_info, upsert_result.upserted_id) return 'Statistics gathering interval successfully set', 201
def put(self, name, device_id): power_limit = request.args.get('power_limit') abort_when_not_int(power_limit) computation_node = abort_when_node_not_found(name) if not any(d['id'] == device_id for d in computation_node['backend_info']['devices']): log.error('There is no such device: %s', device_id) abort(404) limit_info = { 'name': name, 'device_id': device_id, 'power_limit': power_limit } [device_type] = [d['Type'] for d in computation_node['backend_info']['devices'] if d['id'] == device_id] previous_limit_data = get_power_limit(computation_node['address'], computation_node['port'], device_id, device_type) previous_limit_info = json.loads(previous_limit_data.content.decode('ascii')) previous_limit = previous_limit_info[0]['PowerLimit'] upsert_result = database.replace_power_limit_for_device(name, device_id, limit_info) if upsert_result.modified_count: log.info('Power limit for device %s:%s was already set in a database to %s', name, device_id, power_limit) log.info('Stored power limit info %s', limit_info) else: log.info('Stored power limit info %s on id %s', limit_info, upsert_result.upserted_id) try: response = put_power_limit(computation_node['address'], computation_node['port'], device_id, device_type, power_limit) log.info(response.text) response_object = json.loads(response.content.decode('ascii')) if not response_object[0]['Success']: log.info('Could not set power limit on device %s:%s, restoring previous value: %s', name, device_id, previous_limit) try: limit_info['power_limit'] = int(previous_limit) upsert_result = database.replace_power_limit_for_device(name, device_id, limit_info) if upsert_result.modified_count: log.info('Power limit for device %s:%s was already set in a database to %s', name, device_id, power_limit) log.info('Restored previous power limit %s', limit_info) else: log.info('Restored previous power limit info %s:%s', limit_info, upsert_result.upserted_id) except ValueError: pass return response_object[0]['ErrorMessage'], 406 except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', computation_node['address'], computation_node['port']) return 'Failed to set power limit on device, but added to database', 201 return 'Power limit successfully set', 201
def put(self, name, device_id): power_limit = request.args.get('power_limit') abort_when_not_int(power_limit) computation_node = abort_when_node_not_found(name) if not any(d['id'] == device_id for d in computation_node['backend_info']['devices']): log.error('There is no such device: %s', device_id) abort(404) limit_info = { 'name': name, 'device_id': device_id, 'power_limit': power_limit } [device_type] = [ d['Type'] for d in computation_node['backend_info']['devices'] if d['id'] == device_id ] previous_limit_data = get_power_limit(computation_node['address'], computation_node['port'], device_id, device_type) previous_limit_info = json.loads( previous_limit_data.content.decode('ascii')) previous_limit = previous_limit_info[0]['PowerLimit'] upsert_result = database.replace_power_limit_for_device( name, device_id, limit_info) if upsert_result.modified_count: log.info( 'Power limit for device %s:%s was already set in a database to %s', name, device_id, power_limit) log.info('Stored power limit info %s', limit_info) else: log.info('Stored power limit info %s on id %s', limit_info, upsert_result.upserted_id) try: response = put_power_limit(computation_node['address'], computation_node['port'], device_id, device_type, power_limit) log.info(response.text) response_object = json.loads(response.content.decode('ascii')) if not response_object[0]['Success']: log.info( 'Could not set power limit on device %s:%s, restoring previous value: %s', name, device_id, previous_limit) try: limit_info['power_limit'] = int(previous_limit) upsert_result = database.replace_power_limit_for_device( name, device_id, limit_info) if upsert_result.modified_count: log.info( 'Power limit for device %s:%s was already set in a database to %s', name, device_id, power_limit) log.info('Restored previous power limit %s', limit_info) else: log.info('Restored previous power limit info %s:%s', limit_info, upsert_result.upserted_id) except ValueError: pass return response_object[0]['ErrorMessage'], 406 except requests.exceptions.ConnectionError: log.error('Connection could not be established to %s:%s', computation_node['address'], computation_node['port']) return 'Failed to set power limit on device, but added to database', 201 return 'Power limit successfully set', 201
def get(self, name, device_id): computation_node, dev_type = get_com_node_and_dev_type(name, device_id) result = get_constraints(computation_node['address'], computation_node['port'], device_id, dev_type) log.info('Successfully get device %s:%s power limit constraints info: %s', name, device_id, result) return result.json(), 200
def initialize(config): database.configure(config['database']) log.info(database) # to avoid 'unused variable' warning :D api_spec = ApiSpec(config['host']) flask_app.register_blueprint(api_spec.blueprint, url_prefix='/api/hpcpm')
def start_request(*_): request.real_ip = request.headers.get('X-Real-Ip', request.remote_addr) request.start_time = time.time() log.info('REQUEST STARTED: %s %s %s', request.real_ip, request.method, request.url)