Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# FIXME: there may be multiple instances, and spot fleet provides no indication of whether the SFR is
# fulfilled
instance = resources.ec2.Instance(instances[0]["InstanceId"])
else:
if args.spot_price is None:
args.spot_price = get_spot_bid_price(args.instance_type)
logger.info("Bidding ${}/hour for a {} spot instance".format(args.spot_price, args.instance_type))
res = clients.ec2.request_spot_instances(
SpotPrice=str(args.spot_price),
ValidUntil=datetime.datetime.utcnow() + datetime.timedelta(hours=1),
LaunchSpecification=launch_spec,
ClientToken=args.client_token,
DryRun=args.dry_run
)
sir_id = res["SpotInstanceRequests"][0]["SpotInstanceRequestId"]
clients.ec2.get_waiter("spot_instance_request_fulfilled").wait(SpotInstanceRequestIds=[sir_id])
res = clients.ec2.describe_spot_instance_requests(SpotInstanceRequestIds=[sir_id])
instance = resources.ec2.Instance(res["SpotInstanceRequests"][0]["InstanceId"])
else:
instances = resources.ec2.create_instances(MinCount=1, MaxCount=1, ClientToken=args.client_token,
DryRun=args.dry_run, **launch_spec)
instance = instances[0]
except ClientError as e:
expect_error_codes(e, "DryRunOperation")
logger.info("Dry run succeeded")
exit()
instance.wait_until_running()
hkl = hostkey_line(hostnames=[], key=ssh_host_key).strip()
tags = dict(tag.split("=", 1) for tag in args.tags)
add_tags(instance, Name=args.hostname, Owner=ARN.get_iam_username(),
SSHHostPublicKeyPart1=hkl[:255], SSHHostPublicKeyPart2=hkl[255:],
OwnerSSHKeyName=ssh_key_name, **tags)
if (args.format or args.mount) and not args.attach:
raise SystemExit("Arguments --format and --mount require --attach")
if not args.size:
raise SystemExit("Argument --size-gb is required")
create_args = dict(Size=args.size, Encrypted=True)
if args.tags:
create_args.update(TagSpecifications=[dict(ResourceType="volume", Tags=encode_tags(args.tags))])
for arg in "dry_run snapshot_id availability_zone volume_type iops kms_key_id".split():
if getattr(args, arg) is not None:
create_args["".join(x.capitalize() for x in arg.split("_"))] = getattr(args, arg)
if "AvailabilityZone" not in create_args:
if args.attach:
create_args["AvailabilityZone"] = get_metadata("placement/availability-zone")
else:
create_args["AvailabilityZone"] = ensure_subnet(ensure_vpc()).availability_zone
res = clients.ec2.create_volume(**create_args)
clients.ec2.get_waiter("volume_available").wait(VolumeIds=[res["VolumeId"]])
if args.attach:
try:
attach(parser_attach.parse_args([res["VolumeId"]], namespace=args))
except Exception:
print(json.dumps(res, indent=2, default=lambda x: str(x)))
raise
return res
def complete_volume_id(**kwargs):
return [i["VolumeId"] for i in clients.ec2.describe_volumes()["Volumes"]]
def resolve_instance_id(name):
filter_name = "dns-name" if name.startswith("ec2") and name.endswith("compute.amazonaws.com") else "tag:Name"
if name.startswith("i-"):
return name
try:
desc = clients.ec2.describe_instances(Filters=[dict(Name=filter_name, Values=[name])])
return desc["Reservations"][0]["Instances"][0]["InstanceId"]
except IndexError:
raise AegeaException('Could not resolve "{}" to a known instance'.format(name))
def ensure_bless_ssh_cert(ssh_key_name, bless_config, use_kms_auth, max_cert_age=1800):
ssh_key = ensure_local_ssh_key(ssh_key_name)
ssh_key_filename = get_ssh_key_path(ssh_key_name)
ssh_cert_filename = ssh_key_filename + "-cert.pub"
if os.path.exists(ssh_cert_filename) and time.time() - os.stat(ssh_cert_filename).st_mtime < max_cert_age:
logger.info("Using cached Bless SSH certificate %s", ssh_cert_filename)
return ssh_cert_filename
logger.info("Requesting new Bless SSH certificate")
for lambda_regional_config in bless_config["lambda_config"]["regions"]:
if lambda_regional_config["aws_region"] == clients.ec2.meta.region_name:
break
session = boto3.Session(profile_name=bless_config["client_config"]["aws_user_profile"])
iam = session.resource("iam")
sts = session.client("sts")
assume_role_res = sts.assume_role(RoleArn=bless_config["lambda_config"]["role_arn"], RoleSessionName=__name__)
awslambda = boto3.client('lambda',
region_name=lambda_regional_config["aws_region"],
aws_access_key_id=assume_role_res['Credentials']['AccessKeyId'],
aws_secret_access_key=assume_role_res['Credentials']['SecretAccessKey'],
aws_session_token=assume_role_res['Credentials']['SessionToken'])
bless_input = dict(bastion_user=iam.CurrentUser().user_name,
bastion_user_ip="0.0.0.0/0",
bastion_ips=",".join(bless_config["client_config"]["bastion_ips"]),
remote_usernames=",".join(bless_config["client_config"]["remote_users"]),
public_key_to_sign=get_public_key_from_pair(ssh_key),
command="*")
def get_spot_bid_price(instance_type, ondemand_multiplier=1.2):
ondemand_price = get_ondemand_price_usd(clients.ec2.meta.region_name, instance_type)
return float(ondemand_price) * ondemand_multiplier
def get_products(service_code, region=None, filters=None, terms=None, max_cache_age_days=30):
from ... import config
if region is None:
region = clients.ec2.meta.region_name
if terms is None:
terms = ["OnDemand"]
if filters is None:
filters = [("location", region_name(clients.ec2.meta.region_name))]
filters += getattr(config.pricing, "filters_" + service_code, [])
pricing_data = get_pricing_data(service_code, filters=filters, max_cache_age_days=max_cache_age_days)
for product in pricing_data:
product.update(product["product"].pop("attributes"))
for term_name, term_value in product.pop("terms").items():
if term_name not in terms:
continue
term = list(term_value.values())[0]
for price_dimension in term["priceDimensions"].values():
yield dict(dict(product, **term["termAttributes"]), **price_dimension)
elif name.startswith("lt-"):
clients.ec2.delete_launch_template(LaunchTemplateId=name, DryRun=not args.force)
elif name.startswith("fl-"):
if args.force:
clients.ec2.delete_flow_logs(FlowLogIds=[name])
else:
res = clients.ec2.describe_flow_logs(Filters=[dict(Name="flow-log-id", Values=[name])])
assert res["FlowLogs"], "Unknown flow log ID"
elif name.startswith("ami-"):
image = resources.ec2.Image(name)
snapshot_id = image.block_device_mappings[0].get("Ebs", {}).get("SnapshotId")
image.deregister(DryRun=not args.force)
if snapshot_id:
resources.ec2.Snapshot(snapshot_id).delete(DryRun=not args.force)
elif name.startswith("sir-"):
clients.ec2.cancel_spot_instance_requests(SpotInstanceRequestIds=[name], DryRun=not args.force)
elif name.startswith("sfr-"):
clients.ec2.cancel_spot_fleet_requests(SpotFleetRequestIds=[name],
TerminateInstances=False,
DryRun=not args.force)
elif name.startswith("fs-"):
efs = clients.efs
for mount_target in efs.describe_mount_targets(FileSystemId=name)["MountTargets"]:
if args.force:
efs.delete_mount_target(MountTargetId=mount_target["MountTargetId"])
try:
while efs.describe_mount_targets(MountTargetId=mount_target["MountTargetId"]):
time.sleep(1)
except ClientError as e:
expect_error_codes(e, "MountTargetNotFound")
efs.delete_file_system(FileSystemId=name) if args.force else True
elif name.startswith("AKIA") and len(name) == 20 and name.upper() == name:
def reboot(args):
ids, names = resolve_instance_ids(args.names)
clients.ec2.reboot_instances(InstanceIds=ids, DryRun=args.dry_run)