Skip to content

Commit

Permalink
Merge 5b1711c into 8b6c58b
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdonnnj committed Feb 22, 2021
2 parents 8b6c58b + 5b1711c commit e44e2e1
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 105 deletions.
11 changes: 5 additions & 6 deletions src/manage_cyhy_ops/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ def main() -> int:
"--regions": And(
str,
lambda s: False
if False in map(lambda e: e in ALLOWED_REGIONS, s.split(","))
else True,
not in map(lambda r: r in ALLOWED_REGIONS, s.split(",")),
error=f"Invalid region(s) provided. Valid regions are: {ALLOWED_REGIONS}",
),
"--ssm-ssh-prefix": SSM_KEY_VALIDATE,
Expand Down Expand Up @@ -125,8 +124,8 @@ def main() -> int:
managers: List[ManageOperators] = []
for region in regions:
managers.append(ManageOperators(region, cyhy_ops, ssh_prefix))
except Exception as e:
logging.error(e)
except Exception as err:
logging.error(err)
return 1

username = validated_args["USERNAME"]
Expand Down Expand Up @@ -164,5 +163,5 @@ def main() -> int:
# guaranteed in the future. This handles any non-successful error code.
if True in map(lambda e: e != 0, results):
return 1
else:
return 0

return 0
179 changes: 80 additions & 99 deletions src/manage_cyhy_ops/manageoperators.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ def __init__(self, region: str, cyhy_ops_key: str, ssh_key_prefix: str):
self.region = region
try:
self._client = boto3.client("ssm", region_name=region)
except ClientError as e:
logging.error(f'Unable to setup SSM client in region "{region}".')
raise e
except ClientError as err:
logging.error('Unable to setup SSM client in region "%s".', region)
raise err

