Last active
August 29, 2015 14:06
-
-
Save ianunruh/97be36c47110a78432a5 to your computer and use it in GitHub Desktop.
Onboard tenants to OpenStack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from argparse import ArgumentParser, RawTextHelpFormatter | |
import os | |
import sys | |
import keystoneclient.v2_0 | |
import neutronclient.v2_0.client | |
NEUTRON_ROUTER_FORMAT = '{}-router' | |
NEUTRON_NETWORK_FORMAT = '{}-network' | |
def find_or_create_tenant(keystone, name): | |
for tenant in keystone.tenants.list(): | |
if tenant.name == name: | |
return tenant | |
return keystone.tenants.create(name) | |
def find_role(keystone, name): | |
for role in keystone.roles.list(): | |
if role.name == name: | |
return role | |
raise RuntimeError('Could not find role') | |
def find_or_create_user(keystone, username, password): | |
for user in keystone.users.list(): | |
if user.name == username: | |
return user | |
return keystone.users.create(username, password) | |
def grant_role(keystone, user, role, tenant): | |
for r in keystone.roles.roles_for_user(user, tenant): | |
if r == role: | |
return | |
keystone.roles.add_user_role(user, role, tenant) | |
def find_external_network(neutron, name): | |
response = neutron.list_networks() | |
for network in response['networks']: | |
if name: | |
if network['name'] == name: | |
if not network['router:external']: | |
raise ValueError('Network is not an external network') | |
return network['id'] | |
elif network['router:external']: | |
return network['id'] | |
raise RuntimeError('Could not find suitable external network') | |
def find_or_create_router(neutron, name, external_network_id): | |
response = neutron.list_routers() | |
for router in response['routers']: | |
if router['name'] == name: | |
return router['id'] | |
request = { | |
'router': { | |
'name': name, | |
'external_gateway_info': { | |
'network_id': external_network_id | |
} | |
} | |
} | |
response = neutron.create_router(request) | |
return response['router']['id'] | |
def find_or_create_network(neutron, name): | |
response = neutron.list_networks() | |
for network in response['networks']: | |
if network['name'] == name: | |
return network['id'] | |
request = { | |
'network': { | |
'name': name | |
} | |
} | |
response = neutron.create_network(request) | |
return response['network']['id'] | |
def ensure_subnet(neutron, network_id, cidr, router_id): | |
response = neutron.list_subnets() | |
for subnet in response['subnets']: | |
if subnet['cidr'] == cidr: | |
return | |
request = { | |
'subnet': { | |
'network_id': network_id, | |
'ip_version': 4, | |
'cidr': cidr | |
} | |
} | |
response = neutron.create_subnet(request) | |
request = { | |
'subnet_id': response['subnet']['id'] | |
} | |
neutron.add_interface_router(router_id, request) | |
def main(): | |
parser = ArgumentParser( | |
usage='%(prog)s tenant', | |
formatter_class=RawTextHelpFormatter | |
) | |
parser.add_argument('tenant', help='Name of the tenant to create') | |
parser.add_argument('--role', default='Member', help='Role of the user being created') | |
parser.add_argument('--username', help='Username of the user being created') | |
parser.add_argument('--password', help='Password of the user being created') | |
parser.add_argument('--external-network', help='Name of the external network used as the router gateway') | |
parser.add_argument('--cidr', default='192.168.20.0/24', help='CIDR of the subnet being created') | |
parser.add_argument('--skip-network', action='store_true', help='Skip creating the network and subnet') | |
parser.add_argument('--os-auth-url', default=os.getenv('OS_AUTH_URL')) | |
parser.add_argument('--os-username', default=os.getenv('OS_USERNAME')) | |
parser.add_argument('--os-password', default=os.getenv('OS_PASSWORD')) | |
parser.add_argument('--os-tenant-name', default=os.getenv('OS_TENANT_NAME')) | |
args = parser.parse_args() | |
valid = True | |
if not args.os_auth_url: | |
print 'Keystone auth URL required (use --os-auth-url or the OS_AUTH_URL environment variable)' | |
valid = False | |
if not args.os_username: | |
print 'Keystone username required (use --os-username or the OS_USERNAME environment variable)' | |
valid = False | |
if not args.os_password: | |
print 'Keystone password required (use --os-password or the OS_PASSWORD environment variable)' | |
valid = False | |
if not args.os_tenant_name: | |
print 'Keystone tenant name required (use --os-tenant-name or the OS_TENANT_NAME environment variable)' | |
valid = False | |
if not valid: | |
print 'If you have an openrc file available, be sure that you sourced it' | |
return False | |
if not args.username: | |
args.username = args.tenant | |
if not args.password: | |
args.password = args.username | |
# Prepare the tenant and user | |
keystone = keystoneclient.v2_0.client.Client( | |
auth_url=args.os_auth_url, | |
tenant_name=args.os_tenant_name, | |
username=args.os_username, | |
password=args.os_password, | |
timeout=5, | |
) | |
# Create the tenant and user | |
tenant = find_or_create_tenant(keystone, args.tenant) | |
role = find_role(keystone, args.role) | |
user = find_or_create_user(keystone, args.username, args.password) | |
grant_role(keystone, user, role, tenant) | |
# Connect to the Neutron API | |
neutron = neutronclient.v2_0.client.Client( | |
auth_url=args.os_auth_url, | |
tenant_name=args.tenant, | |
username=args.username, | |
password=args.password, | |
timeout=15, | |
) | |
# Create the router | |
external_network_id = find_external_network(neutron, args.external_network) | |
router_name = NEUTRON_ROUTER_FORMAT.format(tenant.name) | |
router_id = find_or_create_router(neutron, router_name, external_network_id) | |
if args.skip_network: | |
return True | |
# Create the network and subnet | |
network_name = NEUTRON_NETWORK_FORMAT.format(tenant.name) | |
network_id = find_or_create_network(neutron, network_name) | |
ensure_subnet(neutron, network_id, args.cidr, router_id) | |
return True | |
if __name__ == '__main__': | |
if not main(): | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment