Skip to content

Commit 63c8fff

Browse files
Use Product and API Subscriptions in all Infrastructures and Samples (#79)
1 parent 148a82c commit 63c8fff

File tree

28 files changed

+398
-87
lines changed

28 files changed

+398
-87
lines changed

infrastructure/afd-apim-pe/create.ipynb

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
" apim_service_id = output.get('apimServiceId', 'APIM Service Id')\n",
119119
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
120120
" afd_endpoint_url = output.get('fdeSecureUrl', 'Front Door Endpoint URL')\n",
121+
" apim_apis = output.getJson('apiOutputs', 'APIs')\n",
121122
"\n",
122123
"utils.print_ok('Deployment completed')\n"
123124
]
@@ -187,9 +188,11 @@
187188
"from apimrequests import ApimRequests\n",
188189
"from apimtesting import ApimTesting\n",
189190
"\n",
190-
"reqs = ApimRequests(apim_gateway_url)\n",
191191
"tests = ApimTesting(\"AFD-APIM-PE Tests (Pre-Lockdown)\", deployment, deployment)\n",
192192
"\n",
193+
"api_subscription_key = apim_apis[0]['subscriptionPrimaryKey']\n",
194+
"reqs = ApimRequests(apim_gateway_url, api_subscription_key)\n",
195+
"\n",
193196
"utils.print_message('Calling Hello World (Root) API via API Management Gateway URL. Expect 200 (if run before disabling API Management public network access).')\n",
194197
"output = reqs.singleGet('/')\n",
195198
"tests.verify(output, 'Hello World from API Management!')\n",
@@ -228,8 +231,9 @@
228231
" raise SystemExit('Deployment failed')\n",
229232
" \n",
230233
"if output.success and output.json_data:\n",
231-
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
232234
" afd_endpoint_url = output.get('fdeSecureUrl', 'Front Door Endpoint URL')\n",
235+
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
236+
" apim_apis = output.getJson('apiOutputs', 'APIs')\n",
233237
"\n",
234238
"utils.print_ok('Deployment completed')\n"
235239
]
@@ -250,35 +254,47 @@
250254
"outputs": [],
251255
"source": [
252256
"import utils\n",
253-
"import json\n",
254257
"from apimrequests import ApimRequests\n",
255258
"from apimtesting import ApimTesting\n",
256259
"\n",
257-
"reqsApim = ApimRequests(apim_gateway_url)\n",
258-
"reqsAfd = ApimRequests(afd_endpoint_url)\n",
259260
"tests = ApimTesting(\"AFD-APIM-PE Tests (Post-Lockdown)\", deployment, deployment)\n",
260261
"\n",
262+
"api_subscription_key = apim_apis[0]['subscriptionPrimaryKey']\n",
263+
"reqsApim = ApimRequests(apim_gateway_url, api_subscription_key)\n",
264+
"reqsAfd = ApimRequests(afd_endpoint_url, api_subscription_key)\n",
265+
"\n",
261266
"# 1) Unsuccessful call to APIM Gateway URL (should fail with 403 Forbidden)\n",
262267
"output = reqsApim.singleGet('/', msg = '1) Calling Hello World (Root) API via API Management Gateway URL. Expect 403 as APIM public access is disabled now.')\n",
263-
"tests.verify(json.loads(output)['statusCode'], 403)\n",
268+
"outputJson = utils.get_json(output)\n",
269+
"tests.verify(outputJson['statusCode'], 403)\n",
264270
"\n",
265271
"# 2) Successful call to Front Door (200)\n",
266272
"output = reqsAfd.singleGet('/', msg = '2) Calling Hello World (Root) API via Azure Front Door. Expect 200.')\n",
267273
"tests.verify(output, 'Hello World from API Management!')\n",
268274
"\n",
269275
"# 3) Successful calls to Front Door -> APIM -> ACA (200)\n",
270276
"if use_ACA:\n",
277+
" reqsAfd = ApimRequests(afd_endpoint_url, apim_apis[1]['subscriptionPrimaryKey'])\n",
271278
" output = reqsAfd.singleGet('/aca-1', msg = '3) Calling Hello World (ACA 1) API via Azure Front Door. Expect 200.')\n",
272279
" tests.verify(output, 'Hello World!')\n",
273280
"\n",
281+
" reqsAfd = ApimRequests(afd_endpoint_url, apim_apis[2]['subscriptionPrimaryKey'])\n",
274282
" output = reqsAfd.singleGet('/aca-2', msg = '4) Calling Hello World (ACA 2) API via Azure Front Door. Expect 200.')\n",
275283
" tests.verify(output, 'Hello World!')\n",
276284
"\n",
285+
" reqsAfd = ApimRequests(afd_endpoint_url, apim_apis[3]['subscriptionPrimaryKey'])\n",
277286
" output = reqsAfd.singleGet('/aca-pool', msg = '5) Calling Hello World (ACA Pool) API via Azure Front Door. Expect 200.')\n",
278287
" tests.verify(output, 'Hello World!')\n",
279288
"else:\n",
280289
" utils.print_message('ACA APIs were not created. Skipping ACA API calls.', blank_above = True)\n",
281290
"\n",
291+
"# 4) Unsuccessful call to Front Door without API subscription key (should fail with 401 Unauthorized)\n",
292+
"reqsNoApiSubscription = ApimRequests(afd_endpoint_url)\n",
293+
"output = reqsNoApiSubscription.singleGet('/', msg = 'Calling Hello World (Root) API without API subscription key. Expect 401.')\n",
294+
"outputJson = utils.get_json(output)\n",
295+
"tests.verify(outputJson['statusCode'], 401)\n",
296+
"tests.verify(outputJson['message'], 'Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.')\n",
297+
"\n",
282298
"tests.print_summary()\n",
283299
"\n",
284300
"utils.print_ok('All done!')"

infrastructure/afd-apim-pe/main.bicep

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,5 +311,16 @@ output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl
311311
output fdeHostName string = afdModule.outputs.fdeHostName
312312
output fdeSecureUrl string = afdModule.outputs.fdeSecureUrl
313313

314-
#disable-next-line outputs-should-not-contain-secrets
315-
//output apimSubscription1Key string = apimModule.outputs.[0].listSecrets().primaryKey
314+
// API outputs
315+
output apiOutputs array = [for i in range(0, length(apis)): {
316+
name: apis[i].name
317+
resourceId: apisModule[i].?outputs.?apiResourceId ?? ''
318+
displayName: apisModule[i].?outputs.?apiDisplayName ?? ''
319+
productAssociationCount: apisModule[i].?outputs.?productAssociationCount ?? 0
320+
subscriptionResourceId: apisModule[i].?outputs.?subscriptionResourceId ?? ''
321+
subscriptionName: apisModule[i].?outputs.?subscriptionName ?? ''
322+
subscriptionPrimaryKey: apisModule[i].?outputs.?subscriptionPrimaryKey ?? ''
323+
subscriptionSecondaryKey: apisModule[i].?outputs.?subscriptionSecondaryKey ?? ''
324+
}]
325+
326+
// [ADD RELEVANT OUTPUTS HERE]

infrastructure/apim-aca/create.ipynb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@
104104
" raise SystemExit('Deployment failed')\n",
105105
"\n",
106106
"if output.success and output.json_data:\n",
107-
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
108-
" aca_url_1 = output.get('acaUrl1', 'ACA Backend 1 URL')\n",
109-
" aca_url_2 = output.get('acaUrl2', 'ACA Backend 2 URL')\n",
107+
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
108+
" aca_url_1 = output.get('acaUrl1', 'ACA Backend 1 URL')\n",
109+
" aca_url_2 = output.get('acaUrl2', 'ACA Backend 2 URL')\n",
110+
" apim_apis = output.getJson('apiOutputs', 'APIs')\n",
110111
"\n",
111112
"utils.print_ok('Deployment completed')"
112113
]
@@ -130,24 +131,33 @@
130131
"from apimrequests import ApimRequests\n",
131132
"from apimtesting import ApimTesting\n",
132133
"\n",
133-
"reqs = ApimRequests(apim_gateway_url)\n",
134134
"tests = ApimTesting(\"APIM-ACA Tests\", deployment, deployment)\n",
135135
"\n",
136+
"reqs = ApimRequests(apim_gateway_url, apim_apis[0]['subscriptionPrimaryKey'])\n",
136137
"output = reqs.singleGet('/', msg = 'Calling Hello World (Root) API')\n",
137138
"tests.verify(output, 'Hello World from API Management!')\n",
138139
"\n",
140+
"reqs = ApimRequests(apim_gateway_url, apim_apis[1]['subscriptionPrimaryKey'])\n",
139141
"output = reqs.singleGet('/aca-1/', msg = 'Calling Hello World (ACA Backend 1) API')\n",
140142
"tests.verify(output, 'Hello World!')\n",
141143
"\n",
144+
"reqs = ApimRequests(apim_gateway_url, apim_apis[2]['subscriptionPrimaryKey'])\n",
142145
"output = reqs.singleGet('/aca-2/', msg = 'Calling Hello World (ACA Backend 2) API')\n",
143146
"tests.verify(output, 'Hello World!')\n",
144147
"\n",
148+
"reqs = ApimRequests(apim_gateway_url, apim_apis[3]['subscriptionPrimaryKey'])\n",
145149
"output = reqs.multiGet('/aca-pool/', 3, msg = 'Calling Hello World (ACA Backend Pool) API')\n",
146150
"tests.verify(len(output), 3)\n",
147151
"tests.verify(output[0]['response'], 'Hello World!')\n",
148152
"tests.verify(output[1]['response'], 'Hello World!')\n",
149153
"tests.verify(output[2]['response'], 'Hello World!')\n",
150154
"\n",
155+
"reqsNoApiSubscription = ApimRequests(apim_gateway_url)\n",
156+
"output = reqsNoApiSubscription.singleGet('/', msg = 'Calling Hello World (Root) API without API subscription key. Expect 401.')\n",
157+
"outputJson = utils.get_json(output)\n",
158+
"tests.verify(outputJson['statusCode'], 401)\n",
159+
"tests.verify(outputJson['message'], 'Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.')\n",
160+
"\n",
151161
"tests.print_summary()\n",
152162
"\n",
153163
"utils.print_ok('All done!')"

