def apply_migration_policies(role_arn): click.echo("Updating state file") with betterboto_client.CrossAccountClientContextManager( "organizations", role_arn, f"organizations", ) as organizations: list_accounts_response = organizations.list_accounts_single_page() list_roots_response = organizations.list_roots_single_page() root_id = list_roots_response.get("Roots")[0].get("Id") org_path = SEP.join(["environment", root_id]) all_files_in_environment_list = helper.getListOfFiles(org_path) # Step 1 Save Attached policies accounts = { account.get("Id"): account.get("Name") for account in list_accounts_response.get("Accounts") } ous = get_organizational_units(root_id) # list all OUs in org org_ids_map = accounts | ous policy_ids_map = dict() # map SCP name to Ids for file_path in os.listdir(service_control_policies_path): policy = helper.read_json( SEP.join([service_control_policies_path, file_path]))["PolicySummary"] policy_ids_map[helper.get_valid_filename( policy["Name"])] = policy["Id"] # TODO make this in accordance with Eamonn's AWS Organized general way of doing things # so the user will be able to type in the file name and the migration wil be applied reverse_org_ids_map = dict((v, k) for k, v in org_ids_map.items()) for migration_policy in os.listdir( make_individual_migration_policies_path): policy = helper.read_json( SEP.join( [make_individual_migration_policies_path, migration_policy])).get("Migration") policy_id = policy.get("Policy_Id") policy_name = policy.get("Policy_Name") target_name = policy.get("Target") target_id = reverse_org_ids_map[target_name] policy_type = policy.get("Migration_Type") try: org.attach_policy( PolicyId=policy_id, TargetId=target_id ) if policy_type == ATTACH_POLICY else org.detach_policy( PolicyId=policy_id, TargetId=target_id) except: print( f"Error when attempting to {policy_type} {policy_name} on target {target_name}." ) else: print( f"Successfully performed {policy_type} {policy_name} on target {target_name}." )
def get_org_structure(org_path) -> dict: file_list = helper.getListOfFiles(org_path) accounts_path = helper.get_account_paths(file_list) ous_path = { path[0].split("/")[-1]: path[0] + "/" for path in os.walk(org_path) if path[0][-9:] != "_accounts" } return accounts_path, ous_path
def clean_up(): for file_path in helper.getListOfFiles(policies_migration_path): if "policies.yaml" in file_path: print(f"Deleted {file_path} policy descriptions files") os.remove(file_path)
def make_migration_policies(role_arn) -> None: # 0 get initial state # 0.1 read for org state # 0.2 read for account state # 1. read current state by looking through _policies folders in organization # 1.1 read for org state # 1.2 read for account state with betterboto_client.CrossAccountClientContextManager( "organizations", role_arn, f"organizations", ) as organizations: list_accounts_response = organizations.list_accounts_single_page() list_roots_response = organizations.list_roots_single_page() root_id = list_roots_response.get("Roots")[0].get("Id") org_path = SEP.join(["environment", root_id]) all_files_in_environment_list = helper.getListOfFiles(org_path) # read initial setup initial_scp_per_target_state = helper.read_yaml(policies_migration_path + "/initial_state.yaml") current_policies_state = dict() attach_policies = dict() detach_policies = dict() print("all_files_in_environment_list", all_files_in_environment_list) for file_path in all_files_in_environment_list: if "_service_control_policies.yaml" in file_path: target_name = file_path.split("/")[-2] print(target_name) policies_list = helper.read_yaml(file_path)["Policies_Attached"] current_policies_state[target_name] = policies_list # 2 Compare migration state to current state for key, value in current_policies_state.items(): print("key", key) print("value", value) print("initial_scp_per_target_state", initial_scp_per_target_state) # find diff policy if value != initial_scp_per_target_state[key]: detached_policy_list = [ item for item in initial_scp_per_target_state[key] if item not in current_policies_state[key] ] attach_policies_list = [ item for item in current_policies_state[key] if item not in initial_scp_per_target_state[key] ] # make sure non empty values are not saved if detached_policy_list: detach_policies[key] = detached_policy_list if attach_policies_list: attach_policies[key] = attach_policies_list # 3 Create migration document summary helper.write_to_file( { "Attached_Policies": attach_policies, "Detached_Policies": detach_policies, }, policies_migration_path, "migration_state_summary.yaml", ) # 3 Create migration folder # map policy name to policy content policies_map = dict() for policy in os.listdir(service_control_policies_path): policies_map[policy.replace(".json", "")] = helper.read_json( SEP.join([service_control_policies_path, policy])) for target, policy_list in attach_policies.items(): print(attach_policies.items()) print("\n") print("target", target) print("\n") # data, path, file_name for policy in policy_list: file_name = f"{ATTACH_POLICY}_SCP_{policy}_TARGET_{target}.json" policies_map[policy]["Migration"] = { "Migration_Type": ATTACH_POLICY, "Target": target, "Policy_Name": policy, "Policy_Id": policies_map[policy].get("PolicySummary").get("Id"), } helper.write_to_file( policies_map[policy], policies_migration_path + "/migrations_to_apply", file_name, ) for target, policy_list in detach_policies.items(): # data, path, file_name for policy in policy_list: file_name = f"{DETACH_POLICY}_SCP_{policy}_TARGET_{target}.json" policies_map[policy]["Migration"] = { "Migration_Type": DETACH_POLICY, "Target": target, "Policy_Name": policy, "Policy_Id": policies_map[policy].get("PolicySummary").get("Id"), } helper.write_to_file( policies_map[policy], policies_migration_path + "/migrations_to_apply", file_name, ) return
def import_organization_policies(role_arn) -> None: click.echo("Updating state file") with betterboto_client.CrossAccountClientContextManager( "organizations", role_arn, f"organizations", ) as organizations: list_accounts_details = organizations.list_accounts_single_page() list_roots_response = organizations.list_roots_single_page() root_id = list_roots_response.get("Roots")[0].get("Id") org_path = SEP.join(["environment", root_id]) all_files_in_environment_list = helper.getListOfFiles(org_path) # Step 0 get all policies in org all_service_control_policies_in_org = org.list_policies( Filter=SERVICE_CONTROL_POLICY).get("Policies") all_service_control_policies_in_org_with_policy_summary = [ org.describe_policy(PolicyId=policy.get("Id")).get("Policy") for policy in all_service_control_policies_in_org ] [ helper.write_to_file( { "PolicySummary": policy.get("PolicySummary"), "Content": json.loads(policy.get("Content")), }, service_control_policies_path, helper.get_valid_filename(policy.get("PolicySummary").get("Name")) + ".json", ) for policy in all_service_control_policies_in_org_with_policy_summary ] # Step 1 Save Attached policies accounts = { account.get("Id"): account.get("Name") for account in list_accounts_details.get("Accounts") } ous = get_organizational_units(root_id) # list all OUs in org service_control_policies_path_for_target = helper.map_scp_path_for_target_name( all_files_in_environment_list, root_id) ( service_control_policies_for_target, scp_name_for_each_target, ) = get_service_control_policies_for_target(ous | accounts, root_id) write_policies_to_target_yaml(service_control_policies_for_target, service_control_policies_path_for_target) # Step 2 Save Inherited policies for file_path in all_files_in_environment_list: if "_service_control_policies.yaml" in file_path: current_scp_path_list = file_path.split("/") root_org_scp_path = org_path + "/_service_control_policies.yaml" local_policy = [ policy for policy in helper.read_yaml(root_org_scp_path) ["Policies_Attached"] ] for i in range(len(current_scp_path_list)): # go through every OU in org structure if "_organizational_units" in current_scp_path_list[i]: current_organizational_unit_index = current_scp_path_list.index( current_scp_path_list[i + 1]) current_policy_path = (SEP.join( current_scp_path_list[: -current_organizational_unit_index] ) + "/_service_control_policies.yaml") # TODO change this to save as policy_name ===> source: Org_source local_policy.extend([ attached_policy for attached_policy in helper.read_yaml( current_policy_path)["Policies_Attached"] if attached_policy not in local_policy ]) if (file_path != root_org_scp_path and "_service_control_policies.yaml" in current_scp_path_list[i]): helper.write_inherited_yaml(local_policy, file_path) # save initial set up helper.write_to_file(scp_name_for_each_target, policies_migration_path, "initial_state.yaml")