Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
feat: Added Azure Naming Service (#221)
Browse files Browse the repository at this point in the history
- [x] Add `AzureNamingService`
- [x] Move naming utils to naming service
- [x] Added `getSafeResourceName` - used by `storageAccount` and `deploymentName`

Resolves [AB#597]
  • Loading branch information
tbarlow12 authored Aug 2, 2019
1 parent 1df392c commit b0c5ef7
Show file tree
Hide file tree
Showing 20 changed files with 359 additions and 272 deletions.
11 changes: 4 additions & 7 deletions src/armTemplates/compositeArmTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import {
ArmResourceTemplateGenerator,
ArmResourceTemplate
} from "../models/armTemplates";
import { Guard } from "../shared/guard";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../models/armTemplates";
import { ServerlessAzureConfig } from "../models/serverless";
import { Utils } from "../shared/utils";
import { AzureNamingService } from "../services/namingService";
import { Guard } from "../shared/guard";

export class CompositeArmTemplate implements ArmResourceTemplateGenerator {
public constructor(private childTemplates: ArmResourceTemplateGenerator[]) {
Expand Down Expand Up @@ -43,7 +40,7 @@ export class CompositeArmTemplate implements ArmResourceTemplateGenerator {
parameters = {
...parameters,
...resource.getParameters(config),
location: Utils.getNormalizedRegionName(config.provider.region)
location: AzureNamingService.getNormalizedRegionName(config.provider.region)
};
});

Expand Down
16 changes: 9 additions & 7 deletions src/armTemplates/resources/apim.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { ServerlessAzureConfig } from "../../models/serverless";
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ApiManagementConfig } from "../../models/apiManagement";
import { Utils } from "../../shared/utils";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ServerlessAzureConfig } from "../../models/serverless";
import { AzureNamingService } from "../../services/namingService";

export class ApimResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.apim && config.provider.apim.name
? config.provider.apim.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-apim`;
return AzureNamingService.getResourceName(
config,
config.provider.apim,
"apim"
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down Expand Up @@ -77,4 +79,4 @@ export class ApimResource implements ArmResourceTemplateGenerator {
apimPublisherName: apimConfig.publisherName,
};
}
}
}
14 changes: 8 additions & 6 deletions src/armTemplates/resources/appInsights.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ServerlessAzureConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { AzureNamingService } from "../../services/namingService";

export class AppInsightsResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.appInsights && config.provider.appInsights.name
? config.provider.appInsights.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-appinsights`;
return AzureNamingService.getResourceName(
config,
config.provider.appInsights,
"appinsights"
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down Expand Up @@ -45,4 +47,4 @@ export class AppInsightsResource implements ArmResourceTemplateGenerator {
appInsightsName: AppInsightsResource.getResourceName(config),
};
}
}
}
16 changes: 9 additions & 7 deletions src/armTemplates/resources/appServicePlan.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ServerlessAzureConfig, ResourceConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ResourceConfig, ServerlessAzureConfig } from "../../models/serverless";
import { AzureNamingService } from "../../services/namingService";

export class AppServicePlanResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.appServicePlan && config.provider.appServicePlan.name
? config.provider.appServicePlan.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-asp`;
return AzureNamingService.getResourceName(
config,
config.provider.appInsights,
"asp"
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down Expand Up @@ -66,4 +68,4 @@ export class AppServicePlanResource implements ArmResourceTemplateGenerator {
appServicePlanSkuTier: resourceConfig.sku.tier,
}
}
}
}
15 changes: 8 additions & 7 deletions src/armTemplates/resources/functionApp.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ServerlessAzureConfig, FunctionAppConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { FunctionAppConfig, ServerlessAzureConfig } from "../../models/serverless";
import { AzureNamingService } from "../../services/namingService";

export class FunctionAppResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
const safeServiceName = config.service.replace(/\s/g, "-");

return config.provider.functionApp && config.provider.functionApp.name
? config.provider.functionApp.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-${safeServiceName}`;
return AzureNamingService.getResourceName(
config,
config.provider.appInsights,
safeServiceName
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down
12 changes: 7 additions & 5 deletions src/armTemplates/resources/hostingEnvironment.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ServerlessAzureConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { AzureNamingService } from "../../services/namingService";

export class HostingEnvironmentResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.hostingEnvironment && config.provider.hostingEnvironment.name
? config.provider.hostingEnvironment.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-ase`;
return AzureNamingService.getResourceName(
config,
config.provider.hostingEnvironment,
"ase"
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down
8 changes: 4 additions & 4 deletions src/armTemplates/resources/storageAccount.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import md5 from "md5";
import { StorageAccountResource } from "./storageAccount";
import { ServerlessAzureConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { AzureNamingService } from "../../services/namingService";
import { StorageAccountResource } from "./storageAccount";

describe("Storage Account Resource", () => {
const config: ServerlessAzureConfig = {
Expand Down Expand Up @@ -142,7 +142,7 @@ describe("Storage Account Resource", () => {
function assertValidStorageAccountName(config: ServerlessAzureConfig, value: string) {
expect(value.length).toBeLessThanOrEqual(24);
expect(value.match(/[a-z0-9]/g).length).toEqual(value.length);
expect(value).toContain(Utils.createShortAzureRegionName(config.provider.region));
expect(value).toContain(AzureNamingService.createShortAzureRegionName(config.provider.region));
expect(value).toContain(createSafeString(config.provider.prefix));
expect(value).toContain(createSafeString(config.provider.stage));
expect(value).toContain(md5(config.service).substr(0, 3));
Expand All @@ -151,4 +151,4 @@ describe("Storage Account Resource", () => {
function createSafeString(value: string) {
return value.replace(/\W+/g, "").toLocaleLowerCase().substr(0, 3);
};
});
});
48 changes: 10 additions & 38 deletions src/armTemplates/resources/storageAccount.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ServerlessAzureConfig, ResourceConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import md5 from "md5";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ResourceConfig, ServerlessAzureConfig } from "../../models/serverless";
import { AzureNamingService } from "../../services/namingService";
import configConstants from "../../config";

export class StorageAccountResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.storageAccount && config.provider.storageAccount.name
? config.provider.storageAccount.name
: StorageAccountResource.getDefaultStorageAccountName(config)
return AzureNamingService.getSafeResourceName(
config,
configConstants.naming.maxLength.storageAccount,
config.provider.storageAccount
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down Expand Up @@ -64,34 +66,4 @@ export class StorageAccountResource implements ArmResourceTemplateGenerator {
storageAccoutSkuTier: resourceConfig.sku.tier,
};
}

/**
* Gets a default storage account name.
* Storage account names can have at most 24 characters and can have only alpha-numerics
* @param config Serverless Azure Config
*/
private static getDefaultStorageAccountName(config: ServerlessAzureConfig): string {
const maxAccountNameLength = 24;
const nameHash = md5(config.service);
const replacer = /\W+/g;

let safePrefix = config.provider.prefix.replace(replacer, "");
const safeRegion = Utils.createShortAzureRegionName(config.provider.region);
let safeStage = Utils.createShortStageName(config.provider.stage);
let safeNameHash = nameHash.substr(0, 6);

const remaining = maxAccountNameLength - (safePrefix.length + safeRegion.length + safeStage.length + safeNameHash.length);

// Dynamically adjust the substring based on space needed
if (remaining < 0) {
const partLength = Math.floor(Math.abs(remaining) / 3);
safePrefix = safePrefix.substr(0, partLength);
safeStage = safeStage.substr(0, partLength);
safeNameHash = safeNameHash.substr(0, partLength);
}

return [safePrefix, safeRegion, safeStage, safeNameHash]
.join("")
.toLocaleLowerCase();
}
}
}
12 changes: 7 additions & 5 deletions src/armTemplates/resources/virtualNetwork.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { ArmResourceTemplateGenerator, ArmResourceTemplate } from "../../models/armTemplates";
import { ArmResourceTemplate, ArmResourceTemplateGenerator } from "../../models/armTemplates";
import { ServerlessAzureConfig } from "../../models/serverless";
import { Utils } from "../../shared/utils";
import { AzureNamingService } from "../../services/namingService";

export class VirtualNetworkResource implements ArmResourceTemplateGenerator {
public static getResourceName(config: ServerlessAzureConfig) {
return config.provider.virtualNetwork && config.provider.virtualNetwork.name
? config.provider.virtualNetwork.name
: `${config.provider.prefix}-${Utils.createShortAzureRegionName(config.provider.region)}-${Utils.createShortStageName(config.provider.stage)}-vnet`;
return AzureNamingService.getResourceName(
config,
config.provider.hostingEnvironment,
"vnet"
);
}

public getTemplate(): ArmResourceTemplate {
Expand Down
10 changes: 10 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ export const configConstants = {
rollback: true,
runFromBlobUrl: false,
},
naming: {
maxLength: {
storageAccount: 24,
deploymentName: 64,
},
suffix: {
deployment: "DEPLOYMENT",
artifact: "ARTIFACT",
}
},
functionAppApiPath: "/api/",
functionAppDomain: ".azurewebsites.net",
functionsAdminApiPath: "/admin/functions/",
Expand Down
4 changes: 2 additions & 2 deletions src/services/apimService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
OperationContract,
ApiPolicyCreateOrUpdateResponse,
} from "@azure/arm-apimanagement/esm/models";
import { Utils } from "../shared/utils";
import { AzureNamingService } from "./namingService";

describe("APIM Service", () => {
const apimConfig = MockFactory.createTestApimConfig();
Expand Down Expand Up @@ -62,7 +62,7 @@ describe("APIM Service", () => {
(serverless.service.provider as any).apim = apimConfigName;

const service = new ApimService(serverless);
const expectedRegionName = Utils.createShortAzureRegionName(service.getRegion());
const expectedRegionName = AzureNamingService.createShortAzureRegionName(service.getRegion());
expect(apimConfigName.name.includes(expectedRegionName)).toBeTruthy();
});

Expand Down
8 changes: 4 additions & 4 deletions src/services/baseService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import fs from "fs";
import mockFs from "mock-fs";
import Serverless from "serverless";
import { ServerlessAzureOptions } from "../models/serverless";
import { Utils } from "../shared/utils";
import { MockFactory } from "../test/mockFactory";
import { BaseService } from "./baseService";
import { AzureNamingService } from "./namingService";

jest.mock("axios", () => jest.fn());
import axios from "axios";
Expand Down Expand Up @@ -42,7 +42,7 @@ describe("Base Service", () => {
let sls: Serverless;

const slsConfig = {
service: "My custom service",
service: "my custom service",
provider: {
resourceGroup: "My-Resource-Group",
deploymentName: "My-Deployment",
Expand Down Expand Up @@ -121,8 +121,8 @@ describe("Base Service", () => {
sls.service.provider["resourceGroup"] = null;
const mockService = new MockService(sls);
const actualResourceGroupName = mockService.getResourceGroupName();
const expectedRegion = Utils.createShortAzureRegionName(mockService.getRegion());
const expectedStage = Utils.createShortStageName(mockService.getStage());
const expectedRegion = AzureNamingService.createShortAzureRegionName(mockService.getRegion());
const expectedStage = AzureNamingService.createShortStageName(mockService.getStage());
const expectedResourceGroupName = `sls-${expectedRegion}-${expectedStage}-${sls.service["service"]}-rg`;

expect(actualResourceGroupName).toEqual(expectedResourceGroupName);
Expand Down
Loading

0 comments on commit b0c5ef7

Please sign in to comment.