Ejemplo n.º 1
0
def detach_volume():
    """Create a snapshot of a volume identified by it's mount path"""
    parser = _get_parser()
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m",
                       "--mount-path",
                       help="Mount point of the volume to be detached"
                       ).completer = FilesCompleter()
    group.add_argument(
        "-i", "--volume-id",
        help="Volume id to detach").completer = ChoicesCompleter(
            info().volume_ids())
    group.add_argument("-d", "--device",
                       help="Device to detach").completer = ChoicesCompleter(
                           info().volume_ids())
    parser.add_argument("-x",
                        "--delete",
                        help="Delete volume after detaching",
                        action="store_true")
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    if is_ec2():
        ebs.detach_volume(
            mount_path=args.mount_path,
            volume_id=args.volume_id,
            device=args.device,
            delete_volume=args.delete,
        )
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 2
0
def list_attached_enis():
    """List all enis in the same availability-zone, i.e. ones that can be attached
    to this instance.
    """
    parser = _get_parser()
    group = parser.add_mutually_exclusive_group()
    group.add_argument(
        "-i",
        "--ip-address",
        help=
        "Include first private ip addresses for the interfaces in the output",
        action="store_true",
    )
    group.add_argument(
        "-f",
        "--full",
        help="Print all available data about attached enis as json",
        action="store_true",
    )
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    if is_ec2():
        enis = info().network_interfaces()
        if args.full:
            print(json.dumps(enis, indent=2, default=dthandler))
        else:
            for eni in enis:
                ip_addr = (":" +
                           eni["PrivateIpAddresses"][0]["PrivateIpAddress"]
                           if args.ip_address and "PrivateIpAddresses" in eni
                           and eni["PrivateIpAddresses"] and "PrivateIpAddress"
                           in eni["PrivateIpAddresses"][0] else "")
                print(eni["NetworkInterfaceId"] + ip_addr)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 3
0
def subnet_id():
    """Get subnet id for instance"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        print(info().subnet_id())
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 4
0
def snapshot_from_volume():
    """Create a snapshot of a volume identified by it's mount path"""
    parser = _get_parser()
    parser.add_argument(
        "-w",
        "--wait",
        help="Wait for the snapshot to finish" + " before returning",
        action="store_true",
    )
    parser.add_argument("tag_key", help="Key of the tag to find volume with")
    parser.add_argument("tag_value",
                        help="Value of the tag to find volume with")
    parser.add_argument("mount_path", help="Where to mount the volume")
    parser.add_argument(
        "-c",
        "--copytags",
        nargs="*",
        help=
        "Tag to copy to the snapshot from instance. Multiple values allowed.",
    )
    parser.add_argument(
        "-t",
        "--tags",
        nargs="*",
        help=
        "Tag to add to the snapshot in the format name=value. Multiple values allowed.",
    )
    parser.add_argument(
        "-i",
        "--ignore-missing-copytags",
        action="store_true",
        help="If set, missing copytags are ignored.",
    )
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    tags = {}
    if args.tags:
        for tag in args.tags:
            try:
                key, value = tag.split("=", 1)
                tags[key] = value
            except ValueError:
                parser.error("Invalid tag/value input: " + tag)
    if is_ec2():
        print(
            ebs.create_snapshot(
                args.tag_key,
                args.tag_value,
                args.mount_path,
                wait=args.wait,
                tags=tags,
                copytags=args.copytags,
                ignore_missing_copytags=args.ignore_missing_copytags,
            ))
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 5
0
def list_tags():
    """List all tags associated with the instance"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        for key, value in info().tags().items():
            print(key + "=" + value)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 6
0
def list_attached_volumes():
    """List attached volumes"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    _ = parser.parse_args()
    if is_ec2():
        for volume_id in info().volume_ids():
            print(volume_id)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 7
0
def cf_stack_id():
    """Get id of the stack the creted this instance"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        print(info().stack_id())
    else:
        parser.error(
            "Only makes sense on an EC2 instance cretated from a CF stack")
Ejemplo n.º 8
0
def cf_logical_id():
    """Get the logical id that is expecting a signal from this instance"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        print(info().logical_id())
    else:
        parser.error(
            "Only makes sense on an EC2 instance cretated from a CF stack")
