我们尝试使用 azuredevops 管道在 Azure API 管理器中以幂等方式自动化跨 API 范围和操作的自定义策略创建。
作为第一个任务,我们必须根据应用程序团队提供的策略列表在不同的场景中创建自定义的initial_policy.xml文件,并且需要根据策略的范围生成它(可能特定于api或可能具体针对其中的单个操作或其中的多个操作)
如果在 api 级别应用相同的策略..我们必须跳过操作级别的策略,并且仅当该策略不存在于 api 级别时才应用它。
因此,如果策略的范围是操作,我们计划从 API 导出策略,并且仅当策略未在 api 级别应用时,才需要为操作修改相同的策略文件。
尝试下面的 bash 任务从输出创建 xml 文件,但它没有以 xml 格式生成。
apiops.sh脚本
#!/bin/bash
api=test-policy
accessTokenResponse=$(az account get-access-token --resource=https://management.core.windows.net/);
#echo "The token response is $accessTokenResponse"
accessToken=$(echo $accessTokenResponse | jq -j '.accessToken');
#echo "The retrieved access token is $accessToken"
authorizationHeader="Bearer $accessToken"
#echo "Generated authorization header $authorizationHeader"
authorizationHeader="Bearer $accessToken"
#echo "Generated authorization header $authorizationHeader"
curl --location 'https://management.azure.com/subscriptions/xxxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.ApiManagement/service/xxxxxx/apis/xxx-api/policies?api-version=2022-08-01&=null' \
-H "Authorization: $authorizationHeader"
./apiops.sh | jq ".value[0].properties.value"
我们可能有以下不同的组合,
完成上述步骤后,在上面创建的自定义initial_policy.xml中,用户输入的参数将被替换(阈值、时间等),并且将创建final_policy.xml。
应用程序管道将按如下方式规划。
stages:
- template: api-ops-pipeline.yaml
parameters:
policyList:
- name: rate_limit_ip
scope: api
apiname: test-policy, test2-policy
- name: IPfilter
scope: operation
ipAddressesFrom: xxxxx
ipAddressesTo: xxxxxxx
operationname: getxxx, getyy, getzz
api-ops-pipeline.yaml
jobs:
- job: api
displayName: 'api policy'
variables:
- group: api_policy
workspace:
clean: all
pool:
name: xxxxxxx
steps:
- ${{ each policy in parameters.policyList }}:
- ${{ if and(eq(policy.name, 'rate_limit_ip'), eq(policy.scope, 'operation') ) }}:
- bash: |
apiName=${{ policy.Name }}
echo "##vso[task.setvariable variable=apiName]$apiName"
xxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxx
name: Resolve_variable
- task: qetza.replacetokens.replacetokens-task.replacetokens@3
displayName: 'create initial xml'
inputs:
rootDirectory: '$(System.DefaultWorkingDirectory)/policy'
targetFiles: initial_policy.xml
tokenPrefix: '${'
tokenSuffix: '}$'
enableTelemetry: false
continueOnError: true
- bash: |
api=test-policy
accessTokenResponse=$(az account get-access-token --resource=https://management.core.windows.net/);
#echo "The token response is $accessTokenResponse"
accessToken=$(echo $accessTokenResponse | jq -j '.accessToken');
#echo "The retrieved access token is $accessToken"
authorizationHeader="Bearer $accessToken"
#echo "Generated authorization header $authorizationHeader"
authorizationHeader="Bearer $accessToken"
#echo "Generated authorization header $authorizationHeader"
curl --location 'https://management.azure.com/subscriptions/xxxxxxxxxxxx/resourceGroups/xxxxxxxxxx/providers/Microsoft.ApiManagement/service/xxxxxx/apis/xxx-api/policies?api-version=2022-08-01&=null' \
-H "Authorization: $authorizationHeader" | jq ".value[0].properties.value"
name: Resolve_variable
您当前的 Bash 脚本正在调用 Azure API 管理 REST API“Api 策略 - 按 Api 列出”以列出 API 级别的策略配置。
jq
”命令解析JSON响应以获取策略配置的XML内容后,没有后续操作将XML内容写入XML文件。如果您通过其他方式运行相同的脚本,例如在本地计算机上手动运行它,也不会生成 XML 文件。
要使用从 REST API“Api Policy - List By Api”获取的 XML 内容生成 XML 文件,您可以尝试如下。
./apiops.sh | jq -r ".value[0].properties.value" > initial_policy.xml
这会将 XML 内容写入 XML 文件 '
initial_policy.xml
':
如果XML文件存在,其原始内容将被新内容覆盖。
如果XML文件不存在,则会自动创建一个新文件,然后写入内容。
此外,要获取 API 级别的策略配置并将其保存到 XML 文件,您还可以尝试使用 Azure PowerShell cmdlet“Get-AzApiManagementPolicy”。
要在管道中调用“Get-AzApiManagementPolicy”cmdlet,您可以尝试如下所示:
创建 ARM 服务连接(Azure 资源管理器服务连接),该连接可以连接并访问 APIM 实例所在的 Azure 订阅和资源组。
AzurePowerShell@5
任务,如下所示。
- task: AzurePowerShell@5
displayName: 'create initial xml'
inputs:
azureSubscription: '{ARM service connection}'
ScriptType: InlineScript
Inline: |
$apimContext = New-AzApiManagementContext -ResourceGroupName "{ResourceGroupName}" -ServiceName "{ServiceName}"
Get-AzApiManagementPolicy -Context $apimContext -ApiId "{ApiId}" -SaveAs "$(System.DefaultWorkingDirectory)\initial_policy.xml"
azurePowerShellVersion: LatestVersion
pwsh: true
{ARM service connection}
:上面创建的ARM服务连接的名称。{ResourceGroupName}
:资源组名称。{ServiceName}
:服务名称。{ApiId}
:API ID。