Merge lp:~gnuoy/charms/trusty/neutron-api/fix-neutron-query into lp:~openstack-charmers-archive/charms/trusty/neutron-api/next

Proposed by Liam Young on 2015-04-21
Status: Merged
Merged at revision: 107
Proposed branch: lp:~gnuoy/charms/trusty/neutron-api/fix-neutron-query
Merge into: lp:~openstack-charmers-archive/charms/trusty/neutron-api/next
Diff against target: 310 lines (+188/-13)
5 files modified
hooks/neutron_api_hooks.py (+14/-10)
hooks/neutron_api_utils.py (+23/-2)
tests/charmhelpers/contrib/openstack/amulet/deployment.py (+1/-1)
unit_tests/test_neutron_api_hooks.py (+24/-0)
unit_tests/test_neutron_api_utils.py (+126/-0)
To merge this branch: bzr merge lp:~gnuoy/charms/trusty/neutron-api/fix-neutron-query
Reviewer Review Type Date Requested Status
James Page 2015-04-21 Approve on 2015-04-21
Review via email: mp+256889@code.launchpad.net
To post a comment you must log in.

charm_lint_check #3682 neutron-api-next for gnuoy mp256889
    LINT OK: passed

Build: http://10.245.162.77:8080/job/charm_lint_check/3682/

charm_unit_test #3470 neutron-api-next for gnuoy mp256889
    UNIT OK: passed

Build: http://10.245.162.77:8080/job/charm_unit_test/3470/

charm_amulet_test #3476 neutron-api-next for gnuoy mp256889
    AMULET FAIL: amulet-test failed

AMULET Results (max last 2 lines):
make: *** [test] Error 1
ERROR:root:Make target returned non-zero.

Full amulet test output: http://paste.ubuntu.com/10860721/
Build: http://10.245.162.77:8080/job/charm_amulet_test/3476/

