~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to bin/nova-manage

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-08-16 14:04:11 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20120816140411-0mr4n241wmk30t9l
Tags: upstream-2012.2~f3
ImportĀ upstreamĀ versionĀ 2012.2~f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
import netaddr
62
62
import optparse
63
63
import os
64
 
import StringIO
65
64
import sys
66
65
 
67
66
 
76
75
gettext.install('nova', unicode=1)
77
76
 
78
77
from nova.api.ec2 import ec2utils
79
 
from nova.auth import manager
80
78
from nova.compat import flagfile
81
79
from nova.compute import instance_types
82
80
from nova.compute import rpcapi as compute_rpcapi
83
81
from nova import context
84
 
from nova import crypto
85
82
from nova import db
86
83
from nova.db import migration
87
84
from nova import exception
88
85
from nova import flags
89
86
from nova.openstack.common import cfg
90
87
from nova.openstack.common import importutils
91
 
from nova.openstack.common import jsonutils
92
88
from nova.openstack.common import log as logging
93
89
from nova.openstack.common import rpc
94
90
from nova.openstack.common import timeutils
132
128
class VpnCommands(object):
133
129
    """Class for managing VPNs."""
134
130
 
135
 
    def __init__(self):
136
 
        self.manager = manager.AuthManager()
137
 
 
138
131
    @args('--project', dest="project_id", metavar='<Project name>',
139
132
            help='Project name')
140
133
    @args('--ip', dest="ip", metavar='<IP Address>', help='IP Address')
219
212
        arguments: path"""
220
213
        exec(compile(open(path).read(), path, 'exec'), locals(), globals())
221
214
 
222
 
    @args('--filename', dest='filename', metavar='<path>', default=False,
223
 
          help='Export file path')
224
 
    def export(self, filename):
225
 
        """Export Nova users into a file that can be consumed by Keystone"""
226
 
 
227
 
        def create_file(filename):
228
 
            data = generate_data()
229
 
            with open(filename, 'w') as f:
230
 
                f.write(data.getvalue())
231
 
 
232
 
        def tenants(data, am):
233
 
            for project in am.get_projects():
234
 
                print >> data, ("tenant add '%s'" %
235
 
                               (project.name))
236
 
                for u in project.member_ids:
237
 
                    user = am.get_user(u)
238
 
                    print >> data, ("user add '%s' '%s' '%s'" %
239
 
                                   (user.name, user.access, project.name))
240
 
                    print >> data, ("credentials add 'EC2' '%s:%s' '%s' '%s'" %
241
 
                            (user.access, project.id, user.secret, project.id))
242
 
 
243
 
        def roles(data, am):
244
 
            for role in am.get_roles():
245
 
                print >> data, ("role add '%s'" % (role))
246
 
 
247
 
        def grant_roles(data, am):
248
 
            roles = am.get_roles()
249
 
            for project in am.get_projects():
250
 
                for u in project.member_ids:
251
 
                    user = am.get_user(u)
252
 
                    for role in db.user_get_roles_for_project(ctxt, u,
253
 
                                                              project.id):
254
 
                        print >> data, ("role grant '%s', '%s', '%s')," %
255
 
                                       (user.name, role, project.name))
256
 
            print >> data
257
 
 
258
 
        def generate_data():
259
 
            data = StringIO.StringIO()
260
 
            am = manager.AuthManager()
261
 
            tenants(data, am)
262
 
            roles(data, am)
263
 
            grant_roles(data, am)
264
 
            data.seek(0)
265
 
            return data
266
 
 
267
 
        ctxt = context.get_admin_context()
268
 
        if filename:
269
 
            create_file(filename)
270
 
        else:
271
 
            data = generate_data()
272
 
            print data.getvalue()
273
 
 
274
 
 
275
 
class RoleCommands(object):
276
 
    """Class for managing roles."""
277
 
 
278
 
    def __init__(self):
279
 
        self.manager = manager.AuthManager()
280
 
 
281
 
    @args('--user', dest="user", metavar='<user name>', help='User name')
282
 
    @args('--role', dest="role", metavar='<user role>', help='User role')
283
 
    @args('--project', dest="project", metavar='<Project name>',
284
 
            help='Project name')
285
 
    def add(self, user, role, project=None):
286
 
        """adds role to user
