1 # Copyright 2016 Cisco Systems, Inc. All rights reserved.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
19 # Module for credentials in Openstack
21 from keystoneauth1.identity import v2
22 from keystoneauth1.identity import v3
23 from keystoneauth1 import session
27 class Credentials(object):
29 def get_session(self):
31 'username': self.rc_username,
32 'password': self.rc_password,
33 'auth_url': self.rc_auth_url
37 if self.rc_identity_api_version == 3:
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
43 auth = v3.Password(**dct)
46 'tenant_name': self.rc_tenant_name
48 auth = v2.Password(**dct)
49 return session.Session(auth=auth, verify=self.rc_cacert)
51 def __parse_openrc(self, file):
52 export_re = re.compile('export OS_([A-Z_]*)="?(.*)')
55 mstr = export_re.match(line)
57 # get rif of posible trailing double quote
58 # the first one was removed by the re
61 if value.endswith('"'):
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('$'):
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)
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
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
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
113 if isinstance(openrc_file, str):
114 if os.path.exists(openrc_file):
115 self.__parse_openrc(open(openrc_file))
117 LOG.error('Error: rc file does not exist %s', openrc_file)
120 self.__parse_openrc(openrc_file)
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'])
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)
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)
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']
155 # always override with CLI argument if provided
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']
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 = ""
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}
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)
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)
185 except Exception as e:
186 LOG.warning("User is not admin, no permission to list user roles. Exception: %s", e)