diff --git a/electron/app/js/wdtPrepareModel.js b/electron/app/js/wdtPrepareModel.js index b348b6c58..d0acb6500 100644 --- a/electron/app/js/wdtPrepareModel.js +++ b/electron/app/js/wdtPrepareModel.js @@ -7,7 +7,6 @@ const path = require('path'); const { readFile } = require('fs/promises'); -const jsYaml = require('js-yaml'); const i18n = require('./i18next.config'); const childProcessExecutor = require('./childProcessExecutor'); @@ -19,15 +18,10 @@ const errorUtils = require('./errorUtils'); const MINIMUM_WDT_PREPARE_VERSION = '2.0.0'; -const _secretsFileName = 'k8s_secrets.json'; -const _wkoDomainSpecFileName = 'wko-domain.yaml'; -const _vzApplicationSpecFileName = 'vz-application.yaml'; +const _resultsFileName = 'results.json'; const _deleteTempDirectory = true; -const _wkoTargetTypeName = i18n.t('prepare-model-wko-target-type-name'); -const _vzTargetTypeName = i18n.t('prepare-model-wko-target-type-name'); - async function prepareModel(currentWindow, stdoutChannel, stderrChannel, prepareConfig) { const logger = getLogger(); const { javaHome, oracleHome, projectDirectory, modelsSubdirectory, modelFiles, @@ -119,7 +113,9 @@ async function prepareModel(currentWindow, stdoutChannel, stderrChannel, prepare } try { - results['secrets'] = await getJsonSecretsContent(outputDirectory); + const jsonResults = await getJsonResultsContent(outputDirectory); + results['secrets'] = jsonResults['secrets']; + results['domain'] = jsonResults['domain']; } catch (err) { results.isSuccess = false; results.reason = errorUtils.getErrorMessage(err); @@ -129,14 +125,6 @@ async function prepareModel(currentWindow, stdoutChannel, stderrChannel, prepare return Promise.resolve(results); } - try { - results['domain'] = await getTargetSpecContent(wdtTargetType, outputDirectory); - } catch (err) { - results.isSuccess = false; - results.reason = errorUtils.getErrorMessage(err); - results.error = err; - logger.error(results.reason); - } removeTempDirectory(outputDirectory).then().catch(); return Promise.resolve(results); } @@ -228,30 +216,30 @@ function getUpdatedModelFileNames(updatedFileMap, files) { return updatedFiles; } -async function getJsonSecretsContent(outputDirectory) { - const secretsFileName = path.join(outputDirectory, _secretsFileName); +async function getJsonResultsContent(outputDirectory) { + const resultsFileName = path.join(outputDirectory, _resultsFileName); return new Promise((resolve, reject) => { - fsUtils.exists(secretsFileName).then(doesExist => { + fsUtils.exists(resultsFileName).then(doesExist => { if (!doesExist) { - return reject(new Error(i18n.t('prepare-model-secrets-file-missing-error-message', - { fileName: secretsFileName }))); + return reject(new Error(i18n.t('prepare-model-results-file-missing-error-message', + { fileName: resultsFileName }))); } - readFile(secretsFileName, { encoding: 'utf8' }).then(data => { + readFile(resultsFileName, { encoding: 'utf8' }).then(data => { let jsonContent; try { jsonContent = JSON.parse(data); - resolve(formatSecretsData(jsonContent)); + resolve(formatResultsData(jsonContent)); } catch (err) { - const error = new Error(i18n.t('prepare-model-secrets-file-parse-error-message', - { fileName: secretsFileName, error: errorUtils.getErrorMessage(err) })); + const error = new Error(i18n.t('prepare-model-results-file-parse-error-message', + { fileName: resultsFileName, error: errorUtils.getErrorMessage(err) })); error.cause = err; reject(err); } }).catch(err => { - const error = new Error(i18n.t('prepare-model-secrets-file-read-error-message', - { fileName: secretsFileName, error: errorUtils.getErrorMessage(err) })); + const error = new Error(i18n.t('prepare-model-results-file-read-error-message', + { fileName: resultsFileName, error: errorUtils.getErrorMessage(err) })); error.cause = err; reject(err); }); @@ -259,18 +247,17 @@ async function getJsonSecretsContent(outputDirectory) { }); } -function formatSecretsData(jsonContent) { +function formatResultsData(jsonContent) { const results = { }; if (!jsonContent) { return results; } - results['domainUID'] = jsonContent.domainUID; const secrets = jsonContent['secrets'] || []; results.secrets = []; - for (const secret of secrets) { + for (const [secretName, secret] of Object.entries(secrets)) { const secretResult = { - name: secret['secretName'] + name: secretName }; const secretKeys = secret['keys']; if (secretKeys) { @@ -289,115 +276,23 @@ function formatSecretsData(jsonContent) { results.secrets.push(secretResult); } } - return results; -} - -async function getTargetSpecContent(wdtTargetType, outputDirectory) { - let result = { }; - switch (wdtTargetType) { - case 'wko': - result = await getWkoSpecContent(outputDirectory); - break; - - case 'vz': - result = await getVzSpecContent(outputDirectory); - break; - - default: - // k8s target produces no spec... - break; - } - return Promise.resolve(result); -} - -async function getWkoSpecContent(outputDirectory) { - const specFile = path.join(outputDirectory, _wkoDomainSpecFileName); - - return new Promise((resolve, reject) => { - fsUtils.exists(specFile).then(doesExist => { - if (!doesExist) { - const error = new Error(i18n.t('prepare-model-spec-file-missing-error-message', - { targetType: _wkoTargetTypeName, fileName: specFile })); - reject(error); - } - readFile(specFile, { encoding: 'utf8' }).then(data => { - try { - const yamlDoc = jsYaml.load(data, { filename: specFile, json: true }); - resolve(formatWkoDomainSpecData(yamlDoc)); - } catch (err) { - const error = new Error(i18n.t('prepare-model-spec-file-parse-error-message', - { targetType: _wkoTargetTypeName, fileName: specFile, error: errorUtils.getErrorMessage(err) })); - error.cause = err; - reject(error); - } - }).catch(err => { - const error = new Error(i18n.t('prepare-model-spec-file-read-error-message', - { targetType: _wkoTargetTypeName, fileName: specFile, error: errorUtils.getErrorMessage(err) })); - error.cause = err; - reject(error); - }); - }).catch(err => reject(getFileExistsErrorMessage(_wkoTargetTypeName, specFile, err))); - }); -} + const domain = {}; + domain['domainUID'] = jsonContent.domainUID; -function formatWkoDomainSpecData(yamlDoc) { - const result = { }; - if (yamlDoc) { - if ('metadata' in yamlDoc && 'name' in yamlDoc['metadata']) { - result['domainUID'] = yamlDoc['metadata']['name']; - } - if ('spec' in yamlDoc && 'clusters' in yamlDoc['spec']) { - const clusters = yamlDoc['spec']['clusters']; - const clustersResult = []; - for (const cluster of clusters) { - const clusterResult = { - clusterName: cluster['clusterName'], - replicas: cluster['replicas'] || 0 - }; - clustersResult.push(clusterResult); - } - result['clusters'] = clustersResult; - } + const clusters = jsonContent['clusters'] || []; + const clustersResult = []; + for (const [clusterName, cluster] of Object.entries(clusters)) { + const clusterResult = { + clusterName: clusterName, + replicas: cluster['serverCount'] || 0 + }; + clustersResult.push(clusterResult); } - return result; -} - -async function getVzSpecContent(outputDirectory) { - const specFile = path.join(outputDirectory, _vzApplicationSpecFileName); + domain['clusters'] = clustersResult; - return new Promise((resolve, reject) => { - fsUtils.exists(specFile).then(doesExist => { - if (!doesExist) { - const error = new Error(i18n.t('prepare-model-spec-file-missing-error-message', - { targetType: _vzTargetTypeName, fileName: specFile })); - reject(error); - } - - readFile(specFile, { encoding: 'utf8' }).then(data => { - let yamlDocs; - try { - yamlDocs = jsYaml.loadAll(data, { filename: specFile, json: true }); - } catch (err) { - const error = new Error(i18n.t('prepare-model-spec-file-parse-error-message', - { targetType: _vzTargetTypeName, fileName: specFile, error: errorUtils.getErrorMessage(err) })); - error.cause = err; - reject(error); - } - - try { - resolve(formatVzApplicationSpecData(specFile, yamlDocs)); - } catch (err) { - reject(err); - } - }).catch(err => { - const error = new Error(i18n.t('prepare-model-spec-file-read-error-message', - { targetType: _vzTargetTypeName, fileName: specFile, error: errorUtils.getErrorMessage(err) })); - error.cause = err; - reject(error); - }); - }).catch(err => reject(getFileExistsErrorMessage(_wkoTargetTypeName, specFile, err))); - }); + results['domain'] = domain; + return results; } function getToolTargetType(wdtTargetType, targetDomainLocation) { @@ -405,53 +300,6 @@ function getToolTargetType(wdtTargetType, targetDomainLocation) { return `${wdtTargetType}${suffix}`; } -function getFileExistsErrorMessage(targetType, fileName, err) { - const error = new Error(i18n.t('prepare-model-spec-file-exists-error-message', - { targetType: targetType, fileName: fileName, error: errorUtils.getErrorMessage(err) })); - error.cause = err; - return error; -} - -function formatVzApplicationSpecData(specFile, yamlDocs) { - const domainSpec = findVzDomainSpec(specFile, yamlDocs); - const domainUID = domainSpec.domainUID; - - const clustersResult = []; - if (domainSpec.clusters) { - for (const cluster of domainSpec.clusters) { - clustersResult.push({ clusterName: cluster.clusterName, replicas: cluster.replicas }); - } - } - return { - domainUID: domainUID, - clusters: clustersResult - }; -} - -function findVzDomainSpec(specFile, yamlDocs) { - let result; - if (yamlDocs && yamlDocs.length > 0) { - for (const yamlDoc of yamlDocs) { - if (yamlDoc['kind'] !== 'Component') { - continue; - } - if (yamlDoc.spec?.workload?.kind === 'VerrazzanoWebLogicWorkload') { - result = yamlDoc; - break; - } - } - } - - if (!result) { - throw new Error(i18n.t('prepare-model-vz-spec-file-missing-domain-error-message', { fileName: specFile })); - } else if (!result.spec?.workload?.spec?.template?.spec) { - throw new Error(i18n.t('prepare-model-vz-spec-file-missing-spec-error-message', { fileName: specFile })); - } else { - result = result.spec.workload.spec.template.spec; - } - return result; -} - module.exports = { prepareModel }; diff --git a/electron/app/locales/en/electron.json b/electron/app/locales/en/electron.json index 4c17a6d9c..5efd35774 100644 --- a/electron/app/locales/en/electron.json +++ b/electron/app/locales/en/electron.json @@ -250,17 +250,9 @@ "prepare-model-model-file-not-exists-error-message": "Unable to prepare model with non-existent model file: {{modelFile}}.", "prepare-model-error-exit-code-error-message": "Prepare Model script exited with {{exitCode}}, which indicates an error.", "prepare-model-execution-failed-error-message": "Prepare Model script failed: {{error}}", - "prepare-model-secrets-file-missing-error-message": "Prepare Model failed to generate the expected secrets file {{fileName}}", - "prepare-model-secrets-file-read-error-message": "Prepare Model failed to read secrets file {{fileName}}: {{error}}", - "prepare-model-secrets-file-parse-error-message": "Prepare Model failed to parse secrets file {{fileName}}: {{error}}", - "prepare-model-spec-file-missing-error-message": "Prepare Model failed to generate the expected {{targetType}} specification file {{fileName}}", - "prepare-model-spec-file-exists-error-message": "Prepare Model failed to determine whether the {{targetType}} specification file {{fileName}} exists: {{error}}", - "prepare-model-spec-file-read-error-message": "Prepare Model failed to read the {{targetType}} specification file {{fileName}}: {{error}}", - "prepare-model-spec-file-parse-error-message": "Prepare Model failed to parse the {{targetType}} specification file {{fileName}}: {{error}}", - "prepare-model-vz-spec-file-missing-domain-error-message": "Prepare model failed to find the Verrazzano component that defined the WebLogic Kubernetes Operator domain in {{fileName}}", - "prepare-model-vz-spec-file-missing-spec-error-message": "Prepare model failed to find the WebLogic Kubernetes Operator domain's spec field in the Verrazzano component defined in {{fileName}}", - "prepare-model-wko-target-type-name": "WebLogic Kubernetes Operator domain", - "prepare-model-vz-target-type-name": "Verrazzano application", + "prepare-model-results-file-missing-error-message": "Prepare Model failed to generate the expected results file {{fileName}}", + "prepare-model-results-file-read-error-message": "Prepare Model failed to read results file {{fileName}}: {{error}}", + "prepare-model-results-file-parse-error-message": "Prepare Model failed to parse results file {{fileName}}: {{error}}", "wit-inspect-inspect-error-message": "Inspecting image {{imageTag}} failed: {{error}}.", "wit-inspect-inspect-parse-error-message": "Inspecting image {{imageTag}} failed due to a JSON parse error parsing the response: {{error}}.", diff --git a/tools/wdt-config/targets/vz-dii/target.json b/tools/wdt-config/targets/vz-dii/target.json index 52d255ab3..c6743fcab 100644 --- a/tools/wdt-config/targets/vz-dii/target.json +++ b/tools/wdt-config/targets/vz-dii/target.json @@ -6,7 +6,7 @@ }, "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "lax", - "credentials_output_method" : "script", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_output" : "vz-application.yaml", diff --git a/tools/wdt-config/targets/vz-pv/target.json b/tools/wdt-config/targets/vz-pv/target.json index fca8c9648..c534c521a 100644 --- a/tools/wdt-config/targets/vz-pv/target.json +++ b/tools/wdt-config/targets/vz-pv/target.json @@ -6,7 +6,7 @@ }, "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "lax", - "credentials_output_method" : "script", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_output" : "vz-application.yaml", diff --git a/tools/wdt-config/targets/vz/target.json b/tools/wdt-config/targets/vz/target.json index 5c3b97a48..116dfb447 100644 --- a/tools/wdt-config/targets/vz/target.json +++ b/tools/wdt-config/targets/vz/target.json @@ -7,7 +7,7 @@ "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "wktui", "credentials_method" : "secrets", - "credentials_output_method" : "json", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_secrets": "runtime-encryption-secret", diff --git a/tools/wdt-config/targets/wko-dii/target.json b/tools/wdt-config/targets/wko-dii/target.json index 83e5d9984..564b8b536 100644 --- a/tools/wdt-config/targets/wko-dii/target.json +++ b/tools/wdt-config/targets/wko-dii/target.json @@ -6,7 +6,7 @@ }, "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "wktui", - "credentials_output_method" : "json", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_output" : "wko-domain.yaml", diff --git a/tools/wdt-config/targets/wko-pv/target.json b/tools/wdt-config/targets/wko-pv/target.json index 6931524db..54d591f64 100644 --- a/tools/wdt-config/targets/wko-pv/target.json +++ b/tools/wdt-config/targets/wko-pv/target.json @@ -6,7 +6,7 @@ }, "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "wktui", - "credentials_output_method" : "json", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_output" : "wko-domain.yaml", diff --git a/tools/wdt-config/targets/wko/target.json b/tools/wdt-config/targets/wko/target.json index 94c62ddd0..fce77b5b3 100644 --- a/tools/wdt-config/targets/wko/target.json +++ b/tools/wdt-config/targets/wko/target.json @@ -7,7 +7,7 @@ "variable_injectors" : {"PORT": {},"HOST": {},"URL": {}}, "validation_method" : "wktui", "credentials_method" : "secrets", - "credentials_output_method" : "json", + "results_output_method" : "json", "exclude_domain_bin_contents": true, "wls_credentials_name" : "__weblogic-credentials__", "additional_secrets": "runtime-encryption-secret",