287
 
        if project is specified, adds project specific role"""
288
 
        if project:
289
 
            projobj = self.manager.get_project(project)
290
 
            if not projobj.has_member(user):
291
 
                print "%s not a member of %s" % (user, project)
292
 
                return
293
 
        self.manager.add_role(user, role, project)
294
 
 
295
 
    @args('--user', dest="user", metavar='<user name>', help='User name')
296
 
    @args('--role', dest="role", metavar='<user role>', help='User role')
297
 
    @args('--project', dest="project", metavar='<Project name>',
298
 
            help='Project name')
299
 
    def has(self, user, role, project=None):
300
 
        """checks to see if user has role
301
 
        if project is specified, returns True if user has
302
 
        the global role and the project role"""
303
 
        print self.manager.has_role(user, role, project)
304
 
 
305
 
    @args('--user', dest="user", metavar='<user name>', help='User name')
306
 
    @args('--role', dest="role", metavar='<user role>', help='User role')
307
 
    @args('--project', dest="project", metavar='<Project name>',
308
 
            help='Project name')
309
 
    def remove(self, user, role, project=None):
310
 
        """removes role from user
311
 
        if project is specified, removes project specific role"""
312
 
        self.manager.remove_role(user, role, project)
313
 
 
314
215
 
315
216
def _db_error(caught_exception):
316
217
    print caught_exception
320
221
    exit(1)
321
222
 
322
223
 
323
 
class UserCommands(object):
324
 
    """Class for managing users."""
325
 
 
326
 
    @staticmethod
327
 
    def _print_export(user):
328
 
        """Print export variables to use with API."""
329
 
        print 'export EC2_ACCESS_KEY=%s' % user.access
330
 
        print 'export EC2_SECRET_KEY=%s' % user.secret
331
 
 
332
 
    def __init__(self):
333
 
        self.manager = manager.AuthManager()
334
 
 
335
 
    @args('--name', dest="name", metavar='<admin name>', help='Admin name')
336
 
    @args('--access', dest="access", metavar='<access>', help='Access')
337
 
    @args('--secret', dest="secret", metavar='<secret>', help='Secret')
338
 
    def admin(self, name, access=None, secret=None):
339
 
        """creates a new admin and prints exports"""
340
 
        try:
341
 
            user = self.manager.create_user(name, access, secret, True)
342
 
        except exception.DBError, e:
343
 
            _db_error(e)
344
 
        self._print_export(user)
345
 
 
346
 
    @args('--name', dest="name", metavar='<name>', help='User name')
347
 
    @args('--access', dest="access", metavar='<access>', help='Access')
348
 
    @args('--secret', dest="secret", metavar='<secret>', help='Secret')
349
 
    def create(self, name, access=None, secret=None):
350
 
        """creates a new user and prints exports"""
351
 
        try:
352
 
            user = self.manager.create_user(name, access, secret, False)
353
 
        except exception.DBError, e:
354
 
            _db_error(e)
355
 
        self._print_export(user)
356
 
 
357
 
    @args('--name', dest="name", metavar='<name>', help='User name')
358
 
    def delete(self, name):
359
 
        """deletes an existing user
360
 
        arguments: name"""
361
 
        self.manager.delete_user(name)
362
 
 
363
 
    @args('--name', dest="name", metavar='<admin name>', help='User name')
364
 
    def exports(self, name):
365
 
        """prints access and secrets for user in export format"""
366
 
        user = self.manager.get_user(name)
367
 
        if user:
368
 
            self._print_export(user)
369
 
        else:
370
 
            print "User %s doesn't exist" % name
371
 
 
372
 
    def list(self):
373
 
        """lists all users"""
374
 
        for user in self.manager.get_users():
375
 
            print user.name
376
 
 
377
 
    @args('--name', dest="name", metavar='<name>', help='User name')
378
 
    @args('--access', dest="access_key", metavar='<access>',
379
 
            help='Access key')
380
 
    @args('--secret', dest="secret_key", metavar='<secret>',
381
 
            help='Secret key')
382
 
    @args('--is_admin', dest='is_admin', metavar="<'T'|'F'>",
383
 
            help='Is admin?')
384
 
    def modify(self, name, access_key, secret_key, is_admin):
385
 
        """update a users keys & admin flag
386
 
        arguments: accesskey secretkey admin
387
 
        leave any field blank to ignore it, admin should be 'T', 'F', or blank
