Merge lp:~frankban/juju-quickstart/env-management-1 into lp:juju-quickstart

Proposed by Francesco Banconi
Status: Merged
Merged at revision: 25
Proposed branch: lp:~frankban/juju-quickstart/env-management-1
Merge into: lp:juju-quickstart
Diff against target: 600 lines (+269/-204)
8 files modified
quickstart/manage.py (+6/-3)
quickstart/models/__init__.py (+17/-0)
quickstart/models/envs.py (+104/-0)
quickstart/tests/models/test_charms.py (+1/-1)
quickstart/tests/models/test_envs.py (+136/-0)
quickstart/tests/test_manage.py (+3/-4)
quickstart/tests/test_utils.py (+0/-111)
quickstart/utils.py (+2/-85)
To merge this branch: bzr merge lp:~frankban/juju-quickstart/env-management-1
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+197709@code.launchpad.net

Description of the change

Envs management: code reorganization.

This branch includes code reorg as
a preparation for the upcoming envs
management work.

It's just about mechanically moving code
to the new models package, except for a
minor fix to test_init_environment in
test_manage.py.

https://codereview.appspot.com/37150043/

To post a comment you must log in.
Revision history for this message
Francesco Banconi (frankban) wrote :

Reviewers: mp+197709_code.launchpad.net,

Message:
Please take a look.

Description:
Envs management: code reorganization.

This branch includes code reorg as
a preparation for the upcoming envs
management work.

It's just about mechanically moving code
to the new models package, except for a
minor fix to test_init_environment in
test_manage.py.

https://code.launchpad.net/~frankban/juju-quickstart/env-management-1/+merge/197709

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/37150043/

Affected files (+269, -202 lines):
   A [revision details]
   M quickstart/manage.py
   A quickstart/models/__init__.py
   M quickstart/models/charms.py
   A quickstart/models/envs.py
   A quickstart/tests/models/__init__.py
   M quickstart/tests/models/test_charms.py
   A quickstart/tests/models/test_envs.py
   M quickstart/tests/test_manage.py
   M quickstart/tests/test_utils.py
   M quickstart/utils.py

Revision history for this message
Gary Poster (gary) wrote :
Revision history for this message
Francesco Banconi (frankban) wrote :

*** Submitted:

Envs management: code reorganization.

This branch includes code reorg as
a preparation for the upcoming envs
management work.

It's just about mechanically moving code
to the new models package, except for a
minor fix to test_init_environment in
test_manage.py.

R=gary.poster
CC=
https://codereview.appspot.com/37150043

