~mdragon/nova/system-usages

« back to all changes in this revision

Viewing changes to bin/nova-manage

  • Committer: Monsyne Dragon
  • Date: 2011-06-28 10:23:00 UTC
  • mfrom: (1077.1.141 nova)
  • Revision ID: mdragon@rackspace.com-20110628102300-lnkdr13k8uuyp30i
remergedĀ trunkĀ 

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
  CLI interface for nova management.
54
54
"""
55
55
 
56
 
import datetime
57
56
import gettext
58
57
import glob
59
58
import json
 
59
import netaddr
60
60
import os
61
61
import sys
62
62
import time
63
63
 
64
 
import IPy
65
64
 
66
65
# If ../nova/__init__.py exists, add ../ to Python search path, so that
67
66
# it will override what happens to be installed in /usr/(local/)lib/python...
78
77
from nova import db
79
78
from nova import exception
80
79
from nova import flags
 
80
from nova import image
81
81
from nova import log as logging
82
82
from nova import quota
83
83
from nova import rpc
96
96
flags.DECLARE('vlan_start', 'nova.network.manager')
97
97
flags.DECLARE('vpn_start', 'nova.network.manager')
98
98
flags.DECLARE('fixed_range_v6', 'nova.network.manager')
99
 
flags.DECLARE('images_path', 'nova.image.local')
100
 
flags.DECLARE('libvirt_type', 'nova.virt.libvirt_conn')
 
99
flags.DECLARE('gateway_v6', 'nova.network.manager')
 
100
flags.DECLARE('libvirt_type', 'nova.virt.libvirt.connection')
101
101
flags.DEFINE_flag(flags.HelpFlag())
102
102
flags.DEFINE_flag(flags.HelpshortFlag())
103
103
flags.DEFINE_flag(flags.HelpXMLFlag())
257
257
        """adds role to user
258
258
        if project is specified, adds project specific role
259
259
        arguments: user, role [project]"""
 
260
        if project:
 
261
            projobj = self.manager.get_project(project)
 
262
            if not projobj.has_member(user):
 
263
                print "%s not a member of %s" % (user, project)
 
264
                return
260
265
        self.manager.add_role(user, role, project)
261
266
 
262
267
    def has(self, user, role, project=None):
362
367
    def add(self, project_id, user_id):
363
368
        """Adds user to project
364
369
        arguments: project_id user_id"""
365
 
        self.manager.add_to_project(user_id, project_id)
 
370
        try:
 
371
            self.manager.add_to_project(user_id, project_id)
 
372
        except exception.UserNotFound as ex:
 
373
            print ex
 
374
            raise
366
375
 
367
376
    def create(self, name, project_manager, description=None):
368
377
        """Creates a new project
369
378
        arguments: name project_manager [description]"""
370
 
        self.manager.create_project(name, project_manager, description)
 
379
        try:
 
380
            self.manager.create_project(name, project_manager, description)
 
381
        except exception.UserNotFound as ex:
 
382
            print ex
 
383
            raise
371
384
 
372
385
    def modify(self, name, project_manager, description=None):
373
386
        """Modifies a project
374
387
        arguments: name project_manager [description]"""
375
 
        self.manager.modify_project(name, project_manager, description)
 
388
        try:
 
389
            self.manager.modify_project(name, project_manager, description)
 
390
        except exception.UserNotFound as ex:
 
391
            print ex
 
392
            raise
376
393
 
377
394
    def delete(self, name):
378
395
        """Deletes an existing project
379
396
        arguments: name"""
380
 
        self.manager.delete_project(name)
 
397
        try:
 
398
            self.manager.delete_project(name)
 
399
        except exception.ProjectNotFound as ex:
 
400
            print ex
 
401
            raise
381
402
 
382
403
    def environment(self, project_id, user_id, filename='novarc'):
383
404
        """Exports environment variables to an sourcable file