388
 
        """
389
 
        if not is_admin:
390
 
            is_admin = None
391
 
        elif is_admin.upper()[0] == 'T':
392
 
            is_admin = True
393
 
        else:
394
 
            is_admin = False
395
 
        self.manager.modify_user(name, access_key, secret_key, is_admin)
396
 
 
397
 
    @args('--name', dest="user_id", metavar='<name>', help='User name')
398
 
    @args('--project', dest="project_id", metavar='<Project name>',
399
 
            help='Project name')
400
 
    def revoke(self, user_id, project_id=None):
401
 
        """revoke certs for a user"""
402
 
        if project_id:
403
 
            crypto.revoke_certs_by_user_and_project(user_id, project_id)
404
 
        else:
405
 
            crypto.revoke_certs_by_user(user_id)
406
 
 
407
 
 
408
224
class ProjectCommands(object):
409
225
    """Class for managing projects."""
410
226
 
411
 
    def __init__(self):
412
 
        self.manager = manager.AuthManager()
413
 
 
414
 
    @args('--project', dest="project_id", metavar='<Project name>',
415
 
            help='Project name')
416
 
    @args('--user', dest="user_id", metavar='<name>', help='User name')
417
 
    def add(self, project_id, user_id):
418
 
        """Adds user to project"""
419
 
        try:
420
 
            self.manager.add_to_project(user_id, project_id)
421
 
        except exception.UserNotFound as ex:
422
 
            print ex
423
 
            raise
424
 
 
425
 
    @args('--project', dest="name", metavar='<Project name>',
426
 
            help='Project name')
427
 
    @args('--user', dest="project_manager", metavar='<user>',
428
 
            help='Project manager')
429
 
    @args('--desc', dest="description", metavar='<description>',
430
 
            help='Description')
431
 
    def create(self, name, project_manager, description=None):
432
 
        """Creates a new project"""
433
 
        try:
434
 
            self.manager.create_project(name, project_manager, description)
435
 
        except exception.UserNotFound as ex:
436
 
            print ex
437
 
            raise
438
 
 
439
 
    @args('--project', dest="name", metavar='<Project name>',
440
 
            help='Project name')
441
 
    @args('--user', dest="project_manager", metavar='<user>',
442
 
            help='Project manager')
443
 
    @args('--desc', dest="description", metavar='<description>',
444
 
            help='Description')
445
 
    def modify(self, name, project_manager, description=None):
446
 
        """Modifies a project"""
447
 
        try:
448
 
            self.manager.modify_project(name, project_manager, description)
449
 
        except exception.UserNotFound as ex:
450
 
            print ex
451
 
            raise
452
 
 
453
 
    @args('--project', dest="name", metavar='<Project name>',
454
 
            help='Project name')
455
 
    def delete(self, name):
456
 
        """Deletes an existing project"""
457
 
        try:
458
 
            self.manager.delete_project(name)
459
 
        except exception.ProjectNotFound as ex:
460
 
            print ex
461
 
            raise
462
 
 
463
 
    @args('--project', dest="project_id", metavar='<Project name>',
464
 
            help='Project name')
465
 
    @args('--user', dest="user_id", metavar='<name>', help='User name')
466
 
    @args('--file', dest="filename", metavar='<filename>',
467
 
            help='File name(Default: novarc)')
468
 
    def environment(self, project_id, user_id, filename='novarc'):
469
 
        """Exports environment variables to a sourceable file"""
470
 
        try:
471
 
            rc = self.manager.get_environment_rc(user_id, project_id)
472
 
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
473
 
            print ex
474
 
            raise
475
 
        if filename == "-":
476
 
            sys.stdout.write(rc)
477
 
        else:
478
 
            with open(filename, 'w') as f:
479
 
                f.write(rc)
480
 
 
481
 
    @args('--user', dest="username", metavar='<username>', help='User name')
482
 
    def list(self, username=None):
483
 
        """Lists all projects"""
484
 
        for project in self.manager.get_projects(username):
485
 
            print project.name
486
 
 
487
 
    @args('--project', dest="project_id", metavar='<Project name>',
488
 
            help='Project name')
489
 
    @args('--key', dest="key", metavar='<key>', help='Key')
490
 
    @args('--value', dest="value", metavar='<value>', help='Value')
491
227
    def quota(self, project_id, key=None, value=None):
492
228
        """Set or display quotas for project"""
493
229
        ctxt = context.get_admin_context()
506
242
 
507
243
    @args('--project', dest="project_id", metavar='<Project name>',
508
244
            help='Project name')
509
 
    @args('--user', dest="user_id", metavar='<name>', help='User name')
510
 
    def remove(self, project_id, user_id):
511
 
        """Removes user from project"""
512
 
        try:
513
 
            self.manager.remove_from_project(user_id, project_id)
514
 
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
515
 
            print ex
516
 
            raise
517
 
 
518
 
    @args('--project', dest="project_id", metavar='<Project name>',
519
 
            help='Project name')
520
245
    def scrub(self, project_id):
521
246
        """Deletes data associated with project"""
522
247
        admin_context = context.get_admin_context()
527
252
        for group in groups:
528
253
            db.security_group_destroy(admin_context, group['id'])
529
254
 
530
 
    @args('--project', dest="project_id", metavar='<Project name>',
531
 
            help='Project name')
532
 
    @args('--user', dest="user_id", metavar='<name>', help='User name')
533
 
    @args('--file', dest="filename", metavar='<filename>',
534
 
            help='File name(Default: nova.zip)')
535
 
    def zipfile(self, project_id, user_id, filename='nova.zip'):
536
 
        """Exports credentials for project to a zip file"""
537
 
        try:
538
 
            zip_file = self.manager.get_credentials(user_id, project_id)
539
 
            if filename == "-":
540
 
                sys.stdout.write(zip_file)
541
 
            else:
542
 
                with open(filename, 'w') as f:
543
 
                    f.write(zip_file)
544
 
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
545
 
            print ex
546
 
            raise
547
 
        except db.api.NoMoreNetworks:
548
 
            print _('No more networks available. If this is a new '
549
 
                    'installation, you need\nto call something like this:\n\n'
550
 
                    '  nova-manage network create pvt 10.0.0.0/8 10 64\n\n')
551
 
        except exception.ProcessExecutionError, e:
552
 
            print e
553
 
            print _("The above error may show that the certificate db has "
554
 
                    "not been created.\nPlease create a database by running "
555
 
                    "a nova-cert server on this host.")
556
255
 
557
256
AccountCommands = ProjectCommands
558
257
 
575
274
            sys.exit(2)
576
275
 
577
276
        instances = db.instance_get_all(context.get_admin_context())
578
 
        instances_by_id = {}
 
277
        instances_by_uuid = {}
579
278
        for instance in instances:
580
 
            instances_by_id[instance['id']] = instance
 
279
            instances_by_uuid[instance['uuid']] = instance
581
280
 
582
281
        print "%-18s\t%-15s\t%-15s\t%s" % (_('network'),
583
282
                                              _('IP address'),
584
283
                                              _('hostname'),
585
284
                                              _('host'))
 
285
 
 
286
        all_networks = {}
 
287
        try:
 
288
            # use network_get_all to retrieve all existing networks
 
289
            # this is to ensure that IPs associated with deleted networks
 
290
            # will not throw exceptions.
 
291
            for network in db.network_get_all(context.get_admin_context()):
 
292
                all_networks[network.id] = network
 
293
        except exception.NoNetworksFound:
 
294
            # do not have any networks, so even if there are IPs, these
 
295
            # IPs should have been deleted ones, so return.
 
296
            print _('No fixed IP found.')
 
297
            return
 
298
 
 
299
        has_ip = False
586
300
        for fixed_ip in fixed_ips:
587
301
            hostname = None
588
302
            host = None
589
303
            mac_address = None
590
 
            network = db.network_get(context.get_admin_context(),
591
 
                                     fixed_ip['network_id'])
592
 
            if fixed_ip['instance_id']:
593
 
                instance = instances_by_id.get(fixed_ip['instance_id'])
594
 
                if instance:
595
 
                    hostname = instance['hostname']
596
 
                    host = instance['host']
597
 
                else:
598
 
                    print ('WARNING: fixed ip %s allocated to missing'
599
 
                           ' instance' % str(fixed_ip['address']))
600
 
            print "%-18s\t%-15s\t%-15s\t%s" % (
601
 
                    network['cidr'],
602
 
                    fixed_ip['address'],
603
 
                    hostname, host)
 
304
            network = all_networks.get(fixed_ip['network_id'])
 
305
            if network:
 
306
                has_ip = True
 
307
                if fixed_ip.get('instance_uuid'):
 
308
                    instance = instances_by_uuid.get(fixed_ip['instance_uuid'])
 
309
                    if instance:
 
310
                        hostname = instance['hostname']
 
311
                        host = instance['host']
 
312
                    else:
 
313
                        print _('WARNING: fixed ip %s allocated to missing'
 
314
                                ' instance') % str(fixed_ip['address'])
 
315
                print "%-18s\t%-15s\t%-15s\t%s" % (
 
316
                        network['cidr'],
 
317
                        fixed_ip['address'],
 
318
                        hostname, host)
 
319
 
 
320
        if not has_ip:
 
321
            print _('No fixed IP found.')
604
322
 
605
323
    @args('--address', dest="address", metavar='<ip address>',
606
324
          help='IP address')
644
362
        try:
645
363
            return [netaddr.IPAddress(addresses)]
646
364
        except ValueError:
647
 
            return netaddr.IPNetwork(addresses).iter_hosts()
 
365
            net = netaddr.IPNetwork(addresses)
 
366
            if net.size < 4:
 
367
                reason = _("/%s should be specified as single address(es) "
 
368
                           "not in cidr format") % net.prefixlen
 
369
                raise exception.InvalidInput(reason=reason)
 
370
            else:
 
371
                return net.iter_hosts()
648
372
 
649
373
    @args('--ip_range', dest="ip_range", metavar='<range>', help='IP range')
650
374
    @args('--pool', dest="pool", metavar='<pool>', help='Optional pool')
657
381
            pool = FLAGS.default_floating_pool
658
382
        if not interface:
659
383
            interface = FLAGS.public_interface
660
 
        for address in self.address_to_hosts(ip_range):
661
 
            db.floating_ip_create(admin_context,
662
 
                                  {'address': str(address),
663
 
                                   'pool': pool,
664
 
                                   'interface': interface})
 
384
 
 
385
        ips = ({'address': str(address), 'pool': pool, 'interface': interface}
 
386
               for address in self.address_to_hosts(ip_range))
 
387
        try:
 
388
            db.floating_ip_bulk_create(admin_context, ips)
 
389
        except exception.FloatingIpExists as exc:
 
390
            # NOTE(simplylizz): Maybe logging would be better here
 
391
            # instead of printing, but logging isn't used here and I
 
392
            # don't know why.
 
393
            print('error: %s' % exc)
 
394
            sys.exit(1)
665
395
 
666
396
    @args('--ip_range', dest="ip_range", metavar='<range>', help='IP range')
667
397
    def delete(self, ip_range):
668
398
        """Deletes floating ips by range"""
669
399
        for address in self.address_to_hosts(ip_range):
670
 
            db.floating_ip_destroy(context.get_admin_context(),
671
 
                                   str(address))
 
400
            try:
 
401
                db.floating_ip_destroy(context.get_admin_context(),
 
402
                                       str(address))
 
403
            except exception.FloatingIpNotFoundForAddress as ex:
 
404
                print "Warning: %s" % ex
672
405
 
673
406
    @args('--host', dest="host", metavar='<host>', help='Host')
674
407
    def list(self, host=None):
684
417
            print _("No floating IP addresses have been defined.")
685
418
            return
686
419
        for floating_ip in floating_ips:
687
 
            instance_id = None
 
420
            instance_uuid = None
688
421
            if floating_ip['fixed_ip_id']:
689
422
                fixed_ip = db.fixed_ip_get(ctxt, floating_ip['fixed_ip_id'])
690
 
                try:
691
 
                    instance = db.instance_get(ctxt, fixed_ip['instance_id'])
692
 
                    instance_id = instance.get('uuid', "none")
693
 
                except exception.InstanceNotFound:
694
 
                    msg = _('Missing instance %s')
695
 
                    instance_id = msg % fixed_ip['instance_id']
 
423
                instance_uuid = fixed_ip['instance_uuid']
696
424
 
697
425
            print "%s\t%s\t%s\t%s\t%s" % (floating_ip['project_id'],
698
426
                                          floating_ip['address'],
699
 
                                          instance_id,
 
427
                                          instance_uuid,
700
428
                                          floating_ip['pool'],
701
429
                                          floating_ip['interface'])
702
430
 
834
562
                          _('VlanID'),
835
563
                          _('project'),
836
564
                          _("uuid"))
837
 
        for network in db.network_get_all(context.get_admin_context()):
838
 
            print _fmt % (network.id,
839
 
                          network.cidr,
840
 
                          network.cidr_v6,
841
 
                          network.dhcp_start,
842
 
                          network.dns1,
843
 
                          network.dns2,
844
 
                          network.vlan,
845
 
                          network.project_id,
846
 
                          network.uuid)
847
 
 
848
 
    def quantum_list(self):
849
 
        """List all created networks with Quantum-relevant fields"""
850
 
        _fmt = "%-32s\t%-10s\t%-10s\t%s , %s"
851
 
        print _fmt % (_('uuid'),
852
 
                      _('project'),
853
 
                      _('priority'),
854
 
                      _('cidr_v4'),
855
 
                      _('cidr_v6'))
856
 
        for network in db.network_get_all(context.get_admin_context()):
857
 
            print _fmt % (network.uuid,
858
 
                          network.project_id,
859
 
                          network.priority,
860
 
                          network.cidr,
861
 
                          network.cidr_v6)
 
565
        try:
 
566
            # Since network_get_all can throw exception.NoNetworksFound
 
567
            # for this command to show a nice result, this exception
 
568
            # should be caught and handled as such.
 
569
            networks = db.network_get_all(context.get_admin_context())
 
570
        except exception.NoNetworksFound:
 
571
            print _('No networks found')
 
572
        else:
 
573
            for network in networks:
 
574
                print _fmt % (network.id,
 
575
                              network.cidr,
 
576
                              network.cidr_v6,
 
577
                              network.dhcp_start,
 
578
                              network.dns1,
 
579
                              network.dns2,
 
580
                              network.vlan,
 
581
                              network.project_id,
 
582
                              network.uuid)
862
583
 
863
584
    @args('--fixed_range', dest="fixed_range", metavar='<x.x.x.x/yy>',
864
585
            help='Network to delete')
1180
901
    def _print_instance_types(self, name, val):
1181
902
        deleted = ('', ', inactive')[val["deleted"] == 1]
1182
903
        print ("%s: Memory: %sMB, VCPUS: %s, Root: %sGB, Ephemeral: %sGb, "
1183
 
            "FlavorID: %s, Swap: %sMB, RXTX Factor: %s") % (
 
904
            "FlavorID: %s, Swap: %sMB, RXTX Factor: %s, ExtraSpecs %s") % (
1184
905
            name, val["memory_mb"], val["vcpus"], val["root_gb"],
1185
906
            val["ephemeral_gb"], val["flavorid"], val["swap"],
1186
 
            val["rxtx_factor"])
 
907
            val["rxtx_factor"], val["extra_specs"])
1187
908
 
1188
909
    @args('--name', dest='name', metavar='<name>',
1189
910
            help='Name of instance type/flavor')
1256
977
        else:
1257
978
            self._print_instance_types(name, inst_types)
1258
979
 
 
980
    @args('--name', dest='name', metavar='<name>',
 
981
           help='Name of instance type/flavor')
 
982
    @args('--key', dest='key', metavar='<key>',
 
983
           help='The key of the key/value pair')
 
984
    @args('--value', dest='value', metavar='<value>',
 
985
           help='The value of the key/value pair')
 
986
    def set_key(self, name, key, value=None):
 
987
        """Add key/value pair to specified instance type's extra_specs"""
 