infrastructure/apim-aca/main.bicep

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,17 @@ output apimServiceName string = apimModule.outputs.name
181181
output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl
182182
output acaUrl1 string = 'https://${acaModule1.outputs.containerAppFqdn}'
183183
output acaUrl2 string = 'https://${acaModule2.outputs.containerAppFqdn}'
184+
185+
// API outputs
186+
output apiOutputs array = [for i in range(0, length(apis)): {
187+
name: apis[i].name
188+
resourceId: apisModule[i].?outputs.?apiResourceId ?? ''
189+
displayName: apisModule[i].?outputs.?apiDisplayName ?? ''
190+
productAssociationCount: apisModule[i].?outputs.?productAssociationCount ?? 0
191+
subscriptionResourceId: apisModule[i].?outputs.?subscriptionResourceId ?? ''
192+
subscriptionName: apisModule[i].?outputs.?subscriptionName ?? ''
193+
subscriptionPrimaryKey: apisModule[i].?outputs.?subscriptionPrimaryKey ?? ''
194+
subscriptionSecondaryKey: apisModule[i].?outputs.?subscriptionSecondaryKey ?? ''
195+
}]
196+
197+
// [ADD RELEVANT OUTPUTS HERE]

infrastructure/simple-apim/create.ipynb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"\n",
9090
"if output.success and output.json_data:\n",
9191
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
92+
" apim_apis = output.getJson('apiOutputs', 'APIs')\n",
9293
"\n",
9394
"utils.print_ok('Deployment completed')"
9495
]
@@ -112,12 +113,20 @@
112113
"from apimrequests import ApimRequests\n",
113114
"from apimtesting import ApimTesting\n",
114115
"\n",
115-
"reqs = ApimRequests(apim_gateway_url)\n",
116116
"tests = ApimTesting(\"Simple APIM Tests\", deployment, deployment)\n",
117117
"\n",
118-
"output = reqs.singleGet('/', msg = 'Calling Hello World (Root) API')\n",
118+
"api_subscription_key = apim_apis[0]['subscriptionPrimaryKey']\n",
119+
"reqs = ApimRequests(apim_gateway_url, api_subscription_key)\n",
120+
"\n",
121+
"output = reqs.singleGet('/', msg = 'Calling Hello World (Root) API. Expect 200.')\n",
119122
"tests.verify(output, 'Hello World from API Management!')\n",
120123
"\n",
124+
"reqsNoApiSubscription = ApimRequests(apim_gateway_url)\n",
125+
"output = reqsNoApiSubscription.singleGet('/', msg = 'Calling Hello World (Root) API without API subscription key. Expect 401.')\n",
126+
"outputJson = utils.get_json(output)\n",
127+
"tests.verify(outputJson['statusCode'], 401)\n",
128+
"tests.verify(outputJson['message'], 'Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.')\n",
129+
"\n",
121130
"tests.print_summary()\n",
122131
"\n",
123132
"utils.print_ok('All done!')"

infrastructure/simple-apim/main.bicep

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,16 @@ output apimServiceId string = apimModule.outputs.id
9191
output apimServiceName string = apimModule.outputs.name
9292
output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl
9393

94-
#disable-next-line outputs-should-not-contain-secrets
95-
//output apimSubscription1Key string = apimModule.outputs.[0].listSecrets().primaryKey
94+
// API outputs
95+
output apiOutputs array = [for i in range(0, length(apis)): {
96+
name: apis[i].name
97+
resourceId: apisModule[i].?outputs.?apiResourceId ?? ''
98+
displayName: apisModule[i].?outputs.?apiDisplayName ?? ''
99+
productAssociationCount: apisModule[i].?outputs.?productAssociationCount ?? 0
100+
subscriptionResourceId: apisModule[i].?outputs.?subscriptionResourceId ?? ''
101+
subscriptionName: apisModule[i].?outputs.?subscriptionName ?? ''
102+
subscriptionPrimaryKey: apisModule[i].?outputs.?subscriptionPrimaryKey ?? ''
103+
subscriptionSecondaryKey: apisModule[i].?outputs.?subscriptionSecondaryKey ?? ''
104+
}]
105+
106+
// [ADD RELEVANT OUTPUTS HERE]

samples/_TEMPLATE/create.ipynb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@
7777
"output = nb_helper.deploy_bicep(bicep_parameters)\n",
7878
"\n",
7979
"if output.json_data:\n",
80-
" apim_name = output.get('apimServiceName', 'APIM Service Name')\n",
80+
" afd_endpoint_url = output.get('fdeSecureUrl', 'Front Door Endpoint URL') # may be deleted if Front Door is not part of a supported infrastructure\n",
81+
" apim_name = output.get('apimServiceName', 'APIM Service Name')\n",
8182
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
83+
" apim_apis = output.getJson('apiOutputs', 'APIs')\n",
8284
"\n",
8385
"utils.print_ok('Deployment completed')"
8486
]
@@ -102,12 +104,17 @@
102104
"source": [
103105
"import utils\n",
104106
"from apimrequests import ApimRequests\n",
107+
"from apimtesting import ApimTesting\n",
105108
"\n",
106-
"# [ADD RELEVANT TESTS HERE]\n",
109+
"tests = ApimTesting(\"Simple APIM Tests\", deployment, deployment)\n",
107110
"\n",
108111
"# 1) Issue a direct request to API Management\n",
109-
"# reqsApim = ApimRequests(apim_gateway_url)\n",
110-
"# reqsApim.singleGet('/request-headers', msg = 'Calling Request Headers API via API Management Gateway URL. Response codes 200 and 403 are both valid depending on the infrastructure used.')\n",
112+
"\n",
113+
"api_subscription_key = apim_apis[0]['subscriptionPrimaryKey']\n",
114+
"reqsApim = ApimRequests(apim_gateway_url, api_subscription_key)\n",
115+
"reqsAfd = ApimRequests(afd_endpoint_url, api_subscription_key) # may be deleted if Front Door is not part of a supported infrastructure\n",
116+
"\n",
117+
"# reqsApim.singleGet('/', msg = 'Calling Hello World (Root) API via API Management Gateway URL. Response codes 200 and 403 are both valid depending on the infrastructure used.')\n",
111118
"\n",
112119
"# # 2) Issue requests against Front Door.\n",
113120
"# # Check if the infrastructure architecture deployment uses Azure Front Door.\n",
@@ -116,7 +123,14 @@
116123
"\n",
117124
"# if afd_endpoint_url:\n",
118125
"# reqsAfd = ApimRequests(afd_endpoint_url)\n",
119-
"# reqsAfd.singleGet('/request-headers', msg = 'Calling Request Headers API via via Azure Front Door. Expect 200.')\n",
126+
"# reqsAfd.singleGet('/', msg = 'Calling Hello World (Root) API via via Azure Front Door. Expect 200.')\n",
127+
"\n",
128+
"# # 3) Unsuccessful call to Front Door without API subscription key (should fail with 401 Unauthorized)\n",
129+
"# reqsNoApiSubscription = ApimRequests(afd_endpoint_url)\n",
130+
"# output = reqsNoApiSubscription.singleGet('/', msg = 'Calling Hello World (Root) API without API subscription key. Expect 401.')\n",
131+
"# outputJson = utils.get_json(output)\n",
132+
"# tests.verify(outputJson['statusCode'], 401)\n",
133+
"# tests.verify(outputJson['message'], 'Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API.')\n",
120134
"\n",
121135
"utils.print_ok('All done!')"
122136
]

