Exemple #1
0
    def test_post_project(self, mock_verify_certificates):
        mock_verify_certificates.return_value = (True, '')
        name = 'test-post-project'
        config = {
            'participants': [{
                'name': 'test-post-participant',
                'domain_name': 'fl-test-post.com',
                'url': '127.0.0.1:32443',
                'certificates': self.TEST_CERTIFICATES
            }],
            'variables': [{
                'name': 'test-post',
                'value': 'test'
            }]
        }
        comment = 'test post project'
        create_response = self.post_helper('/api/v2/projects',
                                           data={
                                               'name': name,
                                               'config': config,
                                               'comment': comment
                                           })
        self.assertEqual(create_response.status_code, HTTPStatus.OK)
        created_project = json.loads(create_response.data).get('data')

        queried_project = Project.query.filter_by(name=name).first()
        self.assertEqual(created_project, queried_project.to_dict())

        mock_verify_certificates.assert_called_once_with(
            parse_certificates(self.TEST_CERTIFICATES))
Exemple #2
0
 def setUp(self):
     super().setUp()
     with open(os.path.join(os.path.dirname(os.path.realpath(__file__)),
                            'test.tar.gz'), 'rb') as file:
         self.TEST_CERTIFICATES = str(b64encode(file.read()), encoding='utf-8')
     self.default_project = Project()
     self.default_project.name = 'test-self.default_project'
     self.default_project.set_config(ParseDict({
         'participants': [
             {
                 'name': 'test-participant',
                 'domain_name': 'fl-test.com',
                 'url': '127.0.0.1:32443'
             }
         ],
         'variables': [
             {
                 'name': 'test',
                 'value': 'test'
             }
         ]
     }, ProjectProto()))
     self.default_project.set_certificate(ParseDict({
         'domain_name_to_cert': {'fl-test.com':
                                     {'certs':
                                          parse_certificates(self.TEST_CERTIFICATES)}},
     }, CertificateStorage()))
     self.default_project.comment = 'test comment'
     db.session.add(self.default_project)
     workflow = Workflow(name='workflow_key_get1',
                         project_id=1)
     db.session.add(workflow)
     db.session.commit()
Exemple #3
0
 def test_parse_certificates(self):
     file_names = [
         'client/client.pem', 'client/client.key', 'client/intermediate.pem', 'client/root.pem',
         'server/server.pem', 'server/server.key', 'server/intermediate.pem', 'server/root.pem'
     ]
     with open(os.path.join(os.path.dirname(os.path.realpath(__file__)),
                            'test.tar.gz'), 'rb') as file:
         certificates = parse_certificates(b64encode(file.read()))
     for file_name in file_names:
         self.assertEqual(str(b64decode(certificates.get(file_name)), encoding='utf-8'),
                          'test {}'.format(file_name))
