示例#1
0
 def test_put_persistent_graph_lock_code_mismatch(
         self, mocker: MockerFixture) -> None:
     """Test put_persistent_graph lock code mismatch."""
     mocker.patch.object(
         CfnginContext,
         "persistent_graph_location",
         {
             "Bucket": "test-bucket",
             "Key": "something.json"
         },
     )
     mocker.patch.object(CfnginContext, "persistent_graph_locked", True)
     mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "0")
     obj = CfnginContext()
     obj.persistent_graph = Graph.from_dict(self.persist_graph_raw,
                                            context=obj)
     with pytest.raises(PersistentGraphLockCodeMissmatch):
         obj.put_persistent_graph("123")
示例#2
0
    def test_unlock_persistent_graph(self):
        """Return 'True' when delete tag is successful."""
        code = '0000'
        context = Context(config=self.persist_graph_config)
        context._s3_bucket_verified = True
        context._persistent_graph = Graph.from_dict({'stack1': []}, context)
        stubber = Stubber(context.s3_conn)

        stubber.add_response(
            'get_object_tagging',
            {'TagSet': gen_tagset({context._persistent_graph_lock_tag: code})},
            context.persistent_graph_location)
        stubber.add_response('delete_object_tagging', {},
                             context.persistent_graph_location)

        with stubber:
            self.assertTrue(context.unlock_persistent_graph(code))
            stubber.assert_no_pending_responses()
示例#3
0
    def test_run_persist(
        self,
        mock_execute: MagicMock,
        mock_unlock: MagicMock,
        mock_lock: MagicMock,
        mock_graph_tags: PropertyMock,
    ) -> None:
        """Test run persist."""
        mock_graph_tags.return_value = {}
        context = self._get_context(
            extra_config_args={"persistent_graph_key": "test.json"})
        context._persistent_graph = Graph.from_steps(
            [Step.from_stack_name("removed", context)])
        deploy_action = deploy.Action(context=context)
        deploy_action.run()

        mock_graph_tags.assert_called_once()
        mock_lock.assert_called_once()
        mock_execute.assert_called_once()
        mock_unlock.assert_called_once()
示例#4
0
    def test_unlock_persistent_graph_no_object(self):
        """Return 'None' when object does not exist.

        This can occur if the object is deleted by 'put_persistent_graph'.

        """
        code = "0000"
        context = Context(config=self.persist_graph_config)
        context._s3_bucket_verified = True
        context._persistent_graph = Graph()
        stubber = Stubber(context.s3_conn)
        expected_params = context.persistent_graph_location.copy()
        expected_params.update({"ResponseContentType": "application/json"})

        stubber.add_client_error("get_object",
                                 "NoSuchKey",
                                 expected_params=expected_params)

        with stubber:
            assert context.unlock_persistent_graph(code)
            stubber.assert_no_pending_responses()
示例#5
0
    def test_unlock_persistent_graph_code_missmatch(self):
        """Error raised when local code does not match object."""
        code = "0000"
        context = Context(config=self.persist_graph_config)
        context._s3_bucket_verified = True
        context._persistent_graph = Graph.from_dict({"stack1": []}, context)
        stubber = Stubber(context.s3_conn)

        stubber.add_response(
            "get_object_tagging",
            {
                "TagSet": gen_tagset(
                    {context._persistent_graph_lock_tag: "1111"})
            },
            context.persistent_graph_location,
        )

        with stubber:
            with self.assertRaises(PersistentGraphCannotUnlock):
                context.unlock_persistent_graph(code)
            stubber.assert_no_pending_responses()
示例#6
0
    def test_lock_persistent_graph(self):
        """Return 'None' when lock is successful."""
        code = "0000"
        context = Context(config=self.persist_graph_config)
        context._s3_bucket_verified = True
        context._persistent_graph = Graph()
        stubber = Stubber(context.s3_conn)
        expected_params = {
            "Tagging": {
                "TagSet":
                gen_tagset({context._persistent_graph_lock_tag: code})
            }
        }
        expected_params.update(context.persistent_graph_location)

        stubber.add_response("get_object_tagging", {"TagSet": []},
                             context.persistent_graph_location)
        stubber.add_response("put_object_tagging", {}, expected_params)

        with stubber:
            self.assertIsNone(context.lock_persistent_graph(code))
            stubber.assert_no_pending_responses()
