Add possibility to reserve IP address for specific nodes

- In the YAML template section 'address_pools', IP address for
  a specific node can be specified in the 'ip_reserved' field:
  <group_name>_<node_name>: <ip_address>

  For example:

    address_pools:
      public-pool01:
        net: 172.16.10.0/24:24
        params:
          ip_reserved:
            gateway: +1
            l2_network_device: +1
            default_cfg01.mk22-lab-advanced.local: 172.16.10.100
            default_ctl01.mk22-lab-advanced.local: +101
            default_ctl02.mk22-lab-advanced.local: +102
            default_ctl03.mk22-lab-advanced.local: +103
          ip_ranges:
            dhcp: [+100, -2]

- Erase the failed environment in case of creation failure, to not
  leave inconsistent objects on host and in database.

Change-Id: Ic53f1f69d718998448b6f26fe46b4e8130addbb1
This commit is contained in:
Dennis Dmitriev 2016-10-26 19:35:08 +03:00
parent a844c12294
commit 05f7650ef3
3 changed files with 55 additions and 29 deletions

View File

@ -302,37 +302,43 @@ class Environment(base.BaseModel):
config = full_config['template']['devops_settings']
environment = cls.create(config['env_name'])
# create groups and drivers
groups = config['groups']
environment.add_groups(groups)
try:
# create groups and drivers
groups = config['groups']
environment.add_groups(groups)
# create address pools
address_pools = config['address_pools']
environment.add_address_pools(address_pools)
# create address pools
address_pools = config['address_pools']
environment.add_address_pools(address_pools)
# process group items
for group_data in groups:
group = environment.get_group(name=group_data['name'])
# process group items
for group_data in groups:
group = environment.get_group(name=group_data['name'])
# add l2_network_devices
group.add_l2_network_devices(
group_data.get('l2_network_devices', {}))
# add l2_network_devices
group.add_l2_network_devices(
group_data.get('l2_network_devices', {}))
# add network_pools
group.add_network_pools(
group_data.get('network_pools', {}))
# add network_pools
group.add_network_pools(
group_data.get('network_pools', {}))
# Connect nodes to already created networks
for group_data in groups:
group = environment.get_group(name=group_data['name'])
# Connect nodes to already created networks
for group_data in groups:
group = environment.get_group(name=group_data['name'])
# add group volumes
group.add_volumes(
group_data.get('group_volumes', []))
# add group volumes
group.add_volumes(
group_data.get('group_volumes', []))
# add nodes
group.add_nodes(
group_data.get('nodes', []))
# add nodes
group.add_nodes(
group_data.get('nodes', []))
except Exception:
logger.error("Creation of the environment '{0}' failed"
.format(config['env_name']))
environment.erase()
raise
return environment

View File

@ -39,7 +39,10 @@ class AddressPool(base.ParamedModel, base.BaseModel):
ip_reserved:
<'gateway'>:<int|IPAddress> # Reserved for gateway.
<'l2_network_device'>:<int|IPAddress> # Reserved for local IP
# for libvirt networks.
# for libvirt networks.
<'groupname_nodename'>:<int|IPAddress> # Reserved for specific node
# IP address for iface in
# this address pool.
... # user-defined IPs (for fuel-qa)
ip_ranges:
<group_name>: [<int|IPAddress>, <int|IPAddress>]
@ -531,7 +534,18 @@ class Interface(base.ParamedModel):
self.delete()
def add_address(self):
ip = self.l2_network_device.address_pool.next_ip()
"""Assign an IP address to the interface
Try to get an IP from reserved IP with name '<group>_<node>'
, or generate next IP if reserved IP wasn't found.
Next IP is generated from the DHCP ip_range, or from the
network range [+2:-2] of all available addresses in the address pool.
"""
reserved_ip_name = helpers.underscored(self.node.group.name,
self.node.name)
reserved_ip = self.l2_network_device.address_pool.get_ip(
reserved_ip_name)
ip = reserved_ip or self.l2_network_device.address_pool.next_ip()
Address.objects.create(
ip_address=str(ip),
interface=self,

View File

@ -28,8 +28,10 @@ class TestManager(TestCase):
def test_network_iterator(self):
environment = models.Environment.create('test_env')
group = environment.add_group(group_name='test-group',
driver_name='devops.driver.empty')
node = models.Node.objects.create(
group=None,
group=group,
name='test_node',
role='default',
)
@ -51,8 +53,10 @@ class TestManager(TestCase):
def test_network_model(self):
environment = models.Environment.create('test_env')
group = environment.add_group(group_name='test-group',
driver_name='devops.driver.empty')
node = models.Node.objects.create(
group=None,
group=group,
name='test_node',
role='default',
)
@ -116,6 +120,8 @@ class TestManager(TestCase):
def test_node_creation(self):
environment = models.Environment.create('test_env3')
group = environment.add_group(group_name='test-group',
driver_name='devops.driver.empty')
pool = network.IpNetworksPool(
networks=[netaddr.IPNetwork('10.1.0.0/24')], prefix=24)
address_pool = models.AddressPool.address_pool_create(
@ -124,7 +130,7 @@ class TestManager(TestCase):
group=None, address_pool=address_pool, name='test_l2_dev')
node = models.Node.objects.create(
group=None,
group=group,
name='test_node',
role='default',
)