384
405
        arguments: project_id user_id [filename='novarc]"""
385
 
        rc = self.manager.get_environment_rc(user_id, project_id)
 
406
        try:
 
407
            rc = self.manager.get_environment_rc(user_id, project_id)
 
408
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
 
409
            print ex
 
410
            raise
386
411
        with open(filename, 'w') as f:
387
412
            f.write(rc)
388
413
 
397
422
        arguments: project_id [key] [value]"""
398
423
        ctxt = context.get_admin_context()
399
424
        if key:
 
425
            if value.lower() == 'unlimited':
 
426
                value = None
400
427
            try:
401
428
                db.quota_update(ctxt, project_id, key, value)
402
 
            except exception.NotFound:
 
429
            except exception.ProjectQuotaNotFound:
403
430
                db.quota_create(ctxt, project_id, key, value)
404
 
        project_quota = quota.get_quota(ctxt, project_id)
 
431
        project_quota = quota.get_project_quotas(ctxt, project_id)
405
432
        for key, value in project_quota.iteritems():
 
433
            if value is None:
 
434
                value = 'unlimited'
406
435
            print '%s: %s' % (key, value)
407
436
 
408
437
    def remove(self, project_id, user_id):
409
438
        """Removes user from project
410
439
        arguments: project_id user_id"""
411
 
        self.manager.remove_from_project(user_id, project_id)
 
440
        try:
 
441
            self.manager.remove_from_project(user_id, project_id)
 
442
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
 
443
            print ex
 
444
            raise
412
445
 
413
446
    def scrub(self, project_id):
414
447
        """Deletes data associated with project
427
460
            zip_file = self.manager.get_credentials(user_id, project_id)
428
461
            with open(filename, 'w') as f:
429
462
                f.write(zip_file)
 
463
        except (exception.UserNotFound, exception.ProjectNotFound) as ex:
 
464
            print ex
 
465
            raise
430
466
        except db.api.NoMoreNetworks:
431
467
            print _('No more networks available. If this is a new '
432
468
                    'installation, you need\nto call something like this:\n\n'
482
518
    def create(self, host, range):
483
519
        """Creates floating ips for host by range
484
520
        arguments: host ip_range"""
485
 
        for address in IPy.IP(range):
 
521
        for address in netaddr.IPNetwork(range):
486
522
            db.floating_ip_create(context.get_admin_context(),
487
523
                                  {'address': str(address),
488
524
                                   'host': host})
490
526
    def delete(self, ip_range):
491
527
        """Deletes floating ips by range
492
528
        arguments: range"""
493
 
        for address in IPy.IP(ip_range):
 
529
        for address in netaddr.IPNetwork(ip_range):
494
530
            db.floating_ip_destroy(context.get_admin_context(),
495
531
                                   str(address))
496
532
 
505
541
        for floating_ip in floating_ips:
506
542
            instance = None
507
543
            if floating_ip['fixed_ip']:
508
 
                instance = floating_ip['fixed_ip']['instance']['ec2_id']
 
544
                instance = floating_ip['fixed_ip']['instance']['hostname']
509
545
            print "%s\t%s\t%s" % (floating_ip['host'],
510
546
                                  floating_ip['address'],
511
547
                                  instance)
514
550
class NetworkCommands(object):
515
551
    """Class for managing networks."""
516
552
 
517
 
    def create(self, fixed_range=None, num_networks=None,
518
 
               network_size=None, vlan_start=None,
519
 
               vpn_start=None, fixed_range_v6=None, label='public'):
520
 
        """Creates fixed ips for host by range
521
 
        arguments: fixed_range=FLAG, [num_networks=FLAG],
522
 
                   [network_size=FLAG], [vlan_start=FLAG],
523
 
                   [vpn_start=FLAG], [fixed_range_v6=FLAG]"""
 
553
    def create(self, fixed_range=None, num_networks=None, network_size=None,
 
554
            vlan_start=None, vpn_start=None, fixed_range_v6=None,
 
555
            gateway_v6=None, label='public'):
 
556
        """Creates fixed ips for host by range"""
524
557
        if not fixed_range:
525
 
            raise TypeError(_('Fixed range in the form of 10.0.0.0/8 is '
526
 
                              'required to create networks.'))
 
558
            msg = _('Fixed range in the form of 10.0.0.0/8 is '
 
559
                    'required to create networks.')
 
560
            print msg
 
561
            raise TypeError(msg)
527
562
        if not num_networks:
528
563
            num_networks = FLAGS.num_networks
529
564
        if not network_size:
534
569
            vpn_start = FLAGS.vpn_start
535
570
        if not fixed_range_v6:
536
571
            fixed_range_v6 = FLAGS.fixed_range_v6
 
572
        if not gateway_v6:
 
573
            gateway_v6 = FLAGS.gateway_v6
537
574
        net_manager = utils.import_object(FLAGS.network_manager)
538
 
        net_manager.create_networks(context.get_admin_context(),
539
 
                                    cidr=fixed_range,
540
 
                                    num_networks=int(num_networks),
541
 
                                    network_size=int(network_size),
542
 
                                    vlan_start=int(vlan_start),
543
 
                                    vpn_start=int(vpn_start),
544
 
                                    cidr_v6=fixed_range_v6,
545
 
                                    label=label)
 
575
        try:
 
576
            net_manager.create_networks(context.get_admin_context(),
 
577
                                        cidr=fixed_range,
 
578
                                        num_networks=int(num_networks),
 
579
                                        network_size=int(network_size),
 
580
                                        vlan_start=int(vlan_start),
 
581
                                        vpn_start=int(vpn_start),
 
582
                                        cidr_v6=fixed_range_v6,
 
583
                                        gateway_v6=gateway_v6,
 
584
                                        label=label)
 
585
        except ValueError, e:
 
586
            print e
 
587
            raise e
546
588
 
547
589
    def list(self):
548
590
        """List all created networks"""
652
694
        """Show a list of all running services. Filter by host & service name.
653
695
        args: [host] [service]"""
654
696
        ctxt = context.get_admin_context()
655
 
        now = datetime.datetime.utcnow()
 
697
        now = utils.utcnow()
656
698
        services = db.service_get_all(ctxt)
657
699
        if host:
658
700
            services = [s for s in services if s['host'] == host]
836
878
        try:
837
879
            instance_types.create(name, memory, vcpus, local_gb,
838
880
                                  flavorid, swap, rxtx_quota, rxtx_cap)
839
 
        except exception.InvalidInputException:
 
881
        except exception.InvalidInput:
840
882
            print "Must supply valid parameters to create instance_type"
841
883
            print e
842
884
            sys.exit(1)
899
941
    """Methods for dealing with a cloud in an odd state"""
900
942
 
901
943
    def __init__(self, *args, **kwargs):
902
 
        self.image_service = utils.import_object(FLAGS.image_service)
 
944
        self.image_service = image.get_default_image_service()
903
945
 
904
946
    def _register(self, container_format, disk_format,
905
947
                  path, owner, name=None, is_public='T',
1018
1060
        machine_images = {}
1019
1061
        other_images = {}
1020
1062
        directory = os.path.abspath(directory)
1021
 
        # NOTE(vish): If we're importing from the images path dir, attempt
1022
 
        #             to move the files out of the way before importing
1023
 
        #             so we aren't writing to the same directory. This
1024
 
        #             may fail if the dir was a mointpoint.
1025
 
        if (FLAGS.image_service == 'nova.image.local.LocalImageService'
1026
 
            and directory == os.path.abspath(FLAGS.images_path)):
1027
 
            new_dir = "%s_bak" % directory
1028
 
            os.rename(directory, new_dir)
1029
 
            os.mkdir(directory)
1030
 
            directory = new_dir
1031
1063
        for fn in glob.glob("%s/*/info.json" % directory):
1032
1064
            try:
1033
1065
                image_path = os.path.join(fn.rpartition('/')[0], 'image')
1044
1076
        self._convert_images(machine_images)
1045
1077
 
1046
1078
 
 
1079
class AgentBuildCommands(object):
 
1080
    """Class for managing agent builds."""
 
1081
 
 
1082
    def create(self, os, architecture, version, url, md5hash,
 
1083
                hypervisor='xen'):
 
1084
        """Creates a new agent build.
 
1085
        arguments: os architecture version url md5hash [hypervisor='xen']"""
 
1086
        ctxt = context.get_admin_context()
 
1087
        agent_build = db.agent_build_create(ctxt,
 
1088
                                            {'hypervisor': hypervisor,
 
1089
                                             'os': os,
 
1090
                                             'architecture': architecture,
 
1091
                                             'version': version,
 
1092
                                             'url': url,
 
1093
                                             'md5hash': md5hash})
 
1094
 
 
1095
    def delete(self, os, architecture, hypervisor='xen'):
 
1096
        """Deletes an existing agent build.
 
1097
        arguments: os architecture [hypervisor='xen']"""
 
1098
        ctxt = context.get_admin_context()
 
1099
        agent_build_ref = db.agent_build_get_by_triple(ctxt,
 
1100
                                  hypervisor, os, architecture)
 
1101
        db.agent_build_destroy(ctxt, agent_build_ref['id'])
 
1102
 
 
1103
    def list(self, hypervisor=None):
 
1104
        """Lists all agent builds.
 
1105
        arguments: <none>"""
 
1106
        fmt = "%-10s  %-8s  %12s  %s"
 
1107
        ctxt = context.get_admin_context()
 
1108
        by_hypervisor = {}
 
1109
        for agent_build in db.agent_build_get_all(ctxt):
 
1110
            buildlist = by_hypervisor.get(agent_build.hypervisor)
 
1111
            if not buildlist:
 
1112
                buildlist = by_hypervisor[agent_build.hypervisor] = []
 
1113
 
 
1114
            buildlist.append(agent_build)
 
1115
 
 
1116
        for key, buildlist in by_hypervisor.iteritems():
 
1117
            if hypervisor and key != hypervisor:
 
1118
                continue
 
1119
 
 
1120
            print "Hypervisor: %s" % key
 
1121
            print fmt % ('-' * 10, '-' * 8, '-' * 12, '-' * 32)
 
1122
            for agent_build in buildlist:
 
1123
                print fmt % (agent_build.os, agent_build.architecture,
 
1124
                             agent_build.version, agent_build.md5hash)
 
1125
                print '    %s' % agent_build.url
 
1126
 
 
1127
            print
 
1128
 
 
1129
    def modify(self, os, architecture, version, url, md5hash,
 
1130
               hypervisor='xen'):
 
1131
        """Update an existing agent build.
 
1132
        arguments: os architecture version url md5hash [hypervisor='xen']
 
1133
        """
 
1134
        ctxt = context.get_admin_context()
 
1135
        agent_build_ref = db.agent_build_get_by_triple(ctxt,
 
1136
                                  hypervisor, os, architecture)
 
1137
        db.agent_build_update(ctxt, agent_build_ref['id'],
 
1138
                              {'version': version,
 
1139
                               'url': url,
 
1140
                               'md5hash': md5hash})
 
1141
 
 
1142
 
 
1143
class ConfigCommands(object):
 
1144
    """Class for exposing the flags defined by flag_file(s)."""
 
1145
 
 
1146
    def __init__(self):
 
1147
        pass
 
1148
 
 
1149
    def list(self):
 
1150
        print FLAGS.FlagsIntoString()
 
1151
 
 
1152
 
1047
1153
CATEGORIES = [
1048
 
    ('user', UserCommands),
1049
1154
    ('account', AccountCommands),
 
1155
    ('agent', AgentBuildCommands),
 
1156
    ('config', ConfigCommands),
 
1157
    ('db', DbCommands),
 
1158
    ('fixed', FixedIpCommands),
 
1159
    ('flavor', InstanceTypeCommands),
 
1160
    ('floating', FloatingIpCommands),
 
1161
    ('instance_type', InstanceTypeCommands),
 
1162
    ('image', ImageCommands),
 
1163
    ('network', NetworkCommands),
1050
1164
    ('project', ProjectCommands),
1051
1165
    ('role', RoleCommands),
 
1166
    ('service', ServiceCommands),
1052
1167
    ('shell', ShellCommands),
1053
 
    ('vpn', VpnCommands),
1054
 
    ('fixed', FixedIpCommands),
1055
 
    ('floating', FloatingIpCommands),
1056
 
    ('network', NetworkCommands),
 
1168
    ('user', UserCommands),
 
1169
    ('version', VersionCommands),
1057
1170
    ('vm', VmCommands),
1058
 
    ('service', ServiceCommands),
1059
 
    ('db', DbCommands),
1060
1171
    ('volume', VolumeCommands),
1061
 
    ('instance_type', InstanceTypeCommands),
1062
 
    ('image', ImageCommands),
1063
 
    ('flavor', InstanceTypeCommands),
1064
 
    ('version', VersionCommands)]
 
1172
    ('vpn', VpnCommands)]
1065
1173
 
1066
1174
 
1067
1175
def lazy_match(name, key_value_tuples):