Example #1
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]):
                     if is_list(code):
                         code = '\n'.join(code)
                     pc = self.polycube.update(cube=id,
                                               code=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 = 'No content to update code with the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Example #2
0
    def validate(self, data, response_type=Ok_Response, id=None):
        try:
            if id is not None:
                if is_list(data):
                    msg = 'When the id is present in the request uri only one record can be managed.'
                    raise Validation_Error({'id': msg})
                elif id in data:
                    msg = 'Present in the request uri.'
                    raise Validation_Error({'id': msg})
                else:
                    data.update(id=id)
            if self.check_unique_id and is_list(
                    data) and not Unique_List.apply('id')(data):
                msg = 'Same id present multiple times in the request.'
                raise Validation_Error({'id': msg})
            self.load(data)
            return response_type(data), True
        except Validation_Error as val_err:

            def __norm(block):
                for field in block.keys():
                    if is_list(block[field]):
                        block[field] = block[field].pop()
                    elif is_dict(block[field]):
                        __norm(block[field])
                return block

            msg = __norm(val_err.normalized_messages())
            return Not_Acceptable_Response(msg), False
Example #3
0
 def add(self, resp):
     if is_list(resp):
         resp.append(self.__data())
     else:
         if not is_list(resp.media):
             resp.media = []
         resp.media.append(self.__data())
         resp_code = int(resp.status.split()[0])
         if self.code is not None and HTTP_Status.lt(resp_code, self.code):
             resp.status = f'{self.code} {self.status()}'
Example #4
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)
Example #5
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)
Example #6
0
 def __norm(block):
     for field in block.keys():
         if is_list(block[field]):
             block[field] = block[field].pop()
         elif is_dict(block[field]):
             __norm(block[field])
     return block
Example #7
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)
Example #8
0
 def on_post(self, req, resp, id=None):
     req_data = req.media or {}
     resp_data, valid = Code_Request_Schema(many=is_list(req_data),
                                            method=HTTP_Method.POST).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.create(cube=id, code=code,
                                               interface=interface, metrics=metrics)
                     if not pc.get('error', False):
                         self.cubes.append(id)
                         msg = f'Code with the id={id} correctly injected'
                         resp_data = Created_Response(msg)
                     else:
                         msg = f'Not possible to inject code with the id={id}'
                         resp_data = Unprocessable_Entity_Response(msg)
                     resp_data.update(pc)
                 else:
                     msg = f'Not possible to inject code with the id={id}'
                     resp_data = Unprocessable_Entity_Response(msg)
                 resp_data.add(resp)
         else:
             msg = f'No content to create code with the {{request}}'
             No_Content_Response(msg, request=req_data).apply(resp)
     else:
         resp_data.apply(resp)
Example #9
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)
Example #10
0
 def __where(self, query, id=None):
     q = None
     for op, clause in query.get('where', {}).items():
         if op == 'and':
             if is_dict(clause):
                 for sub_op, sub_clause in clause.items():
                     if q is None:
                         q = self.__where({'where': {sub_op: sub_clause}})
                     else:
                         q = q & self.__where(
                             {'where': {
                                 sub_op: sub_clause
                             }})
             elif is_list(clause):
                 for sub_clause in clause:
                     if q is None:
                         q = self.__where({'where': sub_clause})
                     else:
                         q = q & self.__where({'where': sub_clause})
         elif op == 'or':
             if is_dict(clause):
                 for sub_op, sub_clause in clause.items():
                     if q is None:
                         q = self.__where({'where': {sub_op: sub_clause}})
                     else:
                         q = q | self.__where(
                             {'where': {
                                 sub_op: sub_clause
                             }})
             elif is_list(clause):
                 for sub_clause in clause:
                     if q is None:
                         q = self.__where({'where': sub_clause})
                     else:
                         q = q | self.__where({'where': sub_clause})
         elif op == 'not':
             q = ~self.__where(clause)
         else:
             prop = self.__fix_target(clause.get('target', None))
             expr = clause.get('expr', None)
             if prop is not None and expr is not None:
                 if op == 'equals':
                     q = Q('match_phrase', **{prop: expr})
                 elif op == 'reg_exp':
                     q = Q('regexp', **{prop: {'value': expr}})
                 elif op == 'wildcard':
                     q = Q('wildcard', **{prop: {'value': expr}})
                 elif op in ['lt', 'lte', 'gt', 'gte']:
                     q = Q('range', **{prop: {op: expr}})
                 else:
                     raise HTTP_Bad_Request(title='Operation unknown',
                                            description=f'{op} unknown')
             else:
                 raise HTTP_Bad_Request(
                     title='Request not valid',
                     description=f'{op} clause with not valid/missing data')
     if id is not None:
         if q is None:
             q = Q('term', _id=id)
         else:
             q = q & Q('term', _id=id)
     return q if q is not None else Q()