Skip to content

Commit a934cb6

Browse files
STRY56801912: Syncing public repo for GitLab Docker (#9)
1 parent 6a23b88 commit a934cb6

File tree

9 files changed

+414
-17
lines changed

9 files changed

+414
-17
lines changed

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,84 @@ This specifies the sonar project key.
173173

174174
```
175175

176+
**Example of get change for ServiceNow via commandline**
177+
```yaml
178+
179+
This custom step needs to be added at job level to get changeRequestNumber from ServiceNow instance with provided changeDetails to identify the change-request.
180+
181+
stages:
182+
- DevOpsGetChange
183+
184+
ServiceNow DevOps Get Change:
185+
stage: DevOpsGetChange
186+
image: servicenowdocker/sndevops:4.0.0
187+
script:
188+
- sndevopscli get change -p "{\"buildNumber\":${CHG_JOB_ID},\"stageName\":\"ServiceNow DevOps Change Step\",\"pipelineName\":\"GitlabDockerGetAndUpdateChange\"}"
189+
190+
-p: It stands for changeDetails. The change details to be used for identifying change request in ServiceNow instance. The change details is a JSON object surrounded by curly braces {} containing key-value pair separated by a comma ,. A key-value pair consists of a key and a value separated by a colon :. The keys supported in key-value pair are buildNumber, pipelineName, stageName
191+
192+
buildNumber: [mandatory]
193+
This specifies ID of the Job where we have created change request.
194+
195+
stageName: [mandatory]
196+
This specifies the Job name where we have created change request..
197+
198+
pipelineName: [mandatory]
199+
This specifies the pipeline name.
200+
201+
Outputs:
202+
sndevopschg.json file created with content: {
203+
"status": "SUCCESS",
204+
"changeRequestNumber": "CHGXXXXX"
205+
}
206+
207+
changeRequestNumber: Change Request Number found for the given change details
208+
status: To know the status of the Change Request GET.
209+
210+
```
211+
212+
**Example of update change for ServiceNow via commandline**
213+
```yaml
214+
215+
This custom step needs to be added at job level to Update change in ServiceNow instance for the changeRequestNumber provided as input along with changeRequestDetails.
216+
217+
stages:
218+
- DevOpsUpdateChangeStage
219+
220+
ServiceNow DevOps Update Change:
221+
stage: DevOpsUpdateChangeStage
222+
image: servicenowdocker/sndevops:4.0.0
223+
script:
224+
- sndevopscli update change -n 'CHGXXXXXX' -p "{\"short_description\":\"G Venkata12345 Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"XXXXX\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}"
225+
226+
-n [Not mandatory if we have sndevopschg.json in our pipeline yml]: It stands for changeRequestNumber. The change request number to identify a unique change request.
227+
Precedence of choosing changeRequestNumber:
228+
- changeRequestNumber mentioned in the pipeline yml
229+
- changeRequestNumber stored in sndevopschg.json.
230+
231+
-p : It stands for changeDetails. The change details to be used for Updating the change request information identified by the specified change request number with the key-value pairs. The change details is a JSON object surrounded by curly braces {} containing key-value pair separated by a comma ,. A key-value pair consists of a key and a value separated by a colon :. The keys supported in key-value pair are short_description, state, description, work_notes ..so on
232+
233+
OR
234+
- sndevopscli update change -p "{\"short_description\":\"Updated Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"XXXXXXXXXX\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}"
235+
236+
NOTE: State should be specified at last in case if you are update the state of change request.
237+
- sndevopscli update change -p "{\"short_description\":\"Updated Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"XXXXXXXXXX\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\","state":"3"}'
238+
239+
```
240+
241+
**Example to incorporate autoCloseChange feature for ServiceNow via commandline**
242+
```yaml
243+
244+
stages:
245+
- changeapproval
246+
247+
ServiceNow DevOps Change Step:
248+
stage: changeapproval
249+
image: servicenowdocker/sndevops:4.0.0
250+
script:
251+
- sndevopscli create change -p "{\"changeStepDetails\":{\"timeout\":3600,\"interval\":100},\"autoCloseChange\":true,\"attributes\":{\"short_description\":\"G Venkata Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"xxxxxxxx\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}}"
252+
253+
autoCloseChange: [optional] : Boolean value
254+
255+
```
256+

gitlab-ci.yml

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
image: servicenowdocker/sndevops:3.1.0
1+
image: servicenowdocker/sndevops:4.0.0
22
stages:
33
- pre-build
44
- build
55
- sonar
66
- changeapproval
7+
- getchange
8+
- updatechange
79
- deploy
810

911

@@ -26,9 +28,35 @@ ServiceNow DevOps SonarScan Results:
2628

2729
ServiceNow DevOps Change Step:
2830
stage: changeapproval
31+
variables:
32+
CHG_JOB_ID: $CI_JOB_ID
2933
script:
30-
- sndevopscli create change -p '{"changeStepDetails":{"timeout":3600,"interval":100},"attributes":{"short_description":"Automated Software Deployment","description":"Automated Software Deployment.","assignment_group":"xxxxxx","implementation_plan":"Software update is tested and results can be found in Test Summaries Tab.","backout_plan":"When software fails in production, the previous software release will be re-deployed.","test_plan":"Testing if the software was successfully deployed or not"}}'
31-
34+
- echo "CHG_JOB_ID=$CHG_JOB_ID" >> generated_job_id.env
35+
- sndevopscli create change -p "{\"changeStepDetails\":{\"timeout\":3600,\"interval\":100},\"autoCloseChange\":true,\"attributes\":{\"short_description\":\"G Venkata Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"a715cd759f2002002920bde8132e7018\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}}"
36+
- sndevopscli get change #If we are placing get change cli command in the same job where we are creating change then no need to mention the changeDetails.
37+
artifacts:
38+
paths:
39+
- generated_job_id.env
40+
41+
DevOps Get Change:
42+
stage: getchange
43+
script:
44+
- source generated_job_id.env
45+
- sndevopscli get change -p "{\"buildNumber\":${CHG_JOB_ID},\"stageName\":\"ServiceNow DevOps Change Step\",\"pipelineName\":\"SmrutiTestDemoProject\"}"
46+
artifacts:
47+
paths:
48+
- sndevopschg.json
49+
dependencies:
50+
- ServiceNow DevOps Change Step
51+
52+
DevOps Update Change:
53+
stage: updatechange
54+
script:
55+
#- sndevopscli update change -n 'CHGXXXX' -p "{\"short_description\":\"Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"xxxxxxx\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}"
56+
- sndevopscli update change -p "{\"short_description\":\"Updated Automated Software Deployment\",\"description\":\"Automated Software Deployment.\",\"assignment_group\":\"xxxxxxx\",\"implementation_plan\":\"Software update is tested and results can be found in Test Summaries Tab.\",\"backout_plan\":\"When software fails in production, the previous software release will be re-deployed.\",\"test_plan\":\"Testing if the software was successfully deployed or not\"}"
57+
dependencies:
58+
- DevOps Get Change
59+
3260
Deploy Job:
3361
stage: deploy
3462
script:

src/api/change/getChange.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
const SnDevopsApi = require('../base/sndevopsApi.js')
2+
const API_GET_CHANGE_PATH = 'api/sn_devops/devops/orchestration/changeInfo';
3+
const axios = require('axios');
4+
const BaseEnv = require('../../common/baseEnv.js');
5+
const fs = require('fs');
6+
7+
class GetChangeManager extends SnDevopsApi {
8+
9+
/**
10+
*
11+
* @param {*} changeDetails :
12+
* {
13+
"build_number": "21",
14+
"pipeline_name": "CI_Pipeline",
15+
"stage_name": "Create_Change"
16+
}
17+
*/
18+
async getChange(changeDetails) {
19+
let status = "NOT-STARTED";
20+
let buildNumber;
21+
let stageName;
22+
let pipelineName;
23+
let url;
24+
let httpHeaders;
25+
let response;
26+
let outputObject = {};
27+
let changeDetailsParsed;
28+
let gitLabProjectId;
29+
30+
try {
31+
outputObject.status = status;
32+
33+
//changeDetails are optional
34+
if(changeDetails) {
35+
try {
36+
changeDetailsParsed = JSON.parse(changeDetails);
37+
buildNumber = changeDetailsParsed.buildNumber;
38+
stageName = changeDetailsParsed.stageName;
39+
pipelineName = changeDetailsParsed.pipelineName;
40+
} catch (e) {
41+
throw new Error("Change request details cannot be retrieved because changeDetails were not parsed.");
42+
}
43+
}
44+
45+
try {
46+
buildNumber = buildNumber || BaseEnv.CI_JOB_ID;
47+
stageName = stageName || BaseEnv.CI_JOB_NAME;
48+
pipelineName = pipelineName || BaseEnv.CI_PROJECT_TITLE;
49+
gitLabProjectId = BaseEnv.CI_PROJECT_ID;
50+
51+
console.log("buildNumber " + buildNumber + " stageName = " + stageName + "pipelineName = " + pipelineName);
52+
53+
url = new URL(API_GET_CHANGE_PATH, this.url);
54+
url.searchParams.append("buildNumber", buildNumber);
55+
url.searchParams.append("stageName", stageName);
56+
url.searchParams.append("pipelineName", pipelineName);
57+
url.searchParams.append("toolId", this.toolId);
58+
url.searchParams.append("pipelineId", gitLabProjectId);
59+
console.log("Get change API = " + url.toString());
60+
61+
httpHeaders = { headers: this._getAuthHeaderWithToken() };
62+
response = await axios.get(url.toString(), httpHeaders);
63+
console.log("[ServiceNow DevOps], Receiving response for Get Change, Response : " + JSON.stringify(response.data));
64+
65+
66+
if (response.data && response.data.result) {
67+
status = "SUCCESS";
68+
console.log('\n \x1b[1m\x1b[32m' + "changeRequestNumber => " + response.data.result.number + '\x1b[0m\x1b[0m');
69+
outputObject.changeRequestNumber = response.data.result.number;
70+
outputObject.status = status;
71+
this._writeToOutputFile(outputObject);
72+
} else {
73+
status = "NOT SUCCESSFUL";
74+
throw new Error('No response from ServiceNow. Please check ServiceNow logs for more details.');
75+
}
76+
77+
} catch(err){
78+
status = "NOT SUCCESSFUL";
79+
if (!err.response) {
80+
throw new Error('No response from ServiceNow. Please check ServiceNow logs for more details.');
81+
} else {
82+
status = "FAILURE";
83+
if (err.message.includes('ECONNREFUSED') || err.message.includes('ENOTFOUND')) {
84+
throw new Error('Change request details cannot be retrieved because the ServiceNow Instance URL is invalid. Enter the correct URL and try again.');
85+
}
86+
87+
else if (err.message.includes('401')) {
88+
throw new Error('The SNOW_TOKEN and SNOW_TOOLID are incorrect. Verify that the GitLab project level variables are configured.');
89+
}
90+
91+
else if (err.message.includes('405')) {
92+
throw new Error('Change request details cannot be retrieved because response Code from ServiceNow is 405. Please check ServiceNow logs for more details.');
93+
}
94+
95+
else if (err.response.status == 500) {
96+
throw new Error('Change request details cannot be retrieved because response code from ServiceNow is 500. Please check ServiceNow logs for more details.')
97+
}
98+
99+
else if (err.response.status == 400 || err.response.status == 404) {
100+
let errMsg = 'ServiceNow DevOps Get Change is not Successful.';
101+
let errMsgSuffix = ' Please provide valid inputs.';
102+
let responseData = err.response.data;
103+
if (responseData && responseData.result && responseData.result.errorMessage) {
104+
errMsg = errMsg + responseData.result.errorMessage + errMsgSuffix;
105+
throw new Error(errMsg);
106+
}
107+
else if (responseData && responseData.result && responseData.result.details && responseData.result.details.errors) {
108+
let errors = responseData.result.details.errors;
109+
for (var index in errors) {
110+
errMsg = errMsg + errors[index].message + errMsgSuffix;
111+
}
112+
throw new Error(errMsg);
113+
}
114+
}
115+
116+
else {
117+
throw new Error('Change request details cannot be retrieved. Please check ServiceNow logs for more details.');
118+
}
119+
}
120+
121+
}
122+
} catch (err) {
123+
console.error('\n \x1b[1m\x1b[31m' + err.message + '\x1b[0m\x1b[0m');
124+
outputObject.status = status;
125+
this._writeToOutputFile(outputObject);
126+
process.exit(1);
127+
}
128+
}
129+
130+
_writeToOutputFile(outputObject) {
131+
// Stringify the JSON object
132+
const outputObjectString = JSON.stringify(outputObject, null, 2);
133+
// Write the JSON string to the sndevopschg.json file
134+
fs.writeFileSync('sndevopschg.json', outputObjectString);
135+
// Log message to confirm the file creation
136+
console.log('sndevopschg.json file created with content:', outputObjectString);
137+
}
138+
}
139+
140+
module.exports = GetChangeManager;

0 commit comments

Comments
 (0)