| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1 | # Copyright 2014 Mirantis Inc. | 
 | 2 | # All Rights Reserved. | 
 | 3 | # | 
 | 4 | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | 
 | 5 | #    not use this file except in compliance with the License. You may obtain | 
 | 6 | #    a copy of the License at | 
 | 7 | # | 
 | 8 | #         http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | # | 
 | 10 | #    Unless required by applicable law or agreed to in writing, software | 
 | 11 | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
 | 12 | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
 | 13 | #    License for the specific language governing permissions and limitations | 
 | 14 | #    under the License. | 
 | 15 |  | 
 | 16 | import copy | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 17 | import re | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 18 | import traceback | 
 | 19 |  | 
 | 20 | from oslo_concurrency import lockutils | 
 | 21 | from oslo_log import log | 
 | 22 | import six | 
| Sam Wan | c7b7f1f | 2015-11-25 00:22:28 -0500 | [diff] [blame] | 23 | from tempest.common import credentials_factory as common_creds | 
| Raissa Sarmento | 7b86b9d | 2017-07-21 14:32:48 +0100 | [diff] [blame] | 24 |  | 
| Valeriy Ponomaryov | 48a2bd7 | 2015-11-05 13:22:44 +0200 | [diff] [blame] | 25 | from tempest import config | 
| Goutham Pacha Ravi | c678e21 | 2020-03-20 11:13:47 -0700 | [diff] [blame] | 26 | from tempest.lib.common import cred_client | 
| Raissa Sarmento | 7b86b9d | 2017-07-21 14:32:48 +0100 | [diff] [blame] | 27 | from tempest.lib.common import dynamic_creds | 
| Ben Swartzlander | 1c4ff52 | 2016-03-02 22:16:23 -0500 | [diff] [blame] | 28 | from tempest.lib.common.utils import data_utils | 
 | 29 | from tempest.lib import exceptions | 
| Valeriy Ponomaryov | 48a2bd7 | 2015-11-05 13:22:44 +0200 | [diff] [blame] | 30 | from tempest import test | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 31 |  | 
| Andrea Frittoli (andreaf) | 369391a | 2016-06-27 18:59:13 +0100 | [diff] [blame] | 32 | from manila_tempest_tests import clients | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 33 | from manila_tempest_tests.common import constants | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 34 | from manila_tempest_tests import share_exceptions | 
| Valeriy Ponomaryov | fcde771 | 2015-12-14 18:06:13 +0200 | [diff] [blame] | 35 | from manila_tempest_tests import utils | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 36 |  | 
 | 37 | CONF = config.CONF | 
 | 38 | LOG = log.getLogger(__name__) | 
 | 39 |  | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 40 | # Test tags related to test direction | 
 | 41 | TAG_POSITIVE = "positive" | 
 | 42 | TAG_NEGATIVE = "negative" | 
 | 43 |  | 
 | 44 | # Test tags related to service involvement | 
| Tom Barron | 69f9696 | 2019-07-29 17:07:03 -0400 | [diff] [blame] | 45 | # Only requires that manila-api service running. | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 46 | TAG_API = "api" | 
| Tom Barron | 69f9696 | 2019-07-29 17:07:03 -0400 | [diff] [blame] | 47 | # Requires all manila services running, intended to test back-end | 
 | 48 | # (manila-share) behavior. | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 49 | TAG_BACKEND = "backend" | 
| Tom Barron | 69f9696 | 2019-07-29 17:07:03 -0400 | [diff] [blame] | 50 | # Requires all manila services running, intended to test API behavior. | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 51 | TAG_API_WITH_BACKEND = "api_with_backend" | 
 | 52 |  | 
 | 53 | TAGS_MAPPER = { | 
 | 54 |     "p": TAG_POSITIVE, | 
 | 55 |     "n": TAG_NEGATIVE, | 
 | 56 |     "a": TAG_API, | 
 | 57 |     "b": TAG_BACKEND, | 
 | 58 |     "ab": TAG_API_WITH_BACKEND, | 
 | 59 | } | 
 | 60 | TAGS_PATTERN = re.compile( | 
 | 61 |     r"(?=.*\[.*\b(%(p)s|%(n)s)\b.*\])(?=.*\[.*\b(%(a)s|%(b)s|%(ab)s)\b.*\])" % | 
 | 62 |     TAGS_MAPPER) | 
 | 63 |  | 
 | 64 |  | 
 | 65 | def verify_test_has_appropriate_tags(self): | 
 | 66 |     if not TAGS_PATTERN.match(self.id()): | 
 | 67 |         msg = ( | 
 | 68 |             "Required attributes either not set or set improperly. " | 
 | 69 |             "Two test attributes are expected:\n" | 
 | 70 |             " - one of '%(p)s' or '%(n)s' and \n" | 
 | 71 |             " - one of '%(a)s', '%(b)s' or '%(ab)s'." | 
 | 72 |         ) % TAGS_MAPPER | 
 | 73 |         raise self.failureException(msg) | 
 | 74 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 75 |  | 
 | 76 | class handle_cleanup_exceptions(object): | 
 | 77 |     """Handle exceptions raised with cleanup operations. | 
 | 78 |  | 
 | 79 |     Always suppress errors when exceptions.NotFound or exceptions.Forbidden | 
 | 80 |     are raised. | 
 | 81 |     Suppress all other exceptions only in case config opt | 
 | 82 |     'suppress_errors_in_cleanup' in config group 'share' is True. | 
 | 83 |     """ | 
 | 84 |  | 
 | 85 |     def __enter__(self): | 
 | 86 |         return self | 
 | 87 |  | 
 | 88 |     def __exit__(self, exc_type, exc_value, exc_traceback): | 
 | 89 |         if not (isinstance(exc_value, | 
 | 90 |                            (exceptions.NotFound, exceptions.Forbidden)) or | 
 | 91 |                 CONF.share.suppress_errors_in_cleanup): | 
 | 92 |             return False  # Do not suppress error if any | 
 | 93 |         if exc_traceback: | 
 | 94 |             LOG.error("Suppressed cleanup error in Manila: " | 
| junboli | b236c24 | 2017-07-18 18:12:37 +0800 | [diff] [blame] | 95 |                       "\n%s", traceback.format_exc()) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 96 |         return True  # Suppress error if any | 
 | 97 |  | 
 | 98 |  | 
 | 99 | def network_synchronized(f): | 
 | 100 |  | 
 | 101 |     def wrapped_func(self, *args, **kwargs): | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 102 |  | 
 | 103 |         # Use lock assuming reusage of common network. | 
 | 104 |         @lockutils.synchronized("manila_network_lock", external=True) | 
 | 105 |         def source_func(self, *args, **kwargs): | 
 | 106 |             return f(self, *args, **kwargs) | 
 | 107 |  | 
 | 108 |         return source_func(self, *args, **kwargs) | 
 | 109 |  | 
 | 110 |     return wrapped_func | 
 | 111 |  | 
 | 112 |  | 
| Valeriy Ponomaryov | fcde771 | 2015-12-14 18:06:13 +0200 | [diff] [blame] | 113 | skip_if_microversion_not_supported = utils.skip_if_microversion_not_supported | 
| Xing Yang | 69b00b5 | 2015-11-22 16:10:44 -0500 | [diff] [blame] | 114 | skip_if_microversion_lt = utils.skip_if_microversion_lt | 
| Valeriy Ponomaryov | a14c225 | 2015-10-29 13:34:32 +0200 | [diff] [blame] | 115 |  | 
 | 116 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 117 | class BaseSharesTest(test.BaseTestCase): | 
 | 118 |     """Base test case class for all Manila API tests.""" | 
 | 119 |  | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 120 |     credentials = ('primary', ) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 121 |     force_tenant_isolation = False | 
| Vitaliy Levitksi | cfebfff | 2016-12-15 16:16:35 +0200 | [diff] [blame] | 122 |     protocols = ["nfs", "cifs", "glusterfs", "hdfs", "cephfs", "maprfs"] | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 123 |  | 
 | 124 |     # Will be cleaned up in resource_cleanup | 
 | 125 |     class_resources = [] | 
 | 126 |  | 
 | 127 |     # Will be cleaned up in tearDown method | 
 | 128 |     method_resources = [] | 
 | 129 |  | 
| Andrea Frittoli (andreaf) | 369391a | 2016-06-27 18:59:13 +0100 | [diff] [blame] | 130 |     # NOTE(andreaf) Override the client manager class to be used, so that | 
 | 131 |     # a stable class is used, which includes plugin registered services as well | 
 | 132 |     client_manager = clients.Clients | 
 | 133 |  | 
| Valeriy Ponomaryov | a14c225 | 2015-10-29 13:34:32 +0200 | [diff] [blame] | 134 |     def skip_if_microversion_not_supported(self, microversion): | 
| Valeriy Ponomaryov | fcde771 | 2015-12-14 18:06:13 +0200 | [diff] [blame] | 135 |         if not utils.is_microversion_supported(microversion): | 
| Valeriy Ponomaryov | a14c225 | 2015-10-29 13:34:32 +0200 | [diff] [blame] | 136 |             raise self.skipException( | 
 | 137 |                 "Microversion '%s' is not supported." % microversion) | 
 | 138 |  | 
| Xing Yang | 69b00b5 | 2015-11-22 16:10:44 -0500 | [diff] [blame] | 139 |     def skip_if_microversion_lt(self, microversion): | 
 | 140 |         if utils.is_microversion_lt(CONF.share.max_api_microversion, | 
 | 141 |                                     microversion): | 
 | 142 |             raise self.skipException( | 
 | 143 |                 "Microversion must be greater than or equal to '%s'." % | 
 | 144 |                 microversion) | 
 | 145 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 146 |     @classmethod | 
| Tom Barron | 4b8834a | 2017-02-02 11:02:20 -0500 | [diff] [blame] | 147 |     def _get_dynamic_creds(cls, name, network_resources=None): | 
| Raissa Sarmento | 7b86b9d | 2017-07-21 14:32:48 +0100 | [diff] [blame] | 148 |         identity_version = CONF.identity.auth_version | 
 | 149 |         if identity_version == 'v3': | 
 | 150 |             identity_uri = CONF.identity.uri_v3 | 
 | 151 |             identity_admin_endpoint_type = CONF.identity.v3_endpoint_type | 
 | 152 |         elif identity_version == 'v2': | 
 | 153 |             identity_uri = CONF.identity.uri | 
 | 154 |             identity_admin_endpoint_type = CONF.identity.v2_admin_endpoint_type | 
 | 155 |  | 
