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 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
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