From f6f52a7c6b59a83e48af5b57e9b62545755ef497 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Wed, 1 Apr 2020 09:41:07 -0700 Subject: [PATCH 1/2] [FEATURE] Added code to have error code and chaining for deployment validate cmd --- docs/commands/data.json | 5 +- src/commands/deployment/create.ts | 4 +- ...decorator.json => validate.decorator.json} | 0 .../deployment/{validation.md => validate.md} | 0 src/commands/deployment/validate.ts | 47 +++++--- src/lib/azure/deploymenttable.ts | 110 ++++++++++-------- src/lib/i18n.json | 15 ++- 7 files changed, 113 insertions(+), 68 deletions(-) rename src/commands/deployment/{validator.decorator.json => validate.decorator.json} (100%) rename src/commands/deployment/{validation.md => validate.md} (100%) diff --git a/docs/commands/data.json b/docs/commands/data.json index 79b206aa9..1395e2ca6 100644 --- a/docs/commands/data.json +++ b/docs/commands/data.json @@ -224,7 +224,8 @@ "description": "Run a test for the configured storage account. This will write test data and delete the test data. For more information on the behavior, please check the online documentation.", "defaultValue": false } - ] + ], + "markdown": "## Description\n\nThis command validates the\n[requirements](https://github.com/CatalystCode/spk/blob/master/guides/service-introspection.md#requirements)\nand the onboard\n[prerequisites](https://github.com/CatalystCode/spk/blob/master/guides/service-introspection.md#prerequisites)\n\n## Note\n\nThe purpose of `--self-test` option is to make sure that `spk` is able to write\ndata to the provided storage account. Once the test ends, it will remove the\ntest data that was added.\n" }, "hld append-variable-group": { "command": "append-variable-group ", @@ -674,4 +675,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/commands/deployment/create.ts b/src/commands/deployment/create.ts index a3bc03327..d8a74e4da 100644 --- a/src/commands/deployment/create.ts +++ b/src/commands/deployment/create.ts @@ -79,7 +79,7 @@ export const handlePipeline1 = async ( ) { throw buildError( errorStatusCode.VALIDATION_ERR, - "introspect-create-cmd-cmd-p1-missing-values" + "introspect-create-cmd-p1-missing-values" ); } await addSrcToACRPipeline( @@ -104,7 +104,7 @@ export const handlePipeline2 = async ( ) { throw buildError( errorStatusCode.VALIDATION_ERR, - "introspect-create-cmd-cmd-p2-missing-values" + "introspect-create-cmd-p2-missing-values" ); } await updateACRToHLDPipeline( diff --git a/src/commands/deployment/validator.decorator.json b/src/commands/deployment/validate.decorator.json similarity index 100% rename from src/commands/deployment/validator.decorator.json rename to src/commands/deployment/validate.decorator.json diff --git a/src/commands/deployment/validation.md b/src/commands/deployment/validate.md similarity index 100% rename from src/commands/deployment/validation.md rename to src/commands/deployment/validate.md diff --git a/src/commands/deployment/validate.ts b/src/commands/deployment/validate.ts index aec1f905b..d14a8b49f 100644 --- a/src/commands/deployment/validate.ts +++ b/src/commands/deployment/validate.ts @@ -11,7 +11,9 @@ import { import { build as buildCmd, exit as exitCmd } from "../../lib/commandBuilder"; import { logger } from "../../logger"; import { ConfigYaml } from "../../types"; -import decorator from "./validator.decorator.json"; +import { build as buildError, log as logError } from "../../lib/errorBuilder"; +import { errorStatusCode } from "../../lib/errorStatusCode"; +import decorator from "./validate.decorator.json"; const service = "spk-self-test"; @@ -64,10 +66,10 @@ export const isValidConfig = (config: ConfigYaml): ValidateConfig => { } if (missingConfig.length > 0) { - logger.error( - "Validation failed. Missing configuration: " + missingConfig.join(" ") - ); - throw new Error("missing configuration in spk configuration"); + throw buildError(errorStatusCode.VALIDATION_ERR, { + errorKey: "introspect-validate-cmd-valid-err", + values: [missingConfig.join(" ")], + }); } else { logger.info("Configuration validation: SUCCEEDED"); } @@ -90,8 +92,10 @@ export const isValidConfig = (config: ConfigYaml): ValidateConfig => { key: config.introspection.azure.key, }; } - throw Error( - "You need to specify configuration for your introspection storage account and DevOps pipeline to run this dashboard. Please initialize the spk tool with the right configuration" + + throw buildError( + errorStatusCode.VALIDATION_ERR, + "introspect-validate-cmd-missing-vals" ); }; @@ -133,8 +137,11 @@ export const writeSelfTestData = async ( return buildId; } catch (err) { - logger.error(err); - throw new Error("Error writing data to service introspection."); + throw buildError( + errorStatusCode.ENV_SETTING_ERR, + "introspect-validate-cmd-write-pipeline", + err + ); } }; @@ -216,12 +223,18 @@ export const runSelfTest = async (config: ValidateConfig): Promise => { if (!isVerified) { logger.error(statusMessage + "FAILED. Please try again."); - } else { - logger.info(statusMessage + "SUCCEEDED."); + throw buildError( + errorStatusCode.ENV_SETTING_ERR, + "introspect-validate-cmd-valid-failed" + ); } + logger.info(statusMessage + "SUCCEEDED."); } catch (err) { - logger.error("Error running self-test."); - throw err; + throw buildError( + errorStatusCode.EXE_FLOW_ERR, + "introspect-validate-cmd-valid-exception", + err + ); } }; @@ -244,7 +257,13 @@ export const execute = async ( } await exitFn(0); } catch (err) { - logger.error(err); + logError( + buildError( + errorStatusCode.CMD_EXE_ERR, + "introspect-validate-cmd-failed", + err + ) + ); await exitFn(1); } }; diff --git a/src/lib/azure/deploymenttable.ts b/src/lib/azure/deploymenttable.ts index 9a181332b..294d0640c 100644 --- a/src/lib/azure/deploymenttable.ts +++ b/src/lib/azure/deploymenttable.ts @@ -148,20 +148,28 @@ export const addSrcToACRPipeline = async ( commitId: string, repository?: string ): Promise => { - const entry: RowSrcToACRPipeline = { - PartitionKey: tableInfo.partitionKey, - RowKey: getRowKey(), - commitId, - imageTag, - p1: pipelineId, - service: serviceName, - }; - if (repository) { - entry.sourceRepo = repository.toLowerCase(); + try { + const entry: RowSrcToACRPipeline = { + PartitionKey: tableInfo.partitionKey, + RowKey: getRowKey(), + commitId, + imageTag, + p1: pipelineId, + service: serviceName, + }; + if (repository) { + entry.sourceRepo = repository.toLowerCase(); + } + await insertToTable(tableInfo, entry); + logger.info("Added first pipeline details to the database"); + return entry; + } catch (err) { + throw buildError( + errorStatusCode.AZURE_STORAGE_OP_ERR, + "deployment-table-add-src-to-acr-pipeline", + err + ); } - await insertToTable(tableInfo, entry); - logger.info("Added first pipeline details to the database"); - return entry; }; /** @@ -330,33 +338,48 @@ export const updateACRToHLDPipeline = async ( pr?: string, repository?: string ): Promise => { - const entries = await findMatchingDeployments( - tableInfo, - "imageTag", - imageTag - ); - - // 1. try to find the matching entry. - if (entries && entries.length > 0) { - const found = await updateMatchingArcToHLDPipelineEntry( - entries, + try { + const entries = await findMatchingDeployments( tableInfo, - pipelineId, - imageTag, - hldCommitId, - env, - pr, - repository + "imageTag", + imageTag ); - if (found) { - return found; + // 1. try to find the matching entry. + if (entries && entries.length > 0) { + const found = await updateMatchingArcToHLDPipelineEntry( + entries, + tableInfo, + pipelineId, + imageTag, + hldCommitId, + env, + pr, + repository + ); + + if (found) { + return found; + } + + // 2. when cannot find the entry, we take the last row and INSERT it. + // TODO: rethink this logic. + return await updateLastRowOfArcToHLDPipelines( + entries, + tableInfo, + pipelineId, + imageTag, + hldCommitId, + env, + pr, + repository + ); } - // 2. when cannot find the entry, we take the last row and INSERT it. + // Fallback: Ideally we should not be getting here, because there should + // always be a p1 for any p2 being created. // TODO: rethink this logic. - return await updateLastRowOfArcToHLDPipelines( - entries, + return await addNewRowToArcToHLDPipelines( tableInfo, pipelineId, imageTag, @@ -365,20 +388,13 @@ export const updateACRToHLDPipeline = async ( pr, repository ); + } catch (err) { + throw buildError( + errorStatusCode.AZURE_STORAGE_OP_ERR, + "deployment-table-add-acr-to-hld-pipeline", + err + ); } - - // Fallback: Ideally we should not be getting here, because there should - // always be a p1 for any p2 being created. - // TODO: rethink this logic. - return await addNewRowToArcToHLDPipelines( - tableInfo, - pipelineId, - imageTag, - hldCommitId, - env, - pr, - repository - ); }; /** diff --git a/src/lib/i18n.json b/src/lib/i18n.json index 9f5104be4..1fdb5e80a 100644 --- a/src/lib/i18n.json +++ b/src/lib/i18n.json @@ -50,11 +50,20 @@ "introspect-create-cmd-failed": "Deployment create command was not successfully executed.", "introspect-create-cmd-no-ops": "No action could be performed for specified arguments.", "introspect-create-cmd-missing-values": "Access key, storage account name, partition key and/or table name were not provided. Provide them.", - "introspect-create-cmd-cmd-p1-missing-values": "Values for image-tag, commit-id and service options were missing. They are required for updating the details of source pipeline. Provide them.", - "introspect-create-cmd-cmd-p2-missing-values": "Values for p2, hld-commit-id, image-tag and env options were missing. They are required For updating the details of image tag release pipeline. Provide them.", + "introspect-create-cmd-p1-missing-values": "Values for image-tag, commit-id and service options were missing. They are required for updating the details of source pipeline. Provide them.", + "introspect-create-cmd-p2-missing-values": "Values for p2, hld-commit-id, image-tag and env options were missing. They are required For updating the details of image tag release pipeline. Provide them.", + + "introspect-validate-cmd-failed": "Deployment validate command was not successfully executed.", + "introspect-validate-cmd-valid-err": "Validation failed. Missing configuration: {0}", + "introspect-validate-cmd-missing-vals": "Configuration for introspection storage account and DevOps pipeline to execute this command were missing. Initialize the spk tool with the right configuration", + "introspect-validate-cmd-valid-failed": "Validation was unsuccessful. Try again.", + "introspect-validate-cmd-valid-exception": "Error was caught during validation.", + "introspect-validate-cmd-write-pipeline": "Error writing data to service introspection.", "deployment-table-update-hld-manifest-pipeline-failed": "Could not update HLD to manifest pipeline.", "deployment-table-update-manifest-commit-id-failed": "Could not update manifest commit Id.", - "deployment-table-update-manifest-commit-id-failed-no-generation": "No manifest generation found to update manifest commit {0}." + "deployment-table-update-manifest-commit-id-failed-no-generation": "No manifest generation found to update manifest commit {0}.", + "deployment-table-add-src-to-acr-pipeline": "Could not add source to ACR pipeline information to storage table.", + "deployment-table-add-acr-to-hld-pipeline": "Could not add ACR to HLD pipeline information to storage table." } } From fee23e6cc7a0a63c776de18d73bba005469a7889 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Wed, 1 Apr 2020 09:48:38 -0700 Subject: [PATCH 2/2] Update validate.test.ts --- src/commands/deployment/validate.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/commands/deployment/validate.test.ts b/src/commands/deployment/validate.test.ts index a58405e94..fe7e5bf79 100644 --- a/src/commands/deployment/validate.test.ts +++ b/src/commands/deployment/validate.test.ts @@ -224,7 +224,9 @@ describe("test runSelfTest function", () => { const config = deepClone(mockedValidateConfig); config.tableName = ""; - await runSelfTest(config); + await expect(runSelfTest(config)).rejects.toThrow( + "introspect-validate-cmd-valid-exception: Error was caught during validation." + ); }); it("negative test: error thrown", async () => { jest