https://codereview.appspot.com/37150043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'quickstart/manage.py'
2--- quickstart/manage.py 2013-12-02 21:36:04 +0000
3+++ quickstart/manage.py 2013-12-04 13:19:54 +0000
4@@ -25,10 +25,13 @@
5 import quickstart
6 from quickstart import (
7 app,
8- charms,
9 settings,
10 utils,
11 )
12+from quickstart.models import (
13+ charms,
14+ envs,
15+)
16
17
18 version = quickstart.get_version()
19@@ -144,7 +147,7 @@
20 )
21 # Validate the environment file.
22 try:
23- env_type, admin_secret = utils.parse_env_file(env_file, env_name)
24+ env_type, admin_secret = envs.parse_env_file(env_file, env_name)
25 except ValueError as err:
26 return parser.error(str(err))
27 # Update the options namespace with the new values.
28@@ -193,7 +196,7 @@
29
30 Exit with an error if the provided arguments are not valid.
31 """
32- default_env_name = utils.get_default_env_name()
33+ default_env_name = envs.get_default_env_name()
34 # Define the help message for the --environment option.
35 env_help = 'The name of the Juju environment to use'
36 # XXX 2013-12-02 makyo:
37
38=== added directory 'quickstart/models'
39=== added file 'quickstart/models/__init__.py'
40--- quickstart/models/__init__.py 1970-01-01 00:00:00 +0000
41+++ quickstart/models/__init__.py 2013-12-04 13:19:54 +0000
42@@ -0,0 +1,17 @@
43+# This file is part of the Juju Quickstart Plugin, which lets users set up a
44+# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
45+# Copyright (C) 2013 Canonical Ltd.
46+#
47+# This program is free software: you can redistribute it and/or modify it under
48+# the terms of the GNU Affero General Public License version 3, as published by
49+# the Free Software Foundation.
50+#
51+# This program is distributed in the hope that it will be useful, but WITHOUT
52+# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
53+# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54+# Affero General Public License for more details.
55+#
56+# You should have received a copy of the GNU Affero General Public License
57+# along with this program. If not, see <http://www.gnu.org/licenses/>.
58+
59+"""Juju Quickstart models."""
60
61=== renamed file 'quickstart/charms.py' => 'quickstart/models/charms.py'
62=== added file 'quickstart/models/envs.py'
63--- quickstart/models/envs.py 1970-01-01 00:00:00 +0000
64+++ quickstart/models/envs.py 2013-12-04 13:19:54 +0000
65@@ -0,0 +1,104 @@
66+# This file is part of the Juju Quickstart Plugin, which lets users set up a
67+# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
68+# Copyright (C) 2013 Canonical Ltd.
69+#
70+# This program is free software: you can redistribute it and/or modify it under
71+# the terms of the GNU Affero General Public License version 3, as published by
72+# the Free Software Foundation.
73+#
74+# This program is distributed in the hope that it will be useful, but WITHOUT
75+# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
76+# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
77+# Affero General Public License for more details.
78+#
79+# You should have received a copy of the GNU Affero General Public License
80+# along with this program. If not, see <http://www.gnu.org/licenses/>.
81+
82+"""Juju Quickstart environments management."""
83+
84+import os
85+import re
86+
87+import yaml
88+
89+from quickstart import utils
90+
91+
92+# Compile the regular expression used to parse the "juju switch" output.
93+_juju_switch_expression = re.compile(r'Current environment: "([\w-]+)"\n')
94+
95+
96+def get_default_env_name():
97+ """Return the current Juju environment name.
98+
99+ The environment name can be set either by
100+ - setting the JUJU_ENV environment variable;
101+ - using "juju switch my-env-name";
102+ - setting the default environment in the environments.yaml file.
103+ The former overrides the latter.
104+
105+ Return None if a default environment is not found.
106+ """
107+ env_name = os.getenv('JUJU_ENV', '').strip()
108+ if env_name:
109+ return env_name
110+ # XXX 2013-10-16 frankban bug=1193244:
111+ # Support the new behavior of juju-switch, currently under development:
112+ # the command will just output the environment name, or exit with an
113+ # error if no default environment is configured.
114+ # The "juju switch" command parses ~/.juju/current-environment file. If the
115+ # environment name is not found there, then it tries to retrieve the name
116+ # from the "default" section of the ~/.juju/environments.yaml file.
117+ retcode, output, _ = utils.call('juju', 'switch')
118+ if retcode:
119+ return None
120+ match = _juju_switch_expression.match(output)
121+ if match is not None:
122+ return match.groups()[0]
123+
124+
125+def parse_env_file(env_file, env_name):
126+ """Parse the provided Juju environments.yaml file.
127+
128+ Return a tuple containing the provider type and the admin secret associated
129+ with the given environment name.
130+
131+ Raise a ValueError if:
132+ - the environment file is not found;
133+ - the environment file contents are not parsable by YAML;
134+ - the YAML contents are not properly structured;
135+ - the environment named envname is not found;
136+ - the environment does not include the "type" field;
137+ - the environment does not include the "admin_secret" field.
138+ """
139+ # Load the Juju environments file.
140+ try:
141+ environments_file = open(env_file)
142+ except IOError as err:
143+ msg = 'unable to open environments file: {}'.format(err)
144+ raise ValueError(msg)
145+ # Parse the Juju environments file.
146+ try:
147+ environments = yaml.safe_load(environments_file)
148+ except Exception as err:
149+ msg = 'unable to parse environments file {}: {}'.format(env_file, err)
150+ raise ValueError(msg)
151+ # Retrieve the information about the current environment.
152+ try:
153+ environment = environments.get('environments', {}).get(env_name)
154+ except AttributeError as err:
155+ msg = 'invalid YAML contents in {}: {}'.format(env_file, environments)
156+ raise ValueError(msg)
157+ if environment is None:
158+ msg = 'environment {} not found in {}'.format(env_name, env_file)
159+ raise ValueError(msg)
160+ # Retrieve the provider type and the admin secret.
161+ env_type = environment.get('type')
162+ if env_type is None:
163+ msg = '{} provider type not found in {}'.format(env_name, env_file)
164+ raise ValueError(msg)
165+ admin_secret = environment.get('admin-secret')
166+ if admin_secret is None:
167+ msg = '{} admin secret not found in {}'.format(env_name, env_file)
168+ raise ValueError(msg)
169+ return env_type, admin_secret
170
171=== added directory 'quickstart/tests/models'
172=== added file 'quickstart/tests/models/__init__.py'
173=== renamed file 'quickstart/tests/test_charms.py' => 'quickstart/tests/models/test_charms.py'
174--- quickstart/tests/test_charms.py 2013-11-22 08:30:42 +0000
175+++ quickstart/tests/models/test_charms.py 2013-12-04 13:19:54 +0000
176@@ -18,7 +18,7 @@
177
178 import unittest
179
180-from quickstart import charms
181+from quickstart.models import charms
182 from quickstart.tests import helpers
183
184
185
186=== added file 'quickstart/tests/models/test_envs.py'
187--- quickstart/tests/models/test_envs.py 1970-01-01 00:00:00 +0000
188+++ quickstart/tests/models/test_envs.py 2013-12-04 13:19:54 +0000
189@@ -0,0 +1,136 @@
190+# This file is part of the Juju Quickstart Plugin, which lets users set up a
191+# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
192+# Copyright (C) 2013 Canonical Ltd.
193+#
194+# This program is free software: you can redistribute it and/or modify it under
195+# the terms of the GNU Affero General Public License version 3, as published by
196+# the Free Software Foundation.
197+#
198+# This program is distributed in the hope that it will be useful, but WITHOUT
199+# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
200+# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
201+# Affero General Public License for more details.
202+#
203+# You should have received a copy of the GNU Affero General Public License
204+# along with this program. If not, see <http://www.gnu.org/licenses/>.
205+
206+"""Tests for the Juju Quickstart environments management."""
207+
208+import unittest
209+
210+import mock
211+import yaml
212+
213+from quickstart.models import envs
214+from quickstart.tests import helpers
215+
216+
217+class TestGetDefaultEnvName(helpers.CallTestsMixin, unittest.TestCase):
218+
219+ def test_environment_variable(self):
220+ # The environment name is successfully returned if JUJU_ENV is set.
221+ with mock.patch('os.environ', {'JUJU_ENV': 'ec2'}):
222+ env_name = envs.get_default_env_name()
223+ self.assertEqual('ec2', env_name)
224+
225+ def test_empty_environment_variable(self):
226+ # The environment name is not found if JUJU_ENV is empty.
227+ with self.patch_call(1):
228+ with mock.patch('os.environ', {'JUJU_ENV': ' '}):
229+ env_name = envs.get_default_env_name()
230+ self.assertIsNone(env_name)
231+
232+ def test_no_environment_variable(self):
233+ # The environment name is not found if JUJU_ENV is not defined.
234+ with self.patch_call(1):
235+ with mock.patch('os.environ', {}):
236+ env_name = envs.get_default_env_name()
237+ self.assertIsNone(env_name)
238+
239+ def test_juju_switch(self):
240+ # The environment name is successfully returned if previously set using
241+ # the "juju switch" command.
242+ output = 'Current environment: "hp"\n'
243+ with self.patch_call(0, output=output) as mock_call:
244+ with mock.patch('os.environ', {}):
245+ env_name = envs.get_default_env_name()
246+ self.assertEqual('hp', env_name)
247+ mock_call.assert_called_once_with('juju', 'switch')
248+
249+ def test_juju_switch_failure(self):
250+ # The environment name is not found if "juju switch" returns an error.
251+ with self.patch_call(1) as mock_call:
252+ with mock.patch('os.environ', {}):
253+ env_name = envs.get_default_env_name()
254+ self.assertIsNone(env_name)
255+ mock_call.assert_called_once_with('juju', 'switch')
256+
257+ def test_juju_switch_nonsense(self):
258+ # The environment name is not found if "juju switch" goes crazy.
259+ with self.patch_call(0, output='Exterminate!') as mock_call:
260+ with mock.patch('os.environ', {}):
261+ env_name = envs.get_default_env_name()
262+ self.assertIsNone(env_name)
263+ mock_call.assert_called_once_with('juju', 'switch')
264+
265+
266+class TestParseEnvFile(
267+ helpers.EnvFileTestsMixin, helpers.ValueErrorTestsMixin,
268+ unittest.TestCase):
269+
270+ def test_no_file(self):
271+ # A ValueError is raised if the environments file is not found.
272+ expected = (
273+ 'unable to open environments file: '
274+ "[Errno 2] No such file or directory: '/no/such/file.yaml'"
275+ )
276+ with self.assert_value_error(expected):
277+ envs.parse_env_file('/no/such/file.yaml', 'ec2')
278+
279+ def test_invalid_yaml(self):
280+ # A ValueError is raised if the environments file is not a valid YAML.
281+ env_file = self.make_env_file(':')
282+ with self.assertRaises(ValueError) as context_manager:
283+ envs.parse_env_file(env_file, 'ec2')
284+ expected = 'unable to parse environments file {}'.format(env_file)
285+ self.assertIn(expected, str(context_manager.exception))
286+
287+ def test_invalid_yaml_contents(self):
288+ # A ValueError is raised if the environments file is not well formed.
289+ env_file = self.make_env_file('a-string')
290+ expected = 'invalid YAML contents in {}: a-string'.format(env_file)
291+ with self.assert_value_error(expected):
292+ envs.parse_env_file(env_file, 'ec2')
293+
294+ def test_no_env(self):
295+ # A ValueError is raised if the environment is not found in the YAML.
296+ contents = yaml.safe_dump({'environments': {'local': {}}})
297+ env_file = self.make_env_file(contents)
298+ expected = 'environment ec2 not found in {}'.format(env_file)
299+ with self.assert_value_error(expected):
300+ envs.parse_env_file(env_file, 'ec2')
301+
302+ def test_no_provider_type(self):
303+ # A ValueError is raised if the provider type is not included in the
304+ # environment info.
305+ contents = yaml.safe_dump({'environments': {'aws': {}}})
306+ env_file = self.make_env_file(contents)
307+ expected = 'aws provider type not found in {}'.format(env_file)
308+ with self.assert_value_error(expected):
309+ envs.parse_env_file(env_file, 'aws')
310+
311+ def test_no_admin_secret(self):
312+ # A ValueError is raised if the admin secret is not included in the
313+ # environment info.
314+ contents = yaml.safe_dump({'environments': {'aws': {'type': 'ec2'}}})
315+ env_file = self.make_env_file(contents)
316+ expected = 'aws admin secret not found in {}'.format(env_file)
317+ with self.assert_value_error(expected):
318+ envs.parse_env_file(env_file, 'aws')
319+
320+ def test_success(self):
321+ # The environment provider type and admin secret are returned.
322+ env_file = self.make_env_file()
323+ env_type, admin_secret = envs.parse_env_file(env_file, 'aws')
324+ self.assertEqual('ec2', env_type)
325+ self.assertEqual('Secret!', admin_secret)
326
327=== modified file 'quickstart/tests/test_manage.py'
328--- quickstart/tests/test_manage.py 2013-12-02 21:36:04 +0000
329+++ quickstart/tests/test_manage.py 2013-12-04 13:19:54 +0000
330@@ -317,7 +317,7 @@
331 and it is also possible to simulate an arbitrary environment name.
332 """
333 mock_get_default_env_name = mock.Mock(return_value=env_name)
334- path = 'quickstart.manage.utils.get_default_env_name'
335+ path = 'quickstart.manage.envs.get_default_env_name'
336 return mock.patch(path, mock_get_default_env_name)
337
338 def call_setup(self, args, env_name='ec2', exit_called=True):
339@@ -358,12 +358,11 @@
340 output = stdout_write.call_args[0][0]
341 self.assertIn('The name of the Juju environment to use (hp)\n', output)
342
343- def test_help_with_init_environment(self):
344+ def test_init_environment(self):
345 # The program calls ensure_environments if env_name is None.
346 with mock.patch('quickstart.app.ensure_environments',
347 return_value='local') as ensure_environments:
348- self.call_setup(['/path/to/bundle.file'], env_name=None,
349- exit_called=False)
350+ self.call_setup([], env_name=None, exit_called=False)
351 self.assertTrue(ensure_environments.called)
352
353 def test_description(self):
354
355=== modified file 'quickstart/tests/test_utils.py'
356--- quickstart/tests/test_utils.py 2013-11-26 09:45:17 +0000
357+++ quickstart/tests/test_utils.py 2013-12-04 13:19:54 +0000
358@@ -235,55 +235,6 @@
359 'unable to find the charm URL', str(context_manager.exception))
360
361
362-class TestGetDefaultEnvName(helpers.CallTestsMixin, unittest.TestCase):
363-
364- def test_environment_variable(self):
365- # The environment name is successfully returned if JUJU_ENV is set.
366- with mock.patch('os.environ', {'JUJU_ENV': 'ec2'}):
367- env_name = utils.get_default_env_name()
368- self.assertEqual('ec2', env_name)
369-
370- def test_empty_environment_variable(self):
371- # The environment name is not found if JUJU_ENV is empty.
372- with self.patch_call(1):
373- with mock.patch('os.environ', {'JUJU_ENV': ' '}):
374- env_name = utils.get_default_env_name()
375- self.assertIsNone(env_name)
376-
377- def test_no_environment_variable(self):
378- # The environment name is not found if JUJU_ENV is not defined.
379- with self.patch_call(1):
380- with mock.patch('os.environ', {}):
381- env_name = utils.get_default_env_name()
382- self.assertIsNone(env_name)
383-
384- def test_juju_switch(self):
385- # The environment name is successfully returned if previously set using
386- # the "juju switch" command.
387- output = 'Current environment: "hp"\n'
388- with self.patch_call(0, output=output) as mock_call:
389- with mock.patch('os.environ', {}):
390- env_name = utils.get_default_env_name()
391- self.assertEqual('hp', env_name)
392- mock_call.assert_called_once_with('juju', 'switch')
393-
394- def test_juju_switch_failure(self):
395- # The environment name is not found if "juju switch" returns an error.
396- with self.patch_call(1) as mock_call:
397- with mock.patch('os.environ', {}):
398- env_name = utils.get_default_env_name()
399- self.assertIsNone(env_name)
400- mock_call.assert_called_once_with('juju', 'switch')
401-
402- def test_juju_switch_nonsense(self):
403- # The environment name is not found if "juju switch" goes crazy.
404- with self.patch_call(0, output='Exterminate!') as mock_call:
405- with mock.patch('os.environ', {}):
406- env_name = utils.get_default_env_name()
407- self.assertIsNone(env_name)
408- mock_call.assert_called_once_with('juju', 'switch')
409-
410-
411 class TestGetServiceInfo(helpers.WatcherDataTestsMixin, unittest.TestCase):
412
413 def test_service_and_unit(self):
414@@ -487,68 +438,6 @@
415 self.assert_bundle('mybundle', ['mysql', 'wordpress'], contents)
416
417
418-class TestParseEnvFile(
419- helpers.EnvFileTestsMixin, helpers.ValueErrorTestsMixin,
420- unittest.TestCase):
421-
422- def test_no_file(self):
423- # A ValueError is raised if the environments file is not found.
424- expected = (
425- 'unable to open environments file: '
426- "[Errno 2] No such file or directory: '/no/such/file.yaml'"
427- )
428- with self.assert_value_error(expected):
429- utils.parse_env_file('/no/such/file.yaml', 'ec2')
430-
431- def test_invalid_yaml(self):
432- # A ValueError is raised if the environments file is not a valid YAML.
433- env_file = self.make_env_file(':')
434- with self.assertRaises(ValueError) as context_manager:
435- utils.parse_env_file(env_file, 'ec2')
436- expected = 'unable to parse environments file {}'.format(env_file)
437- self.assertIn(expected, str(context_manager.exception))
438-
439- def test_invalid_yaml_contents(self):
440- # A ValueError is raised if the environments file is not well formed.
441- env_file = self.make_env_file('a-string')
442- expected = 'invalid YAML contents in {}: a-string'.format(env_file)
443- with self.assert_value_error(expected):
444- utils.parse_env_file(env_file, 'ec2')
445-
446- def test_no_env(self):
447- # A ValueError is raised if the environment is not found in the YAML.
448- contents = yaml.safe_dump({'environments': {'local': {}}})
449- env_file = self.make_env_file(contents)
450- expected = 'environment ec2 not found in {}'.format(env_file)
451- with self.assert_value_error(expected):
452- utils.parse_env_file(env_file, 'ec2')
453-
454- def test_no_provider_type(self):
455- # A ValueError is raised if the provider type is not included in the
456- # environment info.
457- contents = yaml.safe_dump({'environments': {'aws': {}}})
458- env_file = self.make_env_file(contents)
459- expected = 'aws provider type not found in {}'.format(env_file)
460- with self.assert_value_error(expected):
461- utils.parse_env_file(env_file, 'aws')
462-
463- def test_no_admin_secret(self):
464- # A ValueError is raised if the admin secret is not included in the
465- # environment info.
466- contents = yaml.safe_dump({'environments': {'aws': {'type': 'ec2'}}})
467- env_file = self.make_env_file(contents)
468- expected = 'aws admin secret not found in {}'.format(env_file)
469- with self.assert_value_error(expected):
470- utils.parse_env_file(env_file, 'aws')
471-
472- def test_success(self):
473- # The environment provider type and admin secret are returned.
474- env_file = self.make_env_file()
475- env_type, admin_secret = utils.parse_env_file(env_file, 'aws')
476- self.assertEqual('ec2', env_type)
477- self.assertEqual('Secret!', admin_secret)
478-
479-
480 class TestParseStatusOutput(helpers.ValueErrorTestsMixin, unittest.TestCase):
481
482 def test_invalid_yaml(self):
483
484=== modified file 'quickstart/utils.py'
485--- quickstart/utils.py 2013-11-25 18:07:47 +0000
486+++ quickstart/utils.py 2013-12-04 13:19:54 +0000
487@@ -21,22 +21,15 @@
488 import httplib
489 import json
490 import logging
491-import os
492 import pipes
493-import re
494 import socket
495 import subprocess
496 import urllib2
497
498 import yaml
499
500-from quickstart import (
501- charms,
502- settings
503-)
504-
505-# Compile the regular expression used to parse the "juju switch" output.
506-_juju_switch_expression = re.compile(r'Current environment: "([\w-]+)"\n')
507+from quickstart import settings
508+from quickstart.models import charms
509
510
511 def add_apt_repository(repository):
512@@ -134,35 +127,6 @@
513 return charm_url
514
515
516-def get_default_env_name():
517- """Return the current Juju environment name.
518-
519- The environment name can be set either by
520- - setting the JUJU_ENV environment variable;
521- - using "juju switch my-env-name";
522- - setting the default environment in the environments.yaml file.
523- The former overrides the latter.
524-
525- Return None if a default environment is not found.
526- """
527- env_name = os.getenv('JUJU_ENV', '').strip()
528- if env_name:
529- return env_name
530- # XXX 2013-10-16 frankban bug=1193244:
531- # Support the new behavior of juju-switch, currently under development:
532- # the command will just output the environment name, or exit with an
533- # error if no default environment is configured.
534- # The "juju switch" command parses ~/.juju/current-environment file. If the
535- # environment name is not found there, then it tries to retrieve the name
536- # from the "default" section of the ~/.juju/environments.yaml file.
537- retcode, output, _ = call('juju', 'switch')
538- if retcode:
539- return None
540- match = _juju_switch_expression.match(output)
541- if match is not None:
542- return match.groups()[0]
543-
544-
545 def get_service_info(status, service_name):
546 """Retrieve information on the given service and on its first alive unit.
547
548@@ -258,53 +222,6 @@
549 return bundle_name, bundle_services
550
551
552-def parse_env_file(env_file, env_name):
553- """Parse the provided Juju environments.yaml file.
554-
555- Return a tuple containing the provider type and the admin secret associated
556- with the given environment name.
557-
558- Raise a ValueError if:
559- - the environment file is not found;
560- - the environment file contents are not parsable by YAML;
561- - the YAML contents are not properly structured;
562- - the environment named envname is not found;
563- - the environment does not include the "type" field;
564- - the environment does not include the "admin_secret" field.
565- """
566- # Load the Juju environments file.
567- try:
568- environments_file = open(env_file)
569- except IOError as err:
570- msg = 'unable to open environments file: {}'.format(err)
571- raise ValueError(msg)
572- # Parse the Juju environments file.
573- try:
574- environments = yaml.safe_load(environments_file)
575- except Exception as err:
576- msg = 'unable to parse environments file {}: {}'.format(env_file, err)
577- raise ValueError(msg)
578- # Retrieve the information about the current environment.
579- try:
580- environment = environments.get('environments', {}).get(env_name)
581- except AttributeError as err:
582- msg = 'invalid YAML contents in {}: {}'.format(env_file, environments)
583- raise ValueError(msg)
584- if environment is None:
585- msg = 'environment {} not found in {}'.format(env_name, env_file)
586- raise ValueError(msg)
587- # Retrieve the provider type and the admin secret.
588- env_type = environment.get('type')
589- if env_type is None:
590- msg = '{} provider type not found in {}'.format(env_name, env_file)
591- raise ValueError(msg)
592- admin_secret = environment.get('admin-secret')
593- if admin_secret is None:
594- msg = '{} admin secret not found in {}'.format(env_name, env_file)
595- raise ValueError(msg)
596- return env_type, admin_secret
597-
598-
599 def parse_status_output(output):
600 """Parse the output of juju status.
601

Subscribers

People subscribed via source and target branches