Skip to content

Commit

Permalink
formatted python files
Browse files Browse the repository at this point in the history
  • Loading branch information
JTaeuber committed Nov 14, 2024
1 parent 2e385ea commit 3d8e406
Show file tree
Hide file tree
Showing 14 changed files with 634 additions and 524 deletions.
10 changes: 5 additions & 5 deletions kube_downscaler/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,10 @@ def get_parser():
parser.add_argument(
"--upscale-target-only",
help="Upscale only resource in target when waking up namespaces",
action="store_true"
action="store_true",
)
parser.add_argument(
"--namespace",
help="Namespace",
default=os.getenv("NAMESPACE", "")
"--namespace", help="Namespace", default=os.getenv("NAMESPACE", "")
)
parser.add_argument(
"--include-resources",
Expand Down Expand Up @@ -100,7 +98,9 @@ def get_parser():
parser.add_argument(
"--exclude-deployments",
help="Exclude specific deployments from downscaling. Despite its name, this option will match the name of any included resource type (Deployment, StatefulSet, CronJob, ..). (default: py-kube-downscaler,kube-downscaler,downscaler)",
default=os.getenv("EXCLUDE_DEPLOYMENTS", "py-kube-downscaler,kube-downscaler,downscaler"),
default=os.getenv(
"EXCLUDE_DEPLOYMENTS", "py-kube-downscaler,kube-downscaler,downscaler"
),
)
parser.add_argument(
"--downtime-replicas",
Expand Down
4 changes: 3 additions & 1 deletion kube_downscaler/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ def run_loop(

if len(namespaces) >= 1:
constrained_downscaler = True
logging.info("Namespace argument is not empty, the downscaler will run in constrained mode")
logging.info(
"Namespace argument is not empty, the downscaler will run in constrained mode"
)
else:
constrained_downscaler = False

Expand Down
11 changes: 2 additions & 9 deletions kube_downscaler/resources/constraint.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


class KubeDownscalerJobsConstraint(APIObject):

"""Support the Gatakeeper Admission Controller Custom CRDs (https://open-policy-agent.github.io/gatekeeper/website/docs)."""

version = "constraints.gatekeeper.sh/v1beta1"
Expand All @@ -24,15 +23,9 @@ def create_job_constraint(resource_name):
"kind": "KubeDownscalerJobsConstraint",
"metadata": {
"name": resource_name,
"labels": {
"origin": "kube-downscaler"
}
"labels": {"origin": "kube-downscaler"},
},
"spec": {
"match": {
"namespaces": [resource_name]
}
}
"spec": {"match": {"namespaces": [resource_name]}},
}

return obj
48 changes: 24 additions & 24 deletions kube_downscaler/resources/constrainttemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class ConstraintTemplate(APIObject):

"""Support the Gatakeeper Admission Controller Custom CRDs (https://open-policy-agent.github.io/gatekeeper/website/docs)."""

version = "templates.gatekeeper.sh/v1"
Expand All @@ -13,36 +12,47 @@ class ConstraintTemplate(APIObject):

@staticmethod
def create_constraint_template_crd(excluded_jobs, matching_labels):

excluded_jobs_regex = '^(' + '|'.join(excluded_jobs) + ')$'
excluded_jobs_regex = "^(" + "|".join(excluded_jobs) + ")$"

# For backwards compatibility, if the matching_labels FrozenSet has an empty string as the first element,
# we don't ignore anything
first_element = next(iter(matching_labels), None)
first_element_str = first_element.pattern

if first_element_str == "":
logger.debug("Matching_labels arg set to empty string: all resources are considered in the scaling process")
logger.debug(
"Matching_labels arg set to empty string: all resources are considered in the scaling process"
)
matching_labels_arg_is_present = False
else:
matching_labels_arg_is_present = True

if matching_labels_arg_is_present:
matching_labels_rego_string: str = "\n"
for pattern in matching_labels:
matching_labels_rego_string = matching_labels_rego_string + " has_matched_labels(\"" + pattern.pattern + "\", input.review.object.metadata.labels)\n"
matching_labels_rego_string = (
matching_labels_rego_string
+ ' has_matched_labels("'
+ pattern.pattern
+ '", input.review.object.metadata.labels)\n'
)
else:
matching_labels_rego_string: str = ""

rego = """
rego = (
"""
package kubedownscalerjobsconstraint
violation[{"msg": msg}] {
input.review.kind.kind == "Job"
not exist_owner_reference
not exact_match(\"""" + excluded_jobs_regex + """\", input.review.object.metadata.name)
not exact_match(\""""
+ excluded_jobs_regex
+ """\", input.review.object.metadata.name)
not has_exclude_annotation
not is_exclude_until_date_reached""" + matching_labels_rego_string + """
not is_exclude_until_date_reached"""
+ matching_labels_rego_string
+ """
msg := "Job creation is not allowed in this namespace during a kube-downscaler downtime period."
}
Expand Down Expand Up @@ -73,6 +83,7 @@ def create_constraint_template_crd(excluded_jobs, matching_labels):
regex.match(pattern, equals_value_contact)
}
"""
)

obj = {
"apiVersion": "templates.gatekeeper.sh/v1",
Expand All @@ -82,24 +93,13 @@ def create_constraint_template_crd(excluded_jobs, matching_labels):
"annotations": {
"metadata.gatekeeper.sh/title": "Kube Downscaler Jobs Constraint",
"metadata.gatekeeper.sh/version": "1.0.0",
"description": "Policy to downscale jobs in certain namespaces."
}
"description": "Policy to downscale jobs in certain namespaces.",
},
},
"spec": {
"crd": {
"spec": {
"names": {
"kind": "KubeDownscalerJobsConstraint"
}
}
},
"targets": [
{
"target": "admission.k8s.gatekeeper.sh",
"rego": rego
}
]
}
"crd": {"spec": {"names": {"kind": "KubeDownscalerJobsConstraint"}}},
"targets": [{"target": "admission.k8s.gatekeeper.sh", "rego": rego}],
},
}

return obj
6 changes: 4 additions & 2 deletions kube_downscaler/resources/keda.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


class ScaledObject(NamespacedAPIObject):

"""Support the ScaledObject resource (https://keda.sh/docs/2.7/concepts/scaling-deployments/#scaledobject-spec)."""

version = "keda.sh/v1alpha1"
Expand All @@ -21,7 +20,10 @@ def replicas(self):
replicas = -1
elif self.annotations[ScaledObject.keda_pause_annotation] == "0":
replicas = 0
elif self.annotations[ScaledObject.keda_pause_annotation] != "0" and self.annotations[ScaledObject.keda_pause_annotation] is not None:
elif (
self.annotations[ScaledObject.keda_pause_annotation] != "0"
and self.annotations[ScaledObject.keda_pause_annotation] is not None
):
replicas = int(self.annotations[ScaledObject.keda_pause_annotation])
else:
replicas = -1
Expand Down
100 changes: 45 additions & 55 deletions kube_downscaler/resources/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


class KubeDownscalerJobsPolicy(NamespacedAPIObject):

"""Support the Kyverno Admission Controller Custom CRDs (https://kyverno.io/docs/introduction/#quick-start)."""

version = "kyverno.io/v1"
Expand All @@ -19,29 +18,21 @@ def create_job_policy(namespace):
"namespace": namespace,
"labels": {
"origin": "kube-downscaler",
"kube-downscaler/policy-type": "without-matching-labels"
"kube-downscaler/policy-type": "without-matching-labels",
},
"annotations": {
"policies.kyverno.io/title": "Kube Downscaler Jobs Policy",
"policies.kyverno.io/severity": "medium",
"policies.kyverno.io/subject": "Job",
"policies.kyverno.io/description": "Job creation is not allowed in this namespace during a kube-downscaler downtime period."
}
"policies.kyverno.io/description": "Job creation is not allowed in this namespace during a kube-downscaler downtime period.",
},
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"name": "kube-downscaler-jobs-policy",
"match": {
"any": [
{
"resources": {
"kinds": ["Job"]
}
}
]
},
"match": {"any": [{"resources": {"kinds": ["Job"]}}]},
"validate": {
"message": "Job creation is not allowed in this namespace during a kube-downscaler downtime period.",
"deny": {
Expand All @@ -50,25 +41,25 @@ def create_job_policy(namespace):
{
"key": "{{ request.object.metadata.ownerReferences || 'null'}}",
"operator": "Equals",
"value": "null"
"value": "null",
},
{
"key": "{{request.object.metadata.annotations.\"downscaler/exclude\" || ''}}",
"operator": "NotEquals",
"value": "true"
"value": "true",
},
{
"key": "{{ time_after('{{ time_now() }}','{{ request.object.metadata.annotations.\"downscaler/exclude-until\" || '1970-01-01T00:00:00Z' }}') }}",
"operator": "Equals",
"value": True
}
"value": True,
},
]
}
}
}
},
},
}
]
}
],
},
}

return obj
Expand All @@ -83,35 +74,27 @@ def create_job_policy_with_matching_labels(namespace, matching_labels):
"namespace": namespace,
"labels": {
"origin": "kube-downscaler",
"kube-downscaler/policy-type": "with-matching-labels"
"kube-downscaler/policy-type": "with-matching-labels",
},
"annotations": {
"policies.kyverno.io/description": "Job creation is not allowed in this namespace during a kube-downscaler downtime period.",
"policies.kyverno.io/severity": "medium",
"policies.kyverno.io/subject": "Job",
"policies.kyverno.io/title": "Kube Downscaler Jobs Policy"
}
"policies.kyverno.io/title": "Kube Downscaler Jobs Policy",
},
},
"spec": {
"validationFailureAction": "Enforce",
"rules": [
{
"match": {
"any": [
{
"resources": {
"kinds": ["Job"]
}
}
]
},
"match": {"any": [{"resources": {"kinds": ["Job"]}}]},
"name": "kube-downscaler-jobs-policy",
"preconditions": {
"all": [
{
"key": "{{ request.object.metadata.labels || 'NoLabel'}}",
"operator": "NotEquals",
"value": "NoLabel"
"value": "NoLabel",
}
]
},
Expand All @@ -120,8 +103,8 @@ def create_job_policy_with_matching_labels(namespace, matching_labels):
"name": "labels",
"variable": {
"jmesPath": "items(request.object.metadata.labels, 'key', 'value')",
"default": []
}
"default": [],
},
}
],
"validate": {
Expand All @@ -135,56 +118,63 @@ def create_job_policy_with_matching_labels(namespace, matching_labels):
{
"key": "{{ request.object.metadata.ownerReferences || 'null'}}",
"operator": "Equals",
"value": "null"
"value": "null",
},
{
"key": "{{request.object.metadata.annotations.\"downscaler/exclude\" || ''}}",
"operator": "NotEquals",
"value": "true"
"value": "true",
},
{
"key": "{{ time_after('{{ time_now() }}','{{ request.object.metadata.annotations.\"downscaler/exclude-until\" || '1970-01-01T00:00:00Z' }}') }}",
"operator": "Equals",
"value": True
}
"value": True,
},
]
}
}
},
}
]
}
],
},
}
]
}
],
},
}

for pattern in matching_labels:
matching_labels_condition = {
"key": "{{ regex_match('" + pattern.pattern + "', '{{element.key}}={{element.value}}') }}",
"key": "{{ regex_match('"
+ pattern.pattern
+ "', '{{element.key}}={{element.value}}') }}",
"operator": "Equals",
"value": True
"value": True,
}
obj["spec"]["rules"][0]["validate"]["foreach"][0]["deny"]["conditions"]["all"].append(
matching_labels_condition)
obj["spec"]["rules"][0]["validate"]["foreach"][0]["deny"]["conditions"][
"all"
].append(matching_labels_condition)

return obj

@staticmethod
def append_excluded_jobs_condition(obj, excluded_jobs, has_matching_labels_arg):

excluded_jobs_regex = f"^({'|'.join(excluded_jobs)})$"

excluded_jobs_condition = {
"key": "{{ regex_match('" + excluded_jobs_regex + "', '{{request.object.metadata.name}}') }}",
"key": "{{ regex_match('"
+ excluded_jobs_regex
+ "', '{{request.object.metadata.name}}') }}",
"operator": "NotEquals",
"value": True
"value": True,
}

if has_matching_labels_arg:
obj["spec"]["rules"][0]["validate"]["foreach"][0]["deny"]["conditions"]["all"].append(
excluded_jobs_condition)
obj["spec"]["rules"][0]["validate"]["foreach"][0]["deny"]["conditions"][
"all"
].append(excluded_jobs_condition)
else:
obj["spec"]["rules"][0]["validate"]["deny"]["conditions"]["all"].append(excluded_jobs_condition)
obj["spec"]["rules"][0]["validate"]["deny"]["conditions"]["all"].append(
excluded_jobs_condition
)

return obj

Expand Down
Loading

0 comments on commit 3d8e406

Please sign in to comment.