Exemplo n.º 1
0
 def setUp(self, single_full_app_fixture):
     self.filter = NameSpaceFilter()
     self.request_app = SieveMarathonApp.from_json(single_full_app_fixture)
     self.original_app = SieveMarathonApp.from_json(single_full_app_fixture)
     self.account = Account(name="Dev Account", namespace="dev", owner="company")
     self.user = User(tx_email="*****@*****.**")
     self.user.current_account = self.account
    def test_dispatch_should_pass_an_instance_if_SieveMarathonApp_to_filters(
            self):
        """
        Certifica que quando um request remove todas as constraints e algum filtro adiciona novas
        constraints, essas constraints adicionadas pelo filtro são preservadas
        """
        class AddNewConstraintFilter:
            def write(self, user, request_app, original_app):
                assert isinstance(request_app, SieveMarathonApp)
                return request_app

        pipeline = {
            OperationType.WRITE: [
                AddNewConstraintFilter(),
            ]
        }

        request_data = {"constraints": []}
        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                headers={"Content-type": "application/json"},
                data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
    def test_update_app_remove_all_constraints(self):
        """
        Certifica que um request que remove todas as constraints,
        remove essas constraints na app original
        """
        class DummyFilter:
            def write(self, user, request_app, original_app):
                return request_app

        pipeline = {
            OperationType.WRITE: [
                DummyFilter(),
            ]
        }

        request_data = {"constraints": []}
        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                data=json.dumps(request_data),
                headers={"Content-type": "application/json"}) as ctx:
            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(0, len(filtered_app.constraints))
            self._check_other_fields("constraints", filtered_app)
    def test_preserve_envs_added_by_filter(self):
        class AddNewEnvFilter:
            def write(self, user, request_app, original_app):
                request_app.env["env1"] = "env-value1"
                return request_app

        pipeline = {
            OperationType.WRITE: [
                AddNewEnvFilter(),
            ]
        }
        request_data = {"env": []}

        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                headers={"Content-type": "application/json"},
                data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(1, len(filtered_app.env.keys()))
            self.assertEqual({"env1": "env-value1"}, filtered_app.env)
            self._check_other_fields("env", filtered_app)
Exemplo n.º 5
0
    def test_multiapp_response_returns_multiple_marathonapp_instances(
            self, fixture):
        modified_app = fixture.copy()
        modified_app['id'] = '/xablau'

        apps = [fixture, modified_app]
        with application.test_request_context('/v2/apps/',
                                              method='GET',
                                              data=b'') as ctx:
            response = FlaskResponse(response=json.dumps({"apps": apps}),
                                     status=HTTPStatus.OK,
                                     headers={})
            response = Response(ctx.request, response)

        with patch.object(response, 'marathon_client') as client:
            original_apps = [MarathonApp.from_json(app) for app in apps]
            client.get_app.side_effect = original_apps
            apps = list(response.split())
            self.assertEqual([call("/foo"), call("/xablau")],
                             client.get_app.call_args_list)

        self.assertEqual(
            apps,
            [(SieveMarathonApp.from_json(fixture), original_apps[0]),
             (SieveMarathonApp.from_json(modified_app), original_apps[1])])
Exemplo n.º 6
0
    def split(self) -> Apps:

        if self.is_read_request():
            response_content = json.loads(self.response.data)
            if self.is_list_apps_request():
                for app in response_content['apps']:
                    response_app = SieveMarathonApp.from_json(app)
                    app = self.marathon_client.get_app(self.object_id
                                                       or response_app.id)
                    yield response_app, app
                return
            elif self.is_group_request():
                response_group = SieveAppGroup(
                    MarathonGroup.from_json(response_content))
                for current_group in response_group.iterate_groups():
                    group_id = current_group.id
                    group_id_without_namespace = self._remove_namespace_if_exists(
                        self.request.user.current_account.namespace, group_id)
                    original_group = self._get_original_group(
                        self.request.user, group_id_without_namespace)
                    yield current_group, original_group
                return
            elif self.is_tasks_request():
                for task in response_content['tasks']:
                    response_task = MarathonTask.from_json(task)
                    yield response_task, response_task
                return
            elif self.is_deployment():
                content = response_content
                deployments = (MarathonDeployment.from_json(deploy)
                               for deploy in content)

                for deployment in deployments:
                    yield deployment, deployment
                return
            elif self.is_queue_request():
                queue_data = response_content
                queued_apps = (MarathonQueueItem.from_json(queue_item)
                               for queue_item in queue_data['queue'])
                for queued_app in queued_apps:
                    yield queued_app, queued_app
                return
            else:
                response_app = SieveMarathonApp.from_json(
                    response_content.get('app') or response_content)
                app = self.marathon_client.get_app(self.object_id)
                yield response_app, app
                return

        if self.is_write_request():
            response_content = json.loads(self.response.data)
            if 'tasks' in response_content:
                for task in response_content['tasks']:
                    response_task = MarathonTask.from_json(task)
                    yield response_task, response_task
                return
            return

        yield SieveMarathonApp(), self.marathon_client.get_app(self.app_id)
 def setUp(self, single_full_app_fixture):
     self.request = Request(None)
     self.single_full_app_fixture = single_full_app_fixture
     self.filter = IncompatibleFieldsFilter()
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     self.original_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
Exemplo n.º 8
0
 def setUp(self, single_full_app_fixture):
     self.docker_auth_uri = "file:///etc/docker.tar.bz2"
     self.base_uris = ["http://google.com", "file://etc/file.txt"]
     self.single_full_app_fixture = single_full_app_fixture
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     self.original_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     self.filter = AddURIFilter()
Exemplo n.º 9
0
 def setUp(self):
     self.single_full_app_fixture = get_fixture("single_full_app.json")
     self.filter = BasicConstraintFilter()
     self.request_app = SieveMarathonApp.from_json(self.single_full_app_fixture)
     self.original_app = Mock()
     self.user = Mock()
     self.constraints = (BasicConstraintFilter.mesos_constraint, BasicConstraintFilter.workload_constraint)
Exemplo n.º 10
0
    def test_it_recreates_a_get_response_for_multiple_apps(self, fixture):
        modified_app = deepcopy(fixture)
        modified_app['id'] = '/xablau'

        fixtures = [fixture, modified_app]
        expected_response = deepcopy(fixtures)
        with application.test_request_context('/v2/apps/',
                                              method='GET',
                                              data=b'') as ctx:
            response = FlaskResponse(response=json.dumps({"apps": fixtures}),
                                     status=HTTPStatus.OK,
                                     headers={})
            response = Response(ctx.request, response)

        with patch.object(response, 'marathon_client') as client:
            original_apps = [
                SieveMarathonApp.from_json(app) for app in fixtures
            ]
            client.get_app.side_effect = original_apps
            apps = list(response.split())

            joined_response = response.join(apps)

            self.assertIsInstance(joined_response, FlaskResponse)
            self.assertDictEqual(json.loads(joined_response.data),
                                 {'apps': expected_response})
Exemplo n.º 11
0
    def merge_marathon_apps(self, modified_app, base_app):
        """
        A junção das duas apps (request_app (aqui modified_app) e original_app (aqui base_app)) é
        sempre feita pegando todos os dados da original_app e jogando os dados da requst_app "em cima".
        Não podemos usar o `minimal=Fase` na request_app pois para requests que estão *incompletos*, ou seja,
        sem alguns vampos (já veremos exemplo) se esássemos minimal=False, iríramos apagar esses "campos faltantes"
        da original_app. Exemplos:

            request_app = {"instances": 10}
            original_app está completa, com envs, constraints e tudo mais.

            se usamos `minimal=False` na request_app, teremos um JSON com *todos* os campos em branco, menos o "instances".
            Então quando fizermos `merged.update(modified_app.json_repr(minimal=False))`, vamos no final ter um JSON apenas com
            o campo "instances" perrnchido e todo o restante vazio.


        """

        merged = base_app.json_repr(minimal=False)
        merged.update(modified_app.json_repr(minimal=True))
        try:
            raw_request_data = json.loads(self.request.data)
            for key in REMOVABLE_KEYS:
                if key in raw_request_data:
                    merged[key] = raw_request_data[key]
        except Exception as e:
            pass
        if isinstance(base_app, MarathonTask):
            return MarathonTask.from_json(merged)
        return SieveMarathonApp.from_json(merged)
