Пример #1
0
class subnet_create(_NetworkInit, OptionalOutput):
    """Create a new subnet"""

    arguments = dict(
        name=ValueArgument('Subnet name', '--name'),
        allocation_pools=AllocationPoolArgument(
            'start_address,end_address of allocation pool (can be repeated)'
            ' e.g., --alloc-pool=123.45.67.1,123.45.67.8', '--alloc-pool'),
        gateway=ValueArgument('Gateway IP', '--gateway'),
        subnet_id=ValueArgument('The id for the subnet', '--id'),
        ipv6=FlagArgument('If set, IP version is set to 6, else 4', '--ipv6'),
        enable_dhcp=FlagArgument('Enable dhcp (default: off)', '--with-dhcp'),
        network_id=ValueArgument('Set the network ID', '--network-id'),
        cidr=ValueArgument('Set the CIDR', '--cidr'))
    required = ('network_id', 'cidr')

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        try:
            net = self.client.create_subnet(self['network_id'], self['cidr'],
                                            self['name'],
                                            self['allocation_pools'],
                                            self['gateway'], self['subnet_id'],
                                            self['ipv6'], self['enable_dhcp'])
        except ClientError as ce:
            if ce.status in (404, 400):
                self._network_exists(network_id=self['network_id'])
            raise
        self.print_(net, self.print_dict)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #2
0
class network_create(_NetworkInit, OptionalOutput):
    """Create a new network (default type: MAC_FILTERED)"""

    arguments = dict(
        name=ValueArgument('Network name', '--name'),
        shared=FlagArgument(
            'Make network shared (special privileges required)', '--shared'),
        project_id=ValueArgument('Assign network to project', '--project-id'),
        network_type=NetworkTypeArgument(
            'Valid network types: %s' % (', '.join(NetworkTypeArgument.types)),
            '--type'))

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        try:
            net = self.client.create_network(self['network_type'],
                                             name=self['name'],
                                             shared=self['shared'],
                                             project_id=self['project_id'])
        except ClientError as ce:
            if self['project_id'] and ce.status in (400, 403, 404):
                self._project_id_exists(project_id=self['project_id'])
            raise
        self.print_(net, self.print_dict)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #3
0
class IDFilter(object):

    if_arguments = dict(
        id=ValueArgument('filter by id', '--id'),
        id_pref=ValueArgument('filter by id prefix (case insensitive)',
                              '--id-prefix'),
        id_suff=ValueArgument('filter by id suffix (case insensitive)',
                              '--id-suffix'),
        id_like=ValueArgument(
            'print only if id contains this (case insensitive)', '--id-like'))

    def _non_exact_id_filter(self, items):
        np, ns, nl = self['id_pref'], self['id_suff'], self['id_like']
        return [
            item for item in items
            if ((not np) or ('%s' % item['id']).lower().startswith(np.lower()))
            and ((not ns) or ('%s' % item['id']).lower().endswith(ns.lower()))
            and ((not nl) or nl.lower() in ('%s' % item['id']).lower())
        ]

    def _exact_id_filter(self, items):
        return filter_dicts_by_dict(items, dict(
            id=self['id'])) if (self['id']) else items

    def _filter_by_id(self, items):
        return self._non_exact_id_filter(self._exact_id_filter(items))
Пример #4
0
class NameFilter(object):

    nf_arguments = dict(
        name=ValueArgument('filter by name', '--name'),
        name_pref=ValueArgument('filter by name prefix (case insensitive)',
                                '--name-prefix'),
        name_suff=ValueArgument('filter by name suffix (case insensitive)',
                                '--name-suffix'),
        name_like=ValueArgument(
            'print only if name contains this (case insensitive)',
            '--name-like'))

    def _non_exact_name_filter(self, items):
        np, ns, nl = self['name_pref'], self['name_suff'], self['name_like']
        return [
            item for item in items
            if ((not np) or (item['name'] or '').lower().startswith(np.lower())
                ) and ((not ns) or (
                    item['name'] or '').lower().endswith(ns.lower())) and (
                        (not nl) or nl.lower() in (item['name'] or '').lower())
        ]

    def _exact_name_filter(self, items):
        return filter_dicts_by_dict(items, dict(
            name=self['name'] or '')) if (self['name']) else items

    def _filter_by_name(self, items):
        return self._non_exact_name_filter(self._exact_name_filter(items))
