33import json
44import requests
55import logging
6+ import urllib .parse
67
78API_NAMESPACE = 409723
89env_file_path = "/meta/env_vars_to_export"
910
11+ def exportVariable (name , value ):
12+ if os .path .exists (env_file_path ):
13+ file = open (env_file_path , "a" )
14+ else :
15+ file = open ("/tmp/env_vars_to_export" , "a" )
16+ file .write (f"{ name } ={ value } \n " )
17+ file .close ()
18+
19+ def exportJson (name , json ):
20+ if os .path .exists (env_file_path ):
21+ json_file = open ("/codefresh/volume/%s" % (name ), "a" )
22+ else :
23+ json_file = open ("/tmp/%s" % (name ), "a" )
24+ json_file .write (json )
25+ json_file .close ()
26+
1027def getBaseUrl (instance ):
1128 baseUrl = "%s/api" % (instance );
1229 logging .debug ("baseUrl: " + baseUrl )
@@ -41,16 +58,9 @@ def processCreateChangeRequestResponse(response):
4158 logging .info (f" Change Request sys_id: { CR_SYSID } " )
4259 logging .debug ( " Change Request full answer:\n " + FULL_JSON )
4360
44- if os .path .exists (env_file_path ):
45- env_file = open (env_file_path , "a" )
46- env_file .write (f"CR_NUMBER={ CR_NUMBER } \n " )
47- env_file .write (f"CR_SYSID={ CR_SYSID } \n " )
48- env_file .write ("CR_FULL_JSON=/codefresh/volume/servicenow-cr.json\n " )
49- env_file .close ()
50-
51- json_file = open ("/codefresh/volume/servicenow-cr.json" , "w" )
52- json_file .write (FULL_JSON )
53- json_file .close ()
61+ exportVariable ("CR_NUMBER" , CR_NUMBER )
62+ exportVariable ("CR_SYSID" , CR_SYSID )
63+ exportVariable ("CR_CREATE_JSON" , FULL_JSON )
5464
5565#
5666# Call SNow REST API to create a new Change Request
@@ -80,6 +90,79 @@ def createChangeRequest(user, password, baseUrl, data):
8090 auth = (user , password ))
8191 processCreateChangeRequestResponse (response = resp )
8292
93+ def processSearchStandardTemplateResponse (name , response ):
94+ logging .info ("Processing answer from Standard Template search" )
95+ logging .debug ("Template search returned code %s" % (response .status_code ))
96+ if (response .status_code != 200 and response .status_code != 201 ):
97+ logging .critical ("Standard Change Template for '%s' errored out with code %s" , name , response .status_code )
98+ logging .critical ("%s" + response .text )
99+ sys .exit (response .status_code )
100+ data = response .json ()
101+ logging .debug ("Full JSON answer: %s" , data )
102+
103+ if len (data ["result" ]) == 0 :
104+ logging .critical ("Standard Change Template '%s' was not found" , name )
105+ sys .exit (1 )
106+
107+ logging .info ("Standard template search successful" )
108+ STD_SYSID = data ["result" ][0 ]["sys_id" ]
109+ return STD_SYSID
110+
111+ def processCreateStandardChangeRequestResponse (response ):
112+ logging .info ("Processing answer from standard CR creation REST call" )
113+ logging .debug ("Change Request returned code %s" % (response .status_code ))
114+ if (response .status_code != 200 and response .status_code != 201 ):
115+ logging .critical ("Change Request creation failed with code %s" , response .status_code )
116+ logging .critical ("%s" , response .text )
117+ sys .exit (response .status_code )
118+
119+ logging .info ("Change Request creation successful" )
120+ data = response .json ()
121+ FULL_JSON = json .dumps (data , indent = 2 )
122+ CR_NUMBER = data ["result" ]["number" ]["value" ]
123+ CR_SYSID = data ["result" ]["sys_id" ]["value" ]
124+ exportVariable ("CR_NUMBER" , CR_NUMBER )
125+ exportVariable ("CR_SYSID" , CR_SYSID )
126+ exportVariable ("CR_CREATE_JSON" , FULL_JSON )
127+ return CR_NUMBER
128+
129+ # Call SNow REST API to create a new Standard Change Request
130+ # Fields required are pasted in the data
131+ def createStandardChangeRequest (user , password , baseUrl , data , standardName ):
132+ logging .info ("Creating a new Standard Change Request using '%s' template" , standardName )
133+ encodedName = urllib .parse .quote_plus (standardName )
134+
135+ url = "%s/now/table/std_change_record_producer?sysparm_query=sys_name=%s" % (baseUrl , encodedName )
136+
137+ logging .debug ("Standard Change URL %s:" ,url )
138+ resp = requests .get (url ,
139+ headers = {"content-type" :"application/json" },
140+ auth = (user , password ))
141+ sysid = processSearchStandardTemplateResponse (name = standardName , response = resp )
142+ logging .info ("Template found: %s" , sysid )
143+
144+ if (bool (data )):
145+ crBody = json .loads (data )
146+ logging .debug ("Data: %s" , data )
147+ else :
148+ crBody = {}
149+ logging .debug (" Data: None" )
150+ crBody ["cf_build_id" ] = os .getenv ('CF_BUILD_ID' )
151+
152+
153+ url = "%s/sn_chg_rest/change/standard/%s" % (baseUrl , sysid )
154+
155+ logging .debug ("URL %s:" ,url )
156+ logging .debug ("User: %s" , user )
157+ logging .debug ("Body: %s" , crBody )
158+
159+ resp = requests .post (url ,
160+ json = crBody ,
161+ headers = {"content-type" :"application/json" },
162+ auth = (user , password ))
163+ return processCreateStandardChangeRequestResponse (response = resp )
164+
165+
83166def processModifyChangeRequestResponse (response , action ):
84167
85168 logging .debug ("Processing answer from CR %s REST call" % (action ))
@@ -97,24 +180,17 @@ def processModifyChangeRequestResponse(response, action):
97180 FULL_JSON = json .dumps (data , indent = 2 )
98181
99182 if (action == "close" ):
100- jsonVar = "CR_CLOSE_FULL_JSON"
101- jsonFileName = "/codefresh/volume/ servicenow-cr-close.json"
183+ exportVariable ( "CR_CLOSE_FULL_JSON" , "/codefresh/volume/servicenow-cr-close.json" )
184+ exportJson ( " servicenow-cr-close.json", FULL_JSON )
102185 elif (action == "update" ):
103- jsonVar = "CR_UPDATE_FULL_JSON"
104- jsonFileName = "/codefresh/volume/ servicenow-cr-update.json"
186+ exportVariable ( "CR_UPDATE_FULL_JSON" , "/codefresh/volume/servicenow-cr-update.json" )
187+ exportJson ( " servicenow-cr-update.json", FULL_JSON )
105188 else :
106189 print ("ERROR: action unknown. Should not be here. Error should have been caught earlier" )
107- if os .path .exists (env_file_path ):
108- env_file = open (env_file_path , "a" )
109- env_file .write (f"{ jsonVar } =/codefresh/volume/servicenow-cr-close.json\n " )
110- env_file .write (f"CR_NUMBER={ CR_NUMBER } \n " )
111- env_file .write (f"CR_SYSID={ CR_SYSID } \n " )
112190
113- env_file .close ()
191+ exportVariable ("CR_NUMBER" , CR_NUMBER )
192+ exportVariable ("CR_SYSID" , CR_SYSID )
114193
115- json_file = open ("/codefresh/volume/servicenow-cr-close.json" , "w" )
116- json_file .write (FULL_JSON )
117- json_file .close ()
118194
119195# Call SNow REST API to close a CR
120196# Fields required are pasted in the data
@@ -196,6 +272,14 @@ def checkToken(token):
196272 logging .error ("FATAL: TOKEN is not defined." )
197273 sys .exit (1 )
198274
275+ def checkUser (username ):
276+ logging .debug ("Entering checkUser: " )
277+ logging .debug (" CR_USER: %s" % (username ))
278+
279+ if ( username == None ):
280+ logging .error ("FATAL: CR_USER is not defined." )
281+ sys .exit (1 )
282+
199283def checkConflictPolicy (policy ):
200284 logging .debug ("Entering checkConflictPolicy: " )
201285 logging .debug (" CR_CONFLICT_POLICY: %s" % (policy ))
@@ -214,6 +298,7 @@ def main():
214298 PASSWORD = os .getenv ('SN_PASSWORD' )
215299 INSTANCE = os .getenv ('SN_INSTANCE' )
216300 DATA = os .getenv ('CR_DATA' )
301+ STD_NAME = os .getenv ('STD_CR_TEMPLATE' )
217302 DEBUG = True if os .getenv ('DEBUG' , "false" ).lower () == "true" else False
218303 TOKEN = os .getenv ('TOKEN' )
219304 POLICY = os .getenv ('CR_CONFLICT_POLICY' )
@@ -230,17 +315,26 @@ def main():
230315 logging .debug (f" DATA: { DATA } " )
231316 logging .debug (" SYSID: %s" % (os .getenv ('CR_SYSID' )))
232317
318+ checkUser (USER )
233319
234320 if ACTION == "createcr" :
235321 # Used only later in the callback but eant to check for error early
236322 checkToken (TOKEN )
237323 checkConflictPolicy (POLICY )
238324
239- createChangeRequest (user = USER ,
240- password = PASSWORD ,
241- baseUrl = getBaseUrl (instance = INSTANCE ),
242- data = DATA
243- )
325+ if STD_NAME :
326+ cr_number = createStandardChangeRequest (user = USER ,
327+ standardName = STD_NAME ,
328+ password = PASSWORD ,
329+ baseUrl = getBaseUrl (instance = INSTANCE ),
330+ data = DATA
331+ )
332+ else :
333+ createChangeRequest (user = USER ,
334+ password = PASSWORD ,
335+ baseUrl = getBaseUrl (instance = INSTANCE ),
336+ data = DATA
337+ )
244338 elif ACTION == "callback" :
245339 callback (user = USER ,
246340 password = PASSWORD ,
0 commit comments