Merge lp:~frankban/juju-quickstart/jenv-env into lp:juju-quickstart

Proposed by Francesco Banconi
Status: Merged
Merged at revision: 107
Proposed branch: lp:~frankban/juju-quickstart/jenv-env
Merge into: lp:juju-quickstart
Diff against target: 414 lines (+171/-44)
6 files modified
quickstart/app.py (+8/-8)
quickstart/manage.py (+6/-4)
quickstart/models/jenv.py (+69/-2)
quickstart/tests/models/test_jenv.py (+57/-4)
quickstart/tests/test_app.py (+26/-21)
quickstart/tests/test_manage.py (+5/-5)
To merge this branch: bzr merge lp:~frankban/juju-quickstart/jenv-env
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+244772@code.launchpad.net

Description of the change

Use both credentials to connect to Juju.

Use both the user name and password when connecting
to the Juju WebSocket API.

Update the jenv models to reflect what we expect to
find in the jenv file.

QA:
- use quickstart as usual
  (.venv/bin/python juju-quickstart ...);
- the user is now printed to stdout;
- the environment and the GUI log in correctly,
  in the case the environment is bootstrapped by
  quickstart or already there.

https://codereview.appspot.com/190060043/

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

Reviewers: mp+244772_code.launchpad.net,

Message:
Please take a look.

Description:
Use both credentials to connect to Juju.

Use both the user name and password when connecting
to the Juju WebSocket API.

Update the jenv models to reflect what we expect to
find in the jenv file.

QA:
- use quickstart as usual
   (.venv/bin/python juju-quickstart ...);
- the user is now printed to stdout;
- the environment and the GUI log in correctly,
   in the case the environment is bootstrapped by
   quickstart or already there.

https://code.launchpad.net/~frankban/juju-quickstart/jenv-env/+merge/244772

(do not edit description out of merge proposal)

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

Affected files (+173, -44 lines):
   A [revision details]
   M quickstart/app.py
   M quickstart/manage.py
   M quickstart/models/jenv.py
   M quickstart/tests/models/test_jenv.py
   M quickstart/tests/test_app.py
   M quickstart/tests/test_manage.py

Revision history for this message
Jay R. Wren (evarlast) wrote :

On 2014/12/15 17:51:50, frankban wrote:
> Please take a look.

LGTM

https://codereview.appspot.com/190060043/

Revision history for this message
Richard Harding (rharding) wrote :

LGTM no qa. Love it when things are as straight forward as this seems.

https://codereview.appspot.com/190060043/

Revision history for this message
Brad Crittenden (bac) wrote :

QA - OK