| Tom Barron | 4b8834a | 2017-02-02 11:02:20 -0500 | [diff] [blame] | 156 |         return dynamic_creds.DynamicCredentialProvider( | 
| Raissa Sarmento | 7b86b9d | 2017-07-21 14:32:48 +0100 | [diff] [blame] | 157 |             identity_version=identity_version, | 
| Tom Barron | 4b8834a | 2017-02-02 11:02:20 -0500 | [diff] [blame] | 158 |             name=name, | 
 | 159 |             network_resources=network_resources, | 
 | 160 |             credentials_domain=CONF.auth.default_credentials_domain_name, | 
 | 161 |             admin_role=CONF.identity.admin_role, | 
 | 162 |             admin_creds=common_creds.get_configured_admin_credentials(), | 
 | 163 |             identity_admin_domain_scope=CONF.identity.admin_domain_scope, | 
 | 164 |             identity_admin_role=CONF.identity.admin_role, | 
 | 165 |             extra_roles=None, | 
 | 166 |             neutron_available=CONF.service_available.neutron, | 
 | 167 |             create_networks=( | 
 | 168 |                 CONF.share.create_networks_when_multitenancy_enabled), | 
 | 169 |             project_network_cidr=CONF.network.project_network_cidr, | 
 | 170 |             project_network_mask_bits=CONF.network.project_network_mask_bits, | 
 | 171 |             public_network_id=CONF.network.public_network_id, | 
| ghanshyam | 2aea7c3 | 2017-12-11 00:03:56 +0000 | [diff] [blame] | 172 |             resource_prefix='tempest', | 
| Raissa Sarmento | 7b86b9d | 2017-07-21 14:32:48 +0100 | [diff] [blame] | 173 |             identity_admin_endpoint_type=identity_admin_endpoint_type, | 
 | 174 |             identity_uri=identity_uri) | 
| Tom Barron | 4b8834a | 2017-02-02 11:02:20 -0500 | [diff] [blame] | 175 |  | 
 | 176 |     @classmethod | 
| Daniel Mellado | e526914 | 2017-01-12 12:17:58 +0000 | [diff] [blame] | 177 |     def skip_checks(cls): | 
 | 178 |         super(BaseSharesTest, cls).skip_checks() | 
 | 179 |         if not CONF.service_available.manila: | 
 | 180 |             raise cls.skipException("Manila support is required") | 
| lkuchlan | a3b6f7a | 2020-01-07 10:45:45 +0200 | [diff] [blame] | 181 |         if not any(p in CONF.share.enable_protocols for p in cls.protocols): | 
 | 182 |             skip_msg = "%s tests are disabled" % CONF.share.enable_protocols | 
 | 183 |             raise cls.skipException(skip_msg) | 
| Daniel Mellado | e526914 | 2017-01-12 12:17:58 +0000 | [diff] [blame] | 184 |  | 
 | 185 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 186 |     def verify_nonempty(cls, *args): | 
 | 187 |         if not all(args): | 
 | 188 |             msg = "Missing API credentials in configuration." | 
 | 189 |             raise cls.skipException(msg) | 
 | 190 |  | 
 | 191 |     @classmethod | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 192 |     def setup_clients(cls): | 
 | 193 |         super(BaseSharesTest, cls).setup_clients() | 
 | 194 |         os = getattr(cls, 'os_%s' % cls.credentials[0]) | 
| Andrea Frittoli (andreaf) | 369391a | 2016-06-27 18:59:13 +0100 | [diff] [blame] | 195 |         # Initialise share clients for test credentials | 
 | 196 |         cls.shares_client = os.share_v1.SharesClient() | 
 | 197 |         cls.shares_v2_client = os.share_v2.SharesV2Client() | 
 | 198 |         # Initialise network clients for test credentials | 
 | 199 |         if CONF.service_available.neutron: | 
 | 200 |             cls.networks_client = os.network.NetworksClient() | 
 | 201 |             cls.subnets_client = os.network.SubnetsClient() | 
 | 202 |         else: | 
 | 203 |             cls.networks_client = None | 
 | 204 |             cls.subnets_client = None | 
| Valeriy Ponomaryov | 4fb305f | 2016-10-21 13:46:47 +0300 | [diff] [blame] | 205 |  | 
 | 206 |         if CONF.identity.auth_version == 'v3': | 
 | 207 |             project_id = os.auth_provider.auth_data[1]['project']['id'] | 
 | 208 |         else: | 
 | 209 |             project_id = os.auth_provider.auth_data[1]['token']['tenant']['id'] | 
 | 210 |         cls.tenant_id = project_id | 
 | 211 |         cls.user_id = os.auth_provider.auth_data[1]['user']['id'] | 
 | 212 |  | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 213 |         if CONF.share.multitenancy_enabled: | 
| Valeriy Ponomaryov | c5dae27 | 2016-06-10 18:29:24 +0300 | [diff] [blame] | 214 |             if (not CONF.service_available.neutron and | 
 | 215 |                     CONF.share.create_networks_when_multitenancy_enabled): | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 216 |                 raise cls.skipException("Neutron support is required") | 
 | 217 |             share_network_id = cls.provide_share_network( | 
| Andrea Frittoli (andreaf) | 369391a | 2016-06-27 18:59:13 +0100 | [diff] [blame] | 218 |                 cls.shares_v2_client, cls.networks_client) | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 219 |             cls.shares_client.share_network_id = share_network_id | 
 | 220 |             cls.shares_v2_client.share_network_id = share_network_id | 
| haobing1 | 01c7fee | 2018-03-09 16:33:00 +0800 | [diff] [blame] | 221 |             resource = { | 
 | 222 |                 "type": "share_network", | 
 | 223 |                 "id": share_network_id, | 
 | 224 |                 "client": cls.shares_v2_client, | 
 | 225 |             } | 
 | 226 |             cls.class_resources.insert(0, resource) | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 227 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 228 |     def setUp(self): | 
 | 229 |         super(BaseSharesTest, self).setUp() | 
| Valeriy Ponomaryov | dd162cb | 2016-01-20 19:09:49 +0200 | [diff] [blame] | 230 |         self.addCleanup(self.clear_resources) | 
| Valeriy Ponomaryov | 2abf5d7 | 2016-06-01 18:30:12 +0300 | [diff] [blame] | 231 |         verify_test_has_appropriate_tags(self) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 232 |  | 
 | 233 |     @classmethod | 
 | 234 |     def resource_cleanup(cls): | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 235 |         cls.clear_resources(cls.class_resources) | 
| Sam Wan | 241029c | 2016-07-26 03:37:42 -0400 | [diff] [blame] | 236 |         super(BaseSharesTest, cls).resource_cleanup() | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 237 |  | 
 | 238 |     @classmethod | 
 | 239 |     @network_synchronized | 
| Valeriy Ponomaryov | 48a2bd7 | 2015-11-05 13:22:44 +0200 | [diff] [blame] | 240 |     def provide_share_network(cls, shares_client, networks_client, | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 241 |                               ignore_multitenancy_config=False): | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 242 |         """Used for finding/creating share network for multitenant driver. | 
 | 243 |  | 
 | 244 |         This method creates/gets entity share-network for one tenant. This | 
 | 245 |         share-network will be used for creation of service vm. | 
 | 246 |  | 
 | 247 |         :param shares_client: shares client, which requires share-network | 
| Valeriy Ponomaryov | 48a2bd7 | 2015-11-05 13:22:44 +0200 | [diff] [blame] | 248 |         :param networks_client: network client from same tenant as shares | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 249 |         :param ignore_multitenancy_config: provide a share network regardless | 
 | 250 |             of 'multitenancy_enabled' configuration value. | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 251 |         :returns: str -- share network id for shares_client tenant | 
 | 252 |         :returns: None -- if single-tenant driver used | 
 | 253 |         """ | 
 | 254 |  | 
 | 255 |         sc = shares_client | 
| Valeriy Ponomaryov | c5dae27 | 2016-06-10 18:29:24 +0300 | [diff] [blame] | 256 |         search_word = "reusable" | 
 | 257 |         sn_name = "autogenerated_by_tempest_%s" % search_word | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 258 |  | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 259 |         if (not ignore_multitenancy_config and | 
 | 260 |                 not CONF.share.multitenancy_enabled): | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 261 |             # Assumed usage of a single-tenant driver | 
 | 262 |             share_network_id = None | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 263 |         else: | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 264 |             if sc.share_network_id: | 
 | 265 |                 # Share-network already exists, use it | 
 | 266 |                 share_network_id = sc.share_network_id | 
 | 267 |             elif not CONF.share.create_networks_when_multitenancy_enabled: | 
 | 268 |                 share_network_id = None | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 269 |  | 
 | 270 |                 # Try get suitable share-network | 
 | 271 |                 share_networks = sc.list_share_networks_with_detail() | 
 | 272 |                 for sn in share_networks: | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 273 |                     net_info = ( | 
 | 274 |                         utils.share_network_get_default_subnet(sn) | 
 | 275 |                         if utils.share_network_subnets_are_supported() else sn) | 
 | 276 |                     if net_info is None: | 
 | 277 |                         continue | 
 | 278 |                     if(net_info["neutron_net_id"] is None and | 
 | 279 |                             net_info["neutron_subnet_id"] is None and | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 280 |                             sn["name"] and search_word in sn["name"]): | 
 | 281 |                         share_network_id = sn["id"] | 
 | 282 |                         break | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 283 |  | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 284 |                 # Create new share-network if one was not found | 
 | 285 |                 if share_network_id is None: | 
 | 286 |                     sn_desc = "This share-network was created by tempest" | 
 | 287 |                     sn = sc.create_share_network(name=sn_name, | 
 | 288 |                                                  description=sn_desc) | 
 | 289 |                     share_network_id = sn["id"] | 
 | 290 |             else: | 
 | 291 |                 net_id = subnet_id = share_network_id = None | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 292 |                 # Search for networks, created in previous runs | 
 | 293 |                 service_net_name = "share-service" | 
 | 294 |                 networks = networks_client.list_networks() | 
 | 295 |                 if "networks" in networks.keys(): | 
 | 296 |                     networks = networks["networks"] | 
 | 297 |                 for network in networks: | 
 | 298 |                     if (service_net_name in network["name"] and | 
 | 299 |                             sc.tenant_id == network['tenant_id']): | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 300 |                         net_id = network["id"] | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 301 |                         if len(network["subnets"]) > 0: | 
 | 302 |                             subnet_id = network["subnets"][0] | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 303 |                             break | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 304 |  | 
 | 305 |                 # Create suitable network | 
 | 306 |                 if net_id is None or subnet_id is None: | 
 | 307 |                     ic = cls._get_dynamic_creds(service_net_name) | 
 | 308 |                     net_data = ic._create_network_resources(sc.tenant_id) | 
 | 309 |                     network, subnet, router = net_data | 
 | 310 |                     net_id = network["id"] | 
 | 311 |                     subnet_id = subnet["id"] | 
 | 312 |  | 
 | 313 |                 # Try get suitable share-network | 
 | 314 |                 share_networks = sc.list_share_networks_with_detail() | 
 | 315 |                 for sn in share_networks: | 
 | 316 |                     net_info = ( | 
 | 317 |                         utils.share_network_get_default_subnet(sn) | 
 | 318 |                         if utils.share_network_subnets_are_supported() | 
 | 319 |                         else sn) | 
 | 320 |                     if net_info is None: | 
 | 321 |                         continue | 
 | 322 |                     if (net_id == net_info["neutron_net_id"] and | 
 | 323 |                             subnet_id == net_info["neutron_subnet_id"] and | 
 | 324 |                             sn["name"] and search_word in sn["name"]): | 
 | 325 |                         share_network_id = sn["id"] | 
 | 326 |                         break | 