Пример #5
0
class project_list(_AstakosInit, OptionalOutput):
    """List all projects"""

    arguments = dict(
        details=FlagArgument('Show details', ('-l', '--details')),
        name=ValueArgument('Filter by name', ('--with-name', )),
        state=ValueArgument('Filter by state', ('--with-state', )),
        owner=ValueArgument('Filter by owner', ('--with-owner', )),
    )

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        r = self.client.get_projects(self['name'], self['state'],
                                     self['owner'])
        if not (self['details'] or self['output_format']):
            r = [
                dict(id=i['id'], name=i['name'], description=i['description'])
                for i in r
            ]
        self.print_(r)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #6
0
class commission_issue(_AstakosInit, OptionalOutput):
    """Issue commissions as a json string (special privileges required)"""

    arguments = dict(uuid=ValueArgument('User UUID', '--uuid'),
                     source=ValueArgument('Commission source (ex system)',
                                          '--source'),
                     file_path=ValueArgument('File of provisions',
                                             '--provisions-file'),
                     description=ValueArgument('Commision description',
                                               '--description'),
                     force=FlagArgument('Force commission', '--force'),
                     accept=FlagArgument('Do not wait for verification',
                                         '--accept'))
    required = ('uuid', 'source', 'file_path')

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        try:
            with open(self['file_path']) as f:
                provisions = loads(f.read())
        except Exception as e:
            raise CLIError('Failed load a json dict from file %s' %
                           self['file_path'],
                           importance=2,
                           details=['%s' % e])
        self.print_(
            self.client.issue_one_commission(self['uuid'], self['source'],
                                             provisions, self['description']
                                             or '', self['force'],
                                             self['accept']))

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #7
0
class port_create(_port_create):
    """Create a new port (== connect server to network)"""

    arguments = dict(
        name=ValueArgument('A human readable name', '--name'),
        security_group_id=RepeatableArgument(
            'Add a security group id (can be repeated)',
            ('-g', '--security-group')),
        subnet_id=ValueArgument(
            'Subnet id for fixed ips (used with --ip-address)', '--subnet-id'),
        ip_address=ValueArgument('IP address for subnet id', '--ip-address'),
        network_id=ValueArgument('Set the network ID', '--network-id'),
        device_id=ValueArgument(
            'The device is either a virtual server or a virtual router',
            '--device-id'),
        wait=FlagArgument('Wait port to be established', ('-w', '--wait')),
    )
    required = ('network_id', 'device_id')

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        self.connect(self['network_id'], self['device_id'])

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #8
0
 def _run(self, ip_or_ip_id):
     netid = None
     for ip in self.client.list_floatingips():
         if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
             netid = ip['floating_network_id']
             iparg = ValueArgument(parsed_name='--ip')
             iparg.value = ip['floating_ip_address']
             self.arguments['ip_address'] = iparg
             break
     if netid:
         server_id = self['server_id']
         self.error('Creating a port to attach IP %s to server %s' % (
             ip_or_ip_id, server_id))
         try:
             self.connect(netid, server_id)
         except ClientError as ce:
             self.error('Failed to connect network %s with server %s' % (
                 netid, server_id))
             if ce.status in (400, 404):
                 self._server_exists(server_id=server_id)
                 self._network_exists(network_id=netid)
             raise
     else:
         raiseCLIError(
             '%s does not match any reserved IPs or IP ids' % ip_or_ip_id,
             details=errors.Cyclades.about_ips)
Пример #9
0
class server_detach(_CycladesInit):
    """Detach a volume from a VM"""

    arguments = dict(
        attachment_id=ValueArgument(
            'The volume attachment (mutually exclusive to --volume-id)',
            '--attachment-id', ),
        volume_id=ValueArgument(
            'Volume to detach from VM (mutually exclusive to --attachment-id)',
            '--volume-id')
    )
    required = ['attachment_id', 'volume_id']

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.server_id
    @errors.Cyclades.endpoint
    def _run(self, server_id):
        att_id = self['attachment_id']
        if att_id:
            self.client.delete_volume_attachment(server_id, att_id)
        else:
            r = self.client.detach_volume(server_id, self['volume_id'])
            self.error('%s detachment%s deleted, volume is detached' % (
                len(r), '' if len(r) == 1 else 's'))
        self.error('OK')

    def main(self, server_id):
        super(self.__class__, self)._run()
        if all([self['attachment_id'], self['volume_id']]):
            raise CLISyntaxError('Invalid argument compination', details=[
                '%s and %s are mutually exclusive' % (
                    self.arguments['attachment_id'].lvalue,
                    self.arguments['volume_id'].lvalue)])
        self._run(server_id=server_id)
Пример #10
0
class network_connect(_port_create):
    """Connect a network with a device (server or router)"""

    arguments = dict(
        name=ValueArgument('A human readable name for the port', '--name'),
        security_group_id=RepeatableArgument(
            'Add a security group id (can be repeated)',
            ('-g', '--security-group')),
        subnet_id=ValueArgument(
            'Subnet id for fixed ips (used with --ip-address)', '--subnet-id'),
        ip_address=ValueArgument(
            'IP address for subnet id (used with --subnet-id', '--ip-address'),
        wait=FlagArgument('Wait network to connect', ('-w', '--wait')),
        device_id=RepeatableArgument(
            'Connect this device to the network (can be repeated)',
            '--device-id'))
    required = ('device_id', )

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.network_id
    def _run(self, network_id, server_id):
        self.error('Creating a port to connect network %s with device %s' %
                   (network_id, server_id))
        try:
            self.connect(network_id, server_id)
        except ClientError as ce:
            if ce.status in (400, 404):
                self._server_exists(server_id=server_id)
            raise

    def main(self, network_id):
        super(self.__class__, self)._run()
        for sid in self['device_id']:
            self._run(network_id=network_id, server_id=sid)
Пример #11
0
 def _run(self, ip_or_ip_id):
     netid = None
     for ip in self.client.list_floatingips():
         if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
             netid = ip['floating_network_id']
             iparg = ValueArgument(parsed_name='--ip')
             iparg.value = ip['floating_ip_address']
             self.arguments['ip_address'] = iparg
             break
     if netid:
         server_id = self['server_id']
         self.error('Creating a port to attach IP %s to server %s' %
                    (ip_or_ip_id, server_id))
         try:
             self.connect(netid, server_id)
         except ClientError as ce:
             self.error('Failed to connect network %s with server %s' %
                        (netid, server_id))
             if ce.status in (400, 404):
                 self._server_exists(server_id=server_id)
                 self._network_exists(network_id=netid)
             raise
     else:
         raiseCLIError('%s does not match any reserved IPs or IP ids' %
                       ip_or_ip_id,
                       details=errors.Cyclades.about_ips)
Пример #12
0
class user_info(_AstakosInit, OptionalOutput):
    """Get info for (current) session user"""

    arguments = dict(uuid=ValueArgument('Query user with uuid', '--uuid'),
                     name=ValueArgument('Query user with username/email',
                                        '--username'))

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        if self['uuid'] and self['name']:
            raise CLISyntaxError(
                'Arguments uuid and username are mutually exclusive',
                details=['Use either uuid OR username OR none, but NOT both'])
        uuid = self['uuid'] or (self._username2uuid(self['name']) if
                                (self['name']) else None)
        try:
            if any([self['uuid'], self['name']]) and not uuid:
                raise KeyError()
            token = self.astakos.get_token(uuid) if uuid else None
        except KeyError:
            msg = ('id %s' % self['uuid']) if (
                self['uuid']) else 'username %s' % self['name']
            raise CLIError(
                'No user with %s in the cached session list' % msg,
                details=[
                    'To see all cached session users:', '  kamaki user list',
                    'To authenticate and add a new user in the session list:',
                    '  kamaki user add NEW_TOKEN'
                ])
        self.print_(self.astakos.user_info(token), self.print_dict)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #13
