Merge pick up, tweaked role/site/plcore_base or os_manager path when OpenStack not present
diff --git a/planetstack/openstack/driver.py b/planetstack/openstack/driver.py
index 6b04b5d..eba424a 100644
--- a/planetstack/openstack/driver.py
+++ b/planetstack/openstack/driver.py
@@ -1,3 +1,4 @@
+import commands
from planetstack.config import Config
from openstack.client import OpenStackClient
@@ -206,7 +207,7 @@
'dns_nameservers': ['8.8.8.8', '8.8.4.4'],
'allocation_pools': allocation_pools}}
subnet = self.shell.quantum.create_subnet(subnet)['subnet']
-
+ self.add_external_route(subnet)
# TODO: Add route to external network
# e.g. # route add -net 10.0.3.0/24 dev br-ex gw 10.100.0.5
return subnet
@@ -222,7 +223,64 @@
if subnet['id'] == id:
self.delete_subnet_ports(subnet['id'])
self.shell.quantum.delete_subnet(id)
- return
+ self.delete_external_route(subnet)
+ return 1
+
+ def add_external_route(self, subnet):
+ ports = self.shell.quantum.list_ports()['ports']
+
+ gw_ip = subnet['gateway_ip']
+ subnet_id = subnet['id']
+
+ # 1. Find the port associated with the subnet's gateway
+ # 2. Find the router associated with that port
+ # 3. Find the port associated with this router and on the external net
+ # 4. Set up route to the subnet through the port from step 3
+ ip_address = None
+ for port in ports:
+ for fixed_ip in port['fixed_ips']:
+ if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
+ gw_port = port
+ router_id = gw_port['device_id']
+ router = self.shell.quantum.show_router(router_id)['router']
+ ext_net = router['external_gateway_info']['network_id']
+ for port in ports:
+ if port['device_id'] == router_id and port['network_id'] == ext_net:
+ ip_address = port['fixed_ips'][0]['ip_address']
+
+ if ip_address:
+ cmd = "route add -net %s dev br-ex gw %s" % (subnet['cidr'], ip_address)
+ commands.getstatusoutput(cmd)
+
+ return 1
+
+ def delete_external_route(self, subnet):
+ ports = self.shell.quantum.list_ports()['ports']
+
+ gw_ip = subnet['gateway_ip']
+ subnet_id = subnet['id']
+
+ # 1. Find the port associated with the subnet's gateway
+ # 2. Find the router associated with that port
+ # 3. Find the port associated with this router and on the external net
+ # 4. Set up route to the subnet through the port from step 3
+ ip_address = None
+ for port in ports:
+ for fixed_ip in port['fixed_ips']:
+ if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
+ gw_port = port
+ router_id = gw_port['device_id']
+ router = self.shell.quantum.show_router(router_id)['router']
+ ext_net = router['external_gateway_info']['network_id']
+ for port in ports:
+ if port['device_id'] == router_id and port['network_id'] == ext_net:
+ ip_address = port['fixed_ips'][0]['ip_address']
+
+ if ip_address:
+ cmd = "route delete -net %s" % (subnet['cidr'])
+ commands.getstatusoutput(cmd)
+
+ return 1
def create_keypair(self, name, key):
keys = self.shell.nova.keypairs.findall(name=name)
diff --git a/planetstack/openstack/manager.py b/planetstack/openstack/manager.py
index 788a621..166ad19 100644
--- a/planetstack/openstack/manager.py
+++ b/planetstack/openstack/manager.py
@@ -1,13 +1,10 @@
+from netaddr import IPAddress, IPNetwork
from planetstack import settings
-#from django.core import management
-#management.setup_environ(settings)
-import os
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
-
+from django.core import management
+from planetstack.config import Config
try:
from openstack.client import OpenStackClient
from openstack.driver import OpenStackDriver
- from planetstack.config import Config
from core.models import *
has_openstack = True
except:
@@ -28,17 +25,39 @@
class OpenStackManager:
def __init__(self, auth={}, caller=None):
- if auth:
- self.client = OpenStackClient(**auth)
- else:
- self.client = OpenStackClient()
+ self.client = None
+ self.driver = None
+ self.caller = None
self.has_openstack = has_openstack
- self.enabled = manager_enabled
- self.driver = OpenStackDriver(client=self.client)
- self.caller=caller
- if not self.caller:
- self.caller = self.driver.admin_user
- self.caller.kuser_id = self.caller.id
+ self.enabled = manager_enabled
+
+ if has_openstack and manager_enabled:
+ if auth:
+ try:
+ self.init_user(auth, caller)
+ except:
+ # if this fails then it meanse the caller doesn't have a
+ # role at the slice's tenant. if the caller is an admin
+ # just use the admin client/manager.
+ if caller and caller.is_admin:
+ self.init_admin()
+ else: raise
+ else:
+ self.init_admin()
+
+ @require_enabled
+ def init_user(self, auth, caller):
+ self.client = OpenStackClient(**auth)
+ self.driver = OpenStackDriver(client=self.client)
+ self.caller = caller
+
+ @require_enabled
+ def init_admin(self):
+ # use the admin credentials
+ self.client = OpenStackClient()
+ self.driver = OpenStackDriver(client=self.client)
+ self.caller = self.driver.admin_user
+ self.caller.kuser_id = self.caller.id
@require_enabled
def save_role(self, role):
@@ -54,7 +73,7 @@
@require_enabled
def save_key(self, key):
if not key.key_id:
- key_fields = {'name': key.name,
+ key_fields = {'name': key.user.email[:key.user.email.find('@')],
'key': key.key}
nova_key = self.driver.create_keypair(**key_fields)
key.key_id = nova_key.id
@@ -74,14 +93,19 @@
'enabled': True}
keystone_user = self.driver.create_user(**user_fields)
user.kuser_id = keystone_user.id
-
+ if user.site:
+ self.driver.add_user_role(user.kuser_id, user.site.tenant_id, 'user')
+ if user.is_admin:
+ self.driver.add_user_role(user.kuser_id, user.site.tenant_id, 'admin')
+ else:
+ # may have admin role so attempt to remove it
+ self.driver.delete_user_role(user.kuser_id, user.site.tenant_id, 'admin')
+
@require_enabled
def delete_user(self, user):
if user.kuser_id:
self.driver.delete_user(user.kuser_id)
-
-
@require_enabled
def save_site(self, site, add_role=True):
if not site.tenant_id:
@@ -128,6 +152,23 @@
router = self.driver.create_router(slice.name)
slice.router_id = router['id']
+ # create subnet
+ next_subnet = self.get_next_subnet()
+ cidr = str(next_subnet.cidr)
+ ip_version = next_subnet.version
+ start = str(next_subnet[2])
+ end = str(next_subnet[-2])
+ subnet = self.driver.create_subnet(name=slice.name,
+ network_id = network['id'],
+ cidr_ip = cidr,
+ ip_version = ip_version,
+ start = start,
+ end = end)
+ slice.subnet_id = subnet['id']
+ # add subnet as interface to slice's router
+ self.driver.add_router_interface(router['id'], subnet['id'])
+
+
if slice.id and slice.tenant_id:
self.driver.update_tenant(slice.tenant_id,
description=slice.description,
@@ -136,10 +177,26 @@
@require_enabled
def delete_slice(self, slice):
if slice.tenant_id:
+ self.driver.delete_router_interface(slice.router_id, slice.subnet_id)
+ self.driver.delete_subnet(slice.subnet_id)
self.driver.delete_router(slice.router_id)
self.driver.delete_network(slice.network_id)
self.driver.delete_tenant(slice.tenant_id)
+
+
+ def get_next_subnet(self):
+ # limit ourself to 10.0.x.x for now
+ valid_subnet = lambda net: net.startswith('10.0')
+ subnets = self.driver.shell.quantum.list_subnets()['subnets']
+ ints = [int(IPNetwork(subnet['cidr']).ip) for subnet in subnets \
+ if valid_subnet(subnet['cidr'])]
+ ints.sort()
+ last_ip = IPAddress(ints[-1])
+ last_network = IPNetwork(str(last_ip) + "/24")
+ next_network = IPNetwork(str(IPAddress(last_network) + last_network.size) + "/24")
+ return next_network
+
@require_enabled
def save_subnet(self, subnet):
if not subnet.subnet_id:
@@ -163,7 +220,7 @@
self.driver.delete_subnet(subnet.subnet_id)
#del_route = 'route del -net %s' % self.cidr
#commands.getstatusoutput(del_route)
-
+
@require_enabled
def save_sliver(self, sliver):
if not sliver.instance_id:
@@ -174,6 +231,9 @@
sliver.instance_id = instance.id
sliver.instance_name = getattr(instance, 'OS-EXT-SRV-ATTR:instance_name')
+ if sliver.instance_id and ("numberCores" in sliver.changed_fields):
+ self.driver.update_instance_metadata(sliver.instance_id, {"cpu_cores": str(sliver.numberCores)})
+
@require_enabled
def delete_sliver(self, sliver):
if sliver.instance_id: