You could make the function more generic by moving the commonName field into a separate function that checks the input and returns the common name component of the certificate or an empty object. Then take the 2 resulting objects and merge them together using object.union. Here's an example:
policy.rego:
package example new_certificate(issuerName, uid, organization, organizationalUnit) = { "apiVersion": "cert-manager.io/v1", "kind": "Certificate", "metadata": { "name": "test-certificate", "namespace": "tenant-ns" }, "spec": { "isCA": true, "issuerRef": { "group": "rhcs-issuer.it-platform.redhat.com", "kind": "ClusterIssuer", "name": issuerName }, "privateKey": { "algorithm": "ECDSA", "size": 256 }, "secretName": "test-tls", "subject": { "organizations": [ organization ], "organizationalUnits": [ organizationalUnit ] } } } new_common_name(common_name) = cn { trim_space(common_name) != "" cn := { "spec": { "commonName": common_name } } } new_common_name(common_name) = cn { trim_space(common_name) == "" cn := {} } cert1 := object.union(new_certificate("SignalRichard", "77479301", "stack-exchange", "stack-overflow"), new_common_name("stackoverflow.com")) cert2 := object.union(new_certificate("SignalRichard", "77479301", "stack-exchange", "stack-overflow"), new_common_name(""))
Running this code with opa eval -d policy.rego "data.example" results in the following output with cert1 having the commonName field populated and cert2 does not have the field at all:
{ "result": [ { "expressions": [ { "value": { "cert1": { "apiVersion": "cert-manager.io/v1", "kind": "Certificate", "metadata": { "name": "test-certificate", "namespace": "tenant-ns" }, "spec": { "commonName": "stackoverflow.com", "isCA": true, "issuerRef": { "group": "rhcs-issuer.it-platform.redhat.com", "kind": "ClusterIssuer", "name": "SignalRichard" }, "privateKey": { "algorithm": "ECDSA", "size": 256 }, "secretName": "test-tls", "subject": { "organizationalUnits": [ "stack-overflow" ], "organizations": [ "stack-exchange" ] } } }, "cert2": { "apiVersion": "cert-manager.io/v1", "kind": "Certificate", "metadata": { "name": "test-certificate", "namespace": "tenant-ns" }, "spec": { "isCA": true, "issuerRef": { "group": "rhcs-issuer.it-platform.redhat.com", "kind": "ClusterIssuer", "name": "SignalRichard" }, "privateKey": { "algorithm": "ECDSA", "size": 256 }, "secretName": "test-tls", "subject": { "organizationalUnits": [ "stack-overflow" ], "organizations": [ "stack-exchange" ] } } } }, "text": "data.example", "location": { "row": 1, "col": 1 } } ] } ] }
References:
- How do I merge two objects in rego?
- Open Policy Agent/Policy Reference/Built-in Functions/Objects/object.union