| Rodrigo Barbieri | 58d9de3 | 2016-09-06 13:16:47 -0300 | [diff] [blame] | 327 |  | 
 | 328 |                 # Create suitable share-network | 
 | 329 |                 if share_network_id is None: | 
 | 330 |                     sn_desc = "This share-network was created by tempest" | 
 | 331 |                     sn = sc.create_share_network(name=sn_name, | 
 | 332 |                                                  description=sn_desc, | 
 | 333 |                                                  neutron_net_id=net_id, | 
 | 334 |                                                  neutron_subnet_id=subnet_id) | 
 | 335 |                     share_network_id = sn["id"] | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 336 |  | 
 | 337 |         return share_network_id | 
 | 338 |  | 
 | 339 |     @classmethod | 
| marcusvrn | e0d7cfd | 2016-06-24 12:27:55 -0300 | [diff] [blame] | 340 |     def _create_share(cls, share_protocol=None, size=None, name=None, | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 341 |                       snapshot_id=None, description=None, metadata=None, | 
 | 342 |                       share_network_id=None, share_type_id=None, | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 343 |                       share_group_id=None, client=None, | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 344 |                       cleanup_in_class=True, is_public=False, **kwargs): | 
| Valeriy Ponomaryov | 1aaa72d | 2015-09-08 12:59:41 +0300 | [diff] [blame] | 345 |         client = client or cls.shares_v2_client | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 346 |         description = description or "Tempest's share" | 
| yogesh | 06f519f | 2017-06-26 13:16:12 -0400 | [diff] [blame] | 347 |         share_network_id = (share_network_id or | 
 | 348 |                             CONF.share.share_network_id or | 
 | 349 |                             client.share_network_id or None) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 350 |         metadata = metadata or {} | 
| marcusvrn | e0d7cfd | 2016-06-24 12:27:55 -0300 | [diff] [blame] | 351 |         size = size or CONF.share.share_size | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 352 |         kwargs.update({ | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 353 |             'share_protocol': share_protocol, | 
 | 354 |             'size': size, | 
 | 355 |             'name': name, | 
 | 356 |             'snapshot_id': snapshot_id, | 
 | 357 |             'description': description, | 
 | 358 |             'metadata': metadata, | 
 | 359 |             'share_network_id': share_network_id, | 
 | 360 |             'share_type_id': share_type_id, | 
 | 361 |             'is_public': is_public, | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 362 |         }) | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 363 |         if share_group_id: | 
 | 364 |             kwargs['share_group_id'] = share_group_id | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 365 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 366 |         share = client.create_share(**kwargs) | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 367 |         resource = {"type": "share", "id": share["id"], "client": client, | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 368 |                     "share_group_id": share_group_id} | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 369 |         cleanup_list = (cls.class_resources if cleanup_in_class else | 
 | 370 |                         cls.method_resources) | 
 | 371 |         cleanup_list.insert(0, resource) | 
 | 372 |         return share | 
 | 373 |  | 
 | 374 |     @classmethod | 
| Rodrigo Barbieri | 427bc05 | 2016-06-06 17:10:06 -0300 | [diff] [blame] | 375 |     def migrate_share( | 
 | 376 |             cls, share_id, dest_host, wait_for_status, client=None, | 
| Rodrigo Barbieri | 027df98 | 2016-11-24 15:52:03 -0200 | [diff] [blame] | 377 |             force_host_assisted_migration=False, writable=False, | 
 | 378 |             nondisruptive=False, preserve_metadata=False, | 
 | 379 |             preserve_snapshots=False, new_share_network_id=None, | 
| Rodrigo Barbieri | d38d2f5 | 2016-07-19 22:24:56 -0300 | [diff] [blame] | 380 |             new_share_type_id=None, **kwargs): | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 381 |         client = client or cls.shares_v2_client | 
| Rodrigo Barbieri | 427bc05 | 2016-06-06 17:10:06 -0300 | [diff] [blame] | 382 |         client.migrate_share( | 
 | 383 |             share_id, dest_host, | 
 | 384 |             force_host_assisted_migration=force_host_assisted_migration, | 
| Rodrigo Barbieri | 027df98 | 2016-11-24 15:52:03 -0200 | [diff] [blame] | 385 |             writable=writable, preserve_metadata=preserve_metadata, | 
 | 386 |             nondisruptive=nondisruptive, preserve_snapshots=preserve_snapshots, | 
| Rodrigo Barbieri | 427bc05 | 2016-06-06 17:10:06 -0300 | [diff] [blame] | 387 |             new_share_network_id=new_share_network_id, | 
| Rodrigo Barbieri | d38d2f5 | 2016-07-19 22:24:56 -0300 | [diff] [blame] | 388 |             new_share_type_id=new_share_type_id, **kwargs) | 
| Rodrigo Barbieri | e330512 | 2016-02-03 14:32:24 -0200 | [diff] [blame] | 389 |         share = client.wait_for_migration_status( | 
| Rodrigo Barbieri | 427bc05 | 2016-06-06 17:10:06 -0300 | [diff] [blame] | 390 |             share_id, dest_host, wait_for_status, **kwargs) | 
| Rodrigo Barbieri | e330512 | 2016-02-03 14:32:24 -0200 | [diff] [blame] | 391 |         return share | 
 | 392 |  | 
 | 393 |     @classmethod | 
 | 394 |     def migration_complete(cls, share_id, dest_host, client=None, **kwargs): | 
 | 395 |         client = client or cls.shares_v2_client | 
 | 396 |         client.migration_complete(share_id, **kwargs) | 
 | 397 |         share = client.wait_for_migration_status( | 
| Rodrigo Barbieri | 427bc05 | 2016-06-06 17:10:06 -0300 | [diff] [blame] | 398 |             share_id, dest_host, 'migration_success', **kwargs) | 
| Rodrigo Barbieri | b7137ad | 2015-09-06 22:53:16 -0300 | [diff] [blame] | 399 |         return share | 
 | 400 |  | 
 | 401 |     @classmethod | 
| Rodrigo Barbieri | c9abf28 | 2016-08-24 22:01:31 -0300 | [diff] [blame] | 402 |     def migration_cancel(cls, share_id, dest_host, client=None, **kwargs): | 
 | 403 |         client = client or cls.shares_v2_client | 
 | 404 |         client.migration_cancel(share_id, **kwargs) | 
 | 405 |         share = client.wait_for_migration_status( | 
 | 406 |             share_id, dest_host, 'migration_cancelled', **kwargs) | 
 | 407 |         return share | 
 | 408 |  | 
 | 409 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 410 |     def create_share(cls, *args, **kwargs): | 
 | 411 |         """Create one share and wait for available state. Retry if allowed.""" | 
 | 412 |         result = cls.create_shares([{"args": args, "kwargs": kwargs}]) | 
 | 413 |         return result[0] | 
 | 414 |  | 
 | 415 |     @classmethod | 
 | 416 |     def create_shares(cls, share_data_list): | 
 | 417 |         """Creates several shares in parallel with retries. | 
 | 418 |  | 
 | 419 |         Use this method when you want to create more than one share at same | 
 | 420 |         time. Especially if config option 'share.share_creation_retry_number' | 
 | 421 |         has value more than zero (0). | 
 | 422 |         All shares will be expected to have 'available' status with or without | 
 | 423 |         recreation else error will be raised. | 
 | 424 |  | 
 | 425 |         :param share_data_list: list -- list of dictionaries with 'args' and | 
 | 426 |             'kwargs' for '_create_share' method of this base class. | 
 | 427 |             example of data: | 
 | 428 |                 share_data_list=[{'args': ['quuz'], 'kwargs': {'foo': 'bar'}}}] | 
 | 429 |         :returns: list -- list of shares created using provided data. | 
 | 430 |         """ | 
 | 431 |  | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 432 |         for d in share_data_list: | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 433 |             if not isinstance(d, dict): | 
 | 434 |                 raise exceptions.TempestException( | 
 | 435 |                     "Expected 'dict', got '%s'" % type(d)) | 
 | 436 |             if "args" not in d: | 
 | 437 |                 d["args"] = [] | 
 | 438 |             if "kwargs" not in d: | 
 | 439 |                 d["kwargs"] = {} | 
 | 440 |             if len(d) > 2: | 
 | 441 |                 raise exceptions.TempestException( | 
 | 442 |                     "Expected only 'args' and 'kwargs' keys. " | 
 | 443 |                     "Provided %s" % list(d)) | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 444 |  | 
 | 445 |         data = [] | 
 | 446 |         for d in share_data_list: | 
 | 447 |             client = d["kwargs"].pop("client", cls.shares_v2_client) | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 448 |             wait_for_status = d["kwargs"].pop("wait_for_status", True) | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 449 |             local_d = { | 
 | 450 |                 "args": d["args"], | 
 | 451 |                 "kwargs": copy.deepcopy(d["kwargs"]), | 
 | 452 |             } | 
 | 453 |             local_d["kwargs"]["client"] = client | 
 | 454 |             local_d["share"] = cls._create_share( | 
 | 455 |                 *local_d["args"], **local_d["kwargs"]) | 
 | 456 |             local_d["cnt"] = 0 | 
 | 457 |             local_d["available"] = False | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 458 |             local_d["wait_for_status"] = wait_for_status | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 459 |             data.append(local_d) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 460 |  | 
 | 461 |         while not all(d["available"] for d in data): | 
 | 462 |             for d in data: | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 463 |                 if not d["wait_for_status"]: | 
 | 464 |                     d["available"] = True | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 465 |                 if d["available"]: | 
 | 466 |                     continue | 
