Skip to content

Commit

Permalink
#402: Fixing python script
Browse files Browse the repository at this point in the history
Adding code for modifying a CR as well
  • Loading branch information
lrochette committed Oct 11, 2021
1 parent 36d4e2e commit ba7283d
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 39 deletions.
102 changes: 76 additions & 26 deletions incubating/service-now/lib/snow.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def processCallbackResponse(response):
print("Callback creation successful")


def processChangeRequestResponse(response):
def processCreateChangeRequestResponse(response):

print("Processing answer from CR creation REST call")
print("Change Request returned code %s" % (response.status_code))
Expand All @@ -45,7 +45,7 @@ def processChangeRequestResponse(response):
if os.path.exists(env_file_path):
env_file = open(env_file_path, "a")
env_file.write(f"CR_NUMBER={CR_NUMBER}\n")
env_file.write(f"CR_SYS_ID={CR_SYSID}\n")
env_file.write(f"CR_SYSID={CR_SYSID}\n")
env_file.write("CR_FULL_JSON=/codefresh/volume/servicenow-cr.json\n")
env_file.close()

Expand All @@ -56,11 +56,11 @@ def processChangeRequestResponse(response):
#
# Call SNow REST API to create a new Change Request
# Fields required are pasted in the data
def createChangeRequest(user, password, baseUrl, title, data, description):
def createChangeRequest(user, password, baseUrl, data):

if DEBUG:
print("Entering createChangeRequest:")
print("Body: " + data)
print(f"Data: {data}")

if (bool(data)):
crBody=json.loads(data)
Expand All @@ -82,49 +82,77 @@ def createChangeRequest(user, password, baseUrl, title, data, description):
json = crBody,
headers = {"content-type":"application/json"},
auth=(user, password))
processChangeRequestResponse(response=resp)
processCreateChangeRequestResponse(response=resp)

def processCloseChangeRequestResponse(response):
def processModifyChangeRequestResponse(response, action):

print("Processing answer from CR closing REST call")
print("Processing answer from CR %s REST call" %(action))
print("Close Change Request returned code %s" % (response.status_code))
if (response.status_code != 200 and response.status_code != 201):
print("Close Change Request creation failed with code %s" % (response.status_code))
print("%s Change Request creation failed with code %s" % (action, response.status_code))
print("Error: " + response.text)
return response.status_code

print("Close Change Request creation successful")
print("%s Change Request creation successful" %(action))
data=response.json() # json.loads(response.text)

FULL_JSON=json.dumps(data, indent=2)

if (action == "close" ):
jsonVar="CR_CLOSE_FULL_JSON"
jsonFileName="/codefresh/volume/servicenow-cr-close.json"
elif (action == "update" ):
jsonVar="CR_UPDATE_FULL_JSON"
jsonFileName="/codefresh/volume/servicenow-cr-update.json"
else:
print("ERROR: action unknonw. Should not be here. Error should have been caught earlier")
if os.path.exists(env_file_path):
env_file = open(env_file_path, "a")
env_file.write("CR_CLOSE_FULL_JSON=/codefresh/volume/servicenow-cr-close.json\n")
env_file.write(f"{jsonVar}=/codefresh/volume/servicenow-cr-close.json\n")
env_file.close()

json_file=open("/codefresh/volume/servicenow-cr-close.json", "w")
json_file.write(FULL_JSON)
json_file.close()

# Call SNow REST API to close a CR
# Fields required are pasted in the data
def closeChangeRequest(user, password, baseUrl, sysid, code):
def closeChangeRequest(user, password, baseUrl, sysid, code, notes, data):
if DEBUG:
print("Entering closeChangeRequest:")
print("Body: " + data)
print(f"DATA: {data}")
if (bool(data)):
crBody=json.loads(data)
else:
crBody= {}
crBody["state"] = 3
crBody["close_code"] = code
crBody["close_notes"] = notes
url="%s/now/table/change_request/%s" % (baseUrl, sysid)
resp=requests.patch(url,
json = crBody,
headers = {"content-type":"application/json"},
auth=(user, password))
processCloseChangeRequestResponse(response=resp)
processModifyChangeRequestResponse(response=resp, action="close")

# Call SNow REST API to update a CR
# Fields required are pasted in the data
def updateChangeRequest(user, password, baseUrl, sysid, data):
if DEBUG:
print("Entering closeChangeRequest:")
print(f"DATA: {data}")
if (bool(data)):
crBody=json.loads(data)
else:
crBody= {}
print("WARNING: CR_DATA is empty. What are you updating exactly?")

url="%s/now/table/change_request/%s" % (baseUrl, sysid)
resp=requests.patch(url,
json = crBody,
headers = {"content-type":"application/json"},
auth=(user, password))
processModifyChangeRequestResponse(response=resp, action="update")
# Use rest API to call scripted REST API to start a flow that will wait for CR
# to be approved or rejected, then callback Codefreh to approve/deny pipeline
#
Expand Down Expand Up @@ -153,26 +181,31 @@ def callback(user, password, baseUrl, number, cf_build_id, token):
auth=(user, password))
processCallbackResponse(response=resp)

def checkSysid(sysid):
if DEBUG:
print("Entering checkSysid: ")
print(" CR_SYSID: %s" % (sysid))

if ( sysid == None ):
sys.exit("FATAL: CR_SYS_ID is not defined.")


def main():
global DEBUG

ACTION = os.getenv('action', 'createCR').lower()
ACTION = os.getenv('CR_ACTION', 'createCR').lower()
USER = os.getenv('SN_USER')
PASSWORD = os.getenv('SN_PASSWORD')
INSTANCE = os.getenv('SN_INSTANCE')
DATA = os.getenv('data')
DATA = os.getenv('CR_DATA')
#DEBUG = True if os.getenv('debug', "false").lower == "true" else False

if ACTION == "createcr":
TITLE = os.getenv('title', 'Change Request created by Codefresh')
DESCRIPTION = os.getenv('description', '')

createChangeRequest(user=USER,
password=PASSWORD,
baseUrl=getBaseUrl(instance=INSTANCE),
title=TITLE,
data=DATA,
description=DESCRIPTION)
data=DATA)
elif ACTION == "callback":
callback(user=USER,
password=PASSWORD,
Expand All @@ -182,17 +215,34 @@ def main():
cf_build_id=os.getenv('CF_BUILD_ID')
)
elif ACTION == "closecr":
CR_SYS_ID= os.getenv('CR_SYS_ID')
CODE= "successful" if os.getenv('closeCode') == "success" else "unsuccessful"
CR_SYSID= os.getenv('CR_SYSID')
CODE=os.getenv('CR_CLOSE_CODE')
NOTES=os.getenv('CR_CLOSE_NOTES')

checkSysid(CR_SYSID)

closeChangeRequest(
user=USER,
password=PASSWORD,
baseUrl=getBaseUrl(instance=INSTANCE),
number=os.getenv('CR_SYSID'),
code=CODE
sysid=os.getenv('CR_SYSID'),
code=CODE,
notes=NOTES,
data=DATA
)
elif ACTION == "updatecr":
CR_SYSID= os.getenv('CR_SYSID')
checkSysid(CR_SYSID)

updateChangeRequest(
user=USER,
password=PASSWORD,
baseUrl=getBaseUrl(instance=INSTANCE),
sysid=os.getenv('CR_SYSID'),
data=DATA
)
else:
sys.exit(f"Unknown action: {ACTION}")
sys.exit(f"FATAL: Unknown action: {ACTION}. Allowed values are createCR, closeCR or updateCR.")


