Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 7 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
5 changes: 2 additions & 3 deletions src/commands/deployment/onboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
validateValues,
} from "./onboard";
import * as onboardImpl from "./onboard";
import { getErrorMessage } from "../../lib/errorBuilder";

beforeAll(() => {
enableVerboseLogging();
Expand Down Expand Up @@ -237,9 +238,7 @@ describe("test validateValues function", () => {
vals.storageAccountName = "#123";
expect(() => {
validateValues(vals);
}).toThrow(
"The value for storage account name is invalid. Lowercase letters and numbers are allowed."
);
}).toThrow(getErrorMessage("validation-err-storage-account-name-invalid"));
});
it("[-ve]: invalid storageTableName value", () => {
const vals = getMockedValues();
Expand Down
3 changes: 2 additions & 1 deletion src/commands/hld/pipeline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as azdo from "../../lib/azdoClient";
import { BUILD_SCRIPT_URL } from "../../lib/constants";
import { getRepositoryName } from "../../lib/gitutils";
import { disableVerboseLogging, enableVerboseLogging } from "../../logger";
import { getErrorMessage } from "../../lib/errorBuilder";
jest.mock("../../lib/pipelines/pipelines");

import {
Expand Down Expand Up @@ -88,7 +89,7 @@ const orgNameTest = (hasVal: boolean): void => {

if (hasVal) {
expect(() => populateValues(data)).toThrow(
"Organization names must start with a letter or number, followed by letters, numbers or hyphens, and must end with a letter or number."
getErrorMessage("validation-err-org-name")
);
} else {
expect(() => populateValues(data)).toThrow(
Expand Down
6 changes: 4 additions & 2 deletions src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import { create as createSetupLog } from "../lib/setup/setupLog";
import { logger } from "../logger";
import decorator from "./setup.decorator.json";
import { createStorage } from "../lib/setup/azureStorage";
import { build as buildError, log as logError } from "../lib/errorBuilder";
import { errorStatusCode } from "../lib/errorStatusCode";
import { ConfigYaml } from "../types";

interface CommandOptions {
Expand Down Expand Up @@ -211,15 +213,15 @@ export const execute = async (
createSetupLog(rc);
await exitFn(0);
} catch (err) {
logError(buildError(errorStatusCode.CMD_EXE_ERR, "setup-cmd-failed", err));

const msg = getErrorMessage(requestContext, err);

// requestContext will not be created if input validation failed
if (requestContext) {
requestContext.error = msg;
}
createSetupLog(requestContext);

logger.error(msg);
await exitFn(1);
}
};
Expand Down
53 changes: 31 additions & 22 deletions src/lib/errorBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,36 @@ interface ErrorParam {
errorKey: string;
values: string[];
}

/**
* Returns error message
*
* @param errorInstance Error instance
*/
export const getErrorMessage = (errorInstance: string | ErrorParam): string => {
let key = "";
let values: string[] | undefined = undefined;

if (typeof errorInstance === "string") {
key = errorInstance;
} else {
key = errorInstance.errorKey;
values = errorInstance.values;
}

// if key is found in i18n json
if (key in errors) {
let results = errors[key];
if (values) {
values.forEach((val, i) => {
const re = new RegExp("\\{" + i + "}", "g");
results = results.replace(re, val);
});
}
return `${key}: ${results}`;
}
return key;
};
class ErrorChain extends Error {
errorCode: number;
details: string | undefined;
Expand All @@ -25,28 +55,7 @@ class ErrorChain extends Error {
* @param errorInstance Error instance
*/
getErrorMessage(errorInstance: string | ErrorParam): string {
let key = "";
let values: string[] | undefined = undefined;

if (typeof errorInstance === "string") {
key = errorInstance;
} else {
key = errorInstance.errorKey;
values = errorInstance.values;
}

// if key is found in i18n json
if (key in errors) {
let results = errors[key];
if (values) {
values.forEach((val, i) => {
const re = new RegExp("\\{" + i + "}", "g");
results = results.replace(re, val);
});
}
return `${key}: ${results}`;
}
return key;
return getErrorMessage(errorInstance);
}
/**
* Generates error messages and have them in messages array.
Expand Down
43 changes: 42 additions & 1 deletion src/lib/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"storageKeVaultName": "Enter key vault name (have the value as empty and hit enter key to skip)"
},
"errors": {
"setup-cmd-failed": "Setup command was not successfully executed.",

"hld-init-cmd-failed": "Hld init command was not successfully executed.",
"hld-init-cmd-project-path-missing": "Value for project path was not provided. Provide it.",

Expand Down Expand Up @@ -96,6 +98,45 @@
"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-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."
"deployment-table-add-acr-to-hld-pipeline": "Could not add ACR to HLD pipeline information to storage table.",

"validation-err-org-name-missing": "Organization name was missing. Provide it.",
"validation-err-org-name": "Organization name must start with a letter or number, followed by letters, numbers or hyphens, and must end with a letter or number.",
"validation-err-password-missing": "Password was missing. Provide it.",
"validation-err-password-too-short": "Password was too short, it must be more than 8 characters long. Reenter password.",
"validation-err-project-name-missing": "Project name was missing. Provide it.",
"validation-err-project-name-too-long": "Project name was too long, it cannot be longer than 64 characters.",
"validation-err-project-name-begin-underscore": "Project name was invalid as it cannot begin with an underscore",
"validation-err-project-name-period": "Project name was invalid as it cannot begin or end with a period",
"validation-err-project-name-special-char": "Project name can't contain special characters, such as / : \\ ~ & % ; @ ' \" ? < > | # $ * } { , + = [ ]",
"validation-err-personal-access-token-missing": "Personal access token was missing. Provide it",

"validation-err-service-principal-id-missing": "Service Principal Id was missing. Provide it.",
"validation-err-service-principal-id-invalid": "Service Principal Id was invalid. Check and re-enter.",
"validation-err-service-principal-pwd-missing": "Service Principal Password was missing. Provide it.",
"validation-err-service-principal-pwd-invalid": "Service Principal Password was invalid. Check and re-enter.",
"validation-err-service-principal-tenant-id-missing": "Service Principal Tenant Id was missing. Provide it.",
"validation-err-service-principal-tenant-id-invalid": "Service Principal Tenant Id was invalid. Check and re-enter.",

"validation-err-subscription-id-missing": "Subscription Id was missing. Provide it.",
"validation-err-subscription-id-invalid": "Subscription Id was invalid. Check and re-enter.",

"validation-err-storage-account-name-missing": "Storage Account Name was missing. Provide it.",
"validation-err-storage-account-name-invalid": "Storage Account Name was invalid. Only lowercase letters and numbers are allowed.",
"validation-err-storage-account-name-length": "Storage Account Name was invalid. It has to be between 3 and 24 characters long.",
"validation-err-storage-table-name-missing": "Storage Table Name was missing. Provide it.",
"validation-err-storage-table-name-invalid": "The value for storage table name is invalid. It has to be alphanumeric and start with an alphabet.",
"validation-err-storage-table-name-length": "The value for storage table name is invalid. It has to be between 3 and 63 characters long.",
"validation-err-storage-partition-key-missing": "Storage Partition Key was missing. Provide it.",
"validation-err-storage-partition-key-invalid": "The value for storage partition key is invalid. /, \\, # and ? characters are not allowed.",
"validation-err-acr-missing": "Azure Container Registry Name was missing. Provide it.",
"validation-err-acr-invalid": "The value for Azure Container Registry name was invalid. It has to be alphanumeric.",
"validation-err-acr-length": "The value for Azure Container Registry name was invalid as it has to be between 5 and 50 characters long.",
"validation-err-storage-key-vault-invalid": "Storage Key Vault was invalid as it cannot only has dash and alphanumeric characters.",
"validation-err-storage-key-vault-start-letter": "Storage Key Vault was invalid as it must start with a letter.",
"validation-err-storage-key-vault-end-char": "Storage Key Vault was invalid as it must end with letter or digit.",
"validation-err-storage-key-vault-hyphen": "Storage Key Vault was invalid as it cannot contain consecutive hyphens.",
"validation-err-storage-key-vault-length": "Storage Key Vault was invalid as it has to be between 3 and 24 characters long.",
"validation-err-storage-access-key-missing": "Storage Access Key was missing. Provide it."
}
}
70 changes: 18 additions & 52 deletions src/lib/setup/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import fs from "fs";
import inquirer from "inquirer";
import * as promptBuilder from "../promptBuilder";
import {
validateAccessToken,
validateAccessTokenThrowable,
validateACRName,
validateOrgName,
validateProjectName,
validateServicePrincipalId,
validateServicePrincipalPassword,
validateServicePrincipalTenantId,
validateSubscriptionId,
validateStorageAccountName,
validateStorageTableName,
validateOrgNameThrowable,
validateProjectNameThrowable,
validateServicePrincipalIdThrowable,
validateServicePrincipalPasswordThrowable,
validateServicePrincipalTenantIdThrowable,
validateSubscriptionIdThrowable,
validateStorageAccountNameThrowable,
validateStorageTableNameThrowable,
} from "../validator";
import {
ACR_NAME,
Expand Down Expand Up @@ -182,24 +182,12 @@ export const validationServicePrincipalInfoFromFile = (
// file needs to contain sp information if user
// choose not to create SP
if (!rc.toCreateSP) {
const vSPId = validateServicePrincipalId(map.az_sp_id);
if (typeof vSPId === "string") {
throw new Error(vSPId);
}
const vSPPassword = validateServicePrincipalPassword(map.az_sp_password);
if (typeof vSPPassword === "string") {
throw new Error(vSPPassword);
}
const vSPTenantId = validateServicePrincipalTenantId(map.az_sp_tenant);
if (typeof vSPTenantId === "string") {
throw new Error(vSPTenantId);
}
validateServicePrincipalIdThrowable(map.az_sp_id);
validateServicePrincipalPasswordThrowable(map.az_sp_password);
validateServicePrincipalTenantIdThrowable(map.az_sp_tenant);
}

const vSubscriptionId = validateSubscriptionId(map.az_subscription_id);
if (typeof vSubscriptionId === "string") {
throw new Error(vSubscriptionId);
}
validateSubscriptionIdThrowable(map.az_subscription_id);
rc.subscriptionId = map.az_subscription_id;
}
};
Expand Down Expand Up @@ -234,32 +222,11 @@ export const getAnswerFromFile = (file: string): RequestContext => {
const map = parseInformationFromFile(file);
map["azdo_project_name"] = map.azdo_project_name || DEFAULT_PROJECT_NAME;

const vOrgName = validateOrgName(map.azdo_org_name);
if (typeof vOrgName === "string") {
throw new Error(vOrgName);
}

const vProjectName = validateProjectName(map.azdo_project_name);
if (typeof vProjectName === "string") {
throw new Error(vProjectName);
}

const vToken = validateAccessToken(map.azdo_pat);
if (typeof vToken === "string") {
throw new Error(vToken);
}

const vStorageAccountName = validateStorageAccountName(
map.az_storage_account_name
);
if (typeof vStorageAccountName === "string") {
throw new Error(vStorageAccountName);
}

const vStorageTable = validateStorageTableName(map.az_storage_table);
if (typeof vStorageTable === "string") {
throw new Error(vStorageTable);
}
validateOrgNameThrowable(map.azdo_org_name);
validateProjectNameThrowable(map.azdo_project_name);
validateAccessTokenThrowable(map.azdo_pat);
validateStorageAccountNameThrowable(map.az_storage_account_name);
validateStorageTableNameThrowable(map.az_storage_table);

const rc: RequestContext = {
accessToken: map.azdo_pat,
Expand All @@ -276,7 +243,6 @@ export const getAnswerFromFile = (file: string): RequestContext => {

rc.toCreateAppRepo = map.az_create_app === "true";
validationServicePrincipalInfoFromFile(rc, map);

return rc;
};

Expand Down
Loading