Skip to content

Commit

Permalink
Merge branch 'microsoft:master' into ross/devcontainer.json
Browse files Browse the repository at this point in the history
  • Loading branch information
ross-p-smith authored Oct 17, 2023
2 parents 153bac7 + 6e590a2 commit 42823f3
Show file tree
Hide file tree
Showing 15 changed files with 11,743 additions and 219 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

All notable changes to the "Azure Api Management VS Code" extension will be documented in this file.

## [1.0.8 - 2023-09-12]

- Fixed loading API Management instances when expanding an Azure subscription

## [1.0.7 - 2023-09-08]

- Update api-version to 2019-12-01
- Fix issue with policy debugging

## [1.0.6 - 2023-05-06]

- Overridding fevents version to move off a vulnerable package

## [1.0.5 - 2022-06-24]

- Enable Authorizations in Consumption Sku

## [1.0.4 - 2022-06-05]

- Update to latest API Management devops resource kit
Expand Down
11,741 changes: 11,617 additions & 124 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-apimanagement",
"displayName": "Azure API Management",
"description": "An Azure API Management extension for Visual Studio Code.",
"version": "1.0.6",
"version": "1.0.8",
"publisher": "ms-azuretools",
"icon": "resources/apim-icon-newone.png",
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
Expand Down Expand Up @@ -820,7 +820,7 @@
"webpack-profile": "webpack --profile --json --mode production > webpack-stats.json && echo Use http://webpack.github.io/analyse to analyze the stats"
},
"devDependencies": {
"@azure/ms-rest-js": "^2.2.0",
"@azure/ms-rest-js": "^2.7.0",
"@types/fs-extra": "^4.0.3",
"@types/gulp": "^4.0.6",
"@types/mocha": "^5.2.6",
Expand Down
45 changes: 30 additions & 15 deletions src/azure/apim/ApimService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,22 @@
import { HttpOperationResponse, ServiceClient } from "@azure/ms-rest-js";
import { TokenCredentialsBase } from "@azure/ms-rest-nodeauth";
import { createGenericClient } from "vscode-azureextensionui";
import { IApimServiceContract, IAuthorizationAccessPolicyContract, IAuthorizationAccessPolicyPropertiesContract, IAuthorizationContract, IAuthorizationLoginLinkRequest, IAuthorizationLoginLinkResponse, IAuthorizationPropertiesContract, IAuthorizationProviderContract, IAuthorizationProviderPropertiesContract, IGatewayApiContract, IGatewayContract, IMasterSubscription, ITokenStoreIdentityProviderContract } from "./contracts";
import * as Constants from "../../constants";
import {
IApimServiceContract,
IAuthorizationAccessPolicyContract,
IAuthorizationAccessPolicyPropertiesContract,
IAuthorizationContract,
IAuthorizationLoginLinkRequest,
IAuthorizationLoginLinkResponse,
IAuthorizationPropertiesContract,
IAuthorizationProviderContract,
IAuthorizationProviderPropertiesContract,
IGatewayApiContract,
IGatewayContract,
IMasterSubscriptionsSecrets,
ITokenStoreIdentityProviderContract
} from "./contracts";

export class ApimService {
public baseUrl: string;
Expand All @@ -15,7 +30,6 @@ export class ApimService {
public subscriptionId: string;
public resourceGroup: string;
public serviceName: string;
private readonly apiVersion: string = "2018-06-01-preview";
private readonly authorizationProviderApiVersion: string = "2021-12-01-preview";

constructor(credentials: TokenCredentialsBase, endPointUrl: string, subscriptionId: string, resourceGroup: string, serviceName: string) {
Expand All @@ -31,7 +45,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "GET",
url: `${this.baseUrl}/gateways?api-version=${this.apiVersion}&$top=100`
url: `${this.baseUrl}/gateways?api-version=${Constants.apimApiVersion}&$top=100`
});
// tslint:disable-next-line: no-unsafe-any
return <IGatewayContract[]>(result.parsedBody.value);
Expand All @@ -41,7 +55,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "GET",
url: `${this.baseUrl}/gateways/${gatewayName}/apis?api-version=${this.apiVersion}&$top=100`
url: `${this.baseUrl}/gateways/${gatewayName}/apis?api-version=${Constants.apimApiVersion}&$top=100`
});
// tslint:disable-next-line: no-unsafe-any
return <IGatewayApiContract[]>(result.parsedBody.value);
Expand All @@ -51,7 +65,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "PUT",
url: `${this.baseUrl}/gateways/${gatewayName}/apis/${apiName}?api-version=${this.apiVersion}`
url: `${this.baseUrl}/gateways/${gatewayName}/apis/${apiName}?api-version=${Constants.apimApiVersion}`
});
// tslint:disable-next-line: no-unsafe-any
return <IGatewayApiContract>(result.parsedBody);
Expand All @@ -61,7 +75,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
await client.sendRequest({
method: "DELETE",
url: `${this.baseUrl}/gateways/${gatewayName}/apis/${apiName}?api-version=${this.apiVersion}`
url: `${this.baseUrl}/gateways/${gatewayName}/apis/${apiName}?api-version=${Constants.apimApiVersion}`
});
}

