Merge "Add support for Infoblox IPAM configuration via subordinate charm."
This commit is contained in:
commit
6d124b69cc
|
@ -0,0 +1 @@
|
|||
neutron_api_hooks.py
|
|
@ -0,0 +1 @@
|
|||
neutron_api_hooks.py
|
|
@ -0,0 +1 @@
|
|||
neutron_api_hooks.py
|
|
@ -879,3 +879,43 @@ class DesignateContext(context.OSContextGenerator):
|
|||
ctxt['ipv6_ptr_zone_prefix_size'] = (
|
||||
config('ipv6-ptr-zone-prefix-size'))
|
||||
return ctxt
|
||||
|
||||
|
||||
class NeutronInfobloxContext(context.OSContextGenerator):
|
||||
'''Infoblox IPAM context for Neutron API'''
|
||||
interfaces = ['infoblox-neutron']
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {}
|
||||
rdata = {}
|
||||
for rid in relation_ids('infoblox-neutron'):
|
||||
if related_units(rid) and not rdata:
|
||||
for unit in related_units(rid):
|
||||
rdata = relation_get(rid=rid, unit=unit)
|
||||
ctxt['cloud_data_center_id'] = rdata.get('dc_id')
|
||||
break
|
||||
if ctxt.get('cloud_data_center_id') is not None:
|
||||
if not self.check_requirements(rdata):
|
||||
log('Missing Infoblox connection information, passing.')
|
||||
return {}
|
||||
ctxt['enable_infoblox'] = True
|
||||
ctxt['cloud_data_center_id'] = rdata.get('dc_id')
|
||||
ctxt['grid_master_host'] = rdata.get('grid_master_host')
|
||||
ctxt['grid_master_name'] = rdata.get('grid_master_name')
|
||||
ctxt['infoblox_admin_user_name'] = rdata.get('admin_user_name')
|
||||
ctxt['infoblox_admin_password'] = rdata.get('admin_password')
|
||||
# the next three values are non-critical and may accept defaults
|
||||
ctxt['wapi_version'] = rdata.get('wapi_version', '2.3')
|
||||
ctxt['wapi_max_results'] = rdata.get('wapi_max_results', '-50000')
|
||||
ctxt['wapi_paging'] = rdata.get('wapi_paging', True)
|
||||
return ctxt
|
||||
|
||||
def check_requirements(self, rdata):
|
||||
required = [
|
||||
'grid_master_name',
|
||||
'grid_master_host',
|
||||
'admin_user_name',
|
||||
'admin_password',
|
||||
]
|
||||
return len(set(p for p, v in rdata.items() if v).
|
||||
intersection(required)) == len(required)
|
||||
|
|
|
@ -35,6 +35,7 @@ from charmhelpers.core.hookenv import (
|
|||
open_port,
|
||||
unit_get,
|
||||
related_units,
|
||||
is_leader,
|
||||
)
|
||||
|
||||
from charmhelpers.core.host import (
|
||||
|
@ -86,6 +87,7 @@ from neutron_api_utils import (
|
|||
pause_unit_helper,
|
||||
resume_unit_helper,
|
||||
remove_old_packages,
|
||||
is_db_initialised,
|
||||
)
|
||||
from neutron_api_context import (
|
||||
get_dns_domain,
|
||||
|
@ -294,6 +296,7 @@ def config_changed():
|
|||
packages_removed = remove_old_packages()
|
||||
configure_https()
|
||||
update_nrpe_config()
|
||||
infoblox_changed()
|
||||
CONFIGS.write_all()
|
||||
if packages_removed and not is_unit_paused_set():
|
||||
log("Package purge detected, restarting services", "INFO")
|
||||
|
@ -359,7 +362,7 @@ def db_changed():
|
|||
return
|
||||
CONFIGS.write_all()
|
||||
conditional_neutron_migration()
|
||||
|
||||
infoblox_changed()
|
||||
for r_id in relation_ids('neutron-plugin-api-subordinate'):
|
||||
neutron_plugin_api_subordinate_relation_joined(relid=r_id)
|
||||
|
||||
|
@ -415,6 +418,7 @@ def identity_changed():
|
|||
for r_id in relation_ids('neutron-plugin-api-subordinate'):
|
||||
neutron_plugin_api_subordinate_relation_joined(relid=r_id)
|
||||
configure_https()
|
||||
infoblox_changed()
|
||||
|
||||
|
||||
@hooks.hook('neutron-api-relation-joined')
|
||||
|
@ -655,6 +659,34 @@ def designate_changed():
|
|||
CONFIGS.write_all()
|
||||
|
||||
|
||||
@hooks.hook('infoblox-neutron-relation-changed')
|
||||
@restart_on_change(restart_map)
|
||||
def infoblox_changed():
|
||||
# The neutron DB upgrade will add new tables to
|
||||
# neutron db related to infoblox service.
|
||||
# Please take a look to charm-infoblox docs.
|
||||
if 'infoblox-neutron' not in CONFIGS.complete_contexts():
|
||||
log('infoblox-neutron relation incomplete. Peer not ready?')
|
||||
return
|
||||
|
||||
CONFIGS.write(NEUTRON_CONF)
|
||||
|
||||
if is_leader():
|
||||
ready = False
|
||||
if is_db_initialised() and neutron_ready():
|
||||
migrate_neutron_database(upgrade=True)
|
||||
ready = True
|
||||
for rid in relation_ids('infoblox-neutron'):
|
||||
relation_set(relation_id=rid, neutron_api_ready=ready)
|
||||
|
||||
|
||||
@hooks.hook('infoblox-neutron-relation-departed',
|
||||
'infoblox-neutron-relation-broken')
|
||||
@restart_on_change(restart_map)
|
||||
def infoblox_departed():
|
||||
CONFIGS.write_all()
|
||||
|
||||
|
||||
@hooks.hook('update-status')
|
||||
@harden()
|
||||
@harden()
|
||||
|
|
|
@ -173,7 +173,8 @@ BASE_RESOURCE_MAP = OrderedDict([
|
|||
context.WorkerConfigContext(),
|
||||
context.InternalEndpointContext(),
|
||||
context.MemcacheContext(),
|
||||
neutron_api_context.DesignateContext()],
|
||||
neutron_api_context.DesignateContext(),
|
||||
neutron_api_context.NeutronInfobloxContext()],
|
||||
}),
|
||||
(NEUTRON_DEFAULT, {
|
||||
'services': ['neutron-server'],
|
||||
|
|
|
@ -55,6 +55,9 @@ requires:
|
|||
interface: midonet
|
||||
external-dns:
|
||||
interface: designate
|
||||
infoblox-neutron:
|
||||
interface: infoblox
|
||||
scope: container
|
||||
certificates:
|
||||
interface: tls-certificates
|
||||
peers:
|
||||
|
|
|
@ -75,6 +75,10 @@ global_physnet_mtu = {{ global_physnet_mtu }}
|
|||
external_dns_driver = designate
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
ipam_driver = infoblox
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
||||
[quotas]
|
||||
|
@ -121,3 +125,7 @@ lock_path = $state_path/lock
|
|||
{% endif -%}
|
||||
|
||||
{% include "section-oslo-middleware" %}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
{% include "parts/section-infoblox" %}
|
||||
{% endif -%}
|
||||
|
|
|
@ -75,6 +75,10 @@ global_physnet_mtu = {{ global_physnet_mtu }}
|
|||
external_dns_driver = designate
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
ipam_driver = infoblox
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
||||
[quotas]
|
||||
|
@ -120,6 +124,10 @@ lock_path = $state_path/lock
|
|||
{% include "parts/section-designate" %}
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
{% include "parts/section-infoblox" %}
|
||||
{% endif -%}
|
||||
|
||||
[service_providers]
|
||||
service_provider = LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
|
||||
service_provider = VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
|
||||
|
|
|
@ -78,6 +78,10 @@ global_physnet_mtu = {{ global_physnet_mtu }}
|
|||
external_dns_driver = designate
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
ipam_driver = infoblox
|
||||
{% endif -%}
|
||||
|
||||
{% include "parts/section-placement" %}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
@ -125,6 +129,10 @@ lock_path = $state_path/lock
|
|||
{% include "parts/section-designate" %}
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
{% include "parts/section-infoblox" %}
|
||||
{% endif -%}
|
||||
|
||||
[service_providers]
|
||||
service_provider = LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
|
||||
service_provider = VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[infoblox]
|
||||
cloud_data_center_id = {{ cloud_data_center_id }}
|
||||
|
||||
[infoblox-dc:{{ cloud_data_center_id }}]
|
||||
grid_master_host = {{ grid_master_host }}
|
||||
grid_master_name = {{ grid_master_name }}
|
||||
admin_user_name = {{ infoblox_admin_user_name }}
|
||||
admin_password = {{ infoblox_admin_password }}
|
||||
wapi_version = {{ wapi_version }}
|
||||
wapi_max_results = {{ wapi_max_results }}
|
||||
wapi_paging = {{ wapi_paging }}
|
|
@ -1,5 +1,31 @@
|
|||
[nova]
|
||||
{% if enable_infoblox -%}
|
||||
# TODO - Exceptionally we added the content of [keystone_authtoken] due to an
|
||||
# internal mechanism of Infoblox plugin lp-1688039.
|
||||
{% if auth_host -%}
|
||||
auth_type = password
|
||||
{% if api_version == "3" -%}
|
||||
auth_uri = {{ service_protocol }}://{{ service_host }}:{{ service_port }}/v3
|
||||
auth_url = {{ auth_protocol }}://{{ auth_host }}:{{ auth_port }}/v3
|
||||
project_domain_name = {{ admin_domain_name }}
|
||||
user_domain_name = {{ admin_domain_name }}
|
||||
{% else -%}
|
||||
auth_uri = {{ service_protocol }}://{{ service_host }}:{{ service_port }}
|
||||
auth_url = {{ auth_protocol }}://{{ auth_host }}:{{ auth_port }}
|
||||
project_domain_name = default
|
||||
user_domain_name = default
|
||||
{% endif -%}
|
||||
project_name = {{ admin_tenant_name }}
|
||||
username = {{ admin_user }}
|
||||
password = {{ admin_password }}
|
||||
signing_dir = {{ signing_dir }}
|
||||
{% if use_memcache == true %}
|
||||
memcached_servers = {{ memcache_url }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% else %}
|
||||
auth_section = keystone_authtoken
|
||||
{% endif %}
|
||||
region_name = {{ region }}
|
||||
{% if use_internal_endpoints -%}
|
||||
endpoint_type = internal
|
||||
|
|
|
@ -78,6 +78,10 @@ global_physnet_mtu = {{ global_physnet_mtu }}
|
|||
external_dns_driver = designate
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
ipam_driver = infoblox
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
||||
[quotas]
|
||||
|
@ -123,6 +127,10 @@ lock_path = $state_path/lock
|
|||
{% include "parts/section-designate" %}
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
{% include "parts/section-infoblox" %}
|
||||
{% endif -%}
|
||||
|
||||
{% include "parts/section-placement" %}
|
||||
|
||||
[service_providers]
|
||||
|
|
|
@ -78,6 +78,10 @@ global_physnet_mtu = {{ global_physnet_mtu }}
|
|||
external_dns_driver = designate
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
ipam_driver = infoblox
|
||||
{% endif -%}
|
||||
|
||||
{% include "section-zeromq" %}
|
||||
|
||||
[quotas]
|
||||
|
@ -123,6 +127,10 @@ lock_path = $state_path/lock
|
|||
{% include "parts/section-designate" %}
|
||||
{% endif -%}
|
||||
|
||||
{% if enable_infoblox -%}
|
||||
{% include "parts/section-infoblox" %}
|
||||
{% endif -%}
|
||||
|
||||
{% include "parts/section-placement" %}
|
||||
|
||||
[service_providers]
|
||||
|
|
|
@ -1398,3 +1398,54 @@ class NeutronLoadBalancerContextTest(CharmTestCase):
|
|||
'base_url': 'http://1.2.3.4:1234'})
|
||||
with self.assertRaises(ValueError):
|
||||
context.NeutronLoadBalancerContext()()
|
||||
|
||||
|
||||
class NeutronInfobloxContextTest(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NeutronInfobloxContextTest, self).setUp(context, TO_PATCH)
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.config.side_effect = self.test_config.get
|
||||
|
||||
def tearDown(self):
|
||||
super(NeutronInfobloxContextTest, self).tearDown()
|
||||
|
||||
def test_infoblox_no_related_units(self):
|
||||
self.related_units.return_value = []
|
||||
ctxt = context.NeutronInfobloxContext()()
|
||||
expect = {}
|
||||
|
||||
self.assertEqual(expect, ctxt)
|
||||
|
||||
def test_infoblox_related_units(self):
|
||||
self.related_units.return_value = ['unit1']
|
||||
self.relation_ids.return_value = ['rid1']
|
||||
self.test_relation.set(
|
||||
{'dc_id': '0',
|
||||
'grid_master_host': 'foo',
|
||||
'grid_master_name': 'bar',
|
||||
'admin_user_name': 'faz',
|
||||
'admin_password': 'baz'})
|
||||
ctxt = context.NeutronInfobloxContext()()
|
||||
expect = {'enable_infoblox': True,
|
||||
'cloud_data_center_id': '0',
|
||||
'grid_master_host': 'foo',
|
||||
'grid_master_name': 'bar',
|
||||
'infoblox_admin_user_name': 'faz',
|
||||
'infoblox_admin_password': 'baz',
|
||||
'wapi_version': '2.3',
|
||||
'wapi_max_results': '-50000',
|
||||
'wapi_paging': True}
|
||||
|
||||
self.assertEqual(expect, ctxt)
|
||||
|
||||
def test_infoblox_related_units_missing_data(self):
|
||||
self.related_units.return_value = ['unit1']
|
||||
self.relation_ids.return_value = ['rid1']
|
||||
self.test_relation.set(
|
||||
{'dc_id': '0',
|
||||
'grid_master_host': 'foo'})
|
||||
ctxt = context.NeutronInfobloxContext()()
|
||||
expect = {}
|
||||
|
||||
self.assertEqual(expect, ctxt)
|
||||
|
|
|
@ -64,6 +64,7 @@ TO_PATCH = [
|
|||
'get_l2population',
|
||||
'get_overlay_network_type',
|
||||
'is_clustered',
|
||||
'is_leader',
|
||||
'is_elected_leader',
|
||||
'is_qos_requested_and_valid',
|
||||
'is_vlan_trunking_requested_and_valid',
|
||||
|
@ -90,7 +91,7 @@ TO_PATCH = [
|
|||
'remove_old_packages',
|
||||
'services',
|
||||
'service_restart',
|
||||
'generate_ha_relation_data',
|
||||
'is_db_initialised',
|
||||
]
|
||||
NEUTRON_CONF_DIR = "/etc/neutron"
|
||||
|
||||
|
@ -814,7 +815,7 @@ class NeutronAPIHooksTests(CharmTestCase):
|
|||
self.is_elected_leader.return_value = True
|
||||
self.os_release.return_value = 'kilo'
|
||||
hooks.conditional_neutron_migration()
|
||||
self.migrate_neutron_database.assert_called_with()
|
||||
self.migrate_neutron_database.assert_called()
|
||||
|
||||
def test_conditional_neutron_migration_leader_icehouse(self):
|
||||
self.test_relation.set({
|
||||
|
@ -849,3 +850,17 @@ class NeutronAPIHooksTests(CharmTestCase):
|
|||
def test_designate_peer_departed(self):
|
||||
self._call_hook('external-dns-relation-departed')
|
||||
self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))
|
||||
|
||||
def test_infoblox_peer_changed(self):
|
||||
self.is_db_initialised.return_value = True
|
||||
self.test_relation.set({
|
||||
'dc_id': '0',
|
||||
})
|
||||
self.os_release.return_value = 'queens'
|
||||
self.relation_ids.side_effect = self._fake_relids
|
||||
self._call_hook('infoblox-neutron-relation-changed')
|
||||
self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))
|
||||
|
||||
def test_infoblox_peer_departed(self):
|
||||
self._call_hook('infoblox-neutron-relation-departed')
|
||||
self.assertTrue(self.CONFIGS.write.called_with(NEUTRON_CONF))
|
||||
|
|
Loading…
Reference in New Issue