I was surprised to see the username printed as 'user-bac' (because I
hadn't noticed that part of the code).

Why do we have the user- prefix? Is that a juju-gui thing?

I don't think we should make that user visible, i.e. don't print 'user-'
when showing the credentials being used. The prefix does not appear in
the .jenv file or 'juju user list'.

https://codereview.appspot.com/190060043/

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

On 2014/12/15 19:54:50, bac wrote:
> QA - OK

> I was surprised to see the username printed as 'user-bac' (because I
hadn't
> noticed that part of the code).

> Why do we have the user- prefix? Is that a juju-gui thing?

> I don't think we should make that user visible, i.e. don't print
'user-' when
> showing the credentials being used. The prefix does not appear in the
.jenv file
> or 'juju user list'.

Hi Brad,

the use prefix is required when loggin in to the Juju API. But I agree
with you:
hiding it in the UX could be a good idea, especially because I checked
with
the GUI trunk and we already do that in the login form.
I'll merge this and propose a follow up branch to hide the prefix.
Thank you for the QA and thank you all for the reviews!

https://codereview.appspot.com/190060043/

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

*** Submitted:

Use both credentials to connect to Juju.

Use both the user name and password when connecting
to the Juju WebSocket API.

Update the jenv models to reflect what we expect to
find in the jenv file.

QA:
- use quickstart as usual
   (.venv/bin/python juju-quickstart ...);
- the user is now printed to stdout;
- the environment and the GUI log in correctly,
   in the case the environment is bootstrapped by
   quickstart or already there.

R=jay.wren, rharding, bac
CC=
https://codereview.appspot.com/190060043

https://codereview.appspot.com/190060043/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'quickstart/app.py'
--- quickstart/app.py 2014-11-12 16:40:54 +0000
+++ quickstart/app.py 2014-12-15 17:51:32 +0000
@@ -293,16 +293,16 @@
293 raise ProgramExit(msg)293 raise ProgramExit(msg)
294294
295295
296def get_admin_secret(env_name):296def get_credentials(env_name):
297 """Return the Juju admin secret for the given environment name.297 """Return the Juju credentials for the given environment name.
298298
299 Parse the jenv file to retrieve the admin secret.299 Parse the jenv file to retrieve the environment user name and password.
300 Raise a ProgramExit if the admin secret cannot be retrieved.300 Raise a ProgramExit if the credentials cannot be retrieved.
301 """301 """
302 try:302 try:
303 return jenv.get_value(env_name, 'bootstrap-config', 'admin-secret')303 return jenv.get_credentials(env_name)
304 except ValueError as err:304 except ValueError as err:
305 msg = b'cannot retrieve environment admin-secret: {}'.format(err)305 msg = b'cannot retrieve environment credentials: {}'.format(err)
306 raise ProgramExit(msg)306 raise ProgramExit(msg)
307307
308308
@@ -323,7 +323,7 @@
323 return 'wss://{}'.format(api_address)323 return 'wss://{}'.format(api_address)
324324
325325
326def connect(api_url, admin_secret):326def connect(api_url, username, password):
327 """Connect to the Juju API server and log in using the given credentials.327 """Connect to the Juju API server and log in using the given credentials.
328328
329 Return a connected and authenticated Juju Environment instance.329 Return a connected and authenticated Juju Environment instance.
@@ -346,7 +346,7 @@
346 else:346 else:
347 break347 break
348 try:348 try:
349 env.login(admin_secret)349 env.login(password, user=username)
350 except jujuclient.EnvError as err:350 except jujuclient.EnvError as err:
351 msg = 'unable to log in to the Juju API server on {}: {}'351 msg = 'unable to log in to the Juju API server on {}: {}'
352 raise ProgramExit(msg.format(api_url, err.message))352 raise ProgramExit(msg.format(api_url, err.message))
353353
=== modified file 'quickstart/manage.py'
--- quickstart/manage.py 2014-11-12 08:48:35 +0000
+++ quickstart/manage.py 2014-12-15 17:51:32 +0000
@@ -542,10 +542,11 @@
542 api_url = app.get_api_url(options.env_name, juju_command)542 api_url = app.get_api_url(options.env_name, juju_command)
543543
544 # Retrieve the admin-secret for the current environment.544 # Retrieve the admin-secret for the current environment.
545 admin_secret = app.get_admin_secret(options.env_name)545 print('retrieving the Juju environment credentials')
546 username, password = app.get_credentials(options.env_name)
546547
547 print('connecting to {}'.format(api_url))548 print('connecting to {}'.format(api_url))
548 env = app.connect(api_url, admin_secret)549 env = app.connect(api_url, username, password)
549550
550 # Inspect the environment and deploy the charm if required.551 # Inspect the environment and deploy the charm if required.
551 charm_url, machine, service_data, unit_data = app.check_environment(552 charm_url, machine, service_data, unit_data = app.check_environment(
@@ -559,10 +560,11 @@
559 address = app.watch(env, unit_name)560 address = app.watch(env, unit_name)
560 env.close()561 env.close()
561 url = 'https://{}'.format(address)562 url = 'https://{}'.format(address)
562 print('\nJuju GUI URL: {}\npassword: {}\n'.format(url, admin_secret))563 print('\nJuju GUI URL: {}\nusername: {}\npassword: {}\n'.format(
564 url, username, password))
563 gui_api_url = 'wss://{}:443/ws'.format(address)565 gui_api_url = 'wss://{}:443/ws'.format(address)
564 print('connecting to the Juju GUI server')566 print('connecting to the Juju GUI server')
565 gui_env = app.connect(gui_api_url, admin_secret)567 gui_env = app.connect(gui_api_url, username, password)
566568
567 # Handle bundle deployment.569 # Handle bundle deployment.
568 if options.bundle is not None:570 if options.bundle is not None:
569571
=== modified file 'quickstart/models/jenv.py'
--- quickstart/models/jenv.py 2014-11-11 13:21:57 +0000
+++ quickstart/models/jenv.py 2014-12-15 17:51:32 +0000
@@ -22,6 +22,7 @@
2222
23from __future__ import unicode_literals23from __future__ import unicode_literals
2424
25import logging
25import os26import os
2627
27from quickstart import (28from quickstart import (
@@ -30,6 +31,12 @@
30)31)
3132
3233
34# Define the constant tag used by Juju for user entities.
35JUJU_USER_TAG = 'user'
36# Define the default Juju user when an environment is initially bootstrapped.
37JUJU_DEFAULT_USER = 'admin'
38
39
33def exists(env_name):40def exists(env_name):
34 """Report whether the jenv generated file exists for the given env_name."""41 """Report whether the jenv generated file exists for the given env_name."""
35 jenv_path = _get_jenv_path(env_name)42 jenv_path = _get_jenv_path(env_name)
@@ -52,13 +59,73 @@
52 """59 """
53 jenv_path = _get_jenv_path(env_name)60 jenv_path = _get_jenv_path(env_name)
54 data = serializers.yaml_load_from_path(jenv_path)61 data = serializers.yaml_load_from_path(jenv_path)
62 try:
63 return _get_value_from_yaml(data, *args)
64 except ValueError as err:
65 raise ValueError(
66 b'cannot read {}: {}'.format(jenv_path.encode('utf-8'), err))
67
68
69def get_credentials(env_name):
70 """Return the Juju environment credentials stored in the jenv file.
71
72 The credentials are returned as a tuple (username, password).
73
74 Raise a ValueError if:
75 - the environment file is not found;
76 - the environment file contents are not parsable by YAML;
77 - the credentials cannot be found.
78 """
79 jenv_path = _get_jenv_path(env_name)
80 data = serializers.yaml_load_from_path(jenv_path)
81
82 # Retrieve the user name.
83 try:
84 user = _get_value_from_yaml(data, 'user')
85 except ValueError as err:
86 # This is probably an old version of Juju not supporting multiple
87 # users. Return the default user name.
88 logging.warn('cannot retrieve the user name from {}: {}'.format(
89 jenv_path, bytes(err).decode('utf-8')))
90 user = JUJU_DEFAULT_USER
91
92 # Retrieve the password.
93 try:
94 password = _get_value_from_yaml(data, 'password')
95 except ValueError as err:
96 # This is probably an old version of Juju not supporting multiple
97 # users. Fall back to the admin secret.
98 msg = b'cannot retrieve the password from {}: '.format(
99 jenv_path.encode('utf-8'))
100 logging.debug(msg + bytes(err))
101 try:
102 password = _get_value_from_yaml(
103 data, 'bootstrap-config', 'admin-secret')
104 except ValueError as err:
105 raise ValueError(msg + bytes(err))
106
107 return '{}-{}'.format(JUJU_USER_TAG, user), password
108
109
110def _get_value_from_yaml(data, *args):
111 """Read and return a value from the given YAML decoded data.
112
113 Return the value corresponding to the specified args sequence.
114 For instance, if args is ('bootstrap-config', 'admin-secret'), the value
115 associated with the "admin-secret" key included on the "bootstrap-config"
116 section is returned.
117
118 Raise a ValueError if:
119 - the YAML contents are not properly structured;
120 - one the keys in args is not found.
121 """
55 section = 'root'122 section = 'root'
56 for key in args:123 for key in args:
57 try:124 try:
58 data = data[key]125 data = data[key]
59 except (KeyError, TypeError):126 except (KeyError, TypeError):
60 msg = ('invalid YAML contents in {}: ''{} key not found in the {} '127 msg = ('invalid YAML contents: {} key not found in the {} section'
61 'section'.format(jenv_path, key, section))128 ''.format(key, section))
62 raise ValueError(msg.encode('utf-8'))129 raise ValueError(msg.encode('utf-8'))
63 section = key130 section = key
64 return data131 return data
65132
=== modified file 'quickstart/tests/models/test_jenv.py'
--- quickstart/tests/models/test_jenv.py 2014-11-11 13:21:57 +0000
+++ quickstart/tests/models/test_jenv.py 2014-12-15 17:51:32 +0000
@@ -87,8 +87,8 @@
87 # A ValueError is raised if the specified section cannot be found.87 # A ValueError is raised if the specified section cannot be found.
88 with self.make_jenv('local', yaml.safe_dump(self.jenv_data)) as path:88 with self.make_jenv('local', yaml.safe_dump(self.jenv_data)) as path:
89 expected_error = (89 expected_error = (
90 'invalid YAML contents in {}: no-such key not found in the '90 'cannot read {}: invalid YAML contents: no-such key not found '
91 'root section'.format(path))91 'in the root section'.format(path))
92 with self.assert_value_error(expected_error):92 with self.assert_value_error(expected_error):
93 jenv.get_value('local', 'no-such')93 jenv.get_value('local', 'no-such')
9494
@@ -96,8 +96,8 @@
96 # A ValueError is raised if the specified subsection cannot be found.96 # A ValueError is raised if the specified subsection cannot be found.
97 with self.make_jenv('local', yaml.safe_dump(self.jenv_data)) as path:97 with self.make_jenv('local', yaml.safe_dump(self.jenv_data)) as path:
98 expected_error = (98 expected_error = (
99 'invalid YAML contents in {}: series key not found in the '99 'cannot read {}: invalid YAML contents: series key not found '
100 'bootstrap-config section'.format(path))100 'in the bootstrap-config section'.format(path))
101 with self.assert_value_error(expected_error):101 with self.assert_value_error(expected_error):
102 jenv.get_value('local', 'bootstrap-config', 'series')102 jenv.get_value('local', 'bootstrap-config', 'series')
103103
@@ -108,3 +108,56 @@
108 with self.assertRaises(ValueError) as context_manager:108 with self.assertRaises(ValueError) as context_manager:
109 jenv.get_value('ec2')109 jenv.get_value('ec2')
110 self.assertIn(expected_error, bytes(context_manager.exception))110 self.assertIn(expected_error, bytes(context_manager.exception))
111
112
113class TestGetCredentials(
114 helpers.JenvFileTestsMixin, helpers.ValueErrorTestsMixin,
115 unittest.TestCase):
116
117 def test_valid_credentials(self):
118 # The user name and password are correctly returned.
119 data = {'user': 'jean-luc', 'password': 'Secret!'}
120 with self.make_jenv('local', yaml.safe_dump(data)):
121 username, password = jenv.get_credentials('local')
122 self.assertEqual('user-jean-luc', username)
123 self.assertEqual('Secret!', password)
124
125 def test_default_user(self):
126 # The default user name is returned if it's not possible to retrieve it
127 # otherwise.
128 data = {'password': 'Secret!'}
129 with self.make_jenv('local', yaml.safe_dump(data)) as path:
130 expected_logs = [
131 'cannot retrieve the user name from {}: '
132 'invalid YAML contents: '
133 'user key not found in the root section'.format(path)]
134 with helpers.assert_logs(expected_logs, 'warn'):
135 username, password = jenv.get_credentials('local')
136 self.assertEqual('user-admin', username)
137 self.assertEqual('Secret!', password)
138
139 def test_using_admin_secret(self):
140 # If the password is not found in the jenv file, the admin secret is
141 # returned if present.
142 data = {
143 'user': 'who',
144 'bootstrap-config': {'admin-secret': 'Admin!'},
145 }
146 with self.make_jenv('local', yaml.safe_dump(data)) as path:
147 expected_logs = [
148 'cannot retrieve the password from {}: '
149 'invalid YAML contents: '
150 'password key not found in the root section'.format(path)]
151 with helpers.assert_logs(expected_logs, 'debug'):
152 username, password = jenv.get_credentials('local')
153 self.assertEqual('Admin!', password)
154
155 def test_password_not_found(self):
156 # A ValueError is raised if the password cannot be found anywhere.
157 with self.make_jenv('local', yaml.safe_dump({})) as path:
158 expected_error = (
159 'cannot retrieve the password from {}: '
160 'invalid YAML contents: bootstrap-config key '
161 'not found in the root section'.format(path))
162 with self.assert_value_error(expected_error):
163 jenv.get_credentials('local')
111164
=== modified file 'quickstart/tests/test_app.py'
--- quickstart/tests/test_app.py 2014-11-12 12:21:09 +0000
+++ quickstart/tests/test_app.py 2014-12-15 17:51:32 +0000
@@ -469,7 +469,7 @@
469 with self.make_jenv('ec2', '') as path:469 with self.make_jenv('ec2', '') as path:
470 logs = [470 logs = [
471 'cannot retrieve the Juju API URL: '471 'cannot retrieve the Juju API URL: '
472 'invalid YAML contents in {}: '472 'cannot read {}: invalid YAML contents: '
473 'state-servers key not found in the root section'.format(path)473 'state-servers key not found in the root section'.format(path)
474 ]474 ]
475 with helpers.assert_logs(logs, level='warn'):475 with helpers.assert_logs(logs, level='warn'):
@@ -713,31 +713,32 @@
713 # A ProgramExit is raised if the environment type cannot be retrieved.713 # A ProgramExit is raised if the environment type cannot be retrieved.
714 with self.make_jenv('aws', '') as path:714 with self.make_jenv('aws', '') as path:
715 expected_error = (715 expected_error = (
716 'cannot retrieve environment type: invalid YAML '716 'cannot retrieve environment type: cannot read {}: invalid '
717 'contents in {}: bootstrap-config key not found in the root '717 'YAML contents: bootstrap-config key not found in the root '
718 'section'.format(path))718 'section'.format(path))
719 with self.assert_program_exit(expected_error):719 with self.assert_program_exit(expected_error):
720 app.get_env_type('aws')720 app.get_env_type('aws')
721721
722722
723class TestGetAdminSecret(723class TestGetCredentials(
724 helpers.JenvFileTestsMixin, ProgramExitTestsMixin, unittest.TestCase):724 helpers.JenvFileTestsMixin, ProgramExitTestsMixin, unittest.TestCase):
725725
726 def test_success(self):726 def test_success(self):
727 # The admin secret is successfully retrieved.727 # The user name and password are successfully retrieved.
728 with self.make_jenv('ec2', yaml.safe_dump(self.jenv_data)):728 with self.make_jenv('ec2', yaml.safe_dump(self.jenv_data)):
729 admin_secret = app.get_admin_secret('ec2')729 username, password = app.get_credentials('ec2')
730 self.assertEqual('Secret!', admin_secret)730 self.assertEqual('user-admin', username)
731 self.assertEqual('Secret!', password)
731732
732 def test_error(self):733 def test_error(self):
733 # A ProgramExit is raised if the admin secret cannot be retrieved.734 # A ProgramExit is raised if the credentials cannot be retrieved.
734 with self.make_jenv('ec2', '') as path:735 with self.make_jenv('ec2', '') as path:
735 expected_error = (736 expected_error = (
736 'cannot retrieve environment admin-secret: invalid YAML '737 'cannot retrieve environment credentials: cannot retrieve the '
737 'contents in {}: bootstrap-config key not found in the root '738 'password from {}: invalid YAML contents: bootstrap-config '
738 'section'.format(path))739 'key not found in the root section'.format(path))
739 with self.assert_program_exit(expected_error):740 with self.assert_program_exit(expected_error):
740 app.get_admin_secret('ec2')741 app.get_credentials('ec2')
741742
742743
743class TestGetApiUrl(744class TestGetApiUrl(
@@ -768,16 +769,18 @@
768769
769class TestConnect(ProgramExitTestsMixin, unittest.TestCase):770class TestConnect(ProgramExitTestsMixin, unittest.TestCase):
770771
771 admin_secret = 'Secret!'772 username = 'MyUser'
773 password = 'Secret!'
772 api_url = 'wss://api.example.com:17070'774 api_url = 'wss://api.example.com:17070'
773775
774 def test_connection_established(self):776 def test_connection_established(self):
775 # The connection is done and the Environment instance is returned.777 # The connection is done and the Environment instance is returned.
776 with mock.patch('quickstart.juju.connect') as mock_connect:778 with mock.patch('quickstart.juju.connect') as mock_connect:
777 env = app.connect(self.api_url, self.admin_secret)779 env = app.connect(self.api_url, self.username, self.password)
778 mock_connect.assert_called_once_with(self.api_url)780 mock_connect.assert_called_once_with(self.api_url)
779 mock_env = mock_connect()781 mock_env = mock_connect()
780 mock_env.login.assert_called_once_with(self.admin_secret)782 mock_env.login.assert_called_once_with(
783 self.password, user=self.username)
781 self.assertEqual(mock_env, env)784 self.assertEqual(mock_env, env)
782785
783 @mock.patch('time.sleep')786 @mock.patch('time.sleep')
@@ -788,7 +791,7 @@
788 expected = 'unable to connect to the Juju API server on {}: bad wolf'791 expected = 'unable to connect to the Juju API server on {}: bad wolf'
789 with mock.patch('quickstart.juju.connect', mock_connect):792 with mock.patch('quickstart.juju.connect', mock_connect):
790 with self.assert_program_exit(expected.format(self.api_url)):793 with self.assert_program_exit(expected.format(self.api_url)):
791 app.connect(self.api_url, self.admin_secret)794 app.connect(self.api_url, self.username, self.password)
792 mock_connect.assert_called_with(self.api_url)795 mock_connect.assert_called_with(self.api_url)
793 self.assertEqual(30, mock_connect.call_count)796 self.assertEqual(30, mock_connect.call_count)
794 mock_sleep.assert_called_with(1)797 mock_sleep.assert_called_with(1)
@@ -805,10 +808,11 @@
805 mock_connect = mock.Mock(808 mock_connect = mock.Mock(
806 side_effect=[ValueError('bad wolf'), mock_env])809 side_effect=[ValueError('bad wolf'), mock_env])
807 with mock.patch('quickstart.juju.connect', mock_connect):810 with mock.patch('quickstart.juju.connect', mock_connect):
808 env = app.connect(self.api_url, self.admin_secret)811 env = app.connect(self.api_url, self.username, self.password)
809 mock_connect.assert_called_with(self.api_url)812 mock_connect.assert_called_with(self.api_url)
810 self.assertEqual(2, mock_connect.call_count)813 self.assertEqual(2, mock_connect.call_count)
811 mock_env.login.assert_called_once_with(self.admin_secret)814 mock_env.login.assert_called_once_with(
815 self.password, user=self.username)
812 self.assertEqual(mock_env, env)816 self.assertEqual(mock_env, env)
813 mock_sleep.assert_called_once_with(1)817 mock_sleep.assert_called_once_with(1)
814 expected = 'unable to connect to the Juju API server on {}: bad wolf'818 expected = 'unable to connect to the Juju API server on {}: bad wolf'
@@ -822,9 +826,10 @@
822 mock_login = mock_connect().login826 mock_login = mock_connect().login
823 mock_login.side_effect = self.make_env_error('bad wolf')827 mock_login.side_effect = self.make_env_error('bad wolf')
824 with self.assert_program_exit(expected.format(self.api_url)):828 with self.assert_program_exit(expected.format(self.api_url)):
825 app.connect(self.api_url, self.admin_secret)829 app.connect(self.api_url, self.username, self.password)
826 mock_connect.assert_called_with(self.api_url)830 mock_connect.assert_called_with(self.api_url)
827 mock_login.assert_called_once_with(self.admin_secret)831 mock_login.assert_called_once_with(
832 self.password, user=self.username)
828833
829 def test_other_errors(self):834 def test_other_errors(self):
830 # Any other errors occurred during the log in process are not trapped.835 # Any other errors occurred during the log in process are not trapped.
@@ -833,7 +838,7 @@
833 mock_login = mock_connect().login838 mock_login = mock_connect().login
834 mock_login.side_effect = error839 mock_login.side_effect = error
835 with self.assertRaises(ValueError) as context_manager:840 with self.assertRaises(ValueError) as context_manager:
836 app.connect(self.api_url, self.admin_secret)841 app.connect(self.api_url, self.username, self.password)
837 self.assertIs(error, context_manager.exception)842 self.assertIs(error, context_manager.exception)
838843
839844
840845
=== modified file 'quickstart/tests/test_manage.py'
--- quickstart/tests/test_manage.py 2014-11-12 14:10:26 +0000
+++ quickstart/tests/test_manage.py 2014-12-15 17:51:32 +0000
@@ -787,8 +787,8 @@
787 'status': 'trusty',787 'status': 'trusty',
788 # The API URL must be retrieved (the environment was not ready).788 # The API URL must be retrieved (the environment was not ready).
789 'get_api_url': 'wss://1.2.3.4:17070',789 'get_api_url': 'wss://1.2.3.4:17070',
790 # Retrieve the admin secret.790 # Retrieve the environment credentials.
791 'get_admin_secret': 'Secret!',791 'get_credentials': ('MyUser', 'Secret!'),
792 # Connect to the Juju Environment API endpoint.792 # Connect to the Juju Environment API endpoint.
793 'connect': env,793 'connect': env,
794 # The environment is then checked.794 # The environment is then checked.
@@ -838,11 +838,11 @@
838 options.env_name, self.juju_command)838 options.env_name, self.juju_command)
839 mock_app.get_api_url.assert_called_once_with(839 mock_app.get_api_url.assert_called_once_with(
840 options.env_name, self.juju_command)840 options.env_name, self.juju_command)
841 mock_app.get_admin_secret.assert_called_once_with(options.env_name)841 mock_app.get_credentials.assert_called_once_with(options.env_name)
842 mock_app.connect.assert_has_calls([842 mock_app.connect.assert_has_calls([
843 mock.call('wss://1.2.3.4:17070', 'Secret!'),843 mock.call('wss://1.2.3.4:17070', 'MyUser', 'Secret!'),
844 mock.call().close(),844 mock.call().close(),
845 mock.call('wss://1.2.3.4:443/ws', 'Secret!'),845 mock.call('wss://1.2.3.4:443/ws', 'MyUser', 'Secret!'),
846 mock.call().close(),846 mock.call().close(),
847 ])847 ])
848 mock_app.check_environment.assert_called_once_with(848 mock_app.check_environment.assert_called_once_with(

Subscribers

People subscribed via source and target branches