class UploadServerCertificate(IAMRequest):
    DESCRIPTION = 'Upload a server certificate'
    ARGS = [Arg('-s', '--server-certificate-name', metavar='CERTNAME',
                dest='ServerCertificateName', required=True,
                help='name to give the new server certificate (required)'),
            MutuallyExclusiveArgList(
                Arg('-c', '--certificate-body', dest='CertificateBody',
                    metavar='CERT', help='PEM-encoded certificate'),
                Arg('--certificate-file', dest='CertificateBody',
                    metavar='FILE', type=open,
                    help='file containing the PEM-encoded certificate'))
            .required(),
            MutuallyExclusiveArgList(
                Arg('--private-key', dest='PrivateKey', metavar='KEY',
                    help='PEM-encoded private key'),
                Arg('--private-key-file', dest='PrivateKey', metavar='FILE',
                    type=open,
                    help='file containing the PEM-encoded private key'))
            .required(),
            MutuallyExclusiveArgList(
                Arg('--certificate-chain', dest='CertificateChain',
                    metavar='CHAIN', help='''PEM-encoded certificate chain.
                    This is typically the PEM-encoded certificates of the
                    chain, concatenated together.'''),
                Arg('--certificate-chain-file', dest='CertificateChain',
                    metavar='FILE', help='''file containing the PEM-encoded
                    certificate chain. This is typically the PEM-encoded
                    certificates of the chain, concatenated together.''')),
            Arg('-p', '--path', dest='Path',
                help='path for the new server certificate (default: "/")'),
            AS_ACCOUNT]
Пример #2
0
class AssociateAddress(EC2Request):
    DESCRIPTION = 'Associate an elastic IP address with a running instance'
    ARGS = [Arg('PublicIp', metavar='ADDRESS', nargs='?', help='''[Non-VPC
                only] IP address to associate (required)'''),
            Arg('-a', '--allocation-id', dest='AllocationId', metavar='ALLOC',
                help='[VPC only] VPC allocation ID (required)'),
            MutuallyExclusiveArgList(
                Arg('-i', '--instance-id', dest='InstanceId',
                    metavar='INSTANCE', help='''ID of the instance to associate
                    the address with'''),
                Arg('-n', '--network-interface', dest='NetworkInterfaceId',
                    metavar='INTERFACE', help='''[VPC only] network interface
                    to associate the address with'''))
            .required(),
            Arg('-p', '--private-ip-address', dest='PrivateIpAddress',
                metavar='ADDRESS', help='''[VPC only] the private address to
                associate with the address being associated in the VPC
                (default: primary private IP)'''),
            MutuallyExclusiveArgList(
                Arg('--allow-reassociation', dest='AllowReassociation',
                    action='store_const', const='true',
                    help='''[VPC only] allow the address to be associated even
                    if it is already associated with another interface'''),
                Arg('--no-allow-reassociation', dest='AllowReassociation',
                    action='store_const', const='false',
                    help='''[VPC only] do not allow the address to be associated
                    if it is already associated with another interface'''))]

    # noinspection PyExceptionInherit
    def configure(self):
        EC2Request.configure(self)
        if (self.args.get('PublicIp') is not None and
                self.args.get('AllocationId') is not None):
            # Can't be both EC2 and VPC
            raise ArgumentError(
                'argument -a/--allocation-id: not allowed with an IP address')
        if (self.args.get('PublicIp') is None and
                self.args.get('AllocationId') is None):
            # ...but we still have to be one of them
            raise ArgumentError(
                'argument -a/--allocation-id or an IP address is required')
        if (self.args.get('PublicIp') or '').startswith('eipalloc-'):
            # Make allocation IDs work positionally for convenience
            self.params['AllocationId'] = self.params.pop('PublicIp')

    def print_result(self, result):
        if self.args.get('AllocationId'):
            # VPC
            print self.tabify(('ADDRESS', self.args.get('InstanceId'),
                               self.args.get('AllocationId'),
                               result.get('associationId'),
                               self.args.get('PrivateIpAddress')))
        else:
            # EC2
            print self.tabify(('ADDRESS', self.args.get('PublicIp'),
                               self.args.get('InstanceId')))
Пример #3
0
class UpdateStack(CloudFormationRequest):
    DESCRIPTION = 'Update a stack with a new template'
    ARGS = [
        Arg('StackName',
            metavar='STACK',
            help='name of the stack to update (required)'),
        MutuallyExclusiveArgList(
            Arg('--template-file',
                dest='TemplateBody',
                metavar='FILE',
                type=open,
                help='file containing a new JSON template for the stack'),
            Arg('--template-url',
                dest='TemplateURL',
                metavar='URL',
                help='URL pointing to a new JSON template for the stack')).
        required(),
        Arg('--capabilities',
            dest='Capabilities.member',
            metavar='CAP[,...]',
            type=delimited_list(','),
            help='capabilities needed to update the stack'),
        Arg('-p',
            '--parameter',
            dest='param_sets',
            route_to=None,
            metavar='KEY=VALUE',
            type=parameter_list,
            action='append',
            help='''key and value of the parameters to use with the
                stack's template, separated by an "=" character'''),
        MutuallyExclusiveArgList(
            Arg('--tag',
                dest='Tags.member',
                metavar='KEY[=VALUE]',
                type=binary_tag_def,
                action='append',
                help='''key and optional value of a tag to add, separated
                    by an "=" character.  If no value is given the tag's value
                    is set to an empty string.'''),
            Arg('--delete-tags',
                dest='Tags',
                action='store_const',
                const=EMPTY,
                help='remove all tags associated with the stack'))
    ]

    def configure(self):
        CloudFormationRequest.configure(self)
        stack_params = sum(self.args.get('param_sets') or [], [])
        self.params['Parameters.member'] = stack_params

    # pylint: disable=no-self-use
    def print_result(self, result):
        print result.get('StackId')
