Exemplo n.º 1
0
 def on_post(self, req, resp):
     req_data = req.media or {}
     resp_data, valid = Config_Request_Schema(
         many=is_list(req_data),
         method=HTTP_Method.POST).validate(data=req_data)
     if valid:
         req_data_wrap = wrap(req_data)
         if len(req_data_wrap) > 0:
             for config in req_data_wrap:
                 for cfg, cfg_list in config.items():
                     for data in wrap(cfg_list):
                         if cfg == 'actions':
                             output = self.__actions(data)
                             schema = Config_Action_Response_Schema
                         elif cfg == 'parameters':
                             output = self.__parameters(data)
                             schema = Config_Parameter_Response_Schema
                         elif cfg == 'resources':
                             output = self.__resources(data)
                             schema = Config_Resource_Response_Schema
                         output.update(id=data.get('id', None),
                                       timestamp=datetime_to_str())
                         resp_data, valid = schema(
                             many=False,
                             method=HTTP_Method.POST).validate(data=output)
                         if valid:
                             Content_Response(output).add(resp)
                         else:
                             resp_data.add(resp)
         else:
             msg = f'No content to apply configurations with the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Exemplo n.º 2
0
 def on_put(self, req, resp, id=None):
     req_data = req.media or {}
     resp_data, valid = Code_Request_Schema(many=is_list(req_data),
                                            partial=True, method=HTTP_Method.PUT).validate(data=req.media, id=id)
     if valid:
         req_data_wrap = wrap(req_data)
         if len(req_data_wrap) > 0:
             for data in req_data_wrap:
                 id, code, interface, metrics = item_getter('id', 'code',
                                                            'interface', 'metrics')(data)
                 if all([id, code, interface]):
                     pc = self.polycube.update(cube=id, code='\n'.join(code),
                                               interface=interface, metrics=metrics)
                     if not pc.get('error', False):
                         msg = f'Code with the id={id} correctly updated'
                         resp_data = Ok_Response(msg)
                     else:
                         msg = f'Not possible to update code with the id={id}'
                         resp_data = Unprocessable_Entity_Response(msg)
                     resp_data.update(**pc)
                 else:
                     msg = f'Not possible to update code with the id={id}'
                     resp_data = Unprocessable_Entity_Response(msg)
                 resp_data.apply(resp)
         else:
             msg = f'No content to update code with the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Exemplo n.º 3
0
 def on_delete(self, req, resp, id=None):
     req_data = req.media or {}
     resp_data, valid = Code_Request_Schema(many=is_list(req_data),
                                            partial=True, method=HTTP_Method.DELETE).validate(data=req.media, id=id)
     if valid:
         req_data_wrap = wrap(req_data)
         if len(req_data_wrap) > 0:
             for data in req_data_wrap:
                 id = data.get('id', None)
                 if id is not None:
                     pc = self.polycube.delete(cube=id)
                     if not pc.get('error', False):
                         msg = f'Code with the id={id} correctly deleted'
                         resp_data = Reset_Content_Response(msg)
                     else:
                         msg = f'Not possible to delete code with the id={id}'
                         resp_data = Unprocessable_Entity_Response(msg)
                     resp_data.update(**pc)
                 else:
                     msg = f'Not possible to update code with the id={id}'
                     resp_data = Unprocessable_Entity_Response(msg)
                 resp_data.apply(resp)
         else:
             msg = f'No content to delete code with the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Exemplo n.º 4
0
 def __init__(self, catalog, req, resp):
     self.log = Log.get('agent-instance-lcp')
     self.req = req
     self.resp = resp
     self.req_lcp = []
     self.actions = []
     self.parameters = []
     self.resources = []
     self.catalogs = {'actions': {}, 'parameters': {}, 'resources': {}}
     operations = wrap(self.req.get('operations', []))
     for req_op in operations:
         req_lcp_op = {}
         self.req_lcp.append(req_lcp_op)
         self.__prepare(req_lcp_op,
                        'actions',
                        catalog=catalog.actions,
                        data=req_op.get('actions', []),
                        transform_handler=self.__transform_action)
         self.__prepare(req_lcp_op,
                        'parameters',
                        catalog=catalog.parameters,
                        data=req_op.get('parameters', []),
                        transform_handler=self.__transform_parameter)
         self.__prepare(req_lcp_op,
                        'resources',
                        catalog=catalog.resources,
                        data=req_op.get('resources', []),
                        transform_handler=self.__transform_resource)
     self.num = len(operations)
