Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update arm-apimanagement to v9.0.0 #299

Merged
merged 6 commits into from
May 25, 2023
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
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"program": "${workspaceFolder}/system/dist/index.js",
"args": [
"serve",
"${workspaceFolder}/test.yaml"
"${workspaceFolder}/system/package/test.yaml"
],
"envFile": "${workspaceFolder}/.env",
"env": {
Expand Down
10 changes: 5 additions & 5 deletions ingredient/ingredient-apim-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ options:
**apis**

```yaml
apis: #follows this azure spec for *ApiVersionSetContract* : https://github.com/Azure/azure-sdk-for-js/blob/20fe312b1122b21811f9364e3d95fe77202e6466/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L1460
apis: #follows this azure spec for *ApiVersionSetContract* : https://github.com/Azure/azure-sdk-for-js/blob/01898c51c663be4c53e02034a0468cf550ce5279/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L3215
- name: <api-version-name> #unique id for the API (version set) - required
versions:
- versionSchema #See next section for version schema
Expand All @@ -64,7 +64,7 @@ apis: #follows this azure spec for *ApiVersionSetContract* : https://github.com/
**api[n].versions**

```yaml
versions: #follows this azure spec for *ApiCreateOrUpdateParameter* : https://github.com/Azure/azure-sdk-for-js/blob/20fe312b1122b21811f9364e3d95fe77202e6466/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L1310
versions: #follows this azure spec for *ApiCreateOrUpdateParameter* : https://github.com/Azure/azure-sdk-for-js/blob/01898c51c663be4c53e02034a0468cf550ce5279/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L180
- name: <api-name> #typically you want set the id to <api-version-id>-<version> to keep the id consistant for the version set it belongs to - required
version: <string> #version string that will be used as part of the above ApiVersionSetContract.versioningSchema
products: #optional list of product names to assign API to
Expand All @@ -77,15 +77,15 @@ versions: #follows this azure spec for *ApiCreateOrUpdateParameter* : https://gi
**api.versions[n].policies**

```yaml
policies: #scheme follows this azure spec for *PolicyContract* : https://github.com/Azure/azure-sdk-for-js/blob/20fe312b1122b21811f9364e3d95fe77202e6466/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L797
policies: #scheme follows this azure spec for *PolicyContract* : https://github.com/Azure/azure-sdk-for-js/blob/01898c51c663be4c53e02034a0468cf550ce5279/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L3097
- operation: <string> #optional, and if not set this will be the default policy set for the entire api. Otherwise, name of an operation within this api to apply the policy to.
```

**api.versions[n].diagnostics**

```yaml
diagnostics: #scheme follows this azure spec for *PolicyContract* : https://github.com/Azure/azure-sdk-for-js/blob/20fe312b1122b21811f9364e3d95fe77202e6466/sdk/apimanagement/arm-apimanagement/src/models/index.ts#L727
- name: <type of diagnostic> #required name of the diagnostic
diagnostics: #follows this azure spec for *DiagnosticSettingsResource* : https://github.com/Azure/azure-sdk-for-js/blob/20fe312b1122b21811f9364e3d95fe77202e6466/sdk/monitor/arm-monitor/src/models/index.ts#L991
- name: <diagnostics name> #required name of diagnostics settings
```

## Utility Functions
Expand Down
2 changes: 1 addition & 1 deletion ingredient/ingredient-apim-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@types/node": "^10.12.18"
},
"dependencies": {
"@azure/arm-apimanagement": "^6.0.0",
"@azure/arm-apimanagement": "^9.0.0",
"got": "^11.7.0"
},
"publishConfig": {
Expand Down
7 changes: 4 additions & 3 deletions ingredient/ingredient-apim-api/src/functions.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ClientSecretCredential } from '@azure/identity';
import { BaseUtility } from '@azbake/core'
import { ApiManagementClient } from "@azure/arm-apimanagement"
import { ApiGetResponse, BackendGetResponse } from '@azure/arm-apimanagement/esm/models';
import { ApiGetResponse, BackendGetResponse } from '@azure/arm-apimanagement/src/models';

export class ApimApiUtils extends BaseUtility {

public async get_api(resourceGroup: string, apimName: string, apiId: string): Promise<ApiGetResponse> {
const token: any = this.context.AuthToken
const token = new ClientSecretCredential(this.context.AuthToken.domain, this.context.AuthToken.clientId, this.context.AuthToken.secret);

let client = new ApiManagementClient(token, this.context.Environment.authentication.subscriptionId);
let api = await client.api.get(resourceGroup, apimName, apiId);
Expand All @@ -16,7 +17,7 @@ export class ApimApiUtils extends BaseUtility {
}

public async get_backend(resourceGroup: string, apimName: string, backendId: string): Promise<BackendGetResponse> {
const token: any = this.context.AuthToken
const token = new ClientSecretCredential(this.context.AuthToken.domain, this.context.AuthToken.clientId, this.context.AuthToken.secret);

let client = new ApiManagementClient(token, this.context.Environment.authentication.subscriptionId);
let backend = await client.backend.get(resourceGroup, apimName, backendId);
Expand Down
100 changes: 58 additions & 42 deletions ingredient/ingredient-apim-api/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ClientSecretCredential } from '@azure/identity';
import { BaseIngredient, IngredientManager, BakeVariable } from "@azbake/core"
import { ApiManagementClient } from "@azure/arm-apimanagement"
import { DiagnosticCreateOrUpdateOptionalParams, ApiCreateOrUpdateParameter, ApiContract, PolicyContract, ApiPolicyCreateOrUpdateOptionalParams, ProductContract, ApiVersionSetContract, ApiVersionSetCreateOrUpdateOptionalParams, ApiVersionSetContractDetails, DiagnosticContract } from "@azure/arm-apimanagement/esm/models";
import { ApiManagementClient, ProductContract } from "@azure/arm-apimanagement"
import { DiagnosticCreateOrUpdateOptionalParams, ApiCreateOrUpdateParameter, ApiContract, PolicyContract, ApiPolicyCreateOrUpdateOptionalParams, ApiVersionSetContract, ApiVersionSetCreateOrUpdateOptionalParams, ApiVersionSetContractDetails, DiagnosticContract } from "@azure/arm-apimanagement/src/models";
import { RestError } from "@azure/ms-rest-js"
import { PagedAsyncIterableIterator } from '@azure/core-paging';
import * as fs from 'fs';
import stockDiagnostics from "./stockDiagnostics.json"

Expand Down Expand Up @@ -85,7 +87,7 @@ export class ApimApiPlugin extends BaseIngredient {

this._logger.log('APIM API Plugin: Binding APIM to resource: ' + this.resource_group + '\\' + this.resource_name);

const token: any = this._ctx.AuthToken
const token = new ClientSecretCredential(this._ctx.AuthToken.domain, this._ctx.AuthToken.clientId, this._ctx.AuthToken.secret);

this.apim_client = new ApiManagementClient(token, this._ctx.Environment.authentication.subscriptionId)

Expand All @@ -103,14 +105,7 @@ export class ApimApiPlugin extends BaseIngredient {
this.ca_file = fs.readFileSync(pemFile)
}

let apis : Array<ApiContract> = new Array<ApiContract>()
let svcResponse = await this.apim_client.api.listByService(this.resource_group, this.resource_name)
apis = apis.concat(svcResponse)
while(svcResponse.nextLink) {
svcResponse = await this.apim_client.api.listByServiceNext(svcResponse.nextLink)
apis = apis.concat(svcResponse)
}
this.apim_apis = apis
this.apim_apis = await this.GetArrayFromPagedIterator<ApiContract>(this.apim_client.api.listByService(this.resource_group, this.resource_name));

let optionParam =this._ctx.Ingredient.properties.parameters.get('options') || undefined
if (optionParam){
Expand Down Expand Up @@ -194,7 +189,7 @@ export class ApimApiPlugin extends BaseIngredient {
api.apiVersion = api.version
api.apiVersionSetId = apiVersion.id
api.apiVersionSet = apiVersion
let result = await this.apim_client.api.createOrUpdate(this.resource_group, this.resource_name, api.name, api, {ifMatch : '*'})
let result = await this.apim_client.api.beginCreateOrUpdateAndWait(this.resource_group, this.resource_name, api.name, api, {ifMatch : '*'})
this._logger.log("APIM API Plugin: API " + result.displayName + " published")
apiRevisionId = result.apiRevision || ""

Expand Down Expand Up @@ -332,7 +327,7 @@ export class ApimApiPlugin extends BaseIngredient {
let applyDiagnostic = true;

try {
var existingDiagnostics = await this.apim_client.apiDiagnostic.listByService(this.resource_group, this.resource_name, apiId);;
var existingDiagnostics = await this.GetArrayFromPagedIterator<DiagnosticContract>(this.apim_client.apiDiagnostic.listByService(this.resource_group, this.resource_name, apiId));

for (let i = 0; i < existingDiagnostics.length; i++) {
let existingDiagnosticsLoggerId = existingDiagnostics[i].loggerId || ""
Expand All @@ -352,21 +347,17 @@ export class ApimApiPlugin extends BaseIngredient {

if (applyDiagnostic) {
let logErrMessage = "APIM API Plugin: Could not apply diagnostics " + diagnostics.name + " to API " + apiId;
try {
let apiResponse = await this.apim_client.apiDiagnostic.createOrUpdate(

await this.apim_client.apiDiagnostic
.createOrUpdate(
this.resource_group,
this.resource_name,
apiId,
diagnostics.name,
diagnostics,
<DiagnosticCreateOrUpdateOptionalParams>{ifMatch:'*'})

if (apiResponse._response.status != 200 && apiResponse._response.status != 201){
this._logger.error(logErrMessage)
}
} catch (error) {
this._logger.error(logErrMessage + ": '" + error + "'")
}
<DiagnosticCreateOrUpdateOptionalParams>{ifMatch:'*'}
)
.catch((error) => this._logger.error(logErrMessage + '\n' + error))
}
}

Expand All @@ -380,16 +371,29 @@ export class ApimApiPlugin extends BaseIngredient {
let policyData = await this.ResolvePolicy(policy)

if (operation == "base") {
let response = await this.apim_client.apiPolicy.createOrUpdate(this.resource_group, this.resource_name, apiId, policyData, <ApiPolicyCreateOrUpdateOptionalParams>{ifMatch: '*'})
if (response._response.status != 200 && response._response.status != 201) {
this._logger.error("APIM API Plugin: Could not apply API Policy for API " + apiId)
}
await this.apim_client.apiPolicy
.createOrUpdate(
this.resource_group,
this.resource_name,
apiId,
"policy",
policyData,
<ApiPolicyCreateOrUpdateOptionalParams>{ifMatch: '*'}
)
.catch((error) => this._logger.error("APIM API Plugin: Could not apply API Policy for API " + apiId + '\n' + error))
}
else {
let response = await this.apim_client.apiOperationPolicy.createOrUpdate(this.resource_group, this.resource_name, apiId, operation, policyData,<ApiPolicyCreateOrUpdateOptionalParams>{ifMatch: '*'})
if (response._response.status != 200 && response._response.status != 201) {
this._logger.error("APIM API Plugin: Could not apply API Policy for API " + apiId + " operation: " + operation)
}
await this.apim_client.apiOperationPolicy
.createOrUpdate(
this.resource_group,
this.resource_name,
apiId,
operation,
"policy",
policyData,
<ApiPolicyCreateOrUpdateOptionalParams>{ifMatch: '*'}
)
.catch((error) => this._logger.error("APIM API Plugin: Could not apply API Policy for API " + apiId + " operation: " + operation + '\n' + error))
}
}

Expand All @@ -398,25 +402,24 @@ export class ApimApiPlugin extends BaseIngredient {
if (this.apim_client == undefined) return

//Clean existing products if different than the one you are assigning to
var existingProducts = await this.apim_client.apiProduct.listByApis(this.resource_group, this.resource_name, apiId);
var existingProducts = await this.GetArrayFromPagedIterator<ProductContract>(this.apim_client.apiProduct.listByApis(this.resource_group, this.resource_name, apiId));

for (let i = 0; i < existingProducts.length; i++) {
let oldProductId = existingProducts[i].name || ""

if(oldProductId != productId)
{
await this.apim_client.productApi.deleteMethod(this.resource_group, this.resource_name, oldProductId, apiId)
.then((result) => { this._logger.log('APIM API Plugin: Deleting API: ' + apiId + " from product " + oldProductId)})
.catch((failure) => {this._logger.error("APIM API Plugin: Could not delete API " + apiId + "from product " + oldProductId) })
await this.apim_client.productApi.delete(this.resource_group, this.resource_name, oldProductId, apiId)
.then(() => { this._logger.log('APIM API Plugin: Deleting API: ' + apiId + " from product " + oldProductId)})
.catch((failure) => {this._logger.error("APIM API Plugin: Could not delete API " + apiId + "from product " + oldProductId + '\n' + failure) })
}
}

this._logger.log('APIM API Plugin: Assigning APIs: ' + apiId + " to product " + productId)

let apiResponse = await this.apim_client.productApi.createOrUpdate(this.resource_group, this.resource_name, productId, apiId)
if (apiResponse._response.status != 200 && apiResponse._response.status != 201){
this._logger.error("APIM API Plugin: Could not bind API " + apiId + "to product " + productId)
}
await this.apim_client.productApi
.createOrUpdate(this.resource_group, this.resource_name, productId, apiId)
.catch((error) => this._logger.error("APIM API Plugin: Could not bind API " + apiId + "to product " + productId + '\n' + error))
}

private GetApi(id: string): ApiContract | null {
Expand Down Expand Up @@ -446,7 +449,7 @@ export class ApimApiPlugin extends BaseIngredient {

let blockTime = (this.apim_options || <IApimOptions>{}).apiWaitTime

if (policy.value.startsWith("file:///")) {
if (policy.value && policy.value.startsWith("file:///")) {

let content = fs.readFileSync(policy.value.replace("file:///", "")).toString('utf-8')
policy.format = "xml";
Expand Down Expand Up @@ -477,5 +480,18 @@ export class ApimApiPlugin extends BaseIngredient {
setTimeout(resolve,ms)
})
}
}
//https://docs.microsoft.com/en-us/javascript/api/azure-arm-apimanagement/propertycontract?view=azure-node-latest

private async GetArrayFromPagedIterator<T>(pagedIterator: PagedAsyncIterableIterator<T>) : Promise<T[]>
{
let retArray : Array<T> = new Array<T>()

const pages = pagedIterator.byPage();
for await (const page of pages) {
for (const item of page) {
retArray.push(item);
}
}

return retArray;
}
}
Loading