Skip to content

Commit

Permalink
- Rewrote commands with consistent way of passing arguments to contro…
Browse files Browse the repository at this point in the history
…llers.

- Added Account initialization to 'aim init project'.
  • Loading branch information
gitwater committed Aug 1, 2019
1 parent fbf1238 commit c729f32
Show file tree
Hide file tree
Showing 26 changed files with 430 additions and 201 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Changelog for aim
- CloudWatch Alarm descriptions are JSON with metadata about the environment,
region, application, resource group and resource that the alarm is for.

- Rewrote commands with consistent way of passing arguments to controllers.

- Added Account initialization to 'aim init project'.


1.1.0 (2019-07-24)
------------------
Expand Down
2 changes: 1 addition & 1 deletion src/aim/cftemplates/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self,
# Super
super().__init__(aim_ctx,
account_ctx,
aws_account=None,
aws_region=account_config.region,
config_ref=account_config_ref,
aws_name=self.account_id,
iam_capabilities=["CAPABILITY_NAMED_IAM"])
Expand Down
25 changes: 19 additions & 6 deletions src/aim/cftemplates/iam_managed_policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,22 @@ def __init__(self,
Version: "2012-10-17"
Statement:
{0[statement]:s}
Roles:
{0[roles]}
#Users:
# - String
{0[users]}
"""
policy_table = {
'name': None,
'path': None,
'cf_resource_name_prefix': None,
'statement': None,
'roles': None
'roles': None,
'users': None
}

role_fmt = """ - %s
"""
user_fmt = """ - %s
"""

policy_outputs_fmt = """
{0[cf_resource_name_prefix]:s}ManagedPolicy:
Expand Down Expand Up @@ -102,8 +103,20 @@ def __init__(self,

# Roles
policy_table['roles'] = ""
for role in policy_config.roles:
policy_table['roles'] += role_fmt % (role)
if policy_config.roles and len(policy_config.roles) > 0:
policy_table['roles'] = """ Roles:
"""
for role in policy_config.roles:
policy_table['roles'] += role_fmt % (role)

# Users
policy_table['users'] = ""
if policy_config.users and len(policy_config.users) > 0:
policy_table['users'] = """ Users:
"""
for user in policy_config.users:
policy_table['users'] += user_fmt % (user)

# Path
policy_table['path'] = policy_config.path
# Statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ name: Master
title: Master AWS Account
account_type: AWS
account_id: '{{cookiecutter.master_account_id}}'
admin_delegate_role_name: 'AIM-Admin-Delegate-Role'
admin_delegate_role_name: 'Waterbear-Cloud-Admin-Delegate-Role'
region: '{{cookiecutter.default_region}}'
35 changes: 14 additions & 21 deletions src/aim/commands/cmd_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@aim_home_option
@pass_aim_context
@handle_exceptions
def delete_command(aim_ctx, controller_type, component_name=None, config_name=None, config_region=None, home='.'):
def delete_command(aim_ctx, controller_type, arg_1=None, arg_2=None, arg_3=None, arg_4=None, home='.'):
"""Deletes provisioned AWS Resources"""
init_aim_home_option(aim_ctx, home)
if not aim_ctx.home:
Expand All @@ -23,31 +23,24 @@ def delete_command(aim_ctx, controller_type, component_name=None, config_name=No
# component_name,
# config_name
#)
delete_name = "{0} {1}".format(controller_type, component_name)
if config_name:
delete_name += " {0}".format(config_name)
delete_name = "{0} {1}".format(controller_type, arg_1)
if arg_2:
delete_name += " {0}".format(arg_2)
#print("This will delete {} - (model: {} - {})".format(delete_name, aim_obj.name, aim_obj.title))
answer = input("Proceed with deletion (y/N)? ")
if answer.lower() != 'y':
print("Aborting delete operation")
return

aim_ctx.log("Deleting: %s.%s", controller_type, component_name )
aim_ctx.log("Delete: Controller: {} arg_1({}) arg_2({}) arg_3({}) arg_4({})".format(controller_type, arg_1, arg_2, arg_3, arg_4) )
aim_ctx.load_project()

aim_ctx.init_project()
if controller_type == "NetEnv":
config_arg = {
'netenv_id': component_name,
'subenv_id': config_name,
'region': config_region
}
elif controller_type == "EC2":
config_arg = {
'service': component_name,
'id': config_name
}
else:
config_arg = component_name

controller = aim_ctx.get_controller(controller_type, config_arg)
controller_args = {
'command': 'delete',
'arg_1': arg_1,
'arg_2': arg_2,
'arg_3': arg_3,
'arg_4': arg_4
}
controller = aim_ctx.get_controller(controller_type, controller_args)
controller.delete()
77 changes: 37 additions & 40 deletions src/aim/commands/cmd_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,42 @@ def __init__(self, environment):
for an empty or complete AIM Project.
""")
@click.argument('config_type', default='project', type=click.STRING)
@click.option(
"-r",
"--region",
help="AWS region code, e.g. us-west-2",
)
@click.option(
"-k",
"--keypair_name",
help="EC2 keypair name",
)
#@click.argument('controller_type', default='project', type=click.STRING)
#@click.option(
# "-r",
# "--region",
# help="AWS region code, e.g. us-west-2",
#)
#@click.option(
# "-k",
# "--keypair_name",
# help="EC2 keypair name",
#)
@aim_home_option
@controller_args
@pass_aim_context
def init_command(aim_ctx, config_type='project', region=None, keypair_name=None, home='.'):
"""Initializes an AIM Project"""
if config_type == 'project':
print("\nAIM Project initialization")
print("--------------------------\n")
print("About to create a new AIM Project directory at {}\n".format(os.getcwd()))
cookiecutter(os.path.dirname(__file__) + os.sep + 'aim-cookiecutter' + os.sep)
elif config_type == 'keypair':
# ToDo: expand this command to be able to insert a new keypair into an existing EC2.yaml file
base_dir = home + os.sep + 'Resources' + os.sep
if os.path.isfile(base_dir + os.sep + 'EC2.yaml') or os.path.isfile(base_dir + os.sep + 'EC2.yml'):
print("\n{}Resources/EC2.yaml file already exists. Exiting.".format(base_dir))
sys.exit()
init_aim_home_option(aim_ctx, home)
print("\nAIM EC2 keypair initialization")
print("------------------------------\n")
ec2_file = base_dir + os.sep + 'EC2.yaml'
with open(ec2_file, 'w') as f:
f.write(
"""keypairs:
{}:
name: "{}"
region: "{}"
""".format(
keypair_name, keypair_name, region
))
print("Added keypair {} for region {} to file at {}.".format(
keypair_name, region, ec2_file
))
def init_command(aim_ctx, controller_type, arg_1=None, arg_2=None, arg_3=None, arg_4=None, home='.'):
"""Initializes AIM Configuration"""

init_aim_home_option(aim_ctx, home)
if not aim_ctx.home:
print('AIM configuration directory needs to be specified with either --home or AIM_HOME environment variable.')
sys.exit()

aim_ctx.log("Init: Controller: {} arg_1({}) arg_2({}) arg_3({}) arg_4({})".format(controller_type, arg_1, arg_2, arg_3, arg_4) )

# If we are initializing the project, laod_project needs to behave differently
project_init=False
if controller_type == 'project' and arg_1 == None:
project_init=True
aim_ctx.load_project(project_init=project_init)

controller_args = {
'arg_1': arg_1,
'arg_2': arg_2,
'arg_3': arg_3,
'arg_4': arg_4,
'command': 'init'
}
controller = aim_ctx.get_controller(controller_type, controller_args)
controller.init_command(controller_args)
33 changes: 12 additions & 21 deletions src/aim/commands/cmd_provision.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,22 @@
@aim_home_option
@pass_aim_context
@handle_exceptions
def provision_command(aim_ctx, controller_type, component_name=None, config_name=None, config_region=None, home='.'):
def provision_command(aim_ctx, controller_type, arg_1=None, arg_2=None, arg_3=None, arg_4=None, home='.'):
"""Provision AWS Resources"""
init_aim_home_option(aim_ctx, home)
if not aim_ctx.home:
print('AIM configuration directory needs to be specified with either --home or AIM_HOME environment variable.')
sys.exit()
aim_ctx.log("Provisioning Configuration: %s.%s", controller_type, component_name )
aim_ctx.init_project()
#aim_ctx.config_processor.apply()
config_arg = None
if controller_type == "NetEnv":
config_arg = {
'netenv_id': component_name,
'subenv_id': config_name,
'region' : config_region
}
elif controller_type == "EC2":
config_arg = {
'service': component_name,
'id': config_name
}
else:
config_arg = {
'name': component_name
}

controller = aim_ctx.get_controller(controller_type, config_arg)
aim_ctx.log("Provision: Controller: {} arg_1({}) arg_2({}) arg_3({}) arg_4({})".format(controller_type, arg_1, arg_2, arg_3, arg_4) )
aim_ctx.load_project()

controller_args = {
'command': 'provision',
'arg_1': arg_1,
'arg_2': arg_2,
'arg_3': arg_3,
'arg_4': arg_4
}
controller = aim_ctx.get_controller(controller_type, controller_args)
controller.provision()
2 changes: 1 addition & 1 deletion src/aim/commands/cmd_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def shell_command(aim_ctx, netenv_id, env_id, region, instance_ref, home='.'):
print('AIM configuration directory needs to be specified with either --home or AIM_HOME environment variable.')
sys.exit()

aim_ctx.init_project()
aim_ctx.load_project()
config_arg = {
'netenv_id': netenv_id,
'subenv_id': env_id,
Expand Down
30 changes: 11 additions & 19 deletions src/aim/commands/cmd_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,23 @@
@aim_home_option
@pass_aim_context
@handle_exceptions
def validate_command(aim_ctx, controller_type, component_name=None, config_name=None, config_region=None, home='.'):
def validate_command(aim_ctx, controller_type, arg_1=None, arg_2=None, arg_3=None, arg_4=None, home='.'):
"""Validates a Config CloudFormation"""

init_aim_home_option(aim_ctx, home)
if not aim_ctx.home:
print('AIM configuration directory needs to be specified with either --home or AIM_HOME environment variable.')
sys.exit()

aim_ctx.init_project()
config_arg = None
if controller_type == "NetEnv":
config_arg = {
'netenv_id': component_name,
'subenv_id': config_name,
'region' : config_region
}
elif controller_type == "EC2":
config_arg = {
'service': component_name,
'id': config_name
}
else:
config_arg = {
'name': component_name
}
aim_ctx.log("Validate: Controller: {} arg_1({}) arg_2({}) arg_3({}) arg_4({})".format(controller_type, arg_1, arg_2, arg_3, arg_4) )

controller = aim_ctx.get_controller(controller_type, config_arg)
aim_ctx.load_project()
controller_args = {
'command': 'validate',
'arg_1': arg_1,
'arg_2': arg_2,
'arg_3': arg_3,
'arg_4': arg_4
}
controller = aim_ctx.get_controller(controller_type, controller_args)
controller.validate()
2 changes: 1 addition & 1 deletion src/aim/commands/cookiecutter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def test_web_server_responds(verbose):
project = aim.models.load_project_from_yaml(AimReference(), 'tproj')
web_asg = project['ne']['tnet']['dev']['us-west-2'].applications['tapp'].groups['site'].resources['alb']
aim_ctx = AimContext('tproj')
aim_ctx.init_project()
aim_ctx.load_project()
account = aim_ctx.get_account_context(account_name='master')
client = account.get_aws_client('elbv2')
response = client.describe_load_balancers(Names=[web_asg.resource_name])
Expand Down
7 changes: 4 additions & 3 deletions src/aim/commands/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ def controller_args(func):
"""
decorator to add controller args
"""
func = click.argument("config_region", required=False, type=click.STRING)(func)
func = click.argument("config_name", required=False, type=click.STRING)(func)
func = click.argument("component_name", required=True, type=click.STRING)(func)
func = click.argument("arg_4", required=False, type=click.STRING)(func)
func = click.argument("arg_3", required=False, type=click.STRING)(func)
func = click.argument("arg_2", required=False, type=click.STRING)(func)
func = click.argument("arg_1", required=False, type=click.STRING)(func)
func = click.argument("controller_type", required=True, type=click.STRING)(func)
return func

Expand Down
19 changes: 13 additions & 6 deletions src/aim/config/aim_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ def __init__(self,
self.client_cache = {}
self.resource_cache = {}
self.aim_ctx = aim_ctx
self.config = aim_ctx.project['accounts'][name]
if name in aim_ctx.project['accounts'].keys():
self.config = aim_ctx.project['accounts'][name]
else:
self.config = None
self.mfa_account = mfa_account
self.aws_session = None
cache_filename = '-'.join(['aim', aim_ctx.project.name, 'account', self.name])
Expand Down Expand Up @@ -131,9 +134,12 @@ def get_region_from_ref(self, netenv_ref):
return region


def init_project(self):
def load_project(self, project_init=False):
print("Project: %s" % (self.home))
self.project_folder = self.home
if project_init == True:
return

# Config Processor Init
self.config_processor = ConfigProcessor(self)
self.project = load_project_from_yaml(self.aim_ref, self.project_folder, None) #self.config_processor.load_yaml)
Expand Down Expand Up @@ -164,10 +170,11 @@ def init_project(self):
self.get_controller('CodeCommit')
self.get_controller('S3').init({'name': 'buckets'})

def get_controller(self, controller_type, config_arg=None):
def get_controller(self, controller_type, controller_args=None):
#print("Creating controller_type: " + controller_type)
controller_type = controller_type.lower()
controller = None
if controller_type != 'Service':
if controller_type != 'service':
if controller_type in self.controllers:
#print("Returning cached controller: " + controller_type)
controller = self.controllers[controller_type]
Expand All @@ -176,14 +183,14 @@ def get_controller(self, controller_type, config_arg=None):
controller = aim.controllers.klass[controller_type](self)
self.controllers[controller_type] = controller
else:
service_name = config_arg['name']
service_name = controller_args['arg_1']
if service_name.lower() not in self.services:
print("Could not find Service: %s" % (service_name))
raise StackException(AimErrorCode.Unknown)

controller = self.services[service_name.lower()]

controller.init(config_arg)
controller.init(controller_args)
return controller

def log(self, msg, *args):
Expand Down

0 comments on commit c729f32

Please sign in to comment.