DHCP server IP address collision with VM's IP
When a stack is imported in Heat, the DHCP server IP is set to the lowest free IP address of it's pool. Depending on the VM creation order, the DHCP address can either collide with vm1's or vm2's IP. with the alter-allocation-pools flag the exported allocation pools starts at the DHCP's IP address. Change-Id: I8a4815e6c8b2bafa539cf3ad8384be76ef075edc
This commit is contained in:
parent
5d7271dd98
commit
532745e610
|
@ -36,7 +36,7 @@ Usage
|
|||
[--project PROJECT] [--region REGION] [--auth_url AUTH_URL]
|
||||
[--insecure] [--endpoint_type ENDPOINT_TYPE] [--exclude-servers]
|
||||
[--exclude-volumes] [--exclude-keypairs] [--generate-stack-data]
|
||||
[--extract-ports]
|
||||
[--extract-ports] [--alter-allocation-pools]
|
||||
|
||||
Heat template and data file generator
|
||||
|
||||
|
@ -63,6 +63,9 @@ Usage
|
|||
In addition to template, generate Heat stack data
|
||||
file.
|
||||
--extract-ports Export the tenant network ports
|
||||
--alter-allocation-pools
|
||||
Have the DHCP allocation pools start at the DHCP's IP
|
||||
address for the current subnet.
|
||||
|
||||
|
||||
Usage example
|
||||
|
|
|
@ -15,4 +15,6 @@ When this stack is imported in Heat, the DHCP server IP is set to the lowest
|
|||
free IP address of it's pool. Depending on the VM creation order, the DHCP
|
||||
address can either collide with vm1's or vm2's IP.
|
||||
|
||||
Flame comes with an --alter-allocation-pools options that makes the allocation
|
||||
pool of a subnet start at the original DHCP's IP address.
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ To use the CLI of flame::
|
|||
[--project PROJECT] [--region REGION] [--auth_url AUTH_URL]
|
||||
[--insecure] [--endpoint_type ENDPOINT_TYPE] [--exclude-servers]
|
||||
[--exclude-volumes] [--exclude-keypairs] [--generate-stack-data]
|
||||
[--extract-ports]
|
||||
[--extract-ports] [--alter-allocation-pools]
|
||||
|
||||
Heat template and data file generator
|
||||
|
||||
|
@ -37,6 +37,9 @@ To use the CLI of flame::
|
|||
In addition to template, generate Heat stack data
|
||||
file.
|
||||
--extract-ports Export the tenant network ports
|
||||
--alter-allocation-pools
|
||||
Have the DHCP allocation pools start at the DHCP's IP
|
||||
address for the current subnet.
|
||||
|
||||
|
||||
Example
|
||||
|
|
|
@ -75,8 +75,16 @@ def main(args=None):
|
|||
parser.add_argument('--extract-ports', action='store_true',
|
||||
default=False,
|
||||
help="Export the tenant network ports")
|
||||
parser.add_argument('--alter-allocation-pools', action='store_true',
|
||||
default=False,
|
||||
help="Have the DHCP allocation pools start at the "
|
||||
"DHCP's IP address for the current subnet.")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.alter_allocation_pools and not args.extract_ports:
|
||||
raise argparse.ArgumentError(None,
|
||||
"Must use --extract-ports with "
|
||||
"--alter-allocation-pools.")
|
||||
flame = client.Client(args.username, args.password,
|
||||
args.project, args.auth_url,
|
||||
args.os_auth_token,
|
||||
|
@ -88,7 +96,8 @@ def main(args=None):
|
|||
args.exclude_volumes,
|
||||
args.exclude_keypairs,
|
||||
args.generate_stack_data,
|
||||
args.extract_ports)
|
||||
args.extract_ports,
|
||||
args.alter_allocation_pools)
|
||||
template.extract_data()
|
||||
print("### Heat Template ###")
|
||||
print(template.heat_template())
|
||||
|
|
|
@ -143,12 +143,14 @@ class TemplateGenerator(object):
|
|||
|
||||
def extract_vm_details(self, exclude_servers, exclude_volumes,
|
||||
exclude_keypairs, generate_data,
|
||||
extract_ports=False):
|
||||
extract_ports=False,
|
||||
alter_allocation_pools=False):
|
||||
self.exclude_servers = exclude_servers
|
||||
self.exclude_volumes = exclude_volumes
|
||||
self.exclude_keypairs = exclude_keypairs
|
||||
self.generate_data = generate_data
|
||||
self.extract_ports = extract_ports
|
||||
self.alter_allocation_pools = alter_allocation_pools
|
||||
|
||||
self.subnets = self.build_data(self.neutron.subnet_list())
|
||||
self.networks = self.build_data(self.neutron.network_list())
|
||||
|
@ -690,6 +692,19 @@ class TemplateGenerator(object):
|
|||
resources += self._extract_ports()
|
||||
|
||||
subnets = self._extract_subnets()
|
||||
if self.alter_allocation_pools:
|
||||
for subnet in subnets:
|
||||
pools = subnet.properties['allocation_pools']
|
||||
fixed_ips = self.dhcp_fixed_ips.get(subnet.name, [])
|
||||
for pool in pools:
|
||||
for ip in fixed_ips:
|
||||
start_n = socket.inet_aton(pool['start'])
|
||||
end_n = socket.inet_aton(pool['end'])
|
||||
ip_n = socket.inet_aton(ip)
|
||||
if start_n < ip_n <= end_n:
|
||||
# The DHCP IP address is in the pool, we make the
|
||||
# pool start at it's IP address
|
||||
pool['start'] = ip
|
||||
resources += subnets
|
||||
|
||||
resources += self._extract_secgroups()
|
||||
|
|
|
@ -394,12 +394,14 @@ class BaseTestCase(base.TestCase):
|
|||
super(BaseTestCase, self).tearDown()
|
||||
|
||||
def get_generator(self, exclude_servers, exclude_volumes,
|
||||
exclude_keypairs, generate_data, extract_ports):
|
||||
exclude_keypairs, generate_data, extract_ports,
|
||||
alter_dhcp_allocation_pools=False):
|
||||
generator = flame.TemplateGenerator('x', 'x', 'x', 'x', True,
|
||||
'publicURL')
|
||||
generator.extract_vm_details(exclude_servers, exclude_volumes,
|
||||
exclude_keypairs, generate_data,
|
||||
extract_ports)
|
||||
extract_ports,
|
||||
alter_dhcp_allocation_pools)
|
||||
return generator
|
||||
|
||||
def check_stackdata(self, resources, expected_resources):
|
||||
|
@ -658,3 +660,35 @@ class GenerationTests(BaseTestCase):
|
|||
'status': 'COMPLETE',
|
||||
'type': 'OS::Neutron::Port'}
|
||||
self.assertEqual(reference, association_data)
|
||||
|
||||
def test_dhcp_pool_alteration(self):
|
||||
generator = self.get_generator(False, False, False, True, True, True)
|
||||
generator.extract_data()
|
||||
|
||||
subnets = [res['properties']
|
||||
for res in generator.template['resources'].values()
|
||||
if res['type'] == "OS::Neutron::Subnet"]
|
||||
pools = {sn['name']: sn['allocation_pools'] for sn in subnets}
|
||||
reference = {u'int-a-1': [{u'end': u'192.168.203.254',
|
||||
u'start': u'192.168.203.3'}],
|
||||
u'int-a-2': [{u'end': u'192.168.204.254',
|
||||
u'start': u'192.168.204.2'}],
|
||||
u'storage': [{u'end': u'172.19.0.254',
|
||||
u'start': u'172.19.0.2'}]}
|
||||
self.assertEqual(reference, pools)
|
||||
|
||||
def test_no_dhcp_pool_alteration(self):
|
||||
generator = self.get_generator(False, False, False, True, True, False)
|
||||
generator.extract_data()
|
||||
|
||||
subnets = [res['properties']
|
||||
for res in generator.template['resources'].values()
|
||||
if res['type'] == "OS::Neutron::Subnet"]
|
||||
pools = {sn['name']: sn['allocation_pools'] for sn in subnets}
|
||||
reference = {u'int-a-1': [{u'end': u'192.168.203.254',
|
||||
u'start': u'192.168.203.2'}],
|
||||
u'int-a-2': [{u'end': u'192.168.204.254',
|
||||
u'start': u'192.168.204.2'}],
|
||||
u'storage': [{u'end': u'172.19.0.254',
|
||||
u'start': u'172.19.0.2'}]}
|
||||
self.assertEqual(reference, pools)
|
||||
|
|
Loading…
Reference in New Issue