---
policy: /ce/ca/azure/storage/blob-containers-soft-delete
logic: /ce/ca/azure/storage/blob-containers-soft-delete/prod.logic.yaml
executionTime: 2025-04-24T23:45:52.00258529Z
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: 25147ADEFF8D6621D9BEFE535C27B9EA
    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-v2.1.0/03/11"
        - "/frameworks/cis-azure-v3.0.0/04/10"
        - "/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: 1B9CE0AD50D5B9FCE5FAEDCC37DF65E8
    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: "Consider enabling 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: "Consider enabling 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: "The 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: 92D968DD14AC8426E1942BC29A409B13
    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"
script: |-
  CREATE TEMP FUNCTION mock_ExpectedResult()
  RETURNS ARRAY<STRUCT<
          Id STRING,
          expectedResult STRUCT<status STRING, conditionIndex DECIMAL, conditionText STRING, runtimeError STRING>
      >>
  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<STRUCT<
      Id STRING,
      RecordTypeId STRING,
      CA10__disappearanceTime__c TIMESTAMP,
      CA10__blobRetentionPolicyState__c STRING,
      CA10__blobRetentionPolicyDays__c FLOAT64,
      CA10__containerRetentionPolicyState__c STRING,
      CA10__containerRetentionPolicyDays__c FLOAT64,
      context STRUCT<
          snapshotTime TIMESTAMP
      >
  >>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
    return [ {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test1",
    "RecordTypeId" : "RecordTypeId",
    "CA10__disappearanceTime__c" : new Date("2024-11-12T04:22:47Z"),
    "CA10__blobRetentionPolicyState__c" : "",
    "CA10__blobRetentionPolicyDays__c" : null,
    "CA10__containerRetentionPolicyState__c" : "",
    "CA10__containerRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test2",
    "RecordTypeId" : "RecordTypeId",
    "CA10__blobRetentionPolicyState__c" : "",
    "CA10__blobRetentionPolicyDays__c" : null,
    "CA10__containerRetentionPolicyState__c" : "",
    "CA10__containerRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test3",
    "RecordTypeId" : "RecordTypeId",
    "CA10__blobRetentionPolicyState__c" : "Disabled",
    "CA10__blobRetentionPolicyDays__c" : null,
    "CA10__containerRetentionPolicyState__c" : "",
    "CA10__containerRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test4",
    "RecordTypeId" : "RecordTypeId",
    "CA10__blobRetentionPolicyState__c" : "Enabled",
    "CA10__blobRetentionPolicyDays__c" : 7,
    "CA10__containerRetentionPolicyState__c" : "",
    "CA10__containerRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test5",
    "RecordTypeId" : "RecordTypeId",
    "CA10__blobRetentionPolicyState__c" : "Enabled",
    "CA10__blobRetentionPolicyDays__c" : 7,
    "CA10__containerRetentionPolicyState__c" : "Disabled",
    "CA10__containerRetentionPolicyDays__c" : null
  }, {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "Id" : "test6",
    "RecordTypeId" : "RecordTypeId",
    "CA10__blobRetentionPolicyState__c" : "Enabled",
    "CA10__blobRetentionPolicyDays__c" : 7,
    "CA10__containerRetentionPolicyState__c" : "Enabled",
    "CA10__containerRetentionPolicyDays__c" : 7
  } ];
  """;

  CREATE TEMP FUNCTION mock_RecordType()
  RETURNS ARRAY<STRUCT<
      DeveloperName STRING,
      Id STRING,
      context STRUCT<
          snapshotTime TIMESTAMP
      >
  >>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
    return [ {
    "context" : {
      "snapshotTime" : new Date("2024-11-12T04:22:47Z")
    },
    "DeveloperName" : "caAzureRMStorageAccount",
    "Id" : "RecordTypeId"
  } ];
  """;

  CREATE TEMP FUNCTION process_CA10__CaAzureStorageAccount__c(
      obj STRUCT<
          Id STRING,
          RecordTypeId STRING,
          CA10__disappearanceTime__c TIMESTAMP,
          CA10__blobRetentionPolicyState__c STRING,
          CA10__blobRetentionPolicyDays__c FLOAT64,
          CA10__containerRetentionPolicyState__c STRING,
          CA10__containerRetentionPolicyDays__c FLOAT64,
          RecordType STRUCT<
              DeveloperName STRING,
              Id STRING
          >
      >,
      snapshotTime TIMESTAMP
  )
  RETURNS STRUCT<status STRING, conditionIndex DECIMAL, conditionText STRING, currentStateMessage STRING, currentStateReferences STRING, remediation STRING, runtimeError STRING>
  DETERMINISTIC
  LANGUAGE js
  AS r"""
      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));
          };
      }();
      var IsEmptyLib = new function () {
          this.simpleIsEmpty = function(arg) {
              return arg == null;
          };
          this.simpleIsNotEmpty = function(arg) {
              return arg != null;
          };
      }();
      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: "Consider enabling 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: "Consider enabling 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: "The 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.Id AS Id,
          sObject.RecordTypeId AS RecordTypeId,
          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,
          STRUCT (
              `RecordType`.DeveloperName AS DeveloperName,
              `RecordType`.Id AS Id
          ) AS RecordType,
          process_CA10__CaAzureStorageAccount__c(
              STRUCT(
                  sObject.Id AS Id,
                  sObject.RecordTypeId AS RecordTypeId,
                  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,
                  STRUCT (
                      `RecordType`.DeveloperName AS DeveloperName,
                      `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;
