3
3
import json
4
4
import requests
5
5
import logging
6
+ import urllib .parse
6
7
7
8
API_NAMESPACE = 409723
8
9
env_file_path = "/meta/env_vars_to_export"
9
10
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
+
10
27
def getBaseUrl (instance ):
11
28
baseUrl = "%s/api" % (instance );
12
29
logging .debug ("baseUrl: " + baseUrl )
@@ -41,16 +58,9 @@ def processCreateChangeRequestResponse(response):
41
58
logging .info (f" Change Request sys_id: { CR_SYSID } " )
42
59
logging .debug ( " Change Request full answer:\n " + FULL_JSON )
43
60
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 )
54
64
55
65
#
56
66
# Call SNow REST API to create a new Change Request
@@ -80,6 +90,79 @@ def createChangeRequest(user, password, baseUrl, data):
80
90
auth = (user , password ))
81
91
processCreateChangeRequestResponse (response = resp )
82
92
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
+
83
166
def processModifyChangeRequestResponse (response , action ):
84
167
85
168
logging .debug ("Processing answer from CR %s REST call" % (action ))
@@ -97,24 +180,17 @@ def processModifyChangeRequestResponse(response, action):
97
180
FULL_JSON = json .dumps (data , indent = 2 )
98
181
99
182
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 )
102
185
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 )
105
188
else :
106
189
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 " )
112
190
113
- env_file .close ()
191
+ exportVariable ("CR_NUMBER" , CR_NUMBER )
192
+ exportVariable ("CR_SYSID" , CR_SYSID )
114
193
115
- json_file = open ("/codefresh/volume/servicenow-cr-close.json" , "w" )
116
- json_file .write (FULL_JSON )
117
- json_file .close ()
118
194
119
195
# Call SNow REST API to close a CR
120
196
# Fields required are pasted in the data
@@ -196,6 +272,14 @@ def checkToken(token):
196
272
logging .error ("FATAL: TOKEN is not defined." )
197
273
sys .exit (1 )
198
274
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
+
199
283
def checkConflictPolicy (policy ):
200
284
logging .debug ("Entering checkConflictPolicy: " )
201
285
logging .debug (" CR_CONFLICT_POLICY: %s" % (policy ))
@@ -214,6 +298,7 @@ def main():
214
298
PASSWORD = os .getenv ('SN_PASSWORD' )
215
299
INSTANCE = os .getenv ('SN_INSTANCE' )
216
300
DATA = os .getenv ('CR_DATA' )
301
+ STD_NAME = os .getenv ('STD_CR_TEMPLATE' )
217
302
DEBUG = True if os .getenv ('DEBUG' , "false" ).lower () == "true" else False
218
303
TOKEN = os .getenv ('TOKEN' )
219
304
POLICY = os .getenv ('CR_CONFLICT_POLICY' )
@@ -230,17 +315,26 @@ def main():
230
315
logging .debug (f" DATA: { DATA } " )
231
316
logging .debug (" SYSID: %s" % (os .getenv ('CR_SYSID' )))
232
317
318
+ checkUser (USER )
233
319
234
320
if ACTION == "createcr" :
235
321
# Used only later in the callback but eant to check for error early
236
322
checkToken (TOKEN )
237
323
checkConflictPolicy (POLICY )
238
324
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
+ )
244
338
elif ACTION == "callback" :
245
339
callback (user = USER ,
246
340
password = PASSWORD ,
0 commit comments