James Page (james-page) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'hooks/neutron_api_hooks.py'
2--- hooks/neutron_api_hooks.py 2015-04-20 14:11:30 +0000
3+++ hooks/neutron_api_hooks.py 2015-04-21 08:47:17 +0000
4@@ -49,6 +49,7 @@
5 git_install,
6 dvr_router_present,
7 l3ha_router_present,
8+ neutron_ready,
9 register_configs,
10 restart_map,
11 services,
12@@ -131,16 +132,19 @@
13 @hooks.hook('config-changed')
14 @restart_on_change(restart_map(), stopstart=True)
15 def config_changed():
16- if l3ha_router_present() and not get_l3ha():
17- e = ('Cannot disable Router HA while ha enabled routers exist. Please'
18- ' remove any ha routers')
19- log(e, level=ERROR)
20- raise Exception(e)
21- if dvr_router_present() and not get_dvr():
22- e = ('Cannot disable dvr while dvr enabled routers exist. Please'
23- ' remove any distributed routers')
24- log(e, level=ERROR)
25- raise Exception(e)
26+ # If neutron is ready to be queried then check for incompatability between
27+ # existing neutron objects and charm settings
28+ if neutron_ready():
29+ if l3ha_router_present() and not get_l3ha():
30+ e = ('Cannot disable Router HA while ha enabled routers exist.'
31+ ' Please remove any ha routers')
32+ log(e, level=ERROR)
33+ raise Exception(e)
34+ if dvr_router_present() and not get_dvr():
35+ e = ('Cannot disable dvr while dvr enabled routers exist. Please'
36+ ' remove any distributed routers')
37+ log(e, level=ERROR)
38+ raise Exception(e)
39 if config('prefer-ipv6'):
40 setup_ipv6()
41 sync_db_with_multi_ipv6_addresses(config('database'),
42
43=== modified file 'hooks/neutron_api_utils.py'
44--- hooks/neutron_api_utils.py 2015-04-17 12:12:02 +0000
45+++ hooks/neutron_api_utils.py 2015-04-21 08:47:17 +0000
46@@ -307,8 +307,8 @@
47 apt_install('haproxy/trusty-backports', fatal=True)
48
49
50-def router_feature_present(feature):
51- ''' Check For dvr enabled routers '''
52+def get_neutron_client():
53+ ''' Return a neutron client if possible '''
54 env = neutron_api_context.IdentityServiceContext()()
55 if not env:
56 log('Unable to check resources at this time')
57@@ -322,6 +322,12 @@
58 tenant_name=env['admin_tenant_name'],
59 auth_url=auth_url,
60 region_name=env['region'])
61+ return neutron_client
62+
63+
64+def router_feature_present(feature):
65+ ''' Check For dvr enabled routers '''
66+ neutron_client = get_neutron_client()
67 for router in neutron_client.list_routers()['routers']:
68 if router.get(feature, False):
69 return True
70@@ -332,6 +338,21 @@
71 dvr_router_present = partial(router_feature_present, feature='distributed')
72
73
74+def neutron_ready():
75+ ''' Check if neutron is ready by running arbitrary query'''
76+ neutron_client = get_neutron_client()
77+ if not neutron_client:
78+ log('No neutron client, neutron not ready')
79+ return False
80+ try:
81+ neutron_client.list_routers()
82+ log('neutron client ready')
83+ return True
84+ except:
85+ log('neutron query failed, neutron not ready ')
86+ return False
87+
88+
89 def git_install(projects_yaml):
90 """Perform setup, and install git repos specified in yaml parameter."""
91 if git_install_requested():
92
93=== modified file 'tests/charmhelpers/contrib/openstack/amulet/deployment.py'
94--- tests/charmhelpers/contrib/openstack/amulet/deployment.py 2015-04-20 19:13:34 +0000
95+++ tests/charmhelpers/contrib/openstack/amulet/deployment.py 2015-04-21 08:47:17 +0000
96@@ -109,7 +109,7 @@
97 # Must be ordered by OpenStack release (not by Ubuntu release):
98 (self.precise_essex, self.precise_folsom, self.precise_grizzly,
99 self.precise_havana, self.precise_icehouse,
100- self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
101+ self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
102 self.trusty_kilo, self.vivid_kilo) = range(10)
103
104 releases = {
105
106=== modified file 'unit_tests/test_neutron_api_hooks.py'
107--- unit_tests/test_neutron_api_hooks.py 2015-04-02 20:15:28 +0000
108+++ unit_tests/test_neutron_api_hooks.py 2015-04-21 08:47:17 +0000
109@@ -44,6 +44,7 @@
110 'git_install',
111 'is_relation_made',
112 'log',
113+ 'neutron_ready',
114 'open_port',
115 'openstack_upgrade_available',
116 'os_requires_version',
117@@ -147,6 +148,7 @@
118 @patch.object(hooks, 'git_install_requested')
119 def test_config_changed(self, git_requested, conf_https):
120 git_requested.return_value = False
121+ self.neutron_ready.return_value = True
122 self.openstack_upgrade_available.return_value = True
123 self.dvr_router_present.return_value = False
124 self.l3ha_router_present.return_value = False
125@@ -169,12 +171,34 @@
126 self.assertTrue(self.do_openstack_upgrade.called)
127 self.assertTrue(self.apt_install.called)
128
129+ def test_config_changed_nodvr_disprouters(self):
130+ self.neutron_ready.return_value = True
131+ self.dvr_router_present.return_value = True
132+ self.get_dvr.return_value = False
133+ with self.assertRaises(Exception) as context:
134+ self._call_hook('config-changed')
135+ self.assertEqual(context.exception.message,
136+ 'Cannot disable dvr while dvr enabled routers exist.'
137+ ' Please remove any distributed routers')
138+
139+ def test_config_changed_nol3ha_harouters(self):
140+ self.neutron_ready.return_value = True
141+ self.dvr_router_present.return_value = False
142+ self.l3ha_router_present.return_value = True
143+ self.get_l3ha.return_value = False
144+ with self.assertRaises(Exception) as context:
145+ self._call_hook('config-changed')
146+ self.assertEqual(context.exception.message,
147+ 'Cannot disable Router HA while ha enabled routers'
148+ ' exist. Please remove any ha routers')
149+
150 @patch.object(hooks, 'configure_https')
151 @patch.object(hooks, 'git_install_requested')
152 @patch.object(hooks, 'config_value_changed')
153 def test_config_changed_git(self, config_val_changed, git_requested,
154 configure_https):
155 git_requested.return_value = True
156+ self.neutron_ready.return_value = True
157 self.dvr_router_present.return_value = False
158 self.l3ha_router_present.return_value = False
159 self.relation_ids.side_effect = self._fake_relids
160
161=== modified file 'unit_tests/test_neutron_api_utils.py'
162--- unit_tests/test_neutron_api_utils.py 2015-04-17 12:12:02 +0000
163+++ unit_tests/test_neutron_api_utils.py 2015-04-21 08:47:17 +0000
164@@ -3,6 +3,7 @@
165 from collections import OrderedDict
166 from copy import deepcopy
167 import charmhelpers.contrib.openstack.templating as templating
168+import neutron_api_context as ncontext
169
170 templating.OSConfigRenderer = MagicMock()
171
172@@ -57,6 +58,15 @@
173 return plugins[plugin][attr]
174
175
176+class DummyIdentityServiceContext():
177+
178+ def __init__(self, return_value):
179+ self.return_value = return_value
180+
181+ def __call__(self):
182+ return self.return_value
183+
184+
185 class TestNeutronAPIUtils(CharmTestCase):
186 def setUp(self):
187 super(TestNeutronAPIUtils, self).setUp(nutils, TO_PATCH)
188@@ -200,6 +210,122 @@
189 fatal=True)
190 configs.set_release.assert_called_with(openstack_release='juno')
191
192+ @patch.object(ncontext, 'IdentityServiceContext')
193+ @patch('neutronclient.v2_0.client.Client')
194+ def test_get_neutron_client(self, nclient, IdentityServiceContext):
195+ creds = {
196+ 'auth_protocol': 'http',
197+ 'auth_host': 'myhost',
198+ 'auth_port': '2222',
199+ 'admin_user': 'bob',
200+ 'admin_password': 'pa55w0rd',
201+ 'admin_tenant_name': 'tenant1',
202+ 'region': 'region2',
203+ }
204+ IdentityServiceContext.return_value = \
205+ DummyIdentityServiceContext(return_value=creds)
206+ nutils.get_neutron_client()
207+ nclient.assert_called_with(
208+ username='bob',
209+ tenant_name='tenant1',
210+ password='pa55w0rd',
211+ auth_url='http://myhost:2222/v2.0',
212+ region_name='region2',
213+ )
214+
215+ @patch.object(ncontext, 'IdentityServiceContext')
216+ def test_get_neutron_client_noidservice(self, IdentityServiceContext):
217+ creds = {}
218+ IdentityServiceContext.return_value = \
219+ DummyIdentityServiceContext(return_value=creds)
220+ self.assertEquals(nutils.get_neutron_client(), None)
221+
222+ @patch.object(nutils, 'get_neutron_client')
223+ def test_router_feature_present_keymissing(self, get_neutron_client):
224+ routers = {
225+ 'routers': [
226+ {
227+ u'status': u'ACTIVE',
228+ u'external_gateway_info': {
229+ u'network_id': u'eedffb9b-b93e-49c6-9545-47c656c9678e',
230+ u'enable_snat': True
231+ }, u'name': u'provider-router',
232+ u'admin_state_up': True,
233+ u'tenant_id': u'b240d06e38394780a3ea296138cdd174',
234+ u'routes': [],
235+ u'id': u'84182bc8-eede-4564-9c87-1a56bdb26a90',
236+ }
237+ ]
238+ }
239+ get_neutron_client.list_routers.return_value = routers
240+ self.assertEquals(nutils.router_feature_present('ha'), False)
241+
242+ @patch.object(nutils, 'get_neutron_client')
243+ def test_router_feature_present_keyfalse(self, get_neutron_client):
244+ routers = {
245+ 'routers': [
246+ {
247+ u'status': u'ACTIVE',
248+ u'external_gateway_info': {
249+ u'network_id': u'eedffb9b-b93e-49c6-9545-47c656c9678e',
250+ u'enable_snat': True
251+ }, u'name': u'provider-router',
252+ u'admin_state_up': True,
253+ u'tenant_id': u'b240d06e38394780a3ea296138cdd174',
254+ u'routes': [],
255+ u'id': u'84182bc8-eede-4564-9c87-1a56bdb26a90',
256+ u'ha': False,
257+ }
258+ ]
259+ }
260+ dummy_client = MagicMock()
261+ dummy_client.list_routers.return_value = routers
262+ get_neutron_client.return_value = dummy_client
263+ self.assertEquals(nutils.router_feature_present('ha'), False)
264+
265+ @patch.object(nutils, 'get_neutron_client')
266+ def test_router_feature_present_keytrue(self, get_neutron_client):
267+ routers = {
268+ 'routers': [
269+ {
270+ u'status': u'ACTIVE',
271+ u'external_gateway_info': {
272+ u'network_id': u'eedffb9b-b93e-49c6-9545-47c656c9678e',
273+ u'enable_snat': True
274+ }, u'name': u'provider-router',
275+ u'admin_state_up': True,
276+ u'tenant_id': u'b240d06e38394780a3ea296138cdd174',
277+ u'routes': [],
278+ u'id': u'84182bc8-eede-4564-9c87-1a56bdb26a90',
279+ u'ha': True,
280+ }
281+ ]
282+ }
283+
284+ dummy_client = MagicMock()
285+ dummy_client.list_routers.return_value = routers
286+ get_neutron_client.return_value = dummy_client
287+ self.assertEquals(nutils.router_feature_present('ha'), True)
288+
289+ @patch.object(nutils, 'get_neutron_client')
290+ def test_neutron_ready(self, get_neutron_client):
291+ dummy_client = MagicMock()
292+ dummy_client.list_routers.return_value = []
293+ get_neutron_client.return_value = dummy_client
294+ self.assertEquals(nutils.neutron_ready(), True)
295+
296+ @patch.object(nutils, 'get_neutron_client')
297+ def test_neutron_ready_noclient(self, get_neutron_client):
298+ get_neutron_client.return_value = None
299+ self.assertEquals(nutils.neutron_ready(), False)
300+
301+ @patch.object(nutils, 'get_neutron_client')
302+ def test_neutron_ready_clientexception(self, get_neutron_client):
303+ dummy_client = MagicMock()
304+ dummy_client.list_routers.side_effect = Exception('Boom!')
305+ get_neutron_client.return_value = dummy_client
306+ self.assertEquals(nutils.neutron_ready(), False)
307+
308 @patch.object(nutils, 'git_install_requested')
309 @patch.object(nutils, 'git_clone_and_install')
310 @patch.object(nutils, 'git_post_install')

Subscribers

People subscribed via source and target branches