Exemplo n.º 5
0
 def on_base_put(self, req, resp, id=None):
     so = self.doc.Status_Operation
     req_data = req.media or {}
     resp_data, valid = self.schema(many=is_list(req_data),
                                    unknown='INCLUDE',
                                    partial=True,
                                    method=HTTP_Method.PUT).validate(
                                        data=req_data, id=id)
     if valid:
         req_data_wrap = wrap(req_data)
         if len(req_data_wrap) > 0:
             for req_data in req_data_wrap:
                 req_data_lcp = deepcopy(req_data)
                 req_data_id = req_data.pop('id', id)
                 try:
                     if len(req_data) == 0:
                         msg = f'Update for {self.name} with id={req_data_id} not necessary'
                         Not_Modified_Response(msg).add(resp)
                     else:
                         self.rm_ignore_fields(req_data)
                         obj = self.doc.get(id=req_data_id)
                         resp_data_lcp = []
                         hndl = self.get_lcp_handler(HTTP_Method.PUT)
                         modified = hndl(instance=obj,
                                         req=req_data_lcp,
                                         resp=resp_data_lcp)
                         resp_data = Ok_Response(
                             f'{self.name.capitalize()} with the id={req_data_id} correctly updated'
                         )
                         if len(resp_data_lcp) > 0:
                             for rdl in resp_data_lcp:
                                 if rdl['error']:
                                     msg = f'Not possible to update a {self.name} with the id={req_data_id}'
                                     resp_data = Unprocessable_Entity_Response(
                                         msg)
                                     break
                             resp_data.update(lcp_response=resp_data_lcp)
                         force = req_data.get('force', False)
                         if (not resp_data.error
                                 or force) and len(req_data) > 0:
                             res = obj.update(**req_data)
                             if res == so.UPDATED:
                                 modified = True
                                 if force:
                                     msg = f'Some errors occur but the {self.name} with the id={req_data_id} forcedly updated'
                                     resp_data = Unprocessable_Entity_Response(
                                         msg)
                         if not resp_data.error and not modified:
                             msg = f'{self.name.capitalize()} with the id={req_data_id} no need to update'
                             resp_data = Not_Modified_Response(msg)
                         resp_data.add(resp)
                 except Exception as e:
                     msg = f'Not possible to update a {self.name} with the id={req_data_id}'
                     Unprocessable_Entity_Response(msg,
                                                   exception=e).add(resp)
         else:
             msg = f'No content to update {self.name} based on the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Exemplo n.º 6
0
 def _deserialize(self, value, attr, data, **kwargs):
     if value:
         if isinstance(value, str):
             value = value.replace('\r', '').splitlines()
         else:
             value = wrap(value)
     return super(List_or_One, self)._deserialize(value, attr, data, **kwargs)
Exemplo n.º 7
0
def routes(api, spec):
    log = Log.get('resource')
    for res_class in db:
        res = res_class()
        for route in wrap(res_class.routes):
            api.add_route(route, res)
            spec.path(resource=res)
            log.success(f'{route} endpoint configured')
Exemplo n.º 8
0
 def __apply(self, instance, exec_env):
     if self.num > 0:
         schema = 'https' if exec_env.lcp.https else 'http'
         resp_lcp = post_req(
             f'{schema}://{exec_env.hostname}:{exec_env.lcp.port}/config',
             headers={'Authorization': create_token()},
             json=self.req_lcp)
         if resp_lcp.content:
             try:
                 resp_lcp_data = resp_lcp.json()
                 if resp_lcp.status_code >= 300 or (is_dict(resp_lcp)
                                                    and resp_lcp_data.get(
                                                        'error', False)):
                     Unprocessable_Entity_Response(resp_lcp_data) \
                         .add(self.resp)
                     return False
                 else:
                     save_actions = self.__save(
                         instance=instance,
                         data=resp_lcp_data,
                         type='action',
                         catalogs=self.catalogs['actions'],
                         handler=self.__save_action)
                     save_parameters = self.__save(
                         instance=instance,
                         data=resp_lcp_data,
                         type='parameter',
                         catalogs=self.catalogs['parameters'],
                         handler=self.__save_parameter)
                     save_resources = self.__save(
                         instance=instance,
                         data=resp_lcp_data,
                         type='resource',
                         catalogs=self.catalogs['resources'],
                         handler=self.__save_resource)
                     if save_actions or save_parameters or save_resources:
                         instance.save()
                     self.resp.extend(wrap(resp_lcp_data))
                     return True
             except Exception as e:
                 msg = f'Response from LCP({exec_env.meta.id}@{exec_env.hostname}:{exec_env.lcp.port}) not valid'
                 self.log.exception(msg, e)
                 uer = Unprocessable_Entity_Response(msg, exception=e)
                 uer.add(self.resp)
                 return False
         else:
             msg = f'Request to LCP({exec_env.meta.id}@{exec_env.hostname}:{exec_env.lcp.port}) not executed'
             Unprocessable_Entity_Response(msg).add(self.resp)
             return False
     return False