Пример #4
0
class MigrateInstances(EC2Request):
    DESCRIPTION = ('Migrate one instance from its current host, or '
                   'migrate all instances from a specific host')
    ARGS = [
        MutuallyExclusiveArgList(
            Arg('-s',
                '--source',
                dest='SourceHost',
                metavar='HOST',
                help='remove all instances from a specific host'),
            Arg('-i',
                '--instance',
                dest='InstanceId',
                metavar='INSTANCE',
                help='remove one instance from its current host')).required(),
        MutuallyExclusiveArgList(
            Arg('--include-dest',
                action='append',
                route_to=None,
                metavar='HOST',
                help='''allow migration to only a
                    specific host (may be used more than once)'''),
            Arg('--exclude-dest',
                action='append',
                route_to=None,
                metavar='HOST',
                help='''allow migration to any host
                    except a specific one (may be used more than once)''')),
        Arg('--stop-source',
            action='store_true',
            route_to=None,
            help='''also stop the source host to prevent new instances
                from running on it (requires -s/--source)''')
    ]

    def configure(self):
        EC2Request.configure(self)
        if self.args.get('stop_source') and not self.args.get('source'):
            raise ArgumentError('argument --stop-source: only allowed '
                                'with -s/--source')

    def preprocess(self):
        if self.args.get('include_dest'):
            self.params['AllowHosts'] = True
            self.params['DestinationHost'] = self.args['include_dest']
        elif self.args.get('exclude_dest'):
            self.params['AllowHosts'] = False
            self.params['DestinationHost'] = self.args['exclude_dest']

    def postprocess(self, _):
        req = ModifyService.from_other(self,
                                       Name=self.args['source'],
                                       State='STOP')
        req.main()
Пример #5
0
class GetTemplateSummary(CloudFormationRequest):
    DESCRIPTION = "Summarize a template"
    ARGS = [MutuallyExclusiveArgList(
        Arg('StackName', metavar='STACK', nargs='?', help='''name or ID of the
            stack (names cannot be used for deleted stacks)'''),
        Arg('--template-file', dest='TemplateBody',
            metavar='FILE', type=open,
            help='file location containing JSON template'),
        Arg('--template-url', dest='TemplateURL',
            metavar='URL', help='S3 URL for JSON template'))
            .required()]
    LIST_TAGS = ['Capabilities', 'Parameters', 'ResourceTypes']

    def print_result(self, result):
        if result.get('Description'):
            print self.tabify(('DESCRIPTION', result.get('Description')))
        for cap in result.get('Capabilities') or []:
            print self.tabify(('CAPABILITY', cap))
        if result.get('CapabilitiesReason'):
            print self.tabify(('CAPABILITYREASON',
                               result.get('CapabilitiesReason')))
        for res in result.get('ResourceTypes') or []:
            print self.tabify(('RESOURCETYPES', res))
        for param in result.get('Parameters') or []:
            print self.tabify(('PARAMETER', param.get('ParameterKey'),
                               param.get('NoEcho'), param.get('DefaultValue'),
                               param.get('Description')))
        if result.get('Metadata'):
            print self.tabify(('METADATA', result.get('Metadata')))
Пример #6
0
class PutUserPolicy(IAMRequest):
    DESCRIPTION = 'Attach a policy to a user'
    ARGS = [
        Arg('-u',
            '--user-name',
            dest='UserName',
            metavar='USER',
            required=True,
            help='user to attach the policy to (required)'),
        Arg('-p',
            '--policy-name',
            dest='PolicyName',
            metavar='POLICY',
            required=True,
            help='name of the policy (required)'),
        MutuallyExclusiveArgList(
            Arg('-o',
                '--policy-content',
                dest='PolicyDocument',
                metavar='POLICY_CONTENT',
                help='the policy to attach'),
            Arg('-f',
                '--policy-document',
                dest='PolicyDocument',
                metavar='FILE',
                type=open,
                help='file containing the policy to attach')).required(),
        AS_ACCOUNT
    ]
