diff --git a/sdk/mixedreality/test-resources.bicep b/sdk/mixedreality/test-resources.bicep new file mode 100644 index 00000000000..4b6614b214d --- /dev/null +++ b/sdk/mixedreality/test-resources.bicep @@ -0,0 +1,25 @@ +param baseName string = resourceGroup().name +param location string = resourceGroup().location +param testApplicationOid string + + +var apiVersion = '2021-03-01-preview' +var rrAccountName = '${baseName}-arr-account' +var remoteRenderingAdminRoleId = '3df8b902-2a6f-47c7-8cc5-360e9b272a7e' + +resource remoteRenderingAccount 'Microsoft.MixedReality/remoteRenderingAccounts@2021-03-01-preview' = { + name: rrAccountName + location: location +} + +resource remoteRenderingAdminRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(remoteRenderingAccount.id, testApplicationOid, remoteRenderingAdminRoleId) + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', remoteRenderingAdminRoleId) + principalId: testApplicationOid + } +} + +output MIXEDREALITY_ACCOUNT_ID string = remoteRenderingAccount.properties.accountId +output MIXEDREALITY_ACCOUNT_DOMAIN string = remoteRenderingAccount.properties.accountDomain +output MIXEDREALITY_ACCOUNT_KEY string = listKeys(remoteRenderingAccount.id, apiVersion).primaryKey diff --git a/sdk/mixedreality/test-resources.json b/sdk/mixedreality/test-resources.json deleted file mode 100644 index 1a7f9c6fb10..00000000000 --- a/sdk/mixedreality/test-resources.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "baseName": { - "type": "string", - "defaultValue": "[resourceGroup().name]", - "metadata": { - "description": "The base resource name." - } - }, - "tenantId": { - "type": "string", - "defaultValue": "72f988bf-86f1-41af-91ab-2d7cd011db47", - "metadata": { - "description": "The tenant ID to which the application and resources belong." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "The location of the resource. By default, this is the same as the resource group." - } - } - }, - "variables": { - "apiVersion": "2020-05-01", - "asaAccountName": "[concat(parameters('baseName'), '-asa-account')]" - }, - "resources": [ - { - "type": "Microsoft.MixedReality/spatialAnchorsAccounts", - "name": "[variables('asaAccountName')]", - "apiVersion": "[variables('apiVersion')]", - "location": "[parameters('location')]", - "properties": {} - } - ], - "outputs": { - "MIXEDREALITY_ACCOUNT_ID": { - "type": "string", - "value": "[reference(variables('asaAccountName')).accountId]" - }, - "MIXEDREALITY_ACCOUNT_DOMAIN": { - "type": "string", - "value": "[reference(variables('asaAccountName')).accountDomain]" - }, - "MIXEDREALITY_ACCOUNT_KEY": { - "type": "string", - "value": "[listKeys(resourceId('Microsoft.MixedReality/spatialAnchorsAccounts', variables('asaAccountName')), variables('apiVersion')).primaryKey]" - } - } -} diff --git a/sdk/remoterendering/mixed-reality-remote-rendering/karma.conf.js b/sdk/remoterendering/mixed-reality-remote-rendering/karma.conf.js index ef013bff136..7775d630efa 100644 --- a/sdk/remoterendering/mixed-reality-remote-rendering/karma.conf.js +++ b/sdk/remoterendering/mixed-reality-remote-rendering/karma.conf.js @@ -48,6 +48,8 @@ module.exports = function (config) { envPreprocessor: [ "TEST_MODE", + "STORAGE_ACCOUNT_NO_ACCESS_NAME", + "BLOB_CONTAINER_NO_ACCESS_NAME", "REMOTERENDERING_ARR_STORAGE_ACCOUNT_NAME", "REMOTERENDERING_ARR_BLOB_CONTAINER_NAME", "REMOTERENDERING_ARR_ACCOUNT_KEY", diff --git a/sdk/remoterendering/mixed-reality-remote-rendering/test/public/remoteRenderingClient.spec.ts b/sdk/remoterendering/mixed-reality-remote-rendering/test/public/remoteRenderingClient.spec.ts index 5935ecdac67..f9889c7b2f4 100644 --- a/sdk/remoterendering/mixed-reality-remote-rendering/test/public/remoteRenderingClient.spec.ts +++ b/sdk/remoterendering/mixed-reality-remote-rendering/test/public/remoteRenderingClient.spec.ts @@ -185,9 +185,9 @@ describe("RemoteRendering functional tests", () => { it("throws correct exception on no access", async () => { const storageContainerUrl = "https://" + - assertEnvironmentVariable("REMOTERENDERING_ARR_STORAGE_ACCOUNT_NAME") + + assertEnvironmentVariable("STORAGE_ACCOUNT_NO_ACCESS_NAME") + ".blob.core.windows.net/" + - assertEnvironmentVariable("REMOTERENDERING_ARR_BLOB_CONTAINER_NAME"); + assertEnvironmentVariable("BLOB_CONTAINER_NO_ACCESS_NAME"); // Do not provide SAS tokens const inputSettings: AssetConversionInputSettings = { diff --git a/sdk/remoterendering/mixed-reality-remote-rendering/test/utils/recordedClient.ts b/sdk/remoterendering/mixed-reality-remote-rendering/test/utils/recordedClient.ts index 6a2dba074ec..b31b6fc5cb7 100644 --- a/sdk/remoterendering/mixed-reality-remote-rendering/test/utils/recordedClient.ts +++ b/sdk/remoterendering/mixed-reality-remote-rendering/test/utils/recordedClient.ts @@ -24,6 +24,8 @@ const envSetupForPlayback: Record = { REMOTERENDERING_ARR_SAS_TOKEN: "arr_sas_token", REMOTERENDERING_ARR_SERVICE_ENDPOINT: "https://remoterendering.eastus2.mixedreality.azure.com", REMOTERENDERING_ARR_STORAGE_ACCOUNT_NAME: "sdktest", + STORAGE_ACCOUNT_NO_ACCESS_NAME: "sdktestnoaccess", + BLOB_CONTAINER_NO_ACCESS_NAME: "testnoaccess", }; export const recorderStartOptions: RecorderStartOptions = { diff --git a/sdk/remoterendering/test-resources.bicep b/sdk/remoterendering/test-resources.bicep index d4e358269ab..845d44bc8df 100644 --- a/sdk/remoterendering/test-resources.bicep +++ b/sdk/remoterendering/test-resources.bicep @@ -1,19 +1,24 @@ +@minLength(5) param baseName string = resourceGroup().name param location string = resourceGroup().location param baseTime string = utcNow('u') +param testApplicationOid string var arrApiVersion = '2021-03-01-preview' var arrAccountName = '${baseName}-arr-account' var storageApiVersion = '2023-05-01' var storageAccountName = baseName +var storageAccountNoAccessName = '${baseName}na' var blobContainerName = 'test' -var blobContainerResourceName = '${storageAccountName}/default/${blobContainerName}' +var blobContainerNoAccessName = 'noaccess' var sasProperties = { signedPermission: 'rwl' signedExpiry: dateTimeAdd(baseTime, 'P1D') signedResource: 'c' canonicalizedResource: '/blob/${storageAccountName}/${blobContainerName}' } +var remoteRenderingAdminRoleId = '3df8b902-2a6f-47c7-8cc5-360e9b272a7e' +var storageBlobDataContributorRoleId = 'ba92f5b4-2d11-453d-a403-e96b0029c9fe' resource remoteRenderingAccount 'Microsoft.MixedReality/remoteRenderingAccounts@2021-03-01-preview' = { name: arrAccountName @@ -21,7 +26,17 @@ resource remoteRenderingAccount 'Microsoft.MixedReality/remoteRenderingAccounts@ identity: { type: 'SystemAssigned' } - properties: {} + properties: { + storageAccountName: storageAccountName + } +} + +resource remoteRenderingAdminRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(remoteRenderingAccount.id, testApplicationOid, remoteRenderingAdminRoleId) + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', remoteRenderingAdminRoleId) + principalId: testApplicationOid + } } resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = { @@ -46,17 +61,58 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = { } resource blobContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = { - name: blobContainerResourceName + name: '${storageAccountName}/default/${blobContainerName}' dependsOn: [ storageAccount ] } +// Role assignment to grant Storage Blob Data Contributor role to the Remote Rendering Account Managed Identity +resource storageBlobDataContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(storageAccount.id, remoteRenderingAccount.id, storageBlobDataContributorRoleId) + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', storageBlobDataContributorRoleId) + principalId: remoteRenderingAccount.identity.principalId + principalType: 'ServicePrincipal' + } + scope: storageAccount +} + +resource storageAccountNoAccess 'Microsoft.Storage/storageAccounts@2023-05-01' = { + name: storageAccountNoAccessName + location: location + sku: { + name: 'Standard_RAGRS' + } + kind: 'StorageV2' + properties: { + supportsHttpsTrafficOnly: true + encryption: { + keySource: 'Microsoft.Storage' + services: { + blob: { + enabled: true + } + } + } + accessTier: 'Hot' + } +} + +resource blobContainerNoAccess 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = { + name: '${storageAccountNoAccessName}/default/${blobContainerNoAccessName}' + dependsOn: [ + storageAccountNoAccess + ] +} + output REMOTERENDERING_ARR_ACCOUNT_ID string = remoteRenderingAccount.properties.accountId output REMOTERENDERING_ARR_ACCOUNT_DOMAIN string = remoteRenderingAccount.properties.accountDomain output REMOTERENDERING_ARR_ACCOUNT_KEY string = listKeys(resourceId('Microsoft.MixedReality/remoteRenderingAccounts', arrAccountName), arrApiVersion).primaryKey -output REMOTERENDERING_ARR_STORAGE_ACCOUNT_NAME string = storageAccountName output REMOTERENDERING_ARR_STORAGE_ACCOUNT_KEY string = listKeys(resourceId('Microsoft.Storage/storageAccounts', storageAccountName), storageApiVersion).keys[0].value +output REMOTERENDERING_ARR_STORAGE_ACCOUNT_NAME string = storageAccount.name output REMOTERENDERING_ARR_BLOB_CONTAINER_NAME string = blobContainerName +output STORAGE_ACCOUNT_NO_ACCESS_NAME string = storageAccountNoAccess.name +output BLOB_CONTAINER_NO_ACCESS_NAME string = blobContainerNoAccessName output REMOTERENDERING_ARR_SAS_TOKEN string = listServiceSas(storageAccountName, storageApiVersion, sasProperties).serviceSasToken output REMOTERENDERING_ARR_SERVICE_ENDPOINT string = 'https://remoterendering.${location}.mixedreality.azure.com'