Exemplo n.º 9
0
 def __prepare(self, req_op, type, catalog, data, transform_handler):
     catalog_docs = []
     req_op[type] = []
     for data_item in wrap(data):
         id = data_item.get('id', None)
         catalog_doc = self.catalogs[type].get(id, None) or LCP.from_catalog(catalog=catalog, id=id,
                                                                             label=type.title(), resp=self.resp)
         if catalog_doc:
             self.catalogs[type][id] = catalog_doc
             d = catalog_doc.config.to_dict()
             config = transform_handler(d, data_item)
             config.update(**data_item)
             self.log.info(f'Prepare {type}: {config}')
             req_op[type].append(config)
     return catalog_docs
Exemplo n.º 10
0
 def on_base_post(self, req, resp, id=None):
     req_data = req.media or {}
     resp_data, valid = self.schema(many=is_list(req_data),
                                    unknown='INCLUDE',
                                    method=HTTP_Method.POST).validate(
                                        data=req_data, id=id)
     if valid:
         req_data_wrap = wrap(req_data)
         if len(req_data_wrap) > 0:
             for req_data in req_data_wrap:
                 req_data_lcp = deepcopy(req_data)
                 req_data_id = req_data.pop('id', id)
                 try:
                     self.rm_ignore_fields(req_data)
                     obj = self.doc(meta={'id': req_data_id}, **req_data)
                     resp_data_lcp = []
                     resp_data = Created_Response(
                         f'{self.name.capitalize()} with the id={req_data_id} correctly created'
                     )
                     hndl = self.get_lcp_handler(HTTP_Method.POST)
                     hndl(instance=obj,
                          req=req_data_lcp,
                          resp=resp_data_lcp)
                     if len(resp_data_lcp) > 0:
                         for rdl in resp_data_lcp:
                             if rdl['error']:
                                 msg = f'Not possible to create a {self.name} with the id={req_data_id}'
                                 resp_data = Unprocessable_Entity_Response(
                                     msg)
                                 break
                         resp_data.update(lcp_response=resp_data_lcp)
                     force = req_data.get('force', False)
                     if not resp_data.error or force:
                         obj.save()
                         if force:
                             msg = f'Some errors occur but the {self.name} with the id={req_data_id} forcedly created'
                             resp_data = Unprocessable_Entity_Response(msg)
                     resp_data.add(resp)
                 except Exception as e:
                     msg = f'Not possible to create a {self.name} with the id={req_data_id}'
                     Unprocessable_Entity_Response(msg,
                                                   exception=e).add(resp)
         else:
             msg = f'No content to create {self.names} based the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Exemplo n.º 11
0
 def __actions(self, data):
     cmd = data.get('cmd', None)
     daemon = data.get('daemon', False)
     output = dict(type='action')
     run = ' '.join([cmd] + wrap(data.get('args', [])))
     start = time.time()
     proc = self.__run_cmd(cmd=run, daemon=daemon, output=output)
     if daemon:
         output.update(error=False, executed=run, return_code=0)
     else:
         output.update(error=proc.returncode != 0,
                       executed=run,
                       return_code=proc.returncode,
                       duration=time.time() - start)
         self.__set_std(proc.stdout, output, 'stdout')
         self.__set_std(proc.stderr, output, 'stderr')
     return output
