Skip to content

Commit 28fbe6c

Browse files
committed
remove completed users from initial_users secret
so that they are never resynced a second time (potentially undoing a customer update)
1 parent f2f364e commit 28fbe6c

3 files changed

Lines changed: 64 additions & 4 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,9 @@ mas-devops-create-initial-users-for-saas \
7777
--manage-api-port 8443 \
7878
--coreapi-port 8444 \
7979
--admin-dashboard-port 8445
80+
```
81+
82+
Example of initial_users secret:
83+
```json
84+
{"john.smith1@example.com":"primary,john1,smith1","john.smith2@example.com":"primary,john2,smith2","john.smith3@example.com":"secondary,john3,smith3"}
8085
```

bin/mas-devops-create-initial-users-for-saas

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ if __name__ == "__main__":
9999

100100
if initial_users_secret_name is not None:
101101

102+
logger.info(f"Loading initial_users configuration from secret {initial_users_secret_name}")
103+
102104
session = boto3.session.Session()
103105
aws_sm_client = session.client(
104106
service_name='secretsmanager',
@@ -118,6 +120,24 @@ if __name__ == "__main__":
118120
else:
119121
raise Exception("Something unexpected happened")
120122

121-
user_utils.create_initial_users_for_saas(initial_users)
122-
123+
124+
result = user_utils.create_initial_users_for_saas(initial_users)
123125

126+
# if user details were sourced from an AWS SM secret, remove the completed entries from the secret
127+
# so we don't try and resync them the next time round (and potentially undo an update made by a customer)
128+
if initial_users_secret_name is not None:
129+
has_updates = False
130+
for completed_user in result["completed"]:
131+
logger.info(f"Removing synced user {completed_user['email']} from {initial_users_secret_name} secret")
132+
secret_json.pop(completed_user["email"])
133+
has_updates = True
134+
135+
if has_updates:
136+
logger.info(f"Updating secret {initial_users_secret_name}")
137+
try:
138+
aws_sm_client.update_secret( # pragma: allowlist secret
139+
SecretId=initial_users_secret_name,
140+
SecretString=json.dumps(secret_json)
141+
)
142+
except ClientError as e:
143+
raise Exception(f"Failed to update secret {initial_users_secret_name}: {str(e)}")

src/mas/devops/users.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,10 @@ def parse_initial_users_from_aws_secret_json(self, secret_json):
793793
secondary = []
794794
for (email, csv) in secret_json.items():
795795
values = csv.split(",")
796+
797+
if len(values) != 3:
798+
raise Exception(f"Wrong number of CSV values for {email} (expected 3 but got {len(values)})")
799+
796800
user_type = values[0].strip()
797801
given_name = values[1].strip()
798802
family_name = values[2].strip()
@@ -834,15 +838,46 @@ def create_initial_users_for_saas(self, initial_users):
834838
if type(secondary_users) is not list:
835839
raise Exception("'users.secondary' is not a list")
836840

841+
if len(primary_users) == 0 and len(secondary_users) == 0:
842+
self.logger.info("No users left to sync, nothing to do")
843+
return {"completed": [], "failed": []}
844+
837845
# before we do anything, let's check all MAS applications are ready
838846
for mas_application_id in self.mas_workspace_application_ids:
839847
self.await_mas_application_availability(mas_application_id)
840848

849+
completed = []
850+
failed = []
851+
841852
for primary_user in primary_users:
842-
self.create_initial_user_for_saas(primary_user, "PRIMARY")
853+
self.logger.info("")
854+
try:
855+
self.logger.info(f"Syncing primary user {primary_user['email']}")
856+
self.create_initial_user_for_saas(primary_user, "PRIMARY")
857+
completed.append(primary_user)
858+
self.logger.info(f"Completed sync of primary user {primary_user['email']}")
859+
except Exception as e:
860+
self.logger.error(f"Sync of primary user {primary_user['email']} failed: {str(e)}")
861+
failed.append(primary_user)
862+
self.logger.info("")
843863

844864
for secondary_user in secondary_users:
845-
self.create_initial_user_for_saas(secondary_user, "SECONDARY")
865+
self.logger.info("")
866+
try:
867+
self.logger.info("")
868+
self.logger.info(f"Syncing secondary user {secondary_user['email']}")
869+
self.create_initial_user_for_saas(secondary_user, "SECONDARY")
870+
completed.append(secondary_user)
871+
self.logger.info(f"Completed sync of secondary user {secondary_user['email']}")
872+
except Exception as e:
873+
self.logger.error(f"Sync of secondary user {secondary_user['email']} failed: {str(e)}")
874+
failed.append(secondary_user)
875+
self.logger.info("")
876+
877+
return {
878+
"completed": completed,
879+
"failed": failed
880+
}
846881

847882
def create_initial_user_for_saas(self, user, user_type):
848883
if "email" not in user:

0 commit comments

Comments
 (0)