def get_ow_instances(client: boto3.client, stack: str): """ Get a list of opsworks instances in stack """ instances = client.describe_instances(StackId=stack)["Instances"] return instances
def stop_instances_any_type(instance_types: dict, force, client: boto3.client): """ Stop instances regardless of the instance type (ondemand, spot) """ if 'normal' in instance_types: logger.debug("Stopping instances: {}".format(instance_types['normal'])) client.stop_instances(InstanceIds=instance_types['normal'], Force=force) if 'spot' in instance_types: # TODO: proper support for spot fleets # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html # To properly stop spot instances have to cancel spot requests first spot_request_ids = get_spot_request_ids_from_response( client.describe_instances(InstanceIds=instance_types['spot'])) logger.debug("Canceling spot requests: {}".format(spot_request_ids)) client.cancel_spot_instance_requests( SpotInstanceRequestIds=spot_request_ids) logger.debug("Terminating spot instances: {}".format( instance_types['spot'])) client.terminate_instances(InstanceIds=instance_types['spot']) if 'scheduled' in instance_types: # TODO: add support for scheduled inststances # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-scheduled-instances.html raise FailedActivity("Scheduled instances support is not implemented")
def get_random_instance_volume( client: boto3.client, instance_ids: List[str] ) -> List[Dict[str, str]]: results = {} try: response = client.describe_instances(InstanceIds=instance_ids)["Reservations"] for r in response: for e in r.get("Instances", []): instance_id = e["InstanceId"] bdm = e.get("BlockDeviceMappings", []) for b in bdm: # skip root devices if b["DeviceName"] in ("/dev/sda1", "/dev/xvda"): continue results.setdefault(instance_id, []).append( {b["DeviceName"]: b["Ebs"]["VolumeId"]} ) volumes = [] for r in results: # select 1 volume at random volume = random.sample(results[r], 1)[0] for k, v in volume.items(): volumes.append({"InstanceId": r, "DeviceName": k, "VolumeId": v}) return volumes except ClientError as e: raise FailedActivity( "Unable to describe asg instances: %s" % (e.response["Error"]["Message"]) )
def stop_instances_any_type( instance_types: dict = None, force: bool = False, client: boto3.client = None ) -> List[AWSResponse]: """ Stop instances regardless of the instance type (on demand, spot) """ response = [] if "normal" in instance_types: logger.debug("Stopping instances: {}".format(instance_types["normal"])) response.append( client.stop_instances(InstanceIds=instance_types["normal"], Force=force) ) if "spot" in instance_types: # TODO: proper support for spot fleets # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html # To properly stop spot instances have to cancel spot requests first spot_request_ids = get_spot_request_ids_from_response( client.describe_instances(InstanceIds=instance_types["spot"]) ) logger.debug(f"Canceling spot requests: {spot_request_ids}") client.cancel_spot_instance_requests(SpotInstanceRequestIds=spot_request_ids) logger.debug("Terminating spot instances: {}".format(instance_types["spot"])) response.append(client.terminate_instances(InstanceIds=instance_types["spot"])) if "scheduled" in instance_types: # TODO: add support for scheduled instances # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-scheduled-instances.html raise FailedActivity("Scheduled instances support is not implemented") return response
def get_random_instance_volume( client: boto3.client, instance_ids: List[str]) -> List[Dict[str, str]]: results = {} try: response = client.describe_instances( InstanceIds=instance_ids)['Reservations'] for r in response: for e in r.get('Instances', []): instance_id = e['InstanceId'] bdm = e.get('BlockDeviceMappings', []) for b in bdm: # skip root devices if b['DeviceName'] in ('/dev/sda1', '/dev/xvda'): continue results.setdefault(instance_id, []).append( {b['DeviceName']: b['Ebs']['VolumeId']}) volumes = [] for r in results: # select 1 volume at random volume = random.sample(results[r], 1)[0] for k, v in volume.items(): volumes.append({ 'InstanceId': r, 'DeviceName': k, 'VolumeId': v }) return volumes except ClientError as e: raise FailedActivity('Unable to describe asg instances: %s' % (e.response['Error']['Message']))
def get_instance_type_by_id(instance_ids: List[str], client: boto3.client) -> Dict: """ Return dict object with instance ids grouped by instance types """ res = client.describe_instances(InstanceIds=instance_ids) return get_instance_type_from_response(res)
def get_instances_list(client: boto3.client) -> List[str]: logger.info("[!] Getting list of instances...") instances_list = [] instances = client.describe_instances() for instance in instances["Reservations"]: for i in instance["Instances"]: instances_list.append(i.get("InstanceId", None)) logger.info(f"[!] Found {len(instances_list)} instances.") return instances_list
def list_instances_by_type(filters: List[Dict[str, Any]], client: boto3.client) -> List[str]: """ Return all instance ids matching the given filters by type (InstanceLifecycle) ie spot, ondemand, etc. """ logger.debug("EC2 instances query: {}".format(str(filters))) res = client.describe_instances(Filters=filters) logger.debug("Instances matching the filter query: {}".format(str(res))) return get_instance_type_from_response(res)
def list_instance_ids(filters: List[Dict[str, Any]], client: boto3.client) -> List[str]: """ Return of all instance ids matching the given filters. """ res = client.describe_instances(Filters=filters) instance_ids = [] # reservations are instances that were started together for reservation in res['Reservations']: for inst in reservation['Instances']: instance_ids.append(inst['InstanceId']) return instance_ids
def list_instances(client: boto3.client, filters: List[Dict[str, Any]] = None, instance_ids: List[str] = None) -> List[Dict[str, Any]]: """ Return all instance ids matching either the filters or provided list of ids Does not group instances by type """ if filters: params = dict(Filters=filters) else: params = dict(InstanceIds=instance_ids) results = [] response = client.describe_instances(**params)['Reservations'] for r in response: for e in r['Instances']: results.append(e) return results
def terminate_instances_any_type(instance_types: dict = None, client: boto3.client = None ) -> List[AWSResponse]: """ Terminates instance(s) regardless of type """ response = [] for k, v in instance_types.items(): logger.debug('Terminating %s instance(s): %s' % (k, instance_types[k])) if k == 'spot': instances = get_spot_request_ids_from_response( client.describe_instances(InstanceIds=v)) # Cancel spot request prior to termination client.cancel_spot_instance_requests( SpotInstanceRequestIds=instances) response.append(client.terminate_instances(InstanceIds=v)) continue response.append(client.terminate_instances(InstanceIds=v)) return response
def list_instance_volumes( client: boto3.client, instance_ids: List[str] = None, filters: List[Dict[str, Any]] = None, ) -> List[AWSResponse]: """ Return all (non root) instance volumes for instances matching either the provided filters or instance ids (do not group by type) """ if filters: params = dict(Filters=filters) else: params = dict(InstanceIds=instance_ids) response = client.describe_instances(**params)["Reservations"] if not response: raise FailedActivity("no instances found matching: %s" % str(params)) results = {} for r in response: for e in r["Instances"]: instance_id = e["InstanceId"] bdm = e.get("BlockDeviceMappings", []) for b in bdm: if b["DeviceName"] in ("/dev/sda1", "/dev/xvda"): continue results.setdefault(instance_id, []).append( {b["DeviceName"]: b["Ebs"]["VolumeId"]} ) volumes = [] for r in results: # select 1 volume at random volume = random.sample(results[r], 1)[0] for k, v in volume.items(): volumes.append({"InstanceId": r, "DeviceName": k, "VolumeId": v}) return volumes
def list_instance_volumes( client: boto3.client, instance_ids: List[str] = None, filters: List[Dict[str, Any]] = None) -> List[AWSResponse]: """ Return all (non root) instance volumes for instances matching either the provided filters or instance ids (do not group by type) """ if filters: params = dict(Filters=filters) else: params = dict(InstanceIds=instance_ids) response = client.describe_instances(**params)['Reservations'] if not response: raise FailedActivity('no instances found matching: %s' % str(params)) results = {} for r in response: for e in r['Instances']: instance_id = e['InstanceId'] bdm = e.get('BlockDeviceMappings', []) for b in bdm: if b['DeviceName'] in ('/dev/sda1', '/dev/xvda'): continue results.setdefault(instance_id, []).append( {b['DeviceName']: b['Ebs']['VolumeId']}) volumes = [] for r in results: # select 1 volume at random volume = random.sample(results[r], 1)[0] for k, v in volume.items(): volumes.append( {'InstanceId': r, 'DeviceName': k, 'VolumeId': v}) return volumes