|
|
@@ -2,6 +2,7 @@
|
|
|
Services implemented by the OpenStack provider.
|
|
|
"""
|
|
|
import fnmatch
|
|
|
+import logging
|
|
|
import re
|
|
|
|
|
|
from cinderclient.exceptions import NotFound as CinderNotFound
|
|
|
@@ -25,6 +26,7 @@ from cloudbridge.cloud.base.services import BaseVolumeService
|
|
|
from cloudbridge.cloud.interfaces.resources import InstanceType
|
|
|
from cloudbridge.cloud.interfaces.resources import KeyPair
|
|
|
from cloudbridge.cloud.interfaces.resources import MachineImage
|
|
|
+from cloudbridge.cloud.interfaces.resources import Network
|
|
|
from cloudbridge.cloud.interfaces.resources import PlacementZone
|
|
|
from cloudbridge.cloud.interfaces.resources import SecurityGroup
|
|
|
from cloudbridge.cloud.interfaces.resources import Snapshot
|
|
|
@@ -47,6 +49,8 @@ from .resources import OpenStackSnapshot
|
|
|
from .resources import OpenStackSubnet
|
|
|
from .resources import OpenStackVolume
|
|
|
|
|
|
+log = logging.getLogger(__name__)
|
|
|
+
|
|
|
|
|
|
class OpenStackSecurityService(BaseSecurityService):
|
|
|
|
|
|
@@ -564,6 +568,7 @@ class OpenStackInstanceService(BaseInstanceService):
|
|
|
isinstance(instance_type, InstanceType) else \
|
|
|
self.provider.compute.instance_types.find(
|
|
|
name=instance_type)[0].id
|
|
|
+ network_id = network.id if isinstance(network, Network) else network
|
|
|
zone_id = zone.id if isinstance(zone, PlacementZone) else zone
|
|
|
key_pair_name = key_pair.name if \
|
|
|
isinstance(key_pair, KeyPair) else key_pair
|
|
|
@@ -575,11 +580,10 @@ class OpenStackInstanceService(BaseInstanceService):
|
|
|
security_groups_list = security_groups
|
|
|
else:
|
|
|
security_groups_list = None
|
|
|
+ bdm = None
|
|
|
if launch_config:
|
|
|
bdm = self._to_block_device_mapping(launch_config)
|
|
|
- nics = self._format_nics(launch_config)
|
|
|
- else:
|
|
|
- bdm = nics = None
|
|
|
+ net = self._get_network(network_id)
|
|
|
|
|
|
os_instance = self.provider.nova.servers.create(
|
|
|
name,
|
|
|
@@ -592,7 +596,7 @@ class OpenStackInstanceService(BaseInstanceService):
|
|
|
security_groups=security_groups_list,
|
|
|
userdata=user_data,
|
|
|
block_device_mapping_v2=bdm,
|
|
|
- nics=nics)
|
|
|
+ nics=net)
|
|
|
return OpenStackInstance(self.provider, os_instance)
|
|
|
|
|
|
def _to_block_device_mapping(self, launch_config):
|
|
|
@@ -645,14 +649,42 @@ class OpenStackInstanceService(BaseInstanceService):
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
- def _format_nics(self, launch_config):
|
|
|
+ def _get_network(self, network_id=None):
|
|
|
"""
|
|
|
- Format network IDs for the API call.
|
|
|
+ Format the network ID for the API call, figuring out a default network.
|
|
|
+
|
|
|
+ If a network_id is not supplied, figure out which is the default
|
|
|
+ network and use it. A default network is either marked as such by the
|
|
|
+ provider or matches the default network name defined within this
|
|
|
+ library (by default CloudBridgeNet). If a default network cannot be
|
|
|
+ found, attempt to create a new one.
|
|
|
"""
|
|
|
- nics = []
|
|
|
- for net_id in launch_config.network_interfaces:
|
|
|
- nics.append({'net-id': net_id})
|
|
|
- return nics
|
|
|
+ if network_id:
|
|
|
+ return [{'net-id': network_id}]
|
|
|
+ for net in self.provider.network.list():
|
|
|
+ if net.name == OpenStackNetwork.CB_DEFAULT_NETWORK_NAME:
|
|
|
+ return [{'net-id': net.id}]
|
|
|
+ try:
|
|
|
+ # Try to create a complete, Internet-connected new network
|
|
|
+ net = self.provider.network.create(
|
|
|
+ name=OpenStackNetwork.CB_DEFAULT_NETWORK_NAME)
|
|
|
+ sn = net.create_subnet('10.0.0.0/16', '{0}Subnet'.format(
|
|
|
+ OpenStackNetwork.CB_DEFAULT_NETWORK_NAME))
|
|
|
+ router = self.provider.network.create_router('{0}Router'.format(
|
|
|
+ OpenStackNetwork.CB_DEFAULT_NETWORK_NAME))
|
|
|
+ for n in self.provider.network.list():
|
|
|
+ if n.external:
|
|
|
+ external_net = n
|
|
|
+ break
|
|
|
+ router.attach_network(external_net.id)
|
|
|
+ router.add_route(sn.id)
|
|
|
+ return [{'net-id': net.id}]
|
|
|
+ except Exception as exc:
|
|
|
+ # At this point we assume the provider does support user-defined
|
|
|
+ # networks so return None
|
|
|
+ log.warn("Exception occurred trying to create a default "
|
|
|
+ "CloudBridge network: {0}".format(exc))
|
|
|
+ return None
|
|
|
|
|
|
def create_launch_config(self):
|
|
|
return BaseLaunchConfig(self.provider)
|