tenantinfo.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import random
  2. from datetime import datetime
  3. from lib import utils
  4. class TenantInfoManager(object):
  5. def __init__(self):
  6. self.tenants = {}
  7. def add_tenant(self, tenant):
  8. self.tenants[tenant.get_id()] = tenant
  9. def remove_tenant(self, tenant):
  10. del self.tenants[tenant.get_id()]
  11. def get_tenants(self):
  12. tenants = []
  13. for v in list(self.tenants.values()):
  14. tenants.append({'id': v.get_id(), 'name': v.get_name()})
  15. return tenants
  16. def get_tenant(self, tenant_name=None, tenant_id=None):
  17. for t in list(self.tenants.values()):
  18. if tenant_id is not None and len(tenant_id) > 0:
  19. if t.get_id() == tenant_id and not t.expire_soon():
  20. return t
  21. elif tenant_name is not None and len(tenant_name) > 0:
  22. if t.get_name() == tenant_name and not t.expire_soon():
  23. return t
  24. return None
  25. def from_json(self, desc):
  26. for tdesc in desc:
  27. t = TenantInfo(None, None)
  28. t.from_json(tdesc)
  29. self.add_tenant(t)
  30. def to_json(self):
  31. desc = []
  32. for t in list(self.tenants.values()):
  33. desc.append(t.to_json())
  34. return desc
  35. class TenantInfo(object):
  36. def __init__(self, idstr, name):
  37. self.__id = idstr
  38. self.__name = name
  39. self.token = None
  40. self.catalog = None
  41. self.user = None
  42. def set_access_info(self, token, catalog, user, no_check=False):
  43. self.start_time = datetime.utcnow()
  44. self.token = token
  45. self.catalog = catalog
  46. self.user = user
  47. if not no_check:
  48. diff = self.get_expire() - self.start_time
  49. if utils.td_total_seconds(diff) <= 60:
  50. raise Exception('Incorrect system time')
  51. def get_id(self):
  52. if self.__id is None and self.token is not None:
  53. self.__id = self.token['tenant']['id']
  54. return self.__id
  55. def get_name(self):
  56. if self.__name is None and self.token is not None:
  57. self.__name = self.token['tenant']['name']
  58. return self.__name
  59. def get_expire(self):
  60. if self.token:
  61. return utils.parse_isotime(self.token['expires'])
  62. else:
  63. return None
  64. def expire_soon(self):
  65. if self.token is None:
  66. return True
  67. expire = self.get_expire()
  68. utcnow = datetime.utcnow()
  69. if expire <= utcnow:
  70. return True
  71. nowdiff = expire - utcnow
  72. if expire <= self.start_time:
  73. return True
  74. diff = expire - self.start_time
  75. if utils.td_total_seconds(nowdiff) < utils.td_total_seconds(diff)/2:
  76. return True
  77. return False
  78. def get_token(self):
  79. if self.token:
  80. return self.token['id']
  81. else:
  82. return None
  83. def get_regions(self):
  84. if self.catalog is None:
  85. return None
  86. return self.get_regions_v3()
  87. def get_regions_v3(self):
  88. regions = {}
  89. for service in self.catalog:
  90. if service['type'] != 'compute':
  91. continue
  92. for endpoint in service['endpoints']:
  93. region = endpoint['region_id']
  94. if region not in regions:
  95. regions[region] = {}
  96. if endpoint['interface'] == 'public':
  97. regions[region]['publicURL'] = endpoint['url']
  98. elif endpoint['interface'] == 'internal':
  99. regions[region]['internalURL'] = endpoint['url']
  100. ret = []
  101. for region, urls in regions.items():
  102. urls['region'] = region
  103. ret.append(urls)
  104. return ret
  105. def get_regions_v2(self):
  106. regions = []
  107. for service in self.catalog:
  108. if service['type'] != 'compute':
  109. continue
  110. endpoints = service['endpoints']
  111. for endpoint in endpoints:
  112. regions.append({'region': endpoint['region'],
  113. 'publicurl': endpoint['publicURL'],
  114. 'internalurl': endpoint['internalURL'],
  115. })
  116. return regions
  117. def get_endpoint(self, region, service, ep_type, zone=None):
  118. if self.catalog is None:
  119. return None
  120. return self.get_endpoint_v3(region, service, ep_type, zone=zone)
  121. def get_endpoint_v3(self, region, service, ep_type, zone=None):
  122. if not ep_type.endswith('URL'):
  123. ep_type += 'URL'
  124. for s in self.catalog:
  125. if s['type'] == service:
  126. regions = {}
  127. for ep in s['endpoints']:
  128. region = ep['region_id']
  129. if region not in regions:
  130. regions[region] = {}
  131. regions[region]['%sURL' % ep['interface']] = ep['url']
  132. if region is None:
  133. if len(regions) == 1:
  134. for v in list(regions.values()):
  135. return v[ep_type]
  136. else:
  137. raise Exception('No default region')
  138. else:
  139. if zone is not None and len(zone) > 0:
  140. region_zone = '%s-%s' % (region, zone)
  141. if region_zone in regions:
  142. return regions[region_zone][ep_type]
  143. if region in regions:
  144. return regions[region][ep_type]
  145. raise Exception('No such region %s' % region)
  146. def get_endpoint_v2(self, region, service, ep_type, zone=None):
  147. for s in self.catalog:
  148. if s['type'] == service:
  149. sel_ep = None
  150. if region is None or len(region) == 0:
  151. if len(s['endpoints']) == 1:
  152. sel_ep = s['endpoints'][0]
  153. else:
  154. raise Exception('No default region')
  155. else:
  156. reg_eps = []
  157. region_zone = None
  158. if zone is not None and len(zone) > 0:
  159. zon_eps = []
  160. region_zone = '%s-%s' % (region, zone)
  161. for ep in s['endpoints']:
  162. if ep['region'] == region:
  163. reg_eps.append(ep)
  164. elif region_zone is not None and \
  165. ep['region'] == region_zone:
  166. zon_eps.append(ep)
  167. if region_zone is not None and len(zon_eps) > 0:
  168. sel_ep = random.choice(zon_eps) # random for LB
  169. elif len(reg_eps) > 0:
  170. sel_ep = random.choice(reg_eps) # random for LB
  171. if sel_ep is not None and ep_type in sel_ep:
  172. return sel_ep[ep_type]
  173. return None
  174. def from_json(self, desc):
  175. self.id = desc['id']
  176. self.name = desc['name']
  177. if 'token' in desc and 'catalog' in desc:
  178. user = desc.get('user', None)
  179. self.set_access_info(desc['token'], desc['catalog'], user,
  180. no_check=True)
  181. def to_json(self):
  182. desc = {}
  183. desc['id'] = self.get_id()
  184. desc['name'] = self.get_name()
  185. if self.token and self.catalog:
  186. desc['token'] = self.token
  187. desc['catalog'] = self.catalog
  188. desc['user'] = self.user
  189. return desc
  190. def get_roles(self):
  191. if self.user is not None and 'roles' in self.user:
  192. return self.user['roles']
  193. else:
  194. return []
  195. def is_admin(self):
  196. for r in self.get_roles():
  197. if r['name'] == 'admin':
  198. return True
  199. return False
  200. def is_system_admin(self):
  201. if self.is_admin() and self.get_name() == 'system':
  202. return True
  203. else:
  204. return False
  205. def get_user_id(self):
  206. if self.user is not None and 'id' in self.user:
  207. return self.user['id']
  208. return None
  209. def get_user_name(self):
  210. if self.user is not None and 'name' in self.user:
  211. return self.user['name']
  212. return None
  213. def get_user_info(self):
  214. if self.user is not None:
  215. return self.user
  216. return None