0
class ip_create(_NetworkInit, OptionalOutput):
    """Reserve an IP on a network"""

    arguments = dict(
        network_id=ValueArgument('The network to preserve the IP on',
                                 '--network-id'),
        ip_address=ValueArgument('Allocate an IP address', '--address'),
        project_id=ValueArgument('Assign the IP to project', '--project-id'),
    )

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        try:
            self.print_(
                self.client.create_floatingip(
                    self['network_id'],
                    floating_ip_address=self['ip_address'],
                    project_id=self['project_id']), self.print_dict)
        except ClientError as ce:
            if ce.status in (400, 404):
                network_id, ip = self['network_id'], self['ip_address']
                self._network_exists(network_id=network_id)
                if ip:
                    self._ip_exists(ip, network_id, ce)
            if self['project_id'] and ce.status in (400, 403, 404):
                self._project_id_exists(project_id=self['project_id'])
            raise

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #14
0
class flavor_list(_CycladesInit, OptionalOutput, NameFilter, IDFilter):
    """List available hardware flavors"""

    arguments = dict(
        detail=FlagArgument('show detailed output', ('-l', '--details')),
        limit=IntArgument('limit # of listed flavors', ('-n', '--number')),
        more=FlagArgument(
            'output results in pages (-n to set items per page, default 10)',
            '--more'),
        enum=FlagArgument('Enumerate results', '--enumerate'),
        ram=ValueArgument('filter by ram', ('--ram')),
        vcpus=ValueArgument('filter by number of VCPUs', ('--vcpus')),
        disk=ValueArgument('filter by disk size in GB', ('--disk')),
        disk_template=ValueArgument(
            'filter by disk_templace', ('--disk-template')),
        project_id=ValueArgument('filter by project ID', '--project'),
        is_public=FlagArgument('list only public flavors', '--public'),
    )

    def _apply_common_filters(self, flavors):
        common_filters = dict()
        if self['ram']:
            common_filters['ram'] = self['ram']
        if self['vcpus']:
            common_filters['vcpus'] = self['vcpus']
        if self['disk']:
            common_filters['disk'] = self['disk']
        if self['disk_template']:
            common_filters['SNF:disk_template'] = self['disk_template']
        return filter_dicts_by_dict(flavors, common_filters)

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        withcommons = self['ram'] or self['vcpus'] or (
            self['disk'] or self['disk_template'])
        detail = self['detail'] or withcommons
        flavors = self.client.list_flavors(
            detail, is_public=self['is_public'], project_id=self['project_id'])
        flavors = self._filter_by_name(flavors)
        flavors = self._filter_by_id(flavors)
        if withcommons:
            flavors = self._apply_common_filters(flavors)
        if not (self['detail'] or self['output_format']):
            remove_from_items(flavors, 'links')
        if detail and not self['detail']:
            for flv in flavors:
                for key in set(flv).difference(['id', 'name']):
                    flv.pop(key)
        kwargs = dict(out=StringIO(), title=()) if self['more'] else {}
        self.print_(flavors, with_enumeration=self['enum'], **kwargs)
        if self['more']:
            pager(kwargs['out'].getvalue())

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #15
0
class image_modify(_ImageInit):
    """Add / update metadata and properties for an image
    Preserves values not explicitly modified
    """

    arguments = dict(
        image_name=ValueArgument('Change name', '--name'),
        disk_format=ValueArgument('Change disk format', '--disk-format'),
        container_format=ValueArgument('Change container format',
                                       '--container-format'),
        status=ValueArgument('Change status', '--status'),
        publish=FlagArgument('Make the image public', '--public'),
        unpublish=FlagArgument('Make the image private', '--private'),
        property_to_set=KeyValueArgument(
            'set property in key=value form (can be repeated)',
            ('-p', '--property-set')),
        property_to_del=RepeatableArgument(
            'Delete property by key (can be repeated)', '--property-del'),
        member_ID_to_add=RepeatableArgument(
            'Add member to image (can be repeated)', '--member-add'),
        member_ID_to_remove=RepeatableArgument(
            'Remove a member (can be repeated)', '--member-del'),
    )
    required = [
        'image_name', 'disk_format', 'container_format', 'status', 'publish',
        'unpublish', 'property_to_set', 'member_ID_to_add',
        'member_ID_to_remove', 'property_to_del'
    ]

    @errors.Generic.all
    @errors.Image.connection
    @errors.Image.permissions
    @errors.Image.id
    def _run(self, image_id):
        for mid in (self['member_ID_to_add'] or []):
            self.client.add_member(image_id, mid)
        for mid in (self['member_ID_to_remove'] or []):
            self.client.remove_member(image_id, mid)
        meta = self.client.get_meta(image_id)
        for k, v in self['property_to_set'].items():
            meta['properties'][k.upper()] = v
        for k in (self['property_to_del'] or []):
            meta['properties'][k.upper()] = None
        self.client.update_image(image_id,
                                 name=self['image_name'],
                                 disk_format=self['disk_format'],
                                 container_format=self['container_format'],
                                 status=self['status'],
                                 public=self['publish']
                                 or (False if self['unpublish'] else None),
                                 **meta['properties'])

    def main(self, image_id):
        super(self.__class__, self)._run()
        self._run(image_id=image_id)
Пример #16
0
class keypair_upload(_CycladesInit, OptionalOutput):
    """Upload or update a keypair"""

    arguments = dict(
        key_name=ValueArgument(
            'The name of the key',
            '--key-name'),
        public_key=ValueArgument(
            'The contents of the keypair(the public key)',
            '--public-key'),
        force=FlagArgument(
            '(DANGEROUS) Force keypair creation. This option'
            ' will delete an existing keypair in case of a name'
            'conflict. Do not use it if unsure.',
            ('-f', '--force')
        )
    )

    required = ['public_key']

    @errors.Generic.all
    @errors.Keypair.connection
    def _run(self):
        key_name = self['key_name']
        if key_name is None:
            uniq = str(uuid.uuid4())[:8]
            key_name = 'kamaki-key_autogen_{:%m_%d_%H_%M_%S_%f}_{uniq}'.format(
                datetime.now(), uniq=uniq)
        try:
            keypair = self.client.create_key(
                key_name=key_name, public_key=self['public_key'])
        except ClientError as e:
            if e.status == 409 and self['force']:
                self.client.delete_keypair(key_name)
                keypair = self.client.create_key(
                    key_name=key_name, public_key=self['public_key'])
            else:
                help_command = ('kamaki keypair upload -f --key-name %s '
                                '--public-key %s'
                                % (key_name, self['public_key']))
                self._err.write('A keypair with that name already exists. '
                                'To override the conflicting key you can use '
                                'the following command:\n%s\n' %
                                (help_command))
                raise e
        self.print_(keypair, self.print_dict)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #17
0
class quota_list(_AstakosInit, OptionalOutput):
    """Show user quotas"""

    _to_format = set(['cyclades.disk', 'pithos.diskspace', 'cyclades.ram'])
    arguments = dict(resource=ValueArgument('Filter by resource',
                                            '--resource'),
                     project_id=ValueArgument('Filter by project',
                                              '--project-id'),
                     bytes=FlagArgument('Show data size in bytes', '--bytes'))

    def _print_quotas(self, quotas, *args, **kwargs):
        if not self['bytes']:
            for project_id, resources in quotas.items():
                for r in self._to_format.intersection(resources):
                    resources[r] = dict([(k, format_size(v))
                                         for k, v in resources[r].items()])
        self.print_dict(quotas, *args, **kwargs)

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        quotas = self.client.get_quotas()
        if self['project_id']:
            try:
                resources = quotas[self['project_id']]
            except KeyError:
                raise CLIError('User not assigned to project with id "%s" ' %
                               (self['project_id']),
                               details=[
                                   'See all quotas of current user:'******'  kamaki quota list'
                               ])
            quotas = {self['project_id']: resources}
        if self['resource']:
            d = dict()
            for project_id, resources in quotas.items():
                r = dict()
                for resource, value in resources.items():
                    if (resource.startswith(self['resource'])):
                        r[resource] = value
                if r:
                    d[project_id] = r
            if not d:
                raise CLIError('Resource "%s" not found' % self['resource'])
            quotas = d
        self.print_(quotas, self._print_quotas)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #18
0
class server_reboot(_CycladesInit, _ServerWait):
    """Reboot a virtual server"""

    arguments = dict(
        type=ValueArgument('SOFT or HARD - default: SOFT', ('--type')),
        wait=FlagArgument('Wait server to start again', ('-w', '--wait'))
    )

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.server_id
    def _run(self, server_id):
        hard_reboot = None
        if self['type']:
            if self['type'].lower() in ('soft', ):
                hard_reboot = False
            elif self['type'].lower() in ('hard', ):
                hard_reboot = True
            else:
                raise CLISyntaxError(
                    'Invalid reboot type %s' % self['type'],
                    importance=2, details=[
                        '--type values are either SOFT (default) or HARD'])

        self.client.reboot_server(int(server_id), hard_reboot)
        if self['wait']:
            self.wait_while(server_id, 'REBOOT')

    def main(self, server_id):
        super(self.__class__, self)._run()
        self._run(server_id=server_id)
Пример #19
0
class port_list(_NetworkInit, OptionalOutput, NameFilter, IDFilter):
    """List all ports"""

    arguments = dict(detail=FlagArgument('show detailed output',
                                         ('-l', '--details')),
                     more=FlagArgument('output results in pages', '--more'),
                     user_id=ValueArgument(
                         'show only networks belonging to user with this id',
                         '--user-id'))

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self):
        ports = self.client.list_ports()
        ports = self._filter_by_user_id(ports)
        ports = self._filter_by_name(ports)
        ports = self._filter_by_id(ports)
        if not self['detail']:
            ports = [dict(id=p['id'], name=p['name']) for p in ports]
        kwargs = dict()
        if self['more']:
            kwargs['out'] = StringIO()
            kwargs['title'] = ()
        self.print_(ports, **kwargs)
        if self['more']:
            pager(kwargs['out'].getvalue())

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #20
0
class history_show(_HistoryInit):
    """Show history
        Featutes:
        - slice notation (cmd numbers --> N or :N or N: or N1:N2)
        - text matching (--match)
    """

    arguments = dict(match=ValueArgument('Show lines matching this',
                                         '--match'), )

    @errors.Generic.all
    def _run(self, cmd_slice):
        c = self.history.counter
        lines = [
            '%s.  %s' % (i + c, l) for i, l in enumerate(self.history[:])
        ][cmd_slice]
        if not isinstance(cmd_slice, slice):
            lines = [
                lines,
            ]
        if self['match']:
            lines = [l for l in lines if self.history._match(l, self['match'])]
        self.print_items([l[:-1] for l in lines])

    def main(self, cmd_numbers=''):
        super(self.__class__, self)._run()
        sl_args = [int(x) if x else None for x in cmd_numbers.split(':')
                   ] if (cmd_numbers) else [None, None]
        slice_cmds = slice(*sl_args) if len(sl_args) > 1 else sl_args[0]
        self._run(slice_cmds)
Пример #21
0
class user_add(_AstakosInit, OptionalOutput):
    """Authenticate a user by token and add to session user list (cache)"""

    arguments = dict(token=ValueArgument('Token of user to add', '--token'), )
    required = ('token', )

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        ask = self['token'] and self['token'] not in self.astakos._uuids
        try:
            self.print_(self.astakos.authenticate(self['token']),
                        self.print_dict)
        except ClientError as ce:
            if ce.status in (401, ):
                raise CLIError('Token %s was not authenticated' %
                               self['token'],
                               details=['%s' % ce])
        if ask and self.ask_user(
                'Token is temporarily stored in memory. Append it in '
                'configuration file as an alternative token?'):
            tokens = self.astakos._uuids.keys()
            tokens.remove(self.astakos.token)
            self['config'].set_cloud(self.cloud, 'token',
                                     ' '.join([self.astakos.token] + tokens))
            self['config'].write()

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #22
0
class ip_attach(_port_create):
    """Attach an IP on a virtual server"""

    arguments = dict(name=ValueArgument('A human readable name for the port',
                                        '--name'),
                     security_group_id=RepeatableArgument(
                         'Add a security group id (can be repeated)',
                         ('-g', '--security-group')),
                     subnet_id=ValueArgument('Subnet id', '--subnet-id'),
                     wait=FlagArgument('Wait IP to be attached',
                                       ('-w', '--wait')),
                     server_id=ValueArgument('Server to attach to this IP',
                                             '--server-id'))
    required = ('server_id', )

    @errors.Generic.all
    @errors.Cyclades.connection
    def _run(self, ip_or_ip_id):
        netid = None
        for ip in self.client.list_floatingips():
            if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
                netid = ip['floating_network_id']
                iparg = ValueArgument(parsed_name='--ip')
                iparg.value = ip['floating_ip_address']
                self.arguments['ip_address'] = iparg
                break
        if netid:
            server_id = self['server_id']
            self.error('Creating a port to attach IP %s to server %s' %
                       (ip_or_ip_id, server_id))
            try:
                self.connect(netid, server_id)
            except ClientError as ce:
                self.error('Failed to connect network %s with server %s' %
                           (netid, server_id))
                if ce.status in (400, 404):
                    self._server_exists(server_id=server_id)
                    self._network_exists(network_id=netid)
                raise
        else:
            raiseCLIError('%s does not match any reserved IPs or IP ids' %
                          ip_or_ip_id,
                          details=errors.Cyclades.about_ips)

    def main(self, ip_or_ip_id):
        super(self.__class__, self)._run()
        self._run(ip_or_ip_id=ip_or_ip_id)
Пример #23
0
class service_quotas(_AstakosInit, OptionalOutput):
    """Get service quotas"""

    arguments = dict(service_token=ValueArgument('Authenticate service',
                                                 '--service-token'),
                     uuid=ValueArgument('A user uuid to get quotas for',
                                        '--uuid'))
    required = ('service_token')

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @with_temp_token
    def _run(self):
        self.print_(self.client.service_get_quotas(self['uuid']))

    def main(self):
        super(self.__class__, self)._run()
        self._run(token=self['service_token'])
Пример #24
0
class _ApplicationAction(_AstakosInit):

    action = ''
    arguments = dict(
        app_id=ValueArgument('The application ID', '--app-id'),
        reason=ValueArgument('Quote a reason for this action', '--reason'),
    )
    required = ('app_id', )

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @errors.Astakos.project_id
    def _run(self, project_id):
        self.client.application_action(project_id, self['app_id'], self.action,
                                       self['reason'] or '')

    def main(self, project_id):
        super(_ApplicationAction, self)._run()
        self._run(project_id=project_id)