Exemplo n.º 12
0
 def test_create_app_add_uri_if_not_exist(self):
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     filtered_app = self.filter.write(None, self.request_app,
                                      SieveMarathonApp())
     self.assertEqual(1, len(filtered_app.uris))
     self.assertEqual([self.docker_auth_uri], filtered_app.uris)
Exemplo n.º 13
0
    def test_preserve_healthchecks_added_by_filter(self):
        class AddNewHealthCheckFilter:
            def write(self, user, request_app, original_app):
                hc_data = {
                    "command": None,
                    "gracePeriodSeconds": 30,
                    "intervalSeconds": 10,
                    "maxConsecutiveFailures": 3,
                    "path": "/marathon/healthcheck",
                    "portIndex": 0,
                    "protocol": "HTTP",
                    "timeoutSeconds": 5,
                    "ignoreHttp1xx": False
                }
                request_app.health_checks.append(
                    MarathonHealthCheck.from_json(hc_data))
                return request_app

        pipeline = {
            OperationType.WRITE: [
                AddNewHealthCheckFilter(),
            ]
        }
        request_data = {"healthChecks": []}

        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                headers={"Content-type": "application/json"},
                data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(1, len(filtered_app.health_checks))
            self.assertEqual("/marathon/healthcheck",
                             filtered_app.health_checks[0].json_repr()['path'])
            self._check_other_fields("healthChecks", filtered_app)
Exemplo n.º 14
0
    def test_response_apps_remove_namespace_from_app_id_containig_namespace_in_its_name(self, single_full_app_with_tasks_fixture):
        """
        Uma app com id = "/<namespace>/some/other/path/<namespace>/other/app" deve ter apenas a primeira ocorrência de "/<namespace>" removida.
        """
        response_app = original_app = SieveMarathonApp.from_json(single_full_app_with_tasks_fixture)
        response_app.id = "/dev/some/other/path/dev/other/app"

        modified_app = self.filter.response(self.user, response_app, original_app)
        self.assertEqual("/some/other/path/dev/other/app", modified_app.id)
Exemplo n.º 15
0
    def test_a_single_app_response_returns_a_single_marathonapp(self, fixture):
        with application.test_request_context('/v2/apps//foo',
                                              method='GET',
                                              data=b'') as ctx:
            flask_response = FlaskResponse(response=json.dumps(
                {"app": fixture}),
                                           status=HTTPStatus.OK,
                                           headers={})
            response = Response(ctx.request, flask_response)

            with patch.object(response, 'marathon_client') as client:
                client.get_app.return_value = SieveMarathonApp.from_json(
                    fixture)
                apps = list(response.split())
                self.assertEqual([call("/foo")], client.get_app.call_args_list)

            self.assertEqual(apps, [(SieveMarathonApp.from_json(fixture),
                                     client.get_app.return_value)])
Exemplo n.º 16
0
 def test_update_app_do_not_add_uri_if_exist(self):
     self.single_full_app_fixture['uris'] = copy(
         self.base_uris) + [self.docker_auth_uri]
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     filtered_app = self.filter.write(None, self.request_app,
                                      self.original_app)
     self.assertEqual(3, len(filtered_app.uris))
     self.assertEqual(self.base_uris + [self.docker_auth_uri],
                      filtered_app.uris)
Exemplo n.º 17
0
    def setUp(self, single_full_app_fixture):
        self.filter = AddOwnerConstraintFilter()
        rebuild_schema()
        self.session = HollowmanSession()
        self.user = User(tx_email="*****@*****.**",
                         tx_name="John Doe",
                         tx_authkey="69ed620926be4067a36402c3f7e9ddf0")
        self.account_dev = Account(id=4,
                                   name="Dev Team",
                                   namespace="dev",
                                   owner="company")
        self.user.accounts = [self.account_dev]
        self.session.add(self.user)
        self.session.add(self.account_dev)
        self.session.commit()

        self.request_app = SieveMarathonApp.from_json(single_full_app_fixture)
        self.original_app = SieveMarathonApp.from_json(single_full_app_fixture)
        self.user.current_account = self.account_dev
Exemplo n.º 18
0
    def test_response_apps_remove_namespace_from_all_tasks_empty_task_list(self, single_full_app_with_tasks_fixture):
        request_app = original_app = SieveMarathonApp.from_json(single_full_app_with_tasks_fixture)
        request_app.id = "/dev/foo"
        request_app.tasks = []
        original_app.id = "/dev/foo"
        original_app.tasks = []
        self.assertEqual(0, len(request_app.tasks))

        modified_app = self.filter.response(self.user, request_app, original_app)
        self.assertEqual(0, len(self.request_app.tasks))
Exemplo n.º 19
0
    def test_preserve_upgrade_strategy_added_by_filter(self):
        class AddNewUpgradeStrategyFilter:
            def write(self, user, request_app, original_app):
                us_data = {
                    "maximumOverCapacity": 1,
                    "minimumHealthCapacity": 0.75
                }
                request_app.upgrade_strategy = MarathonUpgradeStrategy.from_json(
                    us_data)
                return request_app

        pipeline = {
            OperationType.WRITE: [
                AddNewUpgradeStrategyFilter(),
            ]
        }
        # Simulando uma app que veio sem o campo "upgradeStrategy"
        request_data = {}

        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                headers={"Content-type": "application/json"},
                data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(
                1, filtered_app.upgrade_strategy.maximum_over_capacity)
            self.assertEqual(
                0.75, filtered_app.upgrade_strategy.minimum_health_capacity)
            self._check_other_fields("upgradeStrategy", filtered_app)
Exemplo n.º 20
0
 def test_create_app_add_uri_with_other_existing_uris(self):
     """
     Mesmo se a app já tiver utras uris, temos que adicionar a nossa
     """
     self.single_full_app_fixture['uris'] = copy(self.base_uris)
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     filtered_app = self.filter.write(None, self.request_app,
                                      SieveMarathonApp())
     self.assertEqual(3, len(filtered_app.uris))
     self.assertEqual(self.base_uris + [self.docker_auth_uri],
                      filtered_app.uris)
Exemplo n.º 21
0
    def test_response_apps_remove_namespace_from_all_tasks(self, single_full_app_with_tasks_fixture):
        request_app = original_app = SieveMarathonApp.from_json(single_full_app_with_tasks_fixture)

        self.assertEqual(3, len(request_app.tasks))
        modified_app = self.filter.response(self.user, request_app, original_app)
        self.assertEqual("foo.a29b3666-be63-11e7-8ef1-0242a8c1e33e", modified_app.tasks[0].id)
        self.assertEqual("/foo", modified_app.tasks[0].app_id)

        self.assertEqual("foo.a31e220e-be63-11e7-8ef1-0242a8c1e33e", modified_app.tasks[1].id)
        self.assertEqual("/foo", modified_app.tasks[1].app_id)

        self.assertEqual("foo.a31dfafb-be63-11e7-8ef1-0242a8c1e33e", modified_app.tasks[2].id)
        self.assertEqual("/foo", modified_app.tasks[2].app_id)
Exemplo n.º 22
0
 def test_update_app_do_not_add_uri_if_exist_with_spaces(self):
     """
     Não precisamos fazer o strip nos valores originais pois o Marathon já faz isso pra nós.
     """
     self.single_full_app_fixture['uris'] = copy(
         self.base_uris) + ["      " + self.docker_auth_uri]
     self.request_app = SieveMarathonApp.from_json(
         self.single_full_app_fixture)
     filtered_app = self.filter.write(None, self.request_app,
                                      self.original_app)
     self.assertEqual(3, len(filtered_app.uris))
     self.assertEqual(self.base_uris + ["      " + self.docker_auth_uri],
                      filtered_app.uris)
Exemplo n.º 23
0
    def test_update_app_change_all_constraints(self):
        """
        Devemos respeitar as constraints quem estão da request,
        elas devem substituir as constrains da app original
        """
        class DummyFilter:
            def write(self, user, request_app, original_app):
                return request_app

        pipeline = {
            OperationType.WRITE: [
                DummyFilter(),
            ]
        }

        request_data = {"constraints": [["hostname", "LIKE", "myhost"]]}
        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                data=json.dumps(request_data),
                headers={"Content-type": "application/json"}) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(1, len(filtered_app.constraints))
            self.assertEqual(["hostname", "LIKE", "myhost"],
                             filtered_app.constraints[0].json_repr())
            self._check_other_fields("constraints", filtered_app)
Exemplo n.º 24
0
    def test_preserve_constraints_added_by_filter(self):
        """
        Certifica que quando um request remove todas as constraints e algum filtro adiciona novas
        constraints, essas constraints adicionadas pelo filtro são preservadas
        """
        class AddNewConstraintFilter:
            def write(self, user, request_app, original_app):
                request_app.constraints.append(
                    MarathonConstraint.from_json("key:LIKE:value".split(":")))
                return request_app

        pipeline = {
            OperationType.WRITE: [
                AddNewConstraintFilter(),
            ]
        }

        request_data = {"constraints": []}
        request_app = SieveMarathonApp.from_json(request_data)
        original_app = SieveMarathonApp.from_json(
            deepcopy(self.single_full_app_fixture))

        with application.test_request_context(
                "/v2/apps/foo",
                method="PUT",
                headers={"Content-type": "application/json"},
                data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user,
                                        request,
                                        filters_pipeline=pipeline)
            filtered_request_app = SieveMarathonApp.from_json(
                filtered_request.get_json())
            self.assertEqual(1, len(filtered_request_app.constraints))
            self._check_other_fields("constraints", filtered_request_app)
Exemplo n.º 25
0
    def test_a_request_for_a_new_app_will_return_a_tuple_with_an_empty_marathonapp(
            self, fixture):
        with application.test_request_context('/v2/apps//foo',
                                              method='PUT',
                                              data=json.dumps(fixture)) as ctx:
            ctx.request.user = self.user
            request_parser = Request(ctx.request)
            with patch.object(request_parser, 'marathon_client') as client:
                response_mock = Mock()
                response_mock.headers.get.return_value = 'application/json'
                client.get_app.side_effect = NotFoundError(
                    response=response_mock)
                apps = list(request_parser.split())

            self.assertEqual(apps,
                             [(SieveMarathonApp.from_json(fixture),
                               MarathonApp.from_json({"id": "/dev/foo"}))])
Exemplo n.º 26
0
    def test_it_recreates_a_get_response_for_a_single_app(self, fixture):
        self.maxDiff = None
        with application.test_request_context('/v2/apps//foo',
                                              method='GET',
                                              data=b'') as ctx:
            response = FlaskResponse(response=json.dumps({"app": fixture}),
                                     status=HTTPStatus.OK,
                                     headers={})
            response = Response(ctx.request, response)

        with patch.object(response, 'marathon_client') as client:
            client.get_app.return_value = SieveMarathonApp.from_json(
                deepcopy(fixture))
            apps = list(response.split())

            joined_response = response.join(apps)

            self.assertIsInstance(joined_response, FlaskResponse)
            self.assertDictEqual(json.loads(joined_response.data),
                                 {'app': fixture})
Exemplo n.º 27
0
 def setUp(self, single_full_app_fixture):
     self.sieve_marathon_app = SieveMarathonApp.from_json(
         single_full_app_fixture)
Exemplo n.º 28
0
 def setUp(self, single_full_app_fixture):
     self.filter = LabelsFilter()
     self.single_full_app_fixture = single_full_app_fixture
     self.request_app = SieveMarathonApp.from_json(self.single_full_app_fixture)
     self.original_app = SieveMarathonApp.from_json(self.single_full_app_fixture)
Exemplo n.º 29
0
    def test_response_apps_returns_none_if_outside_current_namespace(self, single_full_app_with_tasks_fixture):
        request_app = original_app =SieveMarathonApp.from_json(single_full_app_with_tasks_fixture)
        request_app.id = original_app.id = "/othernamespace/foo"

        self.assertIsNone(self.filter.response(self.user, request_app, original_app))