Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to the Zowe Installer will be documented in this file.

## `3.4.0`

- Enhancement: Command `zwe validate` contains subcommands which can be used to validate a Zowe instance in advance of running it.

## `3.3.0`

- Bugfix: YAML lookup for HA instances within "haInstances" was not working when HA instance names were uppercase. Now, the lookup is case insensitive to allow for any casing of HA instance names. [#4370](https://github.com/zowe/zowe-install-packaging/pull/4370)
Expand Down
1 change: 0 additions & 1 deletion bin/commands/config/validate/.help
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Runs schema validation upon given zowe yaml configuration files.
This command can be used to prove that the zowe configuration is good before starting zowe.
It requires that zowe.useConfigmgr=true or --configmgr are set.
This command can optionally validate enabled components or all components, but otherwise would only validate the zowe core configuration.
3 changes: 2 additions & 1 deletion bin/commands/internal/start/prepare/.errors
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ZWEL0141E|141|User %s does not have write permission on %s.
ZWEL0302W||You are running the Zowe process under user id IZUSVR. This is not recommended and may impact your z/OS MF server negatively.
ZWEL0317E||Component %s commands.configure ended with rc=%s.
ZWEL0317E||Component %s commands.configure ended with rc=%s.
ZWEL0323E||Certificate validation failed. Fix errors listed before starting Zowe.
24 changes: 18 additions & 6 deletions bin/commands/internal/start/prepare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import * as javaCI from '../../../../libs/java_ci';
import * as node from '../../../../libs/node';
import * as zosmf from '../../../../libs/zosmf';
import * as zoslib from '../../../../libs/zos';
import * as verifyCertificate from '../../../validate/certificate/index';
import * as verifyZosmf from '../../../validate/zosmf/index';

//# This command prepares everything needed to start Zowe.
const cliParameterConfig = std.getenv('ZWE_CLI_PARAMETER_CONFIG');
Expand Down Expand Up @@ -454,16 +456,26 @@ export function execute() {
common.printFormattedInfo("ZWELS", "zwe-internal-start-prepare", `z/OS Version: ${zoslib.formatZosVersion('{major}.{minor}')}`);
common.printFormattedInfo("ZWELS", "zwe-internal-start-prepare", `ESM: ${zos.getEsm()}`);

common.requireZoweYaml();
const enabledComponents=component.getEnabledComponents();

// validation
if (stringlib.itemInList(std.getenv('ZWE_PRIVATE_CORE_COMPONENTS_REQUIRE_JAVA'), std.getenv('ZWE_CLI_PARAMETER_COMPONENT'))) {
// other extensions need to specify `require_java` in their validate.sh
java.requireJava();
java.requireJava();
let certRc = 0;
if (enabledComponents.includes('gateway')) {
certRc = verifyZosmf.execute(false);
} else {
certRc = verifyCertificate.execute(false);
}
if (certRc != 0) {
common.printErrorAndExit("Error ZWEL0323E: Certificate validation failed. Fix errors listed before starting Zowe.", undefined, 323);
}
if (stringlib.itemInList('app-server', std.getenv('ZWE_CLI_PARAMETER_COMPONENT'))) {

if (enabledComponents.includes('app-server')) {
// other extensions need to specify `require_node` in their validate.sh
node.requireNode();
}
common.requireZoweYaml();


// overwrite ZWE_PRIVATE_LOG_LEVEL_ZWELS with zowe.launchScript.logLevel config in YAML
if (ZOWE_CONFIG.zowe.launchScript.logLevel) {
Expand Down Expand Up @@ -493,7 +505,7 @@ export function execute() {
common.printFormattedTrace("ZWELS", "zwe-internal-start-prepare", JSON.stringify(std.getenviron()));
common.printFormattedTrace("ZWELS", "zwe-internal-start-prepare", "<<<");

const enabledComponents=component.getEnabledComponents();


// main lifecycle
// global validations
Expand Down
3 changes: 3 additions & 0 deletions bin/commands/validate/certificate/.examples
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zwe validate certificate -c /path/to/zowe.yaml
zwe validate certificate -c FILE(/customizations/zowe.yaml):FILE(/defaults/zowe.yaml)
zwe validate certificate -c 'FILE(/path/to/zowe.yaml):PARMLIB(ZOWE.PARMLIB(YAML))'
2 changes: 2 additions & 0 deletions bin/commands/validate/certificate/.help
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Validates whether required Zowe keystore and truststore exist and meet Zowe's requirements.
This command can be used to prove that Zowe's keystore and truststore are correct before starting zowe.
16 changes: 16 additions & 0 deletions bin/commands/validate/certificate/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/
import * as index from './index';
import * as configmgr from '../../../libs/configmgr';

index.execute(true);

configmgr.cleanupTempDir();
18 changes: 18 additions & 0 deletions bin/commands/validate/certificate/index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh

#######################################################################
# This program and the accompanying materials are made available
# under the terms of the Eclipse Public License v2.0 which
# accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright Contributors to the Zowe Project.
#######################################################################

if [ -z "${ZWE_PRIVATE_TMP_MERGED_YAML_DIR}" ]; then
# user-facing command, use tmpdir to not mess up workspace permissions
export ZWE_PRIVATE_TMP_MERGED_YAML_DIR=1
fi
_CEE_RUNOPTS="XPLINK(ON),HEAPPOOLS(OFF),HEAPPOOLS64(OFF)" ${ZWE_zowe_runtimeDirectory}/bin/utils/configmgr -script "${ZWE_zowe_runtimeDirectory}/bin/commands/validate/certificate/cli.js"
140 changes: 140 additions & 0 deletions bin/commands/validate/certificate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/

import * as zos from 'zos';
import * as common from '../../../libs/common';
import * as config from '../../../libs/config';
import * as java from '../../../libs/java';
import * as shell from '../../../libs/shell';

export function execute(quitOnError?: boolean): number {
const ZOWE_CONFIG=config.getZoweConfig();

java.requireJava();

const keystoreType = ZOWE_CONFIG.zowe.certificate.keystore.type;
const keystoreAlias = ZOWE_CONFIG.zowe.certificate.keystore.alias;
const keystorePass = ZOWE_CONFIG.zowe.certificate.keystore.password;
const truststoreType = ZOWE_CONFIG.zowe.certificate.truststore.type;
const truststorePass = ZOWE_CONFIG.zowe.certificate.truststore.password;
let keystoreLocation = ZOWE_CONFIG.zowe.certificate.keystore.file;
let truststoreLocation = ZOWE_CONFIG.zowe.certificate.truststore.file;
if (keystoreType == 'JCERACFKS') {
keystoreLocation = keystoreLocation.replace('safkeyring', 'safkeyringjce');
} else if (keystoreType == 'JCECCARACFKS') {
keystoreLocation = keystoreLocation.replace('safkeyring', 'safkeyringjcecca');
} else if (keystoreType == 'JCEHYBRIDRACFKS') {
keystoreLocation = keystoreLocation.replace('safkeyring', 'safkeyringjcehybrid');
}
if (truststoreType == 'JCERACFKS') {
truststoreLocation = truststoreLocation.replace('safkeyring', 'safkeyringjce');
} else if (truststoreType == 'JCECCARACFKS') {
truststoreLocation = truststoreLocation.replace('safkeyring', 'safkeyringjcecca');
} else if (truststoreType == 'JCEHYBRIDRACFKS') {
truststoreLocation = truststoreLocation.replace('safkeyring', 'safkeyringjcehybrid');
}

let argsString = `-Djava.protocol.handler.pkgs=com.ibm.crypto.provider -jar ${ZOWE_CONFIG.zowe.runtimeDirectory}/bin/utils/certificate-analyser.jar `+
`-k ${keystoreLocation} -kt ${keystoreType} -kp ${keystorePass} `+
`-a ${keystoreAlias} -t ${truststoreLocation} -tt ${truststoreType} -tp ${truststorePass}`;

let result = shell.execOutSync('java', ...argsString.split(' '));
let rc = result.rc;
if (rc == 0) {
common.printFormattedInfo("ZWELS", "zwe-validate-certificate", "Certificate checks passed. Output follows:");
let configLines = result.out.split('\n').filter((line)=>line != '++++++++');
console.log(configLines.join('\n'));
} else {
let configLines = result.out.split('\n').filter((line)=>line != '++++++++');

let certificateInvalid = false;
let configInvalid=false;
if (result.out.includes("IRRSDL00")) {
configInvalid=true;
//R_datalib (IRRSDL00) error: profile for ring not found (8, 8, 84)
let irrLine = configLines.filter((line)=> line.includes('IRRSDL00'));
let codes = irrLine[0].substring(0,irrLine[0].length-1).split(':')[1].split('(')[1].split(', ');
let esm = zos.getEsm();
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Could not load keyring. SAF rc=${codes[0]}, ${esm} rc=${codes[1]}, ${esm} rsn=${codes[2]}`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Verify that keystore ${keystoreLocation} is valid and accessible to the Zowe STC`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Verify that truststore ${truststoreLocation} is valid and accessible to the Zowe STC`);
}
if (result.out.includes('Incorrect key ring format')) {
configInvalid=true;
}
if (result.out.includes('is not available in keystore')) {
configInvalid=true;
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Could not load certificate ${keystoreAlias}. Verify it is present in keystore ${keystoreLocation}.`);
}
if (result.out.includes("No trusted certificate found.")) {
//No trusted certificate found. Add " + x509Certificate.getIssuerDN() + " certificate authority to the trust store
//TODO
}
if (result.out.includes("Certificate can't be used for client authentication")) {
certificateInvalid=true;
if (ZOWE_CONFIG.zowe.verifyCertificates != 'DISABLED') {
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate ${keystoreAlias} in keystore ${keystoreLocation} does not need Zowe's requirements.`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate EKU missing Client Auth 1.3.6.1.5.5.7.3.2 attribute.`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `See https://docs.zowe.org/stable/user-guide/configure-certificates#extended-key-usage'`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", 'Create a new certificate that meets the EKU requirements of Zowe before using Zowe.');
}
}
if (result.out.includes("Certificate can't be used for web server")) {
certificateInvalid=true;
if (ZOWE_CONFIG.zowe.verifyCertificates != 'DISABLED') {
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate ${keystoreAlias} in keystore ${keystoreLocation} does not need Zowe's requirements.`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate EKU missing Server Auth 1.3.6.1.5.5.7.3.1 attribute.`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `See https://docs.zowe.org/stable/user-guide/configure-certificates#extended-key-usage'`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", 'Create a new certificate that meets the EKU requirements of Zowe before using Zowe.');
}
}
if (result.out.includes("Not matched hostnames with the certificate:")) {
if (ZOWE_CONFIG.zowe.verifyCertificates == 'STRICT') {
certificateInvalid = true;
//TODO
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate ${keystoreAlias} in keystore ${keystoreLocation} is invalid for some hostnames used with Zowe.`);
}
}
if (result.out.includes("The certificate is expired")) {
certificateInvalid = true;
if (ZOWE_CONFIG.zowe.verifyCertificates == 'DISABLED') {
common.printFormattedWarn("ZWELS", "zwe-validate-certificate", `Certificate ${keystoreAlias} in keystore ${keystoreLocation} has expired.`);
} else {
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Certificate ${keystoreAlias} in keystore ${keystoreLocation} has expired.`);
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Create a new certificate before using Zowe.`);
}
}

if (certificateInvalid) {
if (ZOWE_CONFIG.zowe.verifyCertificates == 'DISABLED') {
rc = 0; //ignored
}
}
if (configInvalid) {
common.printFormattedError("ZWELS", "zwe-validate-certificate", `Correct the zowe.certificate YAML configuration before using Zowe.`);
}

if (rc != 0) {
common.printFormattedError("ZWELS", "zwe-validate-zosmf", "Validation failed. Output follows:");
} else {
common.printFormattedWarn("ZWELS", "zwe-validate-zosmf", "Validation had warnings. Output follows:");
}

console.log(configLines.join('\n'));
}


if (rc && quitOnError) {
common.printErrorAndExit("Error ZWEL0323E: Certificate validation failed. Fix errors listed before starting Zowe.", undefined, 323);
}

return rc;
}
3 changes: 3 additions & 0 deletions bin/commands/validate/config/.examples
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zwe validate config -c /path/to/zowe.yaml
zwe validate config -c FILE(/customizations/zowe.yaml):FILE(/defaults/zowe.yaml) --all
zwe validate config -c 'FILE(/path/to/zowe.yaml):PARMLIB(ZOWE.PARMLIB(YAML))'
3 changes: 3 additions & 0 deletions bin/commands/validate/config/.help
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Runs schema validation upon given zowe yaml configuration files.
This command can be used to prove that the zowe configuration is good before starting zowe.
This command can optionally validate enabled components or all components, but otherwise would only validate the zowe core configuration.
2 changes: 2 additions & 0 deletions bin/commands/validate/config/.parameters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
components||boolean|||||Turns on validation for enabled components.
all||boolean|||||Turns on validation for all components, even disabled ones.
17 changes: 17 additions & 0 deletions bin/commands/validate/config/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/
import * as std from 'cm_std';
import * as index from '../../config/validate/index';
import * as configmgr from '../../../libs/configmgr';

index.execute(std.getenv('ZWE_CLI_PARAMETER_CONFIG'), std.getenv('ZWE_CLI_PARAMETER_COMPONENTS')=='true', std.getenv('ZWE_CLI_PARAMETER_ALL')!='true');

configmgr.cleanupTempDir();
19 changes: 19 additions & 0 deletions bin/commands/validate/config/index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh

#######################################################################
# This program and the accompanying materials are made available
# under the terms of the Eclipse Public License v2.0 which
# accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright Contributors to the Zowe Project.
#######################################################################

if [ -z "${ZWE_PRIVATE_TMP_MERGED_YAML_DIR}" ]; then
# user-facing command, use tmpdir to not mess up workspace permissions
export ZWE_PRIVATE_TMP_MERGED_YAML_DIR=1
fi
_CEE_RUNOPTS="XPLINK(ON),HEAPPOOLS(OFF),HEAPPOOLS64(OFF)" ${ZWE_zowe_runtimeDirectory}/bin/utils/configmgr -script "${ZWE_zowe_runtimeDirectory}/bin/commands/validate/config/cli.js"

3 changes: 3 additions & 0 deletions bin/commands/validate/dependencies/.examples
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
zwe validate dependencies -c /path/to/zowe.yaml
zwe validate dependencies -c FILE(/customizations/zowe.yaml):FILE(/defaults/zowe.yaml) --all
zwe validate dependencies -c 'FILE(/path/to/zowe.yaml):PARMLIB(ZOWE.PARMLIB(YAML))'
2 changes: 2 additions & 0 deletions bin/commands/validate/dependencies/.help
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Checks for the existence of Zowe's dependencies, and that they are a compatible version.
The dependencies that are checked depends upon the components enabled in the YAML provided.
16 changes: 16 additions & 0 deletions bin/commands/validate/dependencies/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
This program and the accompanying materials are made available
under the terms of the Eclipse Public License v2.0 which
accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-v20.html

SPDX-License-Identifier: EPL-2.0

Copyright Contributors to the Zowe Project.
*/
import * as index from './index';
import * as configmgr from '../../../libs/configmgr';

index.execute();

configmgr.cleanupTempDir();
19 changes: 19 additions & 0 deletions bin/commands/validate/dependencies/index.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh

#######################################################################
# This program and the accompanying materials are made available
# under the terms of the Eclipse Public License v2.0 which
# accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-v20.html
#
# SPDX-License-Identifier: EPL-2.0
#
# Copyright Contributors to the Zowe Project.
#######################################################################

if [ -z "${ZWE_PRIVATE_TMP_MERGED_YAML_DIR}" ]; then
# user-facing command, use tmpdir to not mess up workspace permissions
export ZWE_PRIVATE_TMP_MERGED_YAML_DIR=1
fi
_CEE_RUNOPTS="XPLINK(ON),HEAPPOOLS(OFF),HEAPPOOLS64(OFF)" ${ZWE_zowe_runtimeDirectory}/bin/utils/configmgr -script "${ZWE_zowe_runtimeDirectory}/bin/commands/validate/dependencies/cli.js"

Loading
Loading