Пример #7
0
class PutMetricData(CloudWatchRequest):
    DESCRIPTION = 'Add data points or statistics to a metric'
    ARGS = [Arg('-m', '--metric-name', dest='MetricData.member.1.MetricName',
                metavar='METRIC', required=True,
                help='name of the metric to add data points to (required)'),
            Arg('-n', '--namespace', dest='Namespace', required=True,
                help="the metric's namespace (required)"),
            MutuallyExclusiveArgList(
                Arg('-v', '--value', dest='MetricData.member.1.Value',
                    metavar='FLOAT', type=float,
                    help='data value for the metric'),
                Arg('-s', '--statistic-values', '--statisticValues',
                    dest='MetricData.member.1.StatisticValues',
                    metavar=('Maximum=FLOAT,Minimum=FLOAT,SampleCount=FLOAT,'
                             'Sum=FLOAT'), type=_statistic_set,
                    help='''statistic values for the metric.  Maximum, Minimum,
                    SampleCount, and Sum values are all required.'''))
            .required(),
            Arg('-d', '--dimensions', dest='Dimensions.member',
                metavar='KEY1=VALUE1,KEY2=VALUE2,...',
                type=delimited_list(',', item_type=cloudwatch_dimension),
                help='the dimensions of the metric to add data points to'),
            Arg('-t', '--timestamp', dest='MetricData.member.1.Timestamp',
                metavar='YYYY-MM-DDThh:mm:ssZ',
                help='timestamp of the data point'),
            Arg('-u', '--unit', dest='MetricData.member.1.Unit',
                metavar='UNIT', help='unit the metric is being reported in')]
Пример #8
0
class CreateStack(CloudFormationRequest):
    DESCRIPTION = 'Create a new stack'
    ARGS = [Arg('StackName', metavar='STACK',
                help='name of the new stack (required)'),
            MutuallyExclusiveArgList(
                Arg('--template-file', dest='TemplateBody', metavar='FILE',
                    type=open,
                    help="file containing the new stack's JSON template"),
                Arg('--template-url', dest='TemplateURL', metavar='URL',
                    help="URL pointing to the new stack's JSON template"))
            .required(),
            Arg('-d', '--disable-rollback', dest='DisableRollback',
                action='store_true', help='disable rollback on failure'),
            Arg('-n', '--notification-arns', dest='NotificationARNs',
                metavar='ARN[,...]', type=delimited_list(','), action='append',
                help='''SNS ARNs to publish stack actions to'''),
            Arg('-p', '--parameter', dest='param_sets', route_to=None,
                metavar='KEY=VALUE', type=parameter_list, action='append',
                help='''key and value of the parameters to use with the new
                stack's template, separated by an "=" character'''),
            Arg('-t', '--timeout', dest='TimeoutInMinutes', type=int,
                metavar='MINUTES', help='timeout for stack creation'),
            Arg('--tag', dest='Tags.member', metavar='KEY[=VALUE]',
                type=binary_tag_def, action='append',
                help='''key and optional value of the tag to create, separated
                by an "=" character.  If no value is given the tag's value is
                set to an empty string.''')]

    def configure(self):
        CloudFormationRequest.configure(self)
        stack_params = sum(self.args.get('param_sets') or [], [])
        self.params['Parameters.member'] = stack_params

    def print_result(self, result):
        print result.get('StackId')
Пример #9
0
class UpdateStack(CloudFormationRequest):
    DESCRIPTION = 'Update a stack with a new template'
    ARGS = [
        Arg('StackName',
            metavar='STACK',
            help='name of the stack to update (required)'),
        MutuallyExclusiveArgList(
            Arg('--template-file',
                dest='TemplateBody',
                metavar='FILE',
                type=open,
                help='file containing a new JSON template for the stack'),
            Arg('--template-url',
                dest='TemplateURL',
                metavar='URL',
                help='URL pointing to a new JSON template for the stack')).
        required(),
        Arg('-p',
            '--parameter',
            dest='param_sets',
            route_to=None,
            metavar='KEY=VALUE',
            type=parameter_list,
            action='append',
            help='''key and value of the parameters to use with the
                stack's template, separated by an "=" character''')
    ]

    def configure(self):
        CloudFormationRequest.configure(self)
        stack_params = sum(self.args.get('param_sets') or [], [])
        self.params['Parameters.member'] = stack_params

    def print_result(self, result):
        print result.get('StackId')
Пример #10
0
class TerminateInstanceInAutoScalingGroup(AutoScalingRequest,
                                          TabifyingMixin):
    DESCRIPTION = "Manually terminate an auto-scaling instance"
    ARGS = [Arg('InstanceId', metavar='INSTANCE',
                help='ID of the instance to terminate (required)'),
            MutuallyExclusiveArgList(True,
                Arg('-d', '--decrement-desired-capacity', action='store_const',
                    dest='ShouldDecrementDesiredCapacity', const='true',
                    help='''also reduce the desired capacity of the
                    auto-scaling group by 1'''),
                Arg('-D', '--no-decrement-desired-capacity',
                    dest='ShouldDecrementDesiredCapacity',
                    action='store_const', const='false',
                    help='''leave the auto-scaling group's desired capacity
                    as-is.  A new instance may be launched to compensate for
                    the one being terminated.''')),
            Arg('--show-long', action='store_true', route_to=None,
                help='show extra info about the instance being terminated'),
            Arg('-f', '--force', action='store_true', route_to=None,
                help=argparse.SUPPRESS)]  # for compatibility

    def print_result(self, result):
        activity = result['Activity']
        bits = ['INSTANCE',
                activity.get('ActivityId'),
                activity.get('EndTime'),
                activity.get('StatusCode'),
                activity.get('Cause')]
        if self.args['show_long']:
            bits.append(activity.get('StatusMessage'))
            bits.append(activity.get('Progress'))
            bits.append(activity.get('Description'))
            bits.append(activity.get('StartTime'))
        print self.tabify(bits)
