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
=== modified file 'quickstart/manage.py'
--- quickstart/manage.py 2013-12-02 21:36:04 +0000
+++ quickstart/manage.py 2013-12-04 13:19:54 +0000
@@ -25,10 +25,13 @@
25import quickstart25import quickstart
26from quickstart import (26from quickstart import (
27 app,27 app,
28 charms,
29 settings,28 settings,
30 utils,29 utils,
31)30)
31from quickstart.models import (
32 charms,
33 envs,
34)
3235
3336
34version = quickstart.get_version()37version = quickstart.get_version()
@@ -144,7 +147,7 @@
144 )147 )
145 # Validate the environment file.148 # Validate the environment file.
146 try:149 try:
147 env_type, admin_secret = utils.parse_env_file(env_file, env_name)150 env_type, admin_secret = envs.parse_env_file(env_file, env_name)
148 except ValueError as err:151 except ValueError as err:
149 return parser.error(str(err))152 return parser.error(str(err))
150 # Update the options namespace with the new values.153 # Update the options namespace with the new values.
@@ -193,7 +196,7 @@
193196
194 Exit with an error if the provided arguments are not valid.197 Exit with an error if the provided arguments are not valid.
195 """198 """
196 default_env_name = utils.get_default_env_name()199 default_env_name = envs.get_default_env_name()
197 # Define the help message for the --environment option.200 # Define the help message for the --environment option.
198 env_help = 'The name of the Juju environment to use'201 env_help = 'The name of the Juju environment to use'
199 # XXX 2013-12-02 makyo:202 # XXX 2013-12-02 makyo:
200203
=== added directory 'quickstart/models'
=== added file 'quickstart/models/__init__.py'
--- quickstart/models/__init__.py 1970-01-01 00:00:00 +0000
+++ quickstart/models/__init__.py 2013-12-04 13:19:54 +0000
@@ -0,0 +1,17 @@
1# This file is part of the Juju Quickstart Plugin, which lets users set up a
2# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
3# Copyright (C) 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it under
6# the terms of the GNU Affero General Public License version 3, as published by
7# the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12# Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""Juju Quickstart models."""
018
=== renamed file 'quickstart/charms.py' => 'quickstart/models/charms.py'
=== added file 'quickstart/models/envs.py'
--- quickstart/models/envs.py 1970-01-01 00:00:00 +0000
+++ quickstart/models/envs.py 2013-12-04 13:19:54 +0000
@@ -0,0 +1,104 @@
1# This file is part of the Juju Quickstart Plugin, which lets users set up a
2# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
3# Copyright (C) 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it under
6# the terms of the GNU Affero General Public License version 3, as published by
7# the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12# Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""Juju Quickstart environments management."""
18
19import os
20import re
21
22import yaml
23
24from quickstart import utils
25
26
27# Compile the regular expression used to parse the "juju switch" output.
28_juju_switch_expression = re.compile(r'Current environment: "([\w-]+)"\n')
29
30
31def get_default_env_name():
32 """Return the current Juju environment name.
33
34 The environment name can be set either by
35 - setting the JUJU_ENV environment variable;
36 - using "juju switch my-env-name";
37 - setting the default environment in the environments.yaml file.
38 The former overrides the latter.
39
40 Return None if a default environment is not found.
41 """
42 env_name = os.getenv('JUJU_ENV', '').strip()
43 if env_name:
44 return env_name
45 # XXX 2013-10-16 frankban bug=1193244:
46 # Support the new behavior of juju-switch, currently under development:
47 # the command will just output the environment name, or exit with an
48 # error if no default environment is configured.
49 # The "juju switch" command parses ~/.juju/current-environment file. If the
50 # environment name is not found there, then it tries to retrieve the name
51 # from the "default" section of the ~/.juju/environments.yaml file.
52 retcode, output, _ = utils.call('juju', 'switch')
53 if retcode:
54 return None
55 match = _juju_switch_expression.match(output)
56 if match is not None:
57 return match.groups()[0]
58
59
60def parse_env_file(env_file, env_name):
61 """Parse the provided Juju environments.yaml file.
62
63 Return a tuple containing the provider type and the admin secret associated
64 with the given environment name.
65
66 Raise a ValueError if:
67 - the environment file is not found;
68 - the environment file contents are not parsable by YAML;
69 - the YAML contents are not properly structured;
70 - the environment named envname is not found;
71 - the environment does not include the "type" field;
72 - the environment does not include the "admin_secret" field.
73 """
74 # Load the Juju environments file.
75 try:
76 environments_file = open(env_file)
77 except IOError as err:
78 msg = 'unable to open environments file: {}'.format(err)
79 raise ValueError(msg)
80 # Parse the Juju environments file.
81 try:
82 environments = yaml.safe_load(environments_file)
83 except Exception as err:
84 msg = 'unable to parse environments file {}: {}'.format(env_file, err)
85 raise ValueError(msg)
86 # Retrieve the information about the current environment.
87 try:
88 environment = environments.get('environments', {}).get(env_name)
89 except AttributeError as err:
90 msg = 'invalid YAML contents in {}: {}'.format(env_file, environments)
91 raise ValueError(msg)
92 if environment is None:
93 msg = 'environment {} not found in {}'.format(env_name, env_file)
94 raise ValueError(msg)
95 # Retrieve the provider type and the admin secret.
96 env_type = environment.get('type')
97 if env_type is None:
98 msg = '{} provider type not found in {}'.format(env_name, env_file)
99 raise ValueError(msg)
100 admin_secret = environment.get('admin-secret')
101 if admin_secret is None:
102 msg = '{} admin secret not found in {}'.format(env_name, env_file)
103 raise ValueError(msg)
104 return env_type, admin_secret
0105
=== added directory 'quickstart/tests/models'
=== added file 'quickstart/tests/models/__init__.py'
=== renamed file 'quickstart/tests/test_charms.py' => 'quickstart/tests/models/test_charms.py'
--- quickstart/tests/test_charms.py 2013-11-22 08:30:42 +0000
+++ quickstart/tests/models/test_charms.py 2013-12-04 13:19:54 +0000
@@ -18,7 +18,7 @@
1818
19import unittest19import unittest
2020
21from quickstart import charms21from quickstart.models import charms
22from quickstart.tests import helpers22from quickstart.tests import helpers
2323
2424
2525
=== added file 'quickstart/tests/models/test_envs.py'
--- quickstart/tests/models/test_envs.py 1970-01-01 00:00:00 +0000
+++ quickstart/tests/models/test_envs.py 2013-12-04 13:19:54 +0000
@@ -0,0 +1,136 @@
1# This file is part of the Juju Quickstart Plugin, which lets users set up a
2# Juju environment in very few steps (https://launchpad.net/juju-quickstart).
3# Copyright (C) 2013 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it under
6# the terms of the GNU Affero General Public License version 3, as published by
7# the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
11# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12# Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17"""Tests for the Juju Quickstart environments management."""
18
19import unittest
20
21import mock
22import yaml
23
24from quickstart.models import envs
25from quickstart.tests import helpers
26
27
28class TestGetDefaultEnvName(helpers.CallTestsMixin, unittest.TestCase):
29
30 def test_environment_variable(self):
31 # The environment name is successfully returned if JUJU_ENV is set.
32 with mock.patch('os.environ', {'JUJU_ENV': 'ec2'}):
33 env_name = envs.get_default_env_name()
34 self.assertEqual('ec2', env_name)
35
36 def test_empty_environment_variable(self):
37 # The environment name is not found if JUJU_ENV is empty.
38 with self.patch_call(1):
39 with mock.patch('os.environ', {'JUJU_ENV': ' '}):
40 env_name = envs.get_default_env_name()
41 self.assertIsNone(env_name)
42
43 def test_no_environment_variable(self):
44 # The environment name is not found if JUJU_ENV is not defined.
45 with self.patch_call(1):
46 with mock.patch('os.environ', {}):
47 env_name = envs.get_default_env_name()
48 self.assertIsNone(env_name)
49
50 def test_juju_switch(self):
51 # The environment name is successfully returned if previously set using
52 # the "juju switch" command.
53 output = 'Current environment: "hp"\n'
54 with self.patch_call(0, output=output) as mock_call:
55 with mock.patch('os.environ', {}):
56 env_name = envs.get_default_env_name()
57 self.assertEqual('hp', env_name)
58 mock_call.assert_called_once_with('juju', 'switch')
59
60 def test_juju_switch_failure(self):
61 # The environment name is not found if "juju switch" returns an error.
62 with self.patch_call(1) as mock_call:
63 with mock.patch('os.environ', {}):
64 env_name = envs.get_default_env_name()
65 self.assertIsNone(env_name)
66 mock_call.assert_called_once_with('juju', 'switch')
67
68 def test_juju_switch_nonsense(self):
69 # The environment name is not found if "juju switch" goes crazy.
70 with self.patch_call(0, output='Exterminate!') as mock_call:
71 with mock.patch('os.environ', {}):
72 env_name = envs.get_default_env_name()
73 self.assertIsNone(env_name)
74 mock_call.assert_called_once_with('juju', 'switch')
75
76
77class TestParseEnvFile(
78 helpers.EnvFileTestsMixin, helpers.ValueErrorTestsMixin,
79 unittest.TestCase):
80
81 def test_no_file(self):
82 # A ValueError is raised if the environments file is not found.
83 expected = (
84 'unable to open environments file: '
85 "[Errno 2] No such file or directory: '/no/such/file.yaml'"
86 )
87 with self.assert_value_error(expected):
88 envs.parse_env_file('/no/such/file.yaml', 'ec2')
89
90 def test_invalid_yaml(self):
91 # A ValueError is raised if the environments file is not a valid YAML.
92 env_file = self.make_env_file(':')
93 with self.assertRaises(ValueError) as context_manager:
94 envs.parse_env_file(env_file, 'ec2')
95 expected = 'unable to parse environments file {}'.format(env_file)
96 self.assertIn(expected, str(context_manager.exception))
97
98 def test_invalid_yaml_contents(self):
99 # A ValueError is raised if the environments file is not well formed.
100 env_file = self.make_env_file('a-string')
101 expected = 'invalid YAML contents in {}: a-string'.format(env_file)
102 with self.assert_value_error(expected):
103 envs.parse_env_file(env_file, 'ec2')
104
105 def test_no_env(self):
106 # A ValueError is raised if the environment is not found in the YAML.
107 contents = yaml.safe_dump({'environments': {'local': {}}})
108 env_file = self.make_env_file(contents)
109 expected = 'environment ec2 not found in {}'.format(env_file)
110 with self.assert_value_error(expected):
111 envs.parse_env_file(env_file, 'ec2')
112
113 def test_no_provider_type(self):
114 # A ValueError is raised if the provider type is not included in the
115 # environment info.
116 contents = yaml.safe_dump({'environments': {'aws': {}}})
117 env_file = self.make_env_file(contents)
118 expected = 'aws provider type not found in {}'.format(env_file)
119 with self.assert_value_error(expected):
120 envs.parse_env_file(env_file, 'aws')
121
122 def test_no_admin_secret(self):
123 # A ValueError is raised if the admin secret is not included in the
124 # environment info.
125 contents = yaml.safe_dump({'environments': {'aws': {'type': 'ec2'}}})
126 env_file = self.make_env_file(contents)
127 expected = 'aws admin secret not found in {}'.format(env_file)
128 with self.assert_value_error(expected):
129 envs.parse_env_file(env_file, 'aws')
130
131 def test_success(self):
132 # The environment provider type and admin secret are returned.
133 env_file = self.make_env_file()
134 env_type, admin_secret = envs.parse_env_file(env_file, 'aws')
135 self.assertEqual('ec2', env_type)
136 self.assertEqual('Secret!', admin_secret)
0137
=== modified file 'quickstart/tests/test_manage.py'
--- quickstart/tests/test_manage.py 2013-12-02 21:36:04 +0000
+++ quickstart/tests/test_manage.py 2013-12-04 13:19:54 +0000
@@ -317,7 +317,7 @@
317 and it is also possible to simulate an arbitrary environment name.317 and it is also possible to simulate an arbitrary environment name.
318 """318 """
319 mock_get_default_env_name = mock.Mock(return_value=env_name)319 mock_get_default_env_name = mock.Mock(return_value=env_name)
320 path = 'quickstart.manage.utils.get_default_env_name'320 path = 'quickstart.manage.envs.get_default_env_name'
321 return mock.patch(path, mock_get_default_env_name)321 return mock.patch(path, mock_get_default_env_name)
322322
323 def call_setup(self, args, env_name='ec2', exit_called=True):323 def call_setup(self, args, env_name='ec2', exit_called=True):
@@ -358,12 +358,11 @@
358 output = stdout_write.call_args[0][0]358 output = stdout_write.call_args[0][0]
359 self.assertIn('The name of the Juju environment to use (hp)\n', output)359 self.assertIn('The name of the Juju environment to use (hp)\n', output)
360360
361 def test_help_with_init_environment(self):361 def test_init_environment(self):
362 # The program calls ensure_environments if env_name is None.362 # The program calls ensure_environments if env_name is None.
363 with mock.patch('quickstart.app.ensure_environments',363 with mock.patch('quickstart.app.ensure_environments',
364 return_value='local') as ensure_environments:364 return_value='local') as ensure_environments:
365 self.call_setup(['/path/to/bundle.file'], env_name=None,365 self.call_setup([], env_name=None, exit_called=False)
366 exit_called=False)
367 self.assertTrue(ensure_environments.called)366 self.assertTrue(ensure_environments.called)
368367
369 def test_description(self):368 def test_description(self):
370369
=== modified file 'quickstart/tests/test_utils.py'
--- quickstart/tests/test_utils.py 2013-11-26 09:45:17 +0000
+++ quickstart/tests/test_utils.py 2013-12-04 13:19:54 +0000
@@ -235,55 +235,6 @@
235 'unable to find the charm URL', str(context_manager.exception))235 'unable to find the charm URL', str(context_manager.exception))
236236
237237
238class TestGetDefaultEnvName(helpers.CallTestsMixin, unittest.TestCase):
239
240 def test_environment_variable(self):
241 # The environment name is successfully returned if JUJU_ENV is set.
242 with mock.patch('os.environ', {'JUJU_ENV': 'ec2'}):
243 env_name = utils.get_default_env_name()
244 self.assertEqual('ec2', env_name)
245
246 def test_empty_environment_variable(self):
247 # The environment name is not found if JUJU_ENV is empty.
248 with self.patch_call(1):
249 with mock.patch('os.environ', {'JUJU_ENV': ' '}):
250 env_name = utils.get_default_env_name()
251 self.assertIsNone(env_name)
252
253 def test_no_environment_variable(self):
254 # The environment name is not found if JUJU_ENV is not defined.
255 with self.patch_call(1):
256 with mock.patch('os.environ', {}):
257 env_name = utils.get_default_env_name()
258 self.assertIsNone(env_name)
259
260 def test_juju_switch(self):
261 # The environment name is successfully returned if previously set using
262 # the "juju switch" command.
263 output = 'Current environment: "hp"\n'
264 with self.patch_call(0, output=output) as mock_call:
265 with mock.patch('os.environ', {}):
266 env_name = utils.get_default_env_name()
267 self.assertEqual('hp', env_name)
268 mock_call.assert_called_once_with('juju', 'switch')
269
270 def test_juju_switch_failure(self):
271 # The environment name is not found if "juju switch" returns an error.
272 with self.patch_call(1) as mock_call:
273 with mock.patch('os.environ', {}):
274 env_name = utils.get_default_env_name()
275 self.assertIsNone(env_name)
276 mock_call.assert_called_once_with('juju', 'switch')
277
278 def test_juju_switch_nonsense(self):
279 # The environment name is not found if "juju switch" goes crazy.
280 with self.patch_call(0, output='Exterminate!') as mock_call:
281 with mock.patch('os.environ', {}):
282 env_name = utils.get_default_env_name()
283 self.assertIsNone(env_name)
284 mock_call.assert_called_once_with('juju', 'switch')
285
286
287class TestGetServiceInfo(helpers.WatcherDataTestsMixin, unittest.TestCase):238class TestGetServiceInfo(helpers.WatcherDataTestsMixin, unittest.TestCase):
288239
289 def test_service_and_unit(self):240 def test_service_and_unit(self):
@@ -487,68 +438,6 @@
487 self.assert_bundle('mybundle', ['mysql', 'wordpress'], contents)438 self.assert_bundle('mybundle', ['mysql', 'wordpress'], contents)
488439
489440
490class TestParseEnvFile(
491 helpers.EnvFileTestsMixin, helpers.ValueErrorTestsMixin,
492 unittest.TestCase):
493
494 def test_no_file(self):
495 # A ValueError is raised if the environments file is not found.
496 expected = (
497 'unable to open environments file: '
498 "[Errno 2] No such file or directory: '/no/such/file.yaml'"
499 )
500 with self.assert_value_error(expected):
501 utils.parse_env_file('/no/such/file.yaml', 'ec2')
502
503 def test_invalid_yaml(self):
504 # A ValueError is raised if the environments file is not a valid YAML.
505 env_file = self.make_env_file(':')
506 with self.assertRaises(ValueError) as context_manager:
507 utils.parse_env_file(env_file, 'ec2')
508 expected = 'unable to parse environments file {}'.format(env_file)
509 self.assertIn(expected, str(context_manager.exception))
510
511 def test_invalid_yaml_contents(self):
512 # A ValueError is raised if the environments file is not well formed.
513 env_file = self.make_env_file('a-string')
514 expected = 'invalid YAML contents in {}: a-string'.format(env_file)
515 with self.assert_value_error(expected):
516 utils.parse_env_file(env_file, 'ec2')
517
518 def test_no_env(self):
519 # A ValueError is raised if the environment is not found in the YAML.
520 contents = yaml.safe_dump({'environments': {'local': {}}})
521 env_file = self.make_env_file(contents)
522 expected = 'environment ec2 not found in {}'.format(env_file)
523 with self.assert_value_error(expected):
524 utils.parse_env_file(env_file, 'ec2')
525
526 def test_no_provider_type(self):
527 # A ValueError is raised if the provider type is not included in the
528 # environment info.
529 contents = yaml.safe_dump({'environments': {'aws': {}}})
530 env_file = self.make_env_file(contents)
531 expected = 'aws provider type not found in {}'.format(env_file)
532 with self.assert_value_error(expected):
533 utils.parse_env_file(env_file, 'aws')
534
535 def test_no_admin_secret(self):
536 # A ValueError is raised if the admin secret is not included in the
537 # environment info.
538 contents = yaml.safe_dump({'environments': {'aws': {'type': 'ec2'}}})
539 env_file = self.make_env_file(contents)
540 expected = 'aws admin secret not found in {}'.format(env_file)
541 with self.assert_value_error(expected):
542 utils.parse_env_file(env_file, 'aws')
543
544 def test_success(self):
545 # The environment provider type and admin secret are returned.
546 env_file = self.make_env_file()
547 env_type, admin_secret = utils.parse_env_file(env_file, 'aws')
548 self.assertEqual('ec2', env_type)
549 self.assertEqual('Secret!', admin_secret)
550
551
552class TestParseStatusOutput(helpers.ValueErrorTestsMixin, unittest.TestCase):441class TestParseStatusOutput(helpers.ValueErrorTestsMixin, unittest.TestCase):
553442
554 def test_invalid_yaml(self):443 def test_invalid_yaml(self):
555444
=== modified file 'quickstart/utils.py'
--- quickstart/utils.py 2013-11-25 18:07:47 +0000
+++ quickstart/utils.py 2013-12-04 13:19:54 +0000
@@ -21,22 +21,15 @@
21import httplib21import httplib
22import json22import json
23import logging23import logging
24import os
25import pipes24import pipes
26import re
27import socket25import socket
28import subprocess26import subprocess
29import urllib227import urllib2
3028
31import yaml29import yaml
3230
33from quickstart import (31from quickstart import settings
34 charms,32from quickstart.models import charms
35 settings
36)
37
38# Compile the regular expression used to parse the "juju switch" output.
39_juju_switch_expression = re.compile(r'Current environment: "([\w-]+)"\n')
4033
4134
42def add_apt_repository(repository):35def add_apt_repository(repository):
@@ -134,35 +127,6 @@
134 return charm_url127 return charm_url
135128
136129
137def get_default_env_name():
138 """Return the current Juju environment name.
139
140 The environment name can be set either by
141 - setting the JUJU_ENV environment variable;
142 - using "juju switch my-env-name";
143 - setting the default environment in the environments.yaml file.
144 The former overrides the latter.
145
146 Return None if a default environment is not found.
147 """
148 env_name = os.getenv('JUJU_ENV', '').strip()
149 if env_name:
150 return env_name
151 # XXX 2013-10-16 frankban bug=1193244:
152 # Support the new behavior of juju-switch, currently under development:
153 # the command will just output the environment name, or exit with an
154 # error if no default environment is configured.
155 # The "juju switch" command parses ~/.juju/current-environment file. If the
156 # environment name is not found there, then it tries to retrieve the name
157 # from the "default" section of the ~/.juju/environments.yaml file.
158 retcode, output, _ = call('juju', 'switch')
159 if retcode:
160 return None
161 match = _juju_switch_expression.match(output)
162 if match is not None:
163 return match.groups()[0]
164
165
166def get_service_info(status, service_name):130def get_service_info(status, service_name):
167 """Retrieve information on the given service and on its first alive unit.131 """Retrieve information on the given service and on its first alive unit.
168132
@@ -258,53 +222,6 @@
258 return bundle_name, bundle_services222 return bundle_name, bundle_services
259223
260224
261def parse_env_file(env_file, env_name):
262 """Parse the provided Juju environments.yaml file.
263
264 Return a tuple containing the provider type and the admin secret associated
265 with the given environment name.
266
267 Raise a ValueError if:
268 - the environment file is not found;
269 - the environment file contents are not parsable by YAML;
270 - the YAML contents are not properly structured;
271 - the environment named envname is not found;
272 - the environment does not include the "type" field;
273 - the environment does not include the "admin_secret" field.
274 """
275 # Load the Juju environments file.
276 try:
277 environments_file = open(env_file)
278 except IOError as err:
279 msg = 'unable to open environments file: {}'.format(err)
280 raise ValueError(msg)
281 # Parse the Juju environments file.
282 try:
283 environments = yaml.safe_load(environments_file)
284 except Exception as err:
285 msg = 'unable to parse environments file {}: {}'.format(env_file, err)
286 raise ValueError(msg)
287 # Retrieve the information about the current environment.
288 try:
289 environment = environments.get('environments', {}).get(env_name)
290 except AttributeError as err:
291 msg = 'invalid YAML contents in {}: {}'.format(env_file, environments)
292 raise ValueError(msg)
293 if environment is None:
294 msg = 'environment {} not found in {}'.format(env_name, env_file)
295 raise ValueError(msg)
296 # Retrieve the provider type and the admin secret.
297 env_type = environment.get('type')
298 if env_type is None:
299 msg = '{} provider type not found in {}'.format(env_name, env_file)
300 raise ValueError(msg)
301 admin_secret = environment.get('admin-secret')
302 if admin_secret is None:
303 msg = '{} admin secret not found in {}'.format(env_name, env_file)
304 raise ValueError(msg)
305 return env_type, admin_secret
306
307
308def parse_status_output(output):225def parse_status_output(output):
309 """Parse the output of juju status.226 """Parse the output of juju status.
310227

Subscribers

People subscribed via source and target branches