@@ -483,104 +483,6 @@ spec:
483483 targetCPUUtilizationPercentage : 80
484484---
485485
486- apiVersion : v1
487- data :
488- pdb-adv-from-torin.rego : " package kubernetes.admission.policy_pdb\n\n policy_metadata
489- = {\n\n\t # Set MagTape Policy Info\n\t\" name\" : \" policy-pdb\" ,\n\t\" severity\" :
490- \" HIGH\" ,\n\t\" errcode\" : \" MT1005-3\" ,\n\t\" targets\" : {\" PodDisruptionBudget\" },\n\n }\n\n servicetype
491- = input.request.kind.kind\n\n matches {\n\n # Verify request object type matches
492- targets\n policy_metadata.targets[servicetype]\n \n }\n\n limits = {\n\n\t\" minAvailable\" :
493- [0, 66],\n \" maxUnavailable\" : [33, 100],\n\t\n }\n\n # Generates a violation
494- if the input specifes a percentage out-of-range.\n deny[info] {\n\n # Get limit
495- range\n\t range := limits[name]\n\n\t # Get the percentage value\n [percent,
496- true] = get_percentage(input.request.object.spec[name])\n\n # Verify the percentage
497- is within range\n\t not within_range(percent, range)\n\n msg := sprintf(\" [FAIL]
498- %v - Value (%v%%) for \\\" %v\\\" not within range %v%%-%v%% (%v)\" , [policy_metadata.severity,
499- percent, name, range[0], range[1], policy_metadata.errcode])\n\n\t info := {\n
500- \ \" name\" : policy_metadata.name,\n \" severity\" : policy_metadata.severity,\n
501- \ \" errcode\" : policy_metadata.errcode,\n \" msg\" : msg,\n }\n }\n\n deny[info]
502- {\n\t min_available_violation[info]\n }\n\n deny[info] {\n\t max_unavailable_violation[info]\n }\n\n min_available_violation[info]
503- {\n (count(matching_pods) - input.request.object.spec.minAvailable) < 1 \n
504- \ info := {\n \t\" msg\" : \" bad minAvailable\"\n }\n }\n\n # TODO: put test
505- in place for this rule\n max_unavailable_violation[info] {\n\t count(matching_pods)
506- <= input.request.object.spec.maxUnavailable\n info := {\n \t\" msg\" : \" bad
507- maxUnavailable\"\n }\n }\n\n matching_pods := {pod |\n some name\n\t pod :=
508- data.kubernetes.pods[input.request.namespace][name]\n\t matches_podSelector(pod,
509- input.request.object.spec.selector)\n }\n\n # workload_types := {\" deployments\" ,
510- \" statefulsets\" , \" jobs\" }\n # \n # num_matching_replicas := sum({n |\n # some
511- name\n # # TODO: make support other workload types...\n # \t deployment := data.kubernetes.deployments[input.request.namespace][name]\n #
512- \t matches_podSelector(deployment.spec.template, input.request.object.spec.selector)\n #
513- \ n := deployment.spec.replicas\n # })\n\n within_range(x, [_min, _max]) {\n\t x
514- >= _min\n x <= _max\n }\n\n # get_percentage accepts a value and generates a
515- tuple containing the \n # numeric percentage value and a boolean value indicating
516- whether the\n # input value could be converted to a numeric percentage.\n #\n # Examples:\n #\n #
517- \ get_percentage(50) == [0, false]\n # get_percentage(\" 50\" ) == [0, false]\n #
518- \ get_percentage(\" 50%\" ) == [50, true]\n get_percentage(value) = [0, false] {\n\t not
519- is_string(value)\n\n } else = [0, false] {\n\t not contains(value, \" %\" )\n\n } else
520- = [percent, true] {\n\t percent := to_number(trim(value, \" %\" ))\n\n }\n\n #######################################################\n #
521- LabelSelectors\n # Example:\n # matchLabels:\n # role: db\n # matchExpression:\n #
522- \ - key: foo\n # operator: in\n # values: [\" a\" , \" b\" , \" c\" ]\n matches_podSelector(obj,
523- selector) {\n\t selector != null # null label selector matches nothing\n\t selector_matchesExpressions(obj,
524- selector)\n\t selector_matchesLabels(obj, selector)\n }\n\n\n # matchLabels is a
525- map of {key,value} pairs.\n # A single {key,value} in the matchLabels map is equivalent
526- to an element of matchExpressions,\n # whose key field is \" key\" , the operator
527- is \" In\" , and the values array contains only \" value\" .\n # The requirements
528- are ANDed.\n selector_matchesLabels(obj, selector) {\n\t not selector.matchLabels\n }\n\n selector_matchesLabels(obj,
529- selector) {\n\t matchesLabels(obj.metadata.labels, selector.matchLabels)\n }\n\n matchesLabels(labels,
530- matchLabels) {\n\t not matchLabels_fails(labels, matchLabels)\n }\n\n matchLabels_fails(labels,
531- matchLabels) {\n\t value := matchLabels[key]\n\t not labels[key] == value\n }\n\n\n #
532- matchExpressions is a list of LabelSelectorsRequirements:\n # A label selector
533- requirement is a selector that contains values, a key, and an operator that relates
534- the key and values.\n # key is the label key that the selector applies to.\n #
535- \ operator represents a key's relationship to a set of values. Valid operators
536- are In, NotIn, Exists and DoesNotExist.\n # values is an array of string values.
537- If the operator is In or NotIn, the values array must be non-empty. If the operator
538- is Exists or DoesNotExist, the values array must be empty. This array is replaced
539- during a strategic merge patch.\n selector_matchesExpressions(obj, selector) {\n\t not
540- selector.matchExpressions\n }\n\n selector_matchesExpressions(obj, selector) {\n\t matchesExpressions(obj.metadata.labels,
541- selector.matchExpressions)\n }\n\n matchesExpressions(labels, matchExpressions)
542- {\n\t not matchExpressions_fails(labels, matchExpressions)\n }\n\n matchExpressions_fails(labels,
543- matchExpressions) {\n\t me := matchExpressions[_]\n\t not matchExpression(labels,
544- me)\n }\n\n matchExpression(labels, me) {\n\t lower(me.operator) == \" exists\"\n\t labels[me.key]\n }\n\n matchExpression(labels,
545- me) {\n\t lower(me.operator) == \" doesnotexist\"\n\t not labels[me.key]\n }\n\n matchExpression(labels,
546- me) {\n\t lower(me.operator) == \" in\"\n\t me.values[_] == labels[me.key]\n }\n\n matchExpression(labels,
547- me) {\n\t lower(me.operator) == \" notin\"\n\t found := {x | x := me.values[_]; labels[me.key]
548- == x}\n\t count(found) == 0\n }\n\n\n test_min_available_violation_positive {\n count(min_available_violation)
549- > 0 with input as {\n \" request\" : {\n \" kind\" : {\n \" kind\" :
550- \" PodDisruptionBudget\"\n },\n \" namespace\" : \" testns\" ,\n
551- \ \" object\" : {\n \" apiVersion\" : \" policy/v1beta1\" ,\n
552- \ \" kind\" : \" PodDisruptionBudget\" ,\n \" metadata\" :
553- {\n \" name\" : \" test-pdb01\"\n },\n \" spec\" :
554- {\n \" minAvailable\" : 10,\n \" selector\" : {\n \" matchLabels\" :
555- {\n \" app\" : \" test-pdb01\"\n }\n }\n
556- \ }\n }\n }\n } with data.kubernetes.pods.testns
557- as { \n \" test-pdb01-pod1\" : {\n \" metadata\" :
558- {\n \" labels\" : {\n \t\" app\" :
559- \" test-pdb01\"\n }\n\t\t\t\t\t }\n },\n \" nginx\" :
560- {\n \" metadata\" : {}\n }\n }\n }\n\n test_min_available_violation_negative
561- {\n \t count(min_available_violation) == 0 with input as {\n \" request\" :
562- {\n \" kind\" : {\n \" kind\" : \" PodDisruptionBudget\"\n
563- \ },\n \" namespace\" : \" testns\" ,\n \" object\" :
564- {\n \" apiVersion\" : \" policy/v1beta1\" ,\n \" kind\" :
565- \" PodDisruptionBudget\" ,\n \" metadata\" : {\n \" name\" :
566- \" test-pdb01\"\n },\n \" spec\" : {\n \" minAvailable\" :
567- 0,\n \" selector\" : {\n \" matchLabels\" : {\n \" app\" :
568- \" test-pdb01\"\n }\n }\n }\n }\n
569- \ }\n } with data.kubernetes.pods.testns as { \n \" test-pdb01-pod1\" :
570- {\n \" metadata\" : {\n \" labels\" : {\n
571- \ \t\" app\" : \" test-pdb01\"\n }\n\t\t\t\t\t }\n
572- \ },\n \" nginx\" : {\n \" metadata\" :
573- {}\n }\n }\n }"
574- kind : ConfigMap
575- metadata :
576- creationTimestamp : null
577- labels :
578- app : opa
579- openpolicyagent.org/policy : rego
580- name : pdb-adv-from-torin
581- namespace : magtape-system
582- ---
583-
584486apiVersion : v1
585487data :
586488 policy-emptydir-check.rego : " package kubernetes.admission.policy_emptydir\n\n policy_metadata
@@ -756,57 +658,6 @@ metadata:
756658 namespace : magtape-system
757659---
758660
759- apiVersion : v1
760- data :
761- policy-pdb-advanced-check.rego : " package kubernetes.admission.policy_pdb_advanced\n\n import
762- data.kubernetes.pods\n\n policy_metadata = {\n\t # Set MagTape Policy Info\n\t\" name\" :
763- \" policy-pdb-advanced\" ,\n\t\" severity\" : \" HIGH\" ,\n\t\" errcode\" : \" MT1005-2\" ,\n\t\" targets\" :
764- {\" PodDisruptionBudget\" },\n }\n\n servicetype = input.request.kind.kind\n\n matches
765- {\n\t # Verify request object type matches targets\n\t policy_metadata.targets[servicetype]\n }\n\n limits
766- = {\n\t\" minAvailable\" : [0, 66],\n\t\" maxUnavailable\" : [33, 100],\n }\n\n # Generates
767- a violation if the input specifes a percentage out-of-range.\n deny[info] {\n\t #
768- Get limit range\n\t range := limits[name]\n\n\t # Get the percentage value\n\t [percent,
769- true] = get_percentage(input.request.object.spec[name])\n\n\t # Verify the percentage
770- is within range\n\t not within_range(percent, range)\n\n\t msg := sprintf(\" [FAIL]
771- %v - Value (%v%%) for \\\" %v\\\" not within range %v%%-%v%% (%v)\" , [policy_metadata.severity,
772- percent, name, range[0], range[1], policy_metadata.errcode])\n\n\t info := {\n\t\t\" name\" :
773- policy_metadata.name,\n\t\t\" severity\" : policy_metadata.severity,\n\t\t\" errcode\" :
774- policy_metadata.errcode,\n\t\t\" msg\" : msg,\n\t }\n }\n\n within_range(x, [_min,
775- _max]) {\n\t x >= _min\n\t x <= _max\n }\n\n # get_percentage accepts a value and
776- generates a tuple containing the \n # numeric percentage value and a boolean value
777- indicating whether the\n # input value could be converted to a numeric percentage.\n #\n #
778- Examples:\n #\n # get_percentage(50) == [0, false]\n # get_percentage(\" 50\" )
779- == [0, false]\n # get_percentage(\" 50%\" ) == [50, true]\n get_percentage(value)
780- = [0, false] {\n\t not is_string(value)\n }\n\n else = [0, false] {\n\t not contains(value,
781- \" %\" )\n }\n\n else = [percent, true] {\n\t percent := to_number(trim(value, \" %\" ))\n }\n\n ###################################\n\n deny[info]
782- {\n\n # Get limit type\n\t limits[name]\n\n # Get limit value\n\t value :=
783- input.request.object.spec[name]\n\n is_number(value)\n\n #selectors = []\n\n
784- \ selectors := get_pdb_selectors(value)\n\n msg := sprintf(\" [FAIL] %v -
785- Value \\\" %v\\\" for \\\" %v\\\" is an invalid integer (%v)\" , [policy_metadata.severity,
786- value, name, policy_metadata.errcode])\n\n\t info := {\n\t\t\" name\" : policy_metadata.name,\n\t\t\" severity\" :
787- policy_metadata.severity,\n\t\t\" errcode\" : policy_metadata.errcode,\n\t\t\" msg\" :
788- msg,\n\t }\n\n\n #if value is an integer; then\n #\n # pdb_selectors
789- = get_pdb_selectors\n # replicas = get_replicas(pdb_selectors)\n #\n
790- \ # if replicas - value < 1; then\n #\n # deny because it's
791- a blocking/bad config\n #\n # fi\n #\n #fi\n }\n\n\n get_pdb_selectors(pdb)
792- = pdb.spec.matchLabels {\n\n pdb.spec.matchLabels\n }\n\n else = pdb.spec.matchExpressions
793- {\n\n pdb.spec.matchExpressions\n\n }\n\n #func get_replicas(pdb_selectors) {\n #\n #
794- \ count all pods that match all pdb_selectors\n #\n # return count\n #\n #}\n\n\n\n\n ##
795- Notes from discussion with Torin\n\n #- Possible race condition with pods existing
796- if workload and PDB are deployed simultaneously or very close together\n # -
797- Pods may not exist yet at the time the PDB is deployed and that could cause a
798- false positive\n #- Policy can be designed to work off workload replica count\n #
799- \ - \n "
800- kind : ConfigMap
801- metadata :
802- creationTimestamp : null
803- labels :
804- app : opa
805- openpolicyagent.org/policy : rego
806- name : policy-pdb-advanced-check
807- namespace : magtape-system
808- ---
809-
810661apiVersion : v1
811662data :
812663 policy-pdb-check.rego : " package kubernetes.admission.policy_pdb\n\n policy_metadata
0 commit comments