--- policy: /ce/ca/oracle/network/network-security-group-allows-unrestricted-rdp-traffic logic: /ce/ca/oracle/network/network-security-group-allows-unrestricted-rdp-traffic/prod.logic.yaml executionTime: 2026-05-02T12:07:27.043492198Z generationMs: 53 executionMs: 2753 rows: - id: test1 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 199 actual: 199 conditionText: expected: CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.has(INCOMPLIANT) actual: CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.has(INCOMPLIANT) runtimeError: {} - id: test2 match: true status: expected: COMPLIANT actual: COMPLIANT conditionIndex: expected: 200 actual: 200 conditionText: expected: otherwise actual: otherwise runtimeError: {} usedFiles: - path: /ce/ca/oracle/network/network-security-group-allows-unrestricted-rdp-traffic/policy.yaml md5Hash: D0066637F9A30E57C36A3DFB55372B9D content: |- --- names: full: "Oracle IAAS Network Security Group allows unrestricted RDP traffic" contextual: "IAAS Network Security Group allows unrestricted RDP traffic" description: > Ensure that Oracle IAAS Network Security Groups do not allow unrestricted ingress from the internet (0.0.0.0/0 or ::/0) to RDP port 3389. Public RDP exposure increases the attack surface of administrative interfaces and should be restricted to trusted CIDR ranges, bastion hosts, VPN networks, or other approved access paths. type: "COMPLIANCE_POLICY" categories: - "SECURITY" frameworkMappings: - "/frameworks/cis-oracle-v3.1.0/02/04" - "/frameworks/cloudaware/resource-security/network-exposure" similarPolicies: internal: - "dec-x-1122fe57" - path: /ce/ca/oracle/network/network-security-group-allows-unrestricted-rdp-traffic/prod.logic.yaml md5Hash: DD740B5E044879826E3AC2A0CA9A033B content: | --- inputType: "CA10O1__CaOracleIaasNetworkSecurityGroup__c" testData: - file: "test-data.json" conditions: - status: "INCOMPLIANT" currentStateMessage: "The network security group has ingress rules that allow unrestricted RDP access." remediationMessage: "Remove public RDP ingress or restrict it to approved source CIDRs." check: RELATED_LIST_HAS: status: "INCOMPLIANT" relationshipName: "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r" otherwise: status: "COMPLIANT" currentStateMessage: "The network security group does not allow unrestricted RDP access." relatedLists: - relationshipName: "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r" importExtracts: - file: "/types/CA10O1__CaOracleIaasNetworkSecurityGroupRule__c/object.extracts.yaml" conditions: - status: "INAPPLICABLE" currentStateMessage: "This is not an ingress rule." check: NOT_EQUAL: left: EXTRACT: "CA10O1__direction__c" right: TEXT: "INGRESS" - status: "INAPPLICABLE" currentStateMessage: "This ingress rule is not sourced from the internet." check: AND: args: - NOT_EQUAL: left: EXTRACT: "CA10O1__source__c" right: TEXT: "0.0.0.0/0" - NOT_EQUAL: left: EXTRACT: "CA10O1__source__c" right: TEXT: "::/0" - status: "INAPPLICABLE" currentStateMessage: "This ingress rule does not use ALL or TCP protocol." check: NOT: arg: CONTAINS: arg: SET: itemType: "TEXT" items: - "ALL" - "TCP" search: EXTRACT: "CA10O1__protocol__c" - status: "INCOMPLIANT" currentStateMessage: "This ingress rule allows RDP access from the internet." remediationMessage: "Remove this rule or restrict the source CIDR to approved administrative ranges." check: IS_EQUAL: left: EXTRACT: "CA10O1__protocol__c" right: TEXT: "ALL" - status: "INCOMPLIANT" currentStateMessage: "This ingress rule allows RDP access from the internet." remediationMessage: "Remove this rule or restrict the source CIDR to approved administrative ranges." check: AND: args: - IS_EQUAL: left: EXTRACT: "CA10O1__protocol__c" right: TEXT: "TCP" - OR: args: - AND: args: - IS_EMPTY: arg: EXTRACT: "CA10O1__destinationPortMin__c" - IS_EMPTY: arg: EXTRACT: "CA10O1__destinationPortMax__c" - AND: args: - LESS_THAN_EQUAL: left: EXTRACT: "CA10O1__destinationPortMin__c" right: NUMBER: 3389.0 - GREATER_THAN_EQUAL: left: EXTRACT: "CA10O1__destinationPortMax__c" right: NUMBER: 3389.0 otherwise: status: "COMPLIANT" currentStateMessage: "This ingress rule does not allow unrestricted RDP access." - path: /ce/ca/oracle/network/network-security-group-allows-unrestricted-rdp-traffic/test-data.json md5Hash: 95704BED6C6527A88AAAEEA74FCFBDC4 content: | [ { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "199", "conditionText": "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.has(INCOMPLIANT)", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test1", "CA10O1__disappearanceTime__c": null, "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r": [ { "Id": "test1_1", "CA10O1__disappearanceTime__c": null, "CA10O1__networkSecurityGroup__c": "test1", "CA10O1__direction__c": "INGRESS", "CA10O1__source__c": "0.0.0.0/0", "CA10O1__protocol__c": "TCP", "CA10O1__destinationPortMin__c": 3389, "CA10O1__destinationPortMax__c": 3389 } ] }, { "expectedResult": { "status": "COMPLIANT", "conditionIndex": "200", "conditionText": "otherwise", "runtimeError": null }, "context": { "snapshotTime": "2026-04-12T00:00:00Z" }, "Id": "test2", "CA10O1__disappearanceTime__c": null, "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r": [ { "Id": "test2_1", "CA10O1__disappearanceTime__c": null, "CA10O1__networkSecurityGroup__c": "test2", "CA10O1__direction__c": "INGRESS", "CA10O1__source__c": "10.0.0.0/24", "CA10O1__protocol__c": "TCP", "CA10O1__destinationPortMin__c": 3389, "CA10O1__destinationPortMax__c": 3389 } ] } ] - path: /types/CA10O1__CaOracleIaasNetworkSecurityGroupRule__c/object.extracts.yaml md5Hash: 11138716137450A863FB5835E1C9375B content: | --- extracts: - name: "CA10O1__direction__c" value: FIELD: path: "CA10O1__direction__c" - name: "CA10O1__source__c" value: FIELD: path: "CA10O1__source__c" - name: "CA10O1__protocol__c" value: FIELD: path: "CA10O1__protocol__c" - name: "CA10O1__destinationPortMin__c" value: FIELD: path: "CA10O1__destinationPortMin__c" - name: "CA10O1__destinationPortMax__c" value: FIELD: path: "CA10O1__destinationPortMax__c" script: |- CREATE TEMP FUNCTION mock_ExpectedResult() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "Id" : "test1", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "199", "conditionText" : "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.has(INCOMPLIANT)", "runtimeError" : null } }, { "Id" : "test2", "expectedResult" : { "status" : "COMPLIANT", "conditionIndex" : "200", "conditionText" : "otherwise", "runtimeError" : null } } ]; """; CREATE TEMP FUNCTION mock_CA10O1__CaOracleIaasNetworkSecurityGroup__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "Id" : "test1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "Id" : "test2" } ]; """; CREATE TEMP FUNCTION mock_CA10O1__CaOracleIaasNetworkSecurityGroupRule__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__direction__c" : "INGRESS", "CA10O1__source__c" : "0.0.0.0/0", "CA10O1__protocol__c" : "TCP", "CA10O1__destinationPortMin__c" : 3389, "CA10O1__destinationPortMax__c" : 3389, "CA10O1__networkSecurityGroup__c" : "test1", "Id" : "test1_1" }, { "context" : { "snapshotTime" : new Date("2026-04-12T00:00:00Z") }, "CA10O1__direction__c" : "INGRESS", "CA10O1__source__c" : "10.0.0.0/24", "CA10O1__protocol__c" : "TCP", "CA10O1__destinationPortMin__c" : 3389, "CA10O1__destinationPortMax__c" : 3389, "CA10O1__networkSecurityGroup__c" : "test2", "Id" : "test2_1" } ]; """; CREATE TEMP FUNCTION process_CA10O1__CaOracleIaasNetworkSecurityGroup__c( obj STRUCT< CA10O1__disappearanceTime__c TIMESTAMP, Id STRING, CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r ARRAY >> >, snapshotTime TIMESTAMP ) RETURNS STRUCT DETERMINISTIC LANGUAGE js AS r""" var references1 = []; // condition[0], conditionIndex:[0..99] references1.push('Deleted From Oracle [CA10O1__disappearanceTime__c]: ' + obj.CA10O1__disappearanceTime__c); if (obj.CA10O1__disappearanceTime__c != null) { return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10O1__disappearanceTime__c)", currentStateMessage: "Object is deleted in the source", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } var count_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r_INCOMPLIANT2 = 0; if (obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r != null) { for (var i3 = 0; i3 < obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.length; i3++) { if (typeof(obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r[i3].status) !== 'undefined') { if (obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r[i3].status == 'INCOMPLIANT') { count_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r_INCOMPLIANT2 += obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r[i3].count; } } else { if (obj.CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r[i3].result.status == 'INCOMPLIANT') { count_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r_INCOMPLIANT2 += 1; } } } } // condition[1], conditionIndex:[100..199] references1.push('Related list [CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r] ' + (count_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r_INCOMPLIANT2 > 0 ? 'has' : 'does not have') + ' objects in INCOMPLIANT status'); if (count_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r_INCOMPLIANT2 > 0) { return {status: 'INCOMPLIANT', conditionIndex: 199, conditionText: "CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r.has(INCOMPLIANT)", currentStateMessage: "The network security group has ingress rules that allow unrestricted RDP access.", currentStateReferences: references1.join('\n'), remediation: "Remove public RDP ingress or restrict it to approved source CIDRs.", runtimeError: null}; } return {status: 'COMPLIANT', conditionIndex: 200, conditionText: "otherwise", currentStateMessage: "The network security group does not allow unrestricted RDP access.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; """; CREATE TEMP FUNCTION process_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r( obj STRUCT< CA10O1__disappearanceTime__c TIMESTAMP, CA10O1__direction__c STRING, CA10O1__source__c STRING, CA10O1__protocol__c STRING, CA10O1__destinationPortMin__c FLOAT64, CA10O1__destinationPortMax__c FLOAT64, CA10O1__networkSecurityGroup__c STRING, Id STRING >, snapshotTime TIMESTAMP ) RETURNS STRUCT 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)); }; 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 CollectionLib = new function () { this.parse = function(arg, separator, skipEmpty, skipDuplicates, sort, normalize) { if (arg == null) return []; let parts = arg.split(separator); return this.fromArray(parts, skipEmpty, skipDuplicates, sort, normalize); }; this.fromArray = function(arr, skipEmpty, skipDuplicates, sort, normalize) { if (arr == null) return []; let result = []; let seen = new Set(); arr.forEach(el => { let normalized = normalize ? TextLib.normalize(el) : BytesLib.normalize(el); if (!skipEmpty || (normalize ? TextLib.isNotEmpty(el) : BytesLib.isNotEmpty(el))) { if (!skipDuplicates || !seen.has(normalized)) { if (skipDuplicates) seen.add(normalized); result.push(normalized); } } }); if (sort) result.sort(); return result; }; this.equal = function(left, right) { left = left == null ? [] : left; right = right == null ? [] : right; if (left.length !== right.length) return false; for (let i = 0; i < left.length; i++) { if (left[i] !== right[i]) return false; } return true; }; this.notEqual = function(left, right) { return !this.equal(left, right); }; this.size = function(collection) { return collection == null ? 0 : collection.length; }; this.startsWith = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; let normalizedSearch = normalize ? TextLib.normalize(search) : BytesLib.normalize(search); return collection[0] === normalizedSearch; }; this.endsWith = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; let normalizedSearch = normalize ? TextLib.normalize(search) : BytesLib.normalize(search); return collection[collection.length - 1] === normalizedSearch; }; this.contains = function(collection, search, normalize) { if (collection == null || collection.length === 0) return false; return collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search)); }; this.containsAll = function(collection, searchArray, normalize) { if (collection == null || collection.length === 0 || searchArray == null || searchArray.length === 0) return false; return searchArray.every(search => collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search))); }; this.containsAny = function(collection, searchArray, normalize) { if (collection == null || collection.length === 0 || searchArray == null || searchArray.length === 0) return false; return searchArray.some(search => collection.includes(normalize ? TextLib.normalize(search) : BytesLib.normalize(search))); }; }(); var BytesLib = new function () { this.normalize = function(arg) { return arg == null ? '' : arg; }; 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 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 Oracle [CA10O1__disappearanceTime__c]: ' + obj.CA10O1__disappearanceTime__c); if (obj.CA10O1__disappearanceTime__c != null) { return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10O1__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.CA10O1__direction__c; } return this.out; }; references1.push('Direction [obj.CA10O1__direction__c]: ' + obj.CA10O1__direction__c); if (TextLib.notEqual(extract3.call(extract3), 'INGRESS')) { return {status: 'INAPPLICABLE', conditionIndex: 199, conditionText: "extract('CA10O1__direction__c') != 'INGRESS'", currentStateMessage: "This is not an ingress rule.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[2], conditionIndex:[200..299] function extract6() { if (!this.out) { this.out = obj.CA10O1__source__c; } return this.out; }; references1.push('Source [obj.CA10O1__source__c]: ' + obj.CA10O1__source__c); if (TextLib.notEqual(extract6.call(extract6), '0.0.0.0/0') && TextLib.notEqual(extract6.call(extract6), '::/0')) { return {status: 'INAPPLICABLE', conditionIndex: 299, conditionText: "extract('CA10O1__source__c') != '0.0.0.0/0' && extract('CA10O1__source__c') != '::/0'", currentStateMessage: "This ingress rule is not sourced from the internet.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[3], conditionIndex:[300..399] function extract10() { if (!this.out) { this.out = obj.CA10O1__protocol__c; } return this.out; }; references1.push('Protocol [obj.CA10O1__protocol__c]: ' + obj.CA10O1__protocol__c); if (!CollectionLib.contains(CollectionLib.fromArray(['ALL', 'TCP'], true, true, true, true), extract10.call(extract10), true)) { return {status: 'INAPPLICABLE', conditionIndex: 399, conditionText: "not(setOfText(['ALL', 'TCP']).contains(extract('CA10O1__protocol__c')))", currentStateMessage: "This ingress rule does not use ALL or TCP protocol.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[4], conditionIndex:[400..499] function extract13() { if (!this.out) { this.out = obj.CA10O1__protocol__c; } return this.out; }; if (TextLib.equal(extract13.call(extract13), 'ALL')) { return {status: 'INCOMPLIANT', conditionIndex: 499, conditionText: "extract('CA10O1__protocol__c') == 'ALL'", currentStateMessage: "This ingress rule allows RDP access from the internet.", currentStateReferences: references1.join('\n'), remediation: "Remove this rule or restrict the source CIDR to approved administrative ranges.", runtimeError: null}; } // condition[5], conditionIndex:[500..599] function extract16() { if (!this.out) { this.out = obj.CA10O1__protocol__c; } return this.out; }; function extract19() { if (!this.out) { this.out = obj.CA10O1__destinationPortMin__c; } return this.out; }; function extract22() { if (!this.out) { this.out = obj.CA10O1__destinationPortMax__c; } return this.out; }; references1.push('Destination Port Min [obj.CA10O1__destinationPortMin__c]: ' + obj.CA10O1__destinationPortMin__c); references1.push('Destination Port Max [obj.CA10O1__destinationPortMax__c]: ' + obj.CA10O1__destinationPortMax__c); if (TextLib.equal(extract16.call(extract16), 'TCP') && ((IsEmptyLib.simpleIsEmpty(extract19.call(extract19)) && IsEmptyLib.simpleIsEmpty(extract22.call(extract22))) || ((extract19.call(extract19) != null && 3389.0 != null && extract19.call(extract19) <= 3389.0) && (extract22.call(extract22) != null && 3389.0 != null && extract22.call(extract22) >= 3389.0)))) { return {status: 'INCOMPLIANT', conditionIndex: 599, conditionText: "extract('CA10O1__protocol__c') == 'TCP' && ((extract('CA10O1__destinationPortMin__c').isEmpty() && extract('CA10O1__destinationPortMax__c').isEmpty()) || (extract('CA10O1__destinationPortMin__c') <= number(3389.0) && extract('CA10O1__destinationPortMax__c') >= number(3389.0)))", currentStateMessage: "This ingress rule allows RDP access from the internet.", currentStateReferences: references1.join('\n'), remediation: "Remove this rule or restrict the source CIDR to approved administrative ranges.", runtimeError: null}; } return {status: 'COMPLIANT', conditionIndex: 600, conditionText: "otherwise", currentStateMessage: "This ingress rule does not allow unrestricted RDP access.", 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.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.Id AS Id, `CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r`.arr AS CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r, process_CA10O1__CaOracleIaasNetworkSecurityGroup__c( STRUCT( sObject.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.Id AS Id, `CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r`.arr AS CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r ), sObject.context.snapshotTime ) as result FROM UNNEST(mock_CA10O1__CaOracleIaasNetworkSecurityGroup__c()) AS sObject LEFT JOIN ( SELECT sObject.CA10O1__networkSecurityGroup__c, ARRAY_AGG( STRUCT( sObject.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.CA10O1__direction__c AS CA10O1__direction__c, sObject.CA10O1__source__c AS CA10O1__source__c, sObject.CA10O1__protocol__c AS CA10O1__protocol__c, sObject.CA10O1__destinationPortMin__c AS CA10O1__destinationPortMin__c, sObject.CA10O1__destinationPortMax__c AS CA10O1__destinationPortMax__c, sObject.CA10O1__networkSecurityGroup__c AS CA10O1__networkSecurityGroup__c, sObject.Id AS Id, process_CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r( STRUCT( sObject.CA10O1__disappearanceTime__c AS CA10O1__disappearanceTime__c, sObject.CA10O1__direction__c AS CA10O1__direction__c, sObject.CA10O1__source__c AS CA10O1__source__c, sObject.CA10O1__protocol__c AS CA10O1__protocol__c, sObject.CA10O1__destinationPortMin__c AS CA10O1__destinationPortMin__c, sObject.CA10O1__destinationPortMax__c AS CA10O1__destinationPortMax__c, sObject.CA10O1__networkSecurityGroup__c AS CA10O1__networkSecurityGroup__c, sObject.Id AS Id ), sObject.context.snapshotTime ) as result ) ) AS arr FROM UNNEST(mock_CA10O1__CaOracleIaasNetworkSecurityGroupRule__c()) AS sObject GROUP BY sObject.CA10O1__networkSecurityGroup__c ) AS `CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r` ON sObject.Id = `CA10O1__Oracle_IAAS_Network_Security_Group_Rules__r`.CA10O1__networkSecurityGroup__c ) sObject ON sObject.Id = expectedResult.Id;