Пример #25
0
 def _run(self, ip_or_ip_id, server_id):
     netid = None
     for ip in self.client.list_floatingips():
         if ip_or_ip_id in (ip['floating_ip_address'], ip['id']):
             netid = ip['floating_network_id']
             iparg = ValueArgument(parsed_name='--ip')
             iparg.value = ip['floating_ip_address']
             self.arguments['ip_address'] = iparg
             break
     if netid:
         self.error('Creating a port to attach IP %s to server %s' % (
             ip_or_ip_id, server_id))
         self.connect(netid, server_id)
     else:
         raiseCLIError(
             '%s does not match any reserved IPs or IP ids' % ip_or_ip_id,
             details=[
                 'To reserve an IP:', '  [kamaki] ip create',
                 'To see all reserved IPs:', '  [kamaki] ip list'])
Пример #26
0
class _MembershipAction(_AstakosInit, OptionalOutput):

    action = ''
    arguments = dict(reason=ValueArgument('Reason for the action', '--reason'))

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @errors.Astakos.membership_id
    def _run(self, membership_id):
        self.print_(self.client.membership_action(
            membership_id, self.action, self['reason'] or ''))

    def main(self, membership_id):
        super(_MembershipAction, self)._run()
        self._run(membership_id=membership_id)
Пример #27
0
class project_enroll(_AstakosInit):
    """Enroll a user to a project"""

    arguments = dict(email=ValueArgument('User e-mail', '--email'))
    required = ('email', )

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @errors.Astakos.project_id
    def _run(self, project_id):
        self.writeln(self.client.enroll_member(project_id, self['email']))

    def main(self, project_id):
        super(project_enroll, self)._run()
        self._run(project_id=project_id)
Пример #28
0
class membership_list(_AstakosInit, OptionalOutput):
    """List all memberships"""

    arguments = dict(
        project_id=ValueArgument('Filter by project id', '--project-id'))

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @errors.Astakos.project_id
    def _run(self, project_id):
        self.print_(self.client.get_memberships(project_id))

    def main(self):
        super(self.__class__, self)._run()
        self._run(project_id=self['project_id'])
Пример #29
0
class _ProjectAction(_AstakosInit):

    action = ''
    arguments = dict(reason=ValueArgument('Quote a reason for this action',
                                          '--reason'), )

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @errors.Astakos.project_id
    def _run(self, project_id):
        self.client.project_action(project_id, self.action, self['reason']
                                   or '')

    def main(self, project_id):
        super(_ProjectAction, self)._run()
        self._run(project_id=project_id)
Пример #30
0
class endpoint_list(_AstakosInit, OptionalOutput, NameFilter):
    """Get endpoints service endpoints"""

    arguments = dict(endpoint_type=ValueArgument('Filter by type', '--type'))

    @errors.Generic.all
    @errors.Astakos.astakosclient
    def _run(self):
        r = self.client.get_endpoints()['access']['serviceCatalog']
        r = self._filter_by_name(r)
        if self['endpoint_type']:
            r = filter_dicts_by_dict(r, dict(type=self['endpoint_type']))
        self.print_(r)

    def main(self):
        super(self.__class__, self)._run()
        self._run()
Пример #31
0
class subnet_modify(_NetworkInit, OptionalOutput):
    """Modify the attributes of a subnet"""

    arguments = dict(
        new_name=ValueArgument('New name of the subnet', '--name'))
    required = ['new_name']

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.subnet_permissions
    @errors.Cyclades.subnet_id
    def _run(self, subnet_id):
        r = self.client.update_subnet(subnet_id, name=self['new_name'])
        self.print_(r, self.print_dict)

    def main(self, subnet_id):
        super(self.__class__, self)._run()
        self._run(subnet_id=subnet_id)
Пример #32
0
class server_attach(_CycladesInit, OptionalOutput):
    """Attach a volume on a VM"""

    arguments = dict(
        volume_id=ValueArgument('The volume to be attached', '--volume-id')
    )
    required = ('volume_id', )

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.server_id
    @errors.Cyclades.endpoint
    def _run(self, server_id):
        r = self.client.attach_volume(server_id, self['volume_id'])
        self.print_(r, self.print_dict)

    def main(self, server_id):
        super(self.__class__, self)._run()
        self._run(server_id=server_id)