def create_role_ref(self, admin_token, user_id, role_ref): self.__validate_service_or_keystone_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") if not isinstance(role_ref, RoleRef): raise fault.BadRequestFault("Expecting a Role Ref") if role_ref.role_id == None: raise fault.BadRequestFault("Expecting a Role Id") drole = api.ROLE.get(role_ref.role_id) if drole == None: raise fault.ItemNotFoundFault("The role not found") if role_ref.tenant_id != None: dtenant = api.TENANT.get(role_ref.tenant_id) if dtenant == None: raise fault.ItemNotFoundFault("The tenant not found") drole_ref = models.UserRoleAssociation() drole_ref.user_id = duser.id drole_ref.role_id = drole.id if role_ref.tenant_id != None: drole_ref.tenant_id = dtenant.id user_role_ref = api.USER.user_role_add(drole_ref) role_ref.role_ref_id = user_role_ref.id return role_ref
def add_global_role_to_user(self, admin_token, user_id, role_id): self.__validate_service_or_keystone_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") drole = api.ROLE.get(role_id) if drole == None: raise fault.ItemNotFoundFault("The role not found") drole_ref = models.UserRoleAssociation() drole_ref.user_id = duser.id drole_ref.role_id = drole.id api.USER.user_role_add(drole_ref)
def set_user_tenant(self, admin_token, user_id, user): self.__validate_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") if not isinstance(user, User): raise fault.BadRequestFault("Expecting a User") duser = api.USER.get(user_id) if duser == None: raise fault.ItemNotFoundFault("The user could not be found") self.validate_and_fetch_user_tenant(user.tenant_id) values = {'tenant_id': user.tenant_id} api.USER.update(user_id, values) return User_Update(tenant_id=user.tenant_id)
def get_user(self, admin_token, user_id): self.__validate_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") return User_Update(id=duser.id, tenant_id=duser.tenant_id, email=duser.email, enabled=duser.enabled, name=duser.name)
def get_tenant(self, admin_token, tenant_id): self.__validate_admin_token(admin_token) dtenant = api.TENANT.get(tenant_id) if not dtenant: raise fault.ItemNotFoundFault("The tenant could not be found") return Tenant(dtenant.id, dtenant.name, dtenant.desc, dtenant.enabled)
def get_tenant_endpoints(self, admin_token, marker, limit, url, tenant_id): self.__validate_service_or_keystone_admin_token(admin_token) if tenant_id == None: raise fault.BadRequestFault("Expecting a Tenant Id") if api.TENANT.get(tenant_id) == None: raise fault.ItemNotFoundFault("The tenant not found") ts = [] dtenant_endpoints = \ api.ENDPOINT_TEMPLATE.\ endpoint_get_by_tenant_get_page( tenant_id, marker, limit) for dtenant_endpoint in dtenant_endpoints: ts.append(Endpoint(dtenant_endpoint.id, url + '/endpointTemplates/' + \ str(dtenant_endpoint.endpoint_template_id))) links = [] if ts.__len__(): prev, next = \ api.ENDPOINT_TEMPLATE.endpoint_get_by_tenant_get_page_markers( tenant_id, marker, limit) if prev: links.append( atom.Link('prev', "%s?'marker=%s&limit=%s'" % (url, prev, limit))) if next: links.append( atom.Link('next', "%s?'marker=%s&limit=%s'" % (url, next, limit))) return Endpoints(ts, links)
def get_instance_bill(self, instance_id): dinstacne = api.BILLER.get_instance_bill(instance_id) if not dinstacne: raise fault.ItemNotFoundFault("The Instance Bill could not be found") LOG.info('keystone logic servie py get_instance_bill dinstance id:%d name :%s vcpu:%d ram:%d vdisk:%d changed_on %s enabled:%d'% (dinstacne.id, dinstacne.name, dinstacne.total_vcpu, dinstacne.total_ram, dinstacne.total_vdisk, dinstacne.changed_on, dinstacne.enabled)) return Instance_Bill(id=dinstacne.id, name=dinstacne.name, total_vcpu=dinstacne.total_vcpu, total_ram=dinstacne.total_ram, total_vdisk=dinstacne.total_vdisk, changed_on=dinstacne.changed_on, enabled=dinstacne.enabled)
def modify_endpoint_template(self, admin_token, endpoint_template_id, endpoint_template): self.__validate_service_or_keystone_admin_token(admin_token) if not isinstance(endpoint_template, EndpointTemplate): raise fault.BadRequestFault("Expecting a EndpointTemplate") dendpoint_template = api.ENDPOINT_TEMPLATE.get(endpoint_template_id) if not dendpoint_template: raise fault.ItemNotFoundFault( "The endpoint template could not be found") #Check if the passed service exist. if endpoint_template.service != None and\ len(endpoint_template.service.strip()) > 0 and\ api.SERVICE.get(endpoint_template.service) == None: raise fault.BadRequestFault( "A service with that id doesn't exist.") dendpoint_template.region = endpoint_template.region dendpoint_template.service_id = endpoint_template.service dendpoint_template.public_url = endpoint_template.public_url dendpoint_template.admin_url = endpoint_template.admin_url dendpoint_template.internal_url = endpoint_template.internal_url dendpoint_template.enabled = endpoint_template.enabled dendpoint_template.is_global = endpoint_template.is_global dendpoint_template = api.ENDPOINT_TEMPLATE.update( endpoint_template_id, dendpoint_template) return EndpointTemplate( dendpoint_template.id, dendpoint_template.region, dendpoint_template.service_id, dendpoint_template.public_url, dendpoint_template.admin_url, dendpoint_template.internal_url, dendpoint_template.enabled, dendpoint_template.is_global)
def get_tenant_users(self, admin_token, tenant_id, marker, limit, url): self.__validate_token(admin_token, False) if tenant_id == None: raise fault.BadRequestFault("Expecting a Tenant Id") dtenant = api.TENANT.get(tenant_id) if dtenant is None: raise fault.ItemNotFoundFault("The tenant not found") if not dtenant.enabled: raise fault.TenantDisabledFault("Your account has been disabled") ts = [] dtenantusers = api.USER.users_get_by_tenant_get_page( tenant_id, marker, limit) for dtenantuser in dtenantusers: ts.append( User( None, dtenantuser.id, dtenantuser.name, tenant_id, dtenantuser.email, dtenantuser.eppn, dtenantuser.enabled, dtenantuser.tenant_roles if hasattr( dtenantuser, "tenant_roles") else None)) links = [] if ts.__len__(): prev, next = api.USER.users_get_by_tenant_get_page_markers( tenant_id, marker, limit) if prev: links.append( atom.Link('prev', "%s?'marker=%s&limit=%s'" % (url, prev, limit))) if next: links.append( atom.Link('next', "%s?'marker=%s&limit=%s'" % (url, next, limit))) return Users(ts, links)
def get_role(self, admin_token, role_id): self.__validate_service_or_keystone_admin_token(admin_token) drole = api.ROLE.get(role_id) if not drole: raise fault.ItemNotFoundFault("The role could not be found") return Role(drole.id, drole.name, drole.desc, drole.service_id)
def delete_service(self, admin_token, service_id): self.__validate_service_or_keystone_admin_token(admin_token) dservice = api.SERVICE.get(service_id) if not dservice: raise fault.ItemNotFoundFault("The service could not be found") #Delete Related Endpointtemplates and Endpoints. endpoint_templates = api.ENDPOINT_TEMPLATE.get_by_service(service_id) if endpoint_templates != None: for endpoint_template in endpoint_templates: endpoints = api.ENDPOINT_TEMPLATE.\ endpoint_get_by_endpoint_template(endpoint_template.id) if endpoints != None: for endpoint in endpoints: api.ENDPOINT_TEMPLATE.endpoint_delete(endpoint.id) api.ENDPOINT_TEMPLATE.delete(endpoint_template.id) #Delete Related Role and RoleRefs roles = api.ROLE.get_by_service(service_id) if roles != None: for role in roles: role_refs = api.ROLE.ref_get_by_role(role.id) if role_refs != None: for role_ref in role_refs: api.ROLE.ref_delete(role_ref.id) api.ROLE.delete(role.id) api.SERVICE.delete(service_id)
def to_json(self): token = {} token["id"] = self.token.id token["expires"] = self.token.expires.isoformat() if self.token.tenant: token['tenant'] = { 'id': unicode(self.token.tenant.id), 'name': unicode(self.token.tenant.name) } auth = {} auth["token"] = token auth['user'] = { 'id': unicode(self.user.id), 'name': unicode(self.user.username) } if self.user.rolegrants is not None: auth['user']["roles"] = self.user.rolegrants.to_json_values() if self.base_urls is not None and len(self.base_urls) > 0: service_catalog = [] for key, key_base_urls in self.d.items(): service = {} endpoints = [] for base_url in key_base_urls: include_this_endpoint = False endpoint = {} if base_url.region: endpoint["region"] = base_url.region for url_kind in self.url_types: base_url_item = getattr(base_url, url_kind + "_url") if base_url_item: if '%tenant_id%' in base_url_item: if self.token.tenant: # Don't return tenant endpoints if token # not scoped to a tenant endpoint[url_kind + "URL"] = \ base_url_item.replace('%tenant_id%', str(self.token.tenant.id)) include_this_endpoint = True else: endpoint[url_kind + "URL"] = base_url_item include_this_endpoint = True if include_this_endpoint: endpoint['id'] = str(base_url.id) endpoints.append(endpoint) dservice = db_api.SERVICE.get(key) if not dservice: raise fault.ItemNotFoundFault( "The service could not be found for" + str(key)) if len(endpoints): service["name"] = dservice.name service["type"] = dservice.type service["endpoints"] = endpoints service_catalog.append(service) auth["serviceCatalog"] = service_catalog ret = {} ret["access"] = auth return json.dumps(ret)
def get_bill_unit(self, billunit_date): dbillunit = api.BILLER.get(billunit_date) if not dbillunit: raise fault.ItemNotFoundFault("The Bill could not be found") LOG.info('keystone logic servie py get_bill_unit dbillunit id:%d vcpu:%d ram:%d vdisk:%d changed_on %s enabled:%d'% (dbillunit.id, dbillunit.vcpu, dbillunit.ram, dbillunit.vdisk, dbillunit.changed_on, dbillunit.enabled)) return Bill_Unit(id=dbillunit.id, vcpu=dbillunit.vcpu, ram=dbillunit.ram, vdisk=dbillunit.vdisk, date=dbillunit.date, changed_on=dbillunit.changed_on, enabled=dbillunit.enabled)
def revoke_token(self, admin_token, token_id): self.__validate_admin_token(admin_token) dtoken = api.TOKEN.get(token_id) if not dtoken: raise fault.ItemNotFoundFault("Token not found") api.TOKEN.delete(token_id)
def get_service(self, admin_token, service_id): self.__validate_service_or_keystone_admin_token(admin_token) dservice = api.SERVICE.get(service_id) if not dservice: raise fault.ItemNotFoundFault("The service could not be found") return Service(dservice.id, dservice.name, dservice.type, dservice.desc)
def static_file(resp, req, filename, root, guessmime=True, mimetype=None, download=False): """ Opens a file in a safe way and returns a HTTPError object with status code 200, 305, 401 or 404. Sets Content-Type, Content-Length and Last-Modified header. Obeys If-Modified-Since header and HEAD requests. """ root = os.path.abspath(root) + os.sep filename = os.path.abspath(os.path.join(root, filename.strip('/\\'))) if not filename.startswith(root): return ForbiddenFault("Access denied.") if not os.path.exists(filename) or not os.path.isfile(filename): return fault.ItemNotFoundFault("File does not exist.") if not os.access(filename, os.R_OK): return ForbiddenFault( "You do not have permission to access this file.") if not mimetype and guessmime: resp.content_type = mimetypes.guess_type(filename)[0] else: resp.content_type = mimetype or 'text/plain' if download == True: download = os.path.basename(filename) if download: resp.content_disposition = 'attachment; filename="%s"' % download stats = os.stat(filename) lm = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(stats.st_mtime)) resp.last_modified = lm ims = req.environ.get('HTTP_IF_MODIFIED_SINCE') if ims: ims = ims.split(";")[0].strip() # IE sends "<date>; length=146" try: ims = datetime.datetime.fromtimestamp(stats.st_mtime) ims = datetime.datetime.ctime(ims) filetime = datetime.datetime.fromtimestamp(stats.st_mtime) if ims is not None and ims >= filetime: resp.date = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) return Response(body=None, status=304, headerlist=resp.headerlist) except: # TODO(Ziad): handle this better pass resp.content_length = stats.st_size if req.method == 'HEAD': return Response(body=None, status=200, headerlist=resp.headerlist) else: return Response(body=open(filename).read(), status=200, headerlist=resp.headerlist)
def to_xml(self): dom = etree.Element( "access", xmlns="http://docs.openstack.org/identity/api/v2.0") token = etree.Element("token", expires=self.token.expires.isoformat()) token.set("id", self.token.id) if self.token.tenant: tenant = etree.Element("tenant", id=unicode(self.token.tenant.id), name=unicode(self.token.tenant.name)) token.append(tenant) dom.append(token) user = etree.Element("user", id=unicode(self.user.id), name=unicode(self.user.username)) dom.append(user) if self.user.rolegrants is not None: user.append(self.user.rolegrants.to_dom()) if self.base_urls is not None or len(self.base_urls) > 0: service_catalog = etree.Element("serviceCatalog") for key, key_base_urls in self.d.items(): dservice = db_api.SERVICE.get(key) if not dservice: raise fault.ItemNotFoundFault( "The service could not be found") service = etree.Element("service", name=dservice.name, type=dservice.type) for base_url in key_base_urls: include_this_endpoint = False endpoint = etree.Element("endpoint") if base_url.region: endpoint.set("region", base_url.region) for url_kind in self.url_types: base_url_item = getattr(base_url, url_kind + "_url") if base_url_item: if '%tenant_id%' in base_url_item: if self.token.tenant: # Don't return tenant endpoints if token # not scoped to a tenant endpoint.set( url_kind + "URL", base_url_item.replace( '%tenant_id%', str(self.token.tenant.id))) include_this_endpoint = True else: endpoint.set(url_kind + "URL", base_url_item) include_this_endpoint = True if include_this_endpoint: endpoint.set("id", str(base_url.id)) service.append(endpoint) if service.find("endpoint") is not None: service_catalog.append(service) dom.append(service_catalog) return etree.tostring(dom)
def validate_and_fetch_user_tenant(self, tenant_id): if tenant_id: dtenant = api.TENANT.get(tenant_id) if dtenant == None: raise fault.ItemNotFoundFault("The tenant is not found") elif not dtenant.enabled: raise fault.TenantDisabledFault( "Your account has been disabled") return dtenant
def create_endpoint_for_tenant(self, admin_token, tenant_id, endpoint_template, url): self.__validate_service_or_keystone_admin_token(admin_token) if tenant_id == None: raise fault.BadRequestFault("Expecting a Tenant Id") if api.TENANT.get(tenant_id) == None: raise fault.ItemNotFoundFault("The tenant not found") dendpoint_template = api.ENDPOINT_TEMPLATE.get(endpoint_template.id) if not dendpoint_template: raise fault.ItemNotFoundFault( "The endpoint template could not be found") dendpoint = models.Endpoints() dendpoint.tenant_id = tenant_id dendpoint.endpoint_template_id = endpoint_template.id dendpoint = api.ENDPOINT_TEMPLATE.endpoint_add(dendpoint) dendpoint = Endpoint(dendpoint.id, url + '/endpointTemplates/' + unicode(dendpoint.endpoint_template_id)) return dendpoint
def set_user_password(self, admin_token, user_id, user): self.__validate_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") if not isinstance(user, User): raise fault.BadRequestFault("Expecting a User") duser = api.USER.get(user_id) if duser == None: raise fault.ItemNotFoundFault("The user could not be found") values = {'password': user.password} api.USER.update(user_id, values) return User_Update(password=user.password)
def delete_role(self, admin_token, role_id): self.__validate_service_or_keystone_admin_token(admin_token) drole = api.ROLE.get(role_id) if not drole: raise fault.ItemNotFoundFault("The role could not be found") role_refs = api.ROLE.ref_get_by_role(role_id) if role_refs != None: for role_ref in role_refs: api.ROLE.ref_delete(role_ref.id) api.ROLE.delete(role_id)
def __validate_token(self, token_id, belongs_to=None, is_check_token=None): """ Method to validate a token. token_id -- value of actual token that need to be validated. belngs_to -- optional tenant_id to check whether the token is mapped to a specific tenant. is_check_token -- optional argument that tells whether we check the existence of a Token using another Token to authenticate.This value decides the faults that are to be thrown. """ if not token_id: raise fault.UnauthorizedFault("Missing token") (token, user) = self.__get_dauth_data(token_id) if not token: if is_check_token: raise fault.ItemNotFoundFault("Token does not exist.") else: raise fault.UnauthorizedFault( "Bad token, please reauthenticate") if token.expires < datetime.now(): if is_check_token: raise fault.ItemNotFoundFault("Token expired, please renew.") else: raise fault.ForbiddenFault("Token expired, please renew.") if not user.enabled: raise fault.UserDisabledFault("User %s has been disabled!" % user.id) if user.tenant_id: self.__validate_tenant_by_id(user.tenant_id) if token.tenant_id: self.__validate_tenant_by_id(token.tenant_id) if belongs_to and unicode(token.tenant_id) != unicode(belongs_to): raise fault.UnauthorizedFault("Unauthorized on this tenant") return (token, user)
def get_token_by_email(self, admin_token, email): self.__validate_admin_token(admin_token) dmail = api.USER.get_by_email(email) def validate(duser): # The user is already authenticated by gakunin return True if dmail: return self._authenticate(validate, dmail.id) raise fault.ItemNotFoundFault("email not found")
def get_token_by_eppn(self, admin_token, eppn): self.__validate_admin_token(admin_token) deppn = api.USER.get_by_eppn(eppn) def validate(duser): # The user is already authenticated by gakunin return True if deppn: return self._authenticate(validate, deppn.id) raise fault.ItemNotFoundFault("eppn not found")
def get_endpoint_template(self, admin_token, endpoint_template_id): self.__validate_service_or_keystone_admin_token(admin_token) dendpoint_template = api.ENDPOINT_TEMPLATE.get(endpoint_template_id) if not dendpoint_template: raise fault.ItemNotFoundFault( "The endpoint template could not be found") return EndpointTemplate( dendpoint_template.id, dendpoint_template.region, dendpoint_template.service_id, dendpoint_template.public_url, dendpoint_template.admin_url, dendpoint_template.internal_url, dendpoint_template.enabled, dendpoint_template.is_global)
def delete_user(self, admin_token, user_id): self.__validate_admin_token(admin_token) duser = api.USER.get(user_id) if not duser: raise fault.ItemNotFoundFault("The user could not be found") dtenant = api.TENANT.get(duser.tenant_id) if dtenant != None: api.USER.delete_tenant_user(user_id, dtenant.id) else: api.USER.delete(user_id) return None
def delete_endpoint_template(self, admin_token, endpoint_template_id): self.__validate_service_or_keystone_admin_token(admin_token) dendpoint_template = api.ENDPOINT_TEMPLATE.get(endpoint_template_id) if not dendpoint_template: raise fault.ItemNotFoundFault( "The endpoint template could not be found") #Delete Related endpoints endpoints = api.ENDPOINT_TEMPLATE.\ endpoint_get_by_endpoint_template(endpoint_template_id) if endpoints != None: for endpoint in endpoints: api.ENDPOINT_TEMPLATE.endpoint_delete(endpoint.id) api.ENDPOINT_TEMPLATE.delete(endpoint_template_id)
def update_tenant(self, admin_token, tenant_id, tenant): self.__validate_admin_token(admin_token) if not isinstance(tenant, Tenant): raise fault.BadRequestFault("Expecting a Tenant") dtenant = api.TENANT.get(tenant_id) if dtenant == None: raise fault.ItemNotFoundFault("The tenant could not be found") values = {'desc': tenant.description, 'enabled': tenant.enabled} api.TENANT.update(tenant_id, values) tenant = api.TENANT.get(tenant_id) return Tenant(tenant.id, tenant.name, tenant.desc, tenant.enabled)
def delete_tenant(self, admin_token, tenant_id): self.__validate_admin_token(admin_token) dtenant = api.TENANT.get(tenant_id) if dtenant == None: raise fault.ItemNotFoundFault("The tenant could not be found") if not api.TENANT.is_empty(tenant_id): raise fault.ForbiddenFault("You may not delete a tenant that " "contains get_users") api.TENANT.delete(dtenant.id) return None
def get_endpoints_for_token(self, admin_token, token_id): self.__validate_admin_token(admin_token) dtoken = api.TOKEN.get(token_id) if not dtoken: raise fault.ItemNotFoundFault("Token not found") endpoints = api.TENANT.get_all_endpoints(dtoken.tenant_id) # For now it's easier to resend the token data as well. # Who knows, might be useful and the client can reuse their # auth parsing code. token = auth.Token(dtoken.expires, dtoken.id, dtoken.tenant_id) return auth.AuthData(token, endpoints)