Allow setting log level ...

... currently only for update targetgroup
parent d3755dc3
Pipeline #2153 failed with stages
in 49 seconds
#!/usr/bin/env python3
import click
from akinaka_libs import helpers
from time import gmtime, strftime
from akinaka_update.commands import update as update_commands
from akinaka_cleanup.commands import cleanup as cleanup_commands
......@@ -10,8 +11,10 @@ from akinaka_container.commands import container as container_commands
from akinaka_k8s.commands import k8s as k8s_commands
@click.group()
def cli():
pass
@click.option("--log-level", '-l', default="INFO", type=click.Choice(["INFO", "ERROR", "DEBUG"]), help="How much information to show in logging. Default is INFO")
@click.pass_context
def cli(ctx=None, log_level=None):
ctx.obj = {'log_level': log_level}
cli.add_command(update_commands)
cli.add_command(cleanup_commands)
......
from akinaka_libs import helpers
import logging
helpers.set_logger()
helpers.set_logger(level="ERROR")
class AkinakaGeneralError(Exception):
pass
......@@ -18,5 +18,5 @@ class AkinakaCriticalException(Exception):
def __init__(self, message=None):
super().__init__(message)
logging.error(message)
exit(1)
\ No newline at end of file
exit(1)
......@@ -13,5 +13,5 @@ def seconds_from_hours(hours):
def log(message):
print(message)
def set_logger():
return logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S%z')
def set_logger(level='INFO'):
return logging.basicConfig(level=level, format='%(asctime)s [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S%z')
......@@ -34,17 +34,17 @@ class ASG():
target_group_arn = self.get_target_group_arn()
active_asg = self.get_active_asg(target_group_arn)
asg_split = active_asg.split('-')[0:-1]
return '-'.join(asg_split)
def work_out_new_asg(self):
if self.asg is not None:
logging.info("We've been given the ASG name as an argument")
return self.asg
target_group_arn = self.get_target_group_arn()
target_group_arn = self.get_target_group_arn()
active_asg = self.get_active_asg(target_group_arn)
new_asg = self.get_inactive_asg(active_asg)
new_asg = self.get_inactive_asg(active_asg)
return new_asg
......@@ -54,7 +54,7 @@ class ASG():
logging.info("New ASG was worked out as {}. Now updating it's Launch Template".format(new_asg))
self.update_launch_template(new_asg, new_ami, self.get_lt_name(new_asg))
logging.info("Scaling ASG down")
self.scale(new_asg, 0, 0, 0)
while not self.asg_is_empty(new_asg):
......@@ -63,11 +63,11 @@ class ASG():
logging.info("Scaling ASG back up")
self.scale(new_asg, self.scale_to, self.scale_to, self.scale_to)
while len(self.get_auto_scaling_group_instances(new_asg)) < 1:
logging.info("Waiting for instances in ASG to start ...")
sleep(10)
logging.info("First instance has started")
# Try to get information for an instance in the new ASG 20 times
......@@ -84,7 +84,7 @@ class ASG():
logging.info("Error was: {}".format(error))
# Show console output for first instance up until it's Lifecycle Hook has passed
while self.get_auto_scaling_group_instances(auto_scaling_group_id=new_asg, instance_ids=[first_new_instance])[0]['LifecycleState'] != "InService":
while self.get_auto_scaling_group_instances(auto_scaling_group_id=new_asg, instance_ids=[first_new_instance])[0]['LifecycleState'] != "InService":
try:
logging.info("Attempting to retrieve console output from first instance up -- this will not work for non-nitro hypervisor VMs")
logging.info(self.get_instance_console_output(first_new_instance)['Output'])
......@@ -112,10 +112,10 @@ class ASG():
def instance_state(self, instance):
ec2_client = aws_client.create_client('ec2', self.region, self.role_arn)
instance_states = ec2_client.describe_instance_status(IncludeAllInstances=True, InstanceIds=[instance])
while 'InstanceStatuses' not in instance_states:
instance_states = ec2_client.describe_instance_status(InstanceIds=[instance])
return instance_states['InstanceStatuses'][0]['InstanceState']['Name']
def get_lt_name(self, asg):
......@@ -123,7 +123,7 @@ class ASG():
lt_info = asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[asg])
try:
return lt_info['AutoScalingGroups'][0]['LaunchTemplate']['LaunchTemplateName']
return lt_info['AutoScalingGroups'][0]['LaunchTemplate']['LaunchTemplateName']
except Exception as e:
raise exceptions.AkinakaCriticalException("{}: Likely couldn't find the ASG you're trying to update".format(e))
......@@ -160,7 +160,7 @@ class ASG():
def get_target_groups_instances(self, target_group_arn):
"""Returns an array of instance IDs belonging to the target group specified"""
alb_client = aws_client.create_client('elbv2', self.region, self.role_arn)
target_groups_instances = []
these_target_group_instances = alb_client.describe_target_health(TargetGroupArn=target_group_arn)['TargetHealthDescriptions']
......@@ -172,18 +172,18 @@ class ASG():
# from stale ASGs, or anything else is off in them, you will get unexpected results
for instance in these_target_group_instances:
target_groups_instances.append(instance['Target']['Id'])
return target_groups_instances
return target_groups_instances
def get_active_asg(self, target_groups):
ec2_client = aws_client.create_client('ec2', self.region, self.role_arn)
target_groups_instances = self.get_target_groups_instances(target_groups)
instances_with_tags = {}
raw_instances_reservations = ec2_client.describe_instances(InstanceIds=target_groups_instances)['Reservations']
for reservation in raw_instances_reservations:
for instance in reservation['Instances']:
instances_with_tags[instance['InstanceId']] = instance['Tags']
......@@ -199,7 +199,7 @@ class ASG():
return next(iter(instances_with_asg.values()))
def get_inactive_asg(self, active_asg):
def get_inactive_asg(self, active_asg):
asg_parts = active_asg.split('-')
active_colour = asg_parts[-1]
......@@ -286,7 +286,7 @@ class ASG():
instance_id = i['InstanceId'],
instance_state = i['HealthStatus'],
instance_lifecycle_state = i['LifecycleState']
)
)
)
logging.info("Instance {instance_id} is {instance_lifecycle_state}".format(
......@@ -294,10 +294,10 @@ class ASG():
instance_lifecycle_state = i['LifecycleState']
)
)
return target_instances
def asg_is_empty(self, auto_scaling_group_id):
asg_instances = self.get_auto_scaling_group_instances(auto_scaling_group_id)
......@@ -306,9 +306,9 @@ class ASG():
def asgs_healthy_instances(self, auto_scaling_group_id):
asg_instances = self.get_auto_scaling_group_instances(auto_scaling_group_id)
healthy_instances = []
for i in asg_instances:
if i['LifecycleState'] == "InService":
healthy_instances.append(i)
return healthy_instances
\ No newline at end of file
return healthy_instances
......@@ -4,14 +4,12 @@ from akinaka_libs import helpers
from time import gmtime, strftime
import logging
helpers.set_logger()
@click.group()
@click.option("--region", required=True, help="Region your resources are located in")
@click.option("--role-arn", required=True, help="Role ARN which contains necessary assume permissions")
@click.pass_context
def update(ctx, region, role_arn):
ctx.obj = {'region': region, 'role_arn': role_arn}
ctx.obj = {'region': region, 'role_arn': role_arn, 'log_level': ctx.obj.get('log_level')}
pass
def set_deploy_status(verb, region, role_arn, application, reset=None):
......@@ -84,11 +82,12 @@ def asg(ctx, ami, lb, asg_name, target_group, scale_to, skip_status_check):
def targetgroup(ctx, new_asg_target):
region = ctx.obj.get('region')
role_arn = ctx.obj.get('role_arn')
log_level = ctx.obj.get('log_level')
from .targetgroup import update_targetgroup
from .targetgroup import update_targetgroup
try:
target_groups = update_targetgroup.TargetGroup(region, role_arn, new_asg_target)
target_groups = update_targetgroup.TargetGroup(region, role_arn, new_asg_target, log_level)
target_groups.switch_asg()
# We've successfully deployed, so set the status of deploy to "false"
set_deploy_status("stop", region, role_arn, target_groups.get_application_name())
......@@ -96,4 +95,3 @@ def targetgroup(ctx, new_asg_target):
except Exception as e:
logging.error("{}".format(e))
exit(1)
......@@ -2,15 +2,18 @@
from akinaka_client.aws_client import AWS_Client
from akinaka_libs import exceptions
from akinaka_libs import helpers
import logging
aws_client = AWS_Client()
class TargetGroup():
def __init__(self, region, role_arn, new_asg):
def __init__(self, region, role_arn, new_asg, log_level):
self.region = region
self.role_arn = role_arn
self.new_asg = new_asg
self.log_level = log_level
logging.getLogger().setLevel(log_level)
def get_application_name(self):
asg_split = self.new_asg.split('-')[0:-1]
......@@ -23,7 +26,7 @@ class TargetGroup():
"""
return_list = []
# Yes a regexp is smarter, but don't be smart, be safe ;)
asg_split = wanted_asg.split('-')[0:-1]
wanted_asg_prefix = '-'.join(asg_split)
......@@ -31,7 +34,9 @@ class TargetGroup():
for asg in asgs:
if wanted_asg_prefix in asg['AutoScalingGroupName']:
return_list.append(asg)
logging.debug("filter_out_unwanted_asgs(): Wanted ASG prefix: {}, Return list: {}".format(wanted_asg_prefix, return_list))
return return_list
def group_asgs_by_status(self, asgs, wanted_asg):
......@@ -39,10 +44,10 @@ class TargetGroup():
Returns a dict of 'active_asg' and 'inactive_asg' dicts with only the ASGs
matching 'wanted_asgs'
"""
inactive_asg = []
active_asg = []
for asg in asgs['AutoScalingGroups']:
# If the ASG's TargetGroupARNs attribute is empty, it's the inactive one
if len(asg['TargetGroupARNs']) < 1 and asg['AutoScalingGroupName'] == self.new_asg:
......@@ -55,6 +60,8 @@ class TargetGroup():
active_asg = self.filter_out_unwanted_asgs(active_asg, wanted_asg)
inactive_asg = self.filter_out_unwanted_asgs(inactive_asg, wanted_asg)
logging.debug("group_asgs_by_status(): active_asg: {}, inactive_asg: {} ".format(active_asg, inactive_asg))
return {'active_asg': active_asg, 'inactive_asg': inactive_asg}
def switch_asg(self):
......@@ -66,6 +73,8 @@ class TargetGroup():
active_asg = asgs_by_status['active_asg']
inactive_asg = asgs_by_status['inactive_asg']
logging.debug("switch_asg(): asgs_by_status: {}, active_asg: {}, inactive_asg: {}".format(asgs_by_status, active_asg, inactive_asg))
# Exit program if there is no existing active auto scaling groups to perform a switch over
if len(inactive_asg) < 1 or len(active_asg) < 1:
raise exceptions.AkinakaCriticalException('No auto scaling groups are available for this switch over.')
......
......@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="akinaka",
python_requires='>=3.3.0',
version="0.2.27",
version="0.2.28",
author="Afraz",
author_email="afraz@olindata.com",
description="OlinData's aws cli Extras",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment