Пример #1
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)
Пример #2
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)
Пример #3
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()
Пример #4
0
class imagecompute_modify(_CycladesInit):
    """Modify image properties (metadata)"""

    arguments = dict(
        property_to_add=KeyValueArgument(
            'Add property in key=value format (can be repeated)',
            ('--property-add')),
        property_to_del=RepeatableArgument(
            'Delete property by key (can be repeated)',
            ('--property-del'))
    )
    required = ['property_to_add', 'property_to_del']

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Image.permissions
    @errors.Image.id
    def _run(self, image_id):
        if self['property_to_add']:
            self.client.update_image_metadata(
                image_id, **self['property_to_add'])
        for key in (self['property_to_del'] or []):
            self.client.delete_image_metadata(image_id, key)

    def main(self, image_id):
        super(self.__class__, self)._run()
        self._run(image_id=image_id)
Пример #5
0
class network_disconnect(_NetworkInit, _PortWait, OptionalOutput):
    """Disconnect a network from a device"""

    arguments = dict(
        wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')),
        device_id=RepeatableArgument(
            'Disconnect device from the network (can be repeated)',
            '--device-id'))
    required = ('device_id', )

    @errors.Cyclades.server_id
    def _get_vm(self, server_id):
        return self._get_compute_client().get_server_details(server_id)

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.network_id
    def _run(self, network_id, server_id):
        vm = self._get_vm(server_id=server_id)
        ports = [
            port for port in vm['attachments']
            if (port['network_id'] in (network_id, ))
        ]
        if not ports:
            raiseCLIError('Device %s has no network %s attached' %
                          (server_id, network_id),
                          importance=2,
                          details=[
                              'To get device networking',
                              '  kamaki server info %s --nics' % server_id
                          ])
        for port in ports:
            if self['wait']:
                port['status'] = self.client.get_port_details(
                    port['id'])['status']
            self.client.delete_port(port['id'])
            self.error('Deleting port %s (net-id: %s, device-id: %s):' %
                       (port['id'], network_id, server_id))
            if self['wait']:
                try:
                    self.wait_while(port['id'], port['status'])
                except ClientError as ce:
                    if ce.status not in (404, ):
                        raise
                    self.error('Port %s is deleted' % port['id'])

    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)
Пример #6
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)
Пример #7
0
class service_username2uuid(_AstakosInit, OptionalOutput):
    """Get service uuid(s) from username(s)"""

    arguments = dict(service_token=ValueArgument('Authenticate service',
                                                 '--service-token'),
                     username=RepeatableArgument('Username (can be repeated)',
                                                 '--username'))
    required = ('service_token', 'username')

    @errors.Generic.all
    @errors.Astakos.astakosclient
    @with_temp_token
    def _run(self):
        if 1 == len(self['username']):
            self.print_(self.client.service_get_uuid(self['username'][0]))
        else:
            self.print_(self.client.service_get_uuids(self['username']),
                        self.print_dict)

    def main(self):
        super(self.__class__, self)._run()
        self._run(token=self['service_token'])
Пример #8
0
class server_modify(_CycladesInit):
    """Modify attributes of a virtual server"""

    arguments = dict(
        server_name=ValueArgument('The new name', '--name'),
        flavor_id=IntArgument('Resize (set another flavor)', '--flavor-id'),
        firewall_profile=FirewallProfileArgument(
            'Valid values: %s' % (', '.join(FirewallProfileArgument.profiles)),
            '--firewall'),
        metadata_to_set=KeyValueArgument(
            'Set metadata in key=value form (can be repeated)',
            '--metadata-set'),
        metadata_to_delete=RepeatableArgument(
            'Delete metadata by key (can be repeated)', '--metadata-del'),
        public_network_port_id=ValueArgument(
            'Connection to set new firewall (* for all)', '--port-id'),
    )
    required = [
        'server_name', 'flavor_id', 'firewall_profile', 'metadata_to_set',
        'metadata_to_delete']

    def _set_firewall_profile(self, server_id):
        vm = self._restruct_server_info(
            self.client.get_server_details(server_id))
        ports = [p for p in vm['ports'] if 'firewallProfile' in p]
        pick_port = self.arguments['public_network_port_id']
        if pick_port.value:
            ports = [p for p in ports if pick_port.value in (
                '*', '%s' % p['id'])]
        elif len(ports) > 1:
            port_strings = ['Server %s ports to public networks:' % server_id]
            for p in ports:
                port_strings.append('  %s' % p['id'])
                for k in ('network_id', 'ipv4', 'ipv6', 'firewallProfile'):
                    v = p.get(k)
                    if v:
                        port_strings.append('\t%s: %s' % (k, v))
            raise CLIError(
                'Multiple public connections on server %s' % (
                    server_id), details=port_strings + [
                        'To select one:',
                        '  %s PORT_ID' % pick_port.lvalue,
                        'To set all:',
                        '  %s *' % pick_port.lvalue, ])
        if not ports:
            pp = pick_port.value
            raise CLIError(
                'No public networks attached on server %s%s' % (
                    server_id, ' through port %s' % pp if pp else ''),
                details=[
                    'To see all networks:', '  kamaki network list',
                    'To see all connections:',
                    '  kamaki server info %s --nics' % server_id,
                    'To connect to a network:',
                    '  kamaki network connect NETWORK_ID --device-id %s' % (
                        server_id)])
        for port in ports:
            self.error('Set port %s firewall to %s' % (
                port['id'], self['firewall_profile']))
            self.client.set_firewall_profile(
                server_id=server_id,
                profile=self['firewall_profile'],
                port_id=port['id'])

    def _server_is_stopped(self, server_id, cerror):
        vm = self.client.get_server_details(server_id)
        if vm['status'].lower() not in ('stopped'):
            raise CLIError(cerror, details=[
                'To resize a virtual server, it must be STOPPED',
                'Server %s status is %s' % (server_id, vm['status']),
                'To stop the server',
                '  kamaki server shutdown %s -w' % server_id])

    @errors.Generic.all
    @errors.Cyclades.connection
    @errors.Cyclades.server_id
    def _run(self, server_id):
        if self['server_name'] is not None:
            self.client.update_server_name((server_id), self['server_name'])
        if self['flavor_id']:
            try:
                self.client.resize_server(server_id, self['flavor_id'])
            except ClientError as ce:
                if ce.status in (404, ):
                    self._flavor_exists(flavor_id=self['flavor_id'])
                if ce.status in (400, ):
                    self._server_is_stopped(server_id, ce)
                raise
        if self['firewall_profile']:
            self._set_firewall_profile(server_id)
        if self['metadata_to_set']:
            self.client.update_server_metadata(
                server_id, **self['metadata_to_set'])
        for key in (self['metadata_to_delete'] or []):
            errors.Cyclades.metadata(
                self.client.delete_server_metadata)(server_id, key=key)

    def main(self, server_id):
        super(self.__class__, self)._run()
        pnpid = self.arguments['public_network_port_id']
        fp = self.arguments['firewall_profile']
        if pnpid.value and not fp.value:
            raise CLIInvalidArgument('Invalid argument compination', details=[
                'Argument %s should always be combined with %s' % (
                    pnpid.lvalue, fp.lvalue)])
        self._run(server_id=server_id)