Exemplo n.º 12
0
 def __apply(self, instance, exec_env, caller, data):
     h, p = exec_env.hostname, exec_env.lcp.port
     schema = 'https' if exec_env.lcp.https else 'http'
     resp_caller = caller(f'{schema}://{h}:{p}/code',
                          headers={'Authorization': create_token()},
                          json=data(self.catalog))
     if resp_caller.content:
         try:
             self.resp.extend(wrap(resp_caller.json()))
         except Exception as e:
             msg = f'Response from LCP({exec_env.meta.id}@{exec_env.hostname}:{exec_env.lcp.port}) not valid'
             self.log.exception(msg, e)
             uer = Unprocessable_Entity_Response(msg, exception=e)
             uer.add(self.resp)
     else:
         msg = f'Request to LCP({exec_env.meta.id}@{exec_env.hostname}:{exec_env.lcp.port}) not executed'
         Unprocessable_Entity_Response(msg).add(self.resp)
Exemplo n.º 13
0
 def __actions(self, data):
     cmd = data.get('cmd', None)
     daemon = data.get('daemon', False)
     output_format = data.get('output_format', 'plain')
     output = {'type': 'action'}
     run = ' '.join([cmd] + wrap(data.get('args', [])))
     start = time.time()
     proc = self.__run_cmd(cmd=run, daemon=daemon, output=output)
     if daemon:
         output.update(error=False, return_code=0)
     else:
         output.update(error=proc.returncode != 0,
                       return_code=proc.returncode,
                       duration=time.time() - start)
         self.__set_std(proc.stdout, output, 'stdout', output_format)
         self.__set_std(proc.stderr, output, 'stderr', output_format)
     return output
Exemplo n.º 14
0
 def __actions(self, data):
     cmd = data.get('cmd', None)
     daemon = data.get('daemon', None)
     output = dict(type='action')
     # TODO validate daemon if cmd @stop, @restart
     if cmd.startswith('@') and cmd in ('@stop', '@restart'):
         output.update(self.__run_daemon(cmd=cmd, daemon=daemon))
     else:
         run = ' '.join([cmd] + wrap(data.get('args', [])))
         start = time.time()
         proc = self.__run_cmd(cmd=run, daemon=daemon, output=output)
         output.update(error=proc.returncode != 0,
                       executed=run,
                       return_code=proc.returncode,
                       duration=time.time() - start)
         self.__set_std(proc.stdout, output, 'stdout')
         self.__set_std(proc.stderr, output, 'stderr')
     return output
Exemplo n.º 15
0
 def decorator(self):
     if self.__name__.endswith('Selected_Resource'):
         mode = 'selected'
     else:
         mode = 'base'
     for method in wrap(methods):
         base_mth = getattr(self, f'on_base_{method}')
         setattr(self, f'on_{method}', copy_func(base_mth, f'on_{method}'))
         mth = getattr(self, f'on_{method}', None)
         path = Path(
             __file__).parent / f'../docstring/{mode}/{method}.{ext}'
         with path.open('r') as file:
             mth.__doc__ = format(file.read(), self=self)
         if self.schema.__doc__ is not None:
             self.tag = {
                 'name': self.doc.Index.name,
                 'description': self.schema.__doc__.strip(' \n')
             }
     return self
Exemplo n.º 16
0
 def __parameters(self, data):
     schema = data.get('schema', None)
     source = data.get('source', None)
     path = wrap(data.get('path', []))
     value = data.get('value', None)
     output = {'type': 'parameter'}
     try:
         source = expand_user(source)
         output.update(
             self.parsers.get(schema)(schema, source, path, value))
         return output
     except File_Not_Found_Error as e:
         msg = f'Source {source} not found'
         self.log.exception(msg, e)
         return Not_Found_Response(msg, e, type='parameter', data=data)
     except Exception as e:
         msg = f'Source {source} not accessible'
         self.log.exception(msg, e)
         return Bad_Request_Response(e,
                                     message=msg,
                                     type='parameter',
                                     data=data)
Exemplo n.º 17
0
 def __parameters(self, data):
     schema = data.get('schema', None)
     source = data.get('source', None)
     path = wrap(data.get('path', None))
     value = data.get('value', None)
     output = dict(type='parameter')
     try:
         source = expand_user(source)
         output.update(
             self.parsers.get(schema)(schema, source, path, value))
     except File_Not_Found_Error as e:
         self.log.exception(e)
         output.update(error=True,
                       data=data,
                       description=f'Source {source} not found',
                       exception=extract_info(e))
     except Exception as e:
         self.log.exception(e)
         output.update(error=True,
                       data=data,
                       description=f'Source {source} not accessible',
                       exception=extract_info(e))
     return output