Refactoring of NetworkSettings to extend NetworkConfig
[snaps.git] / snaps / openstack / os_credentials.py
1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 #                    and others.  All rights reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain 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,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 from neutronclient.common.utils import str2bool
16 import numbers
17 from snaps import file_utils
18 from snaps.openstack.utils import glance_utils, keystone_utils, cinder_utils
19
20 __author__ = 'spisarski'
21
22
23 class OSCreds:
24     """
25     Represents the credentials required to connect with OpenStack servers
26     """
27
28     def __init__(self, **kwargs):
29         """
30         Constructor
31         :param username: The user (required)
32         :param password: The user's password (required)
33         :param auth_url: The OpenStack cloud's authorization URL (required)
34         :param project_name: The project/tenant name
35         :param identity_api_version: The OpenStack's API version to use for
36                                      Keystone clients
37         :param image_api_version: The OpenStack's API version to use for Glance
38                                   clients
39         :param network_api_version: The OpenStack's API version to use for
40                                     Neutron clients
41         :param compute_api_version: The OpenStack's API version to use for Nova
42                                     clients
43         :param heat_api_version: The OpenStack's API version to use for Heat
44                                     clients
45         :param volume_api_version: The OpenStack's API version to use
46                                    for Cinder clients
47         :param magnum_api_version: The OpenStack's API version to use
48                                    for magnum clients
49         :param user_domain_id: Used for v3 APIs (default='default')
50         :param user_domain_name: Used for v3 APIs (default='Default')
51         :param project_domain_id: Used for v3 APIs (default='default')
52         :param project_domain_name: Used for v3 APIs (default='Default')
53         :param interface: Used to specify the endpoint type for keystone as
54                           public, admin, internal
55         :param proxy_settings: instance of os_credentials.ProxySettings class
56         :param cacert: True for https or the certification file for https
57                        verification (default=False)
58         :param region_name: the region (optional default = None)
59         """
60         self.username = kwargs.get('username')
61         self.password = kwargs.get('password')
62         self.auth_url = kwargs.get('auth_url')
63         self.project_name = kwargs.get('project_name')
64
65         if kwargs.get('identity_api_version') is None:
66             self.identity_api_version = keystone_utils.V2_VERSION_NUM
67         else:
68             self.identity_api_version = float(kwargs['identity_api_version'])
69
70         if kwargs.get('image_api_version') is None:
71             self.image_api_version = glance_utils.VERSION_2
72         else:
73             self.image_api_version = float(kwargs['image_api_version'])
74
75         if kwargs.get('network_api_version') is None:
76             self.network_api_version = 2
77         else:
78             self.network_api_version = float(kwargs['network_api_version'])
79
80         if kwargs.get('compute_api_version') is None:
81             self.compute_api_version = 2
82         else:
83             self.compute_api_version = float(kwargs['compute_api_version'])
84
85         if kwargs.get('heat_api_version') is None:
86             self.heat_api_version = 1
87         else:
88             self.heat_api_version = float(kwargs['heat_api_version'])
89
90         if kwargs.get('volume_api_version') is None:
91             self.volume_api_version = cinder_utils.VERSION_2
92         else:
93             self.volume_api_version = float(kwargs['volume_api_version'])
94
95         if kwargs.get('magnum_api_version') is None:
96             self.magnum_api_version = 1
97         else:
98             self.magnum_api_version = float(kwargs['magnum_api_version'])
99
100         self.user_domain_id = kwargs.get('user_domain_id', 'default')
101
102         if kwargs.get('user_domain_name') is None:
103             self.user_domain_name = 'Default'
104         else:
105             self.user_domain_name = kwargs['user_domain_name']
106
107         self.project_domain_id = kwargs.get('project_domain_id', 'default')
108
109         if kwargs.get('project_domain_name') is None:
110             self.project_domain_name = 'Default'
111         else:
112             self.project_domain_name = kwargs['project_domain_name']
113
114         if kwargs.get('interface') is None:
115             self.interface = 'public'
116         else:
117             self.interface = kwargs['interface']
118
119         self.region_name = kwargs.get('region_name', None)
120
121         self.cacert = False
122         if kwargs.get('cacert') is not None:
123             if isinstance(kwargs.get('cacert'), str):
124                 if file_utils.file_exists(kwargs['cacert']):
125                     self.cacert = kwargs['cacert']
126                 else:
127                     self.cacert = str2bool(kwargs['cacert'])
128             else:
129                 self.cacert = kwargs['cacert']
130
131         if isinstance(kwargs.get('proxy_settings'), ProxySettings):
132             self.proxy_settings = kwargs.get('proxy_settings')
133         elif isinstance(kwargs.get('proxy_settings'), dict):
134             self.proxy_settings = ProxySettings(**kwargs.get('proxy_settings'))
135         else:
136             self.proxy_settings = None
137
138         if (not self.username or not self.password or not self.auth_url
139                 or not self.project_name):
140             raise OSCredsError('username, password, auth_url, and project_name'
141                                ' are required')
142
143         self.auth_url = self.__scrub_auth_url()
144
145     def __scrub_auth_url(self):
146         """
147         As the Python APIs are have more stringent requirements around how the
148         auth_url is formed than the CLI, this method will scrub any version
149         from the end of
150         :return:
151         """
152         auth_url_tokens = self.auth_url.rstrip('/').split('/')
153         last_token = auth_url_tokens[len(auth_url_tokens) - 1]
154         token_iters = len(auth_url_tokens)
155         if last_token.startswith('v'):
156             token_iters -= 1
157         if self.identity_api_version == keystone_utils.V2_VERSION_NUM:
158             last_token = keystone_utils.V2_VERSION_STR
159         else:
160             last_token = 'v' + str(int(self.identity_api_version))
161
162         new_url = None
163         for ctr in range(0, token_iters):
164             if new_url:
165                 new_url += '/' + auth_url_tokens[ctr]
166             else:
167                 new_url = auth_url_tokens[ctr]
168         new_url += '/' + last_token
169
170         return new_url
171
172     @property
173     def __str__(self):
174         """Converts object to a string"""
175         return ('OSCreds - username=' + str(self.username) +
176                 ', password=' + str(self.password) +
177                 ', auth_url=' + str(self.auth_url) +
178                 ', project_name=' + str(self.project_name) +
179                 ', identity_api_version=' + str(self.identity_api_version) +
180                 ', image_api_version=' + str(self.image_api_version) +
181                 ', network_api_version=' + str(self.network_api_version) +
182                 ', compute_api_version=' + str(self.compute_api_version) +
183                 ', heat_api_version=' + str(self.heat_api_version) +
184                 ', user_domain_id=' + str(self.user_domain_id) +
185                 ', user_domain_name=' + str(self.user_domain_name) +
186                 ', project_domain_id=' + str(self.project_domain_id) +
187                 ', project_domain_name=' + str(self.project_domain_name) +
188                 ', interface=' + str(self.interface) +
189                 ', region_name=' + str(self.region_name) +
190                 ', proxy_settings=' + str(self.proxy_settings) +
191                 ', cacert=' + str(self.cacert))
192
193
194 class ProxySettings:
195     """
196     Represents the information required for sending traffic (HTTP & SSH)
197     through a proxy
198     """
199
200     def __init__(self, **kwargs):
201         """
202         Constructor
203         :param host: the HTTP proxy host
204         :param port: the HTTP proxy port
205         :param https_host: the HTTPS proxy host (defaults to host)
206         :param https_port: the HTTPS proxy port (defaults to port)
207         :param ssh_proxy_cmd: the SSH proxy command string (optional)
208         """
209         self.host = kwargs.get('host')
210         self.port = kwargs.get('port')
211         if self.port and isinstance(self.port, numbers.Number):
212             self.port = str(self.port)
213
214         self.https_host = kwargs.get('https_host', self.host)
215         self.https_port = kwargs.get('https_port', self.port)
216         if self.https_port and isinstance(self.https_port, numbers.Number):
217             self.https_port = str(self.https_port)
218
219         self.ssh_proxy_cmd = kwargs.get('ssh_proxy_cmd')
220
221         if not self.host or not self.port:
222             raise ProxySettingsError('host & port are required')
223
224     def __str__(self):
225         """Converts object to a string"""
226         return 'ProxySettings - host=' + str(self.host) + \
227                ', port=' + str(self.port) + \
228                ', ssh_proxy_cmd=' + str(self.ssh_proxy_cmd)
229
230
231 class ProxySettingsError(Exception):
232     """
233     Exception to be thrown when an OSCred are invalid
234     """
235
236
237 class OSCredsError(Exception):
238     """
239     Exception to be thrown when an OSCred are invalid
240     """