This repository has been archived by the owner on Oct 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from hjacobs/rules
Support generic rules to define TTL for arbitrary resources
- Loading branch information
Showing
12 changed files
with
242 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ name = "pypi" | |
[packages] | ||
pykube = "*" | ||
pytz = "*" | ||
jmespath = "*" | ||
|
||
[dev-packages] | ||
flake8 = "*" | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: kube-janitor | ||
data: | ||
rules.yaml: |- | ||
# example rules configuration to set TTL for arbitrary objects | ||
# see https://github.com/hjacobs/kube-janitor for details | ||
rules: | ||
- id: require-application-label | ||
# remove deployments and statefulsets without a label "application" | ||
resources: | ||
# resources are prefixed with "XXX" to make sure they are not active by accident | ||
# modify the rule as needed and remove the "XXX" prefix to activate | ||
- XXXdeployments | ||
- XXXstatefulsets | ||
# see http://jmespath.org/specification.html | ||
jmespath: "!(spec.template.metadata.labels.application)" | ||
ttl: 4d | ||
- id: temporary-pr-namespaces | ||
# delete all namespaces with a name starting with "pr-*" | ||
resources: | ||
# resources are prefixed with "XXX" to make sure they are not active by accident | ||
# modify the rule as needed and remove the "XXX" prefix to activate | ||
- XXXnamespaces | ||
# this uses JMESPath's built-in "starts_with" function | ||
# see http://jmespath.org/specification.html#starts-with | ||
jmespath: "starts_with(metadata.name, 'pr-')" | ||
ttl: 4h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import collections | ||
import jmespath | ||
import logging | ||
import re | ||
import yaml | ||
|
||
from pykube.objects import NamespacedAPIObject | ||
|
||
from .helper import parse_ttl | ||
|
||
RULE_ID_PATTERN = re.compile(r'^[a-z][a-z0-9-]*$') | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Rule(collections.namedtuple('Rule', ['id', 'resources', 'jmespath', 'ttl'])): | ||
|
||
def from_entry(entry: dict): | ||
id_ = entry['id'] | ||
if not RULE_ID_PATTERN.match(id_): | ||
raise ValueError(f'Invalid rule ID "{id_}": it has to match ^[a-z][a-z0-9-]*$') | ||
|
||
# check whether TTL format is correct | ||
parse_ttl(entry['ttl']) | ||
return Rule( | ||
id=id_, | ||
resources=frozenset(entry['resources']), | ||
jmespath=jmespath.compile(entry['jmespath']), | ||
ttl=entry['ttl']) | ||
|
||
def matches(self, resource: NamespacedAPIObject): | ||
if resource.endpoint not in self.resources and '*' not in self.resources: | ||
return False | ||
|
||
result = self.jmespath.search(resource.obj) | ||
logger.debug(f'Rule {self.id} with JMESPath "{self.jmespath.expression}" evaluated for {resource.kind} {resource.namespace}/{resource.name}: {result}') | ||
return bool(result) | ||
|
||
|
||
def load_rules_from_file(filename: str): | ||
with open(filename) as fd: | ||
data = yaml.safe_load(fd) | ||
|
||
try: | ||
entries = data['rules'] | ||
except (TypeError, KeyError): | ||
raise KeyError('The rules YAML file must have a top-level mapping with the key "rules"') | ||
|
||
rules = [] | ||
|
||
for i, entry in enumerate(entries): | ||
try: | ||
if not isinstance(entry, dict): | ||
raise TypeError('rule must be a mapping') | ||
|
||
missing_keys = frozenset(Rule._fields) - entry.keys() | ||
if missing_keys: | ||
raise ValueError(f'rule is missing required keys: {missing_keys}') | ||
|
||
rule = Rule.from_entry(entry) | ||
rules.append(rule) | ||
except Exception as e: | ||
raise TypeError(f'Failed to load rule #{i} from file "{filename}": {e}') | ||
|
||
return rules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from kube_janitor.cmd import get_parser | ||
|
||
|
||
def test_parse_args(): | ||
parser = get_parser() | ||
parser.parse_args(['--dry-run', '--rules-file=/config/rules.yaml']) |
Oops, something went wrong.