@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/dist/state.js CHANGED
@@ -9,10 +9,37 @@ const organizationalUnitSchema = v.strictObject({
9
9
  arn: nonEmptyString,
10
10
  name: nonEmptyString
11
11
  });
12
+ const orgPolicyTypeSchema = v.picklist([
13
+ "SERVICE_CONTROL_POLICY",
14
+ "RESOURCE_CONTROL_POLICY",
15
+ "TAG_POLICY",
16
+ "AISERVICES_OPT_OUT_POLICY",
17
+ "BACKUP_POLICY"
18
+ ]);
19
+ const orgPolicySchema = v.strictObject({
20
+ id: nonEmptyString,
21
+ arn: nonEmptyString,
22
+ name: nonEmptyString,
23
+ description: v.string(),
24
+ type: orgPolicyTypeSchema,
25
+ content: nonEmptyString
26
+ });
27
+ const orgPolicyAttachmentSchema = v.strictObject({
28
+ policyId: nonEmptyString,
29
+ targetId: nonEmptyString,
30
+ targetType: v.picklist(["ROOT", "ORGANIZATIONAL_UNIT", "ACCOUNT"])
31
+ });
12
32
  const accountTagSchema = v.strictObject({
13
33
  key: nonEmptyString,
14
34
  value: v.string()
15
35
  });
