def scale(self, desired): debug("In asgroup.y scale") asgroup = self.get_asgroup() client = util.as_conn() asg_name = self.name() if desired < asgroup['MinSize']: print "Cannot scale: {} is lower than MinSize ({})".format( desired, asgroup['MinSize']) return if desired > asgroup['MaxSize']: print "Cannot scale: {} is greater than MaxSize ({})".format( desired, asgroup['MaxSize']) if not util.confirm("Increase MaxSize to {}?".format(desired)): return asgroup['MaxSize'] = desired client.update_auto_scaling_group(AutoScalingGroupName=asg_name, MaxSize=desired) current = asgroup['DesiredCapacity'] # Set DesiredCapacity response = client.set_desired_capacity(AutoScalingGroupName=asg_name, DesiredCapacity=desired) # Check if DesiredCapacity was changed debug("in asgroup.py scale: running 'asgroup = self.get_asgroup()'") asgroup = self.get_asgroup() new = asgroup['DesiredCapacity'] if (new != current): msg = "Changed ASgroup {} desired_capacity from {} to {}".format( asg_name, current, new) util.message_integrations(msg)
def scale(self, desired): debug("In asgroup.y scale") asgroup = self.get_asgroup() client = util.as_conn() asg_name = self.name() if desired < asgroup['MinSize']: print "Cannot scale: {} is lower than MinSize ({})".format(desired, asgroup['MinSize']) return if desired > asgroup['MaxSize']: print "Cannot scale: {} is greater than MaxSize ({})".format(desired, asgroup['MaxSize']) if not util.confirm("Increase MaxSize to {}?".format(desired)): return asgroup['MaxSize'] = desired client.update_auto_scaling_group( AutoScalingGroupName = asg_name, MaxSize = desired ) current = asgroup['DesiredCapacity'] # Set DesiredCapacity response = client.set_desired_capacity( AutoScalingGroupName = asg_name, DesiredCapacity = desired ) # Check if DesiredCapacity was changed debug("in asgroup.py scale: running 'asgroup = self.get_asgroup()'") asgroup = self.get_asgroup() new = asgroup['DesiredCapacity'] if (new != current): msg = "Changed ASgroup {} desired_capacity from {} to {}".format(asg_name, current, new) util.message_integrations(msg)
def activate(self): conn = util.as_conn() conn = boto.ec2.autoscale.connect_to_region('us-west-2') name = self.name() # check if this LC already exists if self.exists(): if not util.confirm("LaunchConfig {} already exists, overwrite?".format(name)): return True # delete existing conn.delete_launch_configuration(name) # get configuration for this LC cfg = self.role_config lc = LaunchConfiguration( name = name, image_id = cfg.get('ami'), instance_profile_name = cfg.get('iam_profile'), instance_type = cfg.get('instance_type'), security_groups = cfg.get('security_groups'), key_name = cfg.get('keypair_name'), user_data = self.cloud_init_script(), associate_public_ip_address = True, # this is required for your shit to actually work ) if not conn.create_launch_configuration(lc): print "Error creating LaunchConfig {}".format(name) return False util.message_integrations("Activated LaunchConfig {}".format(name)) return lc
def activate(self): debug("in launchconfig.py activate") conn = util.as_conn() name = self.name() if self.exists(): pprint("in launchconfig.py self.exists()") # NOTE: I don't think program logic ever gets here if not util.confirm("LaunchConfig {} already exists, overwrite?".format(name)): pprint("in launchconfig.py activate: Confirmed overwriting LaunchConfig") return True # delete existing pprint("in launchconfig.py activate: deleting LaunchConfig") conn.delete_launch_configuration(LaunchConfigurationName=name) # get configuration for this LC cfg = self.role_config # NOTE: wrap the following in a try block to catch errors lc = conn.create_launch_configuration( AssociatePublicIpAddress = True, # this is required to make your stuff actually work LaunchConfigurationName = name, IamInstanceProfile = cfg.get('iam_profile'), ImageId = cfg.get('ami'), InstanceType = cfg.get('instance_type'), KeyName = cfg.get('keypair_name'), UserData = self.cloud_init_script(), SecurityGroups = cfg.get('security_groups') ) #if not conn.create_launch_configuration(lc): # print "Error creating LaunchConfig {}".format(name) # return False util.message_integrations("Activated LaunchConfig {}".format(name)) return lc
def get_asgroup(self): debug("In asgroup.py get_asgroup") conn = util.as_conn() asg = conn.describe_auto_scaling_groups( AutoScalingGroupNames = [ self.name() ] ) if not asg['AutoScalingGroups']: return None else: asg = asg['AutoScalingGroups'][0] return asg
def get_asgroup(self): debug("In asgroup.py get_asgroup") conn = util.as_conn() asg = conn.describe_auto_scaling_groups( AutoScalingGroupNames=[self.name()]) if not asg['AutoScalingGroups']: return None else: asg = asg['AutoScalingGroups'][0] return asg
def get_lc(self): debug("in launchconfig.py get_lc") conn = util.as_conn() _lcs = conn.describe_launch_configurations()['LaunchConfigurations'] lcs={} for lc in _lcs: lcs[lc['LaunchConfigurationName']]=lc for key, value in lcs.iteritems(): if key.startswith(self.name()): return value # if we didnt find a LaunchConfig above by the time we get to here, return None return None
def activate(self): conn = util.as_conn() cfg = self.role_config name = self.name() # ensure this LC already exists if not self.activate_lc(): return False # look up subnet id subnets = [ self.find_vpc_subnet_by_cidr(cidr) for cidr in cfg.get('subnets_cidr') ] if not subnets or not len(subnets) or None in subnets: print "Valid subnets_cidr are required for {}/{}".format( self.cluster_name, self.role_name) return False print "Using subnets {}".format(", ".join([s.id for s in subnets])) print "AZs: {}".format(cfg.get('availability_zones')) # does the ASgroup already exist? ag = AutoScalingGroup( group_name=self.name(), load_balancers=cfg.get('elbs'), availability_zones=cfg.get('availability_zones'), vpc_zone_identifier=[s.id for s in subnets], launch_config=self.lc().name(), desired_capacity=cfg.get('scale_policy', 'desired'), min_size=cfg.get('scale_policy', 'min_size'), max_size=cfg.get('scale_policy', 'max_size'), ) if not conn.create_auto_scaling_group(ag): print "Failed to create autoscale group" return False # prepare instance tags tags = cfg.get('tags') if not tags: tags = {} tags['cluster'] = self.cluster_name tags['role'] = self.role_name tags['Name'] = self.name() # apply tags tag_set = [self.ag_tag(ag, k, v) for (k, v) in tags.iteritems()] conn.create_or_update_tags(tag_set) util.message_integrations("Activated ASgroup {}".format(name)) return ag
def deactivate(self): debug("in launchconfig.py deactivate") if not self.exists(): return print "Deleting launchconfig..." client = util.as_conn() response = client.delete_launch_configuration( LaunchConfigurationName = self.name() ) sleep(5) # give aws a chance to delete the launchconfig try: response = client.describe_launch_configurations( LaunchConfigurationName = self.name() ) util.message_integrations("Failed to delete LaunchConfig {}".format(self.name())) except: util.message_integrations("Deleted LaunchConfig {}".format(self.name()))
def update_lc(self): debug("In asgroup.py update_lc") oldlc = self.lc() # # NOTE: Why does this try to delete the LaunchConfig ? lc = oldlc.update() # get new version asgroup = self.get_asgroup() # set lc asg_name = asgroup['AutoScalingGroupName'] lcname = lc.name() client = util.as_conn() debug("updating asg: " + asg_name + " with LaunchConfig " + lcname) response = client.update_auto_scaling_group( AutoScalingGroupName = asg_name, LaunchConfigurationName = lcname ) # delete old conn = util.as_conn() if oldlc.name() is not lcname: debug("deleting Launchconfig " + oldlc.name()) conn.delete_launch_configuration ( LaunchConfigurationName = oldlc.name() )
def update_lc(self): oldlc = self.lc() # get new version lc = oldlc.update() # set lc asgroup = self.get_asgroup() lcname = lc.name() setattr(asgroup, 'launch_config_name', lcname) asgroup.update() # delete old conn = util.as_conn() if oldlc.name() is not lcname: util.retry(lambda: conn.delete_launch_configuration(oldlc.name()), 60)
def update_lc(self): debug("In asgroup.py update_lc") oldlc = self.lc() oldname = oldlc.get_lc_server_name() lc = oldlc.update() # create new version asgroup = self.get_asgroup() asg_name = asgroup['AutoScalingGroupName'] lcname = lc.get_lc_server_name() client = util.as_conn() debug("updating asg: " + asg_name + " with LaunchConfig " + lcname) response = client.update_auto_scaling_group( AutoScalingGroupName = asg_name, LaunchConfigurationName = lcname ) # delete old conn = util.as_conn() if oldname is not lcname: # TODO: waiter debug("deleting Launchconfig " + oldname) conn.delete_launch_configuration(LaunchConfigurationName = oldname)
def activate(self): conn = util.as_conn() cfg = self.role_config name = self.name() # ensure this LC already exists if not self.activate_lc(): return False # look up subnet id subnets = [self.find_vpc_subnet_by_cidr(cidr) for cidr in cfg.get('subnets_cidr')] if not subnets or not len(subnets) or None in subnets: print "Valid subnets_cidr are required for {}/{}".format(self.cluster_name, self.role_name) return False print "Using subnets {}".format(", ".join([s.id for s in subnets])) print "AZs: {}".format(cfg.get('availability_zones')) # does the ASgroup already exist? ag = AutoScalingGroup( group_name=self.name(), load_balancers=cfg.get('elbs'), availability_zones=cfg.get('availability_zones'), vpc_zone_identifier=[s.id for s in subnets], launch_config=self.lc().name(), desired_capacity=cfg.get('scale_policy', 'desired'), min_size=cfg.get('scale_policy', 'min_size'), max_size=cfg.get('scale_policy', 'max_size'), ) if not conn.create_auto_scaling_group(ag): print "Failed to create autoscale group" return False # prepare instance tags tags = cfg.get('tags') if not tags: tags = {} tags['cluster'] = self.cluster_name tags['role'] = self.role_name tags['Name'] = self.name() # apply tags tag_set = [self.ag_tag(ag, k,v) for (k,v) in tags.iteritems()] conn.create_or_update_tags(tag_set) util.message_integrations("Activated ASgroup {}".format(name)) return ag
def deactivate(self): # a.k.a asg destroy # NOTE # deleting asg logic should be in its own function # * delete ASG by reducing capacities of asg to 0 # * delete launchconfig # # reducing ASG capacities to 0 triggers eventual instance # termination debug("In asgroup.py deactivate") asg_name = self.name() ag = util.as_conn() ec2 = util.ec2_conn() asg_info = ag.describe_auto_scaling_groups( AutoScalingGroupNames = [ asg_name ] ) if not asg_info['AutoScalingGroups']: print("ASG does not exist. Maybe it was already deleted?") else: # delete the ASG num_instances = len(asg_info['AutoScalingGroups'][0]['Instances']) if self.get_num_instances() == 0: pprint("There are no instances in asg: " + asg_name) print("Deleting asg: " + asg_name) response = ag.delete_auto_scaling_group( AutoScalingGroupName=asg_name ) util.message_integrations("Deleted ASgroup {}".format(asg_name)) else: debug("There are " + str(num_instances) + " instances that need to be removed from asg: " + asg_name) debug("terminating instances in asg: " + asg_name) debug("by setting to 0 MinSize, MaxSize, DesiredCapacity") response = ag.update_auto_scaling_group(AutoScalingGroupName = asg_name, MinSize=0, MaxSize=0, DesiredCapacity=0) debug("Waiting 30 seconds to give AWS time to terminate the instances") if self.get_num_instances() != 0: util.retry(lambda: ag.delete_auto_scaling_group(AutoScalingGroupName=asg_name), 300) if self.get_num_instances() != 0 or self.get_num_instances(): print("unable to delete instances in asg.") return False util.message_integrations("Deleted ASgroup {}".format(asg_name)) # if launch config exists, delete it lc = self.lc() if not lc.exists(): print("launchconfig does not exist. Maybe you deleted it already?") else: lc.deactivate() return True
def update_lc(self): debug("In asgroup.py update_lc") oldlc = self.lc() oldname = oldlc.get_lc_server_name() lc = oldlc.update() # create new version asgroup = self.get_asgroup() asg_name = asgroup['AutoScalingGroupName'] lcname = lc.get_lc_server_name() client = util.as_conn() debug("updating asg: " + asg_name + " with LaunchConfig " + lcname) response = client.update_auto_scaling_group( AutoScalingGroupName=asg_name, LaunchConfigurationName=lcname) # delete old if oldname is not lcname: # TODO: waiter debug("deleting Launchconfig " + oldname) client.delete_launch_configuration(LaunchConfigurationName=oldname)
def __init__(self, cluster_name, role_name): self.cluster_name = cluster_name self.role_name = role_name self.role_config = config.get_role_config(cluster_name, role_name) self.conn = util.as_conn()
def activate(self): debug("In asgroup.py activate") conn = util.as_conn() cfg = self.role_config name = self.name() if not self.activate_lc(): # ensure this LaunchConfig already exists return False subnet_cidrs = cfg.get('subnets_cidr') if not subnet_cidrs or not len(subnet_cidrs) or None in subnet_cidrs: print "Valid subnets_cidr are required for {}/{}".format( self.cluster_name, self.role_name) return False print("Using subnets " + str(subnet_cidrs)) subnet_ids = self.get_subnet_ids_by_cidrs(subnet_cidrs) azs = cfg.get('availability_zones') cfg_args = {} # If AvailabilityZones is defined, add it to the args we will pass to conn.create_auto_scaling_group() if azs: cfg_args['AvailabilityZones'] = azs print "AZs: {}".format(azs) else: pprint("No availability_zones set") # VPCZoneIdentifier ( which can be plural ) takes a string subnet_ids_string = '' _length = len(subnet_ids) for subnet_id in subnet_ids: subnet_ids_string = subnet_ids_string + subnet_id if _length > 1: subnet_ids_string = subnet_ids_string + ', ' _length = _length - 1 pprint("Using subnet ids: " + str(subnet_ids_string)) cfg_args['AutoScalingGroupName'] = self.name() cfg_args['DesiredCapacity'] = cfg.get('scale_policy')['desired'] cfg_args['LoadBalancerNames'] = cfg.get('elbs') cfg_args['LaunchConfigurationName'] = self.lc().get_lc_server_name() cfg_args['MaxSize'] = cfg.get('scale_policy', 'max_size') cfg_args['MinSize'] = cfg.get('scale_policy', 'min_size') cfg_args['VPCZoneIdentifier'] = subnet_ids_string if not cfg_args['LoadBalancerNames']: cfg_args['LoadBalancerNames'] = [] response = conn.create_auto_scaling_group(**cfg_args) # NOTE: should check if asg was created debug('Preparing tags that will be applied to the asg') tags = cfg.get('tags') if not tags: tags = {} tags['cluster'] = self.cluster_name tags['role'] = self.role_name tags['Name'] = self.name() # apply tags tag_set = [self.ag_tag(name, k, v) for (k, v) in tags.iteritems()] debug("Applying tags to asg") conn.create_or_update_tags(Tags=tag_set) util.message_integrations("Activated ASgroup {}".format(name)) # NOTE: what should we be returning here? Not sure. #return ag return name
def deactivate(self): # a.k.a asg destroy # NOTE # deleting asg logic should be in its own function # * delete ASG by reducing capacities of asg to 0 # * delete launchconfig # # reducing ASG capacities to 0 triggers eventual instance # termination debug("In asgroup.py deactivate") asg_name = self.name() ag = util.as_conn() ec2 = util.ec2_conn() asg_info = ag.describe_auto_scaling_groups( AutoScalingGroupNames=[asg_name]) if not asg_info['AutoScalingGroups']: print("ASG does not exist. Maybe it was already deleted?") else: # delete the ASG num_instances = len(asg_info['AutoScalingGroups'][0]['Instances']) if self.get_num_instances() == 0: pprint("There are no instances in asg: " + asg_name) print("Deleting asg: " + asg_name) response = ag.delete_auto_scaling_group( AutoScalingGroupName=asg_name) util.message_integrations( "Deleted ASgroup {}".format(asg_name)) else: debug("There are " + str(num_instances) + " instances that need to be removed from asg: " + asg_name) debug("terminating instances in asg: " + asg_name) debug("by setting to 0 MinSize, MaxSize, DesiredCapacity") response = ag.update_auto_scaling_group( AutoScalingGroupName=asg_name, MinSize=0, MaxSize=0, DesiredCapacity=0) debug( "Waiting 30 seconds to give AWS time to terminate the instances" ) if self.get_num_instances() != 0: util.retry( lambda: ag.delete_auto_scaling_group( AutoScalingGroupName=asg_name), 300) if self.get_num_instances() != 0 or self.get_num_instances(): print("unable to delete instances in asg.") return False util.message_integrations( "Deleted ASgroup {}".format(asg_name)) # if launch config exists, delete it lc = self.lc() if not lc.exists(): print( "launchconfig does not exist. Maybe you deleted it already?") else: lc.deactivate() return True
def get_num_instances(self): ag = util.as_conn() asg_info = ag.describe_auto_scaling_groups( AutoScalingGroupNames=[self.name()]) return len(asg_info['AutoScalingGroups'][0]['Instances'])
def get_num_instances(self): ag = util.as_conn() asg_info = ag.describe_auto_scaling_groups( AutoScalingGroupNames = [ self.name() ] ) return len(asg_info['AutoScalingGroups'][0]['Instances'])
def get_asgroup(self): conn = util.as_conn() ags = conn.get_all_groups(names=[self.name()]) if not len(ags): return None return ags[0]
def deactivate(self): # a.k.a asg destroy # NOTE # deleting asg logic should be in its own function # * delete ASG by reducing capacities of asg to 0 # * delete launchconfig # # reducing ASG capacities to 0 triggers eventual instance # termination debug("In asgroup.py deactivate") asg_name = self.name() ag = util.as_conn() ec2 = util.ec2_conn() asg_info = ag.describe_auto_scaling_groups( AutoScalingGroupNames = [ asg_name ] ) if not asg_info['AutoScalingGroups']: print("ASG does not exist. Maybe it was already deleted? ") else: # delete the ASG num_instances = len(asg_info['AutoScalingGroups'][0]['Instances']) if self.get_num_instances() == 0: pprint("There are no instances in asg: " + asg_name) pprint("Deleting asg: " + asg_name) response = ag.delete_auto_scaling_group( AutoScalingGroupName=asg_name ) util.message_integrations("Deleted ASgroup {}".format(asg_name)) else: debug("There are " + str(num_instances) + " instances that need to be removed from asg: " + asg_name) debug("terminating instances in asg: " + asg_name) debug("by setting to 0 MinSize, MaxSize, DesiredCapacity") response = ag.update_auto_scaling_group(AutoScalingGroupName = asg_name, MinSize=0, MaxSize=0, DesiredCapacity=0) debug("Waiting 30 seconds to give AWS time to terminate the instances") try: sleep(30) except KeyboardInterrupt: pprint("Got impatient.") sys.exit(1) interval = 10 tries = 20 for x in range(0,tries): try: if self.get_num_instances() != 0: raise ValueError("there are still instances in the ASG") break else: # if num instances in asg is 0, # we are clear to delete break except KeyboardInterrupt: pprint("Got impatient") sys.exit(1) except ValueError as e: pprint(e) pass try: if e: pprint("pausing " + str(interval) + " seconds") sleep(interval) else: break except KeyboardInterrupt: pprint("Got impatient") if self.get_num_instances() == 0 or not self.get_num_instances(): pprint("instances in asg deleted.") response = ag.delete_auto_scaling_group( AutoScalingGroupName=asg_name ) util.message_integrations("Deleted ASgroup {}".format(asg_name)) else: pprint("unable to delete instances in asg.") # if launch config exists, delete it lc = self.lc() if not lc.exists(): print("launchconfig does not exist. Maybe you deleted it already?") else: lc.deactivate()
def get_lc(self): conn = util.as_conn() lcs = conn.get_all_launch_configurations(names = [self.name()]) if not len(lcs): return None return lcs[0]
def activate(self): debug("In asgroup.py activate") conn = util.as_conn() cfg = self.role_config name = self.name() if not self.activate_lc(): # ensure this LaunchConfig already exists return False subnet_cidrs = cfg.get('subnets_cidr') if not subnet_cidrs or not len(subnet_cidrs) or None in subnet_cidrs: print "Valid subnets_cidr are required for {}/{}".format(self.cluster_name, self.role_name) return False print("Using subnets " + str(subnet_cidrs)) subnet_ids = self.get_subnet_ids_by_cidrs(subnet_cidrs) azs=cfg.get('availability_zones') cfg_args = {} # If AvailabilityZones is defined, add it to the args we will pass to conn.create_auto_scaling_group() if azs: cfg_args['AvailabilityZones'] = azs print "AZs: {}".format(azs) else: pprint("No availability_zones set") # VPCZoneIdentifier ( which can be plural ) takes a string subnet_ids_string='' _length = len(subnet_ids) for subnet_id in subnet_ids: subnet_ids_string=subnet_ids_string + subnet_id if _length > 1: subnet_ids_string=subnet_ids_string + ', ' _length = _length - 1 pprint("Using subnet ids: " + str(subnet_ids_string)) cfg_args['AutoScalingGroupName'] = self.name() cfg_args['DesiredCapacity'] = cfg.get('scale_policy')['desired'] cfg_args['LoadBalancerNames'] = cfg.get('elbs') cfg_args['LaunchConfigurationName'] = self.lc().name() cfg_args['MaxSize'] = cfg.get('scale_policy', 'max_size') cfg_args['MinSize'] = cfg.get('scale_policy', 'min_size') cfg_args['VPCZoneIdentifier'] = subnet_ids_string if not cfg_args['LoadBalancerNames']: cfg_args['LoadBalancerNames'] = [] response = conn.create_auto_scaling_group(**cfg_args) # NOTE: should check if asg was created debug('Preparing tags that will be applied to the asg') tags = cfg.get('tags') if not tags: tags = {} tags['cluster'] = self.cluster_name tags['role'] = self.role_name tags['Name'] = self.name() # apply tags tag_set = [self.ag_tag(name, k,v) for (k,v) in tags.iteritems()] debug("Applying tags to asg") conn.create_or_update_tags(Tags=tag_set) util.message_integrations("Activated ASgroup {}".format(name)) # NOTE: what should we be returning here? Not sure. #return ag return name
def get_asgroup(self): conn = util.as_conn() ags = conn.get_all_groups(names = [self.name()]) if not len(ags): return None return ags[0]