Esempio n. 1
0
def control(args):
    """Control the stack: update the AutoScaleGroup constraints."""
    config, settings, sinfo = initialize_from_cli(args)
    stack = find_one_stack(args.stack_name, summary=False)
    yield format_stack_summary(stack) + '\n'

    asg = find_one_resource(stack, RES_TYPE_ASG)
    yield format_autoscale(asg)

    if args.min or args.max or args.desired:
        try:
            asg.min_size = int(args.min)
            asg.max_size = int(args.max)
            asg.desired_capacity = int(args.desired)
        except ValueError as error:
            raise CommandError("Invalid value for ASG: %s" % error)

        yield "Change to:"
        yield format_autoscale(asg)

        warn_for_live(sinfo)
        confirm_action(arg, default=True)

        asg.update()
        yield "Updated"
Esempio n. 2
0
def batch_update(args):
    """Update a batch of stacks sequentially."""
    args.template = None

    stacks = find_stacks(args.stack_name)
    yield format_stacks(stacks)

    confirm_action(arg, default=False)

    for stack in stacks:
        args.stack_name = stack.stack_name
        try:
            update(args)
        except CommandError as error:
            print error
            if not confirm('Continue anyway?', default=True):
                raise
Esempio n. 3
0
def delete(args):
    """Delete a stack."""
    config, settings, sinfo = initialize_from_cli(args)

    stack = find_one_stack(args.stack_name)
    yield format_stack_summary(stack)

    warn_for_live(sinfo)
    confirm_action(arg, default=True)

    try:
        res = boto.connect_cloudformation().delete_stack(stack.stack_name)
    except BotoServerError as error:
        if error:
            raise CommandError("BotoServerError: " + error.error_message)
        else:
            raise error
    print("Result %s" % res)
Esempio n. 4
0
def stop(args):
    """Stop the stack: force the AutoScale to shut all instances down."""
    config, settings, sinfo = initialize_from_cli(args)
    stack = find_one_stack(args.stack_name, summary=False)
    yield format_stack_summary(stack)

    asg = find_one_resource(stack, RES_TYPE_ASG)
    yield format_autoscale(asg)

    asg.min_size = 0
    asg.max_size = 0
    asg.desired_capacity = 0

    yield "Change to:"
    yield format_autoscale(asg)

    warn_for_live(sinfo)
    confirm_action(arg, default=True)

    asg.update()
    yield "Updated"
Esempio n. 5
0
def create(args):
    """Create a stack."""
    config, settings, sinfo = initialize_from_cli(args)

    # Read template
    template_path = os.path.join(
        config.get("cfn", "templatedir"),
        args.template if args.template else sinfo['template'])
    template = cfntemplate.CfnTemplate(template_path)
    parameters = cfntemplate.CfnParameters(template, sinfo)
    tags = {
        'Name': args.stack_name,
        'Application': sinfo['Application'],
        'Environment': sinfo['Environment'],
        'Type': sinfo['Type'],
    }

    print("\nStack name: {args.stack_name}\n"
          "\nTemplate: {template!r}\n"
          "\nTags: {tags!r}\n"
          "\nParameters:\n{parameters!r}\n".format(args=args,
                                                   template=template,
                                                   parameters=parameters,
                                                   tags=tags))

    confirm_action(arg, default=True)

    try:
        stackid = boto.connect_cloudformation().create_stack(
            args.stack_name,
            template_body=template.body,
            parameters=parameters,
            tags=tags,
            capabilities=['CAPABILITY_IAM'])
        print("StackId %s" % stackid)
    except BotoServerError as error:
        if error.error_message:
            raise CommandError("BotoServerError: " + error.error_message)
        else:
            raise error
Esempio n. 6
0
def start(args):
    """Start the stack: set AutoScale control to configured values."""
    config, settings, sinfo = initialize_from_cli(args)
    stack = find_one_stack(args.stack_name, summary=False)
    print(format_stack_summary(stack))

    asg = find_one_resource(stack, RES_TYPE_ASG)
    yield format_autoscale(asg)

    try:
        asg.min_size = int(sinfo['AutoScaleMinSize'])
        asg.max_size = int(sinfo['AutoScaleMaxSize'])
        asg.desired_capacity = int(sinfo['AutoScaleDesiredCapacity'])
    except ValueError as error:
        raise CommandError("Invalid values in stack definition: %s" % error)

    yield "Change to:"
    yield format_autoscale(asg)

    warn_for_live(sinfo)
    confirm_action(arg, default=True)

    asg.update()
    yield "Updated"
