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

Commit 7ceb484

Browse files
authored
feat: Added feature to specify Azure subcription ID in CLI before deployment (#203)
* option to specify subscription id from CLI added * Build issue resolved * azureBasePlugin issue resolved * Two test cases added to test subscription ID feature * Changes made accoridng to feedback
1 parent b1feafb commit 7ceb484

File tree

5 files changed

+42
-13
lines changed

5 files changed

+42
-13
lines changed

src/plugins/azureBasePlugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { Guard } from "../shared/guard";
22
import Serverless from "serverless";
33
import { Utils } from "../shared/utils";
44

5-
export abstract class AzureBasePlugin {
5+
export abstract class AzureBasePlugin<TOptions=Serverless.Options> {
66
public constructor(
77
protected serverless: Serverless,
8-
protected options: Serverless.Options,
8+
protected options: TOptions,
99
) {
1010
Guard.null(serverless);
1111
}

src/plugins/deploy/azureDeployPlugin.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { FunctionAppService } from "../../services/functionAppService";
33
import { ResourceService } from "../../services/resourceService";
44
import { Utils } from "../../shared/utils";
55
import { AzureBasePlugin } from "../azureBasePlugin";
6+
import { AzureLoginOptions } from "../../services/loginService";
67

7-
8-
export class AzureDeployPlugin extends AzureBasePlugin {
8+
export class AzureDeployPlugin extends AzureBasePlugin<AzureLoginOptions> {
99
public hooks: { [eventName: string]: Promise<any> };
1010
public commands: any;
1111

12-
public constructor(serverless: Serverless, options: Serverless.Options) {
12+
public constructor(serverless: Serverless, options: AzureLoginOptions) {
1313
super(serverless, options);
1414

1515
this.hooks = {
@@ -31,6 +31,10 @@ export class AzureDeployPlugin extends AzureBasePlugin {
3131
"resourceGroup": {
3232
usage: "Resource group for the service",
3333
shortcut: "g",
34+
},
35+
subscriptionId: {
36+
usage: "Sets the Azure subscription ID",
37+
shortcut: "i",
3438
}
3539
}
3640
}

src/plugins/login/azureLoginPlugin.test.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ describe("Login Plugin", () => {
1010
const envVariables = MockFactory.createTestServicePrincipalEnvVariables()
1111
const credentials = MockFactory.createTestVariables().azureCredentials;
1212

13-
function createPlugin(hasCreds = false, serverless?: Serverless): AzureLoginPlugin {
13+
function createPlugin(hasCreds = false, serverless?: Serverless, options?: Serverless.Options): AzureLoginPlugin {
1414
const sls = serverless || MockFactory.createTestServerless();
1515
if (!hasCreds) {
1616
delete sls.variables["azureCredentials"];
1717
}
18-
const options = MockFactory.createTestServerlessOptions();
19-
return new AzureLoginPlugin(sls, options);
18+
return new AzureLoginPlugin(sls, options || MockFactory.createTestServerlessOptions());
2019
}
2120

2221
function createMockLoginFunction() {
@@ -31,8 +30,8 @@ describe("Login Plugin", () => {
3130
unsetEnvVariables(envVariables);
3231
}
3332

34-
async function invokeLoginHook(hasCreds = false, serverless?: Serverless) {
35-
const plugin = createPlugin(hasCreds, serverless);
33+
async function invokeLoginHook(hasCreds = false, serverless?: Serverless, options?: Serverless.Options) {
34+
const plugin = createPlugin(hasCreds, serverless, options);
3635
await invokeHook(plugin, "before:package:initialize");
3736
}
3837

@@ -92,4 +91,23 @@ describe("Login Plugin", () => {
9291
expect(sls.cli.log).lastCalledWith(`Error: ${errorMessage}`);
9392
expect(process.exit).toBeCalledWith(0);
9493
});
94+
95+
it("Uses the user specified subscription ID", async () => {
96+
const sls = MockFactory.createTestServerless();
97+
const opt = MockFactory.createTestServerlessOptions();
98+
opt["subscriptionId"] = "test-subs-id";
99+
await invokeLoginHook(false, sls, opt);
100+
expect(AzureLoginService.interactiveLogin).toBeCalled()
101+
expect(sls.variables["subscriptionId"]).toEqual("test-subs-id");
102+
expect(sls.cli.log).toBeCalledWith("Using subscription ID: test-subs-id");
103+
})
104+
105+
it("Uses the default subscription ID" , async () => {
106+
const sls = MockFactory.createTestServerless();
107+
const opt = MockFactory.createTestServerlessOptions();
108+
await invokeLoginHook(false, sls, opt);
109+
expect(AzureLoginService.interactiveLogin).toBeCalled()
110+
expect(sls.variables["subscriptionId"]).toEqual("azureSubId");
111+
expect(sls.cli.log).toBeCalledWith("Using subscription ID: azureSubId");
112+
});
95113
});

src/plugins/login/azureLoginPlugin.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import Serverless from "serverless";
22
import AzureProvider from "../../provider/azureProvider";
33
import { AzureLoginService } from "../../services/loginService";
44
import { AzureBasePlugin } from "../azureBasePlugin";
5+
import { AzureLoginOptions } from "../../services/loginService";
56

6-
export class AzureLoginPlugin extends AzureBasePlugin {
7+
export class AzureLoginPlugin extends AzureBasePlugin<AzureLoginOptions> {
78
private provider: AzureProvider;
89
public hooks: { [eventName: string]: Promise<any> };
910

10-
public constructor(serverless: Serverless, options: Serverless.Options) {
11+
public constructor(serverless: Serverless, options: AzureLoginOptions) {
1112
super(serverless, options);
1213
this.provider = (this.serverless.getProvider("azure") as any) as AzureProvider;
1314

@@ -32,7 +33,8 @@ export class AzureLoginPlugin extends AzureBasePlugin {
3233
this.serverless.variables["azureCredentials"] = authResult.credentials;
3334
// Use environment variable for sub ID or use the first subscription in the list (service principal can
3435
// have access to more than one subscription)
35-
this.serverless.variables["subscriptionId"] = process.env.azureSubId || authResult.subscriptions[0].id;
36+
this.serverless.variables["subscriptionId"] = this.options.subscriptionId || process.env.azureSubId || authResult.subscriptions[0].id;
37+
this.serverless.cli.log(`Using subscription ID: ${this.serverless.variables["subscriptionId"]}`);
3638
}
3739
catch (e) {
3840
this.log("Error logging into azure");

src/services/loginService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import open from "open";
2+
import Serverless from "serverless";
23
import {
34
interactiveLoginWithAuthResponse,
45
loginWithServicePrincipalSecretWithAuthResponse,
@@ -7,6 +8,10 @@ import {
78
InteractiveLoginOptions,
89
} from "@azure/ms-rest-nodeauth";
910

11+
export interface AzureLoginOptions extends Serverless.Options {
12+
subscriptionId?: string;
13+
}
14+
1015
export class AzureLoginService {
1116

1217
/**

0 commit comments

Comments
 (0)