| Valeriy Ponomaryov | 1a3e338 | 2016-06-08 15:17:16 +0300 | [diff] [blame] | 467 |                 client = d["kwargs"]["client"] | 
 | 468 |                 share_id = d["share"]["id"] | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 469 |                 try: | 
| Valeriy Ponomaryov | 1a3e338 | 2016-06-08 15:17:16 +0300 | [diff] [blame] | 470 |                     client.wait_for_share_status(share_id, "available") | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 471 |                     d["available"] = True | 
 | 472 |                 except (share_exceptions.ShareBuildErrorException, | 
 | 473 |                         exceptions.TimeoutException) as e: | 
 | 474 |                     if CONF.share.share_creation_retry_number > d["cnt"]: | 
 | 475 |                         d["cnt"] += 1 | 
 | 476 |                         msg = ("Share '%s' failed to be built. " | 
| Valeriy Ponomaryov | 1a3e338 | 2016-06-08 15:17:16 +0300 | [diff] [blame] | 477 |                                "Trying create another." % share_id) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 478 |                         LOG.error(msg) | 
 | 479 |                         LOG.error(e) | 
| Valeriy Ponomaryov | 1a3e338 | 2016-06-08 15:17:16 +0300 | [diff] [blame] | 480 |                         cg_id = d["kwargs"].get("consistency_group_id") | 
 | 481 |                         if cg_id: | 
 | 482 |                             # NOTE(vponomaryov): delete errored share | 
 | 483 |                             # immediately in case share is part of CG. | 
 | 484 |                             client.delete_share( | 
 | 485 |                                 share_id, | 
 | 486 |                                 params={"consistency_group_id": cg_id}) | 
 | 487 |                             client.wait_for_resource_deletion( | 
 | 488 |                                 share_id=share_id) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 489 |                         d["share"] = cls._create_share( | 
 | 490 |                             *d["args"], **d["kwargs"]) | 
 | 491 |                     else: | 
| gecong1973 | 5866380 | 2016-08-25 11:08:45 +0800 | [diff] [blame] | 492 |                         raise | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 493 |  | 
 | 494 |         return [d["share"] for d in data] | 
 | 495 |  | 
 | 496 |     @classmethod | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 497 |     def create_share_group(cls, client=None, cleanup_in_class=True, | 
 | 498 |                            share_network_id=None, **kwargs): | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 499 |         client = client or cls.shares_v2_client | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 500 |         if kwargs.get('source_share_group_snapshot_id') is None: | 
| Goutham Pacha Ravi | 9221f5e | 2016-04-21 13:17:49 -0400 | [diff] [blame] | 501 |             kwargs['share_network_id'] = (share_network_id or | 
 | 502 |                                           client.share_network_id or None) | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 503 |         share_group = client.create_share_group(**kwargs) | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 504 |         resource = { | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 505 |             "type": "share_group", | 
 | 506 |             "id": share_group["id"], | 
 | 507 |             "client": client, | 
 | 508 |         } | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 509 |         if cleanup_in_class: | 
 | 510 |             cls.class_resources.insert(0, resource) | 
 | 511 |         else: | 
 | 512 |             cls.method_resources.insert(0, resource) | 
 | 513 |  | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 514 |         if kwargs.get('source_share_group_snapshot_id'): | 
 | 515 |             new_share_group_shares = client.list_shares( | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 516 |                 detailed=True, | 
| silvacarloss | 6e57568 | 2020-02-18 19:52:35 -0300 | [diff] [blame] | 517 |                 params={'share_group_id': share_group['id']}) | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 518 |  | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 519 |             for share in new_share_group_shares: | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 520 |                 resource = {"type": "share", | 
 | 521 |                             "id": share["id"], | 
 | 522 |                             "client": client, | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 523 |                             "share_group_id": share.get("share_group_id")} | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 524 |                 if cleanup_in_class: | 
 | 525 |                     cls.class_resources.insert(0, resource) | 
 | 526 |                 else: | 
 | 527 |                     cls.method_resources.insert(0, resource) | 
 | 528 |  | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 529 |         client.wait_for_share_group_status(share_group['id'], 'available') | 
 | 530 |         return share_group | 
 | 531 |  | 
 | 532 |     @classmethod | 
 | 533 |     def create_share_group_type(cls, name=None, share_types=(), is_public=None, | 
 | 534 |                                 group_specs=None, client=None, | 
 | 535 |                                 cleanup_in_class=True, **kwargs): | 
 | 536 |         client = client or cls.shares_v2_client | 
| Valeriy Ponomaryov | e92f09f | 2017-03-16 17:25:47 +0300 | [diff] [blame] | 537 |         if (group_specs is None and | 
 | 538 |                 CONF.share.capability_sg_consistent_snapshot_support): | 
| Valeriy Ponomaryov | 3c18893 | 2017-03-15 19:06:23 +0300 | [diff] [blame] | 539 |             group_specs = { | 
 | 540 |                 'consistent_snapshot_support': ( | 
 | 541 |                     CONF.share.capability_sg_consistent_snapshot_support), | 
 | 542 |             } | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 543 |         share_group_type = client.create_share_group_type( | 
 | 544 |             name=name, | 
 | 545 |             share_types=share_types, | 
 | 546 |             is_public=is_public, | 
 | 547 |             group_specs=group_specs, | 
 | 548 |             **kwargs) | 
 | 549 |         resource = { | 
 | 550 |             "type": "share_group_type", | 
 | 551 |             "id": share_group_type["id"], | 
 | 552 |             "client": client, | 
 | 553 |         } | 
 | 554 |         if cleanup_in_class: | 
 | 555 |             cls.class_resources.insert(0, resource) | 
 | 556 |         else: | 
 | 557 |             cls.method_resources.insert(0, resource) | 
 | 558 |         return share_group_type | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 559 |  | 
 | 560 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 561 |     def create_snapshot_wait_for_active(cls, share_id, name=None, | 
 | 562 |                                         description=None, force=False, | 
 | 563 |                                         client=None, cleanup_in_class=True): | 
 | 564 |         if client is None: | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 565 |             client = cls.shares_v2_client | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 566 |         if description is None: | 
 | 567 |             description = "Tempest's snapshot" | 
 | 568 |         snapshot = client.create_snapshot(share_id, name, description, force) | 
 | 569 |         resource = { | 
 | 570 |             "type": "snapshot", | 
 | 571 |             "id": snapshot["id"], | 
 | 572 |             "client": client, | 
 | 573 |         } | 
 | 574 |         if cleanup_in_class: | 
 | 575 |             cls.class_resources.insert(0, resource) | 
 | 576 |         else: | 
 | 577 |             cls.method_resources.insert(0, resource) | 
 | 578 |         client.wait_for_snapshot_status(snapshot["id"], "available") | 
 | 579 |         return snapshot | 
 | 580 |  | 
 | 581 |     @classmethod | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 582 |     def create_share_group_snapshot_wait_for_active( | 
 | 583 |             cls, share_group_id, name=None, description=None, client=None, | 
 | 584 |             cleanup_in_class=True, **kwargs): | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 585 |         client = client or cls.shares_v2_client | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 586 |         if description is None: | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 587 |             description = "Tempest's share group snapshot" | 
 | 588 |         sg_snapshot = client.create_share_group_snapshot( | 
 | 589 |             share_group_id, name=name, description=description, **kwargs) | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 590 |         resource = { | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 591 |             "type": "share_group_snapshot", | 
 | 592 |             "id": sg_snapshot["id"], | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 593 |             "client": client, | 
 | 594 |         } | 
 | 595 |         if cleanup_in_class: | 
 | 596 |             cls.class_resources.insert(0, resource) | 
 | 597 |         else: | 
 | 598 |             cls.method_resources.insert(0, resource) | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 599 |         client.wait_for_share_group_snapshot_status( | 
 | 600 |             sg_snapshot["id"], "available") | 
 | 601 |         return sg_snapshot | 
| Andrew Kerr | bf31e91 | 2015-07-29 10:39:38 -0400 | [diff] [blame] | 602 |  | 
 | 603 |     @classmethod | 
| Goutham Pacha Ravi | 839c98b | 2019-01-14 23:16:23 -0800 | [diff] [blame] | 604 |     def get_availability_zones(cls, client=None, backends=None): | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 605 |         """List the availability zones for "manila-share" services | 
 | 606 |  | 
 | 607 |          that are currently in "up" state. | 
 | 608 |          """ | 
| Goutham Pacha Ravi | 839c98b | 2019-01-14 23:16:23 -0800 | [diff] [blame] | 609 |         client = client or cls.admin_shares_v2_client | 
 | 610 |         backends = ( | 
 | 611 |             '|'.join(['^%s$' % backend for backend in backends]) | 
 | 612 |             if backends else '.*' | 
 | 613 |         ) | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 614 |         cls.services = client.list_services() | 
 | 615 |         zones = [service['zone'] for service in cls.services if | 
| Goutham Pacha Ravi | 839c98b | 2019-01-14 23:16:23 -0800 | [diff] [blame] | 616 |                  service['binary'] == 'manila-share' and | 
 | 617 |                  service['state'] == 'up' and | 
 | 618 |                  re.search(backends, service['host'])] | 