988
        try:
 
989
            try:
 
990
                inst_type = instance_types.get_instance_type_by_name(name)
 
991
            except exception.InstanceTypeNotFoundByName, e:
 
992
                print e
 
993
                sys.exit(2)
 
994
 
 
995
            ctxt = context.get_admin_context()
 
996
            ext_spec = {key: value}
 
997
            db.instance_type_extra_specs_update_or_create(
 
998
                            ctxt,
 
999
                            inst_type["flavorid"],
 
1000
                            ext_spec)
 
1001
            print _("Key %(key)s set to %(value)s on instance"
 
1002
                            " type %(name)s") % locals()
 
1003
        except exception.DBError, e:
 
1004
            _db_error(e)
 
1005
 
 
1006
    @args('--name', dest='name', metavar='<name>',
 
1007
           help='Name of instance type/flavor')
 
1008
    @args('--key', dest='key', metavar='<key>',
 
1009
           help='The key to be deleted')
 
1010
    def unset_key(self, name, key):
 
1011
        """Delete the specified extra spec for instance type"""
 
1012
        try:
 
1013
            try:
 
1014
                inst_type = instance_types.get_instance_type_by_name(name)
 
1015
            except exception.InstanceTypeNotFoundByName, e:
 
1016
                print e
 
1017
                sys.exit(2)
 
1018
 
 
1019
            ctxt = context.get_admin_context()
 
1020
            db.instance_type_extra_specs_delete(
 
1021
                        ctxt,
 
1022
                        inst_type["flavorid"],
 
1023
                        key)
 
1024
 
 
1025
            print _("Key %(key)s on instance type %(name)s unset") % locals()
 
1026
        except exception.DBError, e:
 
1027
            _db_error(e)
 
1028
 
1259
1029
 
1260
1030
class StorageManagerCommands(object):
1261
1031
    """Class for mangaging Storage Backends and Flavors"""
1531
1301
            print "No nova entries in syslog!"
1532
1302
 
1533
1303
 
1534
 
class ExportCommands(object):
1535
 
    """Commands used to export data from Nova"""
1536
 
 
1537
 
    def auth(self):
1538
 
        """Export Nova auth data in format that can be consumed by Keystone"""
1539
 
        print jsonutils.dumps(self._get_auth_data())
1540
 
 
1541
 
    def _get_auth_data(self):
1542
 
        output = {
1543
 
            'users': [],
1544
 
            'tenants': [],
1545
 
            'user_tenant_list': [],
1546
 
            'ec2_credentials': [],
1547
 
            'roles': [],
1548
 
            'role_user_tenant_list': [],
1549
 
        }
1550
 
 
1551
 
        am = manager.AuthManager()
1552
 
 
1553
 
        for user in am.get_users():
1554
 
            # NOTE(vish): Deprecated auth uses an access key, no auth uses a
1555
 
            #             the user_id in place of it.
1556
 
            if FLAGS.auth_strategy == 'deprecated':
1557
 
                access = user.access
1558
 
            else:
1559
 
                access = user.id
1560
 
 
1561
 
            user_dict = {
1562
 
                'id': user.id,
1563
 
                'name': user.name,
1564
 
                'password': access,
1565
 
            }
1566
 
            output['users'].append(user_dict)
1567
 
 
1568
 
            ec2_cred = {
1569
 
                'user_id': user.id,
1570
 
                'access_key': access,
1571
 
                'secret_key': user.secret,
1572
 
            }
1573
 
            output['ec2_credentials'].append(ec2_cred)
1574
 
 
1575
 
        for project in am.get_projects():
1576
 
            tenant = {
1577
 
                'id': project.id,
1578
 
                'name': project.name,
1579
 
                'description': project.description,
1580
 
            }
1581
 
            output['tenants'].append(tenant)
1582
 
 
1583
 
            for user_id in project.member_ids:
1584
 
                membership = {
1585
 
                    'tenant_id': project.id,
1586
 
                    'user_id': user_id,
1587
 
                }
