Skip to content

Commit

Permalink
Split the jinja rendering and json reading into two different functions
Browse files Browse the repository at this point in the history
  • Loading branch information
hgreebe committed Nov 16, 2023
1 parent d582805 commit 5316198
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,3 @@ def render_jinja_template(template_file_path):
f.write(rendered_template)
return template_file_path


def read_jinja_template_at(path):
"""Read the JSON file at path as a Jinja template."""
try:
with open(render_jinja_template(path), encoding="utf-8") as input_file:
return json.load(input_file)
except FileNotFoundError:
fail(f"No file exists at {path}")
except ValueError:
fail(f"File at {path} contains invalid JSON")
return None


def fail(message):
"""Exit nonzero with the given error message."""
sys.exit(message)
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
import json
import os
import shutil
import sys

import jsonschema
from cloudwatch_agent_common_utils import fail, read_jinja_template_at
from cloudwatch_agent_common_utils import render_jinja_template

DEFAULT_SCHEMA_PATH = os.path.realpath(os.path.join(os.path.curdir, "cloudwatch_agent_config_schema.json"))
SCHEMA_PATH = os.environ.get("CW_LOGS_CONFIGS_SCHEMA_PATH", DEFAULT_SCHEMA_PATH)
Expand All @@ -28,6 +29,11 @@
LOG_CONFIGS_BAK_PATH = f"{LOG_CONFIGS_PATH}.bak"


def _fail(message):
"""Exit nonzero with the given error message."""
sys.exit(message)


def parse_args():
"""Parse command line args."""
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -57,9 +63,9 @@ def _read_json_at(path):
with open(path, encoding="utf-8") as input_file:
return json.load(input_file)
except FileNotFoundError:
fail(f"No file exists at {path}")
_fail(f"No file exists at {path}")
except ValueError:
fail(f"File at {path} contains invalid JSON")
_fail(f"File at {path} contains invalid JSON")
return None


Expand All @@ -70,7 +76,7 @@ def _read_schema():

def _read_log_configs():
"""Read the current version of the CloudWatch log configs file, cloudwatch_agent_config.json."""
return read_jinja_template_at(LOG_CONFIGS_PATH)
return _read_json_at(LOG_CONFIGS_PATH)


def _validate_json_schema(input_json):
Expand All @@ -79,7 +85,7 @@ def _validate_json_schema(input_json):
try:
jsonschema.validate(input_json, schema)
except jsonschema.exceptions.ValidationError as validation_err:
fail(str(validation_err))
_fail(str(validation_err))


def _validate_timestamp_keys(input_json):
Expand All @@ -89,7 +95,7 @@ def _validate_timestamp_keys(input_json):
valid_keys |= set(config.get("timestamp_formats").keys())
for log_config in input_json.get("log_configs"):
if log_config.get("timestamp_format_key") not in valid_keys:
fail(
_fail(
f"Log config with log_stream_name {log_config.get('log_stream_name')} and "
f"file_path {log_config.get('file_path'),} contains an invalid timestamp_format_key: "
f"{log_config.get('timestamp_format_key')}. Valid values are {', '.join(valid_keys),}"
Expand All @@ -108,12 +114,13 @@ def _validate_log_config_fields_uniqueness(input_json):
for field in unique_fields:
duplicates = _get_duplicate_values([config.get(field) for config in input_json.get("log_configs")])
if duplicates:
fail(f"The following {field} values are used multiple times: {', '.join(duplicates)}")
_fail(f"The following {field} values are used multiple times: {', '.join(duplicates)}")


def validate_json(input_json=None):
"""Ensure the structure of input_json matches that of the file it will be added to."""
if input_json is None:
render_jinja_template(LOG_CONFIGS_PATH)
input_json = _read_log_configs()
_validate_json_schema(input_json)
_validate_timestamp_keys(input_json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import os
import socket

from cloudwatch_agent_common_utils import read_jinja_template_at
from cloudwatch_agent_common_utils import render_jinja_template

AWS_CLOUDWATCH_CFG_PATH = "/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json"
DEFAULT_METRICS_COLLECTION_INTERVAL = 60
Expand Down Expand Up @@ -63,6 +63,12 @@ def add_instance_log_stream_prefixes(configs):
return configs


def read_data(config_path):
"""Read in log configuration data from config_path."""
with open(config_path, encoding="utf-8") as infile:
return json.load(infile)


def select_configs_for_scheduler(configs, scheduler):
"""Filter out from configs those entries whose 'schedulers' list does not contain scheduler."""
return [config for config in configs if scheduler in config["schedulers"]]
Expand Down Expand Up @@ -217,7 +223,7 @@ def get_dict_value(value, attributes, default=None):
def main():
"""Create cloudwatch agent config file."""
args = parse_args()
config_data = read_jinja_template_at(args.config)
config_data = read_data(render_jinja_template(args.config))
log_configs = select_logs(config_data["log_configs"], args)
log_configs = add_timestamps(log_configs, config_data["timestamp_formats"])
log_configs = add_log_group_name_params(args.log_group, log_configs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

describe file('/usr/local/bin/write_cloudwatch_agent_json.py') do
it { should exist }
its('sha256sum') { should eq '5a2ec92e78c49b2064fea88564b0ffe8ccfda92798de1d8bf8a94158e8c1f366' }
its('sha256sum') { should eq 'f24283f824072456394ab01cd014d37a977fc63fe951c9dd4a7df982bf6e5a82' }
its('owner') { should eq 'root' }
its('group') { should eq 'root' }
its('mode') { should cmp '0755' }
Expand All @@ -64,15 +64,15 @@

describe file('/usr/local/bin/cloudwatch_agent_config_util.py') do
it { should exist }
its('sha256sum') { should eq '68b2a5e96a87eeb4da90cbbb1a4d3796f410b2c2e2c69f084e6515149b6bd29b' }
its('sha256sum') { should eq '9062b9bd5066871e5a4ac5b6e7eaf75e3f97221618861002a7a0dd952c5dbc74' }
its('owner') { should eq 'root' }
its('group') { should eq 'root' }
its('mode') { should cmp '0644' }
end

describe file('/usr/local/bin/cloudwatch_agent_common_utils.py') do
it { should exist }
its('sha256sum') { should eq '2cedb9bf8d430717afe638d989b3f1b97632dfeb89a730c812c4382bc94920ee' }
its('sha256sum') { should eq 'bb6287646444e41990097138980efa026eb105b2ba930772ba8b22a00fd19825' }
its('owner') { should eq 'root' }
its('group') { should eq 'root' }
its('mode') { should cmp '0755' }
Expand Down

0 comments on commit 5316198

Please sign in to comment.