Esempio n. 1
0
def delete_stack(
    profile: Union[str, bool] = False,
    region: Union[str, bool] = False,
    wait: bool = False,
    iam: Union[str, bool] = False,
) -> None:
    """Handle deletion of the stack.

    Two situation, normal deletion and retained deletion.
    When the selected stack is already in a 'DELETE_FAILED' state, extra
    fzf operation would be triggered for user to select logical id to retain
    in order for deletion to be success.

    :param profile: use a different profile for this operation
    :type profile: Union[str, bool], optional
    :param region: use a different region for this operation
    :type region: Union[str, bool], optional
    :param wait: pause the function and wait for stack delete complete
    :type wait: bool, optional
    :param iam: specify a iam arn to delete this stack
    :type iam: Union[str, bool]
    """
    cloudformation = Cloudformation(profile, region)
    cloudformation.set_stack()

    logical_id_list: List[str] = []
    if cloudformation.stack_details["StackStatus"] == "DELETE_FAILED":
        header: str = "stack is in the failed state, specify any resource to skip during deletion"
        logical_id_list = cloudformation.get_stack_resources(empty_allow=True,
                                                             header=header)

    cloudformation_args: Dict[str, Any] = {
        "StackName": cloudformation.stack_name
    }
    if logical_id_list:
        cloudformation_args["RetainResources"] = logical_id_list

    if iam and type(iam) == str:
        cloudformation_args["RoleARN"] = iam
    elif iam and type(iam) == bool:
        iam_instance = IAM(profile=cloudformation.profile)
        iam_instance.set_arns(
            header=
            "select a iam role with permissions to delete the current stack",
            service="cloudformation.amazonaws.com",
        )
        if iam_instance.arns[0]:
            cloudformation_args["RoleARN"] = iam_instance.arns[0]

    if not get_confirmation("Are you sure you want to delete the stack '%s'?" %
                            cloudformation.stack_name):
        sys.exit(1)

    cloudformation.client.delete_stack(**cloudformation_args)
    print("Stack deletion initiated")

    if wait:
        cloudformation.wait("stack_delete_complete",
                            "Wating for stack to be deleted ...")
        print("Stack deleted")
Esempio n. 2
0
 def setUp(self):
     fileloader = FileLoader()
     config_path = Path(__file__).resolve().parent.joinpath(
         "../data/fzfaws.yml")
     fileloader.load_config_file(config_path=str(config_path))
     self.iam = IAM()
     capturedOutput = io.StringIO()
     sys.stdout = capturedOutput
Esempio n. 3
0
    def test_constructor(self):
        self.assertEqual([""], self.iam.arns)
        self.assertEqual("default", self.iam.profile)
        self.assertEqual("us-east-1", self.iam.region)

        iam = IAM(profile="root", region="us-east-1")
        self.assertEqual("root", iam.profile)
        self.assertEqual("us-east-1", iam.region)
        self.assertEqual([""], self.iam.arns)
Esempio n. 4
0
    def _set_permissions(self, update: bool = False) -> None:
        """Set the iam user for the current stack.

        All operation permissions will be based on this
        iam role. Select None to stop using iam role
        and use current profile permissions.

        :param update: show previous values if true
        :type update: bool, optional
        """
        print(80 * "-")
        iam = IAM(profile=self.cloudformation.profile)
        if not update:
            header = (
                "choose an IAM role to explicitly define CloudFormation's permissions\n"
            )
            header += "Note: only IAM role can be assumed by CloudFormation is listed"
            iam.set_arns(header=header, service="cloudformation.amazonaws.com")
        else:
            header = "select a role Choose an IAM role to explicitly define CloudFormation's permissions\n"
            header += "Original value: %s" % self.cloudformation.stack_details.get(
                "RoleARN")
            iam.set_arns(header=header, service="cloudformation.amazonaws.com")
        if iam.arns:
            self._extra_args["RoleARN"] = iam.arns[0]