| Douglas Viroel | 161f180 | 2020-04-25 17:18:14 -0300 | [diff] [blame] | 619 |         return list(set(zones)) | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 620 |  | 
| Goutham Pacha Ravi | 839c98b | 2019-01-14 23:16:23 -0800 | [diff] [blame] | 621 |     @classmethod | 
 | 622 |     def get_pools_matching_share_type(cls, share_type, client=None): | 
 | 623 |         client = client or cls.admin_shares_v2_client | 
 | 624 |         if utils.is_microversion_supported('2.23'): | 
 | 625 |             return client.list_pools( | 
| andrebeltrami | 3b4d485 | 2020-02-04 19:11:54 +0000 | [diff] [blame] | 626 |                 detail=True, | 
| Goutham Pacha Ravi | 839c98b | 2019-01-14 23:16:23 -0800 | [diff] [blame] | 627 |                 search_opts={'share_type': share_type['id']})['pools'] | 
 | 628 |  | 
 | 629 |         pools = client.list_pools(detail=True)['pools'] | 
 | 630 |         share_type = client.get_share_type(share_type['id'])['share_type'] | 
 | 631 |         extra_specs = {} | 
 | 632 |         for k, v in share_type['extra_specs'].items(): | 
 | 633 |             extra_specs[k] = ( | 
 | 634 |                 True if six.text_type(v).lower() == 'true' | 
 | 635 |                 else False if six.text_type(v).lower() == 'false' else v | 
 | 636 |             ) | 
 | 637 |         return [ | 
 | 638 |             pool for pool in pools if all(y in pool['capabilities'].items() | 
 | 639 |                                           for y in extra_specs.items()) | 
 | 640 |         ] | 
 | 641 |  | 
 | 642 |     @classmethod | 
 | 643 |     def get_availability_zones_matching_share_type(cls, share_type, | 
 | 644 |                                                    client=None): | 
 | 645 |  | 
 | 646 |         client = client or cls.admin_shares_v2_client | 
 | 647 |         pools_matching_share_type = cls.get_pools_matching_share_type( | 
 | 648 |             share_type, client=client) | 
 | 649 |         backends_matching_share_type = set( | 
 | 650 |             [pool['name'].split("#")[0] for pool in pools_matching_share_type] | 
 | 651 |         ) | 
 | 652 |         azs = cls.get_availability_zones(backends=backends_matching_share_type) | 
 | 653 |         return azs | 
 | 654 |  | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 655 |     def get_pools_for_replication_domain(self): | 
 | 656 |         # Get the list of pools for the replication domain | 
 | 657 |         pools = self.admin_client.list_pools(detail=True)['pools'] | 
| Ben Swartzlander | 7150c65 | 2017-02-13 22:31:18 -0500 | [diff] [blame] | 658 |         instance_host = self.admin_client.get_share( | 
 | 659 |             self.shares[0]['id'])['host'] | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 660 |         host_pool = [p for p in pools if p['name'] == instance_host][0] | 
 | 661 |         rep_domain = host_pool['capabilities']['replication_domain'] | 
 | 662 |         pools_in_rep_domain = [p for p in pools if p['capabilities'][ | 
 | 663 |             'replication_domain'] == rep_domain] | 
 | 664 |         return rep_domain, pools_in_rep_domain | 
 | 665 |  | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 666 |     @classmethod | 
 | 667 |     def create_share_replica(cls, share_id, availability_zone, client=None, | 
 | 668 |                              cleanup_in_class=False, cleanup=True): | 
 | 669 |         client = client or cls.shares_v2_client | 
| Douglas Viroel | bd4e78c | 2019-09-02 17:16:30 -0300 | [diff] [blame] | 670 |         replica = client.create_share_replica( | 
 | 671 |             share_id, availability_zone=availability_zone) | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 672 |         resource = { | 
 | 673 |             "type": "share_replica", | 
 | 674 |             "id": replica["id"], | 
 | 675 |             "client": client, | 
 | 676 |             "share_id": share_id, | 
 | 677 |         } | 
 | 678 |         # NOTE(Yogi1): Cleanup needs to be disabled during promotion tests. | 
 | 679 |         if cleanup: | 
 | 680 |             if cleanup_in_class: | 
 | 681 |                 cls.class_resources.insert(0, resource) | 
 | 682 |             else: | 
 | 683 |                 cls.method_resources.insert(0, resource) | 
 | 684 |         client.wait_for_share_replica_status( | 
 | 685 |             replica["id"], constants.STATUS_AVAILABLE) | 
 | 686 |         return replica | 
 | 687 |  | 
 | 688 |     @classmethod | 
 | 689 |     def delete_share_replica(cls, replica_id, client=None): | 
 | 690 |         client = client or cls.shares_v2_client | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 691 |         try: | 
 | 692 |             client.delete_share_replica(replica_id) | 
 | 693 |             client.wait_for_resource_deletion(replica_id=replica_id) | 
 | 694 |         except exceptions.NotFound: | 
 | 695 |             pass | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 696 |  | 
 | 697 |     @classmethod | 
 | 698 |     def promote_share_replica(cls, replica_id, client=None): | 
 | 699 |         client = client or cls.shares_v2_client | 
 | 700 |         replica = client.promote_share_replica(replica_id) | 
 | 701 |         client.wait_for_share_replica_status( | 
 | 702 |             replica["id"], | 
 | 703 |             constants.REPLICATION_STATE_ACTIVE, | 
 | 704 |             status_attr="replica_state") | 
 | 705 |         return replica | 
 | 706 |  | 
| Goutham Pacha Ravi | 1727f7a | 2020-05-22 13:41:40 -0700 | [diff] [blame] | 707 |     @classmethod | 
 | 708 |     def _get_access_rule_data_from_config(cls): | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 709 |         """Get the first available access type/to combination from config. | 
 | 710 |  | 
 | 711 |         This method opportunistically picks the first configured protocol | 
 | 712 |         to create the share. Do not use this method in tests where you need | 
 | 713 |         to test depth and breadth in the access types and access recipients. | 
 | 714 |         """ | 
| Goutham Pacha Ravi | 1727f7a | 2020-05-22 13:41:40 -0700 | [diff] [blame] | 715 |         protocol = cls.shares_v2_client.share_protocol | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 716 |  | 
 | 717 |         if protocol in CONF.share.enable_ip_rules_for_protocols: | 
 | 718 |             access_type = "ip" | 
 | 719 |             access_to = utils.rand_ip() | 
 | 720 |         elif protocol in CONF.share.enable_user_rules_for_protocols: | 
 | 721 |             access_type = "user" | 
 | 722 |             access_to = CONF.share.username_for_user_rules | 
 | 723 |         elif protocol in CONF.share.enable_cert_rules_for_protocols: | 
 | 724 |             access_type = "cert" | 
 | 725 |             access_to = "client3.com" | 
 | 726 |         elif protocol in CONF.share.enable_cephx_rules_for_protocols: | 
 | 727 |             access_type = "cephx" | 
 | 728 |             access_to = "eve" | 
 | 729 |         else: | 
 | 730 |             message = "Unrecognized protocol and access rules configuration." | 
| Goutham Pacha Ravi | 1727f7a | 2020-05-22 13:41:40 -0700 | [diff] [blame] | 731 |             raise cls.skipException(message) | 
| yogesh | db32f46 | 2016-09-28 15:09:50 -0400 | [diff] [blame] | 732 |  | 
 | 733 |         return access_type, access_to | 
 | 734 |  | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 735 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 736 |     def create_share_network(cls, client=None, | 
 | 737 |                              cleanup_in_class=False, **kwargs): | 
 | 738 |         if client is None: | 
 | 739 |             client = cls.shares_client | 
 | 740 |         share_network = client.create_share_network(**kwargs) | 
 | 741 |         resource = { | 
 | 742 |             "type": "share_network", | 
 | 743 |             "id": share_network["id"], | 
 | 744 |             "client": client, | 
 | 745 |         } | 
 | 746 |         if cleanup_in_class: | 
 | 747 |             cls.class_resources.insert(0, resource) | 
 | 748 |         else: | 
 | 749 |             cls.method_resources.insert(0, resource) | 
 | 750 |         return share_network | 
 | 751 |  | 
 | 752 |     @classmethod | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 753 |     def create_share_network_subnet(cls, client=None, | 
 | 754 |                                     cleanup_in_class=False, **kwargs): | 
 | 755 |         if client is None: | 
 | 756 |             client = cls.shares_v2_client | 
 | 757 |         share_network_subnet = client.create_subnet(**kwargs) | 
 | 758 |         resource = { | 
 | 759 |             "type": "share-network-subnet", | 
 | 760 |             "id": share_network_subnet["id"], | 
 | 761 |             "extra_params": { | 
 | 762 |                 "share_network_id": share_network_subnet["share_network_id"] | 
 | 763 |             }, | 
 | 764 |             "client": client, | 
 | 765 |         } | 
 | 766 |         if cleanup_in_class: | 
 | 767 |             cls.class_resources.insert(0, resource) | 
 | 768 |         else: | 
 | 769 |             cls.method_resources.insert(0, resource) | 
 | 770 |         return share_network_subnet | 
 | 771 |  | 
 | 772 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 773 |     def create_security_service(cls, ss_type="ldap", client=None, | 
 | 774 |                                 cleanup_in_class=False, **kwargs): | 
 | 775 |         if client is None: | 
 | 776 |             client = cls.shares_client | 
 | 777 |         security_service = client.create_security_service(ss_type, **kwargs) | 
 | 778 |         resource = { | 
 | 779 |             "type": "security_service", | 
 | 780 |             "id": security_service["id"], | 
 | 781 |             "client": client, | 
 | 782 |         } | 
 | 783 |         if cleanup_in_class: | 
 | 784 |             cls.class_resources.insert(0, resource) | 
 | 785 |         else: | 
 | 786 |             cls.method_resources.insert(0, resource) | 
 | 787 |         return security_service | 
 | 788 |  | 
 | 789 |     @classmethod | 
 | 790 |     def create_share_type(cls, name, is_public=True, client=None, | 
 | 791 |                           cleanup_in_class=True, **kwargs): | 
 | 792 |         if client is None: | 
| Valeriy Ponomaryov | a14c225 | 2015-10-29 13:34:32 +0200 | [diff] [blame] | 793 |             client = cls.shares_v2_client | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 794 |         share_type = client.create_share_type(name, is_public, **kwargs) | 
 | 795 |         resource = { | 
 | 796 |             "type": "share_type", | 
 | 797 |             "id": share_type["share_type"]["id"], | 
 | 798 |             "client": client, | 
 | 799 |         } | 
 | 800 |         if cleanup_in_class: | 
 | 801 |             cls.class_resources.insert(0, resource) | 
 | 802 |         else: | 
 | 803 |             cls.method_resources.insert(0, resource) | 
 | 804 |         return share_type | 
 | 805 |  | 
