NFVBENCH-153 Add support for python3
[nfvbench.git] / nfvbench / credentials.py
1 # Copyright 2016 Cisco Systems, Inc.  All rights reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14 #
15
16 import os
17 import re
18
19 # Module for credentials in Openstack
20 import getpass
21 from keystoneauth1.identity import v2
22 from keystoneauth1.identity import v3
23 from keystoneauth1 import session
24 from .log import LOG
25
26
27 class Credentials(object):
28
29     def get_session(self):
30         dct = {
31             'username': self.rc_username,
32             'password': self.rc_password,
33             'auth_url': self.rc_auth_url
34         }
35         auth = None
36
37         if self.rc_identity_api_version == 3:
38             dct.update({
39                 'project_name': self.rc_project_name,
40                 'project_domain_name': self.rc_project_domain_name,
41                 'user_domain_name': self.rc_user_domain_name
42             })
43             auth = v3.Password(**dct)
44         else:
45             dct.update({
46                 'tenant_name': self.rc_tenant_name
47             })
48             auth = v2.Password(**dct)
49         return session.Session(auth=auth, verify=self.rc_cacert)
50
51     def __parse_openrc(self, file):
52         export_re = re.compile('export OS_([A-Z_]*)="?(.*)')
53         for line in file:
54             line = line.strip()
55             mstr = export_re.match(line)
56             if mstr:
57                 # get rif of posible trailing double quote
58                 # the first one was removed by the re
59                 name = mstr.group(1)
60                 value = mstr.group(2)
61                 if value.endswith('"'):
62                     value = value[:-1]
63                 # get rid of password assignment
64                 # echo "Please enter your OpenStack Password: "
65                 # read -sr OS_PASSWORD_INPUT
66                 # export OS_PASSWORD=$OS_PASSWORD_INPUT
67                 if value.startswith('$'):
68                     continue
69                 # Check if api version is provided
70                 # Default is keystone v2
71                 if name == 'IDENTITY_API_VERSION':
72                     self.rc_identity_api_version = int(value)
73
74                 # now match against wanted variable names
75                 elif name == 'USERNAME':
76                     self.rc_username = value
77                 elif name == 'AUTH_URL':
78                     self.rc_auth_url = value
79                 elif name == 'TENANT_NAME':
80                     self.rc_tenant_name = value
81                 elif name == "CACERT":
82                     self.rc_cacert = value
83                 elif name == "REGION_NAME":
84                     self.rc_region_name = value
85                 elif name == "PASSWORD":
86                     self.rc_password = value
87                 elif name == "USER_DOMAIN_NAME":
88                     self.rc_user_domain_name = value
89                 elif name == "PROJECT_NAME":
90                     self.rc_project_name = value
91                 elif name == "PROJECT_DOMAIN_NAME":
92                     self.rc_project_domain_name = value
93
94     #
95     # Read a openrc file and take care of the password
96     # The 2 args are passed from the command line and can be None
97     #
98     def __init__(self, openrc_file, pwd=None, no_env=False):
99         self.rc_password = None
100         self.rc_username = None
101         self.rc_tenant_name = None
102         self.rc_auth_url = None
103         self.rc_cacert = None
104         self.rc_region_name = None
105         self.rc_user_domain_name = None
106         self.rc_project_domain_name = None
107         self.rc_project_name = None
108         self.rc_identity_api_version = 2
109         self.is_admin = False
110         success = True
111
112         if openrc_file:
113             if isinstance(openrc_file, str):
114                 if os.path.exists(openrc_file):
115                     self.__parse_openrc(open(openrc_file))
116                 else:
117                     LOG.error('Error: rc file does not exist %s', openrc_file)
118                     success = False
119             else:
120                 self.__parse_openrc(openrc_file)
121         elif not no_env:
122             # no openrc file passed - we assume the variables have been
123             # sourced by the calling shell
124             # just check that they are present
125             if 'OS_IDENTITY_API_VERSION' in os.environ:
126                 self.rc_identity_api_version = int(os.environ['OS_IDENTITY_API_VERSION'])
127
128             if self.rc_identity_api_version == 2:
129                 for varname in ['OS_USERNAME', 'OS_AUTH_URL', 'OS_TENANT_NAME']:
130                     if varname not in os.environ:
131                         LOG.warning('%s is missing', varname)
132                         success = False
133                 if success:
134                     self.rc_username = os.environ['OS_USERNAME']
135                     self.rc_auth_url = os.environ['OS_AUTH_URL']
136                     self.rc_tenant_name = os.environ['OS_TENANT_NAME']
137                 if 'OS_REGION_NAME' in os.environ:
138                     self.rc_region_name = os.environ['OS_REGION_NAME']
139             elif self.rc_identity_api_version == 3:
140                 for varname in ['OS_USERNAME', 'OS_AUTH_URL', 'OS_PROJECT_NAME',
141                                 'OS_PROJECT_DOMAIN_NAME', 'OS_USER_DOMAIN_NAME']:
142                     if varname not in os.environ:
143                         LOG.warning('%s is missing', varname)
144                         success = False
145                 if success:
146                     self.rc_username = os.environ['OS_USERNAME']
147                     self.rc_auth_url = os.environ['OS_AUTH_URL']
148                     self.rc_project_name = os.environ['OS_PROJECT_NAME']
149                     self.rc_project_domain_name = os.environ['OS_PROJECT_DOMAIN_NAME']
150                     self.rc_user_domain_name = os.environ['OS_USER_DOMAIN_NAME']
151             if 'OS_CACERT' in os.environ:
152                 self.rc_cacert = os.environ['OS_CACERT']
153
154
155         # always override with CLI argument if provided
156         if pwd:
157             self.rc_password = pwd
158         # if password not know, check from env variable
159         elif self.rc_auth_url and not self.rc_password and success:
160             if 'OS_PASSWORD' in os.environ and not no_env:
161                 self.rc_password = os.environ['OS_PASSWORD']
162             else:
163                 # interactively ask for password
164                 self.rc_password = getpass.getpass(
165                     'Please enter your OpenStack Password: ')
166         if not self.rc_password:
167             self.rc_password = ""
168
169         # check if user has admin role in OpenStack project
170         filter = {'service_type': 'identity',
171                   'interface': 'public',
172                   'region_name': self.rc_region_name}
173         try:
174             # /users URL returns exception (HTTP 403) if user is not admin.
175             # try first without the version in case session already has it in
176             # Return HTTP 200 if user is admin
177             self.get_session().get('/users', endpoint_filter=filter)
178             self.is_admin = True
179         except Exception as e:
180             try:
181                 # vX/users URL returns exception (HTTP 403) if user is not admin.
182                 self.get_session().get('/v' + str(self.rc_identity_api_version) + '/users',
183                                        endpoint_filter=filter)
184                 self.is_admin = True
185             except Exception as e:
186                 LOG.warning("User is not admin, no permission to list user roles. Exception: %s", e)