Commits

Pior Bastida  committed e447ad6

Refactor generic commands functions and display functions

  • Participants
  • Parent commits 5faff32

Comments (0)

Files changed (4)

File awstools/commands/__init__.py

 from awstools.application import Applications
 
 
+def get_base_parser():
+    import pkg_resources
+    from argh import ArghParser
+
+    HELP_CFG = "path of an alternative configuration file"
+    HELP_SETTINGS = "path of the application settings configuration file"
+
+    parser = ArghParser(version=pkg_resources.get_distribution("awstools").version)
+    parser.add_argument('--config', default=None, help=HELP_CFG)
+    parser.add_argument('--settings', default=None, help=HELP_SETTINGS)
+
+    return parser
+
+
 def initialize_from_cli(args):
     """
     Read the configuration and settings file and lookup for a stack_info"""
     if sinfo['live'] and sinfo['Environment'] == 'production':
         if not confirm("WARNING: Updating a live stack! Are you sure? "):
             raise CommandError("Aborted")
+
+
+def confirm_action(arg, action="action", default=False):
+    if hasattr(arg, 'force') and arg.force:
+        return
+
+    if not confirm('Confirm %s? ' % action, default=default):
+        raise CommandError("Aborted")

File awstools/commands/cloudformation.py

 # -*- coding: utf-8 -*-
-# Copyright (C) 2012 Ludia Inc.
+# Copyright (C) 2013 Ludia Inc.
 # This software is licensed as described in the file LICENSE, which
 # you should have received as part of this distribution.
-# Author: Pior Bastida <pbastida@socialludia.com>
+# Author: Pior Bastida <pbastida@ludia.com>
 
 import os
 
 
 from awstools.display import (format_stack_summary,
                               format_stack_summary_short,
-                              format_stack_events,
-                              format_autoscale)
+                              format_stack_events)
 from awstools.utils.cloudformation import (find_stacks,
-                                           find_one_stack,
-                                           find_one_resource)
-from awstools.utils.autoscale import update_asg
-from awstools.commands import initialize_from_cli, warn_for_live
+                                           find_one_stack)
+from awstools.commands import (get_base_parser,
+                               initialize_from_cli,
+                               warn_for_live,
+                               confirm_action)
 from awstools import cfntemplate
 
 
 HELP_FORCE = "Don't ask for confirmation"
 
 
+def main():
+    parser = get_base_parser()
+
+    parser.add_commands([ls,
+                         create,
+                         update,
+                         batch_update,
+                         delete,
+                         info,
+                         outputs,
+                         resources,
+                         events,
+                         activities,])
+
+    parser.dispatch(completion=False)
+
+
 @arg('-a', '--all', default=False)
 @arg('stack_name', nargs='?', default='')
 @alias('list')
                                     template=template,
                                     parameters=parameters))
 
-    if not confirm('Confirm this creation? ', default=True):
-        raise CommandError("Aborted")
+    confirm_action(arg, default=True)
 
     try:
         stackid = boto.connect_cloudformation().create_stack(
                                     parameters=parameters))
 
     warn_for_live(sinfo)
-
-    if not args.force:
-        if not confirm('Confirm the update? ', default=True):
-            raise CommandError("Aborted")
+    confirm_action(arg, default=True)
 
     try:
         stackid = boto.connect_cloudformation().update_stack(
     for stack in stacks:
         yield format_stack_summary_short(stack)
 
-    if not confirm('Confirm the batch update? ', default=False):
-        raise CommandError("Aborted")
+    confirm_action(arg, default=False)
 
     for stack in stacks:
         args.stack_name = stack.stack_name
 
 
 @arg('stack_name', help=HELP_SN)
+@arg('-f', '--force', default=False, help=HELP_FORCE)
 @wrap_errors([ValueError, BotoServerError])
 def delete(args):
     config, settings, sinfo = initialize_from_cli(args)
 
     stack = find_one_stack(args.stack_name)
-
-    print(format_stack_summary(stack))
+    yield format_stack_summary(stack)
 
     warn_for_live(sinfo)
-
-    if not confirm('Confirm the deletion? ', default=True):
-        raise CommandError("Aborted")
+    confirm_action(arg, default=True)
 
     try:
         res = boto.connect_cloudformation().delete_stack(stack.stack_name)

File awstools/display.py

 
 import boto
 
+from awstools.utils.cloudformation import (find_one_resource,
+                                           RES_TYPE_ASG,
+                                           RES_TYPE_ELB)
+
+
+
 
 def format_stack_summary(stack):
     tmpl = "Name: {s.stack_name}\n"
     return "\n".join([formatline(e) for e in events])
 
 
-def format_autoscale(asg):
+def format_autoscale(asg, detail=False):
     tmpl = ("AutoScaleGroup: {a.name}\n"
             "AutoScaleGroup min:{a.min_size} max:{a.max_size} "
             "capacity:{a.desired_capacity}\n")
-    return tmpl.format(a=asg)
+
+    if detail:
+        tmpl += "AutoScaleGroup instances:\n  {instances}"
+
+    return tmpl.format(
+        a=asg,
+        instances='\n  '.join(map(repr, asg.instances)),
+    )
+
+
+def format_autoscale_instances(stack):
+    s = []
+
+    tmpl = "  ASG: {id} {health}/{state} LC:{lc}"
+
+    res_asg = find_one_resource(stack, RES_TYPE_ASG)
+
+    for i in res_asg.instances:
+        s.append(tmpl.format(id=i.instance_id,
+                             state=i.lifecycle_state,
+                             health=i.health_status,
+                             lc=i.launch_config_name))
+
+    tmpl = "  ELB: {i.instance_id} {i.state} ({i.reason_code})"
+
+    res_elb_id = find_one_resource(stack, RES_TYPE_ELB, only_id=True)
+    ihealth = boto.connect_elb().describe_instance_health(res_elb_id)
+
+    for i in ihealth:
+        s.append(tmpl.format(i=i))
+
+    return '\n'.join(s)

File awstools/utils/cloudformation.py

         return cfn.describe_stacks(stacks[0].stack_name)[0]
 
 
-def find_one_resource(stack, resource_type):
+RES_TYPE_ASG = 'AWS::AutoScaling::AutoScalingGroup'
+RES_TYPE_ELB = 'AWS::ElasticLoadBalancing::LoadBalancer'
+
+
+def find_one_resource(stack, resource_type, only_id=False):
     stackresources = stack.describe_resources()
 
     resources = [r for r in stackresources if r.resource_type == resource_type]
     if len(resources) > 1:
         raise ValueError("This stack contains more than one AutoScale")
 
-    if resource_type == "AWS::AutoScaling::AutoScalingGroup":
-        try:
-            asg = boto.connect_autoscale().get_all_groups(
-                [resources[0].physical_resource_id])[0]
-        except IndexError:
-            raise ValueError("The AutoScale physical id doesn't exist")
-        return asg
+    phy_id = resources[0].physical_resource_id
+
+    if resource_type == RES_TYPE_ASG:
+        if only_id:
+            return phy_id
+        else:
+            try:
+                return boto.connect_autoscale().get_all_groups([phy_id])[0]
+            except IndexError:
+                raise ValueError("The AutoScale physical id doesn't exist")
+
+    elif resource_type == RES_TYPE_ELB:
+        if only_id:
+            return phy_id
+        else:
+            try:
+                return boto.connect_elb().get_all_load_balancers([phy_id])[0]
+            except IndexError:
+                raise ValueError("The ELB physical id doesn't exist")
 
     else:
         raise NotImplementedError("Unkown resource type")