219
212
arguments: path"""
220
213
exec(compile(open(path).read(), path, 'exec'), locals(), globals())
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"""
227
def create_file(filename):
228
data = generate_data()
229
with open(filename, 'w') as f:
230
f.write(data.getvalue())
232
def tenants(data, am):
233
for project in am.get_projects():
234
print >> data, ("tenant add '%s'" %
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))
244
for role in am.get_roles():
245
print >> data, ("role add '%s'" % (role))
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,
254
print >> data, ("role grant '%s', '%s', '%s')," %
255
(user.name, role, project.name))
259
data = StringIO.StringIO()
260
am = manager.AuthManager()
263
grant_roles(data, am)
267
ctxt = context.get_admin_context()
269
create_file(filename)
271
data = generate_data()
272
print data.getvalue()
275
class RoleCommands(object):
276
"""Class for managing roles."""
279
self.manager = manager.AuthManager()
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>',
285
def add(self, user, role, project=None):
287
if project is specified, adds project specific role"""
289
projobj = self.manager.get_project(project)
290
if not projobj.has_member(user):
291
print "%s not a member of %s" % (user, project)
293
self.manager.add_role(user, role, project)
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>',
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)
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>',
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)
315
216
def _db_error(caught_exception):
316
217
print caught_exception
323
class UserCommands(object):
324
"""Class for managing users."""
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
333
self.manager = manager.AuthManager()
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"""
341
user = self.manager.create_user(name, access, secret, True)
342
except exception.DBError, e:
344
self._print_export(user)
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"""
352
user = self.manager.create_user(name, access, secret, False)
353
except exception.DBError, e:
355
self._print_export(user)
357
@args('--name', dest="name", metavar='<name>', help='User name')
358
def delete(self, name):
359
"""deletes an existing user
361
self.manager.delete_user(name)
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)
368
self._print_export(user)
370
print "User %s doesn't exist" % name
373
"""lists all users"""
374
for user in self.manager.get_users():
377
@args('--name', dest="name", metavar='<name>', help='User name')
378
@args('--access', dest="access_key", metavar='<access>',
380
@args('--secret', dest="secret_key", metavar='<secret>',
382
@args('--is_admin', dest='is_admin', metavar="<'T'|'F'>",
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
391
elif is_admin.upper()[0] == 'T':
395
self.manager.modify_user(name, access_key, secret_key, is_admin)
397
@args('--name', dest="user_id", metavar='<name>', help='User name')
398
@args('--project', dest="project_id", metavar='<Project name>',
400
def revoke(self, user_id, project_id=None):
401
"""revoke certs for a user"""
403
crypto.revoke_certs_by_user_and_project(user_id, project_id)
405
crypto.revoke_certs_by_user(user_id)
408
224
class ProjectCommands(object):
409
225
"""Class for managing projects."""
412
self.manager = manager.AuthManager()
414
@args('--project', dest="project_id", metavar='<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"""
420
self.manager.add_to_project(user_id, project_id)
421
except exception.UserNotFound as ex:
425
@args('--project', dest="name", metavar='<Project name>',
427
@args('--user', dest="project_manager", metavar='<user>',
428
help='Project manager')
429
@args('--desc', dest="description", metavar='<description>',
431
def create(self, name, project_manager, description=None):
432
"""Creates a new project"""
434
self.manager.create_project(name, project_manager, description)
435
except exception.UserNotFound as ex:
439
@args('--project', dest="name", metavar='<Project name>',
441
@args('--user', dest="project_manager", metavar='<user>',
442
help='Project manager')
443
@args('--desc', dest="description", metavar='<description>',
445
def modify(self, name, project_manager, description=None):
446
"""Modifies a project"""
448
self.manager.modify_project(name, project_manager, description)
449
except exception.UserNotFound as ex:
453
@args('--project', dest="name", metavar='<Project name>',
455
def delete(self, name):
456
"""Deletes an existing project"""
458
self.manager.delete_project(name)
459
except exception.ProjectNotFound as ex:
463
@args('--project', dest="project_id", metavar='<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"""
471
rc = self.manager.get_environment_rc(user_id, project_id)
472
except (exception.UserNotFound, exception.ProjectNotFound) as ex:
478
with open(filename, 'w') as f:
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):
487
@args('--project', dest="project_id", metavar='<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()
527
252
for group in groups:
528
253
db.security_group_destroy(admin_context, group['id'])
530
@args('--project', dest="project_id", metavar='<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"""
538
zip_file = self.manager.get_credentials(user_id, project_id)
540
sys.stdout.write(zip_file)
542
with open(filename, 'w') as f:
544
except (exception.UserNotFound, exception.ProjectNotFound) as ex:
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:
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.")
557
256
AccountCommands = ProjectCommands
577
276
instances = db.instance_get_all(context.get_admin_context())
277
instances_by_uuid = {}
579
278
for instance in instances:
580
instances_by_id[instance['id']] = instance
279
instances_by_uuid[instance['uuid']] = instance
582
281
print "%-18s\t%-15s\t%-15s\t%s" % (_('network'),
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.')
586
300
for fixed_ip in fixed_ips:
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'])
595
hostname = instance['hostname']
596
host = instance['host']
598
print ('WARNING: fixed ip %s allocated to missing'
599
' instance' % str(fixed_ip['address']))
600
print "%-18s\t%-15s\t%-15s\t%s" % (
304
network = all_networks.get(fixed_ip['network_id'])
307
if fixed_ip.get('instance_uuid'):
308
instance = instances_by_uuid.get(fixed_ip['instance_uuid'])
310
hostname = instance['hostname']
311
host = instance['host']
313
print _('WARNING: fixed ip %s allocated to missing'
314
' instance') % str(fixed_ip['address'])
315
print "%-18s\t%-15s\t%-15s\t%s" % (
321
print _('No fixed IP found.')
605
323
@args('--address', dest="address", metavar='<ip address>',
606
324
help='IP address')
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),
664
'interface': interface})
385
ips = ({'address': str(address), 'pool': pool, 'interface': interface}
386
for address in self.address_to_hosts(ip_range))
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
393
print('error: %s' % exc)
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(),
401
db.floating_ip_destroy(context.get_admin_context(),
403
except exception.FloatingIpNotFoundForAddress as ex:
404
print "Warning: %s" % ex
673
406
@args('--host', dest="host", metavar='<host>', help='Host')
674
407
def list(self, host=None):
1257
978
self._print_instance_types(name, inst_types)
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"""
990
inst_type = instance_types.get_instance_type_by_name(name)
991
except exception.InstanceTypeNotFoundByName, e:
995
ctxt = context.get_admin_context()
996
ext_spec = {key: value}
997
db.instance_type_extra_specs_update_or_create(
999
inst_type["flavorid"],
1001
print _("Key %(key)s set to %(value)s on instance"
1002
" type %(name)s") % locals()
1003
except exception.DBError, e:
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"""
1014
inst_type = instance_types.get_instance_type_by_name(name)
1015
except exception.InstanceTypeNotFoundByName, e:
1019
ctxt = context.get_admin_context()
1020
db.instance_type_extra_specs_delete(
1022
inst_type["flavorid"],
1025
print _("Key %(key)s on instance type %(name)s unset") % locals()
1026
except exception.DBError, e:
1260
1030
class StorageManagerCommands(object):
1261
1031
"""Class for mangaging Storage Backends and Flavors"""
1531
1301
print "No nova entries in syslog!"
1534
class ExportCommands(object):
1535
"""Commands used to export data from Nova"""
1538
"""Export Nova auth data in format that can be consumed by Keystone"""
1539
print jsonutils.dumps(self._get_auth_data())
1541
def _get_auth_data(self):
1545
'user_tenant_list': [],
1546
'ec2_credentials': [],
1548
'role_user_tenant_list': [],
1551
am = manager.AuthManager()
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
1566
output['users'].append(user_dict)
1570
'access_key': access,
1571
'secret_key': user.secret,
1573
output['ec2_credentials'].append(ec2_cred)
1575
for project in am.get_projects():
1578
'name': project.name,
1579
'description': project.description,
1581
output['tenants'].append(tenant)
1583
for user_id in project.member_ids:
1585
'tenant_id': project.id,
1588
output['user_tenant_list'].append(membership)
1590
for role in am.get_roles():
1591
if role not in output['roles']:
1592
output['roles'].append(role)
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):
1601
'tenant_id': project.id,
1603
output['role_user_tenant_list'].append(role_grant)
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),