if __name__ == "__main__":
Expand Down
44 changes: 31 additions & 13 deletions incubating/service-now/step.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '1.0'
metadata:
name: laurent-cf/service-now
version: 1.1.0
isPublic: true
isPublic: false
description: Integration with ServiceNow Change Management
sources:
- https://github.com/codefresh-io/steps/tree/master/incubating/service-now
Expand All @@ -13,7 +13,7 @@ metadata:
- email: laurent.rochette@codefresh.io
categories:
- utilities
official: true
official: false
tags: []
icon:
type: svg
Expand All @@ -27,11 +27,11 @@ metadata:
type: service-now
stage: deploy
arguments:
action: createCR
CR_ACTION: createCR
SN_INSTANCE: https://instance.service-now.com
SN_USER: ${{SN_USER}}
SN_PASSWORD: ${{SN_PASSWORD}}
data: '{"short_description":"This is a Change Request created by Codefresh","description":"long description for Codefresh build ${{CF_BUILD_ID}}","justification":"because our app is awesome"}'
CR_DATA: '{"short_description":"This is a Change Request created by Codefresh","description":"long description for Codefresh build ${{CF_BUILD_ID}}","justification":"because our app is awesome"}'
wait:
stage: deploy
title: Waiting for the Change Request to be approved
Expand All @@ -45,12 +45,13 @@ metadata:
type: service-now
stage: cleaning
arguments:
action: closeCR
CR_ACTION: closeCR
SN_INSTANCE: https://instance.service-now.com
SN_USER: ${{SN_USER}}
SN_PASSWORD: ${{SN_PASSWORD}}
close_code: ${{workflow.status}}
data: '{"close_code":"success", "close_note":"Closed automatically by Codefresh build ${{CF_BUILD_ID}}"}'
CR_CLOSE_CODE: successful
CR_CLOSE_NOTES: "CR closed by Codefresh build ${{CF_BUILD_ID}}"
CR_DATA: '{"close_note":"Closed automatically by Codefresh build ${{CF_BUILD_ID}}"}'

spec:
arguments: |-
Expand Down Expand Up @@ -98,9 +99,14 @@ spec:
},
"CR_CLOSE_CODE": {
"type": "string",
"description": "Close code for the closeCR action: successful or unsuccessful",
"description": "Close code for the closeCR action: successful, successful_issues or unsuccessful",
"default": "successful"
},
"CR_CLOSE_NOTES": {
"type": "string",
"description": "Close notes for the closeCR action: successful, successful_issues or unsuccessful",
"default": "Closed by Codefresh"
},
"DEBUG": {
"type": "string",
"default": "false",
Expand All @@ -117,12 +123,12 @@ spec:
"patterns": [],
"required": [
"CR_NUMBER",
"CR_SYS_ID"
"CR_SYSID"
],
"properties": {
"CR_SYS_ID": {
"CR_SYSID": {
"type": "string",
"description": "The sys_id of the CR created"
"description": "The sysid of the CR created"
},
"CR_NUMBER": {
"type": "string",
Expand All @@ -132,7 +138,7 @@ spec:
}
stepsTemplate: |-
[[ if .Arguments.CR_ACTION == "closeCR" ]]
createCR:
closeCR:
name: Close a ServiceNow Change Request
title: Use REST API to close the CR
#image: 'quay.io/codefreshplugins/service-now:1.1.0'
Expand All @@ -143,6 +149,18 @@ spec:
- '[[ $key ]]=[[ $val ]]'
[[- end ]]
[[ end ]]
[[ if .Arguments.CR_ACTION == "updateCR" ]]
closeCR:
name: Update a ServiceNow Change Request
title: Use REST API to close the CR
#image: 'quay.io/codefreshplugins/service-now:1.1.0'
image: lrochette/service-now:1.1.0
environment:
- CR_ACTION=updateCR
[[ range $key, $val := .Arguments ]]
- '[[ $key ]]=[[ $val ]]'
[[- end ]]
[[ end ]]
[[ if .Arguments.CR_ACTION == "createCR" ]]
createCR:
name: Create a ServiceNow Change Request
Expand All @@ -160,7 +178,7 @@ spec:
commands:
- |
codefresh create annotation workflow ${{CF_BUILD_ID}} CR_NUMBER=${{CR_NUMBER}}
export createAnnotation_CF_OUTPUT_URL='[[.Arguments.SN_INSTANCE]]/nav_to.do?uri=/change_request.do?sys_id=${{CR_SYS_ID}}'
export createAnnotation_CF_OUTPUT_URL='[[.Arguments.SN_INSTANCE]]/nav_to.do?uri=/change_request.do?sys_id=${{CR_SYSID}}'
# echo $createAnnotation_CF_OUTPUT_URL
# cf_export createAnnotation_CF_OUTPUT_URL
callback:
Expand Down

0 comments on commit ba7283d

Please sign in to comment.