1588
 
                output['user_tenant_list'].append(membership)
1589
 
 
1590
 
        for role in am.get_roles():
1591
 
            if role not in output['roles']:
1592
 
                output['roles'].append(role)
1593
 
 
1594
 
        for project in am.get_projects():
1595
 
            for user_id in project.member_ids:
1596
 
                user = am.get_user(user_id)
1597
 
                for role in am.get_user_roles(user_id, project.id):
1598
 
                    role_grant = {
1599
 
                        'role': role,
1600
 
                        'user_id': user_id,
1601
 
                        'tenant_id': project.id,
1602
 
                    }
1603
 
                    output['role_user_tenant_list'].append(role_grant)
1604
 
 
1605
 
        return output
1606
 
 
1607
 
 
1608
1304
CATEGORIES = [
1609
1305
    ('account', AccountCommands),
1610
1306
    ('agent', AgentBuildCommands),
1611
1307
    ('config', ConfigCommands),
1612
1308
    ('db', DbCommands),
1613
 
    ('export', ExportCommands),
1614
1309
    ('fixed', FixedIpCommands),
1615
1310
    ('flavor', InstanceTypeCommands),
1616
1311
    ('floating', FloatingIpCommands),
1619
1314
    ('logs', GetLogCommands),
1620
1315
    ('network', NetworkCommands),
1621
1316
    ('project', ProjectCommands),
1622
 
    ('role', RoleCommands),
1623
1317
    ('service', ServiceCommands),
1624
1318
    ('shell', ShellCommands),
1625
1319
    ('sm', StorageManagerCommands),
1626
 
    ('user', UserCommands),
1627
1320
    ('version', VersionCommands),
1628
1321
    ('vm', VmCommands),
1629
1322
    ('volume', VolumeCommands),