def layers(row, environmentGuid, hostGuid, stackLayerID): layerData = { 'componentName': row['componentName'], 'hostID': hostGuid, 'environmentID': environmentGuid, 'stackLayerID': stackLayerID, 'version': row['version'] } # Does component already exist? path = { 'environmentName': row['name'], 'hostName': row['hostName'], 'layerType': row['StackLayer'], 'componentName': row['componentName'] } componentId = plutora.getComponentId(path) if (componentId): # Exists componentResponse = plutora.api("GET", "layers/" + componentId) print "Component \"" + componentResponse[ 'componentName'] + "\" exists, updating" componentResponse['version'] = row['version'] plutora.api("PUT", "layers/" + componentId, componentResponse) else: # Does not exist print "Component \"" + row[ 'componentName'] + "\" does not exist, creating" layerResponse = plutora.api("POST", "layers", layerData)
def systems(rowReader): existingObjects = plutora.listToDict(plutora.api("GET", "systems"), "name", "id") organizations = plutora.listToDict(plutora.api("GET", "organizations"), "name", "id") for row in rowReader: # TODO: Validate fields, status Active or Inactive only # Common system data whether exists or not systemData = { 'name': row['name'], 'description': row['description'], 'status': row['status'], # TODO: handle hierarchy 'organizationId': organizations.get(row['organization']), 'vendor': row['vendor'] } # Does the named object exist? if (row['name'] in existingObjects): # Exists print "System \"" + row['name'] + "\" exists, updating" systemGuid = existingObjects[row['name']] systemData['id'] = systemGuid existingSysData = plutora.api("GET", "systems/" + systemGuid) for field in systemData: # If the spreadsheet value is blank, use the existing value from Plutora systemData[field] = systemData[field] or existingSysData[field] systemResponse = plutora.api("PUT", "systems/" + systemGuid, systemData) else: # Does not exist print "System \"" + row['name'] + "\" does not exist, creating" systemResponse = plutora.api("POST", "systems", systemData) systemApi = "systems/" + systemResponse['id'] print "Created " + systemApi + " - " + systemResponse['name'] row['systemGuid'] = systemResponse['id']
def releases(rowReader): existingObjects = plutora.listToDict(plutora.api("GET", "releases"), "identifier", "id") organizations = plutora.listToDict(plutora.api("GET", "organizations"), "name", "id") releaseTypes = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseType"), "value", "id") users = plutora.api("GET", "users") managers = plutora.listToDict(users, "userName", "id") releaseStatusTypes = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseStatusType"), "value", "id") releaseRiskLevels = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseRiskLevel"), "value", "id") parentReleases = existingObjects for row in rowReader: # Common release data whether exists or not releaseData = { 'identifier': row['identifier'], 'name': row['name'], 'summary': row['summary'], 'releaseTypeId': releaseTypes.get(row['ReleaseType']), 'location': row['location'] or "NA", 'releaseStatusTypeId': releaseStatusTypes.get(row['ReleaseStatusType']), 'releaseRiskLevelId': releaseRiskLevels.get(row['ReleaseRiskLevel']), 'implementationDate': row['implementationDate'], 'displayColor': row['displayColor'], 'organizationId': organizations.get(row['organization']), # TODO: temporary workaround for REST required field which is not required in UI 'managerId': managers.get(row['Manager'] or users[0]['userName']), 'parentReleaseId': parentReleases.get(row['ParentRelease']), 'plutoraReleaseType': row['plutoraReleaseType'], 'releaseProjectType': row['releaseProjectType'] # TODO: Additional items } # Does the named object exist? if (row['identifier'] in existingObjects): # Exists print "Release \"" + row['identifier'] + "\" exists, updating" releaseGuid = existingObjects[row['identifier']] releaseData['id'] = releaseGuid existingRelData = plutora.api("GET", "releases/" + releaseGuid) for field in releaseData: # If the spreadsheet value is blank, use the existing value from Plutora releaseData[ field] = releaseData[field] or existingRelData[field] releaseResponse = plutora.api("PUT", "releases/" + releaseGuid, releaseData) else: # Does not exist print "Release \"" + row[ 'identifier'] + "\" does not exist, creating" releaseResponse = plutora.api("POST", "releases", releaseData) releaseApi = "releases/" + releaseResponse['id'] print "Created " + releaseApi + " - " + releaseResponse[ 'identifier'] row['releaseGuid'] = releaseResponse['id']
def environments(rowReader): existingObjects = plutora.listToDict(plutora.api("GET", "environments"), "name", "id") systems = plutora.listToDict(plutora.api("GET", "systems"), "name", "id") useFor = plutora.listToDict( plutora.api("GET", "lookupfields/UsedForWorkItem"), "value", "id") envStatatus = plutora.listToDict( plutora.api("GET", "lookupfields/EnvironmentStatus"), "value", "id") stackLayers = plutora.listToDict( plutora.api("GET", "lookupfields/StackLayer"), "value", "id") for row in rowReader: # Common environment data whether exists or not environmentData = { 'name': row['name'], 'description': row['description'], 'url': row['url'], 'vendor': row['vendor'], 'linkedSystemId': systems.get(row['linkedSystem']), 'environmentMgr': row['environmentMgr'], 'usageWorkItemId': useFor.get(row['UsageWorkItem']), 'environmentStatusId': envStatatus.get(row['EnvironmentStatus']), 'color': row['color'], 'isSharedEnvironment': row['isSharedEnvironment'] } # Does the named object exist? if (row['name'] in existingObjects): # Exists print "Environment \"" + row['name'] + "\" exists, updating" environmentGuid = existingObjects[row['name']] environmentData['id'] = environmentGuid existingEnvData = plutora.api("GET", "environments/" + environmentGuid) for field in environmentData: # If the spreadsheet value is blank, use the existing value from Plutora environmentData[ field] = environmentData[field] or existingEnvData[field] environmentResponse = plutora.api( "PUT", "environments/" + environmentGuid, environmentData) else: # Does not exist print "Environment \"" + row['name'] + "\" does not exist, creating" environmentResponse = plutora.api("POST", "environments", environmentData) environmentApi = "environments/" + environmentResponse['id'] print "Created " + environmentApi + " - " + environmentResponse[ 'name'] row['environmentGuid'] = environmentResponse['id'] environmentGuid = environmentResponse['id'] # Add new object to the list existingObjects[environmentResponse['name']] = environmentGuid # Add host if row.get('hostName'): hosts(row, environmentGuid, stackLayers)
def hosts(row, environmentId, stackLayers): hostName = row['hostName'] hostData = {'name': hostName, 'EnvironmentID': environmentId} existingObjects = plutora.listToDict( plutora.api("GET", "environments/" + environmentId)['hosts'], "name", "id") if (hostName in existingObjects): # Exists print "Host \"" + hostName + "\" exists, updating" hostGuid = existingObjects[hostName] hostData['id'] = hostGuid hostResponse = plutora.api("PUT", "hosts/" + hostGuid, hostData) else: # Does not exist print "Host \"" + hostName + "\" does not exist, creating" hostResponse = plutora.api("POST", "hosts", hostData) hostApi = "hosts/" + hostResponse['id'] print "Created " + hostApi + " - " + hostResponse['name'] row['hostGuid'] = hostResponse['id'] hostGuid = hostResponse['id'] if row.get('StackLayer'): layers(row, environmentId, hostGuid, stackLayers[row['StackLayer']])
with open("jira.cfg") as data_file: jiraCfg = json.load(data_file) j_url = jiraCfg["url"] j_user = jiraCfg["username"] j_password = jiraCfg["password"] # Login to Plutora Jira instance # jira = JIRA(server=j_url,basic_auth=(j_user,j_password)) # Get Jira releases # GET /rest/api/2/project/{projectIdOrKey}/versions jiraReleasesResponse = requests.get(j_url + "/rest/api/2/project/"+ jiraProjectName +"/versions", auth=(j_user, j_password)) jiraReleases = jiraReleasesResponse.json() # Get existing Plutora Releases existingReleases = plutora.listToDict(plutora.api("GET","releases"), "identifier", "id") # For each Jira Release for jiraRelease in jiraReleases: jiraReleaseName = jiraRelease['name'] jiraIssuesReponse = requests.get(j_url + "/rest/api/2/search?jql=fixVersion = " + jiraReleaseName, auth=(j_user, j_password)) jiraIssues = jiraIssuesReponse.json()['issues'] jiraIssueUrl = j_url + "/projects/" + jiraProjectName + "/versions/" + jiraRelease['id'] plutoraRelease = { "identifier": jiraReleaseName, "name": "Jira Version " + jiraReleaseName, "summary": "<a href=\"%s\">%s</a>" % (jiraIssueUrl,jiraIssueUrl), "releaseTypeId": "90d030c3-04a4-4c59-9e4a-90928293b8d0", "releaseType": "Major",
# Two styles: # (1) Column values repeated and # col1 col2 # top1 vala # top1 valb # top2 valc # # (2) First column value then blanks # col1 col2 # top1 # vala # valb # top2 # valc environments = plutora.listToDict(plutora.api("GET", "environments"), "name", "id") layers = plutora.listToDict(plutora.api("GET", "lookupfields/StackLayer"), "value", "id") for row in dictReader: myHost = { 'name': row['host'], 'EnvironmentID': environments[row['environment']] } host = plutora.api("POST", "hosts", myHost) hostApi = "hosts/" + host['id'] print "Created " + hostApi + " - " + host['name'] row['hostGuid'] = host['id']
# import plutora # Create a file to track all created objects so they can be easily deleted import datetime outfile = open( 'primerObjects' + '{:%Y%m%d%H%M%S}'.format(datetime.datetime.now()) + '.txt', 'w') # TODO: create a script to delete objects in the opposite order they were created # Solution: Environment Creation and Modification # Set to False to skip this example if True: # Get to root level organization portfolio orgGuid = plutora.api("GET", "organizations")[0]['id'] print "orgGuid " + orgGuid # Get UsageWorkItemId uwiiGuid = plutora.guidByPathAndName("lookupfields/UsedForWorkItem", "Dev", "value") print "uwiiGuid " + uwiiGuid # Get Environment Status GUID for "Active" envStatusGuid = plutora.guidByPathAndName("lookupfields/EnvironmentStatus", "Active", "value") print "envStatusGuid " + envStatusGuid # Get StackLayerID for "Application" StackLayerID = plutora.guidByPathAndName("lookupfields/StackLayer", "Application", "value")
# Python 2.7 # apiCaller.py # # Description: Command line tool to issue Plutora REST API Calls # # Usage: python apiCaller.py <verb> <path> # Example: python apiCaller.py GET systems # import plutora,sys,json print json.dumps(plutora.api(sys.argv[1],sys.argv[2]),indent=4)
def updateVersion(version,path): componentGuid = plutora.getComponentId(path) layerData = plutora.api("GET","layers/"+componentGuid) layerData['version']=version plutora.api("PUT","layers/"+componentGuid,layerData)
# Plutora REST API Samples and test cases # Several examples are provided below. Change the "if False:" to "if True:" to # enable the example. import plutora # Test cases for functions if False: # Set test value to True to run example ## Get list of System names with GET systems = plutora.api("GET", "systems") for system in systems: print system['name'] if False: # Set test value to True to run example # Look up a system GUID by system name systems = plutora.api("GET", "systems") # Get the name of an existing System firstSystemName=systems[0]['name'] sysGuidList=plutora.listToDict(systems,"name","id") # Show only first found GUID for System name (Plutor allows for multiple Systems with the same name) print "GUID for System name " + firstSystemName + " = " + sysGuidList[firstSystemName] if False: # Set test value to True to run example # Look up a GUID by API path and object name apiPath = "organizations" # Get the name of an existing organization orgName = plutora.api("GET", apiPath)[0]['name'] objectGuid = plutora.guidByPathAndName(apiPath, orgName) print "GUID of \"" + orgName + "\" of " + apiPath + " = " + objectGuid
# Select target Release Phase for the Activities DEV_phaseId = plutora.guidByPathAndName('workitemnames/phases',releasePhase) # Retrieve Jira tasks tasks = jira.search_issues(jql_str, startAt=0, maxResults=10, validate_query=True, fields=None, expand=None, json_result=None) print "Found %d Jira tasks." % len(tasks) # For each Jira task found for task in tasks: print "Processing Jira task %s" % jira.issue(task.key) taskHandle = jira.issue(task.id) Title = taskHandle.raw['fields']['summary'] Description = "Jira task %s" % jira.issue(task.key) EndDate = taskHandle.raw['fields']['duedate'] # Only create Activities with due dates if (EndDate==None): break #print "%sT00:00:00" % EndDate activity = { 'Title': Title, 'Description': Description, 'ActivityDependencyType': 'None', 'Type': 'Activity', 'Status': 'NotStarted', 'AssignedToID': plutora.guidByPathAndName('users',releaseStakeholder,field="userName"), 'AssignedWorkItemID': plutora.guidByPathAndName("releases/%s/phases" % releaseId, DEV_phaseId, field="workItemNameID"), # Phase 'EndDate': "%sT00:00:00" % EndDate } plutora.api('POST',"releases/%s/activities" % releaseId ,data=activity)
import plutora, sys, json releases = plutora.api("GET", "releases") for rel in releases: release = plutora.api("GET", "releases/" + rel['id']) print "Processing release " + release['name']
# Python 2.7 # Delete objects created by primerImplementation.py listed in primerObjects<timestamp>.txt # import plutora, glob for file in glob.glob('primerObjects*.txt'): print "Loading file: " + file # Load object list file with open(file) as f: objects = [x.strip('\n') for x in f.readlines()] for obj in objects[::-1]: print "Deleting " + obj plutora.api("DELETE", obj)
def exportObjects(filename, objectType, filter): import plutora, csv fieldnames = [] for column in plutora.objectFields[objectType]: fieldnames.append(column['name']) print "Creating CSV file for output" csvfile = open(filename + ".csv", 'w') csvfileWriter = csv.DictWriter(csvfile, fieldnames=fieldnames, lineterminator='\n') csvfileWriter.writeheader() objects = plutora.api("GET", objectType) if (objectType == "systems"): organizations = plutora.listToDict(plutora.api("GET", "organizations"), "id", "name") filterKey = "name" elif (objectType == "environments"): systems = plutora.listToDict(plutora.api("GET", "systems"), "id", "name") useFor = plutora.listToDict( plutora.api("GET", "lookupfields/UsedForWorkItem"), "id", "value") envStatatus = plutora.listToDict( plutora.api("GET", "lookupfields/EnvironmentStatus"), "id", "value") layers = plutora.listToDict( plutora.api("GET", "lookupfields/StackLayer"), "id", "value") filterKey = "name" elif (objectType == "releases"): organizations = plutora.listToDict(plutora.api("GET", "organizations"), "id", "name") releaseTypes = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseType"), "id", "value") releaseStatusTypes = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseStatusType"), "id", "value") releaseRiskLevels = plutora.listToDict( plutora.api("GET", "lookupfields/ReleaseRiskLevel"), "id", "value") parentReleases = plutora.listToDict(objects, "id", "identifier") managers = plutora.listToDict(plutora.api("GET", "users"), "id", "userName") filterKey = "identifier" else: print "Invalid object type" exit(10) for object in objects: if ((filter in object[filterKey]) or (filter == "")): objectResponse = plutora.api("GET", objectType + "/" + object['id']) if (objectType == "systems"): row = { "name": objectResponse['name'], "vendor": objectResponse['vendor'], "status": objectResponse['status'], # TODO: handle hiearchy "organization": organizations[objectResponse['organizationId']], "description": objectResponse.get('description', '').encode( 'utf-8').strip(), # handle unicode characters # "isAllowEdit":objectResponse['isAllowEdit'], # "inMyOrganization":objectResponse['inMyOrganization'] } print "Writing " + object[filterKey] csvfileWriter.writerow(row) elif (objectType == "environments"): row = { "name": objectResponse['name'], "description": objectResponse.get('description', '').encode( 'utf-8').strip(), # handle unicode characters, "url": objectResponse.get('url', ''), "vendor": objectResponse['vendor'], "linkedSystem": systems[objectResponse['linkedSystemId']], "environmentMgr": objectResponse.get('environmentMgr', ''), "UsageWorkItem": useFor[objectResponse['usageWorkItemId']], "EnvironmentStatus": envStatatus[objectResponse['environmentStatusId']], "color": objectResponse['color'], "isSharedEnvironment": objectResponse['isSharedEnvironment'] } print "Writing " + object[filterKey] hosts = objectResponse['hosts'] if (len(hosts) == 0): csvfileWriter.writerow(row) for host in hosts: print '\t host: ' + host['name'] row['hostName'] = host['name'] layers = host['layers'] if (len(layers) == 0): csvfileWriter.writerow(row) for layer in layers: print '\t\t layer: ' + layer['stackLayer'] row['StackLayer'] = layer['stackLayer'] print '\t\t\t component: ' + layer['componentName'] row['componentName'] = layer['componentName'] print '\t\t\t\t version' # + layer['version'] or "" row['version'] = layer['version'] or "" csvfileWriter.writerow(row) elif (objectType == "releases"): row = { "identifier": objectResponse['identifier'], "name": objectResponse['name'], "summary": objectResponse.get('summary', '').encode( 'utf-8').strip(), # handle unicode characters, "ReleaseType": releaseTypes[objectResponse['releaseTypeId']], "location": objectResponse['location'], "ReleaseStatusType": releaseStatusTypes[objectResponse['releaseStatusTypeId']], "ReleaseRiskLevel": releaseRiskLevels[objectResponse['releaseRiskLevelId']], "implementationDate": objectResponse['implementationDate'], "displayColor": objectResponse['displayColor'], "organization": organizations[objectResponse['organizationId']], "Manager": managers.get(objectResponse['managerId']), "ParentRelease": parentReleases.get(objectResponse['parentReleaseId']), "plutoraReleaseType": objectResponse['plutoraReleaseType'], "releaseProjectType": objectResponse['releaseProjectType'] } print "Writing " + object[filterKey] csvfileWriter.writerow(row) csvfile.close()
# Python 2.7 # apiCaller.py # # Description: Command line tool to issue Plutora REST API Calls # # Usage: python apiCaller.py <verb> <path> # Example: python apiCaller.py GET systems # import plutora, sys, json print plutora.api(sys.argv[1], sys.argv[2])