| haixin | 0d1d29f | 2019-08-02 16:50:45 +0800 | [diff] [blame] | 806 |     @classmethod | 
 | 807 |     def update_share_type(cls, share_type_id, name=None, | 
 | 808 |                           is_public=None, description=None, | 
 | 809 |                           client=None): | 
 | 810 |         if client is None: | 
 | 811 |             client = cls.shares_v2_client | 
 | 812 |         share_type = client.update_share_type(share_type_id, name, | 
 | 813 |                                               is_public, description) | 
 | 814 |         return share_type | 
 | 815 |  | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 816 |     @classmethod | 
 | 817 |     def update_quotas(cls, project_id, user_id=None, cleanup=True, | 
 | 818 |                       client=None, **kwargs): | 
 | 819 |         client = client or cls.shares_v2_client | 
 | 820 |         updated_quotas = client.update_quotas(project_id, | 
 | 821 |                                               user_id=user_id, | 
 | 822 |                                               **kwargs) | 
 | 823 |         resource = { | 
 | 824 |             "type": "quotas", | 
 | 825 |             "id": project_id, | 
 | 826 |             "client": client, | 
 | 827 |             "user_id": user_id, | 
 | 828 |         } | 
 | 829 |         if cleanup: | 
 | 830 |             cls.method_resources.insert(0, resource) | 
 | 831 |         return updated_quotas | 
 | 832 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 833 |     @staticmethod | 
| Clinton Knight | 4699a8c | 2016-08-16 22:36:13 -0400 | [diff] [blame] | 834 |     def add_extra_specs_to_dict(extra_specs=None): | 
 | 835 |         """Add any required extra-specs to share type dictionary""" | 
| Valeriy Ponomaryov | ad55dc5 | 2015-09-23 13:54:00 +0300 | [diff] [blame] | 836 |         dhss = six.text_type(CONF.share.multitenancy_enabled) | 
 | 837 |         snapshot_support = six.text_type( | 
 | 838 |             CONF.share.capability_snapshot_support) | 
| Clinton Knight | 4699a8c | 2016-08-16 22:36:13 -0400 | [diff] [blame] | 839 |         create_from_snapshot_support = six.text_type( | 
 | 840 |             CONF.share.capability_create_share_from_snapshot_support) | 
 | 841 |  | 
 | 842 |         extra_specs_dict = { | 
| Valeriy Ponomaryov | ad55dc5 | 2015-09-23 13:54:00 +0300 | [diff] [blame] | 843 |             "driver_handles_share_servers": dhss, | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 844 |         } | 
| Clinton Knight | 4699a8c | 2016-08-16 22:36:13 -0400 | [diff] [blame] | 845 |  | 
 | 846 |         optional = { | 
 | 847 |             "snapshot_support": snapshot_support, | 
 | 848 |             "create_share_from_snapshot_support": create_from_snapshot_support, | 
 | 849 |         } | 
 | 850 |         # NOTE(gouthamr): In micro-versions < 2.24, snapshot_support is a | 
 | 851 |         # required extra-spec | 
 | 852 |         extra_specs_dict.update(optional) | 
 | 853 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 854 |         if extra_specs: | 
| Clinton Knight | 4699a8c | 2016-08-16 22:36:13 -0400 | [diff] [blame] | 855 |             extra_specs_dict.update(extra_specs) | 
 | 856 |  | 
 | 857 |         return extra_specs_dict | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 858 |  | 
 | 859 |     @classmethod | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 860 |     def clear_share_replicas(cls, share_id, client=None): | 
 | 861 |         client = client or cls.shares_v2_client | 
 | 862 |         share_replicas = client.list_share_replicas( | 
 | 863 |             share_id=share_id) | 
 | 864 |  | 
 | 865 |         for replica in share_replicas: | 
 | 866 |             try: | 
 | 867 |                 cls.delete_share_replica(replica['id']) | 
 | 868 |             except exceptions.BadRequest: | 
 | 869 |                 # Ignore the exception due to deletion of last active replica | 
 | 870 |                 pass | 
 | 871 |  | 
 | 872 |     @classmethod | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 873 |     def clear_resources(cls, resources=None): | 
 | 874 |         """Deletes resources, that were created in test suites. | 
 | 875 |  | 
 | 876 |         This method tries to remove resources from resource list, | 
 | 877 |         if it is not found, assumed it was deleted in test itself. | 
 | 878 |         It is expected, that all resources were added as LIFO | 
 | 879 |         due to restriction of deletion resources, that is in the chain. | 
 | 880 |  | 
 | 881 |         :param resources: dict with keys 'type','id','client' and 'deleted' | 
 | 882 |         """ | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 883 |         if resources is None: | 
 | 884 |             resources = cls.method_resources | 
 | 885 |         for res in resources: | 
 | 886 |             if "deleted" not in res.keys(): | 
 | 887 |                 res["deleted"] = False | 
 | 888 |             if "client" not in res.keys(): | 
 | 889 |                 res["client"] = cls.shares_client | 
 | 890 |             if not(res["deleted"]): | 
 | 891 |                 res_id = res['id'] | 
 | 892 |                 client = res["client"] | 
 | 893 |                 with handle_cleanup_exceptions(): | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 894 |                     if res["type"] == "share": | 
| Yogesh | 1f931ff | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 895 |                         cls.clear_share_replicas(res_id) | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 896 |                         share_group_id = res.get('share_group_id') | 
 | 897 |                         if share_group_id: | 
 | 898 |                             params = {'share_group_id': share_group_id} | 
