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: