def checkAvailableMachineResources(self, accountId, numcpus=0, memorysize=0, vdisksize=0): """ Check that the required machine resources are available in the given account :param accountId: id of the accountId to check :param numcpus: the required number of cpu cores that need to be free :param memorysize: the required memory size in GB that need to be free :param vdisksize: the required vdisk size in GB that need to be free :return: True if check succeeds, otherwise raise a 400 BadRequest error """ account = self.models.account.get(accountId) resourcelimits = account.resourceLimits # Validate that there still remains enough cpu cores to assign in account if numcpus > 0 and 'CU_C' in resourcelimits: reservedcus = account.resourceLimits['CU_C'] if reservedcus != -1: consumedcus = self.getConsumedCloudUnitsByType( accountId, 'CU_C') availablecus = reservedcus - consumedcus if availablecus < numcpus: raise exceptions.BadRequest( "Required actions will consume an extra %s core(s)," " owning account only has %s free core(s)." % (numcpus, availablecus)) # Validate that there still remains enough memory capacity to assign in account if memorysize > 0 and 'CU_M' in resourcelimits: reservedcus = account.resourceLimits['CU_M'] if reservedcus != -1: consumedcus = self.getConsumedCloudUnitsByType( accountId, 'CU_M') availablecus = reservedcus - consumedcus if availablecus < memorysize: raise exceptions.BadRequest( "Required actions will consume an extra %s GB of " "memory, owning account only has %s GB of free " "memory space." % (memorysize, availablecus)) # Validate that there still remains enough vdisk capacity to assign in account if vdisksize > 0 and 'CU_D' in resourcelimits: reservedcus = account.resourceLimits['CU_D'] if reservedcus != -1: consumedcus = self.getConsumedCloudUnitsByType( accountId, 'CU_D') availablecus = reservedcus - consumedcus if availablecus < vdisksize: raise exceptions.BadRequest( "Required actions will consume an extra %s GB of " "vdisk space, owning account only has %s GB of " "free vdisk space." % (vdisksize, availablecus)) return True
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 syncCreateImage( self, name, url, gid, imagetype, boottype, username=None, password=None, accountId=None, hotresize=True, **kwargs ): if accountId and not self.models.account.exists(accountId): raise exceptions.BadRequest("Specified accountId does not exist") if boottype not in ["bios", "uefi"]: raise exceptions.BadRequest( "Invalid boottype, should be either uefi or bios" ) bytesize = self._getImageSize(url) return self._createImage( name, url, gid, imagetype, boottype, bytesize, username, password, accountId, hotresize, kwargs, )
def restore(self, imageId, **kwargs): image = self.models.image.searchOne({"id": imageId}) if not image: raise exceptions.BadRequest('Image with id "%s" not found' % imageId) account = self.models.account.searchOne({"id": image["accountId"]}) if (account and account["status"] == resourcestatus.Account.DELETED and "imgrestore" not in kwargs): raise exceptions.BadRequest( "Cannot restore an image on a deleted account") if image["status"] != resourcestatus.Image.DELETED: raise exceptions.BadRequest("Can only restore a deleted image") self.models.image.updateSearch( {"id": image["id"]}, { "$set": { "status": resourcestatus.Image.CREATED, "deletionTime": 0 } }, ) self.models.stack.updateSearch({"gid": image["gid"]}, {"$addToSet": { "images": image["id"] }}) return True
def _create(self, accountId, gid, name, description, size=10, type='D', iops=2000, physicalSource=None, nid=None, order=None, **kwargs): if size > 2000 and type != 'P': raise exceptions.BadRequest("Disk size can not be bigger than 2000 GB") if type == 'P' and not (physicalSource and nid): raise exceptions.BadRequest("Need to specify both node id and physical source for disk of type 'P'") disk = self.models.disk.new() disk.name = name disk.descr = description disk.sizeMax = size disk.type = type disk.gid = gid disk.order = order disk.status = resourcestatus.Disk.MODELED disk.iotune = {'total_iops_sec': iops} disk.accountId = accountId disk.id = self.models.disk.set(disk)[0] try: provider = self.cb.getProviderByGID(gid) if type == 'P': volumeid = 'file://{source}?id={nid}'.format(source=physicalSource, nid=nid) disk.referenceId = volumeid volume = self.getStorageVolume(disk, provider) else: volume = provider.create_volume(disk.sizeMax, disk.id) volume.iotune = disk.iotune disk.referenceId = volume.id disk.status = resourcestatus.Disk.CREATED except: self.models.disk.delete(disk.id) raise self.models.disk.set(disk) return disk, volume
def createImage(self, name, url, gid, imagetype, boottype, username=None, password=None, accountId=None, hotresize=True, **kwargs): if accountId and not self.models.account.exists(accountId): raise exceptions.BadRequest("Specified accountId does not exist") if boottype not in ['bios', 'uefi']: raise exceptions.BadRequest( 'Invalid boottype, should be either uefi or bios') bytesize = self._getImageSize(url) ctx = kwargs['ctx'] ctx.events.runAsync( self._createImage, (name, url, gid, imagetype, boottype, bytesize, username, password, accountId, hotresize, kwargs), {}, 'Creating Image {}'.format(name), 'Finished Creating Image', 'Failed to create Image', ) return True
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 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 list(self, cloudspaceId=None, location=None, **kwargs): """ List the available flavors, filtering based on the cloudspace :param cloudspaceId: id of the cloudspace :return list of flavors contains id CU and disksize for every flavor on the cloudspace """ query = {} if not location and not cloudspaceId: raise exceptions.BadRequest("Either cloudspaceId or location should be given") if location: locations = self.models.location.search({'locationCode': location})[1:] if not locations: raise exceptions.BadRequest("Could not find location with code {}".format(location)) gid = locations[0]['gid'] else: cloudspace = self.models.cloudspace.get(cloudspaceId) if cloudspace.allowedVMSizes: query['id'] = {'$in': cloudspace.allowedVMSizes} gid = cloudspace.gid query['gids'] = gid fields = ['id', 'name', 'vcpus', 'memory', 'description', 'CU', 'disks'] results = self.models.size.search({'$fields': fields, '$query': query})[1:] return results
def editDHCPServerId(self, externalnetworkId, dhcpServerId, **kwargs): if self.models.externalnetwork.count({"id": externalnetworkId}) != 1: raise exceptions.BadRequest( "External network ID %s does not exist" % (externalnetworkId)) # If dhcpServerId param from API is less then 0, we should stop if dhcpServerId < 0: raise exceptions.BadRequest( "DHCP server ID is not valid! Use only 0 or positive number") # Get externalnetwork object pool = self.models.externalnetwork.get(externalnetworkId) # If dhcpServerId more then 0, check that DHCP server with this ID is exist # If dhcpServerId equals 0, then just set new value to OSIS if dhcpServerId > 0: # TODO: check that DHCP has corresponding IP pool if not self.models.cloudspace.count({ "id": dhcpServerId, "status": "DEPLOYED" }): raise exceptions.BadRequest( "DHCP server ID %s is not available (can not find or it has a wrong status)" % (dhcpServerId)) pool.dhcpServerId = dhcpServerId #Re-read all leases for this DHCP again self.pcl.cloudbroker.iaas.setupDhcpServer( external_network_id=externalnetworkId) self.models.externalnetwork.set(pool)
def EMAIL(val): atpos = val.find('@') dotpos = val.find('.') if atpos == -1 or dotpos == -1: raise exceptions.BadRequest('Invalid Email Address given') elif dotpos < atpos: raise exceptions.BadRequest('Invalid Email Address given')
def NAME(val): for i in r"""<>"'""": if i in val: raise exceptions.BadRequest( 'The name you entered contains invalid characters') if len(val) < 2: raise exceptions.BadRequest( 'The name cannot be shorter than two characters') return True
def validate(self, auth, ctx): if ctx.params == "": msg = 'No parameters given to actormethod.' ctx.start_response('400 Bad Request', []) return False, msg if auth and ctx.env['beaker.session']['user'] == 'guest': msg = 'NO VALID AUTHORIZATION KEY GIVEN, use get param called key (check key probably auth error).' ctx.start_response('401 Unauthorized', []) return False, msg convertermap = {'int': (int, j.basetype.integer.fromString), 'float': (float, j.basetype.float.fromString), 'bool': (bool, j.basetype.boolean.fromString) } params = self.ws.routes[ctx.path]['params'] def loadList(key): if isinstance(ctx.params[key], (list, types.NoneType)): return try: ctx.params[key] = j.basetype.list.fromString(ctx.params[key]) except ValueError: raise exceptions.BadRequest('Value of param %s not correct needs to be of type %s' % (key, param['type'])) for key, param in params.iteritems(): if key not in ctx.params: if param['optional']: # means is optional ctx.params[key] = param['default'] else: raise exceptions.BadRequest('Param with name:%s is missing.' % key) elif param['type'] in convertermap: type_, converter = convertermap[param['type']] if isinstance(ctx.params[key], (type_, types.NoneType)): continue try: ctx.params[key] = converter(ctx.params[key]) except ValueError: raise exceptions.BadRequest('Value of param %s not correct needs to be of type %s' % (key, param['type'])) elif param['type'] == 'list': loadList(key) elif param['type'] in ['list(int)', 'list(bool)', 'list(float)']: loadList(key) m = re.search("list\((?P<type>\w+)\)", param['type']) if not m: continue type_, converter = convertermap[m.group('type')] for i in xrange(len(ctx.params[key])): try: if not isinstance(ctx.params[key][i], type_): ctx.params[key][i] = converter(ctx.params[key][i]) except ValueError: raise exceptions.BadRequest('Value of param %s not correct needs to be of type %s' % (key, param['type'])) return True, ""
def restore(self, imageId, **kwargs): image = self.models.image.searchOne({'id': imageId}) if not image: raise exceptions.BadRequest('Image with id "%s" not found' % imageId) account = self.models.account.searchOne({'id': image['accountId']}) if account and account['status'] == resourcestatus.Account.DELETED and 'imgrestore' not in kwargs: raise exceptions.BadRequest("Cannot restore an image on a deleted account") if image['status'] != resourcestatus.Image.DELETED: raise exceptions.BadRequest('Can only restore a deleted image') self.models.image.updateSearch({'id': image['id']}, {'$set': {'status': resourcestatus.Image.CREATED, 'deletionTime': 0}}) self.models.stack.updateSearch({'gid': image['gid']}, {'$addToSet': {'images': image['id']}}) return True
def fillResourceLimits(self, resource_limits, preserve_none=False): for limit_type in ['CU_M', 'CU_D', 'CU_C', 'CU_NP', 'CU_I']: if limit_type not in resource_limits or resource_limits[limit_type] is None: resource_limits[limit_type] = None if preserve_none else -1 elif resource_limits[limit_type] < -1 or resource_limits[limit_type] == 0: raise exceptions.BadRequest('A resource limit should be a positive number or -1 (unlimited).') if limit_type == 'CU_M': resource_limits[limit_type] = resource_limits[limit_type] and float(resource_limits[limit_type]) else: resource_limits[limit_type] = resource_limits[limit_type] and int(resource_limits[limit_type]) maxVDiskCapacity = resource_limits['CU_D'] if maxVDiskCapacity is not None and maxVDiskCapacity != -1 and maxVDiskCapacity < 10: raise exceptions.BadRequest("Minimum disk capacity for cloudspace is 10GB.")
def addExternalNetwork(self, name, subnet, gateway, startip, endip, gid, vlan, accountId, pingips, dhcpServerId, **kwargs): """ Adds a public network range to be used for cloudspaces param:subnet the subnet to add in CIDR notation (x.x.x.x/y) """ gateway = gateway.strip() try: net = netaddr.IPNetwork(subnet) if netaddr.IPAddress(startip) not in net: raise exceptions.BadRequest( "Start IP Addresses %s is not in subnet %s" % (startip, subnet)) if netaddr.IPAddress(endip) not in net: raise exceptions.BadRequest( "End IP Addresses %s is not in subnet %s" % (endip, subnet)) if not checkIPS(net, [gateway]): raise exceptions.BadRequest( "Gateway Address %s is not in subnet %s" % (gateway, subnet)) if self.models.externalnetwork.count({'vlan': vlan}) > 0: raise exceptions.Conflict( "VLAN {} is already in use by another external network") except netaddr.AddrFormatError as e: raise exceptions.BadRequest(e.message) if dhcpServerId < 0 and type(dhcpServerId) == int: raise exceptions.BadRequest( "DHCP server ID is not valid! Use only 0 or positive number") if not dhcpServerId: dhcpServerId = 0 if pingips is None: pingips = '8.8.8.8' pingips = self._checkPingIps(pingips) pool = self.models.externalnetwork.new() pool.gid = int(gid) pool.gateway = gateway pool.name = name pool.pingips = pingips pool.vlan = vlan or 0 pool.subnetmask = str(net.netmask) pool.network = str(net.network) pool.accountId = accountId or 0 pool.dhcpServerId = dhcpServerId pool.ips = [str(ip) for ip in netaddr.IPRange(startip, endip)] pool.id, _, _ = self.models.externalnetwork.set(pool) return pool.id
def fw_start(self, fwid, resettype='restore', targetNid=None, **kwargs): """ param:fwid firewall id param:gid grid id """ if resettype not in ['factory', 'restore']: raise exceptions.BadRequest( "Invalid value {} for resettype".format(resettype)) try: running = self.fw_check(fwid) except: running = False if running: return True fwobj = self._getVFWObject(fwid) cloudspace = self.cbmodel.cloudspace.get(int(fwobj.domain)) if cloudspace.externalnetworkip is None: raise exceptions.BadRequest( 'Can not reset VFW which has no external network IP please deploy instead.' ) if resettype == 'restore': restored = self.fw_restore(fwid, targetNid) if resettype == 'factory' or not restored: pool = self.cbmodel.externalnetwork.get( cloudspace.externalnetworkId) externalipaddress = netaddr.IPNetwork(cloudspace.externalnetworkip) publicgw = pool.gateway publiccidr = externalipaddress.prefixlen password = str(uuid.uuid4()) self.fw_create(fwobj.gid, fwobj.domain, password, fwobj.pubips[0], 'routeros', fwobj.id, publicgw, publiccidr, pool.vlan, targetNid, cloudspace.privatenetwork) fwobj = self._getVFWObject(fwid) # to get updated model args = {'fwobject': fwobj.obj2dict()} if fwobj.type == 'routeros': job = self.cb.executeJumpscript('jumpscale', 'vfs_start_routeros', gid=fwobj.gid, nid=fwobj.nid, args=args) else: job = self.cb.executeJumpscript('jumpscale', 'vfs_start', gid=fwobj.gid, nid=fwobj.nid, args=args) if job['state'] != 'OK': raise exceptions.ServiceUnavailable("Failed to start vfw") self.fw_reapply(fwid) return job['result']
def moveToDifferentComputeNode(self, machineId, reason, targetStackId=None, force=False, **kwargs): vmachine = self._validateMachineRequest(machineId) if self.models.disk.count({ 'id': { '$in': vmachine.disks }, 'type': 'P' }) > 0: raise exceptions.BadRequest( "Can't move a vm with physical disks attached") cloudspace = self.models.cloudspace.get(vmachine.cloudspaceId) source_stack = self.models.stack.get(vmachine.stackId) if not targetStackId: targetStackId = self.cb.getBestStack(cloudspace.gid, vmachine.imageId, memory=vmachine.memory)['id'] stack = self.models.stack.get(targetStackId) if not stack.status == "ENABLED": raise exceptions.BadRequest("Target Stack is not active") target_provider = self.cb.getProviderByStackId(targetStackId) if target_provider.gid != source_stack.gid: raise exceptions.BadRequest( 'Target stack %s is not on some grid as source' % target_provider.uri) if vmachine.status != resourcestatus.Machine.HALTED: # create network on target node node = self.cb.getNode(vmachine, target_provider) migrated = target_provider.ex_migrate( node, self.cb.getProviderByStackId(vmachine.stackId), force) if migrated == -1: vmachine.status = resourcestatus.Machine.HALTED elif migrated == 0: args = {'networkid': cloudspace.networkId} self.cb.agentcontroller.executeJumpscript( 'greenitglobe', 'cleanup_network', nid=int(source_stack.referenceId), gid=source_stack.gid, args=args) vmachine.stackId = targetStackId self.models.vmachine.set(vmachine)
def getMatchingUsernames(self, usernameregex, limit=5, **kwargs): """ Get a list of the matching usernames for a given string :param usernameregex: regex of the usernames to searched for :param limit: the number of usernames to return :return: list of dicts with the username and url of the gravatar of the user """ if limit > 20: raise exceptions.BadRequest( "Cannot return more than 20 usernames while matching users") matchingusers = self.systemodel.user.search( {"id": { "$regex": usernameregex }}, size=limit)[1:] if matchingusers: def userinfo(user): emailhash = j.tools.hash.md5_string( next(iter(user["emails"]), "")) return { "username": user["id"], "gravatarurl": "http://www.gravatar.com/avatar/%s" % emailhash, } return map(userinfo, matchingusers) else: return []
def edit(self, imageId, name=None, username=None, password=None, accountId=None, hotResize=None, **kwargs): if accountId and not self.models.account.exists(accountId): raise exceptions.BadRequest("Specified accountId does not exists") self._checkimage(imageId) update = {} if name: update['name'] = name if username: update['username'] = username if password: update['password'] = password if accountId is not None: update['accountId'] = accountId if hotResize == 'False': update['hotResize'] = False elif hotResize == 'True': update['hotResize'] = True if update: self.models.image.updateSearch({'id': imageId}, {'$set': update})
def setData(self, data, **kwargs): """ Set user data param:username username of the user result: """ ctx = kwargs["ctx"] username = ctx.env["beaker.session"]["user"] if username == "guest": ctx.start_response("403 Forbidden", []) return "Forbidden" if not isinstance(data, dict): try: data = json.loads(data) except: raise exceptions.BadRequest("data needs to be in json format") user = j.core.portal.active.auth.getUserInfo(username) if user: try: userdata = json.loads(user.data) except: userdata = {} userdata.update(data) user.data = json.dumps(userdata) self.systemodel.user.set(user) return True else: ctx.start_response("404 Not Found", []) return "User not found"
def delete(self, username, **kwargs): u = self.modelUser.get(username) if getattr(u, 'protected', False): raise exceptions.BadRequest('Cannot delete protected user.') self.modelUser.delete(username) self.modelSession.deleteSearch({'user': username}) return True
def main(j, args, params, tags, tasklet): params.result = page = args.page groupguid = args.getTag('guid') if groupguid is None: raise exceptions.BadRequest("BadRequest", "text/plain") scl = j.clients.osis.getNamespace('system') group = None guidExists = scl.group.search({'id': groupguid})[1:] if guidExists: group = scl.group.get(groupguid) if not group: return params popup = Popup(id='group_edit', header='Change Group', clearForm=False, submit_url='/restmachine/system/usermanager/editGroup') options = list() popup.addText('Enter domain', 'domain', value=group.domain) popup.addText('Enter description', 'description', value=group.description) for user in scl.user.search({})[1:]: available = user['id'] in group.users options.append((user['id'], user['id'], available)) popup.addCheckboxes('Select Users', 'users', options) popup.addHiddenField('name', group.id) popup.write_html(page) return params
def delete(self, accountId, reason, permanently=False, name=None, **kwargs): """ Complete delete an account from the system """ try: account = self._checkAccount(accountId) except (exceptions.BadRequest, exceptions.NotFound): return if name and account["name"] != name: raise exceptions.BadRequest("Incorrect account name specified") startstate = account["status"] def restorestate(eco): account = self.models.account.get(accountId) account.status = startstate self.models.account.set(account) ctx = kwargs["ctx"] ctx.events.runAsync( self._delete, (accountId, reason, permanently, kwargs["ctx"]), {}, "Deleting Account %(name)s" % account, "Finished deleting Account", "Failed to delete Account", errorcb=restorestate, )
def main(j, args, params, tags, tasklet): params.result = page = args.page userguid = args.getTag('guid') if not userguid: raise exceptions.BadRequest("BadRequest", "text/plain") scl = j.clients.osis.getNamespace('system') user = scl.user.get(userguid) popup = Popup(id='user_edit', header='Update User', submit_url='/restmachine/system/usermanager/editUser', clearForm=False) options = list() popup.addText( 'Enter Email Address', 'emails', value=', '.join(user.emails), placeholder='If left empty, email address will not be changed') popup.addHiddenField('domain', user.domain) popup.addText('Enter Password', 'password', type='password', placeholder='If left empty, password will not be changed') for group in scl.group.search({})[1:]: available = group['id'] in user.groups options.append((group['id'], group['id'], available)) popup.addCheckboxes('Select Groups', 'groups', options) popup.addHiddenField('username', user.id) popup.write_html(page) return params
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 destroy(self, cloudspaceId, reason, permanently=False, name=None, **kwargs): """ Destroys a cloudspace and its machines, vfws and routeros """ try: cloudspace = self._getCloudSpace(cloudspaceId) except (exceptions.BadRequest, exceptions.NotFound): return if name and cloudspace["name"] != name: raise exceptions.BadRequest("Incorrect cloudspace name specified") ctx = kwargs["ctx"] ctx.events.runAsync( self._destroy, args=(cloudspace, reason, permanently, ctx), kwargs={}, title="Deleting Cloud Space", success="Finished deleting Cloud Space", error="Failed to delete Cloud Space", )
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 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 setStatus(self, id, gid, status, **kwargs): """ Set different stack statusses, options are 'ENABLED(creation and actions on machines is possible)','DISABLED(Only existing machines are started)', 'OFFLINE(Machine is not available' param:statckid id of the stack to update param:status status e.g ENABLED, DISABLED, or OFFLINE result """ statusses = ["ENABLED", "DECOMMISSIONED", "MAINTENANCE"] stack = self._getStack(id, gid) if status not in statusses: return exceptions.BadRequest("Invalid status %s should be in %s" % (status, ", ".join(statusses))) if status == "ENABLED": if stack["status"] not in ("MAINTENANCE", "ENABLED", "ERROR"): raise exceptions.PreconditionFailed( "Can not enable ComputeNode in state %s" % (stack["status"])) if status == "DECOMMISSIONED": return self.decommission(id, gid, "") elif status == "MAINTENANCE": return self.maintenance(id, gid, vmaction="move") else: return self._changeStackStatus(stack, status)