36
+ const alternateContactSchema = v.strictObject({
37
+ contactType: v.picklist(["BILLING", "OPERATIONS", "SECURITY"]),
38
+ name: v.string(),
39
+ email: v.string(),
40
+ phone: v.string(),
41
+ title: v.optional(v.string())
42
+ });
16
43
  const accountSchema = v.strictObject({
17
44
  id: nonEmptyString,
18
45
  arn: nonEmptyString,
@@ -20,7 +47,8 @@ const accountSchema = v.strictObject({
20
47
  email: nonEmptyString,
21
48
  status: nonEmptyString,
22
49
  parentId: nonEmptyString,
23
- tags: v.array(accountTagSchema)
50
+ tags: v.array(accountTagSchema),
51
+ alternateContacts: v.optional(v.array(alternateContactSchema))
24
52
  });
25
53
  const userSchema = v.strictObject({
26
54
  userId: nonEmptyString,
@@ -42,6 +70,13 @@ const customerManagedPolicyReferenceSchema = v.strictObject({
42
70
  name: nonEmptyString,
43
71
  path: nonEmptyString
44
72
  });
73
+ const permissionsBoundarySchema = v.union([
74
+ v.strictObject({ managedPolicyArn: nonEmptyString }),
75
+ v.strictObject({
76
+ customerManagedPolicyName: nonEmptyString,
77
+ customerManagedPolicyPath: nonEmptyString
78
+ })
79
+ ]);
45
80
  const permissionSetSchema = v.strictObject({
46
81
  permissionSetArn: nonEmptyString,
47
82
  name: nonEmptyString,
@@ -49,7 +84,8 @@ const permissionSetSchema = v.strictObject({
49
84
  sessionDuration: v.nullable(v.string()),
50
85
  inlinePolicy: v.nullable(nonEmptyString),
51
86
  awsManagedPolicies: v.array(nonEmptyString),
52
- customerManagedPolicies: v.array(customerManagedPolicyReferenceSchema)
87
+ customerManagedPolicies: v.array(customerManagedPolicyReferenceSchema),
88
+ permissionsBoundary: v.nullable(permissionsBoundarySchema)
53
89
  });
54
90
  const accountAssignmentSchema = v.strictObject({
55
91
  accountId: nonEmptyString,
@@ -64,13 +100,24 @@ const accessRoleSchema = v.strictObject({
64
100
  principalType: principalTypeSchema,
65
101
  roleName: nonEmptyString
66
102
  });
103
+ const accessControlAttributeSchema = v.strictObject({
104
+ key: nonEmptyString,
105
+ source: v.array(nonEmptyString)
106
+ });
107
+ const delegatedAdministratorSchema = v.strictObject({
108
+ accountId: nonEmptyString,
109
+ servicePrincipal: nonEmptyString
110
+ });
67
111
  const stateSchema = v.strictObject({
68
112
  version: nonEmptyString,
69
113
  generatedAt: nonEmptyString,
70
114
  organization: v.strictObject({
71
115
  rootId: nonEmptyString,
72
116
  organizationalUnits: v.array(organizationalUnitSchema),
73
- accounts: v.array(accountSchema)
117
+ accounts: v.array(accountSchema),
118
+ policies: v.optional(v.array(orgPolicySchema)),
119
+ policyAttachments: v.optional(v.array(orgPolicyAttachmentSchema)),
120
+ delegatedAdministrators: v.optional(v.array(delegatedAdministratorSchema))
74
121
  }),
75
122
  identityCenter: v.strictObject({
76
123
  instanceArn: nonEmptyString,
@@ -80,13 +127,17 @@ const stateSchema = v.strictObject({
80
127
  groupMemberships: v.array(groupMembershipSchema),
81
128
  permissionSets: v.array(permissionSetSchema),
82
129
  accountAssignments: v.array(accountAssignmentSchema),
83
- accessRoles: v.array(accessRoleSchema)
130
+ accessRoles: v.array(accessRoleSchema),
131
+ accessControlAttributes: v.array(accessControlAttributeSchema)
84
132
  })
85
133
  });
86
134
  function validateState(value) {
87
135
  return v.parse(stateSchema, value);
88
136
  }
89
137
  function createWorkingState(props) {
138
+ const policies = props.state.organization.policies ?? [];
139
+ const policyAttachments = props.state.organization.policyAttachments ?? [];
140
+ const delegatedAdministrators = props.state.organization.delegatedAdministrators ?? [];
90
141
  return {
91
142
  version: props.state.version,
92
143
  generatedAt: props.state.generatedAt,
@@ -100,6 +151,18 @@ function createWorkingState(props) {
100
151
  accountsByName: toRecordByProperty(
101
152
  props.state.organization.accounts,
102
153
  "name"
154
+ ),
155
+ policiesById: toRecordByProperty(policies, "id"),
156
+ policiesByName: toRecordByProperty(policies, "name"),
157
+ policyAttachments: structuredClone(policyAttachments),
158
+ policyAttachmentsByKey: toRecordByProperty(
159
+ policyAttachments,
160
+ createOrgPolicyAttachmentKey
161
+ ),
162
+ delegatedAdministrators: structuredClone(delegatedAdministrators),
163
+ delegatedAdministratorsByKey: toRecordByProperty(
164
+ delegatedAdministrators,
165
+ createDelegatedAdministratorKey
103
166
  )
104
167
  },
105
168
  identityCenter: createWorkingIdentityCenterState({
@@ -116,7 +179,16 @@ function materializeWorkingState(props) {
116
179
  organizationalUnits: Object.values(
117
180
  props.workingState.organization.organizationalUnitsById
118
181
  ),
119
- accounts: Object.values(props.workingState.organization.accountsById)
182
+ accounts: Object.values(props.workingState.organization.accountsById),
183
+ policies: Object.values(props.workingState.organization.policiesById),
184
+ policyAttachments: structuredClone(
185
+ props.workingState.organization.policyAttachments
186
+ ),
187
+ ...props.workingState.organization.delegatedAdministrators.length > 0 ? {
188
+ delegatedAdministrators: structuredClone(
189
+ props.workingState.organization.delegatedAdministrators
190
+ )
191
+ } : {}
120
192
  },
121
193
  identityCenter: {
122
194
  instanceArn: props.workingState.identityCenter.instanceArn,
@@ -134,6 +206,9 @@ function materializeWorkingState(props) {
134
206
  ),
135
207
  accessRoles: structuredClone(
136
208
  props.workingState.identityCenter.accessRoles
209
+ ),
210
+ accessControlAttributes: structuredClone(
211
+ props.workingState.identityCenter.accessControlAttributes
137
212
  )
138
213
  }
139
214
  };
@@ -346,7 +421,7 @@ function removeIdcGroupFromWorkingState(props) {
346
421
  }
347
422
  function upsertIdcPermissionSetInWorkingState(props) {
348
423
  const currentPermissionSet = props.workingState.identityCenter.permissionSetsByName[props.permissionSet.name];
349
- 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)) {
424
+ 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)) {
350
425
  return props.workingState;
351
426
  }
352
427
  const remainingPermissionSets = props.workingState.identityCenter.permissionSets.filter(
@@ -488,6 +563,154 @@ function removeAccountAssignmentFromWorkingState(props) {
488
563
  })
489
564
  };
490
565
  }
566
+ function createOrgPolicyAttachmentKey(props) {
567
+ return [props.policyId, props.targetId].join("|");
568
+ }
569
+ function upsertOrgPolicyInWorkingState(props) {
570
+ const currentPolicy = props.workingState.organization.policiesById[props.policy.id];
571
+ 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) {
572
+ return props.workingState;
573
+ }
574
+ const remainingPolicies = Object.values(
575
+ props.workingState.organization.policiesById
576
+ ).filter((p) => p.id !== props.policy.id);
577
+ const nextPolicies = [...remainingPolicies, props.policy];
578
+ return {
579
+ ...props.workingState,
580
+ organization: {
581
+ ...props.workingState.organization,
582
+ policiesById: toRecordByProperty(nextPolicies, "id"),
583
+ policiesByName: toRecordByProperty(nextPolicies, "name")
584
+ }
585
+ };
586
+ }
587
+ function removeOrgPolicyFromWorkingState(props) {
588
+ if (props.workingState.organization.policiesById[props.policyId] == null) {
589
+ return props.workingState;
590
+ }
591
+ const nextPolicies = Object.values(
592
+ props.workingState.organization.policiesById
593
+ ).filter((p) => p.id !== props.policyId);
594
+ const nextAttachments = props.workingState.organization.policyAttachments.filter(
595
+ (a) => a.policyId !== props.policyId
596
+ );
597
+ return {
598
+ ...props.workingState,
599
+ organization: {
600
+ ...props.workingState.organization,
601
+ policiesById: toRecordByProperty(nextPolicies, "id"),
602
+ policiesByName: toRecordByProperty(nextPolicies, "name"),
603
+ policyAttachments: nextAttachments,
604
+ policyAttachmentsByKey: toRecordByProperty(
605
+ nextAttachments,
606
+ createOrgPolicyAttachmentKey
607
+ )
608
+ }
609
+ };
610
+ }
611
+ function addOrgPolicyAttachmentToWorkingState(props) {
612
+ const key = createOrgPolicyAttachmentKey({
613
+ policyId: props.attachment.policyId,
614
+ targetId: props.attachment.targetId
615
+ });
616
+ if (props.workingState.organization.policyAttachmentsByKey[key] != null) {
617
+ return props.workingState;
618
+ }
619
+ const nextAttachments = [
620
+ ...props.workingState.organization.policyAttachments,
621
+ props.attachment
622
+ ];
623
+ return {
624
+ ...props.workingState,
625
+ organization: {
626
+ ...props.workingState.organization,
627
+ policyAttachments: nextAttachments,
628
+ policyAttachmentsByKey: toRecordByProperty(
629
+ nextAttachments,
630
+ createOrgPolicyAttachmentKey
631
+ )
632
+ }
633
+ };
634
+ }
635
+ function removeOrgPolicyAttachmentFromWorkingState(props) {
636
+ const key = createOrgPolicyAttachmentKey({
637
+ policyId: props.policyId,
638
+ targetId: props.targetId
639
+ });
640
+ if (props.workingState.organization.policyAttachmentsByKey[key] == null) {
641
+ return props.workingState;
642
+ }
643
+ const nextAttachments = props.workingState.organization.policyAttachments.filter(
644
+ (a) => createOrgPolicyAttachmentKey({
645
+ policyId: a.policyId,
646
+ targetId: a.targetId
647
+ }) !== key
648
+ );
649
+ return {
650
+ ...props.workingState,
651
+ organization: {
652
+ ...props.workingState.organization,
653
+ policyAttachments: nextAttachments,
654
+ policyAttachmentsByKey: toRecordByProperty(
655
+ nextAttachments,
656
+ createOrgPolicyAttachmentKey
657
+ )
658
+ }
659
+ };
660
+ }
661
+ function createDelegatedAdministratorKey(props) {
662
+ return [props.accountId, props.servicePrincipal].join("|");
663
+ }
664
+ function upsertDelegatedAdministratorInWorkingState(props) {
665
+ const key = createDelegatedAdministratorKey({
666
+ accountId: props.delegatedAdministrator.accountId,
667
+ servicePrincipal: props.delegatedAdministrator.servicePrincipal
668
+ });
669
+ if (props.workingState.organization.delegatedAdministratorsByKey[key] != null) {
670
+ return props.workingState;
671
+ }
672
+ const nextDelegatedAdministrators = [
673
+ ...props.workingState.organization.delegatedAdministrators,
674
+ props.delegatedAdministrator
675
+ ];
676
+ return {
677
+ ...props.workingState,
678
+ organization: {
679
+ ...props.workingState.organization,
680
+ delegatedAdministrators: nextDelegatedAdministrators,
681
+ delegatedAdministratorsByKey: toRecordByProperty(
682
+ nextDelegatedAdministrators,
683
+ createDelegatedAdministratorKey
684
+ )
685
+ }
686
+ };
687
+ }
688
+ function removeDelegatedAdministratorFromWorkingState(props) {
689
+ const key = createDelegatedAdministratorKey({
690
+ accountId: props.accountId,
691
+ servicePrincipal: props.servicePrincipal
692
+ });
693
+ if (props.workingState.organization.delegatedAdministratorsByKey[key] == null) {
694
+ return props.workingState;
695
+ }
696
+ const nextDelegatedAdministrators = props.workingState.organization.delegatedAdministrators.filter(
697
+ (da) => createDelegatedAdministratorKey({
698
+ accountId: da.accountId,
699
+ servicePrincipal: da.servicePrincipal
700
+ }) !== key
701
+ );
702
+ return {
703
+ ...props.workingState,
704
+ organization: {
705
+ ...props.workingState.organization,
706
+ delegatedAdministrators: nextDelegatedAdministrators,
707
+ delegatedAdministratorsByKey: toRecordByProperty(
708
+ nextDelegatedAdministrators,
709
+ createDelegatedAdministratorKey
710
+ )
711
+ }
712
+ };
713
+ }
491
714
  async function readStateFile(path) {
492
715
  const content = await readFile(path, "utf8");
493
716
  const parsed = JSON.parse(content);
@@ -527,7 +750,10 @@ function createWorkingIdentityCenterState(props) {
527
750
  ),
528
751
  accessRoles: createAccessRoles({
529
752
  accountAssignments
530
- })
753
+ }),
754
+ accessControlAttributes: structuredClone(
755
+ props.identityCenter.accessControlAttributes ?? []
756
+ )
531
757
  };
532
758
  }
533
759
  function materializeWorkingIdentityCenterState(props) {
@@ -541,7 +767,10 @@ function materializeWorkingIdentityCenterState(props) {
541
767
  accountAssignments: structuredClone(
542
768
  props.identityCenter.accountAssignments
543
769
  ),
544
- accessRoles: structuredClone(props.identityCenter.accessRoles)
770
+ accessRoles: structuredClone(props.identityCenter.accessRoles),
771
+ accessControlAttributes: structuredClone(
772
+ props.identityCenter.accessControlAttributes
773
+ )
545
774
  };
546
775
  }
547
776
  function createAccessRoles(props) {
@@ -596,24 +825,31 @@ function sortJsonValue(value) {
596
825
  export {
597
826
  addAccountAssignmentToWorkingState,
598
827
  addGroupMembershipToWorkingState,
828
+ addOrgPolicyAttachmentToWorkingState,
599
829
  createAccessRoleName,
600
830
  createGroupMembershipKey,
831
+ createOrgPolicyAttachmentKey,
601
832
  createWorkingState,
602
833
  materializeWorkingState,
603
834
  moveAccountInWorkingState,
604
835
  readStateFile,
605
836
  removeAccountAssignmentFromWorkingState,
837
+ removeDelegatedAdministratorFromWorkingState,
606
838
  removeGroupMembershipFromWorkingState,
607
839
  removeIdcGroupFromWorkingState,
608
840
  removeIdcPermissionSetFromWorkingState,
609
841
  removeIdcUserFromWorkingState,
842
+ removeOrgPolicyAttachmentFromWorkingState,
843
+ removeOrgPolicyFromWorkingState,
610
844
  removeOrganizationalUnitFromWorkingState,
611
845
  renameOrganizationalUnitInWorkingState,
612
846
  stateSchema,
613
847
  upsertAccountInWorkingState,
848
+ upsertDelegatedAdministratorInWorkingState,
614
849
  upsertIdcGroupInWorkingState,
615
850
  upsertIdcPermissionSetInWorkingState,
616
851
  upsertIdcUserInWorkingState,
852
+ upsertOrgPolicyInWorkingState,
617
853
  upsertOrganizationalUnitInWorkingState,
618
854
  validateState
619
855
  };