--- policy: /ce/ca/azure/storage/blob-containers-soft-delete logic: /ce/ca/azure/storage/blob-containers-soft-delete/prod.logic.yaml executionTime: 2026-02-10T22:33:38.514513132Z generationMs: 84 executionMs: 671 rows: - id: test1 match: true status: expected: DISAPPEARED actual: DISAPPEARED conditionIndex: expected: 99 actual: 99 conditionText: expected: isDisappeared(CA10__disappearanceTime__c) actual: isDisappeared(CA10__disappearanceTime__c) runtimeError: {} - id: test2 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 199 actual: 199 conditionText: expected: extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty() actual: extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty() runtimeError: {} - id: test3 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 199 actual: 199 conditionText: expected: extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty() actual: extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty() runtimeError: {} - id: test4 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 299 actual: 299 conditionText: expected: extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty() actual: extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty() runtimeError: {} - id: test5 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 299 actual: 299 conditionText: expected: extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty() actual: extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty() runtimeError: {} - id: test6 match: true status: expected: COMPLIANT actual: COMPLIANT conditionIndex: expected: 399 actual: 399 conditionText: expected: extract('CA10__containerRetentionPolicyState__c') == 'Enabled' && extract('CA10__containerRetentionPolicyDays__c').isNotEmpty() && extract('CA10__blobRetentionPolicyState__c') == 'Enabled' && extract('CA10__blobRetentionPolicyDays__c').isNotEmpty() actual: extract('CA10__containerRetentionPolicyState__c') == 'Enabled' && extract('CA10__containerRetentionPolicyDays__c').isNotEmpty() && extract('CA10__blobRetentionPolicyState__c') == 'Enabled' && extract('CA10__blobRetentionPolicyDays__c').isNotEmpty() runtimeError: {} usedFiles: - path: /ce/ca/azure/storage/blob-containers-soft-delete/policy.yaml md5Hash: B8172CF397119B7E4C4E01484BA4218C content: | --- names: full: Azure Storage Blob Containers Soft Delete is not enabled contextual: Blob Containers Soft Delete is not enabled description: It is recommended that both Azure Containers with attached Blob Storage and standalone containers with Blob Storage be made recoverable by enabling the soft delete configuration. This is to save and recover data when blobs or blob snapshots are erroneously deleted. type: COMPLIANCE_POLICY categories: - RELIABILITY - SECURITY frameworkMappings: - "/frameworks/cis-azure-v5.0.0/09/02/01" - "/frameworks/cis-azure-v5.0.0/09/02/02" - "/frameworks/cloudaware/resource-security/data-protection-and-recovery" similarPolicies: internal: - dec-x-a8281d05 cloudConformity: - url: https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/StorageAccounts/enable-soft-delete.html name: Enable Soft Delete for Azure Blob Storage - path: /ce/ca/azure/storage/blob-containers-soft-delete/prod.logic.yaml md5Hash: 60DC67FB3A1B880FD37702C5F8D0F03A content: | --- inputType: "CA10__CaAzureStorageAccount__c" importExtracts: - file: "/types/CA10__CaAzureStorageAccount__c/object.extracts.yaml" testData: - file: "test-data.json" conditions: - status: "INCOMPLIANT" currentStateMessage: "The soft delete configuration for Azure Storage Blob Storage is not enabled." remediationMessage: "Enable soft delete for blob storage." check: OR: args: - IS_EQUAL: left: EXTRACT: "CA10__blobRetentionPolicyState__c" right: TEXT: "Disabled" - IS_EMPTY: arg: EXTRACT: "CA10__blobRetentionPolicyState__c" - IS_EMPTY: arg: EXTRACT: "CA10__blobRetentionPolicyDays__c" - status: "INCOMPLIANT" currentStateMessage: "The soft delete configuration for Azure Storage Containers is not enabled." remediationMessage: "Enable soft delete for containers." check: OR: args: - IS_EQUAL: left: EXTRACT: "CA10__containerRetentionPolicyState__c" right: TEXT: "Disabled" - IS_EMPTY: arg: EXTRACT: "CA10__containerRetentionPolicyState__c" - IS_EMPTY: arg: EXTRACT: "CA10__containerRetentionPolicyDays__c" - status: "COMPLIANT" currentStateMessage: "Soft delete for Azure Storage containers is enabled." check: AND: args: - IS_EQUAL: left: EXTRACT: "CA10__containerRetentionPolicyState__c" right: TEXT: "Enabled" - NOT_EMPTY: arg: EXTRACT: "CA10__containerRetentionPolicyDays__c" - IS_EQUAL: left: EXTRACT: "CA10__blobRetentionPolicyState__c" right: TEXT: "Enabled" - NOT_EMPTY: arg: EXTRACT: "CA10__blobRetentionPolicyDays__c" otherwise: status: "UNDETERMINED" currentStateMessage: "Unexpected values in the fields." - path: /ce/ca/azure/storage/blob-containers-soft-delete/test-data.json md5Hash: 73BDCE2DBC16989BB851CCD3AEE91049 content: |- [ { "expectedResult": { "status": "DISAPPEARED", "conditionIndex": "99", "conditionText": "isDisappeared(CA10__disappearanceTime__c)", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test1", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": "2024-11-12T04:22:47Z", "CA10__blobRetentionPolicyState__c": "", "CA10__blobRetentionPolicyDays__c": null, "CA10__containerRetentionPolicyState__c": "", "CA10__containerRetentionPolicyDays__c": null, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "199", "conditionText": "extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test2", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": null, "CA10__blobRetentionPolicyState__c": "", "CA10__blobRetentionPolicyDays__c": null, "CA10__containerRetentionPolicyState__c": "", "CA10__containerRetentionPolicyDays__c": null, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "199", "conditionText": "extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test3", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": null, "CA10__blobRetentionPolicyState__c": "Disabled", "CA10__blobRetentionPolicyDays__c": null, "CA10__containerRetentionPolicyState__c": "", "CA10__containerRetentionPolicyDays__c": null, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "299", "conditionText": "extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test4", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": null, "CA10__blobRetentionPolicyState__c": "Enabled", "CA10__blobRetentionPolicyDays__c": 7, "CA10__containerRetentionPolicyState__c": "", "CA10__containerRetentionPolicyDays__c": null, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "299", "conditionText": "extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test5", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": null, "CA10__blobRetentionPolicyState__c": "Enabled", "CA10__blobRetentionPolicyDays__c": 7, "CA10__containerRetentionPolicyState__c": "Disabled", "CA10__containerRetentionPolicyDays__c": null, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } }, { "expectedResult": { "status": "COMPLIANT", "conditionIndex": "399", "conditionText": "extract('CA10__containerRetentionPolicyState__c') == 'Enabled' && extract('CA10__containerRetentionPolicyDays__c').isNotEmpty() && extract('CA10__blobRetentionPolicyState__c') == 'Enabled' && extract('CA10__blobRetentionPolicyDays__c').isNotEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-11-12T04:22:47Z" }, "Id": "test6", "RecordTypeId": "RecordTypeId", "CA10__disappearanceTime__c": null, "CA10__blobRetentionPolicyState__c": "Enabled", "CA10__blobRetentionPolicyDays__c": 7, "CA10__containerRetentionPolicyState__c": "Enabled", "CA10__containerRetentionPolicyDays__c": 7, "RecordType": { "DeveloperName": "caAzureRMStorageAccount", "Id": "RecordTypeId" } } ] - path: /types/CA10__CaAzureStorageAccount__c/object.extracts.yaml md5Hash: 2FD9F962F192FC3E335D23D11315B8F9 content: "---\nextracts:\n# This is a checkbox. Not nullable. Can't have no access,\ \ retrieved via Microsoft.Storage/storageAccounts\n - name: \"CA10__secureTransferRequired__c\"\ \n value: \n FIELD:\n path: \"CA10__secureTransferRequired__c\"\ \n# Values: Enabled, Disabled. Not Nullable. Can't have no access, retrieved\ \ via Microsoft.Storage/storageAccounts\n - name: \"CA10__requireInfrastructureEncryptionState__c\"\ \n value: \n FIELD:\n path: \"CA10__requireInfrastructureEncryptionState__c\"\ \n undeterminedIf:\n isEmpty: \"Corrupted data. Require Infrastructure\ \ Encryption setting cannot be empty.\"\n# Values: Enabled, Disabled. Not Nullable.\ \ Can't have no access, retrieved via Microsoft.Storage/storageAccounts\n -\ \ name: \"CA10__publicNetworkAccessState__c\"\n value: \n FIELD:\n \ \ path: \"CA10__publicNetworkAccessState__c\"\n undeterminedIf:\n\ \ isEmpty: \"Corrupted data. Public Network Access cannot be empty.\"\ \n# Values: Allow, Deny. Not nullable. Can't have no access, retrieved via Microsoft.Storage/storageAccounts.\n\ \ - name: \"CA10__networkAclsDefaultAction__c\"\n value: \n FIELD:\n\ \ path: \"CA10__networkAclsDefaultAction__c\"\n undeterminedIf:\n\ \ isEmpty: \"Corrupted data. Default Network Action cannot be empty.\"\ \n# Values: any combination of Logging|Metrics|AzureServices or None. Not nullable.\ \ \n# Can't have no access, retrieved via Microsoft.Storage/storageAccounts.\n\ \ - name: \"CA10__networkAclsBypass__c\"\n value: \n FIELD:\n \ \ path: \"CA10__networkAclsBypass__c\"\n undeterminedIf:\n \ \ isEmpty: \"Corrupted data. Network Bypass cannot be empty.\"\n# Values TLS1_0,\ \ TLS1_1, TLS1_2. Not nullable. Can't have no access, retrieved via Microsoft.Storage/storageAccounts.\n\ \ - name: \"CA10__minimumTlsVersion__c\"\n value: \n FIELD:\n \ \ path: \"CA10__minimumTlsVersion__c\"\n undeterminedIf:\n \ \ isEmpty: \"Corrupted data. TLS Version cannot be empty.\"\n# Values: Allow,\ \ Deny, null (Old storage accounts can have null, which means that the account\ \ can still have replication). \n# Nullable. Can't have no access, retrieved\ \ via Microsoft.Storage/storageAccounts.\n - name: \"CA10__crossTenantReplication__c\"\ \n value: \n FIELD:\n path: \"CA10__crossTenantReplication__c\"\ \n# Values: Allow, Deny. Not nullable. Can't have no access, retrieved via Microsoft.Storage/storageAccounts.\n\ \ - name: \"CA10__blobPublicAccess__c\"\n value: \n FIELD:\n \ \ path: \"CA10__blobPublicAccess__c\"\n undeterminedIf:\n isEmpty:\ \ \"Corrupted data. Allow Blob Anonymous Access cannot be empty.\"\n# Values\ \ Enabled, Disabled. Not Nullable\n - name: \"CA10__blobLoggingReadState__c\"\ \n value: \n FIELD:\n path: \"CA10__blobLoggingReadState__c\"\ \n undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__blobLoggingReadState__c\"\n currentStateMessage: \"Unable to\ \ determine Blob Container Logging Read property. Possible permission issue\ \ with Microsoft.Storage/storageAccounts/blobServices/containers/read\"\n \ \ isEmpty: \"Storage Blob Logging is not populated yet.\"\n# Values Enabled,\ \ Disabled. Not Nullable\n - name: \"CA10__blobLoggingWriteState__c\"\n \ \ value: \n FIELD:\n path: \"CA10__blobLoggingWriteState__c\"\n\ \ undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__blobLoggingWriteState__c\"\n currentStateMessage: \"Unable\ \ to determine Blob Container Logging Write property. Possible permission issue\ \ with Microsoft.Storage/storageAccounts/blobServices/containers/read\"\n \ \ isEmpty: \"Storage Blob Logging is not populated yet.\"\n # Values\ \ Enabled, Disabled. Not Nullable\n - name: \"CA10__blobLoggingDeleteState__c\"\ \n value: \n FIELD:\n path: \"CA10__blobLoggingDeleteState__c\"\ \n undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__blobLoggingDeleteState__c\"\n currentStateMessage: \"Unable\ \ to determine Blob Container Logging Delete property. Possible permission issue\ \ with Microsoft.Storage/storageAccounts/blobServices/containers/read\"\n \ \ isEmpty: \"Storage Blob Logging is not populated yet.\"\n# Values Enabled,\ \ Disabled. Not Nullable\n - name: \"CA10__queueLoggingReadState__c\"\n \ \ value: \n FIELD:\n path: \"CA10__queueLoggingReadState__c\"\n\ \ undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__queueLoggingReadState__c\"\n currentStateMessage: \"Unable\ \ to determine Queue Logging Read property. Possible permission issue with Microsoft.Storage/storageAccounts/queueServices/queues/read\"\ \n isEmpty: \"Storage Queue Logging is not populated yet.\"\n# Values\ \ Enabled, Disabled. Not Nullable\n - name: \"CA10__queueLoggingWriteState__c\"\ \n value: \n FIELD:\n path: \"CA10__queueLoggingWriteState__c\"\ \n undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__queueLoggingWriteState__c\"\n currentStateMessage: \"Unable\ \ to determine Queue Logging Write property. Possible permission issue with\ \ Microsoft.Storage/storageAccounts/queueServices/queues/read\"\n isEmpty:\ \ \"Storage Queue Logging is not populated yet.\"\n# Values Enabled, Disabled.\ \ Not Nullable\n - name: \"CA10__queueLoggingDeleteState__c\"\n value: \n\ \ FIELD:\n path: \"CA10__queueLoggingDeleteState__c\"\n undeterminedIf:\n\ \ noAccessDelegate:\n path: \"CA10__queueLoggingDeleteState__c\"\ \n currentStateMessage: \"Unable to determine Queue Logging Delete\ \ property. Possible permission issue with Microsoft.Storage/storageAccounts/queueServices/queues/read\"\ \n isEmpty: \"Storage Queue Logging is not populated yet.\"\n# Values\ \ Enabled, Disabled. Not Nullable\n - name: \"CA10__tableLoggingReadState__c\"\ \n value: \n FIELD:\n path: \"CA10__tableLoggingReadState__c\"\ \n undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__tableLoggingReadState__c\"\n currentStateMessage: \"Unable\ \ to determine Table Logging Read property. Possible permission issue with Microsoft.Storage/storageAccounts/tableServices/tables/read\"\ \n isEmpty: \"Storage Table Logging is not populated yet.\"\n# Values\ \ Enabled, Disabled. Not Nullable\n - name: \"CA10__tableLoggingWriteState__c\"\ \n value: \n FIELD:\n path: \"CA10__tableLoggingWriteState__c\"\ \n undeterminedIf:\n noAccessDelegate:\n path: \"\ CA10__tableLoggingWriteState__c\"\n currentStateMessage: \"Unable\ \ to determine Table Logging Write property. Possible permission issue with\ \ Microsoft.Storage/storageAccounts/tableServices/tables/read\"\n isEmpty:\ \ \"Storage Table Logging is not populated yet.\"\n# Values Enabled, Disabled.\ \ Not Nullable\n - name: \"CA10__tableLoggingDeleteState__c\"\n value: \n\ \ FIELD:\n path: \"CA10__tableLoggingDeleteState__c\"\n undeterminedIf:\n\ \ noAccessDelegate:\n path: \"CA10__tableLoggingDeleteState__c\"\ \n currentStateMessage: \"Unable to determine Table Logging Delete\ \ property. Possible permission issue with Microsoft.Storage/storageAccounts/tableServices/tables/read\"\ \n isEmpty: \"Storage Table Logging is not populated yet.\"\n# Values\ \ Microsoft.Storage, Microsoft.Keyvault. Not Nullable. Can't have no access,\ \ retrieved via Microsoft.Storage/storageAccounts\n - name: \"CA10__encryptionKeySource__c\"\ \n value: \n FIELD:\n path: \"CA10__encryptionKeySource__c\"\n\ \ undeterminedIf:\n isEmpty: \"Corrupted data. Encryption Key\ \ Source cannot be empty.\"\n# Nullable. Can't have no access, retrieved via\ \ Microsoft.Storage/storageAccounts\n - name: \"CA10__encryptionKeyVaultUri__c\"\ \n value: \n FIELD:\n path: \"CA10__encryptionKeyVaultUri__c\"\ \n# Nullable. \n - name: \"CA10__blobRetentionPolicyDays__c\"\n value: \n\ \ FIELD:\n path: \"CA10__blobRetentionPolicyDays__c\"\n# Values:\ \ Enabled, Disabled. Nullable. \n - name: \"CA10__blobRetentionPolicyState__c\"\ \n value: \n FIELD:\n path: \"CA10__blobRetentionPolicyState__c\"\ \n# Nullable. \n - name: \"CA10__containerRetentionPolicyDays__c\"\n value:\ \ \n FIELD:\n path: \"CA10__containerRetentionPolicyDays__c\"\n\ # Values: Enabled, Disabled. Nullable. \n - name: \"CA10__containerRetentionPolicyState__c\"\ \n value: \n FIELD:\n path: \"CA10__containerRetentionPolicyState__c\"\ \n# Nullable. Text field.\n - name: \"CA10__skuName__c\"\n value:\n \ \ FIELD:\n path: \"CA10__skuName__c\"\n# Nullable. Text field.\n -\ \ name: \"CA10__defaultToOAuthAuthentication__c\"\n value:\n FIELD:\n\ \ path: \"CA10__defaultToOAuthAuthentication__c\"\n# Nullable. Text field.\n\ \ - name: \"CA10__sharedKeyAccess__c\"\n value:\n FIELD:\n path:\ \ \"CA10__sharedKeyAccess__c\"\n# Nullable. Text field.\n - name: \"CA10__blobVersioning__c\"\ \n value:\n FIELD:\n path: \"CA10__blobVersioning__c\"\n# Text\ \ field.\n - name: \"CA10__locationName__c\"\n value:\n FIELD:\n \ \ path: \"CA10__locationName__c\"\n# Date/Time field.\n - name: \"CA10__primaryKeyCreationTime__c\"\ \n value:\n FIELD:\n path: \"CA10__primaryKeyCreationTime__c\"\ \n# Date/Time field.\n - name: \"CA10__secondaryKeyCreationTime__c\"\n value:\n\ \ FIELD:\n path: \"CA10__secondaryKeyCreationTime__c\"\n# Nullable.\ \ Number field.\n - name: \"CA10__keyExpirationPeriodDays__c\"\n value:\n\ \ FIELD:\n path: \"CA10__keyExpirationPeriodDays__c\"\n\n \ \ " script: |- CREATE TEMP FUNCTION mock_ExpectedResult() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "Id" : "test1", "expectedResult" : { "status" : "DISAPPEARED", "conditionIndex" : "99", "conditionText" : "isDisappeared(CA10__disappearanceTime__c)", "runtimeError" : null } }, { "Id" : "test2", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "199", "conditionText" : "extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty()", "runtimeError" : null } }, { "Id" : "test3", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "199", "conditionText" : "extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty()", "runtimeError" : null } }, { "Id" : "test4", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "299", "conditionText" : "extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty()", "runtimeError" : null } }, { "Id" : "test5", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "299", "conditionText" : "extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty()", "runtimeError" : null } }, { "Id" : "test6", "expectedResult" : { "status" : "COMPLIANT", "conditionIndex" : "399", "conditionText" : "extract('CA10__containerRetentionPolicyState__c') == 'Enabled' && extract('CA10__containerRetentionPolicyDays__c').isNotEmpty() && extract('CA10__blobRetentionPolicyState__c') == 'Enabled' && extract('CA10__blobRetentionPolicyDays__c').isNotEmpty()", "runtimeError" : null } } ]; """; CREATE TEMP FUNCTION mock_CA10__CaAzureStorageAccount__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__disappearanceTime__c" : new Date("2024-11-12T04:22:47Z"), "CA10__blobRetentionPolicyState__c" : "", "CA10__blobRetentionPolicyDays__c" : null, "CA10__containerRetentionPolicyState__c" : "", "CA10__containerRetentionPolicyDays__c" : null, "Id" : "test1", "RecordTypeId" : "RecordTypeId" }, { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__blobRetentionPolicyState__c" : "", "CA10__blobRetentionPolicyDays__c" : null, "CA10__containerRetentionPolicyState__c" : "", "CA10__containerRetentionPolicyDays__c" : null, "Id" : "test2", "RecordTypeId" : "RecordTypeId" }, { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__blobRetentionPolicyState__c" : "Disabled", "CA10__blobRetentionPolicyDays__c" : null, "CA10__containerRetentionPolicyState__c" : "", "CA10__containerRetentionPolicyDays__c" : null, "Id" : "test3", "RecordTypeId" : "RecordTypeId" }, { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__blobRetentionPolicyState__c" : "Enabled", "CA10__blobRetentionPolicyDays__c" : 7, "CA10__containerRetentionPolicyState__c" : "", "CA10__containerRetentionPolicyDays__c" : null, "Id" : "test4", "RecordTypeId" : "RecordTypeId" }, { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__blobRetentionPolicyState__c" : "Enabled", "CA10__blobRetentionPolicyDays__c" : 7, "CA10__containerRetentionPolicyState__c" : "Disabled", "CA10__containerRetentionPolicyDays__c" : null, "Id" : "test5", "RecordTypeId" : "RecordTypeId" }, { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "CA10__blobRetentionPolicyState__c" : "Enabled", "CA10__blobRetentionPolicyDays__c" : 7, "CA10__containerRetentionPolicyState__c" : "Enabled", "CA10__containerRetentionPolicyDays__c" : 7, "Id" : "test6", "RecordTypeId" : "RecordTypeId" } ]; """; CREATE TEMP FUNCTION mock_RecordType() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2024-11-12T04:22:47Z") }, "Id" : "RecordTypeId" } ]; """; CREATE TEMP FUNCTION process_CA10__CaAzureStorageAccount__c( obj STRUCT< CA10__disappearanceTime__c TIMESTAMP, CA10__blobRetentionPolicyState__c STRING, CA10__blobRetentionPolicyDays__c FLOAT64, CA10__containerRetentionPolicyState__c STRING, CA10__containerRetentionPolicyDays__c FLOAT64, Id STRING, RecordTypeId STRING, RecordType STRUCT< Id STRING > >, snapshotTime TIMESTAMP ) RETURNS STRUCT DETERMINISTIC LANGUAGE js AS r""" var IsEmptyLib = new function () { this.simpleIsEmpty = function(arg) { return arg == null; }; this.simpleIsNotEmpty = function(arg) { return arg != null; }; }(); var TextLib = new function () { this.normalize = function(arg) { return arg == null ? '' : arg.replace(/\s+/g, ' ').trim().toLowerCase(); }; this.isEmpty = function(arg) { return this.normalize(arg) == ''; }; this.isNotEmpty = function(arg) { return this.normalize(arg) != ''; }; this.equal = function(left, right) { return this.normalize(left) == this.normalize(right); }; this.notEqual = function(left, right) { return this.normalize(left) != this.normalize(right); }; this.startsWith = function(arg, substring) { return this.normalize(arg).startsWith(this.normalize(substring)); }; this.endsWith = function(arg, substring) { return this.normalize(arg).endsWith(this.normalize(substring)); }; this.contains = function(arg, substring) { return this.normalize(arg).includes(this.normalize(substring)); }; this.containsAll = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.every(sub => normalizedArg.includes(this.normalize(sub))); }; this.containsAny = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.some(sub => normalizedArg.includes(this.normalize(sub))); }; }(); var references1 = []; // condition[0], conditionIndex:[0..99] references1.push('Deleted From Azure [CA10__disappearanceTime__c]: ' + obj.CA10__disappearanceTime__c); if (obj.CA10__disappearanceTime__c != null) { return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10__disappearanceTime__c)", currentStateMessage: "Object is deleted in the source", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[1], conditionIndex:[100..199] function extract3() { if (!this.out) { this.out = obj.CA10__blobRetentionPolicyState__c; } return this.out; }; function extract7() { if (!this.out) { this.out = obj.CA10__blobRetentionPolicyDays__c; } return this.out; }; references1.push('Blob Retention Policy: State [obj.CA10__blobRetentionPolicyState__c]: ' + obj.CA10__blobRetentionPolicyState__c); references1.push('Blob Retention Policy: Days [obj.CA10__blobRetentionPolicyDays__c]: ' + obj.CA10__blobRetentionPolicyDays__c); if (TextLib.equal(extract3.call(extract3), 'Disabled') || TextLib.isEmpty(extract3.call(extract3)) || IsEmptyLib.simpleIsEmpty(extract7.call(extract7))) { return {status: 'INCOMPLIANT', conditionIndex: 199, conditionText: "extract('CA10__blobRetentionPolicyState__c') == 'Disabled' || extract('CA10__blobRetentionPolicyState__c').isEmpty() || extract('CA10__blobRetentionPolicyDays__c').isEmpty()", currentStateMessage: "The soft delete configuration for Azure Storage Blob Storage is not enabled.", currentStateReferences: references1.join('\n'), remediation: "Enable soft delete for blob storage.", runtimeError: null}; } // condition[2], conditionIndex:[200..299] function extract10() { if (!this.out) { this.out = obj.CA10__containerRetentionPolicyState__c; } return this.out; }; function extract14() { if (!this.out) { this.out = obj.CA10__containerRetentionPolicyDays__c; } return this.out; }; references1.push('Container Retention Policy: State [obj.CA10__containerRetentionPolicyState__c]: ' + obj.CA10__containerRetentionPolicyState__c); references1.push('Container Retention Policy: Days [obj.CA10__containerRetentionPolicyDays__c]: ' + obj.CA10__containerRetentionPolicyDays__c); if (TextLib.equal(extract10.call(extract10), 'Disabled') || TextLib.isEmpty(extract10.call(extract10)) || IsEmptyLib.simpleIsEmpty(extract14.call(extract14))) { return {status: 'INCOMPLIANT', conditionIndex: 299, conditionText: "extract('CA10__containerRetentionPolicyState__c') == 'Disabled' || extract('CA10__containerRetentionPolicyState__c').isEmpty() || extract('CA10__containerRetentionPolicyDays__c').isEmpty()", currentStateMessage: "The soft delete configuration for Azure Storage Containers is not enabled.", currentStateReferences: references1.join('\n'), remediation: "Enable soft delete for containers.", runtimeError: null}; } // condition[3], conditionIndex:[300..399] function extract17() { if (!this.out) { this.out = obj.CA10__containerRetentionPolicyState__c; } return this.out; }; function extract20() { if (!this.out) { this.out = obj.CA10__containerRetentionPolicyDays__c; } return this.out; }; function extract23() { if (!this.out) { this.out = obj.CA10__blobRetentionPolicyState__c; } return this.out; }; function extract26() { if (!this.out) { this.out = obj.CA10__blobRetentionPolicyDays__c; } return this.out; }; if (TextLib.equal(extract17.call(extract17), 'Enabled') && IsEmptyLib.simpleIsNotEmpty(extract20.call(extract20)) && TextLib.equal(extract23.call(extract23), 'Enabled') && IsEmptyLib.simpleIsNotEmpty(extract26.call(extract26))) { return {status: 'COMPLIANT', conditionIndex: 399, conditionText: "extract('CA10__containerRetentionPolicyState__c') == 'Enabled' && extract('CA10__containerRetentionPolicyDays__c').isNotEmpty() && extract('CA10__blobRetentionPolicyState__c') == 'Enabled' && extract('CA10__blobRetentionPolicyDays__c').isNotEmpty()", currentStateMessage: "Soft delete for Azure Storage containers is enabled.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } return {status: 'UNDETERMINED', conditionIndex: 400, conditionText: "otherwise", currentStateMessage: "Unexpected values in the fields.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; """; SELECT expectedResult.Id as Id, IF ( IFNULL(expectedResult.expectedResult.status, '') = IFNULL(sObject.result.status, '') AND IFNULL(expectedResult.expectedResult.conditionIndex, -1) = IFNULL(sObject.result.conditionIndex, -1) AND IFNULL(expectedResult.expectedResult.conditionText, '') = IFNULL(sObject.result.conditionText, '') AND IFNULL(expectedResult.expectedResult.runtimeError, '') = IFNULL(sObject.result.runtimeError, ''), "MATCH", "FAIL" ) as match, expectedResult.expectedResult.status as expectedStatus, sObject.result.status as actualStatus, expectedResult.expectedResult.conditionIndex as expectedConditionIndex, sObject.result.conditionIndex as actualConditionIndex, expectedResult.expectedResult.conditionText as expectedConditionText, sObject.result.conditionText as actualConditionText, expectedResult.expectedResult.runtimeError as expectedRuntimeError, sObject.result.runtimeError as actualRuntimeError FROM UNNEST(mock_ExpectedResult()) expectedResult LEFT JOIN ( SELECT sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c, sObject.CA10__blobRetentionPolicyState__c AS CA10__blobRetentionPolicyState__c, sObject.CA10__blobRetentionPolicyDays__c AS CA10__blobRetentionPolicyDays__c, sObject.CA10__containerRetentionPolicyState__c AS CA10__containerRetentionPolicyState__c, sObject.CA10__containerRetentionPolicyDays__c AS CA10__containerRetentionPolicyDays__c, sObject.Id AS Id, sObject.RecordTypeId AS RecordTypeId, STRUCT ( `RecordType`.Id AS Id ) AS RecordType, process_CA10__CaAzureStorageAccount__c( STRUCT( sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c, sObject.CA10__blobRetentionPolicyState__c AS CA10__blobRetentionPolicyState__c, sObject.CA10__blobRetentionPolicyDays__c AS CA10__blobRetentionPolicyDays__c, sObject.CA10__containerRetentionPolicyState__c AS CA10__containerRetentionPolicyState__c, sObject.CA10__containerRetentionPolicyDays__c AS CA10__containerRetentionPolicyDays__c, sObject.Id AS Id, sObject.RecordTypeId AS RecordTypeId, STRUCT ( `RecordType`.Id AS Id ) AS RecordType ), sObject.context.snapshotTime ) as result FROM UNNEST(mock_CA10__CaAzureStorageAccount__c()) AS sObject LEFT JOIN UNNEST(mock_RecordType()) AS `RecordType` ON sObject.RecordTypeId = `RecordType`.Id ) sObject ON sObject.Id = expectedResult.Id;