Пример #11
0
class CreateRoute(EC2Request):
    DESCRIPTION = 'Add a route to a VPC route table'
    ARGS = [Arg('RouteTableId', metavar='RTABLE',
                help='ID of the route table to add the route to (required)'),
            Arg('-r', '--cidr', dest='DestinationCidrBlock',
                metavar='CIDR', required=True,
                help='CIDR address block the route should affect (required)'),
            MutuallyExclusiveArgList(
                Arg('-g', '--gateway-id', metavar='GATEWAY', route_to=None,
                    help='ID of an Internet, NAT, or virtual private '
                         'gateway to target'),
                Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE',
                    help='ID of a NAT instance to target'),
                Arg('-n', '--network-interface', dest='NetworkInterfaceId',
                    help='ID of a network interface to target'),
                Arg('-p', '--vpc-peering-connection', metavar='PEERCON',
                    dest='VpcPeeringConnectionId',
                    help='ID of a VPC peering connection to target'))
            .required()]

    def configure(self):
        EC2Request.configure(self)
        gateway_id = self.args['gateway_id']
        if gateway_id:
            if gateway_id.startswith('nat-'):
                self.params['NatGatewayId'] = gateway_id
            else:
                self.params['GatewayId'] = gateway_id

    def print_result(self, _):
        target = (self.args.get('GatewayId') or self.args.get('InstanceId') or
                  self.args.get('NetworkInterfaceId') or
                  self.args.get('NatGatewayId') or
                  self.args.get('VpcPeeringConnectionId'))
        print self.tabify(('ROUTE', target, self.args['DestinationCidrBlock']))
Пример #12
0
class ValidateTemplate(CloudFormationRequest):
    DESCRIPTION = 'Validate a template'
    ARGS = [
        MutuallyExclusiveArgList(
            Arg('--template-file',
                dest='TemplateBody',
                metavar='FILE',
                type=open,
                help='file location containing JSON template'),
            Arg('--template-url',
                dest='TemplateURL',
                metavar='URL',
                help='S3 URL for JSON template')).required()
    ]
    LIST_TAGS = ['Parameters', 'Capabilities']

    def print_result(self, result):
        print self.tabify(('DESCRIPTION', result.get('Description')))
        for cap in result.get('Capabilities') or []:
            print self.tabify(('CAPABILITY', cap))
        if result.get('CapabilitiesReason'):
            print self.tabify(
                ('CAPABILITIESREASON', result['CapabilitiesReason']))
        for param in result.get('Parameters') or []:
            print self.tabify(
                ('PARAMETER', param.get('ParameterKey'), param.get('NoEcho'),
                 param.get('DefaultValue'), param.get('Description')))
class DescribeNetworkInterfaceAttribute(EC2Request):
    DESCRIPTION = 'Show an attribute of a VPC network interface'
    ARGS = [
        Arg('NetworkInterfaceId',
            metavar='INTERFACE',
            help='''ID of the
                network interface to show info for (required)'''),
        MutuallyExclusiveArgList(
            Arg('-d',
                '--description',
                dest='Attribute',
                action='store_const',
                const='description',
                help="show the interface's description"),
            Arg('--source-dest-check',
                dest='Attribute',
                action='store_const',
                const='sourceDestCheck',
                help='''show whether source/destination address
                    checking is enabled'''),
            Arg('--group-set',
                dest='Attribute',
                action='store_const',
                const='groupSet',
                help='''show the security groups the
                    network interface belongs to'''),
            Arg('-a',
                '--attachment',
                dest='Attribute',
                action='store_const',
                const='attachment',
                help='''show info
                    about the interface's attachment (if any)''')).required()
    ]

    LIST_TAGS = ['groupSet']

    def print_result(self, result):
        print self.tabify(
            ('NETWORKINTERFACE', result.get('networkInterfaceId'),
             self.args['Attribute']))
        if self.args['Attribute'] == 'description':
            print self.tabify(
                ('DESCRIPTION', result['description'].get('value')))
        elif self.args['Attribute'] == 'sourceDestCheck':
            print self.tabify(
                ('SOURCEDESTCHECK', result['sourceDestCheck'].get('value')))
        elif self.args['Attribute'] == 'groupSet':
            for group in result.get('groupSet') or []:
                print self.tabify(
                    ('GROUP', group.get('groupId'), group.get('groupName')))
        elif self.args['Attribute'] == 'attachment':
            attachment = result.get('attachment')
            if attachment:
                attachment_info = [
                    attachment.get(attr)
                    for attr in ('attachmentID', 'deviceIndex', 'status',
                                 'attachTime', 'deleteOnTermination')
                ]
                print self.tabify(['ATTACHMENT'] + attachment_info)
