Remove floating ip of second instance in cinder testcase
[functest.git] / functest / core / tenantnetwork.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2018 Orange and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 """Ease deploying tenant networks
11
12 It offers a simple way to create all tenant network ressources required by a
13 testcase (including all Functest ones):
14   - TenantNetwork1 selects the user and the project set as env vars
15   - TenantNetwork2 creates a user and project to isolate the same ressources
16
17 This classes could be reused by more complexed scenarios (Single VM)
18 """
19
20 import logging
21 import os
22 import time
23 import uuid
24
25 import os_client_config
26 import shade
27 from xtesting.core import testcase
28
29 from functest.utils import config
30 from functest.utils import env
31 from functest.utils import functest_utils
32
33
34 class NewProject(object):
35     """Ease creating new projects/users"""
36     # pylint: disable=too-many-instance-attributes
37
38     __logger = logging.getLogger(__name__)
39
40     def __init__(self, cloud, case_name, guid):
41         self.cloud = None
42         self.orig_cloud = cloud
43         self.case_name = case_name
44         self.guid = guid
45         self.project = None
46         self.user = None
47         self.password = None
48         self.domain = None
49
50     def create(self):
51         """Create projects/users"""
52         assert self.orig_cloud
53         assert self.case_name
54         self.password = str(uuid.uuid4())
55         self.domain = self.orig_cloud.get_domain(
56             name_or_id=self.orig_cloud.auth.get(
57                 "project_domain_name", "Default"))
58         self.project = self.orig_cloud.create_project(
59             name='{}-project_{}'.format(self.case_name, self.guid),
60             description="Created by OPNFV Functest: {}".format(
61                 self.case_name),
62             domain_id=self.domain.id)
63         self.__logger.debug("project: %s", self.project)
64         self.user = self.orig_cloud.create_user(
65             name='{}-user_{}'.format(self.case_name, self.guid),
66             password=self.password,
67             domain_id=self.domain.id)
68         self.__logger.debug("user: %s", self.user)
69         self.orig_cloud.grant_role(
70             "Member", user=self.user.id, project=self.project.id,
71             domain=self.domain.id)
72         osconfig = os_client_config.config.OpenStackConfig()
73         osconfig.cloud_config[
74             'clouds']['envvars']['project_name'] = self.project.name
75         osconfig.cloud_config['clouds']['envvars']['username'] = self.user.name
76         osconfig.cloud_config['clouds']['envvars']['password'] = self.password
77         self.__logger.debug("cloud_config %s", osconfig.cloud_config)
78         self.cloud = shade.OpenStackCloud(
79             cloud_config=osconfig.get_one_cloud())
80         self.__logger.debug("new cloud %s", self.cloud.auth)
81
82     def clean(self):
83         """Remove projects/users"""
84         try:
85             assert self.orig_cloud
86             assert self.user.id
87             assert self.project.id
88             self.orig_cloud.delete_user(self.user.id)
89             self.orig_cloud.delete_project(self.project.id)
90         except Exception:  # pylint: disable=broad-except
91             self.__logger.exception("Cannot clean all ressources")
92
93
94 class TenantNetwork1(testcase.TestCase):
95     # pylint: disable=too-many-instance-attributes
96     """Create a tenant network (scenario1)
97
98     It creates and configures all tenant network ressources required by
99     advanced testcases (subnet, network and router).
100
101     It ensures that all testcases inheriting from TenantNetwork1 could work
102     without network specific configurations (or at least read the same config
103     data).
104     """
105
106     __logger = logging.getLogger(__name__)
107     cidr = '192.168.0.0/24'
108
109     def __init__(self, **kwargs):
110         if "case_name" not in kwargs:
111             kwargs["case_name"] = 'tenantnetwork1'
112         super(TenantNetwork1, self).__init__(**kwargs)
113         self.res_dir = os.path.join(
114             getattr(config.CONF, 'dir_results'), self.case_name)
115         try:
116             cloud_config = os_client_config.get_config()
117             self.cloud = shade.OpenStackCloud(cloud_config=cloud_config)
118         except Exception:  # pylint: disable=broad-except
119             self.cloud = None
120             self.ext_net = None
121             self.__logger.exception("Cannot connect to Cloud")
122         try:
123             self.ext_net = functest_utils.get_external_network(self.cloud)
124         except Exception:  # pylint: disable=broad-except
125             self.__logger.exception("Cannot get the external network")
126         self.guid = str(uuid.uuid4())
127         self.network = None
128         self.subnet = None
129         self.router = None
130
131     def _create_network_ressources(self):
132         assert self.cloud
133         assert self.ext_net
134         provider = {}
135         if hasattr(config.CONF, '{}_network_type'.format(self.case_name)):
136             provider["network_type"] = getattr(
137                 config.CONF, '{}_network_type'.format(self.case_name))
138         if hasattr(config.CONF, '{}_physical_network'.format(self.case_name)):
139             provider["physical_network"] = getattr(
140                 config.CONF, '{}_physical_network'.format(self.case_name))
141         if hasattr(config.CONF, '{}_segmentation_id'.format(self.case_name)):
142             provider["segmentation_id"] = getattr(
143                 config.CONF, '{}_segmentation_id'.format(self.case_name))
144         self.network = self.cloud.create_network(
145             '{}-net_{}'.format(self.case_name, self.guid),
146             provider=provider)
147         self.__logger.debug("network: %s", self.network)
148
149         self.subnet = self.cloud.create_subnet(
150             self.network.id,
151             subnet_name='{}-subnet_{}'.format(self.case_name, self.guid),
152             cidr=getattr(
153                 config.CONF, '{}_private_subnet_cidr'.format(self.case_name),
154                 self.cidr),
155             enable_dhcp=True,
156             dns_nameservers=[env.get('NAMESERVER')])
157         self.__logger.debug("subnet: %s", self.subnet)
158
159         self.router = self.cloud.create_router(
160             name='{}-router_{}'.format(self.case_name, self.guid),
161             ext_gateway_net_id=self.ext_net.id)
162         self.__logger.debug("router: %s", self.router)
163         self.cloud.add_router_interface(self.router, subnet_id=self.subnet.id)
164
165     def run(self, **kwargs):
166         status = testcase.TestCase.EX_RUN_ERROR
167         try:
168             assert self.cloud
169             self.start_time = time.time()
170             self._create_network_ressources()
171             self.result = 100
172             status = testcase.TestCase.EX_OK
173         except Exception:  # pylint: disable=broad-except
174             self.__logger.exception('Cannot run %s', self.case_name)
175         finally:
176             self.stop_time = time.time()
177         return status
178
179     def clean(self):
180         try:
181             assert self.cloud
182             self.cloud.remove_router_interface(self.router, self.subnet.id)
183             self.cloud.delete_router(self.router.id)
184             self.cloud.delete_subnet(self.subnet.id)
185             self.cloud.delete_network(self.network.id)
186         except Exception:  # pylint: disable=broad-except
187             self.__logger.exception("cannot clean all ressources")
188
189
190 class TenantNetwork2(TenantNetwork1):
191     """Create a tenant network (scenario2)
192
193     It creates new user/project before creating and configuring all tenant
194     network ressources required by a testcase (subnet, network and router).
195
196     It ensures that all testcases inheriting from TenantNetwork2 could work
197     without network specific configurations (or at least read the same config
198     data).
199     """
200
201     __logger = logging.getLogger(__name__)
202
203     def __init__(self, **kwargs):
204         if "case_name" not in kwargs:
205             kwargs["case_name"] = 'tenantnetwork2'
206         super(TenantNetwork2, self).__init__(**kwargs)
207         try:
208             assert self.cloud
209             self.project = NewProject(
210                 self.cloud, self.case_name, self.guid)
211             self.project.create()
212             self.cloud = self.project.cloud
213         except Exception:  # pylint: disable=broad-except
214             self.__logger.exception("Cannot create user or project")
215             self.cloud = None
216             self.project = None
217
218     def clean(self):
219         try:
220             super(TenantNetwork2, self).clean()
221             assert self.project
222             self.project.clean()
223         except Exception:  # pylint: disable=broad-except
224             self.__logger.exception("Cannot clean all ressources")