Ejemplo n.º 9
0
def availability_zone():
    """Get availability zone for the instance"""
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        print(info().availability_zone())
    else:
        parser.error(
            "Only makes sense on an EC2 instance cretated from a CF stack")
Ejemplo n.º 10
0
def list_compatible_subnets():
    """List all subnets in the same availability-zone, i.e. ones that can have
    ENIs that can be attached to this instance.
    """
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    parser.parse_args()
    if is_ec2():
        for subnet_id in interface.list_compatible_subnet_ids():
            print(subnet_id)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 11
0
def list_attachable_enis():
    """List all enis in the same availability-zone, i.e. ones that can be attached
    to this instance.
    """
    parser = _get_parser()
    argcomplete.autocomplete(parser)
    _ = parser.parse_args()
    if is_ec2():
        for eni_id in interface.list_attachable_eni_ids():
            print(eni_id)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 12
0
def get_tag():
    """Get the value of a tag for an ec2 instance"""
    parser = _get_parser()
    parser.add_argument("name", help="The name of the tag to get")
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    if is_ec2():
        value = info().tag(args.name)
        if value is not None:
            print(value)
        else:
            sys.exit("Tag " + args.name + " not found")
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 13
0
def volume_info():
    """Get information about an EBS volume via a mountpoint, device or volume-id"""
    parser = _get_parser()
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m",
                       "--mount-path",
                       help="Mount point of the volume to be detached"
                       ).completer = FilesCompleter()
    group.add_argument(
        "-i", "--volume-id",
        help="Volume id to detach").completer = ChoicesCompleter(
            info().volume_ids())
    group.add_argument("-d", "--device",
                       help="Device to detach").completer = ChoicesCompleter(
                           info().volume_ids())
    parser.add_argument(
        "-j",
        "--jmespath",
        help=
        "A jemspath expression to get a specific piece of info from volume",
    )
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    if is_ec2():
        vol_info = ebs.volume_info(mount_path=args.mount_path,
                                   volume_id=args.volume_id,
                                   device=args.device)
        if vol_info:
            if args.jmespath:
                vol_info = search(args.jmespath, vol_info)
            if isinstance(vol_info, dict):
                print(json.dumps(vol_info, indent=2, default=dthandler))
            else:
                print(str(vol_info))
        else:
            print("No volume info found")
            exit(1)
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 14
0
def volume_from_snapshot():
    """Create a volume from an existing snapshot and mount it on the given
    path. The snapshot is identified by a tag key and value. If no tag is
    found, an empty volume is created, attached, formatted and mounted.
    """
    parser = _get_parser()
    parser.add_argument("tag_key", help="Key of the tag to find volume with")
    parser.add_argument("tag_value",
                        help="Value of the tag to find volume with")
    parser.add_argument("mount_path", help="Where to mount the volume")
    parser.add_argument(
        "size_gb",
        nargs="?",
        help="Size in GB for the volum" + "e. If different from sna" +
        "pshot size, volume and " + "filesystem are resized",
        default=None,
        type=int,
    )
    parser.add_argument(
        "-n",
        "--no_delete_on_termination",
        help="Whether to skip deleting the volume on termi" +
        "nation, defaults to false",
        action="store_true",
    )
    parser.add_argument(
        "-c",
        "--copytags",
        nargs="*",
        help=
        "Tag to copy to the volume from instance. Multiple values allowed.",
    )
    parser.add_argument(
        "-t",
        "--tags",
        nargs="*",
        help=
        "Tag to add to the volume in the format name=value. Multiple values allowed.",
    )
    parser.add_argument(
        "-i",
        "--ignore-missing-copytags",
        action="store_true",
        help="If set, missing copytags are ignored.",
    )
    parser.add_argument(
        "-u",
        "--unencrypted",
        action="store_false",
        help="If set, create unencrypted volume",
    )
    volume_type_arg = parser.add_mutually_exclusive_group(required=False)
    volume_type_arg.add_argument("--gp2",
                                 action="store_true",
                                 help="GP2 volume type (default)")
    volume_type_arg.add_argument("--gp3",
                                 action="store_true",
                                 help="GP3 volume type")
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    tags = {}
    if args.tags:
        for tag in args.tags:
            try:
                key, value = tag.split("=", 1)
                tags[key] = value
            except ValueError:
                parser.error("Invalid tag/value input: " + tag)
    if args.gp3:
        volume_type = "gp3"
    else:
        volume_type = "gp2"
    if is_ec2():
        ebs.volume_from_snapshot(
            args.tag_key,
            args.tag_value,
            args.mount_path,
            size_gb=args.size_gb,
            del_on_termination=not args.no_delete_on_termination,
            copytags=args.copytags,
            tags=tags,
            ignore_missing_copytags=args.ignore_missing_copytags,
            encrypted=args.unencrypted,
            volume_type=volume_type,
        )
    else:
        parser.error("Only makes sense on an EC2 instance")