Пример #14
0
class DescribeVpcAttribute(EC2Request):
    DESCRIPTION = 'Show an attribute of a VPC'
    ARGS = [
        Arg('VpcId',
            metavar='VPC',
            help='ID of the VPC to show info for (required)'),
        MutuallyExclusiveArgList(
            Arg('-d',
                '--dns-hostnames',
                dest='Attribute',
                action='store_const',
                const='enableDnsHostnames',
                help='''show whether instances in the VPC are
                    assigned DNS hostnames'''),
            Arg('-s',
                '--dns-support',
                dest='Attribute',
                action='store_const',
                const='enableDnsSupport',
                help='show whether DNS resolution is enabled')).required()
    ]

    def print_result(self, result):
        if self.args['Attribute'] == 'enableDnsHostnames':
            print self.tabify(
                ('RETURN', result['enableDnsHostnames'].get('value')))
        elif self.args['Attribute'] == 'enableDnsSupport':
            print self.tabify(
                ('RETURN', result['enableDnsSupport'].get('value')))
class DescribeSnapshotAttribute(EC2Request):
    DESCRIPTION = 'Show information about an attribute of a snapshot'
    ARGS = [Arg('SnapshotId', metavar='SNAPSHOT', help='snapshot to describe'),
            MutuallyExclusiveArgList(
                Arg('-c', '--create-volume-permission', dest='Attribute',
                    action='store_const', const='createVolumePermission',
                    help='display who can create volumes from the snapshot'),
                Arg('-p', '--product-codes', dest='Attribute',
                    action='store_const', const='productCodes',
                    help='list associated product codes'))
            .required()]
    LIST_TAGS = ['createVolumePermission', 'productCodes']

    def print_result(self, result):
        snapshot_id = result.get('snapshotId')
        for perm in result.get('createVolumePermission', []):
            for (entity_type, entity_name) in perm.items():
                print self.tabify(('createVolumePermission', snapshot_id,
                                   entity_type, entity_name))
        for code in result.get('productCodes', []):
            if 'type' in code:
                code_str = '[{0}: {1}]'.format(code['type'],
                                               code.get('productCode'))
            else:
                code_str = code.get('productCode')
            print self.tabify(('productCodes', snapshot_id, 'productCode',
                               code_str))
Пример #16
0
class PutGroupPolicy(EuareRequest):
    DESCRIPTION = 'Attach a policy to a group'
    ARGS = [
        Arg('-g',
            '--group-name',
            dest='GroupName',
            metavar='GROUP',
            required=True,
            help='group to attach the policy to (required)'),
        Arg('-p',
            '--policy-name',
            dest='PolicyName',
            metavar='POLICY',
            required=True,
            help='name of the policy (required)'),
        MutuallyExclusiveArgList(
            True,
            Arg('-o',
                '--policy-content',
                dest='PolicyDocument',
                metavar='POLICY_CONTENT',
                help='the policy to attach'),
            Arg('-f',
                '--policy-document',
                dest='PolicyDocument',
                metavar='FILE',
                type=open,
                help='file containing the policy to attach')), AS_ACCOUNT
    ]
Пример #17
0
class CreateRole(IAMRequest):
    DESCRIPTION = 'Create a new role'
    ARGS = [arg_role(help='name of the new role (required)'),
            Arg('-p', '--path', dest='Path',
                help='path for the new role (default: "/")'),
            MutuallyExclusiveArgList(
                Arg('-f', dest='AssumeRolePolicyDocument', metavar='FILE',
                    type=file_contents,
                    help='file containing the policy for the new role'),
                Arg('-s', '--service', dest='service_', metavar='SERVICE',
                    route_to=None, help='''service to allow access to
                    the role (e.g. ec2.amazonaws.com)'''),
                # For compatibility with a typo in < 3.2.1
                Arg('--service_', route_to=None, help=argparse.SUPPRESS))
            .required(),
            Arg('-v', '--verbose', action='store_true', route_to=None,
                help="print the new role's ARN, GUID, and policy"),
            AS_ACCOUNT]

    def preprocess(self):
        if self.args.get('service_'):
            statement = {'Effect': 'Allow',
                         'Principal': {'Service': [self.args['service_']]},
                         'Action': ['sts:AssumeRole']}
            policy = {'Version': '2008-10-17',
                      'Statement': [statement]}
            self.params['AssumeRolePolicyDocument'] = json.dumps(policy)

    def print_result(self, result):
        if self.args.get('verbose'):
            print result.get('Role', {}).get('Arn')
            print result.get('Role', {}).get('RoleId')
            print urllib.unquote(result.get('Role', {})
                                 .get('AssumeRolePolicyDocument'))
Пример #18
0
class UpdateAssumeRolePolicy(IAMRequest):
    DESCRIPTION = ("Update a role's trust policy, the policy that allows "
                   "entities to assume a role")
    ARGS = [arg_role(help='role to update (required)'),
            MutuallyExclusiveArgList(
                Arg('-f', dest='PolicyDocument', metavar='FILE',
                    type=file_contents,
                    help='file containing the policy for the new role'),
                Arg('-s', '--service', route_to=None, help='''service to allow
                    access to the role (e.g. ec2.amazonaws.com)'''))
            .required(),
            Arg('-o', dest='verbose', action='store_true',
                help="also print the role's new policy"),
            AS_ACCOUNT]

    def preprocess(self):
        if self.args.get('service'):
            statement = {'Effect': 'Allow',
                         'Principal': {'Service': [self.args['service']]},
                         'Action': ['sts:AssumeRole']}
            policy = {'Version': '2008-10-17',
                      'Statement': [statement]}
            self.params['PolicyDocument'] = json.dumps(policy)

    def print_result(self, _):
        if self.args.get('verbose'):
            print self.params['PolicyDocument']
