From f0cfcd468a8dcb4f5d3ab5b35b807b4ccf02216f Mon Sep 17 00:00:00 2001 From: kukushking Date: Sun, 9 Feb 2025 01:48:29 +0000 Subject: [PATCH] refactor to use paths at the edges --- seedfarmer/__main__.py | 8 +++---- seedfarmer/cli_groups/_bootstrap_group.py | 12 +++++------ seedfarmer/commands/_bootstrap_commands.py | 21 +++++++++++-------- seedfarmer/commands/_deployment_commands.py | 14 ++++++++----- seedfarmer/commands/_stack_commands.py | 8 +++---- seedfarmer/mgmt/deploy_utils.py | 2 +- .../models/manifests/_deployment_manifest.py | 12 ++++------- seedfarmer/services/_iam.py | 4 ++-- seedfarmer/services/session_manager.py | 10 ++++----- seedfarmer/utils.py | 6 ++++-- 10 files changed, 51 insertions(+), 46 deletions(-) diff --git a/seedfarmer/__main__.py b/seedfarmer/__main__.py index ba2689a..30552e6 100644 --- a/seedfarmer/__main__.py +++ b/seedfarmer/__main__.py @@ -66,7 +66,7 @@ def version() -> None: ) @click.option( "--role-prefix", - default="/", + default=None, help="""An IAM path prefix to use with the seedfarmer roles. Use only if bootstrapped with this path""", required=False, @@ -136,7 +136,7 @@ def apply( profile: Optional[str], region: Optional[str], qualifier: Optional[str], - role_prefix: str, + role_prefix: Optional[str], env_files: List[str], debug: bool, dry_run: bool, @@ -211,7 +211,7 @@ def apply( ) @click.option( "--role-prefix", - default="/", + default=None, help="""An IAM path prefix to use with the seedfarmer roles. Use only if bootstrapped with this path""", required=False, @@ -264,7 +264,7 @@ def destroy( profile: Optional[str], region: Optional[str], qualifier: Optional[str], - role_prefix: str, + role_prefix: Optional[str], env_files: List[str], debug: bool, enable_session_timeout: bool, diff --git a/seedfarmer/cli_groups/_bootstrap_group.py b/seedfarmer/cli_groups/_bootstrap_group.py index c53cb5b..017b638 100644 --- a/seedfarmer/cli_groups/_bootstrap_group.py +++ b/seedfarmer/cli_groups/_bootstrap_group.py @@ -103,13 +103,13 @@ def bootstrap() -> None: ) @click.option( "--role-prefix", - default="/", + default=None, help="An IAM path prefix to use with the seedfarmer roles.", required=False, ) @click.option( "--policy-prefix", - default="/", + default=None, help="An IAM path prefix to use with the seedfarmer policies.", required=False, ) @@ -133,8 +133,8 @@ def bootstrap_toolchain( profile: Optional[str], region: Optional[str], qualifier: Optional[str], - role_prefix: str, - policy_prefix: str, + role_prefix: Optional[str], + policy_prefix: Optional[str], as_target: bool, synth: bool, debug: bool, @@ -215,7 +215,7 @@ def bootstrap_toolchain( ) @click.option( "--role-prefix", - default="/", + default=None, help="An IAM path prefix to use with the seedfarmer roles.", required=False, ) @@ -237,7 +237,7 @@ def bootstrap_target( profile: Optional[str], region: Optional[str], qualifier: Optional[str], - role_prefix: str, + role_prefix: Optional[str], synth: bool, debug: bool, ) -> None: diff --git a/seedfarmer/commands/_bootstrap_commands.py b/seedfarmer/commands/_bootstrap_commands.py index a033136..511c5da 100644 --- a/seedfarmer/commands/_bootstrap_commands.py +++ b/seedfarmer/commands/_bootstrap_commands.py @@ -39,7 +39,7 @@ def get_toolchain_template( principal_arn: List[str], role_name: str, permissions_boundary_arn: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> Dict[Any, Any]: with open((os.path.join(CLI_ROOT, "resources/toolchain_role.template")), "r") as f: role = yaml.safe_load(f) @@ -49,6 +49,7 @@ def get_toolchain_template( ] = principal_arn if permissions_boundary_arn: role["Resources"]["ToolchainRole"]["Properties"]["PermissionsBoundary"] = permissions_boundary_arn + role_prefix = role_prefix if role_prefix else "/" template = Template(json.dumps(role)) t = template.render( { @@ -67,8 +68,8 @@ def get_deployment_template( role_name: str, policy_arns: Optional[List[str]], permissions_boundary_arn: Optional[str] = None, - role_prefix: str = "/", - policy_prefix: str = "/", + role_prefix: Optional[str] = None, + policy_prefix: Optional[str] = None, ) -> Dict[Any, Any]: with open((os.path.join(CLI_ROOT, "resources/deployment_role.template")), "r") as f: role = yaml.safe_load(f) @@ -76,6 +77,8 @@ def get_deployment_template( role["Resources"]["DeploymentRole"]["Properties"]["PermissionsBoundary"] = permissions_boundary_arn if policy_arns: role["Resources"]["DeploymentRole"]["Properties"]["ManagedPolicyArns"] = policy_arns + role_prefix = role_prefix if role_prefix else "/" + policy_prefix = policy_prefix if policy_prefix else "/" template = Template(json.dumps(role)) t = template.render( { @@ -101,8 +104,8 @@ def bootstrap_toolchain_account( permissions_boundary_arn: Optional[str] = None, policy_arns: Optional[List[str]] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", - policy_prefix: str = "/", + role_prefix: Optional[str] = None, + policy_prefix: Optional[str] = None, profile: Optional[str] = None, region_name: Optional[str] = None, synthesize: bool = False, @@ -126,7 +129,7 @@ def bootstrap_toolchain_account( _logger.debug((json.dumps(template, indent=4))) if not synthesize: session = create_new_session(profile=profile, region_name=region_name) - session_account_id, session_role_arn, partition = get_sts_identity_info(session=session) + session_account_id, _, _ = get_sts_identity_info(session=session) apply_deploy_logic( template=template, role_name=role_stack_name, @@ -169,8 +172,8 @@ def bootstrap_target_account( project_name: str, permissions_boundary_arn: Optional[str] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", - policy_prefix: str = "/", + role_prefix: Optional[str] = None, + policy_prefix: Optional[str] = None, profile: Optional[str] = None, region_name: Optional[str] = None, session: Optional[Session] = None, @@ -182,7 +185,7 @@ def bootstrap_target_account( if not session: session = create_new_session(profile=profile, region_name=region_name) - session_account_id, session_role_arn, partition = get_sts_identity_info(session=session) + session_account_id, _, partition = get_sts_identity_info(session=session) role_stack_name = get_deployment_role_name(project_name=project_name, qualifier=cast(str, qualifier)) toolchain_role_arn = get_toolchain_role_arn( diff --git a/seedfarmer/commands/_deployment_commands.py b/seedfarmer/commands/_deployment_commands.py index b965ab1..09e0755 100644 --- a/seedfarmer/commands/_deployment_commands.py +++ b/seedfarmer/commands/_deployment_commands.py @@ -436,11 +436,12 @@ def _prime_accounts(args: Dict[str, Any]) -> List[Any]: "region": region, "update_seedkit": update_seedkit, "update_project_policy": update_project_policy, - "role_prefix": role_prefix, - "policy_prefix": policy_prefix, "permissions_boundary_arn": permissions_boundary_arn, } - + if role_prefix: + param_d["role_prefix"] = role_prefix + if policy_prefix: + param_d["policy_prefix"] = policy_prefix if target_account_region["network"] is not None: network = commands.load_network_values( cast(NetworkMapping, target_account_region["network"]), @@ -765,7 +766,7 @@ def apply( profile: Optional[str] = None, region_name: Optional[str] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, dryrun: bool = False, show_manifest: bool = False, enable_session_timeout: bool = False, @@ -914,7 +915,7 @@ def destroy( profile: Optional[str] = None, region_name: Optional[str] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, dryrun: bool = False, show_manifest: bool = False, remove_seedkit: bool = False, @@ -936,6 +937,9 @@ def destroy( qualifier : str, optional Any qualifier on the name of toolchain role Defaults to None + role_prefix : str, optional + IAM path prefix on the ARN of the toolchain and deployment roles + Defaults to '/' dryrun : bool, optional This flag indicates that the deployment WILL NOT enact any deployment changes. diff --git a/seedfarmer/commands/_stack_commands.py b/seedfarmer/commands/_stack_commands.py index 05efff2..e7d5954 100644 --- a/seedfarmer/commands/_stack_commands.py +++ b/seedfarmer/commands/_stack_commands.py @@ -132,7 +132,7 @@ def create_module_deployment_role( docker_credentials_secret: Optional[str] = None, permissions_boundary_arn: Optional[str] = None, session: Optional[boto3.Session] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> None: iam.create_check_iam_role( project_name=config.PROJECT, @@ -442,7 +442,7 @@ def deploy_module_stack( parameters: List[ModuleParameter], docker_credentials_secret: Optional[str] = None, permissions_boundary_arn: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> Tuple[str, str]: """ deploy_module_stack @@ -589,8 +589,8 @@ def deploy_seedkit( private_subnet_ids: Optional[List[str]] = None, security_group_ids: Optional[List[str]] = None, update_seedkit: Optional[bool] = False, - role_prefix: str = "/", - policy_prefix: str = "/", + role_prefix: Optional[str] = None, + policy_prefix: Optional[str] = None, permissions_boundary_arn: Optional[str] = None, **kwargs: Any, ) -> Dict[str, Any]: diff --git a/seedfarmer/mgmt/deploy_utils.py b/seedfarmer/mgmt/deploy_utils.py index 26ccf46..9971cbd 100644 --- a/seedfarmer/mgmt/deploy_utils.py +++ b/seedfarmer/mgmt/deploy_utils.py @@ -118,7 +118,7 @@ def _get_module_info(args: Dict[str, Any]) -> None: { "account_id": target_account_region["account_id"], "region": target_account_region["region"], - "role_prefix": target_account_region.get("role_prefix", "/"), + "role_prefix": target_account_region["role_prefix"], } for target_account_region in deployment_manifest.target_accounts_regions ] diff --git a/seedfarmer/models/manifests/_deployment_manifest.py b/seedfarmer/models/manifests/_deployment_manifest.py index c12c761..3cc5c5f 100644 --- a/seedfarmer/models/manifests/_deployment_manifest.py +++ b/seedfarmer/models/manifests/_deployment_manifest.py @@ -234,6 +234,8 @@ def target_accounts_regions(self) -> List[Dict[str, str]]: self._accounts_regions = [] for target_account in self.target_account_mappings: for region in target_account.region_mappings: + role_prefix = region.role_prefix if region.role_prefix else target_account.role_prefix + policy_prefix = region.policy_prefix if region.policy_prefix else target_account.policy_prefix account_region_args = { "alias": target_account.alias, "account_id": target_account.actual_account_id, @@ -241,15 +243,9 @@ def target_accounts_regions(self) -> List[Dict[str, str]]: "network": region.network, "parameters_regional": region.parameters_regional, "codebuild_image": cast(str, region.codebuild_image), + "role_prefix": role_prefix, + "policy_prefix": policy_prefix, } - role_prefix = region.role_prefix if region.role_prefix else target_account.role_prefix - policy_prefix = region.policy_prefix if region.policy_prefix else target_account.policy_prefix - - if role_prefix: - account_region_args["role_prefix"] = role_prefix - if policy_prefix: - account_region_args["policy_prefix"] = policy_prefix - self._accounts_regions.append(account_region_args) # type: ignore return self._accounts_regions diff --git a/seedfarmer/services/_iam.py b/seedfarmer/services/_iam.py index bfc6f09..1a5780f 100644 --- a/seedfarmer/services/_iam.py +++ b/seedfarmer/services/_iam.py @@ -52,7 +52,7 @@ def create_check_iam_role( group_name: Optional[str] = None, module_name: Optional[str] = None, session: Optional[Session] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> None: _logger.debug("Creating IAM Role with name: %s ", role_name) iam_client = boto3_client("iam", session=session) @@ -61,7 +61,7 @@ def create_check_iam_role( except iam_client.exceptions.NoSuchEntityException: args: Dict[str, Any] = { "RoleName": role_name, - "Path": role_prefix, + "Path": role_prefix if role_prefix else "/", "AssumeRolePolicyDocument": json.dumps(trust_policy), "Description": f"deployment-role for {role_name}", "Tags": [ diff --git a/seedfarmer/services/session_manager.py b/seedfarmer/services/session_manager.py index b856925..5293ec8 100644 --- a/seedfarmer/services/session_manager.py +++ b/seedfarmer/services/session_manager.py @@ -49,7 +49,7 @@ def get_or_create( region_name: Optional[str] = None, toolchain_region: Optional[str] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, profile: Optional[str] = None, enable_reaper: bool = False, **kwargs: Optional[Any], @@ -87,7 +87,7 @@ def get_or_create( profile: Optional[str] = None, toolchain_region: Optional[str] = None, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, reaper_interval: Optional[int] = None, enable_reaper: bool = False, **kwargs: Optional[Any], @@ -102,7 +102,7 @@ def get_or_create( self.config["profile"] = profile self.config["toolchain_region"] = toolchain_region self.config["qualifier"] = qualifier if qualifier else None - self.config["role_prefix"] = role_prefix + self.config["role_prefix"] = role_prefix if role_prefix else "/" self.config = {**self.config, **kwargs} self.toolchain_role_name = get_toolchain_role_name(project_name, cast(str, qualifier)) @@ -143,7 +143,7 @@ def get_deployment_session(self, account_id: str, region_name: str) -> Session: session_key = f"{account_id}-{region_name}" project_name = self.config["project_name"] qualifier = self.config.get("qualifier") if self.config.get("qualifier") else None - role_prefix = self.config.get("role_prefix", "/") + role_prefix = self.config.get("role_prefix") toolchain_region = self.config.get("toolchain_region") if not self.created: raise seedfarmer.errors.InvalidConfigurationError("The SessionManager object was never properly created...") @@ -212,7 +212,7 @@ def _get_toolchain(self) -> Tuple[Session, "AssumeRoleResponseTypeDef"]: profile_name = self.config.get("profile") project_name = self.config.get("project_name") qualifier = self.config.get("qualifier") if self.config.get("qualifier") else None - role_prefix = self.config.get("role_prefix", "/") + role_prefix = self.config.get("role_prefix") toolchain_region = self.config.get("toolchain_region") _logger.debug( f"""Creating a local session with the following info passed in: diff --git a/seedfarmer/utils.py b/seedfarmer/utils.py index e146169..5d863b2 100644 --- a/seedfarmer/utils.py +++ b/seedfarmer/utils.py @@ -148,8 +148,9 @@ def get_toolchain_role_arn( toolchain_account_id: str, project_name: str, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> str: + role_prefix = role_prefix if role_prefix else "/" return ( f"arn:{partition}:iam::{toolchain_account_id}:role{role_prefix}" f"{get_toolchain_role_name(project_name, qualifier)}" @@ -166,8 +167,9 @@ def get_deployment_role_arn( deployment_account_id: str, project_name: str, qualifier: Optional[str] = None, - role_prefix: str = "/", + role_prefix: Optional[str] = None, ) -> str: + role_prefix = role_prefix if role_prefix else "/" return ( f"arn:{partition}:iam::{deployment_account_id}:role{role_prefix}" f"{get_deployment_role_name(project_name, qualifier)}"