| Clinton Knight | e5c8f09 | 2015-08-27 15:00:23 -0400 | [diff] [blame] | 899 |                             client.delete_share(res_id, params=params) | 
 | 900 |                         else: | 
 | 901 |                             client.delete_share(res_id) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 902 |                         client.wait_for_resource_deletion(share_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 903 |                     elif res["type"] == "snapshot": | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 904 |                         client.delete_snapshot(res_id) | 
 | 905 |                         client.wait_for_resource_deletion(snapshot_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 906 |                     elif (res["type"] == "share_network" and | 
| yogesh | 06f519f | 2017-06-26 13:16:12 -0400 | [diff] [blame] | 907 |                             res_id != CONF.share.share_network_id): | 
| Victoria Martinez de la Cruz | cad9201 | 2018-06-08 14:46:35 -0400 | [diff] [blame] | 908 |                         client.delete_share_network(res_id) | 
 | 909 |                         client.wait_for_resource_deletion(sn_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 910 |                     elif res["type"] == "security_service": | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 911 |                         client.delete_security_service(res_id) | 
 | 912 |                         client.wait_for_resource_deletion(ss_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 913 |                     elif res["type"] == "share_type": | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 914 |                         client.delete_share_type(res_id) | 
 | 915 |                         client.wait_for_resource_deletion(st_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 916 |                     elif res["type"] == "share_group": | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 917 |                         client.delete_share_group(res_id) | 
 | 918 |                         client.wait_for_resource_deletion( | 
 | 919 |                             share_group_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 920 |                     elif res["type"] == "share_group_type": | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 921 |                         client.delete_share_group_type(res_id) | 
 | 922 |                         client.wait_for_resource_deletion( | 
 | 923 |                             share_group_type_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 924 |                     elif res["type"] == "share_group_snapshot": | 
| Andrew Kerr | b843692 | 2016-06-01 15:32:43 -0400 | [diff] [blame] | 925 |                         client.delete_share_group_snapshot(res_id) | 
 | 926 |                         client.wait_for_resource_deletion( | 
 | 927 |                             share_group_snapshot_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 928 |                     elif res["type"] == "share_replica": | 
| Yogesh | bdb8810 | 2015-09-29 23:41:02 -0400 | [diff] [blame] | 929 |                         client.delete_share_replica(res_id) | 
 | 930 |                         client.wait_for_resource_deletion(replica_id=res_id) | 
| Andreas Jaeger | 0cb685b | 2020-04-01 13:38:38 +0200 | [diff] [blame] | 931 |                     elif res["type"] == "share_network_subnet": | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 932 |                         sn_id = res["extra_params"]["share_network_id"] | 
 | 933 |                         client.delete_subnet(sn_id, res_id) | 
 | 934 |                         client.wait_for_resource_deletion( | 
 | 935 |                             share_network_subnet_id=res_id, | 
 | 936 |                             sn_id=sn_id) | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 937 |                     elif res["type"] == "quotas": | 
 | 938 |                         user_id = res.get('user_id') | 
 | 939 |                         client.reset_quotas(res_id, user_id=user_id) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 940 |                     else: | 
| huayue | 97bacbf | 2016-01-04 09:57:39 +0800 | [diff] [blame] | 941 |                         LOG.warning("Provided unsupported resource type for " | 
| junboli | b236c24 | 2017-07-18 18:12:37 +0800 | [diff] [blame] | 942 |                                     "cleanup '%s'. Skipping.", res["type"]) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 943 |                 res["deleted"] = True | 
 | 944 |  | 
 | 945 |     @classmethod | 
 | 946 |     def generate_share_network_data(self): | 
 | 947 |         data = { | 
 | 948 |             "name": data_utils.rand_name("sn-name"), | 
 | 949 |             "description": data_utils.rand_name("sn-desc"), | 
 | 950 |             "neutron_net_id": data_utils.rand_name("net-id"), | 
 | 951 |             "neutron_subnet_id": data_utils.rand_name("subnet-id"), | 
 | 952 |         } | 
 | 953 |         return data | 
 | 954 |  | 
 | 955 |     @classmethod | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 956 |     def generate_subnet_data(self): | 
 | 957 |         data = { | 
 | 958 |             "neutron_net_id": data_utils.rand_name("net-id"), | 
 | 959 |             "neutron_subnet_id": data_utils.rand_name("subnet-id"), | 
 | 960 |         } | 
 | 961 |         return data | 
 | 962 |  | 
 | 963 |     @classmethod | 
| Maurice Schreiber | 5ac3717 | 2018-02-01 15:17:31 +0100 | [diff] [blame] | 964 |     def generate_security_service_data(self, set_ou=False): | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 965 |         data = { | 
 | 966 |             "name": data_utils.rand_name("ss-name"), | 
 | 967 |             "description": data_utils.rand_name("ss-desc"), | 
| Valeriy Ponomaryov | fcde771 | 2015-12-14 18:06:13 +0200 | [diff] [blame] | 968 |             "dns_ip": utils.rand_ip(), | 
 | 969 |             "server": utils.rand_ip(), | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 970 |             "domain": data_utils.rand_name("ss-domain"), | 
 | 971 |             "user": data_utils.rand_name("ss-user"), | 
 | 972 |             "password": data_utils.rand_name("ss-password"), | 
 | 973 |         } | 
| Maurice Schreiber | 5ac3717 | 2018-02-01 15:17:31 +0100 | [diff] [blame] | 974 |         if set_ou: | 
 | 975 |             data["ou"] = data_utils.rand_name("ss-ou") | 
 | 976 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 977 |         return data | 
 | 978 |  | 
 | 979 |     # Useful assertions | 
 | 980 |     def assertDictMatch(self, d1, d2, approx_equal=False, tolerance=0.001): | 
 | 981 |         """Assert two dicts are equivalent. | 
 | 982 |  | 
 | 983 |         This is a 'deep' match in the sense that it handles nested | 
 | 984 |         dictionaries appropriately. | 
 | 985 |  | 
 | 986 |         NOTE: | 
 | 987 |  | 
 | 988 |             If you don't care (or don't know) a given value, you can specify | 
 | 989 |             the string DONTCARE as the value. This will cause that dict-item | 
 | 990 |             to be skipped. | 
 | 991 |  | 
 | 992 |         """ | 
 | 993 |         def raise_assertion(msg): | 
 | 994 |             d1str = str(d1) | 
 | 995 |             d2str = str(d2) | 
 | 996 |             base_msg = ('Dictionaries do not match. %(msg)s d1: %(d1str)s ' | 
 | 997 |                         'd2: %(d2str)s' % | 
 | 998 |                         {"msg": msg, "d1str": d1str, "d2str": d2str}) | 
 | 999 |             raise AssertionError(base_msg) | 
 | 1000 |  | 
 | 1001 |         d1keys = set(d1.keys()) | 
 | 1002 |         d2keys = set(d2.keys()) | 
 | 1003 |         if d1keys != d2keys: | 
 | 1004 |             d1only = d1keys - d2keys | 
 | 1005 |             d2only = d2keys - d1keys | 
 | 1006 |             raise_assertion('Keys in d1 and not d2: %(d1only)s. ' | 
 | 1007 |                             'Keys in d2 and not d1: %(d2only)s' % | 
 | 1008 |                             {"d1only": d1only, "d2only": d2only}) | 
 | 1009 |  | 
 | 1010 |         for key in d1keys: | 
 | 1011 |             d1value = d1[key] | 
 | 1012 |             d2value = d2[key] | 
 | 1013 |             try: | 
 | 1014 |                 error = abs(float(d1value) - float(d2value)) | 
 | 1015 |                 within_tolerance = error <= tolerance | 
 | 1016 |             except (ValueError, TypeError): | 
| daiki kato | 6914b1a | 2016-03-16 17:16:57 +0900 | [diff] [blame] | 1017 |                 # If both values aren't convertible to float, just ignore | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1018 |                 # ValueError if arg is a str, TypeError if it's something else | 
 | 1019 |                 # (like None) | 
 | 1020 |                 within_tolerance = False | 
 | 1021 |  | 
 | 1022 |             if hasattr(d1value, 'keys') and hasattr(d2value, 'keys'): | 
 | 1023 |                 self.assertDictMatch(d1value, d2value) | 
 | 1024 |             elif 'DONTCARE' in (d1value, d2value): | 
 | 1025 |                 continue | 
 | 1026 |             elif approx_equal and within_tolerance: | 
 | 1027 |                 continue | 
 | 1028 |             elif d1value != d2value: | 
 | 1029 |                 raise_assertion("d1['%(key)s']=%(d1value)s != " | 
 | 1030 |                                 "d2['%(key)s']=%(d2value)s" % | 
 | 1031 |                                 { | 
 | 1032 |                                     "key": key, | 
 | 1033 |                                     "d1value": d1value, | 
 | 1034 |                                     "d2value": d2value | 
 | 1035 |                                 }) | 
 | 1036 |  | 
| Alex Meade | ba8a160 | 2016-05-06 09:33:09 -0400 | [diff] [blame] | 1037 |     def create_user_message(self): | 
 | 1038 |         """Trigger a 'no valid host' situation to generate a message.""" | 
 | 1039 |         extra_specs = { | 
 | 1040 |             'vendor_name': 'foobar', | 
 | 1041 |             'driver_handles_share_servers': CONF.share.multitenancy_enabled, | 
 | 1042 |         } | 
 | 1043 |         share_type_name = data_utils.rand_name("share-type") | 
 | 1044 |  | 
 | 1045 |         bogus_type = self.create_share_type( | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 1046 |             client=self.admin_shares_v2_client, | 
| Alex Meade | ba8a160 | 2016-05-06 09:33:09 -0400 | [diff] [blame] | 1047 |             name=share_type_name, | 
 | 1048 |             extra_specs=extra_specs)['share_type'] | 
 | 1049 |  | 
 | 1050 |         params = {'share_type_id': bogus_type['id'], | 
 | 1051 |                   'share_network_id': self.shares_v2_client.share_network_id} | 
 | 1052 |         share = self.shares_v2_client.create_share(**params) | 
 | 1053 |         self.addCleanup(self.shares_v2_client.delete_share, share['id']) | 
 | 1054 |         self.shares_v2_client.wait_for_share_status(share['id'], "error") | 
 | 1055 |         return self.shares_v2_client.wait_for_message(share['id']) | 
 | 1056 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1057 |  | 
 | 1058 | class BaseSharesAltTest(BaseSharesTest): | 
 | 1059 |     """Base test case class for all Shares Alt API tests.""" | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 1060 |     credentials = ('alt', ) | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1061 |  | 
 | 1062 |  | 
 | 1063 | class BaseSharesAdminTest(BaseSharesTest): | 
 | 1064 |     """Base test case class for all Shares Admin API tests.""" | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 1065 |     credentials = ('admin', ) | 
 | 1066 |  | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1067 |     @classmethod | 
 | 1068 |     def setup_clients(cls): | 
 | 1069 |         super(BaseSharesAdminTest, cls).setup_clients() | 
 | 1070 |         # Initialise share clients | 
 | 1071 |         cls.admin_shares_v2_client = cls.os_admin.share_v2.SharesV2Client() | 
 | 1072 |  | 
 | 1073 |     @classmethod | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 1074 |     def _create_share_type(cls, is_public=True, specs=None): | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1075 |         name = data_utils.rand_name("unique_st_name") | 
 | 1076 |         extra_specs = cls.add_extra_specs_to_dict(specs) | 
 | 1077 |         return cls.create_share_type( | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 1078 |             name, extra_specs=extra_specs, is_public=is_public, | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1079 |             client=cls.admin_shares_v2_client)['share_type'] | 
 | 1080 |  | 
 | 1081 |     @classmethod | 
 | 1082 |     def _create_share_group_type(cls): | 
 | 1083 |         share_group_type_name = data_utils.rand_name("unique_sgtype_name") | 
 | 1084 |         return cls.create_share_group_type( | 
 | 1085 |             name=share_group_type_name, share_types=[cls.share_type_id], | 
 | 1086 |             client=cls.admin_shares_v2_client) | 
 | 1087 |  | 
| Lucio Seki | 3705694 | 2019-01-24 15:40:20 -0200 | [diff] [blame] | 1088 |     def _create_share_for_manage(self): | 
 | 1089 |         creation_data = { | 
 | 1090 |             'share_type_id': self.st['share_type']['id'], | 
 | 1091 |             'share_protocol': self.protocol, | 
 | 1092 |         } | 
 | 1093 |  | 
 | 1094 |         share = self.create_share(**creation_data) | 
 | 1095 |         share = self.shares_v2_client.get_share(share['id']) | 
 | 1096 |  | 
 | 1097 |         if utils.is_microversion_ge(CONF.share.max_api_microversion, "2.9"): | 
 | 1098 |             el = self.shares_v2_client.list_share_export_locations(share["id"]) | 
 | 1099 |             share["export_locations"] = el | 
 | 1100 |  | 
 | 1101 |         return share | 
 | 1102 |  | 
 | 1103 |     def _unmanage_share_and_wait(self, share): | 
 | 1104 |         self.shares_v2_client.unmanage_share(share['id']) | 
 | 1105 |         self.shares_v2_client.wait_for_resource_deletion(share_id=share['id']) | 
 | 1106 |  | 
 | 1107 |     def _reset_state_and_delete_share(self, share): | 
 | 1108 |         self.shares_v2_client.reset_state(share['id']) | 
 | 1109 |         self._delete_share_and_wait(share) | 
 | 1110 |  | 
 | 1111 |     def _delete_snapshot_and_wait(self, snap): | 
 | 1112 |         self.shares_v2_client.delete_snapshot(snap['id']) | 
 | 1113 |         self.shares_v2_client.wait_for_resource_deletion( | 
 | 1114 |             snapshot_id=snap['id'] | 
 | 1115 |         ) | 
 | 1116 |         self.assertRaises(exceptions.NotFound, | 
 | 1117 |                           self.shares_v2_client.get_snapshot, | 
 | 1118 |                           snap['id']) | 
 | 1119 |  | 
 | 1120 |     def _delete_share_and_wait(self, share): | 
 | 1121 |         self.shares_v2_client.delete_share(share['id']) | 
 | 1122 |         self.shares_v2_client.wait_for_resource_deletion(share_id=share['id']) | 
 | 1123 |         self.assertRaises(exceptions.NotFound, | 
 | 1124 |                           self.shares_v2_client.get_share, | 
 | 1125 |                           share['id']) | 
 | 1126 |  | 
 | 1127 |     def _manage_share(self, share, name, description, share_server_id): | 
 | 1128 |         managed_share = self.shares_v2_client.manage_share( | 
 | 1129 |             service_host=share['host'], | 
 | 1130 |             export_path=share['export_locations'][0], | 
 | 1131 |             protocol=share['share_proto'], | 
 | 1132 |             share_type_id=self.share_type['share_type']['id'], | 
 | 1133 |             name=name, | 
 | 1134 |             description=description, | 
 | 1135 |             share_server_id=share_server_id | 
 | 1136 |         ) | 
 | 1137 |         self.shares_v2_client.wait_for_share_status( | 
 | 1138 |             managed_share['id'], constants.STATUS_AVAILABLE | 
 | 1139 |         ) | 
 | 1140 |  | 
 | 1141 |         return managed_share | 
 | 1142 |  | 
 | 1143 |     def _unmanage_share_server_and_wait(self, server): | 
 | 1144 |         self.shares_v2_client.unmanage_share_server(server['id']) | 
 | 1145 |         self.shares_v2_client.wait_for_resource_deletion( | 
 | 1146 |             server_id=server['id'] | 
 | 1147 |         ) | 
 | 1148 |  | 
 | 1149 |     def _manage_share_server(self, share_server, fields=None): | 
 | 1150 |         params = fields or {} | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 1151 |         subnet_id = params.get('share_network_subnet_id', None) | 
| Lucio Seki | 3705694 | 2019-01-24 15:40:20 -0200 | [diff] [blame] | 1152 |         managed_share_server = self.shares_v2_client.manage_share_server( | 
 | 1153 |             params.get('host', share_server['host']), | 
 | 1154 |             params.get('share_network_id', share_server['share_network_id']), | 
 | 1155 |             params.get('identifier', share_server['identifier']), | 
| Douglas Viroel | b7e27e7 | 2019-08-06 19:40:37 -0300 | [diff] [blame] | 1156 |             share_network_subnet_id=subnet_id, | 
| Lucio Seki | 3705694 | 2019-01-24 15:40:20 -0200 | [diff] [blame] | 1157 |         ) | 
 | 1158 |         self.shares_v2_client.wait_for_share_server_status( | 
 | 1159 |             managed_share_server['id'], | 
 | 1160 |             constants.SERVER_STATE_ACTIVE, | 
 | 1161 |         ) | 
 | 1162 |  | 
 | 1163 |         return managed_share_server | 
 | 1164 |  | 
 | 1165 |     def _delete_share_server_and_wait(self, share_server_id): | 
 | 1166 |         self.shares_v2_client.delete_share_server( | 
 | 1167 |             share_server_id | 
 | 1168 |         ) | 
 | 1169 |         self.shares_v2_client.wait_for_resource_deletion( | 
 | 1170 |             server_id=share_server_id) | 
 | 1171 |  | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 1172 |  | 
 | 1173 | class BaseSharesMixedTest(BaseSharesTest): | 
 | 1174 |     """Base test case class for all Shares API tests with all user roles.""" | 
 | 1175 |     credentials = ('primary', 'alt', 'admin') | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1176 |  | 
| Goutham Pacha Ravi | c678e21 | 2020-03-20 11:13:47 -0700 | [diff] [blame] | 1177 |     # Will be cleaned up in resource_cleanup if the class | 
 | 1178 |     class_project_users_created = [] | 
 | 1179 |  | 
 | 1180 |     @classmethod | 
 | 1181 |     def resource_cleanup(cls): | 
 | 1182 |         cls.clear_project_users(cls.class_project_users_created) | 
 | 1183 |         super(BaseSharesMixedTest, cls).resource_cleanup() | 
 | 1184 |  | 
 | 1185 |     @classmethod | 
 | 1186 |     def clear_project_users(cls, users=None): | 
 | 1187 |         users = users or cls.class_project_users_created | 
 | 1188 |         for user in users: | 
 | 1189 |             with handle_cleanup_exceptions(): | 
 | 1190 |                 cls.os_admin.creds_client.delete_user(user['id']) | 
 | 1191 |  | 
| Marc Koderer | 0abc93b | 2015-07-15 09:18:35 +0200 | [diff] [blame] | 1192 |     @classmethod | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 1193 |     def setup_clients(cls): | 
 | 1194 |         super(BaseSharesMixedTest, cls).setup_clients() | 
| Andrea Frittoli (andreaf) | 369391a | 2016-06-27 18:59:13 +0100 | [diff] [blame] | 1195 |         # Initialise share clients | 
 | 1196 |         cls.admin_shares_client = cls.os_admin.share_v1.SharesClient() | 
 | 1197 |         cls.admin_shares_v2_client = cls.os_admin.share_v2.SharesV2Client() | 
 | 1198 |         cls.alt_shares_client = cls.os_alt.share_v1.SharesClient() | 
 | 1199 |         cls.alt_shares_v2_client = cls.os_alt.share_v2.SharesV2Client() | 
 | 1200 |         # Initialise network clients | 
 | 1201 |         cls.os_admin.networks_client = cls.os_admin.network.NetworksClient() | 
 | 1202 |         cls.os_alt.networks_client = cls.os_alt.network.NetworksClient() | 
| Goutham Pacha Ravi | c678e21 | 2020-03-20 11:13:47 -0700 | [diff] [blame] | 1203 |         # Initialise identity clients | 
 | 1204 |         cls.admin_project = cls.os_admin.auth_provider.auth_data[1]['project'] | 
 | 1205 |         identity_clients = getattr( | 
 | 1206 |             cls.os_admin, 'identity_%s' % CONF.identity.auth_version) | 
 | 1207 |         cls.os_admin.identity_client = identity_clients.IdentityClient() | 
 | 1208 |         cls.os_admin.projects_client = identity_clients.ProjectsClient() | 
 | 1209 |         cls.os_admin.users_client = identity_clients.UsersClient() | 
 | 1210 |         cls.os_admin.roles_client = identity_clients.RolesClient() | 
 | 1211 |         cls.os_admin.domains_client = ( | 
 | 1212 |             cls.os_admin.identity_v3.DomainsClient() if | 
 | 1213 |             CONF.identity.auth_version == 'v3' else None) | 
 | 1214 |         cls.admin_project_member_client = cls.create_user_and_get_client() | 
| Valeriy Ponomaryov | 39cdf72 | 2016-05-30 18:16:15 +0300 | [diff] [blame] | 1215 |  | 
 | 1216 |         if CONF.share.multitenancy_enabled: | 
 | 1217 |             admin_share_network_id = cls.provide_share_network( | 
 | 1218 |                 cls.admin_shares_v2_client, cls.os_admin.networks_client) | 
 | 1219 |             cls.admin_shares_client.share_network_id = admin_share_network_id | 
 | 1220 |             cls.admin_shares_v2_client.share_network_id = ( | 
 | 1221 |                 admin_share_network_id) | 
 | 1222 |  | 
 | 1223 |             alt_share_network_id = cls.provide_share_network( | 
 | 1224 |                 cls.alt_shares_v2_client, cls.os_alt.networks_client) | 
 | 1225 |             cls.alt_shares_client.share_network_id = alt_share_network_id | 
 | 1226 |             cls.alt_shares_v2_client.share_network_id = alt_share_network_id | 
| haobing1 | 01c7fee | 2018-03-09 16:33:00 +0800 | [diff] [blame] | 1227 |             resource = { | 
 | 1228 |                 "type": "share_network", | 
 | 1229 |                 "id": alt_share_network_id, | 
 | 1230 |                 "client": cls.alt_shares_v2_client, | 
 | 1231 |             } | 
 | 1232 |             cls.class_resources.insert(0, resource) | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1233 |  | 
 | 1234 |     @classmethod | 
| Goutham Pacha Ravi | c678e21 | 2020-03-20 11:13:47 -0700 | [diff] [blame] | 1235 |     def create_user_and_get_client(cls, project=None): | 
 | 1236 |         """Create a user in specified project & set share clients for user | 
 | 1237 |  | 
 | 1238 |         The user will have all roles specified in tempest.conf | 
 | 1239 |         :param: project: a dictionary with project ID and name, if not | 
 | 1240 |             specified, the value will be cls.admin_project | 
 | 1241 |         """ | 
 | 1242 |         project_domain_name = ( | 
 | 1243 |             cls.os_admin.identity_client.auth_provider.credentials.get( | 
 | 1244 |                 'project_domain_name', 'Default')) | 
 | 1245 |         cls.os_admin.creds_client = cred_client.get_creds_client( | 
 | 1246 |             cls.os_admin.identity_client, cls.os_admin.projects_client, | 
 | 1247 |             cls.os_admin.users_client, cls.os_admin.roles_client, | 
 | 1248 |             cls.os_admin.domains_client, project_domain_name) | 
 | 1249 |  | 
 | 1250 |         # User info | 
 | 1251 |         project = project or cls.admin_project | 
 | 1252 |         username = data_utils.rand_name('manila_%s' % project['id']) | 
 | 1253 |         password = data_utils.rand_password() | 
 | 1254 |         email = '%s@example.org' % username | 
 | 1255 |  | 
 | 1256 |         user = cls.os_admin.creds_client.create_user( | 
 | 1257 |             username, password, project, email) | 
 | 1258 |         cls.class_project_users_created.append(user) | 
 | 1259 |  | 
 | 1260 |         for conf_role in CONF.auth.tempest_roles: | 
 | 1261 |             cls.os_admin.creds_client.assign_user_role( | 
 | 1262 |                 user, project, conf_role) | 
 | 1263 |  | 
 | 1264 |         user_creds = cls.os_admin.creds_client.get_credentials( | 
 | 1265 |             user, project, password) | 
 | 1266 |         os = clients.Clients(user_creds) | 
 | 1267 |         os.shares_v1_client = os.share_v1.SharesClient() | 
 | 1268 |         os.shares_v2_client = os.share_v2.SharesV2Client() | 
 | 1269 |         return os | 
 | 1270 |  | 
 | 1271 |     @classmethod | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 1272 |     def _create_share_type(cls, is_public=True, specs=None): | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1273 |         name = data_utils.rand_name("unique_st_name") | 
 | 1274 |         extra_specs = cls.add_extra_specs_to_dict(specs) | 
 | 1275 |         return cls.create_share_type( | 
| Goutham Pacha Ravi | af44826 | 2020-06-29 14:24:13 -0700 | [diff] [blame^] | 1276 |             name, extra_specs=extra_specs, is_public=is_public, | 
| Victoria Martinez de la Cruz | f6bc6fa | 2018-02-01 11:27:00 -0500 | [diff] [blame] | 1277 |             client=cls.admin_shares_v2_client)['share_type'] | 
 | 1278 |  | 
 | 1279 |     @classmethod | 
 | 1280 |     def _create_share_group_type(cls): | 
 | 1281 |         share_group_type_name = data_utils.rand_name("unique_sgtype_name") | 
 | 1282 |         return cls.create_share_group_type( | 
 | 1283 |             name=share_group_type_name, share_types=[cls.share_type_id], | 
 | 1284 |             client=cls.admin_shares_v2_client) |