samples/_TEMPLATE/main.bicep

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,17 @@ module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in a
5353
output apimServiceId string = apimService.id
5454
output apimServiceName string = apimService.name
5555
output apimResourceGatewayURL string = apimService.properties.gatewayUrl
56+
57+
// API outputs
58+
output apiOutputs array = [for i in range(0, length(apis)): {
59+
name: apis[i].name
60+
resourceId: apisModule[i].?outputs.?apiResourceId ?? ''
61+
displayName: apisModule[i].?outputs.?apiDisplayName ?? ''
62+
productAssociationCount: apisModule[i].?outputs.?productAssociationCount ?? 0
63+
subscriptionResourceId: apisModule[i].?outputs.?subscriptionResourceId ?? ''
64+
subscriptionName: apisModule[i].?outputs.?subscriptionName ?? ''
65+
subscriptionPrimaryKey: apisModule[i].?outputs.?subscriptionPrimaryKey ?? ''
66+
subscriptionSecondaryKey: apisModule[i].?outputs.?subscriptionSecondaryKey ?? ''
67+
}]
68+
5669
// [ADD RELEVANT OUTPUTS HERE]

samples/authX-pro/create.ipynb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@
121121
"output = nb_helper.deploy_bicep(bicep_parameters)\n",
122122
"\n",
123123
"if output.json_data:\n",
124-
" apim_name = output.get('apimServiceName', 'APIM Service Name')\n",
124+
" apim_name = output.get('apimServiceName', 'APIM Service Name')\n",
125125
" apim_gateway_url = output.get('apimResourceGatewayURL', 'APIM API Gateway URL')\n",
126-
" apim_products = output.getJson('productOutputs', 'Products')\n",
126+
" apim_products = output.getJson('productOutputs', 'Products')\n",
127127
"\n",
128128
"utils.print_ok('Deployment completed')"
129129
]
@@ -152,11 +152,10 @@
152152
"from users import UserHelper\n",
153153
"from authfactory import AuthFactory\n",
154154
"\n",
155-
"# Test the function\n",
156-
"hr_product_apim_subscription_key = apim_products[0]['subscriptionPrimaryKey']\n",
157-
"\n",
158155
"tests = ApimTesting(\"AuthX-Pro Sample Tests\", sample_folder, deployment)\n",
159156
"\n",
157+
"hr_product_apim_subscription_key = apim_products[0]['subscriptionPrimaryKey']\n",
158+
"\n",
160159
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door. If so, assume that APIM is not directly accessible and use the Front Door URL instead.\n",
161160
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
162161
"\n",

