2

I have the following helper function in a test of my OPA policy. I would like to make it more generic and return the resource with the commonName field only if cn is not empty. Any ideas on how I can conditionally add the commonName field?

new_certificate(issuerName, uid, organization, organizationalUnit, cn) = { "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", "commonName": cn, "subject": { "organizations": [ organization ], "organizationalUnits": [ organizationalUnit ] } } } 

Thanks, Erkan

1 Answer 1

0

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:

  1. How do I merge two objects in rego?
  2. Open Policy Agent/Policy Reference/Built-in Functions/Objects/object.union
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.