Expand All @@ -72,7 +86,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "POST",
url: `https://management.azure.com/subscriptions/${this.subscriptionId}/resourceGroups/${this.resourceGroup}/providers/Microsoft.ApiManagement/service/${this.serviceName}/gateways/${gatewayName}/token?api-version=2018-06-01-preview`,
url: `https://management.azure.com/subscriptions/${this.subscriptionId}/resourceGroups/${this.resourceGroup}/providers/Microsoft.ApiManagement/service/${this.serviceName}/gateways/${gatewayName}/token?api-version=${Constants.apimApiVersion}`,
body: {
keyType: keyType,
expiry: expiryDate
Expand All @@ -82,12 +96,13 @@ export class ApimService {
return result.parsedBody.value;
}

public async getSubscriptionMasterkey(): Promise<IMasterSubscription> {
public async getSubscriptionMasterkey(): Promise<IMasterSubscriptionsSecrets> {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "GET",
url: `${this.baseUrl}/subscriptions/master?api-version=${this.apiVersion}`
method: "POST",
url: `${this.baseUrl}/subscriptions/master/listSecrets?api-version=${Constants.apimApiVersion}`
});

// tslint:disable-next-line: no-unsafe-any
return result.parsedBody;
}
Expand Down Expand Up @@ -241,7 +256,7 @@ export class ApimService {
return undefined;
}

// tslint:disable-next-line: no-unsafe-any
// tslint:disable-next-line: no-unsafe-any
return <IAuthorizationProviderContract>(result.parsedBody);
}

Expand All @@ -260,7 +275,7 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "GET",
url: `${this.baseUrl}?api-version=${this.apiVersion}`
url: `${this.baseUrl}?api-version=${Constants.apimApiVersion}`
});
// tslint:disable-next-line:no-any
return <IApimServiceContract>(result.parsedBody);
Expand All @@ -270,10 +285,10 @@ export class ApimService {
const client: ServiceClient = await createGenericClient(this.credentials);
const result: HttpOperationResponse = await client.sendRequest({
method: "PATCH",
url: `${this.baseUrl}?api-version=${this.apiVersion}`,
body: { identity : { type: "systemassigned" } }
url: `${this.baseUrl}?api-version=${Constants.apimApiVersion}`,
body: { identity: { type: "systemassigned" } }
});
// tslint:disable-next-line:no-any
// tslint:disable-next-line:no-any
return <IApimServiceContract>(result.parsedBody);
}

Expand Down
24 changes: 22 additions & 2 deletions src/azure/apim/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface IArmResource {
id: string;
// tslint:disable-next-line: no-reserved-keywords
type: string;
name: string;
// tslint:disable-next-line:no-any
properties: any;
}

export interface IPaged<T> {
value: T[];
count: number;
nextLink?: string;
}

export interface IApimServiceContract {
id: string;
name: string;
Expand Down Expand Up @@ -49,11 +64,16 @@ export interface IGatewayTokenList {
}

export interface IMasterSubscription {
id : string;
name : string;
id: string;
name: string;
properties: ISubscriptionProperty;
}

export interface IMasterSubscriptionsSecrets {
primaryKey: string;
secondaryKey: string;
}

export interface ISubscriptionProperty {
displayName: string;
primaryKey: string;
Expand Down
4 changes: 2 additions & 2 deletions src/commands/debugPolicies/debugPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function getManagementUrl(root: IOperationTreeRoot): string {

async function getDebugGatewayAddressUrl(node: ApiOperationTreeItem): Promise<string> {
// tslint:disable-next-line: prefer-template
const gatewayUrl : string | undefined = ext.context.globalState.get(node.root.serviceName + gatewayHostName);
const gatewayUrl: string | undefined = ext.context.globalState.get(node.root.serviceName + gatewayHostName);
if (gatewayUrl !== undefined) {
return `wss://${gatewayUrl}/debug-0123456789abcdef`;
}
Expand All @@ -73,7 +73,7 @@ async function getDebugGatewayAddressUrl(node: ApiOperationTreeItem): Promise<st
let gatewayHostNameUl = "";
if (hostNameConfigs.length > 1) {
const allHostNames = hostNameConfigs.filter((s) => (s.type === "Proxy"));
const pick = await ext.ui.showQuickPick(allHostNames.map((s) => { return {label: s.hostName, gateway: s}; }), { canPickMany: false});
const pick = await ext.ui.showQuickPick(allHostNames.map((s) => { return { label: s.hostName, gateway: s }; }), { canPickMany: false });
gatewayHostNameUl = `wss://${pick.gateway.hostName}/debug-0123456789abcdef`;
} else {
gatewayHostNameUl = `wss://${hostNameConfigs[0].hostName}/debug-0123456789abcdef`;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/deployGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function getDockerRunCommand(token: string, confEndpoint: string, gatewayName: s
}

function getConfigEndpointUrl(node: GatewayTreeItem): string {
return `"https://${node!.root.serviceName}.management.azure-api.net/subscriptions/${node!.root.subscriptionId}/resourceGroups/${node!.root.resourceGroupName}/providers/Microsoft.ApiManagement/service/${node!.root.serviceName}?api-version=2018-06-01-preview"`;
return `"https://${node!.root.serviceName}.management.azure-api.net/subscriptions/${node!.root.subscriptionId}/resourceGroups/${node!.root.resourceGroupName}/providers/Microsoft.ApiManagement/service/${node!.root.serviceName}?api-version=${Constants.apimApiVersion}"`;
}

function generateDeploymentYaml(gatewayName: string, gatewayToken: string, gatewayEndpoint: string): string {
Expand Down
26 changes: 11 additions & 15 deletions src/commands/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async function extract(node: ApiTreeItem | ServiceTreeItem, apiName?: string): P
},
async () => {
await azUtils.checkAzInstalled();
await dotnetUtils.checkDotnetInstalled();
await dotnetUtils.validateDotnetInstalled();
await runExtractor(configFile, subscriptionId);
}
).then(
Expand Down Expand Up @@ -104,20 +104,16 @@ async function runExtractor(filePath: string, subscriptionId: string): Promise<v
subscriptionId
);

if (await dotnetUtils.checkDotnetVersionInstalled("2.1")) {
await cpUtils.executeCommand(
ext.outputChannel,
workingFolderPath,
'dotnet',
'apimtemplate.dll',
'extract',
'--extractorConfig',
`"${filePath}"`
);
} else {
window.showInformationMessage(localize("dotnetNotInstalled", ".NET framework 2.1 not installed. Please go to 'https://aka.ms/dotnet-core-applaunch?framework=Microsoft.NETCore.App&framework_version=2.1.0&arch=x64&rid=win10-x64' to download"));
throw new Error();
}
await dotnetUtils.validateDotnetInstalled();
await cpUtils.executeCommand(
ext.outputChannel,
workingFolderPath,
'dotnet',
'apimtemplate.dll',
'extract',
'--extractorConfig',
`"${filePath}"`
);
}

async function askFolder(): Promise<Uri[]> {
Expand Down
2 changes: 1 addition & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export enum HttpTriggerDirectionContract {
export const HttpTriggerAuthLevelAdmin = "admin";
export const FunctionAppKeyLength = 40;
export const webAppApiVersion20190801 = "2019-08-01";
export const apimApiVersion = "2019-01-01";
export const apimApiVersion = "2019-12-01";
export const maxTokenValidTimeSpan = 29;
export const gatewayHostName = "CustomerHostName";

Expand Down
37 changes: 8 additions & 29 deletions src/debugger/apimDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import * as request from 'request-promise-native';
import * as vscode from 'vscode';
import { Breakpoint, Handles, InitializedEvent, Logger, logger, LoggingDebugSession, OutputEvent, Scope, StackFrame, StoppedEvent, TerminatedEvent, Thread, ThreadEvent, Variable } from 'vscode-debugadapter';
import { DebugProtocol } from 'vscode-debugprotocol';
import { IArmResource, IMasterSubscriptionsSecrets, IPaged } from "../azure/apim/contracts";
import * as Constants from "../constants";
import { localize } from "../localize";
import { createTemporaryFile } from "../utils/fsUtil";
import { getBearerToken } from '../utils/requestUtil';
Expand Down Expand Up @@ -387,9 +389,9 @@ export class ApimDebugSession extends LoggingDebugSession {
}

private async getMasterSubscriptionKey(managementAddress: string, credential?: TokenCredentialsBase, managementAuth?: string) {
const resourceUrl = `${managementAddress}/subscriptions/master?api-version=2019-01-01`;
const resourceUrl = `${managementAddress}/subscriptions/master/listSecrets?api-version=${Constants.apimApiVersion}`;
const authToken = managementAuth ? managementAuth : await getBearerToken(resourceUrl, "GET", credential!);
const subscription: IApimSubscription = await request.get(resourceUrl, {
const subscription: IMasterSubscriptionsSecrets = await request.post(resourceUrl, {
headers: {
Authorization: authToken
},
Expand All @@ -404,13 +406,13 @@ export class ApimDebugSession extends LoggingDebugSession {
}
});

return subscription.properties.primaryKey;
return subscription.primaryKey;
}

private async getAvailablePolicies(managementAddress: string, credential?: TokenCredentialsBase, managementAuth?: string) {
const resourceUrl = `${managementAddress}/policysnippets?api-version=2019-01-01`;
const resourceUrl = `${managementAddress}/policyDescriptions?api-version=${Constants.apimApiVersion}`;
const authToken = managementAuth ? managementAuth : await getBearerToken(resourceUrl, "GET", credential!);
const snippets: IPolicySnippet[] = await request.get(resourceUrl, {
const policyDescriptions: IPaged<IArmResource> = await request.get(resourceUrl, {
headers: {
Authorization: authToken
},
Expand All @@ -425,19 +427,7 @@ export class ApimDebugSession extends LoggingDebugSession {
}
});

const allPolicies: string[] = [];
let index = 0;
for (const snippet of snippets) {
if (snippet.content !== undefined && snippet.content !== "") {
const idx = /[\s>/]/.exec(snippet.content)!.index;
allPolicies[index] = snippet.content.substring(1, idx);
index += 1;
}
}

// tslint:disable-next-line: no-unnecessary-local-variable
//const allPolicies = snippets.filter(s => s.content !== undefined).map(s => s.content.substring(1, /[\s>/]/.exec(s.content)!.index));
return allPolicies;
return policyDescriptions.value.map(p => p.name);
}

private findThreadByUiId(id: number): [UiRequest, UiThread] | null {
Expand Down Expand Up @@ -515,14 +505,3 @@ export class ApimDebugSession extends LoggingDebugSession {
}
}
}

interface IApimSubscription {
properties: {
primaryKey: string;
secondaryKey: string;
};
}

interface IPolicySnippet {
content: string;
}
2 changes: 1 addition & 1 deletion src/debugger/debuggerConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class DebuggerConnection extends EventEmitter {

public async attach(address: string, key: string, stopOnEntry: boolean) {
let connection: WebSocket;
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
connection = new WebSocket(`${address}?key=${key}`)
.on('error', e => {
if (this.connection == null || this.connection === connection) {
Expand Down
5 changes: 3 additions & 2 deletions src/debugger/policySource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TokenCredentialsBase } from "@azure/ms-rest-nodeauth";
import * as path from 'path';
import * as request from 'request-promise-native';
import { Source } from 'vscode-debugadapter';
import * as Constants from "../constants";
import { getBearerToken } from '../utils/requestUtil';
import { StackFrameScopeContract } from './debuggerConnection';
import { PolicyLocation, PolicyMap, PolicyMapper } from './policyMapper';
Expand Down Expand Up @@ -143,9 +144,9 @@ export class PolicySource {

private getPolicyUrl(scopeId: string): string {
if (scopeId === StackFrameScopeContract.tenant) {
return `${this.managementAddress}/policies/policy?api-version=2019-01-01&format=xml-raw`;
return `${this.managementAddress}/policies/policy?api-version=${Constants.apimApiVersion}&format=xml-raw`;
} else {
return `${this.managementAddress}/${scopeId}/policies/policy?api-version=2019-01-01&format=xml-raw`;
return `${this.managementAddress}/${scopeId}/policies/policy?api-version=${Constants.apimApiVersion}&format=xml-raw`;
}
}
}
Expand Down
Loading

0 comments on commit 42823f3

Please sign in to comment.