def _get_cyhy_ops_list(self):
def _get_cyhy_ops_list(self) -> List[str]:
users: List[str] = []
try:
response = self._client.get_parameter(
Expand All @@ -36,94 +36,82 @@ def _get_cyhy_ops_list(self):
users = response.get("Parameter", {}).get("Value", "").split(",")
except self._client.exceptions.ParameterNotFound:
logging.warning(
f'The CyHy Operators parameter "{self.cyhy_ops_key}" '
f'does not exist in region "{self.region}".'
'The CyHy Operators parameter "%s" does not exist in region "%s".',
self.cyhy_ops_key,
self.region,
)
except ClientError as e:
logging.error(e)
except ClientError as err:
logging.error(err)

return users

def _update_cyhy_ops_users(self, username: str, remove: bool = False) -> int:
"""Update the list of CyHy Operators to use when an instance is built."""
users: List[str] = self._get_cyhy_ops_list()
update_msg: str = "performed no operations on"

logging.debug("Current CyHy Operators: {users}.")
logging.debug("Current CyHy Operators: %s.", users)

if remove:
if username not in users:
logging.warning(
f'User "{username}" is not in the list of active '
f'CyHy Operators in region "{self.region}".'
'User "%s" is not in the list of active CyHy Operators in region "%s".',
username,
self.region,
)
else:
users.remove(username)
update_msg = f'removed "{username}" from'
update_msg = 'removed "%s" from'
else:
if username in users:
logging.warning(
f'User "{username}" is already in the list of active '
f'CyHy Operators in region "{self.region}".'
'User "%s" is already in the list of active CyHy Operators in region "%s".',
username,
self.region,
)
else:
users.append(username)
update_msg = f'added "{username}" to'
update_msg = 'added "%s" to'

if len(users) == 0:
try:
logging.warning(
"No CyHy Operators left, deleting CyHy Operators parameter "
f'from region "{self.region}".'
)
# Response is an empty dictionary on success.
self._client.delete_parameter(Name=self.cyhy_ops_key)
except ClientError as e:
logging.error(
"Unable to delete the CyHy Operators parameter in "
f'region "{self.region}".'
)
logging.error(e)
return 1
else:
updated_users = ",".join(users)
updated_users = ",".join(sorted(users))

logging.debug(f'New CyHy Operators value: "{updated_users}".')
logging.debug('New CyHy Operators value: "%s".', updated_users)

try:
# The SSM response on success currently only contains a version
# number and the parameter tier.
# Neither are useful to us at this time, so we don't store them.
self._client.put_parameter(
Name=self.cyhy_ops_key,
Value=updated_users,
Type="SecureString",
Overwrite=True,
)
log_msg = f'Successfully {update_msg} CyHy Operators in region "%s"'
logging.info(log_msg, username, self.region)
except ClientError as err:
logging.error(
'Unable to update parameter "%s" in region "%s".',
self.cyhy_ops_key,
self.region,
)
logging.error(err)
return 1

try:
# The SSM response on success currently only contains a version
# number and the parameter tier.
# Neither are useful to us at this time, so we don't store them..
self._client.put_parameter(
Name=self.cyhy_ops_key,
Value=updated_users,
Type="SecureString",
Overwrite=True,
)
logging.info(
f"Successfully {update_msg} CyHy Operators in region "
f'"{self.region}".'
)
except ClientError as e:
logging.error(
f'Unable to update parameter "{self.cyhy_ops_key}" '
f'in region "{self.region}".'
)
logging.error(e)
return 1
return 0

def add_user(self, username: str, ssh_key: str, overwrite: bool = False) -> int:
"""Add an Operator to the Parameter Store."""
return_value = 0

# Should this be atomic?
try:
# The SSM response on success currently only contains a version
# number and the parameter tier.
# Neither are useful to us at this time, so we don't store them..
# Neither are useful to us at this time, so we don't store them.
logging.debug(
f'Adding SSH key to Parameter Store in "{self.region}" with key '
f'"{self.ssh_key_prefix}/{username}".'
'Adding SSH key to Parameter Store in "%s" with key "%s/%s".',
self.region,
self.ssh_key_prefix,
username,
)
self._client.put_parameter(
Name=f"{self.ssh_key_prefix}/{username}",
Expand All @@ -132,56 +120,49 @@ def add_user(self, username: str, ssh_key: str, overwrite: bool = False) -> int:
Overwrite=overwrite,
)
logging.info(
f'Successfully added "{username}"\'s SSH key to the '
f'Parameter Store in "{self.region}".'
'Successfully added "%s"\'s SSH key to the Parameter Store in "%s".',
username,
self.region,
)
except self._client.exceptions.ParameterAlreadyExists:
logging.warning(
f'SSH key for "{username}" already exists in the '
f'Parameter Store for region "{self.region}".'
'SSH key for "%s" already exists in the Parameter Store for region "%s".',
username,
self.region,
)
logging.warning(
"If you need to overwrite this value, please use the "
'"--overwrite" switch.'
'If you need to overwrite this value, please use the "--overwrite" switch.'
)
except ClientError as e:
logging.error(e)
except ClientError as err:
logging.error(err)
return 1

ret = self._update_cyhy_ops_users(username)
if ret:
return_value = ret

return return_value
return self._update_cyhy_ops_users(username)

def remove_user(self, username: str, full: bool = False):
def remove_user(self, username: str, full: bool = False) -> int:
"""Remove an Operator from the Parameter Store."""
return_value = 0

# Should this be atomic?
if full:
try:
parameter_name = f"{self.ssh_key_prefix}/{username}"
# Response is an empty dictionary on success.
self._client.delete_parameter(Name=parameter_name)
logging.info(
f'Successfully removed SSH key for user "{username}" '
f'in region "{self.region}".'
'Successfully removed SSH key for user "%s" in region "%s".',
username,
self.region,
)
except self._client.exceptions.ParameterNotFound:
logging.warning(
f'User "{username}" dot not have an SSH key stored in '
f'the Parameter Store of region "{self.region}".'
'User "%s" does not have an SSH key stored in the Parameter Store of region "%s".',
username,
self.region,
)
except ClientError as e:
logging.error(e)
except ClientError as err:
logging.error(err)
return 1

ret = self._update_cyhy_ops_users(username, remove=True)
if ret:
return_value = ret

return return_value
return self._update_cyhy_ops_users(username, remove=True)

def check_user(self, username: str) -> int:
"""Check for the existence of an Operator and return information."""
Expand All @@ -190,30 +171,30 @@ def check_user(self, username: str) -> int:
Name=f"{self.ssh_key_prefix}/{username}", WithDecryption=True
)
logging.info(
f'User "{username}" has the following SSH key in the '
f'Parameter Store of region "{self.region}":'
'User "%s" has the following SSH key in the Parameter Store of region "%s":',
username,
self.region,
)
logging.info(response["Parameter"]["Value"])
except self._client.exceptions.ParameterNotFound:
logging.info(
f'User "{username}" does not have an SSH key in the '
f'Parameter Store of region "{self.region}".'
'User "%s" does not have an SSH key in the Parameter Store of region "%s".',
username,
self.region,
)
except ClientError as e:
logging.error(e)
except ClientError as err:
logging.error(err)
return 1

enabled_users: List[str] = self._get_cyhy_ops_list()
if not enabled_users:
return 1

if username in enabled_users:
user_status = "is set"
else:
user_status = "is not set"
logging.info(
f'User "{username}" {user_status} as a CyHy Operator '
f'in region "{self.region}".'
log_msg = (
'User "%s" is '
+ ("" if username in enabled_users else "not ")
+ 'set as a CyHy Operator in region "%s".'
)
logging.info(log_msg, username, self.region)

return 0

0 comments on commit e44e2e1

Please sign in to comment.