OPA (Open Policy Agent): Part-6: Rego – Enforcing labels For Kubernetes Deployment

Share At:

Open Policy Agent | Policy Language

Overview

In this article, we are going to learn about how to create a  Rule for Kubernetes Deployment Manifest.

The policy will check whether the defined label exists in our pod manifest file.

In order to in Rego, we will convert our pod manifest file (which is in Yaml format) to Json format. We will name it as “input.json”

Working Example

Let’s create a Directory called test7 and create files like below:

policy.rego

package k8srequiredlabels

violation[{"msg": msg, "details": {"missing_labels": missing}}] {
          input.kind == "deployment"
          provided := { x | input.metadata.labels[x]}
          required := { "gatekeeper", "foo"}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("you must provide labels: %v", [missing])
        }

input.json

{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
      "name": "simple-pod",
      "labels": {
        "gatekeeper": "xyz",
        "foo": "bar"
      }
    },
    "spec": {
      "containers": [
        {
          "name": "nginx-container",
          "image": "nginx:1.17.4"
        }
      ]
    }
  }

Understanding Rule

package k8srequiredlabels

violation[{"msg": msg, "details": {"missing_labels": missing}}] {
          input.kind == "deployment"
          provided := { x | input.metadata.labels[x]}
          required := { "gatekeeper", "foo"}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("you must provide labels: %v", [missing])
        }

In rego, the rule will return true if all the conditions inside rule block are true. In our policy there are 2 conditions:

  1. input.kind == “deployment”
  2. count(missing) > 0

In rego, if both the conditions are true, the rule will be true and the “msg” will be displayed. Which means if either of the condition is false, the “msg” will not displayed.

Let’s see this through experiment:

Now let’s test our policy

Testing with existing policy.rego and input.json:

let’s run the below command to test the policy:

 opa eval --input input.json --data policy.rego 'data.k8srequiredlabels.violation'

The output:

rajeevghosh@penguin:~/OPA/test7$ opa eval --input input.json --data policy.rego 'data.k8srequiredlabels.violation'
{
  "result": [
    {
      "expressions": [
        {
          "value": [],
          "text": "data.k8srequiredlabels.violation",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
rajeevghosh@penguin:~/OPA/test7$ 

The “value” field returns empty list [ ] , since all the conditions are not true ( actually both the conditions are false since – (a) We have kind as “Pod” in input.json and (b) the statement – : count > 0 is false since provided labels and required labels are same !!). Hence, the “msg” will NOT be displayed.

Now let’s make both the conditions are true so that the rule returns true and msg is displayed.

Testing with Modified policy.rego and input.json

Let’s make changes to input.json file like below. remember that our policy.rego file remains same

input.json – before

{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
      "name": "simple-pod",
      "labels": {
        "gatekeeper": "xyz",
        "foo": "bar"
      }
    },
    "spec": {
      "containers": [
        {
          "name": "nginx-container",
          "image": "nginx:1.17.4"
        }
      ]
    }
  }

input.json – After

{
    "apiVersion": "v1",
    "kind": "deployment",
    "metadata": {
      "name": "simple-pod",
      "labels": {
        "gatekeeper": "xyz"
      }
    },
    "spec": {
      "containers": [
        {
          "name": "nginx-container",
          "image": "nginx:1.17.4"
        }
      ]
    }
  }

What changes have we made to input.json file ? Well, we have changed kind to “deployment” and have removed one more label : “foo”.

Now let’s test the policy.

opa eval --input input.json --data policy.rego 'data.k8srequiredlabels.violation'

The output:

rajeevghosh@penguin:~/OPA/test7$ opa eval --input input.json --data policy.rego 'data.k8srequiredlabels.violation'
{
  "result": [
    {
      "expressions": [
        {
          "value": [
            {
              "details": {
                "missing_labels": [
                  "foo"
                ]
              },
              "msg": "you must provide labels: {\"foo\"}"
            }
          ],
          "text": "data.k8srequiredlabels.violation",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
rajeevghosh@penguin:~/OPA/test7$ 

Please look at the value field, Now we see that the “msg” is displayed. Why ??

This is because both the below conditions are now true in the rule:

  1. input.kind == “deployment”
  2. count(missing) > 0

This concludes are 6th tutorial on : OPA (Open Policy Agent): Part-5: Rego – Ensuring labels For Kubernetes Deployment.

You may download the code from here.

Happy Learning !!


Share At:
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Back To Top

Contact Us