示例#7
0
    def test_dump(self) -> None:
        """Test dump."""
        requires: List[str] = []
        steps: List[Step] = []

        for i in range(5):
            overrides = {
                "variables": {
                    "PublicSubnets": "1",
                    "SshKeyName": "1",
                    "PrivateSubnets": "1",
                    "Random": "${noop something}",
                },
                "requires": requires,
            }

            stack = Stack(
                definition=generate_definition("vpc", i, **overrides),
                context=self.context,
            )
            requires = [stack.name]

            steps += [Step(stack)]

        graph = Graph.from_steps(steps)
        plan = Plan(description="Test", graph=graph)

        tmp_dir = tempfile.mkdtemp()
        try:
            plan.dump(directory=tmp_dir, context=self.context)

            for step in plan.steps:
                template_path = os.path.join(
                    tmp_dir, stack_template_key_name(step.stack.blueprint)  # type: ignore
                )
                self.assertTrue(os.path.isfile(template_path))
        finally:
            shutil.rmtree(tmp_dir)
示例#8
0
 def test_put_persistent_graph(self, mocker: MockerFixture) -> None:
     """Test put_persistent_graph."""
     mocker.patch.object(
         CfnginContext,
         "persistent_graph_location",
         {
             "Bucket": "test-bucket",
             "Key": "something.json"
         },
     )
     mocker.patch.object(CfnginContext, "persistent_graph_locked", True)
     mocker.patch.object(CfnginContext, "persistent_graph_lock_code", "123")
     obj = CfnginContext()
     obj.persistent_graph = Graph.from_dict(self.persist_graph_raw,
                                            context=obj)
     stubber = Stubber(obj.s3_client)
     stubber.add_response(
         "put_object",
         {},
         {
             "Body":
             json.dumps(self.persist_graph_raw,
                        default=json_serial,
                        indent=4).encode(),
             "ServerSideEncryption":
             "AES256",
             "ACL":
             "bucket-owner-full-control",
             "ContentType":
             "application/json",
             "Tagging":
             "cfngin_lock_code=123",
             **obj.persistent_graph_location,
         },
     )
     with stubber:
         assert not obj.put_persistent_graph("123")
示例#9
0
    def test_generate_plan_with_persist_exclude(self, mock_stack_action,
                                                mock_tags):
        """Test generate plan with persist exclude."""
        mock_stack_action.return_value = MagicMock()
        mock_tags.return_value = {}
        context = mock_context(namespace='test',
                               extra_config_args=self.config_persist,
                               region=self.region)
        persist_step = Step.from_stack_name('removed', context)
        context._persistent_graph = Graph.from_steps([persist_step])
        action = BaseAction(context=context,
                            provider_builder=MockProviderBuilder(
                                self.provider, region=self.region))

        plan = action._generate_plan(include_persistent_graph=False)

        self.assertIsInstance(plan, Plan)
        # order is different between python2/3 so can't compare dicts
        result_graph_dict = plan.graph.to_dict()
        self.assertEqual(2, len(result_graph_dict))
        self.assertEqual(set(), result_graph_dict['stack1'])
        self.assertEqual(set(['stack1']), result_graph_dict['stack2'])
        self.assertEqual(BaseAction.DESCRIPTION, plan.description)
        self.assertTrue(plan.require_unlocked)
示例#10
0
    def test_execute_plan_cancelled(self) -> None:
        """Test execute plan cancelled."""
        vpc = Stack(definition=generate_definition("vpc", 1), context=self.context)
        bastion = Stack(
            definition=generate_definition("bastion", 1, requires=[vpc.name]),
            context=self.context,
        )

        calls: List[str] = []

        def fn(stack: Stack, status: Optional[Status] = None) -> Status:
            calls.append(stack.fqn)
            if stack.fqn == vpc_step.name:
                raise CancelExecution
            return COMPLETE

        vpc_step = Step(vpc, fn=fn)
        bastion_step = Step(bastion, fn=fn)

        graph = Graph.from_steps([vpc_step, bastion_step])
        plan = Plan(description="Test", graph=graph)
        plan.execute(walk)

        self.assertEqual(calls, ["namespace-vpc.1", "namespace-bastion.1"])
示例#11
0
    def test_lock_persistent_graph_locked(self):
        """Error raised when when object is locked."""
        code = '0000'
        context = Context(config=self.persist_graph_config)
        context._s3_bucket_verified = True
        context._persistent_graph = Graph()
        stubber = Stubber(context.s3_conn)
        expected_params = {
            'Tagging': {
                'TagSet':
                gen_tagset({context._persistent_graph_lock_tag: code})
            }
        }
        expected_params.update(context.persistent_graph_location)

        stubber.add_response('get_object_tagging', {
            'TagSet':
            gen_tagset({context._persistent_graph_lock_tag: '1111'})
        }, context.persistent_graph_location)

        with stubber:
            with self.assertRaises(PersistentGraphLocked):
                context.lock_persistent_graph(code)
            stubber.assert_no_pending_responses()
示例#12
0
    def test_dumps(self):
        """Test dumps."""
        graph = Graph()
        graph.add_steps(self.steps)

        self.assertEqual(json.dumps(self.graph_dict), graph.dumps())