def loggedIn(self, userService, userName=None): """ This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance """ uniqueId = userService.unique_id userService.setInUse(True) si = userService.getInstance() si.userLoggedIn(userName) userService.updateData(si) serviceIp = si.getIp() fullUserName = '******' if userService.user is not None: fullUserName = userService.user.manager.name + '\\' + userService.user.name knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' if userName is None: userName = '******' addEvent(userService.deployed_service, ET_LOGIN, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged in".format(userName), log.OSMANAGER) log.useLog('login', uniqueId, serviceIp, userName, knownUserIP, fullUserName, userService.friendly_name, userService.deployed_service.name) counter = int(userService.getProperty('loginsCounter', '0')) + 1 userService.setProperty('loginsCounter', six.text_type(counter))
def webLogout(request: HttpRequest, exit_url: typing.Optional[str] = None) -> HttpResponse: """ Helper function to clear user related data from session. If this method is not used, the session we be cleaned anyway by django in regular basis. """ if request.user: authenticator = request.user.manager.getInstance() username = request.user.name exit_url = authenticator.logout(username) or exit_url if request.user.id != ROOT_ID: # Try yo invoke logout of auth events.addEvent(request.user.manager, events.ET_LOGOUT, username=request.user.name, srcip=request.ip) else: # No user, redirect to / return HttpResponseRedirect(reverse('page.login')) request.session.clear() if exit_url is None: exit_url = GlobalConfig.LOGIN_URL.get() if GlobalConfig.REDIRECT_TO_HTTPS.getBool() is True: exit_url = exit_url.replace('http://', 'https://') # Try to delete session response = HttpResponseRedirect(request.build_absolute_uri(exit_url)) if authenticator: authenticator.webLogoutHook(username, request, response) return response
def __registerUser(authenticator: Authenticator, authInstance: AuthenticatorInstance, username: str) -> typing.Optional[User]: """ Check if this user already exists on database with this authenticator, if don't, create it with defaults This will work correctly with both internal or externals cause we first authenticate the user, if internal and user do not exists in database authenticate will return false, if external and return true, will create a reference in database """ from uds.core.util.request import getRequest username = authInstance.transformUsername(username) logger.debug('Transformed username: %s', username) request = getRequest() usr = authenticator.getOrCreateUser(username, username) usr.real_name = authInstance.getRealName(username) usr.save() if usr is not None and State.isActive(usr.state): # Now we update database groups for this user usr.getManager().recreateGroups(usr) # And add an login event events.addEvent(authenticator, events.ET_LOGIN, username=username, srcip=request.ip) # pylint: disable=maybe-no-member events.addEvent(authenticator, events.ET_PLATFORM, platform=request.os.OS, browser=request.os.Browser, version=request.os.Version) # pylint: disable=maybe-no-member return usr return None
def loggedOut(self, userService, userName=None, save=True): ''' This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance ''' uniqueId = userService.unique_id userService.setInUse(False) si = userService.getInstance() si.userLoggedOut(userName) userService.updateData(si) serviceIp = si.getIp() fullUserName = '******' if userService.user is not None: fullUserName = userService.user.manager.name + '\\' + userService.user.name knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' addEvent(userService.deployed_service, ET_LOGOUT, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged out", log.OSMANAGER) log.useLog('logout', uniqueId, serviceIp, userName, knownUserIP, fullUserName) if save: userService.save()
def __registerUser(authenticator, authInstance, username): """ Check if this user already exists on database with this authenticator, if don't, create it with defaults This will work correctly with both internal or externals cause we first authenticate the user, if internal and user do not exists in database authenticate will return false, if external and return true, will create a reference in database """ from uds.core.util.request import getRequest username = authInstance.transformUsername(username) logger.debug('Transformed username: {0}'.format(username)) request = getRequest() usr = authenticator.getOrCreateUser(username, username) usr.real_name = authInstance.getRealName(username) usr.save() if usr is not None and State.isActive(usr.state): # Now we update database groups for this user usr.getManager().recreateGroups(usr) # And add an login event events.addEvent(authenticator, events.ET_LOGIN, username=username, srcip=request.ip) # pylint: disable=maybe-no-member events.addEvent(authenticator, events.ET_PLATFORM, platform=request.os.OS, browser=request.os.Browser, version=request.os.Version) # pylint: disable=maybe-no-member return usr return None
def webLogout(request, exit_url=None): """ Helper function to clear user related data from session. If this method is not used, the session we be cleaned anyway by django in regular basis. """ authenticator = request.user and request.user.manager.getInstance() or None username = request.user and request.user.name or None exit_url = authenticator.logout(username) or exit_url if request.user is not None and request.user.id != ROOT_ID: # Try yo invoke logout of auth events.addEvent(request.user.manager, events.ET_LOGOUT, username=request.user.name, srcip=request.ip) request.session.clear() if exit_url is None: exit_url = GlobalConfig.LOGIN_URL.get() if GlobalConfig.REDIRECT_TO_HTTPS.getBool() is True: exit_url = exit_url.replace('http://', 'https://') # Try to delete session response = HttpResponseRedirect(request.build_absolute_uri(exit_url)) if authenticator: authenticator.webLogoutHook(username, request, response) return response
def getService(request, idService, idTransport, doTest=True): kind, idService = idService[0], idService[1:] logger.debug('Kind of service: {0}, idService: {1}'.format(kind, idService)) if kind == 'A': # This is an assigned service logger.debug('Getting A service {}'.format(idService)) ads = UserService.objects.get(uuid=idService) ads.deployed_service.validateUser(request.user) else: ds = DeployedService.objects.get(uuid=idService) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(request.user) # Now we have to locate an instance of the service, so we can assign it to user. ads = UserServiceManager.manager().getAssignationForUser(ds, request.user) if ads.isInMaintenance() is True: raise ServiceInMaintenanceMode() logger.debug('Found service: {0}'.format(ads)) trans = Transport.objects.get(uuid=idTransport) # Ensures that the transport is allowed for this service if trans not in ads.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(request.ip) is False: raise InvalidServiceException() if doTest is False: return (None, ads, None, trans, None) # Test if the service is ready if ads.isReady(): log.doLog(ads, log.INFO, "User {0} from {1} has initiated access".format(request.user.name, request.ip), log.WEB) # If ready, show transport for this service, if also ready ofc iads = ads.getInstance() ip = iads.getIp() events.addEvent(ads.deployed_service, events.ET_ACCESS, username=request.user.name, srcip=request.ip, dstip=ip, uniqueid=ads.unique_id) if ip is not None: itrans = trans.getInstance() if itrans.isAvailableFor(ip): ads.setConnectionSource(request.ip, 'unknown') log.doLog(ads, log.INFO, "User service ready", log.WEB) UserServiceManager.manager().notifyPreconnect(ads, itrans.processedUser(ads, request.user), itrans.protocol) return (ip, ads, iads, trans, itrans) else: log.doLog(ads, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug('Transport is not ready for user service {0}'.format(ads)) else: logger.debug('Ip not available from user service {0}'.format(ads)) else: log.doLog(ads, log.WARN, "User {0} from {1} tried to access, but machine was not ready".format(request.user.name, request.ip), log.WEB) return None
def loggedOut(self, userService, userName=None, save=True): """ This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance """ counter = int(userService.getProperty('loginsCounter', '0')) if counter > 0: counter -= 1 userService.setProperty('loginsCounter', six.text_type(counter)) if GlobalConfig.EXCLUSIVE_LOGOUT.getBool(True) is True: if counter > 0: return uniqueId = userService.unique_id userService.setInUse(False) si = userService.getInstance() si.userLoggedOut(userName) userService.updateData(si) serviceIp = si.getIp() fullUserName = '******' if userService.user is not None: fullUserName = userService.user.manager.name + '\\' + userService.user.name knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' if userName is None: userName = '******' addEvent(userService.deployed_service, ET_LOGOUT, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged out".format(userName), log.OSMANAGER) log.useLog('logout', uniqueId, serviceIp, userName, knownUserIP, fullUserName, userService.friendly_name, userService.deployed_service.name) if save: userService.save()
def loggedOut(self, userService: 'UserService', userName: typing.Optional[str] = None) -> None: """ This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance """ counter = int( typing.cast(str, userService.getProperty('loginsCounter', '0'))) if counter > 0: counter -= 1 userService.setProperty('loginsCounter', str(counter)) if GlobalConfig.EXCLUSIVE_LOGOUT.getBool(True) and counter > 0: return uniqueId = userService.unique_id userService.setInUse(False) userServiceInstance = userService.getInstance() userServiceInstance.userLoggedOut(userName or 'unknown') userService.updateData(userServiceInstance) serviceIp = userServiceInstance.getIp() fullUserName = '******' if userService.user: fullUserName = userService.user.manager.name + '\\' + userService.user.name knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' userName = userName or 'unknown' addEvent(userService.deployed_service, ET_LOGOUT, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged out".format(userName), log.OSMANAGER) log.useLog('logout', uniqueId, serviceIp, userName, knownUserIP, fullUserName, userService.friendly_name, userService.deployed_service.name)
def webLogout(request, exit_url=None): ''' Helper function to clear user related data from session. If this method is not used, the session we be cleaned anyway by django in regular basis. ''' # Invoke exit for authenticator if request.user is not None and request.user.id != ROOT_ID: events.addEvent(request.user.manager, events.ET_LOGOUT, username=request.user.name, srcip=request.ip) request.session.clear() if exit_url is None: exit_url = GlobalConfig.LOGIN_URL.get() if GlobalConfig.REDIRECT_TO_HTTPS.getBool() is True: exit_url = exit_url.replace('http://', 'https://') # Try to delete session return HttpResponseRedirect(request.build_absolute_uri(exit_url))
def webLogout(request, exit_url=None): ''' Helper function to clear user related data from session. If this method is not used, the session we be cleaned anyway by django in regular basis. ''' # Invoke exit for authenticator if request.user.id != ROOT_ID: events.addEvent(request.user.manager, events.ET_LOGOUT, username=request.user.name, srcip=request.ip) request.session.clear() if exit_url is None: exit_url = GlobalConfig.LOGIN_URL.get() if GlobalConfig.REDIRECT_TO_HTTPS.getBool() is True: exit_url = exit_url.replace('http://', 'https://') # Try to delete session return HttpResponseRedirect(request.build_absolute_uri(exit_url))
def loggedIn(self, userService, userName=None, save=True): ''' This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance ''' uniqueId = userService.unique_id userService.setInUse(True) si = userService.getInstance() si.userLoggedIn(userName) userService.updateData(si) serviceIp = si.getIp() fullUserName = '******' if userService.user is not None: fullUserName = userService.user.manager.name + '\\' + userService.user.name knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' if userName is None: userName = '******' addEvent(userService.deployed_service, ET_LOGIN, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged in".format(userName), log.OSMANAGER) log.useLog('login', uniqueId, serviceIp, userName, knownUserIP, fullUserName) counter = int(userService.getProperty('loginsCounter', '0')) + 1 userService.setProperty('loginsCounter', six.text_type(counter)) if save: userService.save()
def loggedIn(self, userService: 'UserService', userName: typing.Optional[str] = None) -> None: """ This method: - Add log in event to stats - Sets service in use - Invokes userLoggedIn for user service instance """ uniqueId = userService.unique_id userService.setInUse(True) userServiceInstance = userService.getInstance() userServiceInstance.userLoggedIn(userName or 'unknown') userService.updateData(userServiceInstance) serviceIp = userServiceInstance.getIp() fullUserName = userService.user.manager.name + '\\' + userService.user.name if userService.user else 'unknown' knownUserIP = userService.src_ip + ':' + userService.src_hostname knownUserIP = knownUserIP if knownUserIP != ':' else 'unknown' userName = userName or 'unknown' addEvent(userService.deployed_service, ET_LOGIN, fld1=userName, fld2=knownUserIP, fld3=serviceIp, fld4=fullUserName) log.doLog(userService, log.INFO, "User {0} has logged in".format(userName), log.OSMANAGER) log.useLog('login', uniqueId, serviceIp, userName, knownUserIP, fullUserName, userService.friendly_name, userService.deployed_service.name) counter = int( typing.cast(str, userService.getProperty('loginsCounter', '0'))) + 1 userService.setProperty('loginsCounter', str(counter))
def __registerUser(authenticator, authInstance, username): ''' Check if this user already exists on database with this authenticator, if don't, create it with defaults This will work correctly with both internal or externals cause we first authenticate the user, if internal and user do not exists in database authenticate will return false, if external and return true, will create a reference in database ''' from uds.core.util.request import getRequest username = authInstance.transformUsername(username) logger.debug('Transformed username: {0}'.format(username)) usr = authenticator.getOrCreateUser(username, authInstance.getRealName(username)) if usr is not None and State.isActive(usr.state): # Now we update database groups for this user usr.getManager().recreateGroups(usr) # And add an login event events.addEvent(authenticator, events.ET_LOGIN, username=username, srcip=getRequest().ip) # pylint: disable=maybe-no-member return usr return None
def getAssignationForUser(self, ds, user): assignedUserService = self.getExistingAssignationForUser(ds, user) # If has an assigned user service, returns this without any more work if assignedUserService is not None: return assignedUserService # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1] if len(cache) > 0: cache = cache[0] cache.assignToUser(user) cache.save() # Store assigned ASAP, we do not know how long assignToUser method of instance will take else: cache = None # Out of atomic transaction if cache is not None: logger.debug('Found a cached-ready service from {0} for user {1}, item {2}'.format(ds, user, cache)) addEvent(ds, ET_CACHE_HIT, fld1=ds.cachedUserServices().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE).count()) ci = cache.getInstance() # User Deployment instance ci.assignToUser(user) cache.updateData(ci) cache.save() return cache # Cache missed # Now find if there is a preparing one with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if len(cache) > 0: cache = cache[0] cache.assignToUser(user) cache.save() else: cache = None # Out of atomic transaction if cache is not None: logger.debug('Found a cached-preparing service from {0} for user {1}, item {2}'.format(ds, user, cache)) addEvent(ds, ET_CACHE_MISS, fld1=ds.cachedUserServices().filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING).count()) ci = cache.getInstance() # User Deployment instance ci.assignToUser(user) cache.updateData(ci) cache.save() return cache # Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested ty = ds.service.getType() if ty.usesCache is True: # inCacheL1 = ds.cachedUserServices().filter(UserServiceManager.getCacheStateFilter(services.UserDeployment.L1_CACHE)).count() inAssigned = ds.assignedUserServices().filter(UserServiceManager.getStateFilter()).count() # totalL1Assigned = inCacheL1 + inAssigned if inAssigned >= ds.max_srvs: # cacheUpdater will drop necesary L1 machines, so it's not neccesary to check against inCacheL1 raise MaxServicesReachedException() # Can create new service, create it addEvent(ds, ET_CACHE_MISS, fld1=0) return self.createAssignedFor(ds, user)
def get(self) -> typing.MutableMapping[str, typing.Any]: """ Processes get requests, currently none """ logger.debug( 'Tunnel parameters for GET: %s (%s) from %s', self._args, self._params, self._request.ip ) if ( not isTrustedSource(self._request.ip) or len(self._args) != 2 or len(self._args[0]) != 48 ): # Invalid requests raise AccessDenied() # Try to get ticket from DB try: user, userService, host, port, extra = models.TicketStore.get_for_tunnel( self._args[0] ) data = {} if self._args[1][:4] == 'stop': sent, recv = self._params['sent'], self._params['recv'] # Ensures extra exists... extra = extra or {} now = models.getSqlDatetimeAsUnix() totalTime = now - extra.get('b', now-1) msg = f'User {user.name} stopped tunnel {extra.get("t", "")[:8]}... to {host}:{port}: u:{sent}/d:{recv}/t:{totalTime}.' log.doLog(user.manager, log.INFO, msg) log.doLog(userService, log.INFO, msg) else: if net.ipToLong(self._args[1][:32]) == 0: raise Exception('Invalid from IP') events.addEvent( userService.deployed_service, events.ET_TUNNEL_ACCESS, username=user.pretty_name, srcip=self._args[1], dstip=host, uniqueid=userService.unique_id, ) msg = f'User {user.name} started tunnel {self._args[0][:8]}... to {host}:{port} from {self._args[1]}.' log.doLog(user.manager, log.INFO, msg) log.doLog(userService, log.INFO, msg) # Generate new, notify only, ticket rstr = managers.cryptoManager().randomString(length=8) notifyTicket = models.TicketStore.create_for_tunnel( userService=userService, port=port, host=host, extra={'t': self._args[0], 'b': models.getSqlDatetimeAsUnix()}, validity=MAX_SESSION_LENGTH) data = { 'host': host, 'port': port, 'notify': notifyTicket } return data except Exception as e: logger.info('Ticket ignored: %s', e) raise AccessDenied()
def getService( # pylint: disable=too-many-locals, too-many-branches, too-many-statements self, user: User, os: typing.MutableMapping, srcIp: str, idService: str, idTransport: str, doTest: bool = True, clientHostname: typing.Optional[str] = None ) -> typing.Tuple[typing.Optional[str], UserService, typing.Optional['services.UserDeployment'], Transport, typing.Optional[transports.Transport]]: """ Get service info from user service """ if idService[0] == 'M': # Meta pool return self.getMeta(user, srcIp, os, idService[1:]) userService = self.locateUserService(user, idService, create=True) if not userService: raise InvalidServiceException( _('Invalid service. The service is not available at this moment. Please, try later' )) # Early log of "access try" so we can imagine what is going on userService.setConnectionSource(srcIp, clientHostname or srcIp) if userService.isInMaintenance(): raise ServiceInMaintenanceMode() if not userService.deployed_service.isAccessAllowed(): raise ServiceAccessDeniedByCalendar() if not idTransport: # Find a suitable transport t: Transport for t in userService.deployed_service.transports.order_by( 'priority'): typeTrans = t.getType() if t.validForIp(srcIp) and typeTrans.supportsOs( os['OS']) and t.validForOs(os['OS']): idTransport = t.uuid break try: transport: Transport = Transport.objects.get(uuid=idTransport) except Exception: raise InvalidServiceException() # Ensures that the transport is allowed for this service if userService.deployed_service.transports.filter( id=transport.id).count() == 0: raise InvalidServiceException() # If transport is not available for the request IP... if not transport.validForIp(srcIp): msg = _('The requested transport {} is not valid for {}').format( transport.name, srcIp) logger.error(msg) raise InvalidServiceException(msg) userName = user.name if user else 'unknown' if not doTest: # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name)) return None, userService, None, transport, None serviceNotReadyCode = 0x0001 ip = 'unknown' # Test if the service is ready if userService.isReady(): serviceNotReadyCode = 0x0002 log.doLog( userService, log.INFO, "User {0} from {1} has initiated access".format( user.name, srcIp), log.WEB) # If ready, show transport for this service, if also ready ofc userServiceInstance = userService.getInstance() ip = userServiceInstance.getIp() userService.logIP(ip) # Update known ip logger.debug('IP: %s', ip) if self.checkUuid( userService ) is False: # The service is not the expected one serviceNotReadyCode = 0x0004 log.doLog( userService, log.WARN, "User service is not accessible due to invalid UUID (ip {0})" .format(ip), log.TRANSPORT) logger.debug('UUID check failed for user service %s', userService) else: events.addEvent(userService.deployed_service, events.ET_ACCESS, username=userName, srcip=srcIp, dstip=ip, uniqueid=userService.unique_id) if ip: serviceNotReadyCode = 0x0003 transportInstance = transport.getInstance() if transportInstance.isAvailableFor(userService, ip): # userService.setConnectionSource(srcIp, 'unknown') log.doLog(userService, log.INFO, "User service ready", log.WEB) self.notifyPreconnect( userService, transportInstance.processedUser(userService, user), transportInstance.protocol) traceLogger.info( 'READY on service "%s" for user "%s" with transport "%s" (ip:%s)', userService.name, userName, transport.name, ip) return ip, userService, userServiceInstance, transport, transportInstance message = transportInstance.getCustomAvailableErrorMsg( userService, ip) log.doLog(userService, log.WARN, message, log.TRANSPORT) logger.debug( 'Transport is not ready for user service %s: %s', userService, message) else: logger.debug('Ip not available from user service %s', userService) else: log.doLog( userService, log.WARN, "User {} from {} tried to access, but service was not ready". format(user.name, srcIp), log.WEB) traceLogger.error( 'ERROR %s on service "%s" for user "%s" with transport "%s" (ip:%s)', serviceNotReadyCode, userService.name, userName, transport.name, ip) raise ServiceNotReadyError(code=serviceNotReadyCode, service=userService, transport=transport)
def getAssignationForUser( self, servicePool: ServicePool, user: User ) -> typing.Optional[UserService]: # pylint: disable=too-many-branches if servicePool.service.getInstance().spawnsNew is False: assignedUserService = self.getExistingAssignationForUser( servicePool, user) else: assignedUserService = None # If has an assigned user service, returns this without any more work if assignedUserService: return assignedUserService if servicePool.isRestrained(): raise InvalidServiceException( _('The requested service is restrained')) cache: typing.Optional[UserService] = None # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): caches = typing.cast( typing.List[UserService], servicePool.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE, os_state=State.USABLE)[:1]) if caches: cache = caches[0] # Ensure element is reserved correctly on DB if servicePool.cachedUserServices().select_for_update().filter( user=None, uuid=typing.cast( UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of previous atomic if not cache: with transaction.atomic(): caches = typing.cast( typing.List[UserService], servicePool.cachedUserServices().select_for_update(). filter(cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1]) if cache: cache = caches[0] if servicePool.cachedUserServices().select_for_update( ).filter(user=None, uuid=typing.cast(UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of atomic transaction if cache: # Early assign cache.assignToUser(user) logger.debug( 'Found a cached-ready service from %s for user %s, item %s', servicePool, user, cache) events.addEvent(servicePool, events.ET_CACHE_HIT, fld1=servicePool.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE).count()) return cache # Cache missed # Now find if there is a preparing one with transaction.atomic(): caches = servicePool.cachedUserServices().select_for_update( ).filter(cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if caches: cache = caches[0] if servicePool.cachedUserServices().select_for_update().filter( user=None, uuid=typing.cast( UserService, cache).uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None # Out of atomic transaction if cache: cache.assignToUser(user) logger.debug( 'Found a cached-preparing service from %s for user %s, item %s', servicePool, user, cache) events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=servicePool.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING).count()) return cache # Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested serviceType = servicePool.service.getType() if serviceType.usesCache: # inCacheL1 = ds.cachedUserServices().filter(UserServiceManager.getCacheStateFilter(services.UserDeployment.L1_CACHE)).count() inAssigned = servicePool.assignedUserServices().filter( UserServiceManager.getStateFilter()).count() # totalL1Assigned = inCacheL1 + inAssigned if inAssigned >= servicePool.max_srvs: # cacheUpdater will drop unnecesary L1 machines, so it's not neccesary to check against inCacheL1 log.doLog( servicePool, log.WARN, 'Max number of services reached: {}'.format( servicePool.max_srvs), log.INTERNAL) raise MaxServicesReachedError() # Can create new service, create it events.addEvent(servicePool, events.ET_CACHE_MISS, fld1=0) return self.createAssignedFor(servicePool, user)
def getService(self, user, srcIp, idService, idTransport, doTest=True): """ Get service info from """ userService = self.locateUserService(user, idService, create=True) # Early log of "access try" so we can imagine what is going on userService.setConnectionSource(srcIp, 'unknown') if userService.isInMaintenance() is True: raise ServiceInMaintenanceMode() if userService.deployed_service.isAccessAllowed() is False: raise ServiceAccessDeniedByCalendar() if idTransport is None or idTransport == '': # Find a suitable transport for v in userService.deployed_service.transports.order_by( 'priority'): if v.validForIp(srcIp): idTransport = v.uuid break try: trans = Transport.objects.get(uuid=idTransport) except Exception: raise InvalidServiceException() # Ensures that the transport is allowed for this service if trans not in userService.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(srcIp) is False: msg = 'The requested transport {} is not valid for {}'.format( trans.name, srcIp) logger.error(msg) raise InvalidServiceException(msg) if user is not None: userName = user.name else: userName = '******' if doTest is False: # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name)) return None, userService, None, trans, None serviceNotReadyCode = 0x0001 ip = 'unknown' # Test if the service is ready if userService.isReady(): serviceNotReadyCode = 0x0002 log.doLog( userService, log.INFO, "User {0} from {1} has initiated access".format( user.name, srcIp), log.WEB) # If ready, show transport for this service, if also ready ofc iads = userService.getInstance() ip = iads.getIp() userService.logIP(ip) # Update known ip if self.checkUuid( userService) is False: # Machine is not what is expected serviceNotReadyCode = 0x0004 log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug( 'Transport is not ready for user service {0}'.format( userService)) else: events.addEvent(userService.deployed_service, events.ET_ACCESS, username=userName, srcip=srcIp, dstip=ip, uniqueid=userService.unique_id) if ip is not None: serviceNotReadyCode = 0x0003 itrans = trans.getInstance() if itrans.isAvailableFor(userService, ip): # userService.setConnectionSource(srcIp, 'unknown') log.doLog(userService, log.INFO, "User service ready", log.WEB) self.notifyPreconnect( userService, itrans.processedUser(userService, user), itrans.protocol) traceLogger.info( 'READY on service "{}" for user "{}" with transport "{}" (ip:{})' .format(userService.name, userName, trans.name, ip)) return ip, userService, iads, trans, itrans else: message = itrans.getCustomAvailableErrorMsg( userService, ip) log.doLog(userService, log.WARN, message, log.TRANSPORT) logger.debug( 'Transport is not ready for user service {}: {}'. format(userService, message)) else: logger.debug( 'Ip not available from user service {0}'.format( userService)) else: log.doLog( userService, log.WARN, "User {0} from {1} tried to access, but service was not ready". format(user.name, srcIp), log.WEB) traceLogger.error( 'ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})' .format(serviceNotReadyCode, userService.name, userName, trans.name, ip)) raise ServiceNotReadyError(code=serviceNotReadyCode, service=userService, transport=trans)
def getAssignationForUser(self, ds, user): if ds.service.getInstance().spawnsNew is False: assignedUserService = self.getExistingAssignationForUser(ds, user) else: assignedUserService = None # If has an assigned user service, returns this without any more work if assignedUserService is not None: return assignedUserService # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE, os_state=State.USABLE)[:1] if len(cache) == 0: cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1] if len(cache) > 0: cache = cache[0] cache.assignToUser(user) cache.save( ) # Store assigned ASAP, we do not know how long assignToUser method of instance will take else: cache = None # Out of atomic transaction if cache is not None: logger.debug( 'Found a cached-ready service from {0} for user {1}, item {2}'. format(ds, user, cache)) events.addEvent(ds, events.ET_CACHE_HIT, fld1=ds.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE).count()) ci = cache.getInstance() # User Deployment instance ci.assignToUser(user) cache.updateData(ci) cache.save() return cache # Cache missed # Now find if there is a preparing one with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if len(cache) > 0: cache = cache[0] cache.assignToUser(user) cache.save() else: cache = None # Out of atomic transaction if cache is not None: logger.debug( 'Found a cached-preparing service from {0} for user {1}, item {2}' .format(ds, user, cache)) events.addEvent(ds, events.ET_CACHE_MISS, fld1=ds.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING).count()) ci = cache.getInstance() # User Deployment instance ci.assignToUser(user) cache.updateData(ci) cache.save() return cache # Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested ty = ds.service.getType() if ty.usesCache is True: # inCacheL1 = ds.cachedUserServices().filter(UserServiceManager.getCacheStateFilter(services.UserDeployment.L1_CACHE)).count() inAssigned = ds.assignedUserServices().filter( UserServiceManager.getStateFilter()).count() # totalL1Assigned = inCacheL1 + inAssigned if inAssigned >= ds.max_srvs: # cacheUpdater will drop necesary L1 machines, so it's not neccesary to check against inCacheL1 raise MaxServicesReachedError() # Can create new service, create it events.addEvent(ds, events.ET_CACHE_MISS, fld1=0) return self.createAssignedFor(ds, user)
def getService(self, user, srcIp, idService, idTransport, doTest=True): ''' Get service info from ''' userService = self.locateUserService(user, idService, create=True) if userService.isInMaintenance() is True: raise ServiceInMaintenanceMode() if userService.deployed_service.isAccessAllowed() is False: raise ServiceAccessDeniedByCalendar() if idTransport is None or idTransport == '': # Find a suitable transport for v in userService.deployed_service.transports.order_by('priority'): if v.validForIp(srcIp): idTransport = v.uuid break try: trans = Transport.objects.get(uuid=idTransport) except Exception: raise InvalidServiceException() # Ensures that the transport is allowed for this service if trans not in userService.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(srcIp) is False: msg = 'The requested transport {} is not valid for {}'.format(trans.name, srcIp) logger.error(msg) raise InvalidServiceException(msg) if user is not None: userName = user.name else: userName = '******' if doTest is False: # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name)) return (None, userService, None, trans, None) serviceNotReadyCode = 0x0001 ip = 'unknown' # Test if the service is ready if userService.isReady(): serviceNotReadyCode = 0x0002 log.doLog(userService, log.INFO, "User {0} from {1} has initiated access".format(user.name, srcIp), log.WEB) # If ready, show transport for this service, if also ready ofc iads = userService.getInstance() ip = iads.getIp() userService.logIP(ip) # Update known ip if self.checkUuid(userService) is False: # Machine is not what is expected serviceNotReadyCode = 0x0004 log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug('Transport is not ready for user service {0}'.format(userService)) else: events.addEvent(userService.deployed_service, events.ET_ACCESS, username=userName, srcip=srcIp, dstip=ip, uniqueid=userService.unique_id) if ip is not None: serviceNotReadyCode = 0x0003 itrans = trans.getInstance() if itrans.isAvailableFor(userService, ip): userService.setConnectionSource(srcIp, 'unknown') log.doLog(userService, log.INFO, "User service ready", log.WEB) self.notifyPreconnect(userService, itrans.processedUser(userService, user), itrans.protocol) traceLogger.info('READY on service "{}" for user "{}" with transport "{}" (ip:{})'.format(userService.name, userName, trans.name, ip)) return (ip, userService, iads, trans, itrans) else: message = itrans.getCustomAvailableErrorMsg(userService, ip) log.doLog(userService, log.WARN, message, log.TRANSPORT) logger.debug('Transport is not ready for user service {}: {}'.format(userService, message)) else: logger.debug('Ip not available from user service {0}'.format(userService)) else: log.doLog(userService, log.WARN, "User {0} from {1} tried to access, but service was not ready".format(user.name, srcIp), log.WEB) traceLogger.error('ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})'.format(serviceNotReadyCode, userService.name, userName, trans.name, ip)) raise ServiceNotReadyError(code=serviceNotReadyCode, service=userService, transport=trans)
def connection(self, doNotCheck=False): kind, idService = self._args[0][0], self._args[0][1:] idTransport = self._args[1] logger.debug('Type: {}, Service: {}, Transport: {}'.format(kind, idService, idTransport)) try: logger.debug('Kind of service: {0}, idService: {1}'.format(kind, idService)) if kind == 'A': # This is an assigned service ads = UserService.objects.get(uuid=processUuid(idService)) else: ds = DeployedService.objects.get(uuid=processUuid(idService)) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(self._user) # Now we have to locate an instance of the service, so we can assign it to user. ads = UserServiceManager.manager().getAssignationForUser(ds, self._user) if ads.isInMaintenance() is True: return Connection.result(error='Service in maintenance') logger.debug('Found service: {0}'.format(ads)) trans = Transport.objects.get(uuid=processUuid(idTransport)) if trans.validForIp(self._request.ip) is False: return Connection.result(error='Access denied') # Test if the service is ready if doNotCheck or ads.isReady(): log.doLog(ads, log.INFO, "User {0} from {1} has initiated access".format(self._user.name, self._request.ip), log.WEB) # If ready, show transport for this service, if also ready ofc iads = ads.getInstance() ip = iads.getIp() logger.debug('IP: {}'.format(ip)) events.addEvent(ads.deployed_service, events.ET_ACCESS, username=self._user.name, srcip=self._request.ip, dstip=ip, uniqueid=ads.unique_id) if ip is not None: itrans = trans.getInstance() if itrans.providesConnetionInfo() and (doNotCheck or itrans.isAvailableFor(ads, ip)): ads.setConnectionSource(self._request.ip, 'unknown') log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB) ci = { 'username': '', 'password': '', 'domain': '', 'protocol': 'unknown', 'ip': ip } ci.update(itrans.getConnectionInfo(ads, self._user, 'UNKNOWN')) UserServiceManager.manager().notifyPreconnect(ads, itrans.processedUser(ads, self._user), itrans.protocol) return Connection.result(result=ci) else: log.doLog(ads, log.WARN, "User service is not accessible by REST (ip {0})".format(ip), log.TRANSPORT) logger.debug('Transport {} is not accesible for user service {} from {}'.format(trans, ads, self._request.ip)) logger.debug("{}, {}".format(itrans.providesConnetionInfo(), itrans.isAvailableFor(ads, ip))) else: logger.debug('Ip not available from user service {0}'.format(ads)) else: log.doLog(ads, log.WARN, "User {0} from {1} tried to access, but service was not ready".format(self._user.name, self._request.ip), log.WEB) # Not ready, show message and return to this page in a while return Connection.result(error='Service not ready') except Exception as e: return Connection.result(error=six.text_type(e))
def getService(request, idService, idTransport, doTest=True): kind, idService = idService[0], idService[1:] logger.debug('Kind of service: {0}, idService: {1}'.format( kind, idService)) if kind == 'A': # This is an assigned service logger.debug('Getting A service {}'.format(idService)) ads = UserService.objects.get(uuid=idService) ads.deployed_service.validateUser(request.user) else: ds = DeployedService.objects.get(uuid=idService) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(request.user) # Now we have to locate an instance of the service, so we can assign it to user. ads = UserServiceManager.manager().getAssignationForUser( ds, request.user) if ads.isInMaintenance() is True: raise ServiceInMaintenanceMode() logger.debug('Found service: {0}'.format(ads)) trans = Transport.objects.get(uuid=idTransport) # Ensures that the transport is allowed for this service if trans not in ads.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(request.ip) is False: raise InvalidServiceException() if doTest is False: return (None, ads, None, trans, None) # Test if the service is ready if ads.isReady(): log.doLog( ads, log.INFO, "User {0} from {1} has initiated access".format( request.user.name, request.ip), log.WEB) # If ready, show transport for this service, if also ready ofc iads = ads.getInstance() ip = iads.getIp() events.addEvent(ads.deployed_service, events.ET_ACCESS, username=request.user.name, srcip=request.ip, dstip=ip, uniqueid=ads.unique_id) if ip is not None: itrans = trans.getInstance() if itrans.isAvailableFor(ip): ads.setConnectionSource(request.ip, 'unknown') log.doLog(ads, log.INFO, "User service ready", log.WEB) UserServiceManager.manager().notifyPreconnect( ads, itrans.processedUser(ads, request.user), itrans.protocol) return (ip, ads, iads, trans, itrans) else: log.doLog(ads, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug( 'Transport is not ready for user service {0}'.format(ads)) else: logger.debug('Ip not available from user service {0}'.format(ads)) else: log.doLog( ads, log.WARN, "User {0} from {1} tried to access, but machine was not ready". format(request.user.name, request.ip), log.WEB) return None
def getService(self, user, srcIp, idService, idTransport, doTest=True): ''' Get service info from ''' kind, idService = idService[0], idService[1:] logger.debug('Kind of service: {0}, idService: {1}'.format( kind, idService)) if kind == 'A': # This is an assigned service logger.debug('Getting A service {}'.format(idService)) userService = UserService.objects.get(uuid=idService) userService.deployed_service.validateUser(user) else: ds = ServicePool.objects.get(uuid=idService) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(user) # Now we have to locate an instance of the service, so we can assign it to user. userService = self.getAssignationForUser(ds, user) logger.debug('Found service: {0}'.format(userService)) if userService.isInMaintenance() is True: raise ServiceInMaintenanceMode() # If service is not visible, do not allow it to be used if userService.deployed_service.isVisible() is False: raise InvalidServiceException() if userService.deployed_service.isAccessAllowed() is False: raise ServiceAccessDeniedByCalendar() if idTransport is None or idTransport == '': # Find a suitable transport for v in userService.deployed_service.transports.order_by( 'priority'): if v.validForIp(srcIp): idTransport = v.uuid break try: trans = Transport.objects.get(uuid=idTransport) except Exception: raise InvalidServiceException() # Ensures that the transport is allowed for this service if trans not in userService.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(srcIp) is False: raise InvalidServiceException() if user is not None: userName = user.name if doTest is False: # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name)) return (None, userService, None, trans, None) serviceNotReadyCode = 0x0001 ip = 'unknown' # Test if the service is ready if userService.isReady(): serviceNotReadyCode = 0x0002 log.doLog( userService, log.INFO, "User {0} from {1} has initiated access".format( user.name, srcIp), log.WEB) # If ready, show transport for this service, if also ready ofc iads = userService.getInstance() ip = iads.getIp() if self.checkUuid( userService) is False: # Machine is not what is expected serviceNotReadyCode = 0x0004 log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug( 'Transport is not ready for user service {0}'.format( userService)) else: events.addEvent(userService.deployed_service, events.ET_ACCESS, username=userName, srcip=srcIp, dstip=ip, uniqueid=userService.unique_id) if ip is not None: serviceNotReadyCode = 0x0003 itrans = trans.getInstance() if itrans.isAvailableFor(userService, ip): userService.setConnectionSource(srcIp, 'unknown') log.doLog(userService, log.INFO, "User service ready", log.WEB) self.notifyPreconnect( userService, itrans.processedUser(userService, user), itrans.protocol) traceLogger.info( 'READY on service "{}" for user "{}" with transport "{}" (ip:{})' .format(userService.name, userName, trans.name, ip)) return (ip, userService, iads, trans, itrans) else: log.doLog( userService, log.WARN, "User service is not accessible (ip {0})".format( ip), log.TRANSPORT) logger.debug( 'Transport is not ready for user service {0}'. format(userService)) else: logger.debug( 'Ip not available from user service {0}'.format( userService)) else: log.doLog( userService, log.WARN, "User {0} from {1} tried to access, but service was not ready". format(user.name, srcIp), log.WEB) traceLogger.error( 'ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})' .format(serviceNotReadyCode, userService.name, userName, trans.name, ip)) raise ServiceNotReadyError(code=serviceNotReadyCode, service=userService, transport=trans)
def getService(self, user, srcIp, idService, idTransport, doTest=True): ''' Get service info from ''' kind, idService = idService[0], idService[1:] logger.debug('Kind of service: {0}, idService: {1}'.format(kind, idService)) if kind == 'A': # This is an assigned service logger.debug('Getting A service {}'.format(idService)) userService = UserService.objects.get(uuid=idService) userService.deployed_service.validateUser(user) else: ds = ServicePool.objects.get(uuid=idService) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(user) # Now we have to locate an instance of the service, so we can assign it to user. userService = self.getAssignationForUser(ds, user) logger.debug('Found service: {0}'.format(userService)) if userService.isInMaintenance() is True: raise ServiceInMaintenanceMode() # If service is not visible, do not allow it to be used if userService.deployed_service.isVisible() is False: raise InvalidServiceException() if userService.deployed_service.isAccessAllowed() is False: raise ServiceAccessDeniedByCalendar() if idTransport is None or idTransport == '': # Find a suitable transport for v in userService.deployed_service.transports.order_by('priority'): if v.validForIp(srcIp): idTransport = v.uuid break try: trans = Transport.objects.get(uuid=idTransport) except Exception: raise InvalidServiceException() # Ensures that the transport is allowed for this service if trans not in userService.deployed_service.transports.all(): raise InvalidServiceException() # If transport is not available for the request IP... if trans.validForIp(srcIp) is False: raise InvalidServiceException() if user is not None: userName = user.name if doTest is False: # traceLogger.info('GOT service "{}" for user "{}" with transport "{}" (NOT TESTED)'.format(userService.name, userName, trans.name)) return (None, userService, None, trans, None) serviceNotReadyCode = 0x0001 ip = 'unknown' # Test if the service is ready if userService.isReady(): serviceNotReadyCode = 0x0002 log.doLog(userService, log.INFO, "User {0} from {1} has initiated access".format(user.name, srcIp), log.WEB) # If ready, show transport for this service, if also ready ofc iads = userService.getInstance() ip = iads.getIp() if self.checkUuid(userService) is False: # Machine is not what is expected serviceNotReadyCode = 0x0004 log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug('Transport is not ready for user service {0}'.format(userService)) else: events.addEvent(userService.deployed_service, events.ET_ACCESS, username=userName, srcip=srcIp, dstip=ip, uniqueid=userService.unique_id) if ip is not None: serviceNotReadyCode = 0x0003 itrans = trans.getInstance() if itrans.isAvailableFor(userService, ip): userService.setConnectionSource(srcIp, 'unknown') log.doLog(userService, log.INFO, "User service ready", log.WEB) self.notifyPreconnect(userService, itrans.processedUser(userService, user), itrans.protocol) traceLogger.info('READY on service "{}" for user "{}" with transport "{}" (ip:{})'.format(userService.name, userName, trans.name, ip)) return (ip, userService, iads, trans, itrans) else: log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT) logger.debug('Transport is not ready for user service {0}'.format(userService)) else: logger.debug('Ip not available from user service {0}'.format(userService)) else: log.doLog(userService, log.WARN, "User {0} from {1} tried to access, but service was not ready".format(user.name, srcIp), log.WEB) traceLogger.error('ERROR {} on service "{}" for user "{}" with transport "{}" (ip:{})'.format(serviceNotReadyCode, userService.name, userName, trans.name, ip)) raise ServiceNotReadyError(code=serviceNotReadyCode, service=userService, transport=trans)
def connection(self, doNotCheck=False): kind, idService = self._args[0][0], self._args[0][1:] idTransport = self._args[1] logger.debug('Type: {}, Service: {}, Transport: {}'.format( kind, idService, idTransport)) try: logger.debug('Kind of service: {0}, idService: {1}'.format( kind, idService)) if kind == 'A': # This is an assigned service ads = UserService.objects.get(uuid=processUuid(idService)) else: ds = DeployedService.objects.get(uuid=processUuid(idService)) # We first do a sanity check for this, if the user has access to this service # If it fails, will raise an exception ds.validateUser(self._user) # Now we have to locate an instance of the service, so we can assign it to user. ads = UserServiceManager.manager().getAssignationForUser( ds, self._user) if ads.isInMaintenance() is True: return Connection.result(error='Service in maintenance') logger.debug('Found service: {0}'.format(ads)) trans = Transport.objects.get(uuid=processUuid(idTransport)) if trans.validForIp(self._request.ip) is False: return Connection.result(error='Access denied') # Test if the service is ready if doNotCheck or ads.isReady(): log.doLog( ads, log.INFO, "User {0} from {1} has initiated access".format( self._user.name, self._request.ip), log.WEB) # If ready, show transport for this service, if also ready ofc iads = ads.getInstance() ip = iads.getIp() logger.debug('IP: {}'.format(ip)) events.addEvent(ads.deployed_service, events.ET_ACCESS, username=self._user.name, srcip=self._request.ip, dstip=ip, uniqueid=ads.unique_id) if ip is not None: itrans = trans.getInstance() if itrans.providesConnetionInfo() and ( doNotCheck or itrans.isAvailableFor(ads, ip)): ads.setConnectionSource(self._request.ip, 'unknown') log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB) ci = { 'username': '', 'password': '', 'domain': '', 'protocol': 'unknown', 'ip': ip } ci.update( itrans.getConnectionInfo(ads, self._user, 'UNKNOWN')) UserServiceManager.manager().notifyPreconnect( ads, itrans.processedUser(ads, self._user), itrans.protocol) return Connection.result(result=ci) else: log.doLog( ads, log.WARN, "User service is not accessible by REST (ip {0})". format(ip), log.TRANSPORT) logger.debug( 'Transport {} is not accesible for user service {} from {}' .format(trans, ads, self._request.ip)) logger.debug("{}, {}".format( itrans.providesConnetionInfo(), itrans.isAvailableFor(ads, ip))) else: logger.debug( 'Ip not available from user service {0}'.format(ads)) else: log.doLog( ads, log.WARN, "User {0} from {1} tried to access, but service was not ready" .format(self._user.name, self._request.ip), log.WEB) # Not ready, show message and return to this page in a while return Connection.result(error='Service not ready') except Exception as e: return Connection.result(error=six.text_type(e))
def getAssignationForUser(self, ds, user): if ds.service.getInstance().spawnsNew is False: assignedUserService = self.getExistingAssignationForUser(ds, user) else: assignedUserService = None # If has an assigned user service, returns this without any more work if assignedUserService is not None: return assignedUserService if ds.isRestrained(): raise InvalidServiceException( _('The requested service is restrained')) # Now try to locate 1 from cache already "ready" (must be usable and at level 1) with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE, os_state=State.USABLE)[:1] if len(cache) != 0: cache = cache[0] # Ensure element is reserved correctly on DB if ds.cachedUserServices().select_for_update().filter( user=None, uuid=cache.uuid).update(user=user, cache_level=0) != 1: cache = None else: cache = None if cache == None: with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE)[:1] if len(cache) > 0: cache = cache[0] if ds.cachedUserServices().select_for_update().filter( user=None, uuid=cache.uuid).update( user=user, cache_level=0) != 1: cache = None else: cache = None if cache: cache.assignToUser(user, save=True) # Out of atomic transaction if cache is not None: logger.debug( 'Found a cached-ready service from {0} for user {1}, item {2}'. format(ds, user, cache)) events.addEvent(ds, events.ET_CACHE_HIT, fld1=ds.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.USABLE).count()) return cache # Cache missed # Now find if there is a preparing one with transaction.atomic(): cache = ds.cachedUserServices().select_for_update().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING)[:1] if len(cache) > 0: cache = cache[0] if ds.cachedUserServices().select_for_update().filter( user=None, uuid=cache.uuid).update(user=user, cache_level=0) != 1: cache = None else: cache.assignToUser(user, save=True) else: cache = None # Out of atomic transaction if cache is not None: logger.debug( 'Found a cached-preparing service from {0} for user {1}, item {2}' .format(ds, user, cache)) events.addEvent(ds, events.ET_CACHE_MISS, fld1=ds.cachedUserServices().filter( cache_level=services.UserDeployment.L1_CACHE, state=State.PREPARING).count()) return cache # Can't assign directly from L2 cache... so we check if we can create e new service in the limits requested ty = ds.service.getType() if ty.usesCache is True: # inCacheL1 = ds.cachedUserServices().filter(UserServiceManager.getCacheStateFilter(services.UserDeployment.L1_CACHE)).count() inAssigned = ds.assignedUserServices().filter( UserServiceManager.getStateFilter()).count() # totalL1Assigned = inCacheL1 + inAssigned if inAssigned >= ds.max_srvs: # cacheUpdater will drop necesary L1 machines, so it's not neccesary to check against inCacheL1 log.doLog( ds, log.WARN, 'Max number of services reached: {}'.format(ds.max_srvs), log.INTERNAL) raise MaxServicesReachedError() # Can create new service, create it events.addEvent(ds, events.ET_CACHE_MISS, fld1=0) return self.createAssignedFor(ds, user)