Esempio n. 5
0
class TestIAM(unittest.TestCase):
    def setUp(self):
        fileloader = FileLoader()
        config_path = Path(__file__).resolve().parent.joinpath(
            "../data/fzfaws.yml")
        fileloader.load_config_file(config_path=str(config_path))
        self.iam = IAM()
        capturedOutput = io.StringIO()
        sys.stdout = capturedOutput

    def tearDown(self):
        sys.stdout = sys.__stdout__

    def test_constructor(self):
        self.assertEqual([""], self.iam.arns)
        self.assertEqual("default", self.iam.profile)
        self.assertEqual("us-east-1", self.iam.region)

        iam = IAM(profile="root", region="us-east-1")
        self.assertEqual("root", iam.profile)
        self.assertEqual("us-east-1", iam.region)
        self.assertEqual([""], self.iam.arns)

    @patch.object(Paginator, "paginate")
    @patch.object(Pyfzf, "process_list")
    @patch.object(Pyfzf, "append_fzf")
    @patch.object(Pyfzf, "execute_fzf")
    def test_setarns(self, mocked_fzf_execute, mocked_fzf_append,
                     mocked_fzf_list, mocked_result):
        mocked_result.return_value = [{
            "Roles": [{
                "Path": "/",
                "RoleName": "admincloudformaitontest",
                "RoleId": "AROAVQL5EWXLRDZGWYAU2",
                "Arn": "arn:aws:iam::111111:role/admincloudformaitontest",
                "CreateDate": "2010-09-09",
                "AssumeRolePolicyDocument": {
                    "Version":
                    "2012-10-17",
                    "Statement": [{
                        "Sid": "",
                        "Effect": "Allow",
                        "Principal": {
                            "Service": "cloudformation.amazonaws.com"
                        },
                        "Action": "sts:AssumeRole",
                    }],
                },
                "Description":
                "Allows CloudFormation to create and manage AWS stacks and resources on your behalf.",
                "MaxSessionDuration": 3600,
            }]
        }]

        # general test
        mocked_fzf_execute.return_value = (
            "arn:aws:iam::111111:role/admincloudformaitontest")
        self.iam.set_arns()
        self.assertEqual(self.iam.arns,
                         ["arn:aws:iam::111111:role/admincloudformaitontest"])
        mocked_fzf_append.assert_not_called()
        mocked_fzf_list.assert_called_with(
            [{
                "Path": "/",
                "RoleName": "admincloudformaitontest",
                "RoleId": "AROAVQL5EWXLRDZGWYAU2",
                "Arn": "arn:aws:iam::111111:role/admincloudformaitontest",
                "CreateDate": "2010-09-09",
                "AssumeRolePolicyDocument": {
                    "Version":
                    "2012-10-17",
                    "Statement": [{
                        "Sid": "",
                        "Effect": "Allow",
                        "Principal": {
                            "Service": "cloudformation.amazonaws.com"
                        },
                        "Action": "sts:AssumeRole",
                    }],
                },
                "Description":
                "Allows CloudFormation to create and manage AWS stacks and resources on your behalf.",
                "MaxSessionDuration": 3600,
            }],
            "RoleName",
            "Arn",
        )

        # parameter test
        self.iam.set_arns(service="cloudformation.amazonaws.com")
        mocked_fzf_append.assert_called_with(
            "RoleName: admincloudformaitontest  Arn: arn:aws:iam::111111:role/admincloudformaitontest"
        )

        mocked_fzf_append.reset_mock()
        self.iam.set_arns(service="hello")
        mocked_fzf_append.assert_not_called()

        mocked_fzf_list.reset_mock()
        self.iam.set_arns(header="hello", empty_allow=True, multi_select=True)
        mocked_fzf_list.assert_called_once()
        mocked_fzf_execute.assert_called_with(empty_allow=True,
                                              header="hello",
                                              multi_select=True,
                                              print_col=4)

        self.iam.set_arns(arns="111111")
        self.assertEqual(self.iam.arns, ["111111"])

        self.iam.set_arns(arns=["111111", "222222"])
        self.assertEqual(self.iam.arns, ["111111", "222222"])

        # empty result test
        self.iam.arns = [""]
        mocked_fzf_execute.reset_mock()
        mocked_fzf_append.reset_mock()
        mocked_result.return_value = []
        mocked_fzf_execute.return_value = ""
        self.iam.set_arns(service="cloudformation.amazonaws.com")
        mocked_fzf_append.assert_not_called()
        mocked_fzf_execute.assert_called_once()
        self.assertEqual([""], self.iam.arns)