Support Apex with services in containers
[doctor.git] / doctor_tests / user.py
1 ##############################################################################
2 # Copyright (c) 2017 ZTE Corporation and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import os
10
11 from keystoneclient import exceptions as ks_exceptions
12 from oslo_config import cfg
13
14 from doctor_tests.identity_auth import get_session
15 from doctor_tests.os_clients import keystone_client
16 from doctor_tests.os_clients import nova_client
17
18
19 OPTS = [
20     cfg.StrOpt('doctor_user',
21                default='doctor',
22                help='the name of test user',
23                required=True),
24     cfg.StrOpt('doctor_passwd',
25                default='doctor',
26                help='the password of test user',
27                required=True),
28     cfg.StrOpt('doctor_project',
29                default='doctor',
30                help='the name of test project',
31                required=True),
32     cfg.StrOpt('doctor_role',
33                default='_member_',
34                help='the role of test user',
35                required=True),
36     cfg.StrOpt('doctor_domain_id',
37                default=os.environ.get('OS_PROJECT_DOMAIN_ID', 'default'),
38                help='the domain id of the doctor project',
39                required=True),
40     cfg.IntOpt('quota_instances',
41                default=os.environ.get('VM_COUNT', 1),
42                help='the quota of instances in test user',
43                required=True),
44     cfg.IntOpt('quota_cores',
45                default=os.environ.get('VM_COUNT', 1),
46                help='the quota of cores in test user',
47                required=True),
48 ]
49
50
51 class User(object):
52
53     def __init__(self, conf, log):
54         self.conf = conf
55         self.log = log
56         self.def_quota = None
57         self.restore_def_quota = False
58         self.keystone = keystone_client(
59             self.conf.keystone_version, get_session())
60         self.nova = nova_client(conf.nova_version, get_session())
61         self.users = {}
62         self.projects = {}
63         self.roles = {}
64         self.use_exist_role = False
65         self.roles_for_user = {}
66         self.roles_for_admin = {}
67
68     def create(self):
69         """create test user, project and etc"""
70         self.log.info('user create start......')
71
72         self._create_project()
73         self._create_user()
74         self._create_role()
75         self._add_user_role_in_project(is_admin=False)
76         self._add_user_role_in_project(is_admin=True)
77
78         self.log.info('user create end......')
79
80     def _create_project(self):
81         """create test project"""
82         self.projects = {project.name: project for project in
83                          self.keystone.projects.list(
84                              domain=self.conf.doctor_domain_id)}
85         if self.conf.doctor_project not in self.projects:
86             self.log.info('create project......')
87             test_project = self.keystone.projects.create(
88                 self.conf.doctor_project,
89                 self.conf.doctor_domain_id)
90             self.projects[test_project.name] = test_project
91         else:
92             self.log.info('project %s already created......'
93                           % self.conf.doctor_project)
94         self.log.info('test project %s'
95                       % str(self.projects[self.conf.doctor_project]))
96
97     def _create_user(self):
98         """create test user"""
99         self.users = {user.name: user for user in
100                       self.keystone.users.list(
101                           domain=self.conf.doctor_domain_id)}
102         if self.conf.doctor_user not in self.users:
103             self.log.info('create user......')
104             test_user = self.keystone.users.create(
105                 self.conf.doctor_user,
106                 password=self.conf.doctor_passwd,
107                 domain=self.conf.doctor_domain_id)
108             self.users[test_user.name] = test_user
109         else:
110             self.log.info('user %s already created......'
111                           % self.conf.doctor_user)
112         self.log.info('test user %s'
113                       % str(self.users[self.conf.doctor_user]))
114
115     def _create_role(self):
116         """create test role"""
117         self.roles = {role.name: role for role in
118                       self.keystone.roles.list()}
119         if self.conf.doctor_role not in self.roles:
120             self.log.info('create role......')
121             test_role = self.keystone.roles.create(
122                 self.conf.doctor_role)
123             self.roles[test_role.name] = test_role
124         else:
125             self.use_exist_role = True
126             self.log.info('role %s already created......'
127                           % self.conf.doctor_role)
128         self.log.info('test role %s' % str(self.roles[self.conf.doctor_role]))
129
130     def _add_user_role_in_project(self, is_admin=False):
131         """add test user with test role in test project"""
132
133         project = self.projects.get(self.conf.doctor_project)
134
135         user_name = 'admin' if is_admin else self.conf.doctor_user
136         user = self.users.get(user_name)
137
138         role_name = 'admin' if is_admin else self.conf.doctor_role
139         role = self.roles.get(role_name)
140
141         roles_for_user = self.roles_for_admin \
142             if is_admin else self.roles_for_user
143
144         try:
145             self.keystone.roles.check(role, user=user, project=project)
146             self.log.info('Already grant a role:%s to user: %s on'
147                           ' project: %s'
148                           % (role_name, user_name,
149                              self.conf.doctor_project))
150         except ks_exceptions.NotFound:
151             self.keystone.roles.grant(role, user=user, project=project)
152             roles_for_user[role_name] = role
153
154     def _restore_default_quota(self):
155         if self.def_quota is not None and self.restore_def_quota:
156             self.log.info('restore default quota......')
157             self.nova.quota_classes.update('default',
158                                            instances=self.def_quota.instances,
159                                            cores=self.def_quota.cores)
160
161     def delete(self):
162         """delete the test user, project and role"""
163         self.log.info('user delete start......')
164
165         project = self.projects.get(self.conf.doctor_project)
166         user = self.users.get(self.conf.doctor_user)
167         role = self.roles.get(self.conf.doctor_role)
168
169         self._restore_default_quota()
170
171         if project:
172             if 'admin' in self.roles_for_admin:
173                 self.keystone.roles.revoke(
174                     self.roles['admin'],
175                     user=self.users['admin'],
176                     project=project)
177
178             if user:
179                 if role and self.conf.doctor_role in self.roles_for_user:
180                     self.keystone.roles.revoke(
181                         role, user=user, project=project)
182                     if not self.use_exist_role:
183                         self.keystone.roles.delete(role)
184                 self.keystone.users.delete(user)
185
186             self.keystone.projects.delete(project)
187         self.log.info('user delete end......')
188
189     def update_quota(self, instances=None, cores=None):
190         self.log.info('quota update start......')
191         project = self.projects.get(self.conf.doctor_project)
192
193         user = self.users.get(self.conf.doctor_user)
194
195         if instances is not None:
196             quota_instances = instances
197         else:
198             quota_instances = self.conf.quota_instances
199         if cores is not None:
200             quota_cores = cores
201         else:
202             quota_cores = self.conf.quota_cores
203
204         if project and user:
205             # default needs to be at least the same as with doctor_user
206             self.log.info('default quota update start......')
207
208             self.def_quota = self.nova.quota_classes.get('default')
209             if quota_instances > self.def_quota.instances:
210                 self.restore_def_quota = True
211                 self.nova.quota_classes.update('default',
212                                                instances=quota_instances)
213             if quota_cores > self.def_quota.cores:
214                 self.restore_def_quota = True
215                 self.nova.quota_classes.update('default',
216                                                cores=quota_cores)
217             self.log.info('user quota update start......')
218             self.quota = self.nova.quotas.get(project.id,
219                                               user_id=user.id)
220             if quota_instances > self.quota.instances:
221                 self.nova.quotas.update(project.id,
222                                         instances=quota_instances,
223                                         user_id=user.id)
224             if quota_cores > self.quota.cores:
225                 self.nova.quotas.update(project.id,
226                                         cores=quota_cores,
227                                         user_id=user.id)
228         else:
229             raise Exception('No project or role for update quota')
230         self.log.info('quota update end......')