Exemple #4
0
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name',
                            required=True,
                            type=str,
                            help=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                                'name', 'Empty'))
        parser.add_argument('config',
                            required=True,
                            type=dict,
                            help=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                                'config', 'Empty'))
        parser.add_argument('comment')
        data = parser.parse_args()
        name = data['name']
        config = data['config']
        comment = data['comment']

        if Project.query.filter_by(name=name).first() is not None:
            raise InvalidArgumentException(
                details=ErrorMessage.NAME_CONFLICT.value.format(name))

        if config.get('participants') is None:
            raise InvalidArgumentException(
                details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                    'participants', 'Empty'))
        if len(config.get('participants')) != 1:
            # TODO: remove limit after operator supports multiple participants
            raise InvalidArgumentException(
                details='Currently not support multiple participants.')

        # exact configuration from variables
        # TODO: one custom host for one participant
        custom_host = None
        for variable in config.get('variables', []):
            if variable.get('name') == 'CUSTOM_HOST':
                custom_host = variable.get('value')

        # parse participant
        certificates = {}
        for participant in config.get('participants'):
            if 'name' not in participant.keys() or \
                'url' not in participant.keys() or \
                'domain_name' not in participant.keys():
                raise InvalidArgumentException(
                    details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                        'participants', 'Participant must have name, '
                        'domain_name and url.'))
            if re.match(_URL_REGEX, participant.get('url')) is None:
                raise InvalidArgumentException('URL pattern is wrong')
            domain_name = participant.get('domain_name')
            # Grpc spec
            participant['grpc_spec'] = {
                'authority': '{}-client-auth.com'.format(domain_name[:-4])
            }
            if participant.get('certificates') is not None:
                current_cert = parse_certificates(
                    participant.get('certificates'))
                success, err = verify_certificates(current_cert)
                if not success:
                    raise InvalidArgumentException(err)
                certificates[domain_name] = {'certs': current_cert}
            if 'certificates' in participant.keys():
                participant.pop('certificates')

        new_project = Project()
        # generate token
        # If users send a token, then use it instead.
        # If `token` is None, generate a new one by uuid.
        config['name'] = name
        token = config.get('token', uuid4().hex)
        config['token'] = token

        # check format of config
        try:
            new_project.set_config(ParseDict(config, ProjectProto()))
        except Exception as e:
            raise InvalidArgumentException(
                details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                    'config', e))
        new_project.set_certificate(
            ParseDict({'domain_name_to_cert': certificates},
                      CertificateStorage()))
        new_project.name = name
        new_project.token = token
        new_project.comment = comment

        # create add on
        for participant in new_project.get_config().participants:
            if participant.domain_name in\
                new_project.get_certificate().domain_name_to_cert.keys():
                _create_add_on(
                    participant,
                    new_project.get_certificate().domain_name_to_cert[
                        participant.domain_name], custom_host)
        try:
            new_project = db.session.merge(new_project)
            db.session.commit()
        except Exception as e:
            raise InvalidArgumentException(details=str(e))

        return {'data': new_project.to_dict()}
Exemple #5
0
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name',
                            required=True,
                            type=str,
                            help=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                                'name', 'Empty'))
        parser.add_argument('config',
                            required=True,
                            type=dict,
                            help=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                                'config', 'Empty'))
        parser.add_argument('comment')
        data = parser.parse_args()
        name = data['name']
        config = data['config']
        comment = data['comment']

        if Project.query.filter_by(name=name).first() is not None:
            raise InvalidArgumentException(
                details=ErrorMessage.NAME_CONFLICT.value.format(name))

        if config.get('participants') is None:
            raise InvalidArgumentException(
                details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                    'participants', 'Empty'))
        if len(config.get('participants')) != 1:
            # TODO: remove limit after operator supports multiple participants
            raise InvalidArgumentException(
                details='Currently not support multiple participants.')

        certificates = {}
        for participant in config.get('participants'):
            if 'name' not in participant.keys() or \
                'url' not in participant.keys() or \
                'domain_name' not in participant.keys():
                raise InvalidArgumentException(
                    details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                        'participants', 'Participant must have name, '
                        'domain_name and url.'))
            domain_name = participant.get('domain_name')
            if participant.get('certificates') is not None:
                current_cert = parse_certificates(
                    participant.get('certificates'))
                # check validation
                for file_name in _CERTIFICATE_FILE_NAMES:
                    if current_cert.get(file_name) is None:
                        raise InvalidArgumentException(
                            details=ErrorMessage.PARAM_FORMAT_ERROR.value.
                            format('certificates', '{} not existed'.format(
                                file_name)))
                certificates[domain_name] = {'certs': current_cert}
                participant.pop('certificates')

                # create add on
                try:
                    k8s_client = get_client()
                    for domain_name, certificate in certificates.items():
                        create_add_on(k8s_client, domain_name,
                                      participant.get('url'), current_cert)
                except RuntimeError as e:
                    raise InvalidArgumentException(details=str(e))

        new_project = Project()
        # generate token
        # If users send a token, then use it instead.
        # If `token` is None, generate a new one by uuid.
        config['name'] = name
        token = config.get('token', uuid4().hex)
        config['token'] = token

        # check format of config
        try:
            new_project.set_config(ParseDict(config, ProjectProto()))
        except Exception as e:
            raise InvalidArgumentException(
                details=ErrorMessage.PARAM_FORMAT_ERROR.value.format(
                    'config', e))
        new_project.set_certificate(
            ParseDict({'domain_name_to_cert': certificates},
                      CertificateStorage()))
        new_project.name = name
        new_project.token = token
        new_project.comment = comment

        try:
            new_project = db.session.merge(new_project)
            db.session.commit()
        except Exception as e:
            raise InvalidArgumentException(details=str(e))

        return {'data': new_project.to_dict()}