Skip to content

Commit 093fc6f

Browse files
Merge branch 'dev' into troubleshooting-tweaks
2 parents c4a38ef + 2ba97ef commit 093fc6f

File tree

2 files changed

+60
-29
lines changed

2 files changed

+60
-29
lines changed

__tests__/api/BundlePush/BundlePusher.test.ts

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ describe("BundlePusher01", () => {
114114
lstatSpy = jest.spyOn(fs, "lstatSync").mockImplementation(() => ( IS_NOT_DIRECTORY ));
115115
cmciSpy = jest.spyOn(cmci, "getResource").mockImplementation(() => ({ response: { records: {} } }));
116116
consoleText = "";
117-
zosmfProfile = { host: "testhost", user: "testuser" };
118-
sshProfile = { host: "testhost", user: "testuser" };
117+
zosmfProfile = { host: "wibble", user: "user", password: "thisIsntReal" };
118+
sshProfile = { host: "wibble", user: "user", password: "thisIsntReal" };
119119
cicsProfile = undefined;
120120
});
121121
afterEach(() => {
@@ -226,15 +226,13 @@ describe("BundlePusher01", () => {
226226
expect(consoleText).not.toContain("WARNING: ssh profile");
227227
});
228228
it("should complain with mismatching zOSMF and CICS profile host names", async () => {
229-
cicsProfile = { host: "wibble", user: "testuser", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
229+
cicsProfile = { host: "different", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
230230

231231
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
232232
"PUSH operation completed");
233-
expect(consoleText).toContain("WARNING: cics profile --host value 'wibble' does not match zosmf value 'testhost'.");
233+
expect(consoleText).toContain("WARNING: cics profile --host value 'different' does not match zosmf value 'wibble'.");
234234
});
235235
it("should not complain with matching zOSMF and CICS profile host names", async () => {
236-
zosmfProfile = { host: "wibble", user: "user" };
237-
sshProfile = { host: "wibble", user: "user" };
238236
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
239237

240238
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
@@ -274,9 +272,38 @@ describe("BundlePusher01", () => {
274272
"PUSH operation completed");
275273
expect(consoleText).toContain("WARNING: cics profile --user value 'joe' does not match zosmf value 'fred'.");
276274
});
275+
it("should complain with mismatching zOSMF and SSH profile passwords", async () => {
276+
zosmfProfile = { host: "wibble", user: "fred", password: "fakeZosmfPassword" };
277+
sshProfile = { host: "wibble", user: "fred", password: "fakeSshPassword" };
278+
279+
await runPushTestWithError("__tests__/__resources__/ExampleBundle01", false,
280+
"Incompatible security credentials exist in the zosmf and ssh profiles.");
281+
282+
expect(consoleText).not.toContain("fakeZosmfPassword");
283+
expect(consoleText).not.toContain("fakeSshPassword");
284+
});
285+
it("should tolerate mismatching zOSMF and SSH credentials if SSH keys are used", async () => {
286+
zosmfProfile = { host: "wibble", user: "fred", password: "fakeZosmfPassword" };
287+
sshProfile = { host: "wibble", user: "fred", privateKey: "fakeSshKey" };
288+
289+
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
290+
"PUSH operation completed");
291+
292+
expect(consoleText).not.toContain("fakeZosmfPassword");
293+
expect(consoleText).not.toContain("fakeSshKey");
294+
});
295+
it("should complain with mismatching zOSMF and cics profile passwords", async () => {
296+
zosmfProfile = { host: "wibble", user: "fred", password: "fakePassword" };
297+
sshProfile = { host: "wibble", user: "fred", password: "fakePassword" };
298+
cicsProfile = { host: "wibble", user: "fred", password: "fakePassword2", cicsPlex: "12345678" };
299+
300+
await runPushTestWithError("__tests__/__resources__/ExampleBundle01", false,
301+
"Incompatible security credentials exist in the zosmf and cics profiles.");
302+
303+
expect(consoleText).not.toContain("fakePassword");
304+
expect(consoleText).not.toContain("fakePassword2");
305+
});
277306
it("should complain with mismatching cics-deploy and CICS plex names", async () => {
278-
zosmfProfile = { host: "wibble", user: "fred" };
279-
sshProfile = { host: "wibble", user: "fred" };
280307
cicsProfile = { host: "wibble", user: "fred", password: "thisIsntReal", cicsPlex: "wibble", regionName: "12345678" };
281308

282309
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
@@ -1025,8 +1052,6 @@ describe("BundlePusher01", () => {
10251052
expect(cmciSpy).toHaveBeenCalledTimes(0);
10261053
});
10271054
it("should cope with a NODEJSAPP in the bundle with a CICS profile specified", async () => {
1028-
zosmfProfile = { host: "wibble", user: "user" };
1029-
sshProfile = { host: "wibble", user: "user" };
10301055
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal" };
10311056
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
10321057
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I http://www.ibm.com/xmlns/prod/cics/bundle/NODEJSAPP"}] );
@@ -1046,8 +1071,6 @@ describe("BundlePusher01", () => {
10461071
expect(cmciSpy).toHaveBeenCalledTimes(1);
10471072
});
10481073
it("should query scope even with no NODEJSAPPs", async () => {
1049-
zosmfProfile = { host: "wibble", user: "user" };
1050-
sshProfile = { host: "wibble", user: "user" };
10511074
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678" };
10521075
readSpy = jest.spyOn(fs, "readFileSync").mockImplementation((data: string) => {
10531076
if (data.indexOf("cics.xml") > -1) {
@@ -1090,8 +1113,6 @@ describe("BundlePusher01", () => {
10901113
expect(cmciSpy).toHaveBeenCalledTimes(1);
10911114
});
10921115
it("should cope with a NODEJSAPP in the bundle with a CICS profile specified and --verbose", async () => {
1093-
zosmfProfile = { host: "wibble", user: "user" };
1094-
sshProfile = { host: "wibble", user: "user" };
10951116
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal" };
10961117
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
10971118
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I http://www.ibm.com/xmlns/prod/cics/bundle/NODEJSAPP"}] );
@@ -1121,8 +1142,6 @@ describe("BundlePusher01", () => {
11211142
expect(cmciSpy).toHaveBeenCalledTimes(1);
11221143
});
11231144
it("should generate diagnostics even if deploy fails", async () => {
1124-
zosmfProfile = { host: "wibble", user: "user" };
1125-
sshProfile = { host: "wibble", user: "user" };
11261145
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal" };
11271146
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
11281147
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2055I"}] );
@@ -1180,8 +1199,6 @@ describe("BundlePusher01", () => {
11801199
expect(cmciSpy).toHaveBeenCalledTimes(2);
11811200
});
11821201
it("should tolerate a Node.js diagnostics generation failure - region", async () => {
1183-
zosmfProfile = { host: "wibble", user: "user" };
1184-
sshProfile = { host: "wibble", user: "user" };
11851202
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
11861203
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
11871204
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I http://www.ibm.com/xmlns/prod/cics/bundle/NODEJSAPP"}] );
@@ -1202,8 +1219,6 @@ describe("BundlePusher01", () => {
12021219
expect(cmciSpy).toHaveBeenCalledTimes(1);
12031220
});
12041221
it("should tolerate a Node.js diagnostics generation failure - nodejsapp", async () => {
1205-
zosmfProfile = { host: "wibble", user: "user" };
1206-
sshProfile = { host: "wibble", user: "user" };
12071222
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
12081223
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
12091224
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I"}] );
@@ -1249,8 +1264,6 @@ describe("BundlePusher01", () => {
12491264
expect(cmciSpy).toHaveBeenCalledTimes(2);
12501265
});
12511266
it("should tolerate a Node.js diagnostics generation failure - nodejsapp empty", async () => {
1252-
zosmfProfile = { host: "wibble", user: "user" };
1253-
sshProfile = { host: "wibble", user: "user" };
12541267
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
12551268
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
12561269
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I"}] );
@@ -1296,8 +1309,6 @@ describe("BundlePusher01", () => {
12961309
expect(cmciSpy).toHaveBeenCalledTimes(2);
12971310
});
12981311
it("should generate Node.js diagnostics for 1 enabled NODEJSAPP", async () => {
1299-
zosmfProfile = { host: "wibble", user: "user" };
1300-
sshProfile = { host: "wibble", user: "user" };
13011312
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
13021313
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
13031314
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I"}] );
@@ -1355,8 +1366,6 @@ describe("BundlePusher01", () => {
13551366
expect(cmciSpy).toHaveBeenCalledTimes(2);
13561367
});
13571368
it("should generate Node.js diagnostics for 1 disabled NODEJSAPP", async () => {
1358-
zosmfProfile = { host: "wibble", user: "user" };
1359-
sshProfile = { host: "wibble", user: "user" };
13601369
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
13611370
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
13621371
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I"}] );
@@ -1414,11 +1423,9 @@ describe("BundlePusher01", () => {
14141423
expect(cmciSpy).toHaveBeenCalledTimes(2);
14151424
});
14161425
it("should generate Node.js diagnostics for 2 NODEJSAPPs", async () => {
1417-
zosmfProfile = { host: "wibble", user: "user" };
1418-
sshProfile = { host: "wibble", user: "user" };
1419-
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
14201426
submitSpy = jest.spyOn(SubmitJobs, "submitJclString").mockImplementation(() =>
14211427
[{ddName: "SYSTSPRT", stepName: "DFHDPLOY", data: "DFHRL2012I"}] );
1428+
cicsProfile = { host: "wibble", user: "user", password: "thisIsntReal", cicsPlex: "12345678", regionName: "12345678" };
14221429
readSpy = jest.spyOn(fs, "readFileSync").mockImplementation((data: string) => {
14231430
if (data.indexOf("cics.xml") > -1) {
14241431
return "<manifest xmlns=\"http://www.ibm.com/xmlns/prod/cics/bundle\">" +

src/api/BundlePush/BundlePusher.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,23 +209,47 @@ export class BundlePusher {
209209

210210
private validateProfiles(zosmfProfile: IProfile, sshProfile: IProfile, cicsProfile: IProfile) {
211211
// Do the required profiles share the same host name?
212+
let sameHostAndUser = true;
212213
if (zosmfProfile.host !== sshProfile.host) {
214+
sameHostAndUser = false;
213215
this.issueWarning("ssh profile --host value '" + sshProfile.host + "' does not match zosmf value '" + zosmfProfile.host + "'.");
214216
}
217+
215218
// Do the required profiles share the same user name?
216219
if (zosmfProfile.user.toUpperCase() !== sshProfile.user.toUpperCase()) {
220+
sameHostAndUser = false;
217221
this.issueWarning("ssh profile --user value '" + sshProfile.user + "' does not match zosmf value '" + zosmfProfile.user + "'.");
218222
}
219223

224+
// If the zoSMF user and host are the same then validate that the passwords are the same too.
225+
// It's possible, especially over a password change, that one profile may have been updated
226+
// and not the other. Attemps to use the wrong password could result in the account being revoked.
227+
if (sameHostAndUser) {
228+
if (sshProfile.password !== undefined) {
229+
if (zosmfProfile.password !== sshProfile.password) {
230+
throw new Error("Incompatible security credentials exist in the zosmf and ssh profiles.");
231+
}
232+
}
233+
}
234+
220235
// Is the optional CICS profile compatible?
221236
if (cicsProfile !== undefined) {
237+
sameHostAndUser = true;
222238
if (zosmfProfile.host !== cicsProfile.host) {
239+
sameHostAndUser = false;
223240
this.issueWarning("cics profile --host value '" + cicsProfile.host + "' does not match zosmf value '" + zosmfProfile.host + "'.");
224241
}
225242
if (zosmfProfile.user.toUpperCase() !== cicsProfile.user.toUpperCase()) {
243+
sameHostAndUser = false;
226244
this.issueWarning("cics profile --user value '" + cicsProfile.user + "' does not match zosmf value '" + zosmfProfile.user + "'.");
227245
}
228246

247+
if (sameHostAndUser) {
248+
if (zosmfProfile.password !== cicsProfile.password) {
249+
throw new Error("Incompatible security credentials exist in the zosmf and cics profiles.");
250+
}
251+
}
252+
229253
// Do the cics-plexes match?
230254
if (cicsProfile.cicsPlex !== undefined && this.params.arguments.cicsplex !== cicsProfile.cicsPlex) {
231255
this.issueWarning("cics profile --cics-plex value '" + cicsProfile.cicsPlex +

0 commit comments

Comments
 (0)