Ejemplo n.º 15
0
 def __init__(self):
     if (os.path.isfile(INSTANCE_DATA)
             and time.time() - os.path.getmtime(INSTANCE_DATA) < 900):
         try:
             self._info = json.load(open(INSTANCE_DATA))
         except BaseException:
             pass
     if not self._info and is_ec2():
         try:
             if not wait_net_service("169.254.169.254", 80, 120):
                 raise Exception(
                     "Failed to connect to instance identity service")
             response = get_retry(INSTANCE_IDENTITY_URL)
             self._info = json.loads(response.text)
             os.environ["AWS_DEFAULT_REGION"] = self.region()
             instance_info = {}
             try:
                 instance_info = _get_instance_info(
                     self._info["instanceId"])
             except ClientError:
                 pass
             if instance_info:
                 self._info.update(instance_info)
             tags = {}
             tag_response = {"Tags": []}
             try:
                 tag_response = self._get_tag_response()
             except ClientError:
                 pass
             for tag in tag_response["Tags"]:
                 tags[tag["Key"]] = tag["Value"]
             self._info["Tags"] = tags
             if "aws:cloudformation:stack-name" in self._info["Tags"]:
                 self._info["stack_name"] = tags[
                     "aws:cloudformation:stack-name"]
             if "aws:cloudformation:stack-id" in self._info["Tags"]:
                 self._info["stack_id"] = tags[
                     "aws:cloudformation:stack-id"]
             if self.stack_name():
                 stack_parameters, stack = stack_params_and_outputs_and_stack(
                     stack_name=self.stack_name())
                 self._info["StackData"] = stack_parameters
                 self._info["FullStackData"] = stack
         except ConnectionError:
             self._info = {}
         info_file = None
         info_file_dir = tempfile.gettempdir()
         info_file_parent = os.path.dirname(info_file_dir)
         if not os.path.isdir(info_file_dir) and os.access(
                 info_file_parent, os.W_OK):
             os.makedirs(info_file_dir)
         if not os.access(info_file_dir, os.W_OK):
             home = expanduser("~")
             info_file_dir = home + os.sep + ".ndt"
         if not os.path.isdir(info_file_dir) and os.access(
                 info_file_parent, os.W_OK):
             os.makedirs(info_file_dir)
         if os.access(info_file_dir, os.W_OK):
             info_file = info_file_dir + os.sep + "instance-data.json"
             with open(info_file, "w") as outf:
                 outf.write(
                     json.dumps(self._info,
                                skipkeys=True,
                                indent=2,
                                default=dthandler))
                 try:
                     os.chmod(info_file, 0o666)
                     os.chmod(info_file_dir, 0o777)
                 except BaseException:
                     pass
     if self.region():
         os.environ["AWS_DEFAULT_REGION"] = self.region()
     if ("FullStackData" in self._info
             and "StackStatus" in self._info["FullStackData"]):
         self._info["initial_status"] = self._info["FullStackData"][
             "StackStatus"]
     if "Tags" in self._info:
         tags = self._info["Tags"]
         if "aws:cloudformation:stack-name" in tags:
             self._info["stack_name"] = tags[
                 "aws:cloudformation:stack-name"]
         if "aws:cloudformation:stack-id" in tags:
             self._info["stack_id"] = tags["aws:cloudformation:stack-id"]
         if "aws:cloudformation:logical-id" in tags:
             self._info["logical_id"] = tags[
                 "aws:cloudformation:logical-id"]