in source/msam/chalicelib/periodic.py [0:0]
def ssm_run_command():
"""
Runs all applicable SSM document commands on a given managed instance.
"""
try:
table_name = CONTENT_TABLE_NAME
ssm_client = boto3.client('ssm', config=MSAM_BOTO3_CONFIG)
db_resource = boto3.resource('dynamodb', config=MSAM_BOTO3_CONFIG)
db_table = db_resource.Table(table_name)
instance_ids = {}
# get all the managed instances from the DB with tag MSAM-NodeType
response = db_table.query(
IndexName="ServiceRegionIndex",
KeyConditionExpression=Key("service").eq("ssm-managed-instance"),
FilterExpression="contains(#data, :tagname)",
ExpressionAttributeNames={"#data": "data"},
ExpressionAttributeValues={":tagname": "MSAM-NodeType"}
)
items = response.get("Items", [])
while "LastEvaluatedKey" in response:
response = db_table.query(
IndexName="ServiceRegionIndex",
KeyConditionExpression=Key("service").eq("ssm-managed-instance"),
FilterExpression="contains(#data, :tagname)",
ExpressionAttributeNames={"#data": "data"},
ExpressionAttributeValues={":tagname": "MSAM-NodeType"},
ExclusiveStartKey=response['LastEvaluatedKey']
)
items.append(response.get("Items", []))
for item in items:
data = json.loads(item['data'])
if "MSAM-NodeType" in data["Tags"]:
instance_ids[data['Id']] = data['Tags']['MSAM-NodeType']
# get all the SSM documents applicable to MSAM, filtering by MSAM-NodeType tag
# When we support more than just ElementalLive, add to the list of values for MSAM-NodeType during filtering
document_list = ssm_client.list_documents(
Filters=[
{
'Key': 'tag:MSAM-NodeType',
'Values': [
'ElementalLive',
]
},
{
'Key': 'Owner',
'Values': [
'Self'
]
}
]
)
document_ids = document_list['DocumentIdentifiers']
while "NextToken" in document_list:
document_list = ssm_client.list_documents(
Filters=[
{
'Key': 'tag:MSAM-NodeType',
'Values': [
'ElementalLive',
]
},
{
'Key': 'Owner',
'Values': [
'Self'
]
}
],
NextToken=document_list["NextToken"]
)
document_ids.append(document_list['DocumentIdentifiers'])
document_names = {}
for document in document_ids:
if "Tags" in document:
for tag in document["Tags"]:
if tag['Key'] == "MSAM-NodeType":
document_names[document["Name"]] = tag['Value']
# loop over all instances and run applicable commands based on node type
for instance_id, id_type in instance_ids.items():
for name, doc_type in document_names.items():
if id_type in doc_type:
# maybe eventually doc type could be comma-delimited string if doc applies to more than one type?
print("running command: %s on %s " % (name, instance_id))
try:
response = ssm_client.send_command(
InstanceIds=[
instance_id,
],
DocumentName=name,
TimeoutSeconds=600,
Parameters={
},
MaxConcurrency='50',
MaxErrors='0',
CloudWatchOutputConfig={
'CloudWatchLogGroupName': SSM_LOG_GROUP_NAME,
'CloudWatchOutputEnabled': True
}
)
print(response)
except ClientError as error:
print(error)
if error.response['Error']['Code'] == "InvalidInstanceId":
continue
except ClientError as error:
print(error)