Add support for network labels
This patch adds the ability to specify a net-label instead of using a net-id (network UUID). Rather than use network UUID's in our nodepool.yaml config files it would be nice to use the more meaningful network labels instead. This should make the config file more readable across the various cloud providers and matches how we use image names (instead of image UUIDs) as well. The current implementation relies on the os-tenant-networks extension in Nova to provide the network label lookup. Given that nodepool is currently focused around using novaclient this made the most sense. We may at some point in the future want to use the Neutron API directly for this information or perhaps use a combination of both approaches to accommodate a variety of provider API deployment choices. Tested locally on my TripleO overcloud using two Neutron networks. Change-Id: I9bdd35adf2d85659cf1b992ccd2fcf98fb124528
This commit is contained in:
parent
fc335e41be
commit
e471cea178
@ -153,6 +153,9 @@ same name. Example::
|
||||
boot-timeout: 120
|
||||
launch-timeout: 900
|
||||
template-hostname: '{image.name}-{timestamp}.template.openstack.org'
|
||||
networks:
|
||||
- net-id: 'some-uuid'
|
||||
- net-label: 'some-network-name'
|
||||
images:
|
||||
- name: precise
|
||||
base-image: 'Precise'
|
||||
@ -199,6 +202,13 @@ Both `boot-timeout` and `launch-timeout` keys are optional. The
|
||||
`boot-timeout` key defaults to 60 seconds and `launch-timeout` key
|
||||
will default to 3600 seconds.
|
||||
|
||||
The optional `networks` section may be used to specify custom
|
||||
Neutron networks that get attached to each node. You can specify
|
||||
Neutron networks using either the `net-id` or `net-label`. If
|
||||
only the `net-label` is specified the network UUID is automatically
|
||||
queried via the Nova os-tenant-networks API extension (this requires
|
||||
that the cloud provider has deployed this extension).
|
||||
|
||||
The `availability-zones` key is optional. Without it nodepool will rely
|
||||
on nova to schedule an availability zone. If it is provided the value
|
||||
should be a list of availability zone names. Nodepool will select one
|
||||
|
@ -1014,7 +1014,7 @@ class NodePool(threading.Thread):
|
||||
p.boot_timeout = provider.get('boot-timeout', 60)
|
||||
p.launch_timeout = provider.get('launch-timeout', 3600)
|
||||
p.use_neutron = bool(provider.get('networks', ()))
|
||||
p.nics = provider.get('networks')
|
||||
p.networks = provider.get('networks')
|
||||
p.azs = provider.get('availability-zones')
|
||||
p.template_hostname = provider.get(
|
||||
'template-hostname',
|
||||
@ -1084,7 +1084,7 @@ class NodePool(threading.Thread):
|
||||
new_pm.boot_timeout != old_pm.provider.boot_timeout or
|
||||
new_pm.launch_timeout != old_pm.provider.launch_timeout or
|
||||
new_pm.use_neutron != old_pm.provider.use_neutron or
|
||||
new_pm.nics != old_pm.provider.nics or
|
||||
new_pm.networks != old_pm.provider.networks or
|
||||
new_pm.azs != old_pm.provider.azs):
|
||||
return False
|
||||
new_images = new_pm.images
|
||||
|
@ -20,6 +20,8 @@ import logging
|
||||
import paramiko
|
||||
import novaclient
|
||||
import novaclient.client
|
||||
import novaclient.extension
|
||||
import novaclient.v1_1.contrib.tenant_networks
|
||||
import threading
|
||||
import time
|
||||
|
||||
@ -219,6 +221,12 @@ class DeleteImageTask(Task):
|
||||
client.images.delete(**self.args)
|
||||
|
||||
|
||||
class FindNetworkTask(Task):
|
||||
def main(self, client):
|
||||
network = client.tenant_networks.find(**self.args)
|
||||
return dict(id=str(network.id))
|
||||
|
||||
|
||||
class ProviderManager(TaskManager):
|
||||
log = logging.getLogger("nodepool.ProviderManager")
|
||||
|
||||
@ -228,6 +236,7 @@ class ProviderManager(TaskManager):
|
||||
self.provider = provider
|
||||
self._client = self._getClient()
|
||||
self._images = {}
|
||||
self._networks = {}
|
||||
self._cloud_metadata_read = False
|
||||
self.__flavors = {}
|
||||
self.__extensions = {}
|
||||
@ -253,9 +262,11 @@ class ProviderManager(TaskManager):
|
||||
self._cloud_metadata_read = True
|
||||
|
||||
def _getClient(self):
|
||||
tenant_networks = novaclient.extension.Extension(
|
||||
'tenant_networks', novaclient.v1_1.contrib.tenant_networks)
|
||||
args = ['1.1', self.provider.username, self.provider.password,
|
||||
self.provider.project_id, self.provider.auth_url]
|
||||
kwargs = {}
|
||||
kwargs = {'extensions': [tenant_networks]}
|
||||
if self.provider.service_type:
|
||||
kwargs['service_type'] = self.provider.service_type
|
||||
if self.provider.service_name:
|
||||
@ -295,6 +306,13 @@ class ProviderManager(TaskManager):
|
||||
self._images[name] = image
|
||||
return image
|
||||
|
||||
def findNetwork(self, label):
|
||||
if label in self._networks:
|
||||
return self._networks[label]
|
||||
network = self.submitTask(FindNetworkTask(label=label))
|
||||
self._networks[label] = network
|
||||
return network
|
||||
|
||||
def deleteImage(self, name):
|
||||
if name in self._images:
|
||||
del self._images[name]
|
||||
@ -323,7 +341,16 @@ class ProviderManager(TaskManager):
|
||||
if az:
|
||||
create_args['availability_zone'] = az
|
||||
if self.provider.use_neutron:
|
||||
create_args['nics'] = self.provider.nics
|
||||
nics = []
|
||||
for network in self.provider.networks:
|
||||
if 'net-id' in network:
|
||||
nics.append({'net-id': network['net-id']})
|
||||
elif 'net-label' in network:
|
||||
net_id = self.findNetwork(network['net-label'])['id']
|
||||
nics.append({'net-id': net_id})
|
||||
else:
|
||||
raise Exception("Invalid 'networks' configuration.")
|
||||
create_args['nics'] = nics
|
||||
|
||||
return self.submitTask(CreateServerTask(**create_args))
|
||||
|
||||
|
@ -37,6 +37,7 @@ providers:
|
||||
pool: 'fake'
|
||||
networks:
|
||||
- net-id: 'some-uuid'
|
||||
- net-label: 'some-label'
|
||||
images:
|
||||
- name: nodepool-fake
|
||||
base-image: 'Fake Precise'
|
||||
|
Loading…
x
Reference in New Issue
Block a user