samples/authX-pro/main.bicep

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,16 @@ output apimResourceGatewayURL string = apimService.properties.gatewayUrl
108108

109109
// Product outputs
110110
output productOutputs array = [for i in range(0, length(products)): {
111-
productResourceId: productModule[i].outputs.productResourceId
112-
productName: productModule[i].outputs.productName
113-
productDisplayName: productModule[i].outputs.productDisplayName
114-
productState: productModule[i].outputs.productState
111+
resourceId: productModule[i].outputs.productResourceId
112+
name: productModule[i].outputs.productName
113+
displayName: productModule[i].outputs.productDisplayName
114+
state: productModule[i].outputs.productState
115115
subscriptionRequired: productModule[i].outputs.subscriptionRequired
116116
approvalRequired: productModule[i].outputs.approvalRequired
117117
policyResourceId: productModule[i].outputs.policyResourceId
118118
hasPolicyAttached: productModule[i].outputs.hasPolicyAttached
119119
subscriptionResourceId: productModule[i].outputs.subscriptionResourceId
120+
subscriptionName: productModule[i].outputs.subscriptionName
120121
subscriptionPrimaryKey: productModule[i].outputs.subscriptionPrimaryKey
121122
subscriptionSecondaryKey: productModule[i].outputs.subscriptionSecondaryKey
122123
}]

0 commit comments

Comments
 (0)