Best Python code snippet using pyatom_python
ReqMgrRESTModel.py
Source:ReqMgrRESTModel.py  
1#!/usr/bin/env python2"""3ReqMgrRESTModel4This holds the methods for the REST model, all methods which5will be available via HTTP PUT/GET/POST commands from the interface,6the validation, the security for each, and the function calls for the7DB interfaces they execute.8https://twiki.cern.ch/twiki/bin/viewauth/CMS/ReqMgrSystemDesign9"""10import sys11import math12import cherrypy13import json14import threading15import urllib16import logging17import WMCore.Lexicon18from WMCore.Wrappers import JsonWrapper19from WMCore.WebTools.RESTModel import RESTModel20import WMCore.HTTPFrontEnd.RequestManager.ReqMgrWebTools as Utilities21from WMCore.WMException import WMException22import WMCore.RequestManager.RequestDB.Interface.User.Registration          as Registration23import WMCore.RequestManager.RequestDB.Interface.User.Requests              as UserRequests24import WMCore.RequestManager.RequestDB.Interface.Request.ListRequests       as ListRequests25import WMCore.RequestManager.RequestDB.Interface.Request.GetRequest         as GetRequest26import WMCore.RequestManager.RequestDB.Interface.Admin.RequestManagement    as RequestAdmin27import WMCore.RequestManager.RequestDB.Interface.Admin.ProdManagement       as ProdManagement28import WMCore.RequestManager.RequestDB.Interface.Admin.GroupManagement      as GroupManagement29import WMCore.RequestManager.RequestDB.Interface.Admin.UserManagement       as UserManagement30import WMCore.RequestManager.RequestDB.Interface.ProdSystem.ProdMgrRetrieve as ProdMgrRetrieve31import WMCore.RequestManager.RequestDB.Interface.Admin.SoftwareManagement   as SoftwareAdmin32import WMCore.RequestManager.RequestDB.Interface.Request.ChangeState        as ChangeState33import WMCore.RequestManager.RequestDB.Interface.Group.Information          as GroupInfo34import WMCore.RequestManager.RequestDB.Interface.Request.Campaign           as Campaign35class ReqMgrRESTModel(RESTModel):36    """ The REST interface to the ReqMgr database.  Documentation may37    be found at https://twiki.cern.ch/twiki/bin/viewauth/CMS/ReqMgrSystemDesign """38    def __init__(self, config):39        RESTModel.__init__(self, config)40        self.couchUrl = config.couchUrl41        self.workloadDBName = config.workloadDBName42        self.configDBName = config.configDBName43        self.security_params = {'roles':config.security_roles}44        # Optional values for individual methods45        self.reqPriorityMax = getattr(config, 'maxReqPriority', 100)46        self._addMethod('GET', 'request', self.getRequest, 47                       args = ['requestName'],48                       secured=True, validation=[self.isalnum], expires = 0)49        self._addMethod('GET', 'assignment', self.getAssignment,50                       args = ['teamName', 'request'],51                       secured=True, validation = [self.isalnum], expires = 0)52        self._addMethod('GET', 'user', self.getUser,53                       args = ['userName'], 54                       secured=True, validation = [self.isalnum], expires = 0)55        self._addMethod('GET', 'group', self.getGroup,56                       args = ['group', 'user'], secured=True, expires = 0)57        self._addMethod('GET', 'version', self.getVersion, args = [], 58                        secured=True, expires = 0)59        self._addMethod('GET', 'team', self.getTeam, args = [], 60                        secured=True, expires = 0)61        self._addMethod('GET', 'workQueue', self.getWorkQueue,62                       args = ['request', 'workQueue'], 63                       secured=True, validation = [self.isalnum], expires = 0)64        self._addMethod('GET', 'message', self.getMessage,65                       args = ['request'], 66                       secured=True, validation = [self.isalnum], expires = 0)67        self._addMethod('GET', 'inputdataset', self.getInputDataset,68                       args = ['prim', 'proc', 'tier'],69                       secured=True)70        self._addMethod('GET', 'outputdataset', self.getOutputDataset,71                       args = ['prim', 'proc', 'tier'],72                       secured=True)73        self._addMethod('GET', 'campaign', self.getCampaign,74                       args = ['campaign'],75                       secured=True, validation = [self.isalnum], expires = 0)76        self._addMethod('PUT', 'request', self.putRequest,77                       args = ['requestName', 'status', 'priority'],78                       secured=True, validation = [self.isalnum, self.reqPriority])79        self._addMethod('PUT', 'assignment', self.putAssignment,80                       args = ['team', 'requestName'],81                       secured=True, security_params=self.security_params,82                       validation = [self.isalnum])83        self._addMethod('PUT', 'user', self.putUser,84                       args = ['userName', 'email', 'dnName'],85                       secured=True, security_params=self.security_params,86                       validation = [self.validateUser])87        self._addMethod('PUT', 'group', self.putGroup,88                       args = ['group', 'user'],89                       secured=True, security_params=self.security_params,90                       validation = [self.isalnum])91        self._addMethod('PUT', 'version', self.putVersion,92                       args = ['version', 'scramArch'],93                       secured=True, security_params=self.security_params,94                       validation = [self.validateVersion])95        self._addMethod('PUT', 'team', self.putTeam,96                       args = ['team'],97                       secured=True, security_params=self.security_params,98                       validation = [self.isalnum])99        self._addMethod('PUT', 'workQueue', self.putWorkQueue, 100                       args = ['request', 'url'],101                       secured=True, security_params=self.security_params,102                       validation = [self.validatePutWorkQueue])103        self._addMethod('PUT', 'message', self.putMessage,104                       args = ['request'],105                       secured=True, security_params=self.security_params,106                       validation = [self.isalnum])107        self._addMethod('PUT', 'campaign', self.putCampaign,108                       args = ['campaign', 'request'],109                       secured=True, 110                       validation = [self.isalnum])111        self._addMethod('POST', 'request', self.postRequest,112                        args = ['requestName', 'events_written', 113                                'events_merged', 'files_written',114                                'files_merged', 'percent_written', 115                                'percent_success', 'dataset'],116                        secured=True, validation = [self.validateUpdates])117        self._addMethod('POST', 'user', self.postUser,118                        args = ['user', 'priority'],119                        secured=True, security_params=self.security_params,120                        validation = [self.isalnum, self.intpriority])121        self._addMethod('POST',  'group', self.postGroup,122                        args = ['group', 'priority'],123                        secured=True, security_params=self.security_params,124                        validation = [self.isalnum, self.intpriority])125        self._addMethod('DELETE', 'request', self.deleteRequest,126                        args = ['requestName'],127                        secured=True, security_params=self.security_params,128                        validation = [self.isalnum])129        self._addMethod('DELETE', 'user', self.deleteUser,130                        args = ['user'],131                        secured=True, security_params=self.security_params,132                        validation = [self.isalnum])133        self._addMethod('DELETE', 'group', self.deleteGroup,134                        args = ['group', 'user'],135                        secured=True, security_params=self.security_params,136                        validation = [self.isalnum])137        self._addMethod('DELETE', 'version', self.deleteVersion,138                        args = ['version', 'scramArch'],139                        secured=True, validation = [self.validateVersion])140        self._addMethod('DELETE', 'team', self.deleteTeam,141                        args = ['team'],142                        secured=True, security_params=self.security_params,143                        validation = [self.isalnum])144        self._addMethod('DELETE', 'campaign', self.deleteCampaign,145                        args = ['campaign'],146                        secured=True, security_params=self.security_params,147                        validation = [self.isalnum])148        self._addMethod('GET', 'requestnames', self.getRequestNames,149                       args = [], secured=True, expires = 0)150        self._addMethod('GET', 'outputDatasetsByRequestName', self.getOutputForRequest,151                       args = ['requestName'], secured=True,152                       validation=[self.isalnum], expires = 0)153        self._addMethod('GET', 'outputDatasetsByPrepID', self.getOutputForPrepID,154                       args = ['prepID'], secured=True, 155                       validation=[self.isalnum], expires = 0)        156        self._addMethod('GET', 'mostRecentOutputDatasetsByPrepID', self.getMostRecentOutputForPrepID,157                       args = ['prepID'], secured=True, 158                       validation=[self.isalnum], expires = 0)159        cherrypy.engine.subscribe('start_thread', self.initThread)160    161    def initThread(self, thread_index):162        """ The ReqMgr expects the DBI to be contained in the Thread  """163        myThread = threading.currentThread()164        #myThread = cherrypy.thread_data165        # Get it from the DBFormatter superclass166        myThread.dbi = self.dbi167    def isalnum(self, index):168        """ Validates that all input is alphanumeric, 169            with spaces and underscores tolerated"""170        for v in index.values():171            WMCore.Lexicon.identifier(v)172        return index173    def getDataset(self, prim, proc, tier):174        """ If only prim exists, assume it's urlquoted.175            If all three exists, assue it's /prim/proc/tier 176        """177        if not proc and not tier:178            dataset = urllib.unquote(prim)179        elif prim and proc and tier:180            dataset = "/%s/%s/%s" % (prim, proc, tier)181        WMCore.Lexicon.dataset(dataset) 182        return dataset183    def intpriority(self, index):184        """ Casts priority to an integer """185        if index.has_key('priority'):186            value = int(index['priority'])187            if math.fabs(value) >= sys.maxint:188                msg = "Invalid priority!  Priority must have abs() less then MAXINT!" 189                raise cherrypy.HTTPError(400, msg)190            index['priority'] = value191        return index192    def reqPriority(self, index):193        """194        _reqPriority_195        Sets request priority to an integer.196        Also makes sure it's within a certain value.197        """198        if not index.has_key('priority'):199            return index200        201        index = self.intpriority(index = index)202        value = index['priority']203        if math.fabs(value) > self.reqPriorityMax:204            msg = "Invalid requestPriority!  Request priority must have abs() less then %i!" % self.reqPriorityMax205            raise cherrypy.HTTPError(400, msg)206            207        return index208    209    def validateUser(self, index):210        assert index['userName'].isalnum()211        assert '@' in index['email']212        assert index['email'].replace('@','').replace('.','').isalnum()213        if 'dnName' in index:214            assert index['dnName'].replace(' ','').isalnum()215        return index216    def validateVersion(self, index):217        """ Make sure it's a legitimate CMSSW version format """218        WMCore.Lexicon.cmsswversion(index['version'])219        return index220    def findRequest(self, requestName):221        """ Either returns the request object, or None """222        requests = ListRequests.listRequests()223        for request in requests:224            if request['RequestName'] == requestName:225                return request226        return None227    def getRequest(self, requestName=None):228        """ If a request name is specified, return the details of the request. 229        Otherwise, return an overview of all requests """230        if requestName == None:231            return GetRequest.getRequests()232        else:233            result   = Utilities.requestDetails(requestName)234            try:235                teamNames       = GetRequest.getAssignmentsByName(requestName)236                result['teams'] = teamNames237            except:238                # Ignore errors, then we just don't have a team name239                pass240            return result241    def getRequestNames(self):242        """ return all the request names in RequestManager as list """243        #TODO this could me combined with getRequest244        return GetRequest.getOverview()245    def getOutputForRequest(self, requestName):246        """Return the datasets produced by this request."""247        return Utilities.getOutputForRequest(requestName)248    def getOutputForPrepID(self, prepID):249        """Return the datasets produced by this prep ID. in a dict of requestName:dataset list"""250        requestIDs = GetRequest.getRequestByPrepID(prepID)251        result = {}252        for requestID in requestIDs:253            request = GetRequest.getRequest(requestID)254            requestName = request["RequestName"]255            helper = Utilities.loadWorkload(request)256            result[requestName] =  helper.listOutputDatasets()257        return result258    def getMostRecentOutputForPrepID(self, prepID):259        """Return the datasets produced by the most recently submitted request with this prep ID"""260        requestIDs = GetRequest.getRequestByPrepID(prepID)261        # most recent will have the largest ID262        requestID = max(requestIDs)263        request = GetRequest.getRequest(requestID)264        helper = Utilities.loadWorkload(request)265        return helper.listOutputDatasets()266 267    def getAssignment(self, teamName=None, request=None):268        """ If a team name is passed in, get all assignments for that team.269        If a request is passed in, return a list of teams the request is 270        assigned to 271        """272        # better to use ReqMgr/RequestDB/Interface/ProdSystem/ProdMgrRetrieve?273        #requestIDs = ProdMgrRetrieve.findAssignedRequests(teamName)274        # Maybe now assigned to team is same as assigned to ProdMgr275        result = []276        if teamName != None:277            requestIDs = ListRequests.listRequestsByTeam(teamName, "assigned").values()278            requests = [GetRequest.getRequest(reqID) for reqID in requestIDs]279            # put highest priorities first280            requests.sort(key=lambda r: r['RequestPriority'], reverse=True)281            # return list of tuples, since we need sorting282            result = [[req['RequestName'], req['RequestWorkflow']] for req in requests]283        elif request != None:284            result = GetRequest.getAssignmentsByName(request)285        return result286    def getUser(self, userName=None, group=None):287        """ No args returns a list of all users.  Group returns groups this user is in.  Username288            returs a JSON with information about the user """289        if userName != None:290            if not Registration.isRegistered(userName):291                raise cherrypy.HTTPError(404, "Cannot find user")292            result = {}293            result['groups'] = GroupInfo.groupsForUser(userName).keys()294            result['requests'] = UserRequests.listRequests(userName).keys()295            result['priority'] = UserManagement.getPriority(userName)296            result.update(Registration.userInfo(userName))297            return json.dumps(result)298        elif group != None:299            GroupInfo.usersInGroup(group)    300        else:301            return Registration.listUsers()302        303    def getGroup(self, group=None, user=None):304        """ No args lists all groups, one args returns JSON with users and priority """305        if group != None:306            result = {}307            result['users'] =  GroupInfo.usersInGroup(group)308            try:309                result['priority'] = GroupManagement.getPriority(group)310            except IndexError:311                raise cherrypy.HTTPError(404, "Cannot find group/group priority")312            return json.dumps(result)313        elif user != None:   314            return GroupInfo.groupsForUser(user).keys()315        else:316            return GroupInfo.listGroups()317    def getVersion(self):318        """ Returns a list of all CMSSW versions registered with ReqMgr """319        archList = SoftwareAdmin.listSoftware()320        result   = []321        for arch in archList.keys():322            for version in archList[arch]:323                if not version in result:324                    result.append(version)325        return result326      327    def getTeam(self):328        """ Returns a list of all teams registered with ReqMgr """329        return ProdManagement.listTeams()330    def getWorkQueue(self, request=None, workQueue=None):331        """ If a request is passed in, return the URl of the workqueue.332        If a workqueue is passed in, return all requests acquired by it """333        if workQueue != None:334            return ProdMgrRetrieve.findAssignedRequests(workQueue)335        if request != None:336            return ProdManagement.getProdMgr(request)337        # return all the workqueue ulr338        return GetRequest.getGlobalQueues()339    def getMessage(self, request):340        """ Returns a list of messages attached to this request """341        return ChangeState.getMessages(request)342    def getInputDataset(self, prim, proc=None, tier=None):343        """ returns a list of requests with this input dataset 344         Input can either be a single urlquoted dataset, or a 345         /prim/proc/tier"""346        dataset = self.getDataset(prim, proc, tier)347        return GetRequest.getRequestsByCriteria("Datasets.GetRequestByInput", dataset)  348    def getOutputDataset(self, prim, proc=None, tier=None):349        """ returns a list of requests with this output dataset 350         Input can either be a single urlquoted dataset, or a351         /prim/proc/tier"""352        dataset = self.getDataset(prim, proc, tier)353        return GetRequest.getRequestsByCriteria("Datasets.GetRequestByOutput", dataset)354    def getCampaign(self, campaign=None):355        """ returns a list of all campaigns if no argument, and a list of356             all requests in a campaign if there is an argument """357        if campaign == None:358            return Campaign.listCampaigns()359        else:360            return Campaign.listRequestsByCampaign(campaign)361    def putWorkQueue(self, request, url):362        """ Registers the request as "acquired" by the workqueue with the given URL """363        Utilities.changeStatus(request, "acquired")364        return ProdManagement.associateProdMgr(request, urllib.unquote(url))365    def validatePutWorkQueue(self, index):366        assert index['request'].replace('_','').replace('-','').replace('.','').isalnum()367        assert index['url'].startswith('http')368        return index369    def putRequest(self, requestName=None, status=None, priority=None):370        """ Checks the request n the body with one arg, and changes the status with kwargs """371        request = None372        if requestName:373            request = self.findRequest(requestName)374        if request == None:375            """ Creates a new request, with a JSON-encoded schema that is sent in the376            body of the request """377            body = cherrypy.request.body.read()378            schema = Utilities.unidecode(JsonWrapper.loads(body))379            schema.setdefault('CouchURL', Utilities.removePasswordFromUrl(self.couchUrl))380            schema.setdefault('CouchDBName', self.configDBName)381            try:382                request = Utilities.makeRequest(schema, self.couchUrl, self.workloadDBName)383            except cherrypy.HTTPError:384                # Assume that this is a valid HTTPError385                raise386            except WMException, ex:387                raise cherrypy.HTTPError(400, ex._message)388            except Exception, ex:389                raise cherrypy.HTTPError(400, ex.message)390        # see if status & priority need to be upgraded391        if status != None:392            # forbid assignment here393            if status == 'assigned' and request['RequestStatus'] != 'ops-hold':394                raise cherrypy.HTTPError(403, "Cannot change status without a team.  Please use PUT /reqmgr/rest/assignment/<team>/<requestName>")395            try:396                Utilities.changeStatus(requestName, status)397            except RuntimeError, e:398                # ignore some of these errors: https://svnweb.cern.ch/trac/CMSDMWM/ticket/2002399                if status != 'announced' and status != 'closed-out':400                    raise cherrypy.HTTPError(403, "Failed to change status: %s" % str(e))401        if priority != None:402            Utilities.changePriority(requestName, priority) 403        return request404    def putAssignment(self, team, requestName):405        """ Assigns this request to this team """406        # see if it's already assigned407        team = urllib.unquote(team)408        if not team in ProdManagement.listTeams():409            raise cherrypy.HTTPError(404,"Cannot find this team")410        requestNamesAndIDs = ListRequests.listRequestsByTeam(team)411        if requestName in requestNamesAndIDs.keys():412            raise cherrypy.HTTPError(400,"Already assigned to this team")413        return ChangeState.assignRequest(requestName, team)414    def putUser(self, userName, email, dnName=None):415        """ Needs to be passed an e-mail address, maybe dnName """416        if Registration.isRegistered(userName):417            return "User already exists"418        result = Registration.registerUser(userName, email, dnName)419    def putGroup(self, group, user=None):420        """ Creates a group, or if a user is passed, adds that user to the group """421        if(user != None):422            # assume group exists and add user to it423            return GroupManagement.addUserToGroup(user, group)424        if GroupInfo.groupExists(group):425            return "Group already exists"426        GroupManagement.addGroup(group)427    def putVersion(self, version, scramArch = None):428        """ Registers a new CMSSW version with ReqMgr """429        return SoftwareAdmin.addSoftware(version, scramArch = scramArch)430    def putTeam(self, team):431        """ Registers a team with ReqMgr """432        return ProdManagement.addTeam(urllib.unquote(team))433    def putMessage(self, request):434        """ Attaches a message to this request """435        message = JsonWrapper.loads( cherrypy.request.body.read() )436        result = ChangeState.putMessage(request, message)437        return result438    def putCampaign(self, campaign, request=None):439        """ Adds a campaign if it doesn't already exist, and optionally440            associates a request with it """441        if request:442            requestID = GetRequest.requestID(request)443            if requestID:444                result = Campaign.associateCampaign(campaign, requestID)445                Utilities.associateCampaign(campaign = campaign,446                                            requestName = request,447                                            couchURL = self.couchUrl,448                                            couchDBName = self.workloadDBName)449                return result450            else:451                return False452        else:453            Campaign.addCampaign(campaign)454        455#    def postRequest(self, requestName, events_written=None, events_merged=None, 456#                    files_written=None, files_merged = None, dataset=None):457    def postRequest(self, requestName, **kwargs):458        """459        Add a progress update to the request Id provided, params can460        optionally contain:461        - *events_written* Int462        - *events_merged*  Int463        - *files_written*  Int464        - *files_merged*   int465        - *percent_success* float466        - *percent_complete float467        - *dataset*        string (dataset name)468        """469        return ChangeState.updateRequest(requestName, kwargs)470    def validateUpdates(self, index):471        """ Check the values for the updates """472        for k in ['events_written', 'events_merged', 473                  'files_written', 'files_merged']:474            if k in index:475                index[k] = int(index[k])476        for k in ['percent_success', 'percent_complete']:477            if k in index:478                index[k] = float(index[k])479        return index480    def postUser(self, user, priority):481        """ Change the user's priority """482        return UserManagement.setPriority(user, priority)483    def postGroup(self, group, priority):484        """ Change the group's priority """485        return GroupManagement.setPriority(group, priority)486    def deleteRequest(self, requestName):487        """ Deletes a request from the ReqMgr """488        request = self.findRequest(requestName)489        if request == None:490            raise cherrypy.HTTPError(404, "No such request")491        return RequestAdmin.deleteRequest(request['RequestID'])492    def deleteUser(self, user):493        """ Deletes a user, as well as deleting his requests and removing494            him from all groups """495        if user in self.getUser():496            requests = json.loads(self.getUser(user))['requests']497            for request in requests:498                self.deleteRequest(request)499            for group in GroupInfo.groupsForUser(user).keys():500                GroupManagement.removeUserFromGroup(user, group)501            return UserManagement.deleteUser(user)502    def deleteGroup(self, group, user=None):503        """ If no user is sent, delete the group.  Otherwise, delete the user from the group """504        if user == None:505            return GroupManagement.deleteGroup(group)506        else:507            return GroupManagement.removeUserFromGroup(user, group) 508    def deleteVersion(self, version, scramArch):509        """ Un-register this software version with ReqMgr """510        SoftwareAdmin.removeSoftware(version, scramArch)511    def deleteTeam(self, team):512        """ Delete this team from ReqMgr """513        ProdManagement.removeTeam(urllib.unquote(team))514    def deleteCampaign(self, campaign):...authorizer.py
Source:authorizer.py  
1import jwt2import re3from os import environ4JWT_SECRET = environ.get('JWT_SECRET', 'm3chsh0p_4p1')5access_request = [6    {7        'method': 'GET',8        'resource': '/items'9    },10    {11        'method': 'POST',12        'resource': '/items'13    }14]15def handler(event, context):16    print('Authorization Token: ' + event['authorizationToken'])17    print('Method ARN: ' + event['methodArn'])18    if 'authorizationToken' not in event:19        raise Exception('Unauthorized')20    if not event['authorizationToken'].startswith('Bearer'):21        raise Exception('Unaunthorized')22    token = event['authorizationToken'].replace('Bearer', '').strip()23    try:24        payload = jwt.decode(token, JWT_SECRET, algorithm="HS256")25        # check the user belongs to the database26    except jwt.exceptions.InvalidTokenError:27        raise Exception('Token invalid or expired')28    aws_data = get_aws_data(event)29    policy = AuthPolicy(payload['user_id'], aws_data['awsAccountId'])30    policy.restApiId = aws_data['restApiId']31    policy.region = aws_data['region']32    policy.stage = aws_data['stage']33    for request in access_request:34        policy.allowMethod(request['method'], request['resource'])35    authResponse = policy.build()36    authResponse['context'] = {37        'userId': payload['user_id'],38        'jwtToken': token39    }40    return authResponse41def get_aws_data(event):42    tmp = event['methodArn'].split(':')43    awsAccountId = tmp[4]44    apiGatewayArnTmp = tmp[5].split('/')45    region = tmp[3]46    rest_api_id = apiGatewayArnTmp[0]47    stage = apiGatewayArnTmp[1]48    49    return { 'awsAccountId': awsAccountId, 'region': region, 'restApiId': rest_api_id, 'stage': stage }50class HttpVerb:51    GET     = "GET"52    POST    = "POST"53    PUT     = "PUT"54    PATCH   = "PATCH"55    HEAD    = "HEAD"56    DELETE  = "DELETE"57    OPTIONS = "OPTIONS"58    ALL     = "*"59class AuthPolicy(object):60    awsAccountId = ""61    """The AWS account id the policy will be generated for. This is used to create the method ARNs."""62    principalId = ""63    """The principal used for the policy, this should be a unique identifier for the end user."""64    version = "2012-10-17"65    """The policy version used for the evaluation. This should always be '2012-10-17'"""66    pathRegex = "^[/.a-zA-Z0-9-\*]+$"67    """The regular expression used to validate resource paths for the policy"""68    """these are the internal lists of allowed and denied methods. These are lists69    of objects and each object has 2 properties: A resource ARN and a nullable70    conditions statement.71    the build method processes these lists and generates the approriate72    statements for the final policy"""73    allowMethods = []74    denyMethods = []75    restApiId = "*"76    """The API Gateway API id. By default this is set to '*'"""77    region = "*"78    """The region where the API is deployed. By default this is set to '*'"""79    stage = "*"80    """The name of the stage used in the policy. By default this is set to '*'"""81    def __init__(self, principal, awsAccountId):82        self.awsAccountId = awsAccountId83        self.principalId = principal84        self.allowMethods = []85        self.denyMethods = []86    def _addMethod(self, effect, verb, resource, conditions):87        """Adds a method to the internal lists of allowed or denied methods. Each object in88        the internal list contains a resource ARN and a condition statement. The condition89        statement can be null."""90        if verb != "*" and not hasattr(HttpVerb, verb):91            raise NameError("Invalid HTTP verb " + verb + ". Allowed verbs in HttpVerb class")92        resourcePattern = re.compile(self.pathRegex)93        if not resourcePattern.match(resource):94            raise NameError("Invalid resource path: " + resource + ". Path should match " + self.pathRegex)95        if resource[:1] == "/":96            resource = resource[1:]97        resourceArn = ("arn:aws:execute-api:" +98            self.region + ":" +99            self.awsAccountId + ":" +100            self.restApiId + "/" +101            self.stage + "/" +102            verb + "/" +103            resource)104        if effect.lower() == "allow":105            self.allowMethods.append({106                'resourceArn' : resourceArn,107                'conditions' : conditions108            })109        elif effect.lower() == "deny":110            self.denyMethods.append({111                'resourceArn' : resourceArn,112                'conditions' : conditions113            })114    def _getEmptyStatement(self, effect):115        """Returns an empty statement object prepopulated with the correct action and the116        desired effect."""117        statement = {118            'Action': 'execute-api:Invoke',119            'Effect': effect[:1].upper() + effect[1:].lower(),120            'Resource': []121        }122        return statement123    def _getStatementForEffect(self, effect, methods):124        """This function loops over an array of objects containing a resourceArn and125        conditions statement and generates the array of statements for the policy."""126        statements = []127        if len(methods) > 0:128            statement = self._getEmptyStatement(effect)129            for curMethod in methods:130                if curMethod['conditions'] is None or len(curMethod['conditions']) == 0:131                    statement['Resource'].append(curMethod['resourceArn'])132                else:133                    conditionalStatement = self._getEmptyStatement(effect)134                    conditionalStatement['Resource'].append(curMethod['resourceArn'])135                    conditionalStatement['Condition'] = curMethod['conditions']136                    statements.append(conditionalStatement)137            statements.append(statement)138        return statements139    def allowAllMethods(self):140        """Adds a '*' allow to the policy to authorize access to all methods of an API"""141        self._addMethod("Allow", HttpVerb.ALL, "*", [])142    def denyAllMethods(self):143        """Adds a '*' allow to the policy to deny access to all methods of an API"""144        self._addMethod("Deny", HttpVerb.ALL, "*", [])145    def allowMethod(self, verb, resource):146        """Adds an API Gateway method (Http verb + Resource path) to the list of allowed147        methods for the policy"""148        self._addMethod("Allow", verb, resource, [])149    def denyMethod(self, verb, resource):150        """Adds an API Gateway method (Http verb + Resource path) to the list of denied151        methods for the policy"""152        self._addMethod("Deny", verb, resource, [])153    def allowMethodWithConditions(self, verb, resource, conditions):154        """Adds an API Gateway method (Http verb + Resource path) to the list of allowed155        methods and includes a condition for the policy statement. More on AWS policy156        conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""157        self._addMethod("Allow", verb, resource, conditions)158    def denyMethodWithConditions(self, verb, resource, conditions):159        """Adds an API Gateway method (Http verb + Resource path) to the list of denied160        methods and includes a condition for the policy statement. More on AWS policy161        conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""162        self._addMethod("Deny", verb, resource, conditions)163    def build(self):164        """Generates the policy document based on the internal lists of allowed and denied165        conditions. This will generate a policy with two main statements for the effect:166        one statement for Allow and one statement for Deny.167        Methods that includes conditions will have their own statement in the policy."""168        if ((self.allowMethods is None or len(self.allowMethods) == 0) and169            (self.denyMethods is None or len(self.denyMethods) == 0)):170            raise NameError("No statements defined for the policy")171        policy = {172            'principalId' : self.principalId,173            'policyDocument' : {174                'Version' : self.version,175                'Statement' : []176            }177        }178        policy['policyDocument']['Statement'].extend(self._getStatementForEffect("Allow", self.allowMethods))179        policy['policyDocument']['Statement'].extend(self._getStatementForEffect("Deny", self.denyMethods))...CRABRESTModelMock.py
Source:CRABRESTModelMock.py  
1from WMCore.WebTools.RESTModel import RESTModel2import WMCore3import threading4import cherrypy5import imp6import os7import uuid8import tempfile9SI_RESULT = {}10SI_RESULT['server_dn']  = ''11SI_RESULT['my_proxy'] = 'myproxy.cern.ch'12FILE_NAME = 'src_output.root'13goodLumisResult = '{"1":[ [1,15],  [30,50] ], "3":[ [10,15], [30,50] ]}'14publishResult   = {u'status': True, u'message': 'Publication completed for campaign ewv_crab_something_1_111229_140959', u'summary': {u'/primary/secondary-out1-v1/USER': {u'files': 10, u'blocks': 1, u'existingFiles': 10}, u'/primary/secondary-out2-v1/USER': {u'files': 10, u'blocks': 1, u'existingFiles': 10}}}15class CRABRESTModelMock(RESTModel):16    def __init__(self, config={}):17        RESTModel.__init__(self, config)18        self.mapme = imp.load_source('', os.path.join( os.path.dirname(__file__), "../../../data/mapper.py"))19        self.defaulturi = self.mapme.defaulturi20        self._addMethod('POST', 'user', self.addNewUser,21                        args=[],22                        validation=[self.isalnum])23        self._addMethod('POST', 'task', self.postRequest,24                        args=['requestName'],25                        validation=[self.isalnum])26        self._addMethod('DELETE', 'task', self.deleteRequest,27                        args=['requestID'],28                        validation=[self.isalnum])29        self._addMethod('GET', 'task', self.getTaskStatus,30                        args=['requestID'],31                        validation=[self.isalnum])32        #/data33        self._addMethod('GET', 'data', self.getDataLocation,34                       args=['requestID','jobRange'], validation=[self.isalnum])35        self._addMethod('POST', 'publish', self.publish,36                        args=['requestName'],37                        validation=[self.isalnum])38        #/goodLumis39        self._addMethod('GET', 'goodLumis', self.getGoodLumis,40                       args=['requestID'], validation=[self.isalnum])41        #42        self._addMethod('POST', 'lumiMask', self.postLumiMask,43                       args=[], validation=[self.isalnum])44        # Server45        self._addMethod('GET', 'info', self.getServerInfo,46                        args=[],47                        validation=[self.isalnum])48        self._addMethod('GET', 'requestmapping', self.getClientMapping,49                        args=[],50                        validation=[self.isalnum])51        self._addMethod('GET', 'jobErrors', self.getJobErrors,52                        args=['requestID'],53                        validation=[self.isalnum])54        self._addMethod('POST', 'resubmit', self.reSubmit,55                        args=['requestID'],56                        validation=[self.isalnum])57        cherrypy.engine.subscribe('start_thread', self.initThread)58    #not sure if we really need to validate input.59    def isalnum(self, call_input):60        """61        Validates that all input is alphanumeric, with spaces and underscores62        tolerated.63        """64        for v in call_input.values():65            WMCore.Lexicon.identifier(v)66        return call_input67    def initThread(self, thread_index):68        """69        The ReqMgr expects the DBI to be contained in the Thread70        """71        myThread = threading.currentThread()72        #myThread = cherrypy.thread_data73        # Get it from the DBFormatter superclass74        myThread.dbi = self.dbi75    def getServerInfo(self):76        """77        Return information to allow client operations78        """79        return SI_RESULT80    def getTaskStatus(self, requestID):81        return {u'workflows': [{u'request': u'cinquilli.nocern_crab_TESTME_1_111025_181202',82                  u'requestDetails': {u'RequestMessages': [], u'RequestStatus': u'aborted'},83                  u'states': {u'/cinquilli.nocern_crab_TESTME_1_111025_181202/Analysis': {u'success': {u'count': 9, u'jobIDs': [117, 118, 119, 120, 121, 122, 123, 124, 125],84                                                                                                       u'jobs': [1, 2, 3, 4, 5, 6, 7, 8, 9]}},85                              u'/cinquilli.nocern_crab_TESTME_1_111025_181202/Analysis/LogCollect': {u'success': {u'count': 1, u'jobIDs': [126], u'jobs': [10]}}},86                  u'subOrder': 1},87                 {u'request': u'cinquilli.nocern_crab_TESTME_1_resubmit_111028_000117',88                  u'requestDetails': {u'RequestMessages': [['request failed']], u'RequestStatus': u'failed'},89                  u'states': {},90                  u'subOrder': 2}]}91    def getDataLocation(self, requestID, jobRange):92        f = open(FILE_NAME, 'w')93        f.close()94        return {u'data': [{u'output': {u'1': {u'pfn': unicode(FILE_NAME)}},95                           u'request': u'cinquilli.nocern_crab_TESTME_1_111025_181202',96                           u'subOrder': 1},97                          {u'output': {},98                           u'request': u'cinquilli.nocern_crab_TESTME_1_resubmit_111028_000117',99                           u'subOrder': 2}]}100    def getGoodLumis(self, requestID):101        """102        Mockup to return the list of good lumis processed as generated103        by CouchDB104        """105        return goodLumisResult106    def publish(self, requestName):107        """108        Mockup to return the publication summary109        """110        return publishResult111    def getClientMapping(self):112        """113        Return the dictionary that allows the client to map the client configuration to the server request114        It also returns the URI for each API115        """116        return self.defaulturi117    def deleteRequest(self, requestID):118        return {"result": "ok"}119    def addNewUser(self):120        return { "hn_name" : "mmascher" }121    def postRequest(self, requestName):122          return {'ID': 'mmascher_crab_MyAnalysis26_110707_164957'}123    def postLumiMask(self):124        """125        Mock version of result of ACDC upload126        """127        result = {}128        result['DocID']  = uuid.uuid4().hex129        result['DocRev'] = uuid.uuid4().hex130        result['Name']   = "%s-cmsRun1" % params['RequestName']131        return result132    def getJobErrors(self, requestID):133        failed = {'1':134                   {'0': {135                     'step1': [ { "details": "Error in StageOut: 99109\n'x.z.root' does not match regular expression /store/temp/([a-zA-Z0-9\\-_]+).root",136                                  "type":"Misc. StageOut error: 99109\n",137                                  "exitCode":99109 }138                              ],139                     'step2': [ { "details": "Cannot find file in jobReport path: /x/y/z/job_134/Report.1.pkl",140                                  "type":"99999",141                                  "exitCode":84 }142                              ]143                     }144                   },145                  '2':146                   {'0': {147                     'step1': [ { "details": "Error in StageOut: 99109\n'x.z.root' does not match regular expression /store/temp/([a-zA-Z0-9\\-_]+).root",148                                  "type":"Misc. StageOut error: 99109\n",149                                  "exitCode":99109 }150                              ]151                     },152                    '1': {153                     'step1': [ { "details": "Error in StageOut: 99109\n'x.z.root' does not match regular expression /store/temp/([a-zA-Z0-9\\-_]+).root",                                                           "type":"Misc. StageOut error: 99109\n",154                                  "exitCode":99109 }155                              ]156                     }157                   }158                 }159        return {u'errors': [{u'details': failed, u'request': u'cinquilli.nocern_crab_TESTME_1_111025_181202', u'subOrder': 1},160                            {u'details': {}, u'request': u'cinquilli.nocern_crab_TESTME_1_resubmit_111028_000117', u'subOrder': 2}]}161    def reSubmit(self, requestID):...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
