|
10 | 10 | # License for the specific language governing permissions and limitations |
11 | 11 | # under the License. |
12 | 12 |
|
| 13 | +import json |
13 | 14 | import logging |
14 | 15 | import os |
15 | 16 | import shlex |
@@ -48,33 +49,52 @@ def execute(cmd, fail_ok=False, merge_stderr=False): |
48 | 49 | class TestCase(testtools.TestCase): |
49 | 50 |
|
50 | 51 | @classmethod |
51 | | - def openstack(cls, cmd, cloud=ADMIN_CLOUD, fail_ok=False): |
| 52 | + def openstack( |
| 53 | + cls, |
| 54 | + cmd, |
| 55 | + *, |
| 56 | + cloud=ADMIN_CLOUD, |
| 57 | + fail_ok=False, |
| 58 | + parse_output=False, |
| 59 | + ): |
52 | 60 | """Executes openstackclient command for the given action |
53 | 61 |
|
54 | | - NOTE(dtroyer): There is a subtle distinction between passing |
55 | | - cloud=None and cloud='': for compatibility reasons passing |
56 | | - cloud=None continues to include the option '--os-auth-type none' |
57 | | - in the command while passing cloud='' omits the '--os-auth-type' |
58 | | - option completely to let the default handlers be invoked. |
| 62 | + :param cmd: A string representation of the command to execute. |
| 63 | + :param cloud: The cloud to execute against. This can be a string, empty |
| 64 | + string, or None. A string results in '--os-auth-type $cloud', an |
| 65 | + empty string results in the '--os-auth-type' option being |
| 66 | + omitted, and None resuts in '--os-auth-type none' for legacy |
| 67 | + reasons. |
| 68 | + :param fail_ok: If failure is permitted. If False (default), a command |
| 69 | + failure will result in `~tempest.lib.exceptions.CommandFailed` |
| 70 | + being raised. |
| 71 | + :param parse_output: If true, pass the '-f json' parameter and decode |
| 72 | + the output. |
| 73 | + :returns: The output from the command. |
| 74 | + :raises: `~tempest.lib.exceptions.CommandFailed` if the command failed |
| 75 | + and ``fail_ok`` was ``False``. |
59 | 76 | """ |
| 77 | + auth_args = [] |
60 | 78 | if cloud is None: |
61 | 79 | # Execute command with no auth |
62 | | - return execute( |
63 | | - 'openstack --os-auth-type none ' + cmd, |
64 | | - fail_ok=fail_ok |
65 | | - ) |
66 | | - elif cloud == '': |
67 | | - # Execute command with no auth options at all |
68 | | - return execute( |
69 | | - 'openstack ' + cmd, |
70 | | - fail_ok=fail_ok |
71 | | - ) |
72 | | - else: |
| 80 | + auth_args.append('--os-auth-type none') |
| 81 | + elif cloud != '': |
73 | 82 | # Execute command with an explicit cloud specified |
74 | | - return execute( |
75 | | - 'openstack --os-cloud=' + cloud + ' ' + cmd, |
76 | | - fail_ok=fail_ok |
77 | | - ) |
| 83 | + auth_args.append(f'--os-cloud {cloud}') |
| 84 | + |
| 85 | + format_args = [] |
| 86 | + if parse_output: |
| 87 | + format_args.append('-f json') |
| 88 | + |
| 89 | + output = execute( |
| 90 | + ' '.join(['openstack'] + auth_args + [cmd] + format_args), |
| 91 | + fail_ok=fail_ok, |
| 92 | + ) |
| 93 | + |
| 94 | + if parse_output: |
| 95 | + return json.loads(output) |
| 96 | + else: |
| 97 | + return output |
78 | 98 |
|
79 | 99 | @classmethod |
80 | 100 | def is_service_enabled(cls, service, version=None): |
|
0 commit comments