class UploadSigningCertificate(IAMRequest):
    DESCRIPTION = 'Upload a signing certificate'
    ARGS = [
        Arg('-u',
            '--user-name',
            dest='UserName',
            metavar='USER',
            help='''user the signing certificate is for (default: current
                user)'''),
        MutuallyExclusiveArgList(
            Arg('-c',
                '--certificate-body',
                dest='CertificateBody',
                metavar='CERT',
                help='contents of the new certificate'),
            Arg('-f',
                '--certificate-file',
                dest='CertificateBody',
                metavar='FILE',
                type=open,
                help='file containing the new certificate')).required(),
        AS_ACCOUNT
    ]

    def print_result(self, result):
        print result.get('Certificate', {}).get('CertificateId')
Пример #20
0
class CreateNetworkInterface(EC2Request):
    DESCRIPTION = 'Create a new VPC network interface'
    ARGS = [
        Arg('SubnetId',
            metavar='SUBNET',
            help='''subnet to create
                the new network interface in (required)'''),
        Arg('-d',
            '--description',
            dest='Description',
            metavar='DESC',
            help='description for the new network interface'),
        Arg('-g',
            '--group',
            dest='SecurityGroupName',
            metavar='GROUP',
            action='append',
            help='''ID of a security group to add the new network interface
                to.  This option may be used more than once.  Each time adds
                the network interface to an additional security group.'''),
        Arg('--private-ip-address',
            metavar='ADDRESS',
            route_to=None,
            help='''assign a specific primary private IP address to the
                new network interface'''),
        MutuallyExclusiveArgList(
            Arg('--secondary-address',
                '--secondary-private-ip-address',
                metavar='ADDRESS',
                route_to=None,
                action='append',
                help='''assign a specific secondary private IP address
                    to the new network interface.  Use this option multiple
                    times to add additional addresses.'''),
            Arg('--secondary-count',
                '--secondary-private-ip-address-count',
                dest='SecondaryPrivateIpAddressCount',
                metavar='COUNT',
                type=int,
                help='''automatically assign a specific number of secondary
                    private IP addresses to the new network interface'''))
    ]
    LIST_TAGS = ['groupSet', 'privateIpAddressesSet']

    def preprocess(self):
        addrs = []
        if self.args.get('private_ip_address'):
            addrs.append({
                'PrivateIpAddress': self.args['private_ip_address'],
                'Primary': True
            })
        for addr in self.args.get('secondary_private_ip_address') or []:
            addrs.append({'PrivateIpAddress': addr, 'Primary': False})
        self.params['PrivateIpAddresses'] = addrs

    def print_result(self, result):
        self.print_interface(result.get('networkInterface') or {})
Пример #21
0
class CreateLoadBalancer(ELBRequest, TabifyingMixin):
    DESCRIPTION = ('Create a load balancer\n\nAfter the load balancer is '
                   'created, instances must be registered with it separately.')
    ARGS = [
        Arg('LoadBalancerName',
            metavar='ELB',
            help='name of the new load balancer (required)'),
        MutuallyExclusiveArgList(
            Arg('-s',
                '--subnets',
                metavar='SUBNET1,SUBNET2,...',
                dest='Subnets.member',
                type=delimited_list(','),
                help='''[VPC only] subnets the load balancer should run in
                    (required)'''),
            Arg('-z',
                '--availability-zones',
                metavar='ZONE1,ZONE2,...',
                dest='AvailabilityZones.member',
                type=delimited_list(','),
                help='''[Non-VPC only] availability zones the load balancer
                    should run in (required)''')).required(),
        Arg('-l',
            '--listener',
            dest='Listeners.member',
            action='append',
            metavar=('"lb-port=PORT, protocol={HTTP,HTTPS,SSL,TCP}, '
                     'instance-port=PORT, instance-protocol={HTTP,HTTPS,'
                     'SSL,TCP}, cert-id=ARN"'),
            required=True,
            type=listener,
            help='''port/protocol settings for the load balancer, where
                lb-port is the external port number, protocol is the external
                protocol, instance-port is the back end server port number,
                instance-protocol is the protocol to use for routing traffic to
                back end instances, and cert-id is the ARN of the server
                certificate to use for encrypted connections.  lb-port,
                protocol, and instance-port are required.  This option may be
                used multiple times.  (at least 1 required)'''),
        Arg('-i',
            '--scheme',
            dest='Scheme',
            choices=('internal', ),
            metavar='internal',
            help='''[VPC only] "internal" to make the
                new load balancer private to a VPC'''),
        Arg('-g',
            '--security-groups',
            dest='SecurityGroups.member',
            metavar='GROUP1,GROUP2,...',
            type=delimited_list(','),
            help='''[VPC only] IDs of the security groups to assign to the
                new load balancer''')
    ]

    def print_result(self, result):
        print self.tabify(('DNS_NAME', result.get('DNSName')))
