@beesolve/aws-accounts 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/applyLogic.js +571 -225
- package/dist/awsConfig.js +441 -30
- package/dist/cli.js +86 -23
- package/dist/commands/graveyard.js +27 -0
- package/dist/commands/remote.js +206 -39
- package/dist/commands/validate.js +75 -0
- package/dist/diff.js +336 -14
- package/dist/lambda/handler.js +8 -4
- package/dist/lambdaClient.js +5 -2
- package/dist/operations.js +116 -1
- package/dist/scanLogic.js +237 -9
- package/dist/state.js +244 -8
- package/dist-lambda/handler.mjs +1164 -248
- package/dist-lambda/lambda.zip +0 -0
- package/package.json +2 -1
package/dist-lambda/handler.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
|
9
9
|
import { OrganizationsClient as OrganizationsClient3 } from "@aws-sdk/client-organizations";
|
|
10
10
|
import { SSOAdminClient as SSOAdminClient3 } from "@aws-sdk/client-sso-admin";
|
|
11
11
|
import { IdentitystoreClient as IdentitystoreClient3 } from "@aws-sdk/client-identitystore";
|
|
12
|
-
import { AccountClient as
|
|
12
|
+
import { AccountClient as AccountClient3 } from "@aws-sdk/client-account";
|
|
13
13
|
|
|
14
14
|
// node_modules/valibot/dist/index.mjs
|
|
15
15
|
var store$4;
|
|
@@ -792,6 +792,22 @@ var provisionIdcPermissionSetOperationSchema = strictObject({
|
|
|
792
792
|
permissionSetName: string(),
|
|
793
793
|
targetScope: literal("ALL_PROVISIONED_ACCOUNTS")
|
|
794
794
|
});
|
|
795
|
+
var permissionsBoundaryOperationValueSchema = union([
|
|
796
|
+
strictObject({ managedPolicyArn: string() }),
|
|
797
|
+
strictObject({
|
|
798
|
+
customerManagedPolicyName: string(),
|
|
799
|
+
customerManagedPolicyPath: string()
|
|
800
|
+
})
|
|
801
|
+
]);
|
|
802
|
+
var putIdcPermissionSetPermissionsBoundaryOperationSchema = strictObject({
|
|
803
|
+
kind: literal("putIdcPermissionSetPermissionsBoundary"),
|
|
804
|
+
permissionSetName: string(),
|
|
805
|
+
permissionsBoundary: permissionsBoundaryOperationValueSchema
|
|
806
|
+
});
|
|
807
|
+
var deleteIdcPermissionSetPermissionsBoundaryOperationSchema = strictObject({
|
|
808
|
+
kind: literal("deleteIdcPermissionSetPermissionsBoundary"),
|
|
809
|
+
permissionSetName: string()
|
|
810
|
+
});
|
|
795
811
|
var grantIdcAccountAssignmentOperationSchema = strictObject({
|
|
796
812
|
kind: literal("grantIdcAccountAssignment"),
|
|
797
813
|
accountName: string(),
|
|
@@ -806,6 +822,92 @@ var revokeIdcAccountAssignmentOperationSchema = strictObject({
|
|
|
806
822
|
principalType: picklist(["GROUP", "USER"]),
|
|
807
823
|
principalName: string()
|
|
808
824
|
});
|
|
825
|
+
var setIdcAccessControlAttributesOperationSchema = strictObject({
|
|
826
|
+
kind: literal("setIdcAccessControlAttributes"),
|
|
827
|
+
attributes: array(
|
|
828
|
+
strictObject({
|
|
829
|
+
key: string(),
|
|
830
|
+
source: array(string())
|
|
831
|
+
})
|
|
832
|
+
)
|
|
833
|
+
});
|
|
834
|
+
var alternateContactTypeSchema = picklist([
|
|
835
|
+
"BILLING",
|
|
836
|
+
"OPERATIONS",
|
|
837
|
+
"SECURITY"
|
|
838
|
+
]);
|
|
839
|
+
var putAlternateContactOperationSchema = strictObject({
|
|
840
|
+
kind: literal("putAlternateContact"),
|
|
841
|
+
accountId: string(),
|
|
842
|
+
accountName: string(),
|
|
843
|
+
contactType: alternateContactTypeSchema,
|
|
844
|
+
name: string(),
|
|
845
|
+
email: string(),
|
|
846
|
+
phone: string(),
|
|
847
|
+
title: optional(string())
|
|
848
|
+
});
|
|
849
|
+
var deleteAlternateContactOperationSchema = strictObject({
|
|
850
|
+
kind: literal("deleteAlternateContact"),
|
|
851
|
+
accountId: string(),
|
|
852
|
+
accountName: string(),
|
|
853
|
+
contactType: alternateContactTypeSchema
|
|
854
|
+
});
|
|
855
|
+
var registerDelegatedAdministratorOperationSchema = strictObject({
|
|
856
|
+
kind: literal("registerDelegatedAdministrator"),
|
|
857
|
+
accountId: string(),
|
|
858
|
+
accountName: string(),
|
|
859
|
+
servicePrincipal: string()
|
|
860
|
+
});
|
|
861
|
+
var deregisterDelegatedAdministratorOperationSchema = strictObject({
|
|
862
|
+
kind: literal("deregisterDelegatedAdministrator"),
|
|
863
|
+
accountId: string(),
|
|
864
|
+
accountName: string(),
|
|
865
|
+
servicePrincipal: string()
|
|
866
|
+
});
|
|
867
|
+
var createOrgPolicyOperationSchema = strictObject({
|
|
868
|
+
kind: literal("createOrgPolicy"),
|
|
869
|
+
policyName: string(),
|
|
870
|
+
policyType: picklist([
|
|
871
|
+
"SERVICE_CONTROL_POLICY",
|
|
872
|
+
"RESOURCE_CONTROL_POLICY",
|
|
873
|
+
"TAG_POLICY",
|
|
874
|
+
"AISERVICES_OPT_OUT_POLICY",
|
|
875
|
+
"BACKUP_POLICY"
|
|
876
|
+
]),
|
|
877
|
+
description: string(),
|
|
878
|
+
content: string()
|
|
879
|
+
});
|
|
880
|
+
var updateOrgPolicyContentOperationSchema = strictObject({
|
|
881
|
+
kind: literal("updateOrgPolicyContent"),
|
|
882
|
+
policyId: string(),
|
|
883
|
+
policyName: string(),
|
|
884
|
+
content: string()
|
|
885
|
+
});
|
|
886
|
+
var updateOrgPolicyDescriptionOperationSchema = strictObject({
|
|
887
|
+
kind: literal("updateOrgPolicyDescription"),
|
|
888
|
+
policyId: string(),
|
|
889
|
+
policyName: string(),
|
|
890
|
+
description: string()
|
|
891
|
+
});
|
|
892
|
+
var attachOrgPolicyOperationSchema = strictObject({
|
|
893
|
+
kind: literal("attachOrgPolicy"),
|
|
894
|
+
policyId: string(),
|
|
895
|
+
policyName: string(),
|
|
896
|
+
targetId: string(),
|
|
897
|
+
targetName: string()
|
|
898
|
+
});
|
|
899
|
+
var detachOrgPolicyOperationSchema = strictObject({
|
|
900
|
+
kind: literal("detachOrgPolicy"),
|
|
901
|
+
policyId: string(),
|
|
902
|
+
policyName: string(),
|
|
903
|
+
targetId: string(),
|
|
904
|
+
targetName: string()
|
|
905
|
+
});
|
|
906
|
+
var deleteOrgPolicyOperationSchema = strictObject({
|
|
907
|
+
kind: literal("deleteOrgPolicy"),
|
|
908
|
+
policyId: string(),
|
|
909
|
+
policyName: string()
|
|
910
|
+
});
|
|
809
911
|
var operationSchema = variant("kind", [
|
|
810
912
|
moveAccountOperationSchema,
|
|
811
913
|
createOuOperationSchema,
|
|
@@ -834,8 +936,21 @@ var operationSchema = variant("kind", [
|
|
|
834
936
|
attachIdcCustomerManagedPolicyReferenceToPermissionSetOperationSchema,
|
|
835
937
|
detachIdcCustomerManagedPolicyReferenceFromPermissionSetOperationSchema,
|
|
836
938
|
provisionIdcPermissionSetOperationSchema,
|
|
939
|
+
putIdcPermissionSetPermissionsBoundaryOperationSchema,
|
|
940
|
+
deleteIdcPermissionSetPermissionsBoundaryOperationSchema,
|
|
837
941
|
grantIdcAccountAssignmentOperationSchema,
|
|
838
|
-
revokeIdcAccountAssignmentOperationSchema
|
|
942
|
+
revokeIdcAccountAssignmentOperationSchema,
|
|
943
|
+
createOrgPolicyOperationSchema,
|
|
944
|
+
updateOrgPolicyContentOperationSchema,
|
|
945
|
+
updateOrgPolicyDescriptionOperationSchema,
|
|
946
|
+
attachOrgPolicyOperationSchema,
|
|
947
|
+
detachOrgPolicyOperationSchema,
|
|
948
|
+
deleteOrgPolicyOperationSchema,
|
|
949
|
+
putAlternateContactOperationSchema,
|
|
950
|
+
deleteAlternateContactOperationSchema,
|
|
951
|
+
setIdcAccessControlAttributesOperationSchema,
|
|
952
|
+
registerDelegatedAdministratorOperationSchema,
|
|
953
|
+
deregisterDelegatedAdministratorOperationSchema
|
|
839
954
|
]);
|
|
840
955
|
var unsupportedDiffKindSchema = picklist([
|
|
841
956
|
"ambiguousOuRename",
|
|
@@ -885,10 +1000,37 @@ var organizationalUnitSchema = strictObject({
|
|
|
885
1000
|
arn: nonEmptyString,
|
|
886
1001
|
name: nonEmptyString
|
|
887
1002
|
});
|
|
1003
|
+
var orgPolicyTypeSchema = picklist([
|
|
1004
|
+
"SERVICE_CONTROL_POLICY",
|
|
1005
|
+
"RESOURCE_CONTROL_POLICY",
|
|
1006
|
+
"TAG_POLICY",
|
|
1007
|
+
"AISERVICES_OPT_OUT_POLICY",
|
|
1008
|
+
"BACKUP_POLICY"
|
|
1009
|
+
]);
|
|
1010
|
+
var orgPolicySchema = strictObject({
|
|
1011
|
+
id: nonEmptyString,
|
|
1012
|
+
arn: nonEmptyString,
|
|
1013
|
+
name: nonEmptyString,
|
|
1014
|
+
description: string(),
|
|
1015
|
+
type: orgPolicyTypeSchema,
|
|
1016
|
+
content: nonEmptyString
|
|
1017
|
+
});
|
|
1018
|
+
var orgPolicyAttachmentSchema = strictObject({
|
|
1019
|
+
policyId: nonEmptyString,
|
|
1020
|
+
targetId: nonEmptyString,
|
|
1021
|
+
targetType: picklist(["ROOT", "ORGANIZATIONAL_UNIT", "ACCOUNT"])
|
|
1022
|
+
});
|
|
888
1023
|
var accountTagSchema = strictObject({
|
|
889
1024
|
key: nonEmptyString,
|
|
890
1025
|
value: string()
|
|
891
1026
|
});
|
|
1027
|
+
var alternateContactSchema = strictObject({
|
|
1028
|
+
contactType: picklist(["BILLING", "OPERATIONS", "SECURITY"]),
|
|
1029
|
+
name: string(),
|
|
1030
|
+
email: string(),
|
|
1031
|
+
phone: string(),
|
|
1032
|
+
title: optional(string())
|
|
1033
|
+
});
|
|
892
1034
|
var accountSchema = strictObject({
|
|
893
1035
|
id: nonEmptyString,
|
|
894
1036
|
arn: nonEmptyString,
|
|
@@ -896,7 +1038,8 @@ var accountSchema = strictObject({
|
|
|
896
1038
|
email: nonEmptyString,
|
|
897
1039
|
status: nonEmptyString,
|
|
898
1040
|
parentId: nonEmptyString,
|
|
899
|
-
tags: array(accountTagSchema)
|
|
1041
|
+
tags: array(accountTagSchema),
|
|
1042
|
+
alternateContacts: optional(array(alternateContactSchema))
|
|
900
1043
|
});
|
|
901
1044
|
var userSchema = strictObject({
|
|
902
1045
|
userId: nonEmptyString,
|
|
@@ -918,6 +1061,13 @@ var customerManagedPolicyReferenceSchema = strictObject({
|
|
|
918
1061
|
name: nonEmptyString,
|
|
919
1062
|
path: nonEmptyString
|
|
920
1063
|
});
|
|
1064
|
+
var permissionsBoundarySchema = union([
|
|
1065
|
+
strictObject({ managedPolicyArn: nonEmptyString }),
|
|
1066
|
+
strictObject({
|
|
1067
|
+
customerManagedPolicyName: nonEmptyString,
|
|
1068
|
+
customerManagedPolicyPath: nonEmptyString
|
|
1069
|
+
})
|
|
1070
|
+
]);
|
|
921
1071
|
var permissionSetSchema = strictObject({
|
|
922
1072
|
permissionSetArn: nonEmptyString,
|
|
923
1073
|
name: nonEmptyString,
|
|
@@ -925,7 +1075,8 @@ var permissionSetSchema = strictObject({
|
|
|
925
1075
|
sessionDuration: nullable(string()),
|
|
926
1076
|
inlinePolicy: nullable(nonEmptyString),
|
|
927
1077
|
awsManagedPolicies: array(nonEmptyString),
|
|
928
|
-
customerManagedPolicies: array(customerManagedPolicyReferenceSchema)
|
|
1078
|
+
customerManagedPolicies: array(customerManagedPolicyReferenceSchema),
|
|
1079
|
+
permissionsBoundary: nullable(permissionsBoundarySchema)
|
|
929
1080
|
});
|
|
930
1081
|
var accountAssignmentSchema = strictObject({
|
|
931
1082
|
accountId: nonEmptyString,
|
|
@@ -940,13 +1091,24 @@ var accessRoleSchema = strictObject({
|
|
|
940
1091
|
principalType: principalTypeSchema,
|
|
941
1092
|
roleName: nonEmptyString
|
|
942
1093
|
});
|
|
1094
|
+
var accessControlAttributeSchema = strictObject({
|
|
1095
|
+
key: nonEmptyString,
|
|
1096
|
+
source: array(nonEmptyString)
|
|
1097
|
+
});
|
|
1098
|
+
var delegatedAdministratorSchema = strictObject({
|
|
1099
|
+
accountId: nonEmptyString,
|
|
1100
|
+
servicePrincipal: nonEmptyString
|
|
1101
|
+
});
|
|
943
1102
|
var stateSchema = strictObject({
|
|
944
1103
|
version: nonEmptyString,
|
|
945
1104
|
generatedAt: nonEmptyString,
|
|
946
1105
|
organization: strictObject({
|
|
947
1106
|
rootId: nonEmptyString,
|
|
948
1107
|
organizationalUnits: array(organizationalUnitSchema),
|
|
949
|
-
accounts: array(accountSchema)
|
|
1108
|
+
accounts: array(accountSchema),
|
|
1109
|
+
policies: optional(array(orgPolicySchema)),
|
|
1110
|
+
policyAttachments: optional(array(orgPolicyAttachmentSchema)),
|
|
1111
|
+
delegatedAdministrators: optional(array(delegatedAdministratorSchema))
|
|
950
1112
|
}),
|
|
951
1113
|
identityCenter: strictObject({
|
|
952
1114
|
instanceArn: nonEmptyString,
|
|
@@ -956,10 +1118,14 @@ var stateSchema = strictObject({
|
|
|
956
1118
|
groupMemberships: array(groupMembershipSchema),
|
|
957
1119
|
permissionSets: array(permissionSetSchema),
|
|
958
1120
|
accountAssignments: array(accountAssignmentSchema),
|
|
959
|
-
accessRoles: array(accessRoleSchema)
|
|
1121
|
+
accessRoles: array(accessRoleSchema),
|
|
1122
|
+
accessControlAttributes: array(accessControlAttributeSchema)
|
|
960
1123
|
})
|
|
961
1124
|
});
|
|
962
1125
|
function createWorkingState(props) {
|
|
1126
|
+
const policies = props.state.organization.policies ?? [];
|
|
1127
|
+
const policyAttachments = props.state.organization.policyAttachments ?? [];
|
|
1128
|
+
const delegatedAdministrators = props.state.organization.delegatedAdministrators ?? [];
|
|
963
1129
|
return {
|
|
964
1130
|
version: props.state.version,
|
|
965
1131
|
generatedAt: props.state.generatedAt,
|
|
@@ -973,6 +1139,18 @@ function createWorkingState(props) {
|
|
|
973
1139
|
accountsByName: toRecordByProperty(
|
|
974
1140
|
props.state.organization.accounts,
|
|
975
1141
|
"name"
|
|
1142
|
+
),
|
|
1143
|
+
policiesById: toRecordByProperty(policies, "id"),
|
|
1144
|
+
policiesByName: toRecordByProperty(policies, "name"),
|
|
1145
|
+
policyAttachments: structuredClone(policyAttachments),
|
|
1146
|
+
policyAttachmentsByKey: toRecordByProperty(
|
|
1147
|
+
policyAttachments,
|
|
1148
|
+
createOrgPolicyAttachmentKey
|
|
1149
|
+
),
|
|
1150
|
+
delegatedAdministrators: structuredClone(delegatedAdministrators),
|
|
1151
|
+
delegatedAdministratorsByKey: toRecordByProperty(
|
|
1152
|
+
delegatedAdministrators,
|
|
1153
|
+
createDelegatedAdministratorKey
|
|
976
1154
|
)
|
|
977
1155
|
},
|
|
978
1156
|
identityCenter: createWorkingIdentityCenterState({
|
|
@@ -989,7 +1167,16 @@ function materializeWorkingState(props) {
|
|
|
989
1167
|
organizationalUnits: Object.values(
|
|
990
1168
|
props.workingState.organization.organizationalUnitsById
|
|
991
1169
|
),
|
|
992
|
-
accounts: Object.values(props.workingState.organization.accountsById)
|
|
1170
|
+
accounts: Object.values(props.workingState.organization.accountsById),
|
|
1171
|
+
policies: Object.values(props.workingState.organization.policiesById),
|
|
1172
|
+
policyAttachments: structuredClone(
|
|
1173
|
+
props.workingState.organization.policyAttachments
|
|
1174
|
+
),
|
|
1175
|
+
...props.workingState.organization.delegatedAdministrators.length > 0 ? {
|
|
1176
|
+
delegatedAdministrators: structuredClone(
|
|
1177
|
+
props.workingState.organization.delegatedAdministrators
|
|
1178
|
+
)
|
|
1179
|
+
} : {}
|
|
993
1180
|
},
|
|
994
1181
|
identityCenter: {
|
|
995
1182
|
instanceArn: props.workingState.identityCenter.instanceArn,
|
|
@@ -1007,6 +1194,9 @@ function materializeWorkingState(props) {
|
|
|
1007
1194
|
),
|
|
1008
1195
|
accessRoles: structuredClone(
|
|
1009
1196
|
props.workingState.identityCenter.accessRoles
|
|
1197
|
+
),
|
|
1198
|
+
accessControlAttributes: structuredClone(
|
|
1199
|
+
props.workingState.identityCenter.accessControlAttributes
|
|
1010
1200
|
)
|
|
1011
1201
|
}
|
|
1012
1202
|
};
|
|
@@ -1219,7 +1409,7 @@ function removeIdcGroupFromWorkingState(props) {
|
|
|
1219
1409
|
}
|
|
1220
1410
|
function upsertIdcPermissionSetInWorkingState(props) {
|
|
1221
1411
|
const currentPermissionSet = props.workingState.identityCenter.permissionSetsByName[props.permissionSet.name];
|
|
1222
|
-
if (currentPermissionSet != null && currentPermissionSet.permissionSetArn === props.permissionSet.permissionSetArn && currentPermissionSet.name === props.permissionSet.name && currentPermissionSet.description === props.permissionSet.description && currentPermissionSet.sessionDuration === props.permissionSet.sessionDuration && currentPermissionSet.inlinePolicy === props.permissionSet.inlinePolicy && JSON.stringify(currentPermissionSet.awsManagedPolicies) === JSON.stringify(props.permissionSet.awsManagedPolicies) && JSON.stringify(currentPermissionSet.customerManagedPolicies) === JSON.stringify(props.permissionSet.customerManagedPolicies)) {
|
|
1412
|
+
if (currentPermissionSet != null && currentPermissionSet.permissionSetArn === props.permissionSet.permissionSetArn && currentPermissionSet.name === props.permissionSet.name && currentPermissionSet.description === props.permissionSet.description && currentPermissionSet.sessionDuration === props.permissionSet.sessionDuration && currentPermissionSet.inlinePolicy === props.permissionSet.inlinePolicy && JSON.stringify(currentPermissionSet.awsManagedPolicies) === JSON.stringify(props.permissionSet.awsManagedPolicies) && JSON.stringify(currentPermissionSet.customerManagedPolicies) === JSON.stringify(props.permissionSet.customerManagedPolicies) && JSON.stringify(currentPermissionSet.permissionsBoundary) === JSON.stringify(props.permissionSet.permissionsBoundary)) {
|
|
1223
1413
|
return props.workingState;
|
|
1224
1414
|
}
|
|
1225
1415
|
const remainingPermissionSets = props.workingState.identityCenter.permissionSets.filter(
|
|
@@ -1361,6 +1551,154 @@ function removeAccountAssignmentFromWorkingState(props) {
|
|
|
1361
1551
|
})
|
|
1362
1552
|
};
|
|
1363
1553
|
}
|
|
1554
|
+
function createOrgPolicyAttachmentKey(props) {
|
|
1555
|
+
return [props.policyId, props.targetId].join("|");
|
|
1556
|
+
}
|
|
1557
|
+
function upsertOrgPolicyInWorkingState(props) {
|
|
1558
|
+
const currentPolicy = props.workingState.organization.policiesById[props.policy.id];
|
|
1559
|
+
if (currentPolicy != null && currentPolicy.id === props.policy.id && currentPolicy.arn === props.policy.arn && currentPolicy.name === props.policy.name && currentPolicy.description === props.policy.description && currentPolicy.type === props.policy.type && currentPolicy.content === props.policy.content) {
|
|
1560
|
+
return props.workingState;
|
|
1561
|
+
}
|
|
1562
|
+
const remainingPolicies = Object.values(
|
|
1563
|
+
props.workingState.organization.policiesById
|
|
1564
|
+
).filter((p) => p.id !== props.policy.id);
|
|
1565
|
+
const nextPolicies = [...remainingPolicies, props.policy];
|
|
1566
|
+
return {
|
|
1567
|
+
...props.workingState,
|
|
1568
|
+
organization: {
|
|
1569
|
+
...props.workingState.organization,
|
|
1570
|
+
policiesById: toRecordByProperty(nextPolicies, "id"),
|
|
1571
|
+
policiesByName: toRecordByProperty(nextPolicies, "name")
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
function removeOrgPolicyFromWorkingState(props) {
|
|
1576
|
+
if (props.workingState.organization.policiesById[props.policyId] == null) {
|
|
1577
|
+
return props.workingState;
|
|
1578
|
+
}
|
|
1579
|
+
const nextPolicies = Object.values(
|
|
1580
|
+
props.workingState.organization.policiesById
|
|
1581
|
+
).filter((p) => p.id !== props.policyId);
|
|
1582
|
+
const nextAttachments = props.workingState.organization.policyAttachments.filter(
|
|
1583
|
+
(a) => a.policyId !== props.policyId
|
|
1584
|
+
);
|
|
1585
|
+
return {
|
|
1586
|
+
...props.workingState,
|
|
1587
|
+
organization: {
|
|
1588
|
+
...props.workingState.organization,
|
|
1589
|
+
policiesById: toRecordByProperty(nextPolicies, "id"),
|
|
1590
|
+
policiesByName: toRecordByProperty(nextPolicies, "name"),
|
|
1591
|
+
policyAttachments: nextAttachments,
|
|
1592
|
+
policyAttachmentsByKey: toRecordByProperty(
|
|
1593
|
+
nextAttachments,
|
|
1594
|
+
createOrgPolicyAttachmentKey
|
|
1595
|
+
)
|
|
1596
|
+
}
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
function addOrgPolicyAttachmentToWorkingState(props) {
|
|
1600
|
+
const key = createOrgPolicyAttachmentKey({
|
|
1601
|
+
policyId: props.attachment.policyId,
|
|
1602
|
+
targetId: props.attachment.targetId
|
|
1603
|
+
});
|
|
1604
|
+
if (props.workingState.organization.policyAttachmentsByKey[key] != null) {
|
|
1605
|
+
return props.workingState;
|
|
1606
|
+
}
|
|
1607
|
+
const nextAttachments = [
|
|
1608
|
+
...props.workingState.organization.policyAttachments,
|
|
1609
|
+
props.attachment
|
|
1610
|
+
];
|
|
1611
|
+
return {
|
|
1612
|
+
...props.workingState,
|
|
1613
|
+
organization: {
|
|
1614
|
+
...props.workingState.organization,
|
|
1615
|
+
policyAttachments: nextAttachments,
|
|
1616
|
+
policyAttachmentsByKey: toRecordByProperty(
|
|
1617
|
+
nextAttachments,
|
|
1618
|
+
createOrgPolicyAttachmentKey
|
|
1619
|
+
)
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
function removeOrgPolicyAttachmentFromWorkingState(props) {
|
|
1624
|
+
const key = createOrgPolicyAttachmentKey({
|
|
1625
|
+
policyId: props.policyId,
|
|
1626
|
+
targetId: props.targetId
|
|
1627
|
+
});
|
|
1628
|
+
if (props.workingState.organization.policyAttachmentsByKey[key] == null) {
|
|
1629
|
+
return props.workingState;
|
|
1630
|
+
}
|
|
1631
|
+
const nextAttachments = props.workingState.organization.policyAttachments.filter(
|
|
1632
|
+
(a) => createOrgPolicyAttachmentKey({
|
|
1633
|
+
policyId: a.policyId,
|
|
1634
|
+
targetId: a.targetId
|
|
1635
|
+
}) !== key
|
|
1636
|
+
);
|
|
1637
|
+
return {
|
|
1638
|
+
...props.workingState,
|
|
1639
|
+
organization: {
|
|
1640
|
+
...props.workingState.organization,
|
|
1641
|
+
policyAttachments: nextAttachments,
|
|
1642
|
+
policyAttachmentsByKey: toRecordByProperty(
|
|
1643
|
+
nextAttachments,
|
|
1644
|
+
createOrgPolicyAttachmentKey
|
|
1645
|
+
)
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
function createDelegatedAdministratorKey(props) {
|
|
1650
|
+
return [props.accountId, props.servicePrincipal].join("|");
|
|
1651
|
+
}
|
|
1652
|
+
function upsertDelegatedAdministratorInWorkingState(props) {
|
|
1653
|
+
const key = createDelegatedAdministratorKey({
|
|
1654
|
+
accountId: props.delegatedAdministrator.accountId,
|
|
1655
|
+
servicePrincipal: props.delegatedAdministrator.servicePrincipal
|
|
1656
|
+
});
|
|
1657
|
+
if (props.workingState.organization.delegatedAdministratorsByKey[key] != null) {
|
|
1658
|
+
return props.workingState;
|
|
1659
|
+
}
|
|
1660
|
+
const nextDelegatedAdministrators = [
|
|
1661
|
+
...props.workingState.organization.delegatedAdministrators,
|
|
1662
|
+
props.delegatedAdministrator
|
|
1663
|
+
];
|
|
1664
|
+
return {
|
|
1665
|
+
...props.workingState,
|
|
1666
|
+
organization: {
|
|
1667
|
+
...props.workingState.organization,
|
|
1668
|
+
delegatedAdministrators: nextDelegatedAdministrators,
|
|
1669
|
+
delegatedAdministratorsByKey: toRecordByProperty(
|
|
1670
|
+
nextDelegatedAdministrators,
|
|
1671
|
+
createDelegatedAdministratorKey
|
|
1672
|
+
)
|
|
1673
|
+
}
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
function removeDelegatedAdministratorFromWorkingState(props) {
|
|
1677
|
+
const key = createDelegatedAdministratorKey({
|
|
1678
|
+
accountId: props.accountId,
|
|
1679
|
+
servicePrincipal: props.servicePrincipal
|
|
1680
|
+
});
|
|
1681
|
+
if (props.workingState.organization.delegatedAdministratorsByKey[key] == null) {
|
|
1682
|
+
return props.workingState;
|
|
1683
|
+
}
|
|
1684
|
+
const nextDelegatedAdministrators = props.workingState.organization.delegatedAdministrators.filter(
|
|
1685
|
+
(da) => createDelegatedAdministratorKey({
|
|
1686
|
+
accountId: da.accountId,
|
|
1687
|
+
servicePrincipal: da.servicePrincipal
|
|
1688
|
+
}) !== key
|
|
1689
|
+
);
|
|
1690
|
+
return {
|
|
1691
|
+
...props.workingState,
|
|
1692
|
+
organization: {
|
|
1693
|
+
...props.workingState.organization,
|
|
1694
|
+
delegatedAdministrators: nextDelegatedAdministrators,
|
|
1695
|
+
delegatedAdministratorsByKey: toRecordByProperty(
|
|
1696
|
+
nextDelegatedAdministrators,
|
|
1697
|
+
createDelegatedAdministratorKey
|
|
1698
|
+
)
|
|
1699
|
+
}
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1364
1702
|
function createAccessRoleName(assignment) {
|
|
1365
1703
|
return `AWSReservedSSO_${assignment.permissionSetArn.split("/").at(-1) ?? "PermissionSet"}_${assignment.accountId}`;
|
|
1366
1704
|
}
|
|
@@ -1395,7 +1733,10 @@ function createWorkingIdentityCenterState(props) {
|
|
|
1395
1733
|
),
|
|
1396
1734
|
accessRoles: createAccessRoles({
|
|
1397
1735
|
accountAssignments
|
|
1398
|
-
})
|
|
1736
|
+
}),
|
|
1737
|
+
accessControlAttributes: structuredClone(
|
|
1738
|
+
props.identityCenter.accessControlAttributes ?? []
|
|
1739
|
+
)
|
|
1399
1740
|
};
|
|
1400
1741
|
}
|
|
1401
1742
|
function materializeWorkingIdentityCenterState(props) {
|
|
@@ -1409,7 +1750,10 @@ function materializeWorkingIdentityCenterState(props) {
|
|
|
1409
1750
|
accountAssignments: structuredClone(
|
|
1410
1751
|
props.identityCenter.accountAssignments
|
|
1411
1752
|
),
|
|
1412
|
-
accessRoles: structuredClone(props.identityCenter.accessRoles)
|
|
1753
|
+
accessRoles: structuredClone(props.identityCenter.accessRoles),
|
|
1754
|
+
accessControlAttributes: structuredClone(
|
|
1755
|
+
props.identityCenter.accessControlAttributes
|
|
1756
|
+
)
|
|
1413
1757
|
};
|
|
1414
1758
|
}
|
|
1415
1759
|
function createAccessRoles(props) {
|
|
@@ -1448,28 +1792,43 @@ import {
|
|
|
1448
1792
|
ListUsersCommand
|
|
1449
1793
|
} from "@aws-sdk/client-identitystore";
|
|
1450
1794
|
import {
|
|
1795
|
+
DescribeOrganizationCommand,
|
|
1796
|
+
DescribePolicyCommand,
|
|
1451
1797
|
ListAccountsCommand,
|
|
1798
|
+
ListDelegatedAdministratorsCommand,
|
|
1799
|
+
ListDelegatedServicesForAccountCommand,
|
|
1452
1800
|
ListOrganizationalUnitsForParentCommand,
|
|
1453
1801
|
ListParentsCommand,
|
|
1802
|
+
ListPoliciesCommand,
|
|
1454
1803
|
ListRootsCommand,
|
|
1455
|
-
ListTagsForResourceCommand
|
|
1804
|
+
ListTagsForResourceCommand,
|
|
1805
|
+
ListTargetsForPolicyCommand
|
|
1456
1806
|
} from "@aws-sdk/client-organizations";
|
|
1457
1807
|
import {
|
|
1458
1808
|
DescribePermissionSetCommand,
|
|
1459
1809
|
GetInlinePolicyForPermissionSetCommand,
|
|
1810
|
+
GetPermissionsBoundaryForPermissionSetCommand,
|
|
1460
1811
|
ListAccountAssignmentsCommand,
|
|
1461
1812
|
ListAccountsForProvisionedPermissionSetCommand,
|
|
1462
1813
|
ListCustomerManagedPolicyReferencesInPermissionSetCommand,
|
|
1814
|
+
DescribeInstanceAccessControlAttributeConfigurationCommand,
|
|
1463
1815
|
ListInstancesCommand,
|
|
1464
1816
|
ListManagedPoliciesInPermissionSetCommand,
|
|
1465
1817
|
ListPermissionSetsCommand
|
|
1466
1818
|
} from "@aws-sdk/client-sso-admin";
|
|
1819
|
+
import {
|
|
1820
|
+
GetAlternateContactCommand
|
|
1821
|
+
} from "@aws-sdk/client-account";
|
|
1467
1822
|
async function scanOrganization(props) {
|
|
1468
|
-
const
|
|
1469
|
-
|
|
1823
|
+
const [rootsResponse, orgResponse] = await Promise.all([
|
|
1824
|
+
props.organizationsClient.send(new ListRootsCommand({})),
|
|
1825
|
+
props.organizationsClient.send(new DescribeOrganizationCommand({}))
|
|
1826
|
+
]);
|
|
1827
|
+
const root = rootsResponse.Roots?.[0];
|
|
1470
1828
|
if (root?.Id == null) {
|
|
1471
1829
|
throw new Error("No organization root found.");
|
|
1472
1830
|
}
|
|
1831
|
+
const managementAccountId = orgResponse.Organization?.MasterAccountId;
|
|
1473
1832
|
const organizationalUnits = await collectOrganizationalUnits({
|
|
1474
1833
|
organizationsClient: props.organizationsClient,
|
|
1475
1834
|
parentId: root.Id
|
|
@@ -1493,6 +1852,11 @@ async function scanOrganization(props) {
|
|
|
1493
1852
|
ResourceId: account.Id
|
|
1494
1853
|
})
|
|
1495
1854
|
);
|
|
1855
|
+
const alternateContacts = await scanAlternateContacts({
|
|
1856
|
+
accountClient: props.accountClient,
|
|
1857
|
+
accountId: account.Id,
|
|
1858
|
+
isManagementAccount: account.Id === managementAccountId
|
|
1859
|
+
});
|
|
1496
1860
|
accounts.push({
|
|
1497
1861
|
id: account.Id,
|
|
1498
1862
|
arn: account.Arn,
|
|
@@ -1510,17 +1874,138 @@ async function scanOrganization(props) {
|
|
|
1510
1874
|
value: tag.Value ?? ""
|
|
1511
1875
|
}
|
|
1512
1876
|
];
|
|
1513
|
-
})
|
|
1877
|
+
}),
|
|
1878
|
+
alternateContacts: alternateContacts.length > 0 ? alternateContacts : void 0
|
|
1514
1879
|
});
|
|
1515
1880
|
}
|
|
1516
1881
|
nextToken = response.NextToken;
|
|
1517
1882
|
} while (nextToken != null);
|
|
1883
|
+
const [{ policies, policyAttachments }, delegatedAdministrators] = await Promise.all([
|
|
1884
|
+
scanOrganizationPolicies({
|
|
1885
|
+
organizationsClient: props.organizationsClient
|
|
1886
|
+
}),
|
|
1887
|
+
scanDelegatedAdministrators({
|
|
1888
|
+
organizationsClient: props.organizationsClient
|
|
1889
|
+
})
|
|
1890
|
+
]);
|
|
1518
1891
|
return {
|
|
1519
1892
|
rootId: root.Id,
|
|
1520
1893
|
organizationalUnits,
|
|
1521
|
-
accounts
|
|
1894
|
+
accounts,
|
|
1895
|
+
policies,
|
|
1896
|
+
policyAttachments,
|
|
1897
|
+
delegatedAdministrators: delegatedAdministrators.length > 0 ? delegatedAdministrators : void 0
|
|
1522
1898
|
};
|
|
1523
1899
|
}
|
|
1900
|
+
async function scanDelegatedAdministrators(props) {
|
|
1901
|
+
const accountIds = new Array();
|
|
1902
|
+
let nextToken;
|
|
1903
|
+
do {
|
|
1904
|
+
const response = await props.organizationsClient.send(
|
|
1905
|
+
new ListDelegatedAdministratorsCommand({ NextToken: nextToken })
|
|
1906
|
+
);
|
|
1907
|
+
for (const admin of response.DelegatedAdministrators ?? []) {
|
|
1908
|
+
if (admin.Id == null) {
|
|
1909
|
+
continue;
|
|
1910
|
+
}
|
|
1911
|
+
accountIds.push(admin.Id);
|
|
1912
|
+
}
|
|
1913
|
+
nextToken = response.NextToken;
|
|
1914
|
+
} while (nextToken != null);
|
|
1915
|
+
const results = [];
|
|
1916
|
+
for (const accountId of accountIds) {
|
|
1917
|
+
let servicesNextToken;
|
|
1918
|
+
do {
|
|
1919
|
+
const response = await props.organizationsClient.send(
|
|
1920
|
+
new ListDelegatedServicesForAccountCommand({
|
|
1921
|
+
AccountId: accountId,
|
|
1922
|
+
NextToken: servicesNextToken
|
|
1923
|
+
})
|
|
1924
|
+
);
|
|
1925
|
+
for (const service of response.DelegatedServices ?? []) {
|
|
1926
|
+
if (service.ServicePrincipal == null) {
|
|
1927
|
+
continue;
|
|
1928
|
+
}
|
|
1929
|
+
results.push({ accountId, servicePrincipal: service.ServicePrincipal });
|
|
1930
|
+
}
|
|
1931
|
+
servicesNextToken = response.NextToken;
|
|
1932
|
+
} while (servicesNextToken != null);
|
|
1933
|
+
}
|
|
1934
|
+
return results;
|
|
1935
|
+
}
|
|
1936
|
+
var ORG_POLICY_TYPES = [
|
|
1937
|
+
"SERVICE_CONTROL_POLICY",
|
|
1938
|
+
"RESOURCE_CONTROL_POLICY",
|
|
1939
|
+
"TAG_POLICY",
|
|
1940
|
+
"AISERVICES_OPT_OUT_POLICY",
|
|
1941
|
+
"BACKUP_POLICY"
|
|
1942
|
+
];
|
|
1943
|
+
async function scanOrganizationPolicies(props) {
|
|
1944
|
+
const policies = [];
|
|
1945
|
+
const policyAttachments = [];
|
|
1946
|
+
for (const policyType of ORG_POLICY_TYPES) {
|
|
1947
|
+
let nextToken;
|
|
1948
|
+
const policyIds = [];
|
|
1949
|
+
do {
|
|
1950
|
+
const response = await props.organizationsClient.send(
|
|
1951
|
+
new ListPoliciesCommand({ Filter: policyType, NextToken: nextToken })
|
|
1952
|
+
);
|
|
1953
|
+
for (const summary of response.Policies ?? []) {
|
|
1954
|
+
if (summary.Id == null || summary.AwsManaged === true) {
|
|
1955
|
+
continue;
|
|
1956
|
+
}
|
|
1957
|
+
policyIds.push(summary.Id);
|
|
1958
|
+
}
|
|
1959
|
+
nextToken = response.NextToken;
|
|
1960
|
+
} while (nextToken != null);
|
|
1961
|
+
for (const policyId of policyIds) {
|
|
1962
|
+
const describeResponse = await props.organizationsClient.send(
|
|
1963
|
+
new DescribePolicyCommand({ PolicyId: policyId })
|
|
1964
|
+
);
|
|
1965
|
+
const policy = describeResponse.Policy;
|
|
1966
|
+
if (policy?.PolicySummary?.Id == null || policy.PolicySummary.Arn == null || policy.PolicySummary.Name == null) {
|
|
1967
|
+
continue;
|
|
1968
|
+
}
|
|
1969
|
+
const content = policy.Content;
|
|
1970
|
+
if (content == null || content.length === 0) {
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
policies.push({
|
|
1974
|
+
id: policy.PolicySummary.Id,
|
|
1975
|
+
arn: policy.PolicySummary.Arn,
|
|
1976
|
+
name: policy.PolicySummary.Name,
|
|
1977
|
+
description: policy.PolicySummary.Description ?? "",
|
|
1978
|
+
type: policyType,
|
|
1979
|
+
content
|
|
1980
|
+
});
|
|
1981
|
+
let targetsNextToken;
|
|
1982
|
+
do {
|
|
1983
|
+
const targetsResponse = await props.organizationsClient.send(
|
|
1984
|
+
new ListTargetsForPolicyCommand({
|
|
1985
|
+
PolicyId: policyId,
|
|
1986
|
+
NextToken: targetsNextToken
|
|
1987
|
+
})
|
|
1988
|
+
);
|
|
1989
|
+
for (const target of targetsResponse.Targets ?? []) {
|
|
1990
|
+
if (target.TargetId == null || target.Type == null) {
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1993
|
+
const targetType = target.Type;
|
|
1994
|
+
if (targetType !== "ROOT" && targetType !== "ORGANIZATIONAL_UNIT" && targetType !== "ACCOUNT") {
|
|
1995
|
+
continue;
|
|
1996
|
+
}
|
|
1997
|
+
policyAttachments.push({
|
|
1998
|
+
policyId,
|
|
1999
|
+
targetId: target.TargetId,
|
|
2000
|
+
targetType
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
targetsNextToken = targetsResponse.NextToken;
|
|
2004
|
+
} while (targetsNextToken != null);
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
return { policies, policyAttachments };
|
|
2008
|
+
}
|
|
1524
2009
|
async function collectOrganizationalUnits(props) {
|
|
1525
2010
|
const children = [];
|
|
1526
2011
|
let nextToken;
|
|
@@ -1563,7 +2048,7 @@ async function scanIdentityCenter(props) {
|
|
|
1563
2048
|
instances,
|
|
1564
2049
|
requestedInstanceArn: props.requestedInstanceArn
|
|
1565
2050
|
});
|
|
1566
|
-
const [users, groups, permissionSets] = await Promise.all([
|
|
2051
|
+
const [users, groups, permissionSets, accessControlAttributes] = await Promise.all([
|
|
1567
2052
|
listIdentityStoreUsers({
|
|
1568
2053
|
identityStoreClient: props.identityStoreClient,
|
|
1569
2054
|
identityStoreId: instance.identityStoreId
|
|
@@ -1575,6 +2060,10 @@ async function scanIdentityCenter(props) {
|
|
|
1575
2060
|
listPermissionSets({
|
|
1576
2061
|
ssoAdminClient: props.ssoAdminClient,
|
|
1577
2062
|
instanceArn: instance.instanceArn
|
|
2063
|
+
}),
|
|
2064
|
+
scanAccessControlAttributes({
|
|
2065
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
2066
|
+
instanceArn: instance.instanceArn
|
|
1578
2067
|
})
|
|
1579
2068
|
]);
|
|
1580
2069
|
const groupMemberships = await listGroupMemberships({
|
|
@@ -1599,9 +2088,30 @@ async function scanIdentityCenter(props) {
|
|
|
1599
2088
|
groupMemberships,
|
|
1600
2089
|
permissionSets,
|
|
1601
2090
|
accountAssignments,
|
|
1602
|
-
accessRoles
|
|
2091
|
+
accessRoles,
|
|
2092
|
+
accessControlAttributes
|
|
1603
2093
|
};
|
|
1604
2094
|
}
|
|
2095
|
+
async function scanAccessControlAttributes(props) {
|
|
2096
|
+
let response;
|
|
2097
|
+
try {
|
|
2098
|
+
response = await props.ssoAdminClient.send(
|
|
2099
|
+
new DescribeInstanceAccessControlAttributeConfigurationCommand({
|
|
2100
|
+
InstanceArn: props.instanceArn
|
|
2101
|
+
})
|
|
2102
|
+
);
|
|
2103
|
+
} catch (err) {
|
|
2104
|
+
if (err != null && typeof err === "object" && "name" in err && err.name === "ResourceNotFoundException") {
|
|
2105
|
+
return [];
|
|
2106
|
+
}
|
|
2107
|
+
throw err;
|
|
2108
|
+
}
|
|
2109
|
+
const attributes = response.InstanceAccessControlAttributeConfiguration?.AccessControlAttributes ?? [];
|
|
2110
|
+
return attributes.filter((attr) => attr.Key != null).map((attr) => ({
|
|
2111
|
+
key: attr.Key,
|
|
2112
|
+
source: attr.Value?.Source ?? []
|
|
2113
|
+
}));
|
|
2114
|
+
}
|
|
1605
2115
|
function selectIdentityCenterInstance(props) {
|
|
1606
2116
|
if (props.requestedInstanceArn != null) {
|
|
1607
2117
|
const selected2 = props.instances.find(
|
|
@@ -1752,7 +2262,8 @@ async function listPermissionSets(props) {
|
|
|
1752
2262
|
const [
|
|
1753
2263
|
inlinePolicy,
|
|
1754
2264
|
awsManagedPolicies,
|
|
1755
|
-
customerManagedPolicies
|
|
2265
|
+
customerManagedPolicies,
|
|
2266
|
+
permissionsBoundary
|
|
1756
2267
|
] = await Promise.all([
|
|
1757
2268
|
getInlinePolicyForPermissionSet({
|
|
1758
2269
|
ssoAdminClient: props.ssoAdminClient,
|
|
@@ -1768,6 +2279,11 @@ async function listPermissionSets(props) {
|
|
|
1768
2279
|
ssoAdminClient: props.ssoAdminClient,
|
|
1769
2280
|
instanceArn: props.instanceArn,
|
|
1770
2281
|
permissionSetArn: permissionSet.PermissionSetArn
|
|
2282
|
+
}),
|
|
2283
|
+
getPermissionsBoundaryForPermissionSet({
|
|
2284
|
+
ssoAdminClient: props.ssoAdminClient,
|
|
2285
|
+
instanceArn: props.instanceArn,
|
|
2286
|
+
permissionSetArn: permissionSet.PermissionSetArn
|
|
1771
2287
|
})
|
|
1772
2288
|
]);
|
|
1773
2289
|
return {
|
|
@@ -1777,7 +2293,8 @@ async function listPermissionSets(props) {
|
|
|
1777
2293
|
sessionDuration: permissionSet.SessionDuration ?? null,
|
|
1778
2294
|
inlinePolicy,
|
|
1779
2295
|
awsManagedPolicies,
|
|
1780
|
-
customerManagedPolicies
|
|
2296
|
+
customerManagedPolicies,
|
|
2297
|
+
permissionsBoundary
|
|
1781
2298
|
};
|
|
1782
2299
|
})
|
|
1783
2300
|
);
|
|
@@ -1795,6 +2312,29 @@ async function getInlinePolicyForPermissionSet(props) {
|
|
|
1795
2312
|
const inlinePolicy = response.InlinePolicy?.trim();
|
|
1796
2313
|
return inlinePolicy != null && inlinePolicy.length > 0 ? inlinePolicy : null;
|
|
1797
2314
|
}
|
|
2315
|
+
async function getPermissionsBoundaryForPermissionSet(props) {
|
|
2316
|
+
const response = await props.ssoAdminClient.send(
|
|
2317
|
+
new GetPermissionsBoundaryForPermissionSetCommand({
|
|
2318
|
+
InstanceArn: props.instanceArn,
|
|
2319
|
+
PermissionSetArn: props.permissionSetArn
|
|
2320
|
+
})
|
|
2321
|
+
);
|
|
2322
|
+
const boundary = response.PermissionsBoundary;
|
|
2323
|
+
if (boundary == null) {
|
|
2324
|
+
return null;
|
|
2325
|
+
}
|
|
2326
|
+
if (boundary.ManagedPolicyArn != null) {
|
|
2327
|
+
return { managedPolicyArn: boundary.ManagedPolicyArn };
|
|
2328
|
+
}
|
|
2329
|
+
const ref = boundary.CustomerManagedPolicyReference;
|
|
2330
|
+
if (ref?.Name != null) {
|
|
2331
|
+
return {
|
|
2332
|
+
customerManagedPolicyName: ref.Name,
|
|
2333
|
+
customerManagedPolicyPath: ref.Path ?? "/"
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
return null;
|
|
2337
|
+
}
|
|
1798
2338
|
async function listManagedPoliciesInPermissionSet(props) {
|
|
1799
2339
|
const managedPolicies = [];
|
|
1800
2340
|
let nextToken;
|
|
@@ -1892,18 +2432,61 @@ async function listAccountsForPermissionSet(props) {
|
|
|
1892
2432
|
} while (nextToken != null);
|
|
1893
2433
|
return accountIds;
|
|
1894
2434
|
}
|
|
2435
|
+
var ALTERNATE_CONTACT_TYPES = ["BILLING", "OPERATIONS", "SECURITY"];
|
|
2436
|
+
async function scanAlternateContacts(props) {
|
|
2437
|
+
const results = await Promise.all(
|
|
2438
|
+
ALTERNATE_CONTACT_TYPES.map(async (contactType) => {
|
|
2439
|
+
try {
|
|
2440
|
+
const response = await props.accountClient.send(
|
|
2441
|
+
new GetAlternateContactCommand({
|
|
2442
|
+
AccountId: props.isManagementAccount ? void 0 : props.accountId,
|
|
2443
|
+
AlternateContactType: contactType
|
|
2444
|
+
})
|
|
2445
|
+
);
|
|
2446
|
+
const c = response.AlternateContact;
|
|
2447
|
+
if (c == null || c.EmailAddress == null || c.Name == null) {
|
|
2448
|
+
return null;
|
|
2449
|
+
}
|
|
2450
|
+
return {
|
|
2451
|
+
contactType,
|
|
2452
|
+
name: c.Name,
|
|
2453
|
+
email: c.EmailAddress,
|
|
2454
|
+
phone: c.PhoneNumber ?? "",
|
|
2455
|
+
...c.Title != null ? { title: c.Title } : {}
|
|
2456
|
+
};
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
if (error != null && typeof error === "object" && "name" in error && error.name === "ResourceNotFoundException") {
|
|
2459
|
+
return null;
|
|
2460
|
+
}
|
|
2461
|
+
throw error;
|
|
2462
|
+
}
|
|
2463
|
+
})
|
|
2464
|
+
);
|
|
2465
|
+
return results.filter((c) => c != null);
|
|
2466
|
+
}
|
|
1895
2467
|
|
|
1896
2468
|
// src/applyLogic.ts
|
|
1897
|
-
import { PutAccountNameCommand } from "@aws-sdk/client-account";
|
|
1898
2469
|
import {
|
|
2470
|
+
DeleteAlternateContactCommand,
|
|
2471
|
+
PutAccountNameCommand,
|
|
2472
|
+
PutAlternateContactCommand
|
|
2473
|
+
} from "@aws-sdk/client-account";
|
|
2474
|
+
import {
|
|
2475
|
+
AttachPolicyCommand,
|
|
1899
2476
|
CreateOrganizationalUnitCommand,
|
|
2477
|
+
CreatePolicyCommand,
|
|
2478
|
+
DeregisterDelegatedAdministratorCommand,
|
|
1900
2479
|
DeleteOrganizationalUnitCommand,
|
|
2480
|
+
DeletePolicyCommand,
|
|
2481
|
+
DetachPolicyCommand,
|
|
1901
2482
|
ListAccountsForParentCommand,
|
|
1902
2483
|
ListOrganizationalUnitsForParentCommand as ListOrganizationalUnitsForParentCommand2,
|
|
1903
2484
|
MoveAccountCommand as MoveAccountCommand2,
|
|
2485
|
+
RegisterDelegatedAdministratorCommand,
|
|
1904
2486
|
TagResourceCommand,
|
|
1905
2487
|
UntagResourceCommand,
|
|
1906
|
-
UpdateOrganizationalUnitCommand
|
|
2488
|
+
UpdateOrganizationalUnitCommand,
|
|
2489
|
+
UpdatePolicyCommand
|
|
1907
2490
|
} from "@aws-sdk/client-organizations";
|
|
1908
2491
|
import {
|
|
1909
2492
|
CreateGroupMembershipCommand,
|
|
@@ -1923,6 +2506,7 @@ import {
|
|
|
1923
2506
|
CreatePermissionSetCommand,
|
|
1924
2507
|
DeleteAccountAssignmentCommand,
|
|
1925
2508
|
DeleteInlinePolicyFromPermissionSetCommand,
|
|
2509
|
+
DeletePermissionsBoundaryFromPermissionSetCommand,
|
|
1926
2510
|
DeletePermissionSetCommand,
|
|
1927
2511
|
DescribeAccountAssignmentCreationStatusCommand,
|
|
1928
2512
|
DescribeAccountAssignmentDeletionStatusCommand,
|
|
@@ -1931,6 +2515,8 @@ import {
|
|
|
1931
2515
|
DetachManagedPolicyFromPermissionSetCommand,
|
|
1932
2516
|
ProvisionPermissionSetCommand,
|
|
1933
2517
|
PutInlinePolicyToPermissionSetCommand,
|
|
2518
|
+
PutPermissionsBoundaryToPermissionSetCommand,
|
|
2519
|
+
UpdateInstanceAccessControlAttributeConfigurationCommand,
|
|
1934
2520
|
UpdatePermissionSetCommand
|
|
1935
2521
|
} from "@aws-sdk/client-sso-admin";
|
|
1936
2522
|
|
|
@@ -2069,39 +2655,38 @@ function isCompleteAccountWithStatus(account, expectedAccountId) {
|
|
|
2069
2655
|
|
|
2070
2656
|
// src/applyLogic.ts
|
|
2071
2657
|
async function executeOperation(props) {
|
|
2072
|
-
|
|
2073
|
-
if (operation.kind === "moveAccount") {
|
|
2658
|
+
if (props.operation.kind === "moveAccount") {
|
|
2074
2659
|
props.logger.log(
|
|
2075
|
-
`Moving "${operation.accountName}" (${operation.accountId}): ${operation.fromOuName} -> ${operation.toOuName}`
|
|
2660
|
+
`Moving "${props.operation.accountName}" (${props.operation.accountId}): ${props.operation.fromOuName} -> ${props.operation.toOuName}`
|
|
2076
2661
|
);
|
|
2077
2662
|
await props.organizationsClient.send(
|
|
2078
2663
|
new MoveAccountCommand2({
|
|
2079
|
-
AccountId: operation.accountId,
|
|
2080
|
-
SourceParentId: operation.fromOuId,
|
|
2081
|
-
DestinationParentId: operation.toOuId
|
|
2664
|
+
AccountId: props.operation.accountId,
|
|
2665
|
+
SourceParentId: props.operation.fromOuId,
|
|
2666
|
+
DestinationParentId: props.operation.toOuId
|
|
2082
2667
|
})
|
|
2083
2668
|
);
|
|
2084
|
-
props.logger.log(`Done: "${operation.accountName}"`);
|
|
2669
|
+
props.logger.log(`Done: "${props.operation.accountName}"`);
|
|
2085
2670
|
return moveAccountInWorkingState({
|
|
2086
2671
|
workingState: props.state,
|
|
2087
|
-
accountId: operation.accountId,
|
|
2088
|
-
parentId: operation.toOuId
|
|
2672
|
+
accountId: props.operation.accountId,
|
|
2673
|
+
parentId: props.operation.toOuId
|
|
2089
2674
|
});
|
|
2090
2675
|
}
|
|
2091
|
-
if (operation.kind === "createOu") {
|
|
2676
|
+
if (props.operation.kind === "createOu") {
|
|
2092
2677
|
props.logger.log(
|
|
2093
|
-
`Creating OU "${operation.ouName}" under ${operation.parentOuName}...`
|
|
2678
|
+
`Creating OU "${props.operation.ouName}" under ${props.operation.parentOuName}...`
|
|
2094
2679
|
);
|
|
2095
2680
|
const response = await props.organizationsClient.send(
|
|
2096
2681
|
new CreateOrganizationalUnitCommand({
|
|
2097
|
-
ParentId: operation.parentOuId,
|
|
2098
|
-
Name: operation.ouName
|
|
2682
|
+
ParentId: props.operation.parentOuId,
|
|
2683
|
+
Name: props.operation.ouName
|
|
2099
2684
|
})
|
|
2100
2685
|
);
|
|
2101
2686
|
const createdOu = response.OrganizationalUnit;
|
|
2102
2687
|
if (createdOu?.Id == null || createdOu.Arn == null || createdOu.Name == null) {
|
|
2103
2688
|
throw new Error(
|
|
2104
|
-
`CreateOrganizationalUnit for "${operation.ouName}" returned incomplete OU data.`
|
|
2689
|
+
`CreateOrganizationalUnit for "${props.operation.ouName}" returned incomplete OU data.`
|
|
2105
2690
|
);
|
|
2106
2691
|
}
|
|
2107
2692
|
props.logger.log(`Done: "${createdOu.Name}"`);
|
|
@@ -2109,55 +2694,55 @@ async function executeOperation(props) {
|
|
|
2109
2694
|
workingState: props.state,
|
|
2110
2695
|
organizationalUnit: {
|
|
2111
2696
|
id: createdOu.Id,
|
|
2112
|
-
parentId: operation.parentOuId,
|
|
2697
|
+
parentId: props.operation.parentOuId,
|
|
2113
2698
|
arn: createdOu.Arn,
|
|
2114
2699
|
name: createdOu.Name
|
|
2115
2700
|
}
|
|
2116
2701
|
});
|
|
2117
2702
|
}
|
|
2118
|
-
if (operation.kind === "renameOu") {
|
|
2703
|
+
if (props.operation.kind === "renameOu") {
|
|
2119
2704
|
props.logger.log(
|
|
2120
|
-
`Renaming OU "${operation.fromOuName}" -> "${operation.toOuName}"...`
|
|
2705
|
+
`Renaming OU "${props.operation.fromOuName}" -> "${props.operation.toOuName}"...`
|
|
2121
2706
|
);
|
|
2122
2707
|
await props.organizationsClient.send(
|
|
2123
2708
|
new UpdateOrganizationalUnitCommand({
|
|
2124
|
-
OrganizationalUnitId: operation.ouId,
|
|
2125
|
-
Name: operation.toOuName
|
|
2709
|
+
OrganizationalUnitId: props.operation.ouId,
|
|
2710
|
+
Name: props.operation.toOuName
|
|
2126
2711
|
})
|
|
2127
2712
|
);
|
|
2128
|
-
props.logger.log(`Done: "${operation.toOuName}"`);
|
|
2713
|
+
props.logger.log(`Done: "${props.operation.toOuName}"`);
|
|
2129
2714
|
return renameOrganizationalUnitInWorkingState({
|
|
2130
2715
|
workingState: props.state,
|
|
2131
|
-
organizationalUnitId: operation.ouId,
|
|
2132
|
-
name: operation.toOuName
|
|
2716
|
+
organizationalUnitId: props.operation.ouId,
|
|
2717
|
+
name: props.operation.toOuName
|
|
2133
2718
|
});
|
|
2134
2719
|
}
|
|
2135
|
-
if (operation.kind === "deleteOu") {
|
|
2136
|
-
props.logger.log(`Deleting OU "${operation.ouName}"...`);
|
|
2720
|
+
if (props.operation.kind === "deleteOu") {
|
|
2721
|
+
props.logger.log(`Deleting OU "${props.operation.ouName}"...`);
|
|
2137
2722
|
await assertOrganizationalUnitIsEmpty({
|
|
2138
2723
|
organizationsClient: props.organizationsClient,
|
|
2139
|
-
organizationalUnitId: operation.ouId,
|
|
2140
|
-
organizationalUnitName: operation.ouName
|
|
2724
|
+
organizationalUnitId: props.operation.ouId,
|
|
2725
|
+
organizationalUnitName: props.operation.ouName
|
|
2141
2726
|
});
|
|
2142
2727
|
await props.organizationsClient.send(
|
|
2143
2728
|
new DeleteOrganizationalUnitCommand({
|
|
2144
|
-
OrganizationalUnitId: operation.ouId
|
|
2729
|
+
OrganizationalUnitId: props.operation.ouId
|
|
2145
2730
|
})
|
|
2146
2731
|
);
|
|
2147
|
-
props.logger.log(`Done: "${operation.ouName}"`);
|
|
2732
|
+
props.logger.log(`Done: "${props.operation.ouName}"`);
|
|
2148
2733
|
return removeOrganizationalUnitFromWorkingState({
|
|
2149
2734
|
workingState: props.state,
|
|
2150
|
-
organizationalUnitId: operation.ouId
|
|
2735
|
+
organizationalUnitId: props.operation.ouId
|
|
2151
2736
|
});
|
|
2152
2737
|
}
|
|
2153
|
-
if (operation.kind === "createAccount") {
|
|
2738
|
+
if (props.operation.kind === "createAccount") {
|
|
2154
2739
|
const result = await createAccountAndMoveToOu({
|
|
2155
2740
|
organizationsClient: props.organizationsClient,
|
|
2156
2741
|
logger: props.logger,
|
|
2157
|
-
accountName: operation.accountName,
|
|
2158
|
-
accountEmail: operation.accountEmail,
|
|
2742
|
+
accountName: props.operation.accountName,
|
|
2743
|
+
accountEmail: props.operation.accountEmail,
|
|
2159
2744
|
sourceParentId: props.context.organization.rootId,
|
|
2160
|
-
destinationParentId: operation.targetOuId,
|
|
2745
|
+
destinationParentId: props.operation.targetOuId,
|
|
2161
2746
|
timeoutInMs: props.runtime.createAccount.timeoutInMs,
|
|
2162
2747
|
pollIntervalInMs: props.runtime.createAccount.pollIntervalInMs
|
|
2163
2748
|
});
|
|
@@ -2169,33 +2754,33 @@ async function executeOperation(props) {
|
|
|
2169
2754
|
name: result.account.name,
|
|
2170
2755
|
email: result.account.email,
|
|
2171
2756
|
status: result.account.status,
|
|
2172
|
-
parentId: operation.targetOuId,
|
|
2757
|
+
parentId: props.operation.targetOuId,
|
|
2173
2758
|
tags: []
|
|
2174
2759
|
}
|
|
2175
2760
|
});
|
|
2176
2761
|
}
|
|
2177
|
-
if (operation.kind === "updateAccountTags") {
|
|
2178
|
-
const account = props.state.organization.accountsById[operation.accountId];
|
|
2762
|
+
if (props.operation.kind === "updateAccountTags") {
|
|
2763
|
+
const account = props.state.organization.accountsById[props.operation.accountId];
|
|
2179
2764
|
if (account == null) {
|
|
2180
2765
|
throw new Error(
|
|
2181
|
-
`Could not resolve account "${operation.accountName}" (${operation.accountId}) in working state.`
|
|
2766
|
+
`Could not resolve account "${props.operation.accountName}" (${props.operation.accountId}) in working state.`
|
|
2182
2767
|
);
|
|
2183
2768
|
}
|
|
2184
2769
|
const currentTags = new Map(
|
|
2185
2770
|
(account.tags ?? []).map((tag) => [tag.key, tag.value])
|
|
2186
2771
|
);
|
|
2187
|
-
const desiredTags = new Map(Object.entries(operation.tags));
|
|
2772
|
+
const desiredTags = new Map(Object.entries(props.operation.tags));
|
|
2188
2773
|
const tagsToApply = [...desiredTags.entries()].filter(([key, value]) => currentTags.get(key) !== value).map(([Key, Value]) => ({ Key, Value }));
|
|
2189
2774
|
const tagKeysToRemove = [...currentTags.keys()].filter(
|
|
2190
2775
|
(key) => desiredTags.has(key) === false
|
|
2191
2776
|
);
|
|
2192
2777
|
props.logger.log(
|
|
2193
|
-
`Updating account tags "${operation.accountName}" (${operation.accountId})...`
|
|
2778
|
+
`Updating account tags "${props.operation.accountName}" (${props.operation.accountId})...`
|
|
2194
2779
|
);
|
|
2195
2780
|
if (tagsToApply.length > 0) {
|
|
2196
2781
|
await props.organizationsClient.send(
|
|
2197
2782
|
new TagResourceCommand({
|
|
2198
|
-
ResourceId: operation.accountId,
|
|
2783
|
+
ResourceId: props.operation.accountId,
|
|
2199
2784
|
Tags: tagsToApply
|
|
2200
2785
|
})
|
|
2201
2786
|
);
|
|
@@ -2203,84 +2788,84 @@ async function executeOperation(props) {
|
|
|
2203
2788
|
if (tagKeysToRemove.length > 0) {
|
|
2204
2789
|
await props.organizationsClient.send(
|
|
2205
2790
|
new UntagResourceCommand({
|
|
2206
|
-
ResourceId: operation.accountId,
|
|
2791
|
+
ResourceId: props.operation.accountId,
|
|
2207
2792
|
TagKeys: tagKeysToRemove
|
|
2208
2793
|
})
|
|
2209
2794
|
);
|
|
2210
2795
|
}
|
|
2211
|
-
props.logger.log(`Done: tags updated for "${operation.accountName}"`);
|
|
2796
|
+
props.logger.log(`Done: tags updated for "${props.operation.accountName}"`);
|
|
2212
2797
|
return upsertAccountInWorkingState({
|
|
2213
2798
|
workingState: props.state,
|
|
2214
2799
|
account: {
|
|
2215
2800
|
...account,
|
|
2216
|
-
tags: Object.entries(operation.tags).map(([key, value]) => ({
|
|
2801
|
+
tags: Object.entries(props.operation.tags).map(([key, value]) => ({
|
|
2217
2802
|
key,
|
|
2218
2803
|
value
|
|
2219
2804
|
}))
|
|
2220
2805
|
}
|
|
2221
2806
|
});
|
|
2222
2807
|
}
|
|
2223
|
-
if (operation.kind === "updateAccountName") {
|
|
2808
|
+
if (props.operation.kind === "updateAccountName") {
|
|
2224
2809
|
props.logger.log(
|
|
2225
|
-
`Renaming account (${operation.accountId}): "${operation.fromAccountName}" -> "${operation.toAccountName}"...`
|
|
2810
|
+
`Renaming account (${props.operation.accountId}): "${props.operation.fromAccountName}" -> "${props.operation.toAccountName}"...`
|
|
2226
2811
|
);
|
|
2227
2812
|
await props.accountClient.send(
|
|
2228
2813
|
new PutAccountNameCommand({
|
|
2229
|
-
AccountId: operation.accountId,
|
|
2230
|
-
AccountName: operation.toAccountName
|
|
2814
|
+
AccountId: props.operation.accountId,
|
|
2815
|
+
AccountName: props.operation.toAccountName
|
|
2231
2816
|
})
|
|
2232
2817
|
);
|
|
2233
2818
|
props.logger.log(
|
|
2234
|
-
`Done: account "${operation.toAccountName}" (${operation.accountId})`
|
|
2819
|
+
`Done: account "${props.operation.toAccountName}" (${props.operation.accountId})`
|
|
2235
2820
|
);
|
|
2236
|
-
const account = props.state.organization.accountsById[operation.accountId];
|
|
2821
|
+
const account = props.state.organization.accountsById[props.operation.accountId];
|
|
2237
2822
|
if (account == null) {
|
|
2238
2823
|
throw new Error(
|
|
2239
|
-
`Could not resolve account (${operation.accountId}) in working state after rename.`
|
|
2824
|
+
`Could not resolve account (${props.operation.accountId}) in working state after rename.`
|
|
2240
2825
|
);
|
|
2241
2826
|
}
|
|
2242
2827
|
return upsertAccountInWorkingState({
|
|
2243
2828
|
workingState: props.state,
|
|
2244
2829
|
account: {
|
|
2245
2830
|
...account,
|
|
2246
|
-
name: operation.toAccountName
|
|
2831
|
+
name: props.operation.toAccountName
|
|
2247
2832
|
}
|
|
2248
2833
|
});
|
|
2249
2834
|
}
|
|
2250
|
-
if (operation.kind === "removeAccount") {
|
|
2835
|
+
if (props.operation.kind === "removeAccount") {
|
|
2251
2836
|
props.logger.log(
|
|
2252
|
-
`Moving removed account "${operation.accountName}" (${operation.accountId}) to ${operation.toOuName}...`
|
|
2837
|
+
`Moving removed account "${props.operation.accountName}" (${props.operation.accountId}) to ${props.operation.toOuName}...`
|
|
2253
2838
|
);
|
|
2254
2839
|
await props.organizationsClient.send(
|
|
2255
2840
|
new MoveAccountCommand2({
|
|
2256
|
-
AccountId: operation.accountId,
|
|
2257
|
-
SourceParentId: operation.fromOuId,
|
|
2258
|
-
DestinationParentId: operation.toOuId
|
|
2841
|
+
AccountId: props.operation.accountId,
|
|
2842
|
+
SourceParentId: props.operation.fromOuId,
|
|
2843
|
+
DestinationParentId: props.operation.toOuId
|
|
2259
2844
|
})
|
|
2260
2845
|
);
|
|
2261
2846
|
props.logger.log(
|
|
2262
|
-
`Done: "${operation.accountName}" -> ${operation.toOuName}`
|
|
2847
|
+
`Done: "${props.operation.accountName}" -> ${props.operation.toOuName}`
|
|
2263
2848
|
);
|
|
2264
2849
|
return moveAccountInWorkingState({
|
|
2265
2850
|
workingState: props.state,
|
|
2266
|
-
accountId: operation.accountId,
|
|
2267
|
-
parentId: operation.toOuId
|
|
2851
|
+
accountId: props.operation.accountId,
|
|
2852
|
+
parentId: props.operation.toOuId
|
|
2268
2853
|
});
|
|
2269
2854
|
}
|
|
2270
|
-
if (operation.kind === "createIdcUser") {
|
|
2271
|
-
props.logger.log(`Creating IdC user "${operation.userName}"...`);
|
|
2855
|
+
if (props.operation.kind === "createIdcUser") {
|
|
2856
|
+
props.logger.log(`Creating IdC user "${props.operation.userName}"...`);
|
|
2272
2857
|
const response = await props.identityStoreClient.send(
|
|
2273
2858
|
new CreateUserCommand({
|
|
2274
2859
|
IdentityStoreId: props.state.identityCenter.identityStoreId,
|
|
2275
|
-
UserName: operation.userName,
|
|
2276
|
-
DisplayName: operation.displayName,
|
|
2860
|
+
UserName: props.operation.userName,
|
|
2861
|
+
DisplayName: props.operation.displayName,
|
|
2277
2862
|
Name: buildIdentityStoreUserName({
|
|
2278
|
-
userName: operation.userName,
|
|
2279
|
-
displayName: operation.displayName
|
|
2863
|
+
userName: props.operation.userName,
|
|
2864
|
+
displayName: props.operation.displayName
|
|
2280
2865
|
}),
|
|
2281
|
-
Emails: operation.email.length > 0 ? [
|
|
2866
|
+
Emails: props.operation.email.length > 0 ? [
|
|
2282
2867
|
{
|
|
2283
|
-
Value: operation.email,
|
|
2868
|
+
Value: props.operation.email,
|
|
2284
2869
|
Type: "Work",
|
|
2285
2870
|
Primary: true
|
|
2286
2871
|
}
|
|
@@ -2289,45 +2874,45 @@ async function executeOperation(props) {
|
|
|
2289
2874
|
);
|
|
2290
2875
|
if (response.UserId == null) {
|
|
2291
2876
|
throw new Error(
|
|
2292
|
-
`CreateUser for "${operation.userName}" returned no user id.`
|
|
2877
|
+
`CreateUser for "${props.operation.userName}" returned no user id.`
|
|
2293
2878
|
);
|
|
2294
2879
|
}
|
|
2295
|
-
props.logger.log(`Done: "${operation.userName}"`);
|
|
2880
|
+
props.logger.log(`Done: "${props.operation.userName}"`);
|
|
2296
2881
|
return upsertIdcUserInWorkingState({
|
|
2297
2882
|
workingState: props.state,
|
|
2298
2883
|
user: {
|
|
2299
2884
|
userId: response.UserId,
|
|
2300
|
-
userName: operation.userName,
|
|
2301
|
-
displayName: operation.displayName,
|
|
2302
|
-
email: operation.email
|
|
2885
|
+
userName: props.operation.userName,
|
|
2886
|
+
displayName: props.operation.displayName,
|
|
2887
|
+
email: props.operation.email
|
|
2303
2888
|
}
|
|
2304
2889
|
});
|
|
2305
2890
|
}
|
|
2306
|
-
if (operation.kind === "updateIdcUser") {
|
|
2891
|
+
if (props.operation.kind === "updateIdcUser") {
|
|
2307
2892
|
const user = resolveUserByName({
|
|
2308
2893
|
state: props.state,
|
|
2309
|
-
userName: operation.userName
|
|
2894
|
+
userName: props.operation.userName
|
|
2310
2895
|
});
|
|
2311
2896
|
const operations = [];
|
|
2312
|
-
if (user.displayName !== operation.displayName) {
|
|
2897
|
+
if (user.displayName !== props.operation.displayName) {
|
|
2313
2898
|
operations.push({
|
|
2314
2899
|
AttributePath: "displayName",
|
|
2315
|
-
AttributeValue: operation.displayName
|
|
2900
|
+
AttributeValue: props.operation.displayName
|
|
2316
2901
|
});
|
|
2317
2902
|
operations.push({
|
|
2318
2903
|
AttributePath: "name",
|
|
2319
2904
|
AttributeValue: buildIdentityStoreUserName({
|
|
2320
|
-
userName: operation.userName,
|
|
2321
|
-
displayName: operation.displayName
|
|
2905
|
+
userName: props.operation.userName,
|
|
2906
|
+
displayName: props.operation.displayName
|
|
2322
2907
|
})
|
|
2323
2908
|
});
|
|
2324
2909
|
}
|
|
2325
|
-
if (user.email !== operation.email && operation.email.length > 0) {
|
|
2910
|
+
if (user.email !== props.operation.email && props.operation.email.length > 0) {
|
|
2326
2911
|
operations.push({
|
|
2327
2912
|
AttributePath: "emails",
|
|
2328
2913
|
AttributeValue: [
|
|
2329
2914
|
{
|
|
2330
|
-
Value: operation.email,
|
|
2915
|
+
Value: props.operation.email,
|
|
2331
2916
|
Type: "Work",
|
|
2332
2917
|
Primary: true
|
|
2333
2918
|
}
|
|
@@ -2337,7 +2922,7 @@ async function executeOperation(props) {
|
|
|
2337
2922
|
if (operations.length === 0) {
|
|
2338
2923
|
return props.state;
|
|
2339
2924
|
}
|
|
2340
|
-
props.logger.log(`Updating IdC user "${operation.userName}"...`);
|
|
2925
|
+
props.logger.log(`Updating IdC user "${props.operation.userName}"...`);
|
|
2341
2926
|
await props.identityStoreClient.send(
|
|
2342
2927
|
new UpdateUserCommand({
|
|
2343
2928
|
IdentityStoreId: props.state.identityCenter.identityStoreId,
|
|
@@ -2345,65 +2930,65 @@ async function executeOperation(props) {
|
|
|
2345
2930
|
Operations: operations
|
|
2346
2931
|
})
|
|
2347
2932
|
);
|
|
2348
|
-
props.logger.log(`Done: "${operation.userName}"`);
|
|
2933
|
+
props.logger.log(`Done: "${props.operation.userName}"`);
|
|
2349
2934
|
return upsertIdcUserInWorkingState({
|
|
2350
2935
|
workingState: props.state,
|
|
2351
2936
|
user: {
|
|
2352
2937
|
...user,
|
|
2353
|
-
displayName: operation.displayName,
|
|
2354
|
-
email: operation.email.length > 0 ? operation.email : user.email
|
|
2938
|
+
displayName: props.operation.displayName,
|
|
2939
|
+
email: props.operation.email.length > 0 ? props.operation.email : user.email
|
|
2355
2940
|
}
|
|
2356
2941
|
});
|
|
2357
2942
|
}
|
|
2358
|
-
if (operation.kind === "deleteIdcUser") {
|
|
2943
|
+
if (props.operation.kind === "deleteIdcUser") {
|
|
2359
2944
|
const user = resolveUserByName({
|
|
2360
2945
|
state: props.state,
|
|
2361
|
-
userName: operation.userName
|
|
2946
|
+
userName: props.operation.userName
|
|
2362
2947
|
});
|
|
2363
|
-
props.logger.log(`Deleting IdC user "${operation.userName}"...`);
|
|
2948
|
+
props.logger.log(`Deleting IdC user "${props.operation.userName}"...`);
|
|
2364
2949
|
await props.identityStoreClient.send(
|
|
2365
2950
|
new DeleteUserCommand({
|
|
2366
2951
|
IdentityStoreId: props.state.identityCenter.identityStoreId,
|
|
2367
2952
|
UserId: user.userId
|
|
2368
2953
|
})
|
|
2369
2954
|
);
|
|
2370
|
-
props.logger.log(`Done: "${operation.userName}"`);
|
|
2955
|
+
props.logger.log(`Done: "${props.operation.userName}"`);
|
|
2371
2956
|
return removeIdcUserFromWorkingState({
|
|
2372
2957
|
workingState: props.state,
|
|
2373
|
-
userName: operation.userName
|
|
2958
|
+
userName: props.operation.userName
|
|
2374
2959
|
});
|
|
2375
2960
|
}
|
|
2376
|
-
if (operation.kind === "createIdcGroup") {
|
|
2377
|
-
props.logger.log(`Creating IdC group "${operation.groupDisplayName}"...`);
|
|
2961
|
+
if (props.operation.kind === "createIdcGroup") {
|
|
2962
|
+
props.logger.log(`Creating IdC group "${props.operation.groupDisplayName}"...`);
|
|
2378
2963
|
const response = await props.identityStoreClient.send(
|
|
2379
2964
|
new CreateGroupCommand({
|
|
2380
2965
|
IdentityStoreId: props.state.identityCenter.identityStoreId,
|
|
2381
|
-
DisplayName: operation.groupDisplayName,
|
|
2382
|
-
Description: operation.description.trim().length > 0 ? operation.description : void 0
|
|
2966
|
+
DisplayName: props.operation.groupDisplayName,
|
|
2967
|
+
Description: props.operation.description.trim().length > 0 ? props.operation.description : void 0
|
|
2383
2968
|
})
|
|
2384
2969
|
);
|
|
2385
2970
|
if (response.GroupId == null) {
|
|
2386
2971
|
throw new Error(
|
|
2387
|
-
`CreateGroup for "${operation.groupDisplayName}" returned no group id.`
|
|
2972
|
+
`CreateGroup for "${props.operation.groupDisplayName}" returned no group id.`
|
|
2388
2973
|
);
|
|
2389
2974
|
}
|
|
2390
|
-
props.logger.log(`Done: "${operation.groupDisplayName}"`);
|
|
2975
|
+
props.logger.log(`Done: "${props.operation.groupDisplayName}"`);
|
|
2391
2976
|
return upsertIdcGroupInWorkingState({
|
|
2392
2977
|
workingState: props.state,
|
|
2393
2978
|
group: {
|
|
2394
2979
|
groupId: response.GroupId,
|
|
2395
|
-
displayName: operation.groupDisplayName,
|
|
2396
|
-
description: operation.description
|
|
2980
|
+
displayName: props.operation.groupDisplayName,
|
|
2981
|
+
description: props.operation.description
|
|
2397
2982
|
}
|
|
2398
2983
|
});
|
|
2399
2984
|
}
|
|
2400
|
-
if (operation.kind === "updateIdcGroupDescription") {
|
|
2985
|
+
if (props.operation.kind === "updateIdcGroupDescription") {
|
|
2401
2986
|
const group = resolveGroupByDisplayName({
|
|
2402
2987
|
state: props.state,
|
|
2403
|
-
groupDisplayName: operation.groupDisplayName
|
|
2988
|
+
groupDisplayName: props.operation.groupDisplayName
|
|
2404
2989
|
});
|
|
2405
2990
|
props.logger.log(
|
|
2406
|
-
`Updating IdC group description for "${operation.groupDisplayName}"...`
|
|
2991
|
+
`Updating IdC group description for "${props.operation.groupDisplayName}"...`
|
|
2407
2992
|
);
|
|
2408
2993
|
await props.identityStoreClient.send(
|
|
2409
2994
|
new UpdateGroupCommand({
|
|
@@ -2412,46 +2997,46 @@ async function executeOperation(props) {
|
|
|
2412
2997
|
Operations: [
|
|
2413
2998
|
{
|
|
2414
2999
|
AttributePath: "description",
|
|
2415
|
-
AttributeValue: operation.description
|
|
3000
|
+
AttributeValue: props.operation.description
|
|
2416
3001
|
}
|
|
2417
3002
|
]
|
|
2418
3003
|
})
|
|
2419
3004
|
);
|
|
2420
|
-
props.logger.log(`Done: group "${operation.groupDisplayName}"`);
|
|
3005
|
+
props.logger.log(`Done: group "${props.operation.groupDisplayName}"`);
|
|
2421
3006
|
return upsertIdcGroupInWorkingState({
|
|
2422
3007
|
workingState: props.state,
|
|
2423
3008
|
group: {
|
|
2424
3009
|
...group,
|
|
2425
|
-
description: operation.description
|
|
3010
|
+
description: props.operation.description
|
|
2426
3011
|
}
|
|
2427
3012
|
});
|
|
2428
3013
|
}
|
|
2429
|
-
if (operation.kind === "deleteIdcGroup") {
|
|
3014
|
+
if (props.operation.kind === "deleteIdcGroup") {
|
|
2430
3015
|
const group = resolveGroupByDisplayName({
|
|
2431
3016
|
state: props.state,
|
|
2432
|
-
groupDisplayName: operation.groupDisplayName
|
|
3017
|
+
groupDisplayName: props.operation.groupDisplayName
|
|
2433
3018
|
});
|
|
2434
|
-
props.logger.log(`Deleting IdC group "${operation.groupDisplayName}"...`);
|
|
3019
|
+
props.logger.log(`Deleting IdC group "${props.operation.groupDisplayName}"...`);
|
|
2435
3020
|
await props.identityStoreClient.send(
|
|
2436
3021
|
new DeleteGroupCommand({
|
|
2437
3022
|
IdentityStoreId: props.state.identityCenter.identityStoreId,
|
|
2438
3023
|
GroupId: group.groupId
|
|
2439
3024
|
})
|
|
2440
3025
|
);
|
|
2441
|
-
props.logger.log(`Done: "${operation.groupDisplayName}"`);
|
|
3026
|
+
props.logger.log(`Done: "${props.operation.groupDisplayName}"`);
|
|
2442
3027
|
return removeIdcGroupFromWorkingState({
|
|
2443
3028
|
workingState: props.state,
|
|
2444
|
-
groupDisplayName: operation.groupDisplayName
|
|
3029
|
+
groupDisplayName: props.operation.groupDisplayName
|
|
2445
3030
|
});
|
|
2446
3031
|
}
|
|
2447
|
-
if (operation.kind === "addIdcGroupMembership") {
|
|
3032
|
+
if (props.operation.kind === "addIdcGroupMembership") {
|
|
2448
3033
|
const resolvedMembership = resolveGroupMembershipDependencies({
|
|
2449
3034
|
state: props.state,
|
|
2450
|
-
groupDisplayName: operation.groupDisplayName,
|
|
2451
|
-
userName: operation.userName
|
|
3035
|
+
groupDisplayName: props.operation.groupDisplayName,
|
|
3036
|
+
userName: props.operation.userName
|
|
2452
3037
|
});
|
|
2453
3038
|
props.logger.log(
|
|
2454
|
-
`Adding user "${operation.userName}" to IdC group "${operation.groupDisplayName}"...`
|
|
3039
|
+
`Adding user "${props.operation.userName}" to IdC group "${props.operation.groupDisplayName}"...`
|
|
2455
3040
|
);
|
|
2456
3041
|
const response = await props.identityStoreClient.send(
|
|
2457
3042
|
new CreateGroupMembershipCommand({
|
|
@@ -2464,11 +3049,11 @@ async function executeOperation(props) {
|
|
|
2464
3049
|
);
|
|
2465
3050
|
if (response.MembershipId == null) {
|
|
2466
3051
|
throw new Error(
|
|
2467
|
-
`CreateGroupMembership for group "${operation.groupDisplayName}" and user "${operation.userName}" returned no membership id.`
|
|
3052
|
+
`CreateGroupMembership for group "${props.operation.groupDisplayName}" and user "${props.operation.userName}" returned no membership id.`
|
|
2468
3053
|
);
|
|
2469
3054
|
}
|
|
2470
3055
|
props.logger.log(
|
|
2471
|
-
`Done: user "${operation.userName}" -> group "${operation.groupDisplayName}"`
|
|
3056
|
+
`Done: user "${props.operation.userName}" -> group "${props.operation.groupDisplayName}"`
|
|
2472
3057
|
);
|
|
2473
3058
|
return addGroupMembershipToWorkingState({
|
|
2474
3059
|
workingState: props.state,
|
|
@@ -2479,93 +3064,94 @@ async function executeOperation(props) {
|
|
|
2479
3064
|
}
|
|
2480
3065
|
});
|
|
2481
3066
|
}
|
|
2482
|
-
if (operation.kind === "createIdcPermissionSet") {
|
|
3067
|
+
if (props.operation.kind === "createIdcPermissionSet") {
|
|
2483
3068
|
props.logger.log(
|
|
2484
|
-
`Creating IdC permission set "${operation.permissionSetName}"...`
|
|
3069
|
+
`Creating IdC permission set "${props.operation.permissionSetName}"...`
|
|
2485
3070
|
);
|
|
2486
3071
|
const response = await props.ssoAdminClient.send(
|
|
2487
3072
|
new CreatePermissionSetCommand({
|
|
2488
3073
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2489
|
-
Name: operation.permissionSetName,
|
|
2490
|
-
Description: operation.description.length > 0 ? operation.description : void 0,
|
|
2491
|
-
SessionDuration: operation.sessionDuration ?? void 0
|
|
3074
|
+
Name: props.operation.permissionSetName,
|
|
3075
|
+
Description: props.operation.description.length > 0 ? props.operation.description : void 0,
|
|
3076
|
+
SessionDuration: props.operation.sessionDuration ?? void 0
|
|
2492
3077
|
})
|
|
2493
3078
|
);
|
|
2494
3079
|
const permissionSetArn = response.PermissionSet?.PermissionSetArn;
|
|
2495
3080
|
if (permissionSetArn == null) {
|
|
2496
3081
|
throw new Error(
|
|
2497
|
-
`CreatePermissionSet for "${operation.permissionSetName}" returned no permission set arn.`
|
|
3082
|
+
`CreatePermissionSet for "${props.operation.permissionSetName}" returned no permission set arn.`
|
|
2498
3083
|
);
|
|
2499
3084
|
}
|
|
2500
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3085
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2501
3086
|
return upsertIdcPermissionSetInWorkingState({
|
|
2502
3087
|
workingState: props.state,
|
|
2503
3088
|
permissionSet: {
|
|
2504
3089
|
permissionSetArn,
|
|
2505
|
-
name: operation.permissionSetName,
|
|
2506
|
-
description: operation.description,
|
|
2507
|
-
sessionDuration: operation.sessionDuration,
|
|
3090
|
+
name: props.operation.permissionSetName,
|
|
3091
|
+
description: props.operation.description,
|
|
3092
|
+
sessionDuration: props.operation.sessionDuration,
|
|
2508
3093
|
inlinePolicy: null,
|
|
2509
3094
|
awsManagedPolicies: [],
|
|
2510
|
-
customerManagedPolicies: []
|
|
3095
|
+
customerManagedPolicies: [],
|
|
3096
|
+
permissionsBoundary: null
|
|
2511
3097
|
}
|
|
2512
3098
|
});
|
|
2513
3099
|
}
|
|
2514
|
-
if (operation.kind === "updateIdcPermissionSetDescription") {
|
|
3100
|
+
if (props.operation.kind === "updateIdcPermissionSetDescription") {
|
|
2515
3101
|
const permissionSet = resolvePermissionSetByName({
|
|
2516
3102
|
state: props.state,
|
|
2517
|
-
permissionSetName: operation.permissionSetName
|
|
3103
|
+
permissionSetName: props.operation.permissionSetName
|
|
2518
3104
|
});
|
|
2519
3105
|
props.logger.log(
|
|
2520
|
-
`Updating IdC permission set description for "${operation.permissionSetName}"...`
|
|
3106
|
+
`Updating IdC permission set description for "${props.operation.permissionSetName}"...`
|
|
2521
3107
|
);
|
|
2522
3108
|
await props.ssoAdminClient.send(
|
|
2523
3109
|
new UpdatePermissionSetCommand({
|
|
2524
3110
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2525
3111
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2526
|
-
Description: operation.description.trim().length > 0 ? operation.description : void 0
|
|
3112
|
+
Description: props.operation.description.trim().length > 0 ? props.operation.description : void 0
|
|
2527
3113
|
})
|
|
2528
3114
|
);
|
|
2529
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3115
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2530
3116
|
return upsertIdcPermissionSetInWorkingState({
|
|
2531
3117
|
workingState: props.state,
|
|
2532
3118
|
permissionSet: {
|
|
2533
3119
|
...permissionSet,
|
|
2534
|
-
description: operation.description
|
|
3120
|
+
description: props.operation.description
|
|
2535
3121
|
}
|
|
2536
3122
|
});
|
|
2537
3123
|
}
|
|
2538
|
-
if (operation.kind === "updateIdcPermissionSetSessionDuration") {
|
|
3124
|
+
if (props.operation.kind === "updateIdcPermissionSetSessionDuration") {
|
|
2539
3125
|
const permissionSet = resolvePermissionSetByName({
|
|
2540
3126
|
state: props.state,
|
|
2541
|
-
permissionSetName: operation.permissionSetName
|
|
3127
|
+
permissionSetName: props.operation.permissionSetName
|
|
2542
3128
|
});
|
|
2543
3129
|
props.logger.log(
|
|
2544
|
-
`Updating IdC permission set session duration for "${operation.permissionSetName}"...`
|
|
3130
|
+
`Updating IdC permission set session duration for "${props.operation.permissionSetName}"...`
|
|
2545
3131
|
);
|
|
2546
3132
|
await props.ssoAdminClient.send(
|
|
2547
3133
|
new UpdatePermissionSetCommand({
|
|
2548
3134
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2549
3135
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2550
|
-
SessionDuration: operation.sessionDuration ?? void 0
|
|
3136
|
+
SessionDuration: props.operation.sessionDuration ?? void 0
|
|
2551
3137
|
})
|
|
2552
3138
|
);
|
|
2553
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3139
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2554
3140
|
return upsertIdcPermissionSetInWorkingState({
|
|
2555
3141
|
workingState: props.state,
|
|
2556
3142
|
permissionSet: {
|
|
2557
3143
|
...permissionSet,
|
|
2558
|
-
sessionDuration: operation.sessionDuration
|
|
3144
|
+
sessionDuration: props.operation.sessionDuration
|
|
2559
3145
|
}
|
|
2560
3146
|
});
|
|
2561
3147
|
}
|
|
2562
|
-
if (operation.kind === "deleteIdcPermissionSet") {
|
|
3148
|
+
if (props.operation.kind === "deleteIdcPermissionSet") {
|
|
2563
3149
|
const permissionSet = resolvePermissionSetByName({
|
|
2564
3150
|
state: props.state,
|
|
2565
|
-
permissionSetName: operation.permissionSetName
|
|
3151
|
+
permissionSetName: props.operation.permissionSetName
|
|
2566
3152
|
});
|
|
2567
3153
|
props.logger.log(
|
|
2568
|
-
`Deleting IdC permission set "${operation.permissionSetName}"...`
|
|
3154
|
+
`Deleting IdC permission set "${props.operation.permissionSetName}"...`
|
|
2569
3155
|
);
|
|
2570
3156
|
await props.ssoAdminClient.send(
|
|
2571
3157
|
new DeletePermissionSetCommand({
|
|
@@ -2573,44 +3159,45 @@ async function executeOperation(props) {
|
|
|
2573
3159
|
PermissionSetArn: permissionSet.permissionSetArn
|
|
2574
3160
|
})
|
|
2575
3161
|
);
|
|
2576
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3162
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2577
3163
|
return removeIdcPermissionSetFromWorkingState({
|
|
2578
3164
|
workingState: props.state,
|
|
2579
|
-
permissionSetName: operation.permissionSetName
|
|
3165
|
+
permissionSetName: props.operation.permissionSetName
|
|
2580
3166
|
});
|
|
2581
3167
|
}
|
|
2582
|
-
if (operation.kind === "putIdcPermissionSetInlinePolicy") {
|
|
3168
|
+
if (props.operation.kind === "putIdcPermissionSetInlinePolicy") {
|
|
3169
|
+
const { inlinePolicy } = props.operation;
|
|
2583
3170
|
const permissionSet = resolvePermissionSetByName({
|
|
2584
3171
|
state: props.state,
|
|
2585
|
-
permissionSetName: operation.permissionSetName
|
|
3172
|
+
permissionSetName: props.operation.permissionSetName
|
|
2586
3173
|
});
|
|
2587
3174
|
props.logger.log(
|
|
2588
|
-
`Putting inline policy on IdC permission set "${operation.permissionSetName}"...`
|
|
3175
|
+
`Putting inline policy on IdC permission set "${props.operation.permissionSetName}"...`
|
|
2589
3176
|
);
|
|
2590
3177
|
await props.ssoAdminClient.send(
|
|
2591
3178
|
new PutInlinePolicyToPermissionSetCommand({
|
|
2592
3179
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2593
3180
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2594
|
-
InlinePolicy:
|
|
3181
|
+
InlinePolicy: inlinePolicy
|
|
2595
3182
|
})
|
|
2596
3183
|
);
|
|
2597
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3184
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2598
3185
|
return upsertPermissionSetPolicyState({
|
|
2599
3186
|
state: props.state,
|
|
2600
|
-
permissionSetName: operation.permissionSetName,
|
|
3187
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2601
3188
|
update: (currentPermissionSet) => ({
|
|
2602
3189
|
...currentPermissionSet,
|
|
2603
|
-
inlinePolicy
|
|
3190
|
+
inlinePolicy
|
|
2604
3191
|
})
|
|
2605
3192
|
});
|
|
2606
3193
|
}
|
|
2607
|
-
if (operation.kind === "deleteIdcPermissionSetInlinePolicy") {
|
|
3194
|
+
if (props.operation.kind === "deleteIdcPermissionSetInlinePolicy") {
|
|
2608
3195
|
const permissionSet = resolvePermissionSetByName({
|
|
2609
3196
|
state: props.state,
|
|
2610
|
-
permissionSetName: operation.permissionSetName
|
|
3197
|
+
permissionSetName: props.operation.permissionSetName
|
|
2611
3198
|
});
|
|
2612
3199
|
props.logger.log(
|
|
2613
|
-
`Deleting inline policy from IdC permission set "${operation.permissionSetName}"...`
|
|
3200
|
+
`Deleting inline policy from IdC permission set "${props.operation.permissionSetName}"...`
|
|
2614
3201
|
);
|
|
2615
3202
|
await props.ssoAdminClient.send(
|
|
2616
3203
|
new DeleteInlinePolicyFromPermissionSetCommand({
|
|
@@ -2618,154 +3205,158 @@ async function executeOperation(props) {
|
|
|
2618
3205
|
PermissionSetArn: permissionSet.permissionSetArn
|
|
2619
3206
|
})
|
|
2620
3207
|
);
|
|
2621
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3208
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2622
3209
|
return upsertPermissionSetPolicyState({
|
|
2623
3210
|
state: props.state,
|
|
2624
|
-
permissionSetName: operation.permissionSetName,
|
|
3211
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2625
3212
|
update: (currentPermissionSet) => ({
|
|
2626
3213
|
...currentPermissionSet,
|
|
2627
3214
|
inlinePolicy: null
|
|
2628
3215
|
})
|
|
2629
3216
|
});
|
|
2630
3217
|
}
|
|
2631
|
-
if (operation.kind === "attachIdcManagedPolicyToPermissionSet") {
|
|
3218
|
+
if (props.operation.kind === "attachIdcManagedPolicyToPermissionSet") {
|
|
3219
|
+
const { managedPolicyArn } = props.operation;
|
|
2632
3220
|
const permissionSet = resolvePermissionSetByName({
|
|
2633
3221
|
state: props.state,
|
|
2634
|
-
permissionSetName: operation.permissionSetName
|
|
3222
|
+
permissionSetName: props.operation.permissionSetName
|
|
2635
3223
|
});
|
|
2636
3224
|
props.logger.log(
|
|
2637
|
-
`Attaching managed policy "${
|
|
3225
|
+
`Attaching managed policy "${managedPolicyArn}" to IdC permission set "${props.operation.permissionSetName}"...`
|
|
2638
3226
|
);
|
|
2639
3227
|
await props.ssoAdminClient.send(
|
|
2640
3228
|
new AttachManagedPolicyToPermissionSetCommand({
|
|
2641
3229
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2642
3230
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2643
|
-
ManagedPolicyArn:
|
|
3231
|
+
ManagedPolicyArn: managedPolicyArn
|
|
2644
3232
|
})
|
|
2645
3233
|
);
|
|
2646
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3234
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2647
3235
|
return upsertPermissionSetPolicyState({
|
|
2648
3236
|
state: props.state,
|
|
2649
|
-
permissionSetName: operation.permissionSetName,
|
|
3237
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2650
3238
|
update: (currentPermissionSet) => ({
|
|
2651
3239
|
...currentPermissionSet,
|
|
2652
3240
|
awsManagedPolicies: [
|
|
2653
3241
|
...currentPermissionSet.awsManagedPolicies,
|
|
2654
|
-
|
|
3242
|
+
managedPolicyArn
|
|
2655
3243
|
]
|
|
2656
3244
|
})
|
|
2657
3245
|
});
|
|
2658
3246
|
}
|
|
2659
|
-
if (operation.kind === "detachIdcManagedPolicyFromPermissionSet") {
|
|
3247
|
+
if (props.operation.kind === "detachIdcManagedPolicyFromPermissionSet") {
|
|
3248
|
+
const { managedPolicyArn } = props.operation;
|
|
2660
3249
|
const permissionSet = resolvePermissionSetByName({
|
|
2661
3250
|
state: props.state,
|
|
2662
|
-
permissionSetName: operation.permissionSetName
|
|
3251
|
+
permissionSetName: props.operation.permissionSetName
|
|
2663
3252
|
});
|
|
2664
3253
|
props.logger.log(
|
|
2665
|
-
`Detaching managed policy "${
|
|
3254
|
+
`Detaching managed policy "${managedPolicyArn}" from IdC permission set "${props.operation.permissionSetName}"...`
|
|
2666
3255
|
);
|
|
2667
3256
|
await props.ssoAdminClient.send(
|
|
2668
3257
|
new DetachManagedPolicyFromPermissionSetCommand({
|
|
2669
3258
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2670
3259
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2671
|
-
ManagedPolicyArn:
|
|
3260
|
+
ManagedPolicyArn: managedPolicyArn
|
|
2672
3261
|
})
|
|
2673
3262
|
);
|
|
2674
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3263
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2675
3264
|
return upsertPermissionSetPolicyState({
|
|
2676
3265
|
state: props.state,
|
|
2677
|
-
permissionSetName: operation.permissionSetName,
|
|
3266
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2678
3267
|
update: (currentPermissionSet) => ({
|
|
2679
3268
|
...currentPermissionSet,
|
|
2680
3269
|
awsManagedPolicies: currentPermissionSet.awsManagedPolicies.filter(
|
|
2681
|
-
(
|
|
3270
|
+
(arn) => arn !== managedPolicyArn
|
|
2682
3271
|
)
|
|
2683
3272
|
})
|
|
2684
3273
|
});
|
|
2685
3274
|
}
|
|
2686
|
-
if (operation.kind === "attachIdcCustomerManagedPolicyReferenceToPermissionSet") {
|
|
3275
|
+
if (props.operation.kind === "attachIdcCustomerManagedPolicyReferenceToPermissionSet") {
|
|
3276
|
+
const { customerManagedPolicyName, customerManagedPolicyPath } = props.operation;
|
|
2687
3277
|
const permissionSet = resolvePermissionSetByName({
|
|
2688
3278
|
state: props.state,
|
|
2689
|
-
permissionSetName: operation.permissionSetName
|
|
3279
|
+
permissionSetName: props.operation.permissionSetName
|
|
2690
3280
|
});
|
|
2691
3281
|
props.logger.log(
|
|
2692
|
-
`Attaching customer-managed policy "${
|
|
3282
|
+
`Attaching customer-managed policy "${customerManagedPolicyPath}${customerManagedPolicyName}" to IdC permission set "${props.operation.permissionSetName}"...`
|
|
2693
3283
|
);
|
|
2694
3284
|
await props.ssoAdminClient.send(
|
|
2695
3285
|
new AttachCustomerManagedPolicyReferenceToPermissionSetCommand({
|
|
2696
3286
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2697
3287
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2698
3288
|
CustomerManagedPolicyReference: {
|
|
2699
|
-
Name:
|
|
2700
|
-
Path:
|
|
3289
|
+
Name: customerManagedPolicyName,
|
|
3290
|
+
Path: customerManagedPolicyPath
|
|
2701
3291
|
}
|
|
2702
3292
|
})
|
|
2703
3293
|
);
|
|
2704
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3294
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2705
3295
|
return upsertPermissionSetPolicyState({
|
|
2706
3296
|
state: props.state,
|
|
2707
|
-
permissionSetName: operation.permissionSetName,
|
|
3297
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2708
3298
|
update: (currentPermissionSet) => ({
|
|
2709
3299
|
...currentPermissionSet,
|
|
2710
3300
|
customerManagedPolicies: [
|
|
2711
3301
|
...currentPermissionSet.customerManagedPolicies,
|
|
2712
3302
|
{
|
|
2713
|
-
name:
|
|
2714
|
-
path:
|
|
3303
|
+
name: customerManagedPolicyName,
|
|
3304
|
+
path: customerManagedPolicyPath
|
|
2715
3305
|
}
|
|
2716
3306
|
]
|
|
2717
3307
|
})
|
|
2718
3308
|
});
|
|
2719
3309
|
}
|
|
2720
|
-
if (operation.kind === "detachIdcCustomerManagedPolicyReferenceFromPermissionSet") {
|
|
3310
|
+
if (props.operation.kind === "detachIdcCustomerManagedPolicyReferenceFromPermissionSet") {
|
|
3311
|
+
const { customerManagedPolicyName, customerManagedPolicyPath } = props.operation;
|
|
2721
3312
|
const permissionSet = resolvePermissionSetByName({
|
|
2722
3313
|
state: props.state,
|
|
2723
|
-
permissionSetName: operation.permissionSetName
|
|
3314
|
+
permissionSetName: props.operation.permissionSetName
|
|
2724
3315
|
});
|
|
2725
3316
|
props.logger.log(
|
|
2726
|
-
`Detaching customer-managed policy "${
|
|
3317
|
+
`Detaching customer-managed policy "${customerManagedPolicyPath}${customerManagedPolicyName}" from IdC permission set "${props.operation.permissionSetName}"...`
|
|
2727
3318
|
);
|
|
2728
3319
|
await props.ssoAdminClient.send(
|
|
2729
3320
|
new DetachCustomerManagedPolicyReferenceFromPermissionSetCommand({
|
|
2730
3321
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2731
3322
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2732
3323
|
CustomerManagedPolicyReference: {
|
|
2733
|
-
Name:
|
|
2734
|
-
Path:
|
|
3324
|
+
Name: customerManagedPolicyName,
|
|
3325
|
+
Path: customerManagedPolicyPath
|
|
2735
3326
|
}
|
|
2736
3327
|
})
|
|
2737
3328
|
);
|
|
2738
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3329
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2739
3330
|
return upsertPermissionSetPolicyState({
|
|
2740
3331
|
state: props.state,
|
|
2741
|
-
permissionSetName: operation.permissionSetName,
|
|
3332
|
+
permissionSetName: props.operation.permissionSetName,
|
|
2742
3333
|
update: (currentPermissionSet) => ({
|
|
2743
3334
|
...currentPermissionSet,
|
|
2744
3335
|
customerManagedPolicies: currentPermissionSet.customerManagedPolicies.filter(
|
|
2745
|
-
(
|
|
3336
|
+
(policy) => policy.name !== customerManagedPolicyName || policy.path !== customerManagedPolicyPath
|
|
2746
3337
|
)
|
|
2747
3338
|
})
|
|
2748
3339
|
});
|
|
2749
3340
|
}
|
|
2750
|
-
if (operation.kind === "provisionIdcPermissionSet") {
|
|
3341
|
+
if (props.operation.kind === "provisionIdcPermissionSet") {
|
|
2751
3342
|
const permissionSet = resolvePermissionSetByName({
|
|
2752
3343
|
state: props.state,
|
|
2753
|
-
permissionSetName: operation.permissionSetName
|
|
3344
|
+
permissionSetName: props.operation.permissionSetName
|
|
2754
3345
|
});
|
|
2755
3346
|
props.logger.log(
|
|
2756
|
-
`Provisioning IdC permission set "${operation.permissionSetName}" to all provisioned accounts...`
|
|
3347
|
+
`Provisioning IdC permission set "${props.operation.permissionSetName}" to all provisioned accounts...`
|
|
2757
3348
|
);
|
|
2758
3349
|
const response = await props.ssoAdminClient.send(
|
|
2759
3350
|
new ProvisionPermissionSetCommand({
|
|
2760
3351
|
InstanceArn: props.state.identityCenter.instanceArn,
|
|
2761
3352
|
PermissionSetArn: permissionSet.permissionSetArn,
|
|
2762
|
-
TargetType: operation.targetScope
|
|
3353
|
+
TargetType: props.operation.targetScope
|
|
2763
3354
|
})
|
|
2764
3355
|
);
|
|
2765
3356
|
const requestId = response.PermissionSetProvisioningStatus?.RequestId ?? void 0;
|
|
2766
3357
|
if (requestId == null) {
|
|
2767
3358
|
throw new Error(
|
|
2768
|
-
`ProvisionPermissionSet for "${operation.permissionSetName}" returned no request id.`
|
|
3359
|
+
`ProvisionPermissionSet for "${props.operation.permissionSetName}" returned no request id.`
|
|
2769
3360
|
);
|
|
2770
3361
|
}
|
|
2771
3362
|
await waitForPermissionSetProvisioningSuccess({
|
|
@@ -2775,16 +3366,63 @@ async function executeOperation(props) {
|
|
|
2775
3366
|
requestId,
|
|
2776
3367
|
timeoutInMs: props.runtime.permissionSetProvisioning.timeoutInMs,
|
|
2777
3368
|
pollIntervalInMs: props.runtime.permissionSetProvisioning.pollIntervalInMs,
|
|
2778
|
-
operationLabel: `"${operation.permissionSetName}"`
|
|
3369
|
+
operationLabel: `"${props.operation.permissionSetName}"`
|
|
2779
3370
|
});
|
|
2780
|
-
props.logger.log(`Done: "${operation.permissionSetName}"`);
|
|
3371
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
2781
3372
|
return props.state;
|
|
2782
3373
|
}
|
|
2783
|
-
if (operation.kind === "
|
|
3374
|
+
if (props.operation.kind === "putIdcPermissionSetPermissionsBoundary") {
|
|
3375
|
+
const permissionSet = resolvePermissionSetByName({
|
|
3376
|
+
state: props.state,
|
|
3377
|
+
permissionSetName: props.operation.permissionSetName
|
|
3378
|
+
});
|
|
3379
|
+
props.logger.log(
|
|
3380
|
+
`Putting permissions boundary on IdC permission set "${props.operation.permissionSetName}"...`
|
|
3381
|
+
);
|
|
3382
|
+
const boundary = props.operation.permissionsBoundary;
|
|
3383
|
+
await props.ssoAdminClient.send(
|
|
3384
|
+
new PutPermissionsBoundaryToPermissionSetCommand({
|
|
3385
|
+
InstanceArn: props.state.identityCenter.instanceArn,
|
|
3386
|
+
PermissionSetArn: permissionSet.permissionSetArn,
|
|
3387
|
+
PermissionsBoundary: "managedPolicyArn" in boundary ? { ManagedPolicyArn: boundary.managedPolicyArn } : {
|
|
3388
|
+
CustomerManagedPolicyReference: {
|
|
3389
|
+
Name: boundary.customerManagedPolicyName,
|
|
3390
|
+
Path: boundary.customerManagedPolicyPath
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
})
|
|
3394
|
+
);
|
|
3395
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
3396
|
+
return upsertIdcPermissionSetInWorkingState({
|
|
3397
|
+
workingState: props.state,
|
|
3398
|
+
permissionSet: { ...permissionSet, permissionsBoundary: boundary }
|
|
3399
|
+
});
|
|
3400
|
+
}
|
|
3401
|
+
if (props.operation.kind === "deleteIdcPermissionSetPermissionsBoundary") {
|
|
3402
|
+
const permissionSet = resolvePermissionSetByName({
|
|
3403
|
+
state: props.state,
|
|
3404
|
+
permissionSetName: props.operation.permissionSetName
|
|
3405
|
+
});
|
|
3406
|
+
props.logger.log(
|
|
3407
|
+
`Deleting permissions boundary from IdC permission set "${props.operation.permissionSetName}"...`
|
|
3408
|
+
);
|
|
3409
|
+
await props.ssoAdminClient.send(
|
|
3410
|
+
new DeletePermissionsBoundaryFromPermissionSetCommand({
|
|
3411
|
+
InstanceArn: props.state.identityCenter.instanceArn,
|
|
3412
|
+
PermissionSetArn: permissionSet.permissionSetArn
|
|
3413
|
+
})
|
|
3414
|
+
);
|
|
3415
|
+
props.logger.log(`Done: "${props.operation.permissionSetName}"`);
|
|
3416
|
+
return upsertIdcPermissionSetInWorkingState({
|
|
3417
|
+
workingState: props.state,
|
|
3418
|
+
permissionSet: { ...permissionSet, permissionsBoundary: null }
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3421
|
+
if (props.operation.kind === "removeIdcGroupMembership") {
|
|
2784
3422
|
const resolvedMembership = resolveGroupMembershipDependencies({
|
|
2785
3423
|
state: props.state,
|
|
2786
|
-
groupDisplayName: operation.groupDisplayName,
|
|
2787
|
-
userName: operation.userName
|
|
3424
|
+
groupDisplayName: props.operation.groupDisplayName,
|
|
3425
|
+
userName: props.operation.userName
|
|
2788
3426
|
});
|
|
2789
3427
|
const membershipId = await resolveGroupMembershipId({
|
|
2790
3428
|
state: props.state,
|
|
@@ -2793,7 +3431,7 @@ async function executeOperation(props) {
|
|
|
2793
3431
|
userId: resolvedMembership.userId
|
|
2794
3432
|
});
|
|
2795
3433
|
props.logger.log(
|
|
2796
|
-
`Removing user "${operation.userName}" from IdC group "${operation.groupDisplayName}"...`
|
|
3434
|
+
`Removing user "${props.operation.userName}" from IdC group "${props.operation.groupDisplayName}"...`
|
|
2797
3435
|
);
|
|
2798
3436
|
await props.identityStoreClient.send(
|
|
2799
3437
|
new DeleteGroupMembershipCommand({
|
|
@@ -2802,7 +3440,7 @@ async function executeOperation(props) {
|
|
|
2802
3440
|
})
|
|
2803
3441
|
);
|
|
2804
3442
|
props.logger.log(
|
|
2805
|
-
`Done: user "${operation.userName}" x group "${operation.groupDisplayName}"`
|
|
3443
|
+
`Done: user "${props.operation.userName}" x group "${props.operation.groupDisplayName}"`
|
|
2806
3444
|
);
|
|
2807
3445
|
return removeGroupMembershipFromWorkingState({
|
|
2808
3446
|
workingState: props.state,
|
|
@@ -2812,21 +3450,21 @@ async function executeOperation(props) {
|
|
|
2812
3450
|
}
|
|
2813
3451
|
});
|
|
2814
3452
|
}
|
|
2815
|
-
if (operation.kind === "grantIdcAccountAssignment") {
|
|
3453
|
+
if (props.operation.kind === "grantIdcAccountAssignment") {
|
|
2816
3454
|
const resolvedAssignment = resolveAssignmentDependencies({
|
|
2817
3455
|
state: props.state,
|
|
2818
|
-
accountName: operation.accountName,
|
|
2819
|
-
permissionSetName: operation.permissionSetName,
|
|
2820
|
-
principalType: operation.principalType,
|
|
2821
|
-
principalName: operation.principalName
|
|
3456
|
+
accountName: props.operation.accountName,
|
|
3457
|
+
permissionSetName: props.operation.permissionSetName,
|
|
3458
|
+
principalType: props.operation.principalType,
|
|
3459
|
+
principalName: props.operation.principalName
|
|
2822
3460
|
});
|
|
2823
3461
|
props.logger.log(
|
|
2824
|
-
`Granting IdC assignment "${operation.permissionSetName}" to ${formatPrincipalLabel(
|
|
3462
|
+
`Granting IdC assignment "${props.operation.permissionSetName}" to ${formatPrincipalLabel(
|
|
2825
3463
|
{
|
|
2826
|
-
principalType: operation.principalType,
|
|
2827
|
-
principalName: operation.principalName
|
|
3464
|
+
principalType: props.operation.principalType,
|
|
3465
|
+
principalName: props.operation.principalName
|
|
2828
3466
|
}
|
|
2829
|
-
)} on "${operation.accountName}"...`
|
|
3467
|
+
)} on "${props.operation.accountName}"...`
|
|
2830
3468
|
);
|
|
2831
3469
|
const response = await props.ssoAdminClient.send(
|
|
2832
3470
|
new CreateAccountAssignmentCommand({
|
|
@@ -2841,7 +3479,7 @@ async function executeOperation(props) {
|
|
|
2841
3479
|
const requestId = response.AccountAssignmentCreationStatus?.RequestId;
|
|
2842
3480
|
if (requestId == null) {
|
|
2843
3481
|
throw new Error(
|
|
2844
|
-
`CreateAccountAssignment for "${operation.permissionSetName}" on "${operation.accountName}" returned no request id.`
|
|
3482
|
+
`CreateAccountAssignment for "${props.operation.permissionSetName}" on "${props.operation.accountName}" returned no request id.`
|
|
2845
3483
|
);
|
|
2846
3484
|
}
|
|
2847
3485
|
await waitForAccountAssignmentCreationSuccess({
|
|
@@ -2851,10 +3489,10 @@ async function executeOperation(props) {
|
|
|
2851
3489
|
requestId,
|
|
2852
3490
|
timeoutInMs: props.runtime.accountAssignment.timeoutInMs,
|
|
2853
3491
|
pollIntervalInMs: props.runtime.accountAssignment.pollIntervalInMs,
|
|
2854
|
-
operationLabel: `"${operation.permissionSetName}" on "${operation.accountName}"`
|
|
3492
|
+
operationLabel: `"${props.operation.permissionSetName}" on "${props.operation.accountName}"`
|
|
2855
3493
|
});
|
|
2856
3494
|
props.logger.log(
|
|
2857
|
-
`Done: "${operation.permissionSetName}" -> "${operation.accountName}"`
|
|
3495
|
+
`Done: "${props.operation.permissionSetName}" -> "${props.operation.accountName}"`
|
|
2858
3496
|
);
|
|
2859
3497
|
return addAccountAssignmentToWorkingState({
|
|
2860
3498
|
workingState: props.state,
|
|
@@ -2866,21 +3504,21 @@ async function executeOperation(props) {
|
|
|
2866
3504
|
}
|
|
2867
3505
|
});
|
|
2868
3506
|
}
|
|
2869
|
-
if (operation.kind === "revokeIdcAccountAssignment") {
|
|
3507
|
+
if (props.operation.kind === "revokeIdcAccountAssignment") {
|
|
2870
3508
|
const resolvedAssignment = resolveAssignmentDependencies({
|
|
2871
3509
|
state: props.state,
|
|
2872
|
-
accountName: operation.accountName,
|
|
2873
|
-
permissionSetName: operation.permissionSetName,
|
|
2874
|
-
principalType: operation.principalType,
|
|
2875
|
-
principalName: operation.principalName
|
|
3510
|
+
accountName: props.operation.accountName,
|
|
3511
|
+
permissionSetName: props.operation.permissionSetName,
|
|
3512
|
+
principalType: props.operation.principalType,
|
|
3513
|
+
principalName: props.operation.principalName
|
|
2876
3514
|
});
|
|
2877
3515
|
props.logger.log(
|
|
2878
|
-
`Revoking IdC assignment "${operation.permissionSetName}" from ${formatPrincipalLabel(
|
|
3516
|
+
`Revoking IdC assignment "${props.operation.permissionSetName}" from ${formatPrincipalLabel(
|
|
2879
3517
|
{
|
|
2880
|
-
principalType: operation.principalType,
|
|
2881
|
-
principalName: operation.principalName
|
|
3518
|
+
principalType: props.operation.principalType,
|
|
3519
|
+
principalName: props.operation.principalName
|
|
2882
3520
|
}
|
|
2883
|
-
)} on "${operation.accountName}"...`
|
|
3521
|
+
)} on "${props.operation.accountName}"...`
|
|
2884
3522
|
);
|
|
2885
3523
|
const response = await props.ssoAdminClient.send(
|
|
2886
3524
|
new DeleteAccountAssignmentCommand({
|
|
@@ -2895,7 +3533,7 @@ async function executeOperation(props) {
|
|
|
2895
3533
|
const requestId = response.AccountAssignmentDeletionStatus?.RequestId;
|
|
2896
3534
|
if (requestId == null) {
|
|
2897
3535
|
throw new Error(
|
|
2898
|
-
`DeleteAccountAssignment for "${operation.permissionSetName}" on "${operation.accountName}" returned no request id.`
|
|
3536
|
+
`DeleteAccountAssignment for "${props.operation.permissionSetName}" on "${props.operation.accountName}" returned no request id.`
|
|
2899
3537
|
);
|
|
2900
3538
|
}
|
|
2901
3539
|
await waitForAccountAssignmentDeletionSuccess({
|
|
@@ -2905,10 +3543,10 @@ async function executeOperation(props) {
|
|
|
2905
3543
|
requestId,
|
|
2906
3544
|
timeoutInMs: props.runtime.accountAssignment.timeoutInMs,
|
|
2907
3545
|
pollIntervalInMs: props.runtime.accountAssignment.pollIntervalInMs,
|
|
2908
|
-
operationLabel: `"${operation.permissionSetName}" on "${operation.accountName}"`
|
|
3546
|
+
operationLabel: `"${props.operation.permissionSetName}" on "${props.operation.accountName}"`
|
|
2909
3547
|
});
|
|
2910
3548
|
props.logger.log(
|
|
2911
|
-
`Done: "${operation.permissionSetName}" x "${operation.accountName}"`
|
|
3549
|
+
`Done: "${props.operation.permissionSetName}" x "${props.operation.accountName}"`
|
|
2912
3550
|
);
|
|
2913
3551
|
return removeAccountAssignmentFromWorkingState({
|
|
2914
3552
|
workingState: props.state,
|
|
@@ -2920,7 +3558,271 @@ async function executeOperation(props) {
|
|
|
2920
3558
|
}
|
|
2921
3559
|
});
|
|
2922
3560
|
}
|
|
2923
|
-
|
|
3561
|
+
if (props.operation.kind === "createOrgPolicy") {
|
|
3562
|
+
props.logger.log(
|
|
3563
|
+
`Creating org policy "${props.operation.policyName}" (${props.operation.policyType})...`
|
|
3564
|
+
);
|
|
3565
|
+
const response = await props.organizationsClient.send(
|
|
3566
|
+
new CreatePolicyCommand({
|
|
3567
|
+
Name: props.operation.policyName,
|
|
3568
|
+
Description: props.operation.description.length > 0 ? props.operation.description : void 0,
|
|
3569
|
+
Content: props.operation.content,
|
|
3570
|
+
Type: props.operation.policyType
|
|
3571
|
+
})
|
|
3572
|
+
);
|
|
3573
|
+
const policy = response.Policy?.PolicySummary;
|
|
3574
|
+
if (policy?.Id == null || policy.Arn == null) {
|
|
3575
|
+
throw new Error(
|
|
3576
|
+
`CreatePolicy for "${props.operation.policyName}" returned incomplete data.`
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
props.logger.log(`Done: "${props.operation.policyName}"`);
|
|
3580
|
+
return upsertOrgPolicyInWorkingState({
|
|
3581
|
+
workingState: props.state,
|
|
3582
|
+
policy: {
|
|
3583
|
+
id: policy.Id,
|
|
3584
|
+
arn: policy.Arn,
|
|
3585
|
+
name: props.operation.policyName,
|
|
3586
|
+
description: props.operation.description,
|
|
3587
|
+
type: props.operation.policyType,
|
|
3588
|
+
content: props.operation.content
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
if (props.operation.kind === "updateOrgPolicyContent") {
|
|
3593
|
+
props.logger.log(
|
|
3594
|
+
`Updating org policy content "${props.operation.policyName}"...`
|
|
3595
|
+
);
|
|
3596
|
+
await props.organizationsClient.send(
|
|
3597
|
+
new UpdatePolicyCommand({
|
|
3598
|
+
PolicyId: props.operation.policyId,
|
|
3599
|
+
Content: props.operation.content
|
|
3600
|
+
})
|
|
3601
|
+
);
|
|
3602
|
+
props.logger.log(`Done: "${props.operation.policyName}"`);
|
|
3603
|
+
const currentPolicy = props.state.organization.policiesById[props.operation.policyId];
|
|
3604
|
+
if (currentPolicy == null) {
|
|
3605
|
+
return props.state;
|
|
3606
|
+
}
|
|
3607
|
+
return upsertOrgPolicyInWorkingState({
|
|
3608
|
+
workingState: props.state,
|
|
3609
|
+
policy: { ...currentPolicy, content: props.operation.content }
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
if (props.operation.kind === "updateOrgPolicyDescription") {
|
|
3613
|
+
props.logger.log(
|
|
3614
|
+
`Updating org policy description "${props.operation.policyName}"...`
|
|
3615
|
+
);
|
|
3616
|
+
await props.organizationsClient.send(
|
|
3617
|
+
new UpdatePolicyCommand({
|
|
3618
|
+
PolicyId: props.operation.policyId,
|
|
3619
|
+
Description: props.operation.description
|
|
3620
|
+
})
|
|
3621
|
+
);
|
|
3622
|
+
props.logger.log(`Done: "${props.operation.policyName}"`);
|
|
3623
|
+
const currentPolicy = props.state.organization.policiesById[props.operation.policyId];
|
|
3624
|
+
if (currentPolicy == null) {
|
|
3625
|
+
return props.state;
|
|
3626
|
+
}
|
|
3627
|
+
return upsertOrgPolicyInWorkingState({
|
|
3628
|
+
workingState: props.state,
|
|
3629
|
+
policy: { ...currentPolicy, description: props.operation.description }
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
if (props.operation.kind === "attachOrgPolicy") {
|
|
3633
|
+
props.logger.log(
|
|
3634
|
+
`Attaching org policy "${props.operation.policyName}" to "${props.operation.targetName}"...`
|
|
3635
|
+
);
|
|
3636
|
+
const resolvedPolicyId = resolvePolicyId({
|
|
3637
|
+
state: props.state,
|
|
3638
|
+
policyId: props.operation.policyId,
|
|
3639
|
+
policyName: props.operation.policyName
|
|
3640
|
+
});
|
|
3641
|
+
await props.organizationsClient.send(
|
|
3642
|
+
new AttachPolicyCommand({
|
|
3643
|
+
PolicyId: resolvedPolicyId,
|
|
3644
|
+
TargetId: props.operation.targetId
|
|
3645
|
+
})
|
|
3646
|
+
);
|
|
3647
|
+
props.logger.log(
|
|
3648
|
+
`Done: "${props.operation.policyName}" -> "${props.operation.targetName}"`
|
|
3649
|
+
);
|
|
3650
|
+
const targetType = props.operation.targetId === props.context.organization.rootId ? "ROOT" : props.state.organization.organizationalUnitsById[props.operation.targetId] != null ? "ORGANIZATIONAL_UNIT" : "ACCOUNT";
|
|
3651
|
+
return addOrgPolicyAttachmentToWorkingState({
|
|
3652
|
+
workingState: props.state,
|
|
3653
|
+
attachment: {
|
|
3654
|
+
policyId: resolvedPolicyId,
|
|
3655
|
+
targetId: props.operation.targetId,
|
|
3656
|
+
targetType
|
|
3657
|
+
}
|
|
3658
|
+
});
|
|
3659
|
+
}
|
|
3660
|
+
if (props.operation.kind === "detachOrgPolicy") {
|
|
3661
|
+
props.logger.log(
|
|
3662
|
+
`Detaching org policy "${props.operation.policyName}" from "${props.operation.targetName}"...`
|
|
3663
|
+
);
|
|
3664
|
+
await props.organizationsClient.send(
|
|
3665
|
+
new DetachPolicyCommand({
|
|
3666
|
+
PolicyId: props.operation.policyId,
|
|
3667
|
+
TargetId: props.operation.targetId
|
|
3668
|
+
})
|
|
3669
|
+
);
|
|
3670
|
+
props.logger.log(
|
|
3671
|
+
`Done: "${props.operation.policyName}" x "${props.operation.targetName}"`
|
|
3672
|
+
);
|
|
3673
|
+
return removeOrgPolicyAttachmentFromWorkingState({
|
|
3674
|
+
workingState: props.state,
|
|
3675
|
+
policyId: props.operation.policyId,
|
|
3676
|
+
targetId: props.operation.targetId
|
|
3677
|
+
});
|
|
3678
|
+
}
|
|
3679
|
+
if (props.operation.kind === "deleteOrgPolicy") {
|
|
3680
|
+
props.logger.log(`Deleting org policy "${props.operation.policyName}"...`);
|
|
3681
|
+
await props.organizationsClient.send(
|
|
3682
|
+
new DeletePolicyCommand({ PolicyId: props.operation.policyId })
|
|
3683
|
+
);
|
|
3684
|
+
props.logger.log(`Done: "${props.operation.policyName}"`);
|
|
3685
|
+
return removeOrgPolicyFromWorkingState({
|
|
3686
|
+
workingState: props.state,
|
|
3687
|
+
policyId: props.operation.policyId
|
|
3688
|
+
});
|
|
3689
|
+
}
|
|
3690
|
+
if (props.operation.kind === "putAlternateContact") {
|
|
3691
|
+
const { contactType } = props.operation;
|
|
3692
|
+
props.logger.log(
|
|
3693
|
+
`Setting ${contactType} alternate contact for "${props.operation.accountName}" (${props.operation.accountId})...`
|
|
3694
|
+
);
|
|
3695
|
+
await props.accountClient.send(
|
|
3696
|
+
new PutAlternateContactCommand({
|
|
3697
|
+
AccountId: props.operation.accountId,
|
|
3698
|
+
AlternateContactType: contactType,
|
|
3699
|
+
Name: props.operation.name,
|
|
3700
|
+
EmailAddress: props.operation.email,
|
|
3701
|
+
PhoneNumber: props.operation.phone,
|
|
3702
|
+
Title: props.operation.title
|
|
3703
|
+
})
|
|
3704
|
+
);
|
|
3705
|
+
props.logger.log(
|
|
3706
|
+
`Done: ${contactType} contact for "${props.operation.accountName}"`
|
|
3707
|
+
);
|
|
3708
|
+
const account = props.state.organization.accountsById[props.operation.accountId];
|
|
3709
|
+
if (account == null) {
|
|
3710
|
+
throw new Error(
|
|
3711
|
+
`Could not resolve account (${props.operation.accountId}) in working state.`
|
|
3712
|
+
);
|
|
3713
|
+
}
|
|
3714
|
+
const updatedContacts = [
|
|
3715
|
+
...(account.alternateContacts ?? []).filter(
|
|
3716
|
+
(c) => c.contactType !== contactType
|
|
3717
|
+
),
|
|
3718
|
+
{
|
|
3719
|
+
contactType,
|
|
3720
|
+
name: props.operation.name,
|
|
3721
|
+
email: props.operation.email,
|
|
3722
|
+
phone: props.operation.phone,
|
|
3723
|
+
title: props.operation.title
|
|
3724
|
+
}
|
|
3725
|
+
];
|
|
3726
|
+
return upsertAccountInWorkingState({
|
|
3727
|
+
workingState: props.state,
|
|
3728
|
+
account: { ...account, alternateContacts: updatedContacts }
|
|
3729
|
+
});
|
|
3730
|
+
}
|
|
3731
|
+
if (props.operation.kind === "deleteAlternateContact") {
|
|
3732
|
+
const { contactType } = props.operation;
|
|
3733
|
+
props.logger.log(
|
|
3734
|
+
`Deleting ${contactType} alternate contact for "${props.operation.accountName}" (${props.operation.accountId})...`
|
|
3735
|
+
);
|
|
3736
|
+
await props.accountClient.send(
|
|
3737
|
+
new DeleteAlternateContactCommand({
|
|
3738
|
+
AccountId: props.operation.accountId,
|
|
3739
|
+
AlternateContactType: contactType
|
|
3740
|
+
})
|
|
3741
|
+
);
|
|
3742
|
+
props.logger.log(
|
|
3743
|
+
`Done: removed ${contactType} contact for "${props.operation.accountName}"`
|
|
3744
|
+
);
|
|
3745
|
+
const account = props.state.organization.accountsById[props.operation.accountId];
|
|
3746
|
+
if (account == null) {
|
|
3747
|
+
throw new Error(
|
|
3748
|
+
`Could not resolve account (${props.operation.accountId}) in working state.`
|
|
3749
|
+
);
|
|
3750
|
+
}
|
|
3751
|
+
return upsertAccountInWorkingState({
|
|
3752
|
+
workingState: props.state,
|
|
3753
|
+
account: {
|
|
3754
|
+
...account,
|
|
3755
|
+
alternateContacts: (account.alternateContacts ?? []).filter(
|
|
3756
|
+
(c) => c.contactType !== contactType
|
|
3757
|
+
)
|
|
3758
|
+
}
|
|
3759
|
+
});
|
|
3760
|
+
}
|
|
3761
|
+
if (props.operation.kind === "setIdcAccessControlAttributes") {
|
|
3762
|
+
props.logger.log(
|
|
3763
|
+
`Setting IdC access control attributes (${props.operation.attributes.length} attribute(s))...`
|
|
3764
|
+
);
|
|
3765
|
+
await props.ssoAdminClient.send(
|
|
3766
|
+
new UpdateInstanceAccessControlAttributeConfigurationCommand({
|
|
3767
|
+
InstanceArn: props.state.identityCenter.instanceArn,
|
|
3768
|
+
InstanceAccessControlAttributeConfiguration: {
|
|
3769
|
+
AccessControlAttributes: props.operation.attributes.map((attr) => ({
|
|
3770
|
+
Key: attr.key,
|
|
3771
|
+
Value: { Source: attr.source }
|
|
3772
|
+
}))
|
|
3773
|
+
}
|
|
3774
|
+
})
|
|
3775
|
+
);
|
|
3776
|
+
props.logger.log(`Done: access control attributes updated`);
|
|
3777
|
+
return {
|
|
3778
|
+
...props.state,
|
|
3779
|
+
identityCenter: {
|
|
3780
|
+
...props.state.identityCenter,
|
|
3781
|
+
accessControlAttributes: props.operation.attributes
|
|
3782
|
+
}
|
|
3783
|
+
};
|
|
3784
|
+
}
|
|
3785
|
+
if (props.operation.kind === "registerDelegatedAdministrator") {
|
|
3786
|
+
props.logger.log(
|
|
3787
|
+
`Registering delegated administrator "${props.operation.accountName}" (${props.operation.accountId}) for ${props.operation.servicePrincipal}...`
|
|
3788
|
+
);
|
|
3789
|
+
await props.organizationsClient.send(
|
|
3790
|
+
new RegisterDelegatedAdministratorCommand({
|
|
3791
|
+
AccountId: props.operation.accountId,
|
|
3792
|
+
ServicePrincipal: props.operation.servicePrincipal
|
|
3793
|
+
})
|
|
3794
|
+
);
|
|
3795
|
+
props.logger.log(
|
|
3796
|
+
`Done: "${props.operation.accountName}" for ${props.operation.servicePrincipal}`
|
|
3797
|
+
);
|
|
3798
|
+
return upsertDelegatedAdministratorInWorkingState({
|
|
3799
|
+
workingState: props.state,
|
|
3800
|
+
delegatedAdministrator: {
|
|
3801
|
+
accountId: props.operation.accountId,
|
|
3802
|
+
servicePrincipal: props.operation.servicePrincipal
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
}
|
|
3806
|
+
if (props.operation.kind === "deregisterDelegatedAdministrator") {
|
|
3807
|
+
props.logger.log(
|
|
3808
|
+
`Deregistering delegated administrator "${props.operation.accountName}" (${props.operation.accountId}) for ${props.operation.servicePrincipal}...`
|
|
3809
|
+
);
|
|
3810
|
+
await props.organizationsClient.send(
|
|
3811
|
+
new DeregisterDelegatedAdministratorCommand({
|
|
3812
|
+
AccountId: props.operation.accountId,
|
|
3813
|
+
ServicePrincipal: props.operation.servicePrincipal
|
|
3814
|
+
})
|
|
3815
|
+
);
|
|
3816
|
+
props.logger.log(
|
|
3817
|
+
`Done: removed "${props.operation.accountName}" for ${props.operation.servicePrincipal}`
|
|
3818
|
+
);
|
|
3819
|
+
return removeDelegatedAdministratorFromWorkingState({
|
|
3820
|
+
workingState: props.state,
|
|
3821
|
+
accountId: props.operation.accountId,
|
|
3822
|
+
servicePrincipal: props.operation.servicePrincipal
|
|
3823
|
+
});
|
|
3824
|
+
}
|
|
3825
|
+
assertUnreachable(props.operation, "Unsupported operation kind in apply.");
|
|
2924
3826
|
}
|
|
2925
3827
|
function resolveAssignmentDependencies(props) {
|
|
2926
3828
|
const account = props.state.organization.accountsByName[props.accountName];
|
|
@@ -2980,6 +3882,16 @@ function resolveGroupByDisplayName(props) {
|
|
|
2980
3882
|
}
|
|
2981
3883
|
return group;
|
|
2982
3884
|
}
|
|
3885
|
+
function resolvePolicyId(props) {
|
|
3886
|
+
if (props.policyId !== "__pending_creation__") return props.policyId;
|
|
3887
|
+
const policy = props.state.organization.policiesByName[props.policyName];
|
|
3888
|
+
if (policy == null) {
|
|
3889
|
+
throw new Error(
|
|
3890
|
+
`Could not resolve policy "${props.policyName}" in working state.`
|
|
3891
|
+
);
|
|
3892
|
+
}
|
|
3893
|
+
return policy.id;
|
|
3894
|
+
}
|
|
2983
3895
|
function resolvePermissionSetByName(props) {
|
|
2984
3896
|
const permissionSet = props.state.identityCenter.permissionSetsByName[props.permissionSetName];
|
|
2985
3897
|
if (permissionSet == null) {
|
|
@@ -3269,7 +4181,9 @@ var scanResponseSchema = strictObject({
|
|
|
3269
4181
|
users: number(),
|
|
3270
4182
|
groups: number(),
|
|
3271
4183
|
permissionSets: number(),
|
|
3272
|
-
accountAssignments: number()
|
|
4184
|
+
accountAssignments: number(),
|
|
4185
|
+
policies: number(),
|
|
4186
|
+
policyAttachments: number()
|
|
3273
4187
|
}),
|
|
3274
4188
|
state: stateSchema
|
|
3275
4189
|
});
|
|
@@ -3339,7 +4253,7 @@ var s3Client = new S3Client({});
|
|
|
3339
4253
|
var organizationsClient = new OrganizationsClient3({});
|
|
3340
4254
|
var ssoAdminClient = new SSOAdminClient3({});
|
|
3341
4255
|
var identityStoreClient = new IdentitystoreClient3({});
|
|
3342
|
-
var accountClient = new
|
|
4256
|
+
var accountClient = new AccountClient3({});
|
|
3343
4257
|
async function handler(event) {
|
|
3344
4258
|
try {
|
|
3345
4259
|
const parseResult = safeParse(lambdaRequestSchema, event);
|
|
@@ -3364,7 +4278,7 @@ async function handler(event) {
|
|
|
3364
4278
|
return validateResponse(response);
|
|
3365
4279
|
}
|
|
3366
4280
|
if (request.action === "scan") {
|
|
3367
|
-
const response = await handleScan({ s3Client, bucket, organizationsClient, ssoAdminClient, identityStoreClient });
|
|
4281
|
+
const response = await handleScan({ s3Client, bucket, organizationsClient, ssoAdminClient, identityStoreClient, accountClient });
|
|
3368
4282
|
return validateResponse(response);
|
|
3369
4283
|
}
|
|
3370
4284
|
if (request.action === "getStateUrl") {
|
|
@@ -3453,7 +4367,7 @@ function isS3PreconditionFailed(error) {
|
|
|
3453
4367
|
async function handleScan(props) {
|
|
3454
4368
|
const identityCenterInstanceArn = process.env.IDENTITY_CENTER_INSTANCE_ARN || void 0;
|
|
3455
4369
|
const [organization, identityCenter] = await Promise.all([
|
|
3456
|
-
scanOrganization({ organizationsClient: props.organizationsClient }),
|
|
4370
|
+
scanOrganization({ organizationsClient: props.organizationsClient, accountClient: props.accountClient }),
|
|
3457
4371
|
scanIdentityCenter({
|
|
3458
4372
|
ssoAdminClient: props.ssoAdminClient,
|
|
3459
4373
|
identityStoreClient: props.identityStoreClient,
|
|
@@ -3480,7 +4394,9 @@ async function handleScan(props) {
|
|
|
3480
4394
|
users: state.identityCenter.users.length,
|
|
3481
4395
|
groups: state.identityCenter.groups.length,
|
|
3482
4396
|
permissionSets: state.identityCenter.permissionSets.length,
|
|
3483
|
-
accountAssignments: state.identityCenter.accountAssignments.length
|
|
4397
|
+
accountAssignments: state.identityCenter.accountAssignments.length,
|
|
4398
|
+
policies: state.organization.policies?.length ?? 0,
|
|
4399
|
+
policyAttachments: state.organization.policyAttachments?.length ?? 0
|
|
3484
4400
|
},
|
|
3485
4401
|
state
|
|
3486
4402
|
};
|