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
24 from keystoneclient import client
25 from keystoneclient import utils
29 class Credentials(object):
31 def get_session(self):
33 'username': self.rc_username,
34 'password': self.rc_password,
35 'auth_url': self.rc_auth_url
39 if self.rc_identity_api_version == 3:
41 'project_name': self.rc_project_name,
42 'project_domain_name': self.rc_project_domain_name,
43 'user_domain_name': self.rc_user_domain_name
45 auth = v3.Password(**dct)
48 'tenant_name': self.rc_tenant_name
50 auth = v2.Password(**dct)
51 return session.Session(auth=auth, verify=self.rc_cacert)
53 def __parse_openrc(self, file):
54 export_re = re.compile('export OS_([A-Z_]*)="?(.*)')
57 mstr = export_re.match(line)
59 # get rif of posible trailing double quote
60 # the first one was removed by the re
63 if value.endswith('"'):
65 # get rid of password assignment
66 # echo "Please enter your OpenStack Password: "
67 # read -sr OS_PASSWORD_INPUT
68 # export OS_PASSWORD=$OS_PASSWORD_INPUT
69 if value.startswith('$'):
71 # Check if api version is provided
72 # Default is keystone v2
73 if name == 'IDENTITY_API_VERSION':
74 self.rc_identity_api_version = int(value)
76 # now match against wanted variable names
77 elif name == 'USERNAME':
78 self.rc_username = value
79 elif name == 'AUTH_URL':
80 self.rc_auth_url = value
81 elif name == 'TENANT_NAME':
82 self.rc_tenant_name = value
83 elif name == "CACERT":
84 self.rc_cacert = value
85 elif name == "REGION_NAME":
86 self.rc_region_name = value
87 elif name == "PASSWORD":
88 self.rc_password = value
89 elif name == "USER_DOMAIN_NAME":
90 self.rc_user_domain_name = value
91 elif name == "PROJECT_NAME":
92 self.rc_project_name = value
93 elif name == "PROJECT_DOMAIN_NAME":
94 self.rc_project_domain_name = value
97 # Read a openrc file and take care of the password
98 # The 2 args are passed from the command line and can be None
100 def __init__(self, openrc_file, pwd=None, no_env=False):
101 self.rc_password = None
102 self.rc_username = None
103 self.rc_tenant_name = None
104 self.rc_auth_url = None
105 self.rc_cacert = None
106 self.rc_region_name = None
107 self.rc_user_domain_name = None
108 self.rc_project_domain_name = None
109 self.rc_project_name = None
110 self.rc_identity_api_version = 2
111 self.is_admin = False
115 if isinstance(openrc_file, str):
116 if os.path.exists(openrc_file):
117 self.__parse_openrc(open(openrc_file))
119 LOG.error('Error: rc file does not exist %s', openrc_file)
122 self.__parse_openrc(openrc_file)
124 # no openrc file passed - we assume the variables have been
125 # sourced by the calling shell
126 # just check that they are present
127 if 'OS_IDENTITY_API_VERSION' in os.environ:
128 self.rc_identity_api_version = int(os.environ['OS_IDENTITY_API_VERSION'])
130 if self.rc_identity_api_version == 2:
131 for varname in ['OS_USERNAME', 'OS_AUTH_URL', 'OS_TENANT_NAME']:
132 if varname not in os.environ:
133 LOG.warning('%s is missing', varname)
136 self.rc_username = os.environ['OS_USERNAME']
137 self.rc_auth_url = os.environ['OS_AUTH_URL']
138 self.rc_tenant_name = os.environ['OS_TENANT_NAME']
139 if 'OS_REGION_NAME' in os.environ:
140 self.rc_region_name = os.environ['OS_REGION_NAME']
141 elif self.rc_identity_api_version == 3:
142 for varname in ['OS_USERNAME', 'OS_AUTH_URL', 'OS_PROJECT_NAME',
143 'OS_PROJECT_DOMAIN_NAME', 'OS_USER_DOMAIN_NAME']:
144 if varname not in os.environ:
145 LOG.warning('%s is missing', varname)
148 self.rc_username = os.environ['OS_USERNAME']
149 self.rc_auth_url = os.environ['OS_AUTH_URL']
150 self.rc_project_name = os.environ['OS_PROJECT_NAME']
151 self.rc_project_domain_name = os.environ['OS_PROJECT_DOMAIN_NAME']
152 self.rc_user_domain_name = os.environ['OS_USER_DOMAIN_NAME']
153 if 'OS_CACERT' in os.environ:
154 self.rc_cacert = os.environ['OS_CACERT']
157 # always override with CLI argument if provided
159 self.rc_password = pwd
160 # if password not know, check from env variable
161 elif self.rc_auth_url and not self.rc_password and success:
162 if 'OS_PASSWORD' in os.environ and not no_env:
163 self.rc_password = os.environ['OS_PASSWORD']
165 # interactively ask for password
166 self.rc_password = getpass.getpass(
167 'Please enter your OpenStack Password: ')
168 if not self.rc_password:
169 self.rc_password = ""
171 # check if user has admin role in OpenStack project
173 keystone = client.Client(session=self.get_session())
174 user = utils.find_resource(keystone.users, self.rc_username)
175 if self.rc_identity_api_version == 2:
176 tenant = utils.find_resource(keystone.tenants, self.rc_tenant_name)
177 roles = keystone.roles.roles_for_user(user, tenant=tenant.id)
178 elif self.rc_identity_api_version == 3:
179 project = utils.find_resource(keystone.projects, self.rc_project_name)
180 roles = keystone.roles.list(user=user.id, project=project.id)
182 if role.name == 'admin':
185 LOG.warning("User is not admin, no permission to list user roles")