Пример #22
0
class EuStore(BaseService):
    NAME = 'eustore'
    DESCRIPTION = 'Eucalyptus Image Store'
    REGION_ENVVAR = 'EUCA_REGION'
    URL_ENVVAR = 'EUSTORE_URL'
    ARGS = [MutuallyExclusiveArgList(
                Arg('--region', dest='userregion', metavar='USER@REGION',
                    help='''name of the region and/or user in config files to
                    use to connect to the service'''),
                Arg('-U', '--url', help='EuStore service URL'))]
class DescribeImageAttribute(EC2Request):
    DESCRIPTION = 'Show information about an attribute of an image'
    ARGS = [Arg('ImageId', metavar='IMAGE', help='image to describe'),
            MutuallyExclusiveArgList(
                Arg('-l', '--launch-permission', dest='Attribute',
                    action='store_const', const='launchPermission',
                    help='display launch permissions'),
                Arg('-p', '--product-codes', dest='Attribute',
                    action='store_const', const='productCodes',
                    help='list associated product codes'),
                Arg('-B', '--block-device-mapping', dest='Attribute',
                    action='store_const', const='blockDeviceMapping',
                    help='describe block device mappings'),
                Arg('--kernel', dest='Attribute', action='store_const',
                    const='kernel', help='show associated kernel image ID'),
                Arg('--ramdisk', dest='Attribute', action='store_const',
                    const='ramdisk', help='show associated ramdisk image ID'),
                Arg('--description', dest='Attribute', action='store_const',
                    const='description', help="show the image's description"))
            .required()]
    LIST_TAGS = ['blockDeviceMapping', 'launchPermission', 'productCodes']

    def print_result(self, result):
        image_id = result.get('imageId')
        for perm in result.get('launchPermission', []):
            for (entity_type, entity_name) in perm.items():
                print self.tabify(('launchPermission', image_id, entity_type,
                                   entity_name))
        for code in result.get('productCodes', []):
            if 'type' in code:
                code_str = '[{0}: {1}]'.format(code['type'],
                                               code.get('productCode'))
            else:
                code_str = code.get('productCode')
            print self.tabify(('productCodes', image_id, 'productCode',
                               code_str))
        for blockdev in result.get('blockDeviceMapping', []):
            blockdev_src = (blockdev.get('virtualName') or
                            blockdev.get('ebs', {}).get('snapshotId'))
            blockdev_str = '{0}: {1}'.format(blockdev.get('deviceName'),
                                             blockdev_src)

            # TODO:  figure out how to print mappings that create new volumes
            print self.tabify(('blockDeviceMapping', image_id,
                               'blockDeviceMap', blockdev_str))
        if result.get('kernel'):
            print self.tabify(('kernel', image_id, None,
                               result['kernel'].get('value')))
        if result.get('ramdisk'):
            print self.tabify(('ramdisk', image_id, None,
                               result['ramdisk'].get('value')))
        if result.get('description'):
            print self.tabify(('description', image_id, None,
                               result['description'].get('value')))
Пример #24
0
class PutAccountPolicy(EuareRequest):
    DESCRIPTION = '[Eucalyptus cloud admin only] Attach a policy to an account'
    ARGS = [Arg('-a', '--account-name', dest='AccountName', metavar='ACCOUNT',
                required=True,
                help='account to attach the policy to (required)'),
            Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY',
                required=True, help='name of the policy (required)'),
            MutuallyExclusiveArgList(True,
                Arg('-o', '--policy-content', dest='PolicyDocument',
                    metavar='POLICY_CONTENT', help='the policy to attach'),
                Arg('-f', '--policy-document', dest='PolicyDocument',
                    metavar='FILE', type=open,
                    help='file containing the policy to attach'))]
Пример #25
0
class ReleaseRole(BaseCommand):
    DESCRIPTION = '''\
        Release IAM role credentials

        The %(prog)s utility removes the credentials created by
        euare-assumerole(1) by outputting shellcode that deletes
        the environment variables it creates.  Use it inside an eval
        command to make this process seamless:

            $ eval `euare-releaserole`

        Note that if the credentials used to initially assume the role
        were supplied in the form of environment variables those
        environment variables will need to be reset:

            $ source eucarc'''
    SUITE = Euca2ools
    ARGS = [
        MutuallyExclusiveArgList(
            Arg('-c',
                dest='csh_output',
                route_to=None,
                action='store_true',
                help='''generate C-shell commands on
                    stdout (default if SHELL looks like a csh-style shell'''),
            Arg('-s',
                dest='sh_output',
                route_to=None,
                action='store_true',
                help='''generate Bourne shell
                    commands on stdout (default if SHELL does not look
                    like a csh-style shell'''))
    ]

    def print_result(self, _):
        for var in ('AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY', 'EC2_ACCESS_KEY',
                    'AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY',
                    'EC2_SECRET_KEY', 'AWS_SESSION_TOKEN',
                    'AWS_SECURITY_TOKEN', 'AWS_CREDENTIAL_EXPIRATION',
                    'EC2_USER_ID', 'AWS_CREDENTIAL_FILE'):
            if (self.args.get('csh_output')
                    or (not self.args.get('sh_output')
                        and os.getenv('SHELL', '').endswith('csh'))):
                fmt = 'unsetenv {0};'
            else:
                fmt = 'unset {0};'
            print fmt.format(var)
        print
        print '# If you can read this, rerun this program with eval:'
        print '#     eval `{0}`'.format(' '.join(
            pipes.quote(arg) for arg in sys.argv))
Пример #26
0
class AssignPrivateIpAddresses(EC2Request):
    DESCRIPTION = ('Assign one or more private IP addresses to a network '
                   'interface\n\nNote that an instance\'s type may affect '
                   'the number of addresses it can hold at once.')
    ARGS = [
        Arg('-n',
            '--network-interface',
            metavar='INTERFACE',
            dest='NetworkInterfaceId',
            help='''ID of the network interface
                to assign addresses to (required)'''),
        Arg('positional_interface',
            nargs='?',
            route_to=None,
            help=argparse.SUPPRESS),
        MutuallyExclusiveArgList(
            Arg('--secondary-address',
                '--secondary-private-ip-address',
                metavar='ADDRESS',
                dest='PrivateIpAddress',
                action='append',
                help='''assign a specific secondary
                    private IP address to the network interface.  Use this
                    option multiple times to add additional addresses.'''),
            Arg('--secondary-count',
                '--secondary-private-ip-address-count',
                type=int,
                dest='SecondaryPrivateIpAddressCount',
                metavar='COUNT',
                help='''automatically assign a specific number of secondary
                    private IP addresses to the network interface''')).
        required(),
        Arg('--allow-reassignment',
            dest='AllowReassignment',
            action='store_true',
            help='''Allow addresses to be assigned
                even if they are already associated with other interfaces''')
    ]

    def configure(self):
        EC2Request.configure(self)
        if self.args.get('positional_interface'):
            if self.params.get('NetworkInterfaceId'):
                # Shouldn't be supplied both positionally and optionally
                raise ArgumentError('unrecognized arguments: {0}'.format(
                    self.args['positional_interface']))
            self.params['NetworkInterfaceId'] = \
                self.args['positional_interface']
        if not self.params.get('NetworkInterfaceId'):
            raise ArgumentError('argument -n/--network-interface is required')
Пример #27
0
class MigrateInstances(EC2Request):
    DESCRIPTION = ('Migrate one instance from its current host, or '
                   'migrate all instances from a specific host')
    ARGS = [
        MutuallyExclusiveArgList(
            Arg('-s',
                '--source',
                dest='SourceHost',
                metavar='HOST',
                help='remove all instances from a specific host'),
            Arg('-i',
                '--instance',
                dest='InstanceId',
                metavar='INSTANCE',
                help='remove one instance from its current host')).required(),
        MutuallyExclusiveArgList(
            Arg('--include-dest',
                action='append',
                route_to=None,
                metavar='HOST',
                help='''allow migration to only a
                    specific host (may be used more than once)'''),
            Arg('--exclude-dest',
                action='append',
                route_to=None,
                metavar='HOST',
                help='''allow migration to any host
                    except a specific one (may be used more than once)'''))
    ]

    def preprocess(self):
        if self.args.get('include_dest'):
            self.params['AllowHosts'] = True
            self.params['DestinationHost'] = self.args['include_dest']
        elif self.args.get('exclude_dest'):
            self.params['AllowHosts'] = False
            self.params['DestinationHost'] = self.args['exclude_dest']
Пример #28
0
class Walrus(requestbuilder.service.BaseService):
    NAME = 's3'
    DESCRIPTION = 'Object storage service'
    AUTH_CLASS = requestbuilder.auth.S3RestAuth
    REGION_ENVVAR = 'EUCA_REGION'
    URL_ENVVAR = 'S3_URL'

    ARGS = [MutuallyExclusiveArgList(
                Arg('--region', dest='userregion', metavar='USER@REGION',
                    help='''name of the region and/or user in config files to
                    use to connect to the service'''),
                Arg('-U', '--url', metavar='URL',
                    help='storage service endpoint URL'))]

    def handle_http_error(self, response):
        raise AWSError(response)
Пример #29
0
class ModifyPropertyValue(PropertiesRequest):
    DESCRIPTION = 'Change the value of a property'
    ARGS = [
        Arg('Name',
            metavar='PROPERTY',
            help='name of the property to change (required)'),
        MutuallyExclusiveArgList(
            Arg('-v',
                '--value',
                dest='Value',
                help='new value for the property'),
            Arg('-r',
                '--reset',
                dest='Reset',
                action='store_true',
                help='reset the property to its default value')).required()
    ]
class UploadSigningCertificate(IAMRequest):
    DESCRIPTION = 'Upload a signing certificate'
    ARGS = [arg_user(help='''user the signing certificate is for
                     (default: current user)'''),
            MutuallyExclusiveArgList(
                Arg('-c', '--certificate-body', dest='CertificateBody',
                    metavar='CERT_CONTENT',
                    help='PEM-encoded contents of the new certificate'),
                Arg('-f', '--certificate-file', dest='CertificateBody',
                    metavar='FILE', type=open,
                    help='file containing the new certificate'))
            .required(),
            AS_ACCOUNT]

    # pylint: disable=no-self-use
    def print_result(self, result):
        print result.get('Certificate', {}).get('CertificateId')