Esempio n. 7
0
def update(args):
    """Update a stack."""
    config, settings, sinfo = initialize_from_cli(args)

    # Read template
    template = cfntemplate.CfnTemplate(
        os.path.join(
            config.get("cfn", "templatedir"),
            args.template if args.template else sinfo['template']
        )
    )

    parameters = cfntemplate.CfnParameters(template, sinfo)

    print("\nStack name: {args.stack_name}\n"
          "\nTemplate: {template!r}\n"
          "\nParameters:\n"
          "{parameters!r}\n".format(args=args,
                                    template=template,
                                    parameters=parameters))

    warn_for_live(sinfo)
    confirm_action(arg, default=True)

    try:
        stackid = boto.connect_cloudformation().update_stack(
            args.stack_name,
            template_body=template.body,
            parameters=parameters,
            capabilities=['CAPABILITY_IAM'])
        print("StackId %s" % stackid)
    except BotoServerError as error:
        if error.error_message:
            raise CommandError("BotoServerError: " + error.error_message)
        else:
            raise error
Esempio n. 8
0
def migrate_cfg(args):
    """Migrate the stack: re-instantiate all instances."""
    config, settings, sinfo = initialize_from_cli(args)
    stack = find_one_stack(args.stack_name, summary=False)
    print(format_stack_summary(stack))

    asg = find_one_resource(stack, RES_TYPE_ASG)
    yield format_autoscale(asg)

    orig_min = asg.min_size
    orig_max = asg.max_size
    orig_desired = asg.desired_capacity
    orig_term_pol = asg.termination_policies

    mig_min = orig_desired * 2
    mig_max = orig_desired * 2
    mig_desired = orig_desired * 2
    mig_term_pol = [u'OldestLaunchConfiguration', u'OldestInstance']

    if orig_desired != len(asg.instances):
        raise CommandError("The ASG is not stable (desired != instances)")

    for instance in asg.instances:
        if instance.health_status != 'Healthy':
            raise CommandError("The ASG is not stable (instance not healthy)")

    warn_for_live(sinfo)
    confirm_action(arg, default=True)

    yield "\n <> Setting termination policy to %s" % mig_term_pol
    asg.termination_policies = mig_term_pol
    asg.update()

    yield "\n <> Growing the desired capacity from %s to %s" % (
        orig_desired, mig_desired)
    asg.min_size = mig_min
    asg.max_size = mig_max
    asg.desired_capacity = mig_desired
    asg.update()

    yield "\n <> Waiting instances to stabilize..."
    while True:
        sleep(30)
        asg = find_one_resource(stack, RES_TYPE_ASG)
        res_elb_id = find_one_resource(stack, RES_TYPE_ELB, only_id=True)
        elbinstances = boto.connect_elb().describe_instance_health(res_elb_id)
        if len(asg.instances) < mig_desired:
            yield "    NOTYET: only %i instances created" % len(asg.instances)
            continue
        elif [i for i in asg.instances if i.health_status != 'Healthy']:
            yield "    NOTYET: still unhealthy instances"
            continue
        elif len(elbinstances) < mig_desired:
            yield "    NOTYET: only %i instances in ELB" % len(elbinstances)
            continue
        elif [i for i in elbinstances if i.state != 'InService']:
            yield "    NOTYET: not all instances are ELB:InService"
            continue
        else:
            yield "    OK: %s healthy instances in ELB" % len(asg.instances)
            break

    yield "\n <> Checking new ASG state..."
    asg = find_one_resource(stack, RES_TYPE_ASG)
    yield format_autoscale(asg)
    yield format_autoscale_instances(stack)

    yield "\n <> Restoring previous ASG control:"
    asg.termination_policies = orig_term_pol
    asg.min_size = orig_min
    asg.max_size = orig_max
    asg.desired_capacity = orig_desired
    yield format_autoscale(asg)

    if confirm('Restoring ASG config?', default=True):
        try:
            asg.update()
        except BotoServerError as error:
            yield "\n <> Restoration failed!"
            yield error
        else:
            yield "\n <> ASG control restored."
    else:
        yield "WARNING: The ASG desired capacity was doubled!"