def checkCloudspaceStatus(self, requiredaccessrights, cloudspace): """ Check if the required action can be executed on a cloudspace. If cloudspace is 'DESTROYED' then a 404 NotFound will be returned, else if an action requires a permission other than READ, the call will fail with 403 Forbidden if cloudspace is not in any of the statuses 'VIRTUAL', 'DEPLOYING' or'DEPLOYED' :param requiredaccessrights: the required access rights to access an cloudspace or one of its machines :param cloudspace: the cloudspace object its status should be checked :raise Exception with 404 if destroyed or 403 Forbidden if non-read action cannot be performed on cloudspace or one of its machines """ if cloudspace.status == resourcestatus.Cloudspace.DESTROYED: raise exceptions.NotFound('Could not find an accessible resource.') elif cloudspace.status == resourcestatus.Cloudspace.DELETED and requiredaccessrights != set( 'D'): raise exceptions.NotFound('Could not find an accessible resource.') elif requiredaccessrights != set('R') and cloudspace.status not in [ resourcestatus.Cloudspace.VIRTUAL, resourcestatus.Cloudspace.DEPLOYING, resourcestatus.Cloudspace.DEPLOYED ]: raise exceptions.Forbidden( 'Only READ actions can be executed on cloudspace ' '(or one of its machines) with status %s.' % cloudspace.status)
def updateUser(self, accountId, userId, accesstype, explicit=True, **kwargs): """ Update user access rights :param accountId: id of the account :param userId: userid/email for registered users or emailaddress for unregistered users :param accesstype: 'R' for read only access, 'RCX' for Write and 'ARCXDU' for Admin :return True if user access was updated successfully """ accountId = int(accountId) if not self.models.account.exists(accountId): raise exceptions.NotFound("Account does not exist") self.cb.isValidRole(accesstype) account = self.models.account.get(accountId) for ace in account.acl: if ace.userGroupId == userId: if not self.cb.isaccountuserdeletable(ace, account.acl): raise exceptions.BadRequest( "User is last admin on the account, cannot change " "user's access rights" ) break else: raise exceptions.NotFound("User does not have any access rights to update") self.models.account.updateSearch( {"id": accountId, "acl.userGroupId": userId}, {"$set": {"acl.$.right": accesstype, "acl.$.explicit": explicit}}, ) return True
def main(j, args, params, tags, tasklet): from jose import jwt as jose_jwt from JumpScale.portal.portal import exceptions import json params.result = (args.doc, args.doc) node_id = args.requestContext.params.get("node") remote = None data = {} if node_id: node_name, remote = j.apps.cloudbroker.zeroaccess._get_node_info(node_id) data["name"] = node_name oauth = j.clients.oauth.get(instance="itsyouonline") try: jwt = oauth.get_active_jwt(session=args.requestContext.env["beaker.session"]) except: raise exceptions.NotFound("Page not found") if jwt: jwt_data = jose_jwt.get_unverified_claims(jwt) jwt_data = json.loads(jwt_data) scope = "user:memberof:{}.0-access".format(oauth.id) if scope not in jwt_data["scope"]: raise exceptions.NotFound("Page not found") table_data = j.apps.cloudbroker.zeroaccess.listSessions( remote=remote, ctx=args.requestContext ) else: table_data = [["No jwt found please logout and login again", "", "", "", ""]] if not table_data: table_data = [["No sessions found", "", "", "", ""]] data["tables"] = table_data args.doc.applyTemplate(data, False) return params
def _validate_forward( self, cloudspaceId, publicIp, publicPort, machineId, localPort, protocol=None, **kwargs ): machineId = int(machineId) cloudspaceId = int(cloudspaceId) cloudspace = self.models.cloudspace.get(cloudspaceId) fw = self.netmgr.fw_list(cloudspace.gid, cloudspaceId) if publicPort > 65535 or publicPort < 1: raise exceptions.BadRequest("Public port should be between 1 and 65535") if localPort > 65535 or localPort < 1: raise exceptions.BadRequest("Local port should be between 1 and 65535") if protocol and protocol not in ("tcp", "udp"): raise exceptions.BadRequest("Protocol should be either tcp or udp") if cloudspace.status != "DEPLOYED": raise exceptions.BadRequest( "Cannot create a portforwarding during cloudspace deployment." ) if len(fw) == 0: raise exceptions.NotFound( "Incorrect cloudspace or there is no corresponding gateway" ) try: publicIp = str(netaddr.IPNetwork(publicIp).ip) except netaddr.AddrFormatError: raise exceptions.BadRequest("Invalid public IP %s" % publicIp) if cloudspace.externalnetworkip.split("/")[0] != publicIp: raise exceptions.BadRequest("Invalid public IP %s" % publicIp) machine = j.apps.cloudapi.machines.get(machineId) if machine["cloudspaceid"] != cloudspaceId: raise exceptions.BadRequest( "Machine {} does not belong to cloudspace {}".format( machine["name"], cloudspace.name ) ) localIp = self._getLocalIp(machine) if localIp is None: raise exceptions.NotFound( "Cannot create portforwarding when Virtual Machine did not acquire an IP Address." ) return cloudspace, machine, fw[0], publicIp
def update(self, cloudspaceId, id, publicIp, publicPort, machineId, localPort, protocol, **kwargs): """ Update a port forwarding rule :param cloudspaceId: id of the cloudspace :param id: id of the portforward to edit :param publicIp: public ipaddress :param publicPort: public port :param machineId: id of the virtual machine :param localPort: local port :param protocol: protocol udp or tcp """ machineId = int(machineId) cloudspaceId = int(cloudspaceId) cloudspace = self.models.cloudspace.get(cloudspaceId) fw = self.netmgr.fw_list(cloudspace.gid, cloudspaceId) if len(fw) == 0: raise exceptions.NotFound( 'Incorrect cloudspace or there is no corresponding gateway') fw_id = fw[0]['guid'] if not self.netmgr.fw_check(fw_id, timeout=5): raise exceptions.ServiceUnavailable( 'Can not update PortForward at this time') forwards = self.netmgr.fw_forward_list(fw_id, cloudspace.gid) id = int(id) if not id < len(forwards): raise exceptions.NotFound('Cannot find the rule with id %s' % str(id)) forward = forwards[id] machine = self.models.vmachine.get(machineId) if machine.nics: if machine.nics[0].ipAddress != 'Undefined': localIp = machine.nics[0].ipAddress else: raise exceptions.NotFound( 'No correct ipaddress found for machine with id %s' % machineId) self.netmgr.fw_forward_delete(fw_id, cloudspace.gid, forward['publicIp'], forward['publicPort'], forward['localIp'], forward['localPort'], forward['protocol']) forwards = self.netmgr.fw_forward_list(fw_id, cloudspace.gid) if self._selfcheckduplicate(forwards, publicIp, publicPort, protocol): raise exceptions.Conflict( "Forward for %s with port %s already exists" % (publicIp, publicPort)) self.netmgr.fw_forward_create(fw_id, cloudspace.gid, publicIp, publicPort, localIp, localPort, protocol) forwards = self.netmgr.fw_forward_list(fw_id, cloudspace.gid) return self._process_list(forwards, cloudspaceId)
def main(j, args, params, tags, tasklet): from jose import jwt as jose_jwt from JumpScale.portal.portal import exceptions import json page = args.page modifier = j.html.getPageModifierGridDataTables(page) ocl = j.clients.osis.getNamespace("system") oauth = j.clients.oauth.get(instance="itsyouonline") try: jwt = oauth.get_active_jwt( session=args.requestContext.env["beaker.session"]) except: raise exceptions.NotFound("Page not found") if jwt: jwt_data = jose_jwt.get_unverified_claims(jwt) jwt_data = json.loads(jwt_data) scope = "user:memberof:{}.0-access".format(oauth.id) if scope not in jwt_data["scope"]: raise exceptions.NotFound("Page not found") nodes = [] for node_id in ocl.node.list(): node = ocl.node.get(node_id) ip = "" if "master" in node.roles: continue else: _, ip = j.apps.cloudbroker.zeroaccess._get_node_info(node_id) if not ip: continue name = '<a href="/cbgrid/0-access Node?node={id}">{name}</a>'.format( name=node.name, id=node_id) nodes.append([node.id, name, ip]) mgmt_name, mgmt_ip = j.apps.cloudbroker.zeroaccess._get_node_info("0") name = '<a href="/cbgrid/0-access Node?node={id}">{name}</a>'.format( name=mgmt_name, id="0") nodes.append(["0", name, mgmt_ip]) fieldnames = ["ID", "Name", "IP"] if nodes: page.addList(nodes, fieldnames) else: page.addList([["Can not list nodes", "", ""]], fieldnames) params.result = page return params
def _checkMachine(self, machineId): vmachines = self.models.vmachine.search({'id': machineId})[1:] if not vmachines: raise exceptions.NotFound("Machine with id %s does not exists" % machineId) return vmachines[0]
def checkAccountStatus(self, requiredaccessrights, account): """ Check if the required action can be executed on an account. If account is 'DISABLED', 'DESTROYED', 'ERROR' and action requires a permission other than READ, the call should fail with 403 Forbidden Check if the required action can be executed on an account. If account is 'DESTROYED' then a 404 NotFound will be returned, else if an action requires a permission other than READ, the call will fail with 403 Forbidden if account is not 'CONFIRMED' :param requiredaccessrights: the required access rights to access an account or one of its cloudspaces or machines :param account: the account object its status should be checked :raise Exception with 403 Forbidden if action cannot be performed on account or one of its cloduspaces or machines :raise Exception with 404 if destroyed or 403 Forbidden if non-read action cannot be performed on account or one of its cloudspace or machines """ if account.status == 'DESTROYED': raise exceptions.NotFound('Could not find an accessible resource.') elif requiredaccessrights != set( 'R') and account.status != 'CONFIRMED': raise exceptions.Forbidden( 'Only READ actions can be executed on account ' '(or one of its cloudspace or machines) with status %s.' % account.status)
def list(self, cloudspaceId, machineId=None, **kwargs): """ List all port forwarding rules in a cloudspace or machine :param cloudspaceId: id of the cloudspace :param machineId: id of the machine, all rules of cloudspace will be listed if set to None """ machine = None if machineId: machineId = int(machineId) machine = self.models.vmachine.get(machineId) def getIP(): if machine: for nic in machine.nics: if nic.ipAddress != "Undefined": return nic.ipAddress return None localip = getIP() if machine and not localip: return [] cloudspaceId = int(cloudspaceId) cloudspace = self.models.cloudspace.get(cloudspaceId) fw = self.netmgr.fw_list(cloudspace.gid, cloudspaceId) if len(fw) == 0: raise exceptions.NotFound( "Incorrect cloudspace or there is no corresponding gateway" ) fw_id = fw[0]["guid"] fw_gid = fw[0]["gid"] forwards = self.netmgr.fw_forward_list(fw_id, fw_gid, localip) return self._process_list(forwards, cloudspaceId)
def addUser(self, machineId, username, accesstype, **kwargs): """ Give a user access rights. Access rights can be 'R' or 'W' param:machineId id of the machine param:username id of the user to give access or emailaddress to invite an external user param:accesstype 'R' for read only access, 'W' for Write access result bool """ machineId = self._checkMachine(machineId) machineId = machineId['id'] user = self.cb.checkUser(username, activeonly=False) vmachineacl = authenticator.auth().getVMachineAcl(machineId) if username in vmachineacl: updated = j.apps.cloudapi.machines.updateUser( machineId=machineId, userId=username, accesstype=accesstype) if not updated: raise exceptions.PreconditionFailed( 'User already has same access level to owning ' 'account or cloudspace') if user: j.apps.cloudapi.machines.addUser(machineId=machineId, userId=username, accesstype=accesstype) else: raise exceptions.NotFound('User with username %s is not found' % username) return True
def getVFW(self, cloudspaceId, **kwargs): """ Get VFW info param:cloudspaceId id of the cloudspace """ cloudspaceId = int(cloudspaceId) if not self.models.cloudspace.exists(cloudspaceId): raise exceptions.NotFound("Cloudspace with id %s not found" % (cloudspaceId)) cloudspace = self.models.cloudspace.get(cloudspaceId) fwid = "%s_%s" % (cloudspace.gid, cloudspace.networkId) if not self.vfwcl.virtualfirewall.exists(fwid): raise exceptions.BadRequest("Can't get VFW of %s cloudspace" % (cloudspace.status)) network = self.vfwcl.virtualfirewall.get(fwid) network_obj = network.dump() if self.syscl.node.exists(network.nid): network_obj["nodename"] = self.syscl.node.get(network.nid).name else: network_obj["nodename"] = str(network.nid) try: if self.cb.netmgr.fw_check(network.guid, timeout=5): network_obj["status"] = "RUNNING" else: network_obj["status"] = "HALTED" except: network_obj["status"] = "UNKNOWN" return network_obj
def _addACE( self, accountId, userId, accesstype, userstatus="CONFIRMED", explicit=True ): """ Add a new ACE to the ACL of the account :param accountId: id of the account :param userId: userid/email for registered users or emailaddress for unregistered users :param accesstype: 'R' for read only access, 'RCX' for Write and 'ARCXDU' for Admin :param userstatus: status of the user (CONFIRMED or INVITED) :return True if ACE was added successfully """ accountId = int(accountId) if not self.models.account.exists(accountId): raise exceptions.NotFound("Account does not exist") self.cb.isValidRole(accesstype) account = self.models.account.get(accountId) for ace in account.acl: if ace.userGroupId == userId: raise exceptions.BadRequest( "User already has access rights to this account" ) acl = account.new_acl() acl.userGroupId = userId acl.type = "U" acl.right = accesstype acl.status = userstatus acl.explicit = explicit self.models.account.updateSearch( {"id": accountId}, {"$push": {"acl": acl.obj2dict()}} ) return True
def _checkCloudspace(self, cloudspaceId): cloudspaces = self.models.cloudspace.search({"id": cloudspaceId})[1:] if not cloudspaces: raise exceptions.NotFound( "Cloud space with id %s does not exists" % cloudspaceId) return cloudspaces[0]
def updateUser(self, username, password, emailaddress, groups, domain=None): users = self.osisuser.search({'id': username})[1:] if not users: raise exceptions.NotFound('Could not find user with the username: %s.' % username) else: user = self.osisuser.get(users[0]['guid']) if password: if not self._isValidPassword(password): raise exceptions.BadRequest("Password should have at least 8 characters and not " "more than 60 characters.") else: user.passwd = j.tools.hash.md5_string(password) if emailaddress and emailaddress != ['']: if not self._isValidEmailAddress(emailaddress[0]): raise exceptions.BadRequest('Email address %s is in an invalid format.' % emailaddress[0]) if emailaddress != user.emails and self.osisuser.search({'emails': emailaddress})[1:]: raise exceptions.Conflict('Email address %s is already registered in the ' 'system with a different username.' % emailaddress[0]) user.emails = emailaddress user.groups = groups if domain: user.domain = domain self.osisuser.set(user) return True
def limitInternetBandwith(self, cloudspaceId, rate, burst, **kwargs): """ This will put a limit on the outgoing traffic on the public VIF of the VFW on the physical machine param:cloudspaceId Id of the cloudspace to limit param:reate maximum speeds in kilobytes per second, 0 means unlimited param:burst maximum speed in kilobytes per second, 0 means unlimited result bool """ cloudspace = self.ccl.cloudspace.get(cloudspaceId) vfwid = "%s_%s" % (cloudspace.gid, cloudspace.networkId) if not self.vcl.virtualfirewall.exists(vfwid): raise exceptions.NotFound("VFW for cloudspace %s does not exists" % cloudspaceId) vfw = self.vcl.virtualfirewall.get(vfwid) self.cb.executeJumpscript( "cloudscalers", "limitpublicnet", gid=vfw.gid, nid=vfw.nid, args={ "networkId": cloudspace.networkId, "rate": rate, "burst": burst }, )
def resetVFW(self, cloudspaceId, resettype, targetNid=None, **kwargs): """ Restore the virtual firewall of a cloudspace on an available firewall node param:cloudspaceId id of the cloudspace """ cloudspaceId = int(cloudspaceId) if not self.models.cloudspace.exists(cloudspaceId): raise exceptions.NotFound("Cloudspace with id %s not found" % (cloudspaceId)) if resettype not in ["factory", "restore"]: raise exceptions.BadRequest( "Invalid value {} for resettype".format(resettype)) cloudspace = self.models.cloudspace.get(cloudspaceId) if cloudspace.status != resourcestatus.Cloudspace.DEPLOYED: raise exceptions.BadRequest( "Can not reset VFW which is not deployed please deploy instead." ) self._destroyVFW(cloudspace.gid, cloudspaceId, deletemodel=False) fwid = "{}_{}".format(cloudspace.gid, cloudspace.networkId) # redeploy vfw self.cb.netmgr.fw_start(fwid, resettype, targetNid)
def addUser(self, accountId, userId, accesstype, explicit=True, **kwargs): """ Give a registered user access rights :param accountId: id of the account :param userId: username or emailaddress of the user to grant access :param accesstype: 'R' for read only access, 'RCX' for Write and 'ARCXDU' for Admin :return True if user was added successfully """ user = self.cb.checkUser(userId, activeonly=False) if not user: raise exceptions.NotFound("User is not registered on the system") else: # Replace email address with ID userId = user["id"] self._addACE( accountId, userId, accesstype, userstatus="CONFIRMED", explicit=explicit ) try: j.apps.cloudapi.users.sendShareResourceEmail( user, "account", accountId, accesstype ) return True except: self.deleteUser(accountId, userId, recursivedelete=False) raise
def addExternalIPS(self, externalnetworkId, startip, endip, **kwargs): """ Add public ips to an existing range """ if not self.models.externalnetwork.exists(externalnetworkId): raise exceptions.NotFound( "Could not find external network with id %s" % externalnetworkId) pool = self.models.externalnetwork.get(externalnetworkId) try: net = netaddr.IPNetwork("{}/{}".format(pool.network, pool.subnetmask)) if netaddr.IPAddress(startip) not in net: raise exceptions.BadRequest( "Start IP Addresses %s is not in subnet %s" % (startip, net)) if netaddr.IPAddress(endip) not in net: raise exceptions.BadRequest( "End IP Addresses %s is not in subnet %s" % (endip, net)) except netaddr.AddrFormatError as e: raise exceptions.BadRequest(e.message) ips = set(pool.ips) newset = {str(ip) for ip in netaddr.IPRange(startip, endip)} usedips = self._getUsedIPS(pool) duplicateips = usedips.intersection(newset) if duplicateips: raise exceptions.Conflict( "New range overlaps with existing deployed IP Addresses") ips.update(newset) pool.ips = list(ips) self.models.externalnetwork.set(pool) return True
def processor_restext(self, env, start_response, path, ctx=False): """ rest processer gen 2 (not used by the original get code) """ if ctx == False: raise RuntimeError("ctx cannot be empty") if not self.ws.isAdminFromCTX(ctx): raise exceptions.NotFound('Not Found') try: j.logger.log("Routing request to %s" % path, 9) def respond(contentType, msg): if contentType: start_response('200 OK', [('Content-Type', contentType)]) return msg success, message, params = self.restextPathProcessor(path) if not success: params["error"] = message return self.ws.raiseError(ctx, message) requestmethod = ctx.env['REQUEST_METHOD'] paths = params['paths'] appname = paths[0] model = paths[1] objectid = None if len(paths) > 2: objectid = int(paths[2]) ctx.params['id'] = objectid osiscl = j.clients.osis.getCategory(self.ws.osis, appname, model) osismap = { 'GET': ['get', 'list', 'search'], 'POST': [''], 'DELETE': ['delete'] } if requestmethod == 'GET': result = self._handle_get(ctx, osiscl, objectid) elif requestmethod in ('POST', 'PUT'): result = self._handle_post(ctx, osiscl, objectid) elif requestmethod == 'DELETE': result = self._handle_delete(ctx, osiscl, objectid) else: start_response('405 Method not allowed', [('Content-Type', 'text/html')]) return 'Requested method is not allowed' ctx.fformat = 'jsonraw' contentType, result = self.ws.reformatOutput(ctx, result) return respond(contentType, result) except Exception as errorObject: eco = j.errorconditionhandler.parsePythonErrorObject(errorObject) if ctx == False: print("NO webserver context yet, serious error") eco.process() print(eco) else: return self.ws.raiseError(ctx, errorObject=eco)
def _getNode(self, id): id = int(id) if isinstance(id, str) else id if not isinstance(id, int): raise exceptions.BadRequest("Node id should be either string or integer") node = self.scl.node.searchOne({"id": id}) if not node: raise exceptions.NotFound("Node with id %s not found" % id) return node
def restore(self, diskId, reason, **kwargs): disk = self.models.disk.searchOne({'id': diskId}) if not disk or disk['status'] == resourcestatus.Disk.DESTROYED: raise exceptions.NotFound("Couldn't find disk with id: %s" % diskId) if disk['status'] != resourcestatus.Disk.TOBEDELETED: raise exceptions.BadRequest('Cannot restore an attached or non deleted disk') self.models.disk.updateSearch({'id': diskId}, {'$set': {'status': resourcestatus.Disk.CREATED, 'deletionTime': 0}}) return True
def _getFirewallId(self, cloudspaceId): cloudspace = self.models.cloudspace.get(cloudspaceId) fw = self.netmgr.fw_list(cloudspace.gid, cloudspaceId) if len(fw) == 0: raise exceptions.NotFound( 'Incorrect cloudspace or there is no corresponding gateway') return fw[0]['guid'], fw[0]['gid']
def _getStackFromNode(self, nid, gid): nid = nid if isinstance(nid, str) else str(nid) stack = self.models.stack.searchOne({ "referenceId": nid, "gid": int(gid) }) if not stack: raise exceptions.NotFound("ComputeNode with id %s not found" % id) return stack
def get(self, taskguid, **kwargs): task = self.redis.get('tasks.{}'.format(taskguid)) greenlet = self.rest.tasks.get(taskguid) if task is None and greenlet is None: raise exceptions.NotFound("Task is not found") elif task is None and greenlet is not None: raise exceptions.BaseError(202, [], '') elif task is not None: return json.loads(task)
def _checkAccount(self, accountId): account = self.models.account.searchOne({"id": accountId}) if not account: raise exceptions.NotFound("Account not found") if account["status"] == resourcestatus.Account.DESTROYED: raise exceptions.BadRequest("Specified account is destroyed") return account
def _checkAccount(self, accountId): account = self.models.account.searchOne({'id': accountId}) if not account: raise exceptions.NotFound('Account not found') if account['status'] == resourcestatus.Account.DESTROYED: raise exceptions.BadRequest('Specified account is destroyed') return account
def rename(self, name, gid, **kwargs): location = next(iter(self.models.location.search({"gid": gid})[1:]), None) if not location: raise exceptions.NotFound("Could not find location with gid %s" % gid) location["name"] = name self.models.location.set(location) return True
def get(self, diskId, **kwargs): """ Get disk details :param diskId: id of the disk :return: dict with the disk details """ if not self.models.disk.exists(diskId): raise exceptions.NotFound("Can not find disk with id %s" % diskId) return self.models.disk.get(diskId).dump()
def delete(self, username, **kwargs): """ Delete the user from all ACLs and set user status to inactive :param username: username of the user to delete :return: True if deletion was successful """ user = self.cb.checkUser(username) if not user: raise exceptions.NotFound("User with name %s does not exists" % username) else: userobj = self.syscl.user.get(user['id']) query = {'acl.userGroupId': username, 'acl.type': 'U'} # Delete user from all accounts, if account status is Destoryed then delete without # further validation accountswiththisuser = self.models.account.search(query)[1:] for account in accountswiththisuser: if account['status'] in ['DESTROYED', 'DESTROYING']: # Delete immediately without further checks accountobj = self.models.account.get(account['guid']) accountobj.acl = filter(lambda a: a.userGroupId != username, accountobj.acl) self.models.account.set(accountobj) else: try: j.apps.cloudbroker.account.deleteUser(accountId=account['id'], username=username, recursivedelete=True) except HTTPError as ex: if ex.status_code == 400 and ex.msg.count('is the last admin on the account'): raise exceptions.BadRequest(ex.msg) else: raise # Delete user from cloudspaces cloudspaceswiththisuser = self.models.cloudspace.search(query)[1:] for cloudspace in cloudspaceswiththisuser: j.apps.cloudbroker.cloudspace.deleteUser(cloudspaceId=cloudspace['id'], username=username, recursivedelete=True) # Delete user from vmachines machineswiththisuser = self.models.vmachine.search(query)[1:] for machine in machineswiththisuser: j.apps.cloudbroker.machine.deleteUser(machineId=machine['id'], username=username) # Set the user to inactive userobj.active = False gid = userobj.gid uid = userobj.id userobj.id = 'DELETED_%i_%s' % (time.time(), uid) userobj.guid = '%s_DELETED_%i_%s' % (gid, time.time(), uid) userobj.protected = False self.syscl.user.delete(uid) self.syscl.user.set(userobj) self.syscl.sessioncache.deleteSearch({'user': uid}) return True
def refreshCommand(self, nid, cmd, **kwargs): if not self.scl.node.exists(nid): raise exceptions.NotFound("Could find not with id %s" % nid) node = self.scl.node.get(nid) org, name = cmd.split('_', 1) self.acl.executeJumpscript(org, name, nid=nid, gid=node.gid, wait=False) return "Scheduled reload of command"