def _validate_apps(data): """ Validate Apps configuration Parameters data: configuration (dict) """ if not 'apps' in data: return # verify apps pids = set() app_ids = [] for app in data['apps']: # id if app['id'] in app_ids: raise ValueError("App {}, multiple apps with same id.".format( app['id'])) app_ids.append(app['id']) # app's cores validation if 'cores' in app: for core in app['cores']: if not common.PQOS_API.check_core(core): raise ValueError("App {}, Invalid core {}.".format( app['id'], core)) # app's pool validation app_pool = None for pool in data['pools']: if 'apps' in pool and app['id'] in pool['apps']: if app_pool: raise ValueError("App {}, Assigned to more than one pool."\ .format(app['id'])) app_pool = pool if app_pool is None: raise ValueError("App {} not assigned to any pool.".format( app['id'])) if 'cores' in app: diff_cores = set(app['cores']).difference(app_pool['cores']) if diff_cores: raise ValueError("App {}, cores {} does not match Pool {}."\ .format(app['id'], diff_cores, app_pool['id'])) # app's pids validation for pid in app['pids']: if not pid_ops.is_pid_valid(pid): raise ValueError("App {}, PID {} is not valid.".format( app['id'], pid)) if pids.intersection(app['pids']): raise ValueError("App {}, PIDs {} already assigned to another App."\ .format(app['id'], pids.intersection(app['pids']))) pids |= set(app['pids'])
def post(): # pylint: disable=too-many-branches """ Handles HTTP POST /apps request. Add a new App Raises NotFound, BadRequest Returns: response, status code """ json_data = request.get_json() # validate app schema try: schema, resolver = ConfigStore.load_json_schema('add_app.json') jsonschema.validate(json_data, schema, resolver=resolver) except jsonschema.ValidationError as error: raise BadRequest("Request validation failed - %s" % (str(error))) data = deepcopy(common.CONFIG_STORE.get_config()) if 'pools' not in data: raise NotFound("No pools in config file") json_data['id'] = common.CONFIG_STORE.get_new_app_id() if 'pids' in json_data: # validate pids for pid in json_data['pids']: if not pid_ops.is_pid_valid(pid): raise BadRequest("New APP not added, invalid PID: " + str(pid)) # if pool_id not provided on app creation if 'pool_id' not in json_data or not json_data['pool_id']: json_data['pool_id'] = None # if apps cores list is a subset of existing pool cores list, # make existing pool a destination pool for app if 'cores' in json_data and json_data['cores']: for core in json_data['cores']: if not common.PQOS_API.check_core(core): raise BadRequest("New APP not added, invalid core: " + str(core)) for pool in data['pools']: if set(json_data['cores']).issubset(pool['cores']): json_data['pool_id'] = pool['id'] break # if it is not, make default pool a destination pool if json_data['pool_id'] is None: json_data['pool_id'] = 0 if 'cores' in json_data: json_data.pop('cores') try: pool = common.CONFIG_STORE.get_pool(data, json_data['pool_id']) except Exception as ex: raise BadRequest("New APP not added, " + str(ex)) # update pool configuration to include new app if not 'apps' in pool: pool['apps'] = [] pool['apps'].append(json_data['id']) json_data.pop('pool_id') data['apps'].append(json_data) try: common.CONFIG_STORE.validate(data) except AdmissionControlError: pass except Exception as ex: raise BadRequest("New APP not added, " + str(ex)) common.CONFIG_STORE.set_config(data) res = { 'id': json_data['id'], 'message': "New APP added to pool {}".format(str(pool['id'])) } return res, 201
def post(): # pylint: disable=too-many-branches """ Handles HTTP POST /apps request. Add a new App Raises NotFound, BadRequest, InternalError Returns: response, status code """ def get_app_id(): """ Get ID for new App Returns: ID for new App """ # put all ids into list app_ids = [] for app in data['apps']: app_ids.append(app['id']) app_ids = sorted(app_ids) # no app found in config if not app_ids: return 1 # add new app to apps # find an id new_ids = list(set(range(1, app_ids[-1])) - set(app_ids)) if new_ids: return new_ids[0] return app_ids[-1] + 1 json_data = request.get_json() # validate app schema try: schema, resolver = ConfigStore.load_json_schema('add_app.json') jsonschema.validate(json_data, schema, resolver=resolver) except jsonschema.ValidationError as error: raise BadRequest("Request validation failed - %s" % (str(error))) data = deepcopy(common.CONFIG_STORE.get_config()) if 'pools' not in data: raise NotFound("No pools in config file") json_data['id'] = get_app_id() if 'pids' in json_data: # validate pids for pid in json_data['pids']: valid = pid_ops.is_pid_valid(pid) if not valid: raise BadRequest("New APP not added, please provide valid pid's") # if pool_id not provided on app creation if 'pool_id' not in json_data or not json_data['pool_id']: json_data['pool_id'] = None # if apps cores list is a subset of existing pool cores list, # make existing pool a destination pool for app if 'cores' in json_data and json_data['cores']: for pool in data['pools']: if set(json_data['cores']).issubset(pool['cores']): json_data['pool_id'] = pool['id'] break # if it is not, make default pool a destination pool if json_data['pool_id'] is None: json_data['pool_id'] = 0 if 'cores' in json_data: json_data.pop('cores') # update pool configuration to include new app for pool in data['pools']: if pool['id'] == json_data['pool_id']: if not 'apps' in pool: pool['apps'] = [] pool['apps'].append(json_data['id']) break json_data.pop('pool_id') data['apps'].append(json_data) try: common.CONFIG_STORE.validate(data) except Exception as ex: raise BadRequest("New APP not added, " + str(ex)) else: common.CONFIG_STORE.set_config(data) res = {'id': json_data['id']} return res, 201
def validate(data): #pylint: disable=too-many-branches """ Validate configuration Parameters data: configuration (dict) """ # validates config schema schema, resolver = ConfigStore.load_json_schema('appqos.json') jsonschema.validate(data, schema, resolver=resolver) cores = set() pool_ids = [] # verify pools for pool in data['pools']: # id if pool['id'] in pool_ids: raise ValueError( "Pool {}, multiple pools with same id.".format(pool['id'])) pool_ids.append(pool['id']) # pool cores for core in pool['cores']: if not common.PQOS_API.check_core(core): raise ValueError("Pool {}, Invalid core {}.".format( pool['id'], core)) if cores.intersection(pool['cores']): raise ValueError("Pool {}, Cores {} already assigned to another pool."\ .format(pool['id'], cores.intersection(pool['cores']))) cores |= set(pool['cores']) # check app reference if 'apps' in pool: for app_id in pool['apps']: ConfigStore.get_app(data, app_id) # verify apps if 'apps' in data: pids = set() app_ids = [] for app in data['apps']: # id if app['id'] in app_ids: raise ValueError( "App {}, multiple apps with same id.".format( app['id'])) app_ids.append(app['id']) # app's cores validation if 'cores' in app: for core in app['cores']: if not common.PQOS_API.check_core(core): raise ValueError("App {}, Invalid core {}.".format( app['id'], core)) # app's pool validation app_pool = None for pool in data['pools']: if 'apps' in pool and app['id'] in pool['apps']: if app_pool: raise ValueError("App {}, Assigned to more than one pool."\ .format(app['id'])) app_pool = pool if app_pool is None: raise ValueError("App {} not assigned to any pool.".format( app['id'])) if 'cores' in app: diff_cores = set(app['cores']).difference( app_pool['cores']) if diff_cores: raise ValueError("App {}, cores {} does not match Pool {}."\ .format(app['id'], diff_cores, app_pool['id'])) # app's pids validation for pid in app['pids']: if not pid_ops.is_pid_valid(pid): raise ValueError("App {}, PID {} is not valid.".format( app['id'], pid)) if pids.intersection(app['pids']): raise ValueError("App {}, PIDs {} already assigned to another App."\ .format(app['id'], cores.intersection(app['pids']))) pids |= set(app['pids'])
def post(): """ Handles HTTP POST /apps request. Add a new App Raises NotFound, BadRequest, InternalError Returns: response, status code """ def get_app_id(): """ Get ID for new App Returns: ID for new App """ # put all ids into list app_ids = [] for app in data['apps']: app_ids.append(app['id']) app_ids = sorted(app_ids) # no app found in config if not app_ids: return 1 # add new app to apps # find an id new_ids = list(set(range(1, app_ids[-1])) - set(app_ids)) if new_ids: return new_ids[0] return app_ids[-1] + 1 json_data = request.get_json() # validate app schema try: schema, resolver = ConfigStore.load_json_schema('add_app.json') jsonschema.validate(json_data, schema, resolver=resolver) except jsonschema.ValidationError as error: raise BadRequest("Request validation failed - %s" % (str(error))) data = deepcopy(common.CONFIG_STORE.get_config()) if 'pools' not in data: raise NotFound("No pools in config file") json_data['id'] = get_app_id() if 'pids' in json_data: # validate pids for pid in json_data['pids']: valid = pid_ops.is_pid_valid(pid) if not valid: raise BadRequest( "New APP not added, please provide valid pid's") for pool in data['pools']: if pool['id'] == json_data['pool_id']: if not 'apps' in pool: pool['apps'] = [] pool['apps'].append(json_data['id']) break json_data.pop('pool_id') data['apps'].append(json_data) try: common.CONFIG_STORE.validate(data) except Exception as ex: raise BadRequest("New APP not added, " + str(ex)) else: common.CONFIG_STORE.set_config(data) res = {'id': json_data['id']} return res, 201
def post(): # pylint: disable=too-many-branches """ Handles HTTP POST /apps request. Add a new App Raises NotFound, BadRequest, InternalError Returns: response, status code """ def get_app_id(): """ Get ID for new App Returns: ID for new App """ # put all ids into list app_ids = [] for app in data['apps']: app_ids.append(app['id']) app_ids = sorted(app_ids) # no app found in config if not app_ids: return 1 # add new app to apps # find an id new_ids = list(set(range(1, app_ids[-1])) - set(app_ids)) if new_ids: return new_ids[0] return app_ids[-1] + 1 json_data = request.get_json() # validate app schema try: schema, resolver = ConfigStore.load_json_schema('add_app.json') jsonschema.validate(json_data, schema, resolver=resolver) except jsonschema.ValidationError as error: raise BadRequest("Request validation failed - %s" % (str(error))) data = deepcopy(common.CONFIG_STORE.get_config()) if 'pools' not in data: raise NotFound("No pools in config file") json_data['id'] = get_app_id() if 'pids' in json_data: # validate pids for pid in json_data['pids']: valid = pid_ops.is_pid_valid(pid) if not valid: raise BadRequest( "New APP not added, please provide valid pid's") # if pool_id not provided on app creation if 'pool_id' not in json_data or not json_data['pool_id']: json_data['pool_id'] = None # if apps cores list is a subset of existing pool cores list, # make existing pool a destination pool for app if 'cores' in json_data and json_data['cores']: for pool in data['pools']: if set(json_data['cores']).issubset(pool['cores']): json_data['pool_id'] = pool['id'] break # if it is not, make default pool a destination pool if json_data['pool_id'] is None: json_data['pool_id'] = 0 if 'cores' in json_data: json_data.pop('cores') # update pool configuration to include new app for pool in data['pools']: if pool['id'] == json_data['pool_id']: if not 'apps' in pool: pool['apps'] = [] pool['apps'].append(json_data['id']) break json_data.pop('pool_id') data['apps'].append(json_data) try: common.CONFIG_STORE.validate(data) except Exception as ex: raise BadRequest("New APP not added, " + str(ex)) else: common.CONFIG_STORE.set_config(data) res = {'id': json_data['id']} return res, 201
def validate(data): #pylint: disable=too-many-branches """ Validate configuration Parameters data: configuration (dict) """ # validates config schema schema, resolver = ConfigStore.load_json_schema('appqos.json') jsonschema.validate(data, schema, resolver=resolver) cores = set() pool_ids = [] # verify pools for pool in data['pools']: # id if pool['id'] in pool_ids: raise ValueError("Pool {}, multiple pools with same id.".format(pool['id'])) pool_ids.append(pool['id']) # pool cores for core in pool['cores']: if not common.PQOS_API.check_core(core): raise ValueError("Pool {}, Invalid core {}.".format(pool['id'], core)) if cores.intersection(pool['cores']): raise ValueError("Pool {}, Cores {} already assigned to another pool."\ .format(pool['id'], cores.intersection(pool['cores']))) cores |= set(pool['cores']) # check app reference if 'apps' in pool: for app_id in pool['apps']: ConfigStore.get_app(data, app_id) # verify apps if 'apps' in data: pids = set() app_ids = [] for app in data['apps']: # id if app['id'] in app_ids: raise ValueError("App {}, multiple apps with same id.".format(app['id'])) app_ids.append(app['id']) # app's cores validation if 'cores' in app: for core in app['cores']: if not common.PQOS_API.check_core(core): raise ValueError("App {}, Invalid core {}.".format(app['id'], core)) # app's pool validation app_pool = None for pool in data['pools']: if 'apps' in pool and app['id'] in pool['apps']: if app_pool: raise ValueError("App {}, Assigned to more than one pool."\ .format(app['id'])) app_pool = pool if app_pool is None: raise ValueError("App {} not assigned to any pool.".format(app['id'])) if 'cores' in app: diff_cores = set(app['cores']).difference(app_pool['cores']) if diff_cores: raise ValueError("App {}, cores {} does not match Pool {}."\ .format(app['id'], diff_cores, app_pool['id'])) # app's pids validation for pid in app['pids']: if not pid_ops.is_pid_valid(pid): raise ValueError("App {}, PID {} is not valid.".format(app['id'], pid)) if pids.intersection(app['pids']): raise ValueError("App {}, PIDs {} already assigned to another App."\ .format(app['id'], cores.intersection(app['pids']))) pids |= set(app['pids'])