Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
break
if i + 1 < len(devices) and re.search("InvalidParameterValue.+Attachment point.+is already in use", str(e)):
logger.warn("BDM node %s is already in use, looking for next available node", devices[i])
continue
raise
res = clients.ec2.get_waiter("volume_in_use").wait(VolumeIds=[args.volume_id])
if args.format or args.mount:
for i in range(30):
try:
find_devnode(args.volume_id)
break
except Exception:
logger.debug("Waiting for device node to appear for %s", args.volume_id)
time.sleep(1)
if args.format:
logger.info("Formatting %s (%s)", args.volume_id, find_devnode(args.volume_id))
label = get_fs_label(args.volume_id)
command = get_mkfs_command(fs_type=args.format, label=label) + find_devnode(args.volume_id)
subprocess.check_call(command, shell=True, stdout=sys.stderr.buffer)
if args.mount:
logger.info("Mounting %s at %s", args.volume_id, args.mount)
subprocess.check_call(["mount", find_devnode(args.volume_id), args.mount], stdout=sys.stderr.buffer)
return res
parser_attach = register_parser(attach, parent=ebs_parser, help="Attach an EBS volume to an EC2 instance")
def ensure_subnet(vpc, availability_zone=None):
if availability_zone is not None and availability_zone not in availability_zones():
msg = "Unknown availability zone {} (choose from {})"
raise AegeaException(msg.format(availability_zone, list(availability_zones())))
for subnet in vpc.subnets.all():
if availability_zone is not None and subnet.availability_zone != availability_zone:
continue
break
else:
from ipaddress import ip_network
from ... import config
subnet_cidrs = ip_network(str(config.vpc.cidr[ARN.get_region()])).subnets(new_prefix=config.vpc.subnet_prefix)
subnets = {}
for az, subnet_cidr in zip(availability_zones(), subnet_cidrs):
logger.info("Creating subnet with CIDR %s in %s, %s", subnet_cidr, vpc, az)
subnets[az] = resources.ec2.create_subnet(VpcId=vpc.id, CidrBlock=str(subnet_cidr), AvailabilityZone=az)
clients.ec2.get_waiter("subnet_available").wait(SubnetIds=[subnets[az].id])
add_tags(subnets[az], Name=__name__)
clients.ec2.modify_subnet_attribute(SubnetId=subnets[az].id,
MapPublicIpOnLaunch=dict(Value=config.vpc.map_public_ip_on_launch))
subnet = subnets[availability_zone] if availability_zone is not None else list(subnets.values())[0]
return subnet
def watch(args):
_, cluster, task_id = ARN(args.task_arn).resource.split("/")
logger.info("Watching task %s (%s)", task_id, cluster)
last_status, events_received = None, 0
while last_status != "STOPPED":
res = clients.ecs.describe_tasks(cluster=cluster, tasks=[args.task_arn])
if len(res["tasks"]) == 1:
task_desc = res["tasks"][0]
if task_desc["lastStatus"] != last_status:
logger.info("Task %s %s", args.task_arn, format_task_status(task_desc["lastStatus"]))
last_status = task_desc["lastStatus"]
try:
for event in CloudwatchLogReader("/".join([args.task_name, args.task_name, task_id]),
log_group_name=args.task_name):
print(str(Timestamp(event["timestamp"])), event["message"])
events_received += 1
except ClientError as e:
expect_error_codes(e, "ResourceNotFoundException")
if last_status is None and events_received > 0:
break # Logs retrieved successfully but task record is no longer in ECS
time.sleep(1)
def watch(args):
job_desc = get_job_desc(args.job_id)
args.job_name = job_desc["jobName"]
logger.info("Watching job %s (%s)", args.job_id, args.job_name)
last_status = None
while last_status not in {"SUCCEEDED", "FAILED"}:
job_desc = get_job_desc(args.job_id)
if job_desc["status"] != last_status:
logger.info("Job %s %s", args.job_id, format_job_status(job_desc["status"]))
last_status = job_desc["status"]
if job_desc["status"] in {"RUNNING", "SUCCEEDED", "FAILED"}:
logger.info("Job %s log stream: %s", args.job_id, job_desc.get("container", {}).get("logStreamName"))
save_job_desc(job_desc)
if job_desc["status"] in {"RUNNING", "SUCCEEDED", "FAILED"} and "logStreamName" in job_desc["container"]:
args.log_stream_name = job_desc["container"]["logStreamName"]
get_logs(args)
if "statusReason" in job_desc:
logger.info("Job %s: %s", args.job_id, job_desc["statusReason"])
if job_desc.get("container", {}).get("exitCode"):
return SystemExit(job_desc["container"]["exitCode"])
try:
ec2_key_pairs = list(resources.ec2.key_pairs.filter(KeyNames=[name]))
if verify_pem_file and not os.path.exists(get_ssh_key_path(name)):
msg = "Key {} found in EC2, but not in ~/.ssh."
msg += " Delete the key in EC2, copy it to {}, or specify another key."
raise KeyError(msg.format(name, get_ssh_key_path(name)))
except ClientError as e:
expect_error_codes(e, "InvalidKeyPair.NotFound")
ec2_key_pairs = None
if not ec2_key_pairs:
ssh_key = ensure_local_ssh_key(name)
resources.ec2.import_key_pair(KeyName=name,
PublicKeyMaterial=get_public_key_from_pair(ssh_key))
logger.info("Imported SSH key %s", get_ssh_key_path(name))
add_ssh_key_to_agent(name)
return name
def ensure_local_ssh_key(name):
from paramiko import RSAKey
if os.path.exists(get_ssh_key_path(name)):
ssh_key = RSAKey.from_private_key_file(get_ssh_key_path(name))
else:
logger.info("Creating key pair %s", name)
ssh_key = new_ssh_key()
makedirs(os.path.dirname(get_ssh_key_path(name)), exist_ok=True)
ssh_key.write_private_key_file(get_ssh_key_path(name))
return ssh_key
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,
export_task_args.update(destinationPrefix=cache_key)
for log_object in bucket.objects.filter(Prefix=cache_key):
logger.debug("Reusing completed export task %s", log_object.key)
break
else:
logger.debug("Starting new log export task %s", export_task_args)
task_desc = clients.logs.create_export_task(**export_task_args)
try:
while task_desc.get("status", {}).get("code") != "COMPLETED":
res = clients.logs.describe_export_tasks(taskId=task_desc["taskId"])
assert len(res["exportTasks"]) == 1
task_desc = res["exportTasks"][0]
if task_desc["status"]["code"] in {"CANCELLED", "FAILED"}:
raise Exception("Log export task failed: " + task_desc["status"]["message"])
msg = "log export task: {logGroupName} {from}..{to} -> s3://{destination}/{destinationPrefix} %s"
logger.info(msg.format(**task_desc), task_desc["status"]["code"])
time.sleep(1)
finally:
try:
clients.logs.cancel_export_task(taskId=task_desc["taskId"])
# TODO: if cancel successful, clean up s3 prefix
except Exception:
pass
return bucket.objects.filter(Prefix=cache_key)
def ssh(args):
job_desc = clients.batch.describe_jobs(jobs=[args.job_id])["jobs"][0]
job_queue_desc = clients.batch.describe_job_queues(jobQueues=[job_desc["jobQueue"]])["jobQueues"][0]
ce = job_queue_desc["computeEnvironmentOrder"][0]["computeEnvironment"]
ce_desc = clients.batch.describe_compute_environments(computeEnvironments=[ce])["computeEnvironments"][0]
ecs_ci_arn = job_desc["container"]["containerInstanceArn"]
ecs_ci_desc = clients.ecs.describe_container_instances(cluster=ce_desc["ecsClusterArn"],
containerInstances=[ecs_ci_arn])["containerInstances"][0]
ecs_ci_ec2_id = ecs_ci_desc["ec2InstanceId"]
for reservation in paginate(clients.ec2.get_paginator("describe_instances"), InstanceIds=[ecs_ci_ec2_id]):
ecs_ci_address = reservation["Instances"][0]["PublicDnsName"]
logger.info("Job {} is on ECS container instance {} ({})".format(args.job_id, ecs_ci_ec2_id, ecs_ci_address))
ssh_args = ["ssh", "-l", "ec2-user", ecs_ci_address,
"docker", "ps", "--filter", "name=" + args.job_id, "--format", "{{.ID}}"]
logger.info("Running: {}".format(" ".join(ssh_args)))
container_id = subprocess.check_output(ssh_args).decode().strip()
subprocess.call(["ssh", "-t", "-l", "ec2-user", ecs_ci_address,
"docker", "exec", "--interactive", "--tty", container_id] + (args.ssh_args or ["/bin/bash", "-l"]))