def test_rule_invalid_id(): with pytest.raises(ValueError): Rule.from_entry({ 'id': 'X', 'resources': [], 'jmespath': 'a.b', 'ttl': '1s' })
def test_rule_matches(): rule = Rule.from_entry({ 'id': 'test', 'resources': ['deployments'], 'jmespath': 'metadata.labels.app', 'ttl': '30m' }) resource = Deployment( None, {'metadata': { 'namespace': 'ns-1', 'name': 'deploy-1' }}) assert not rule.matches(resource) resource.obj['metadata']['labels'] = {'app': ''} assert not rule.matches(resource) resource.obj['metadata']['labels']['app'] = 'foobar' assert rule.matches(resource) resource = StatefulSet(None, {'metadata': { 'namespace': 'ns-1', 'name': 'ss-1' }}) assert not rule.matches(resource) resource = StatefulSet(None, { 'metadata': { 'namespace': 'ns-1', 'name': 'ss-1', 'labels': { 'app': 'x' } } }) assert not rule.matches(resource)
def test_rule_matches(): rule = Rule.from_entry( { "id": "test", "resources": ["deployments"], "jmespath": "metadata.labels.app", "ttl": "30m", } ) resource = Deployment(None, {"metadata": {"namespace": "ns-1", "name": "deploy-1"}}) assert not rule.matches(resource) resource.obj["metadata"]["labels"] = {"app": ""} assert not rule.matches(resource) resource.obj["metadata"]["labels"]["app"] = "foobar" assert rule.matches(resource) resource = StatefulSet(None, {"metadata": {"namespace": "ns-1", "name": "ss-1"}}) assert not rule.matches(resource) resource = StatefulSet( None, {"metadata": {"namespace": "ns-1", "name": "ss-1", "labels": {"app": "x"}}}, ) assert not rule.matches(resource)
def test_clean_up_by_rule(): api_mock = MagicMock(name='APIMock') rule = Rule.from_entry({ 'id': 'r1', 'resources': ['customfoos'], 'jmespath': "metadata.namespace == 'ns-1'", 'ttl': '10m' }) def get(**kwargs): if kwargs.get('url') == 'namespaces': data = {'items': [{'metadata': {'name': 'ns-1'}}]} elif kwargs.get('url') == 'customfoos': data = { 'items': [{ 'metadata': { 'name': 'foo-1', 'namespace': 'ns-1', 'creationTimestamp': '2019-01-17T15:14:38Z', } }] } elif kwargs['version'] == 'v1': data = {'resources': []} elif kwargs['version'] == 'srcco.de/v1': data = { 'resources': [{ 'kind': 'CustomFoo', 'name': 'customfoos', 'namespaced': True, 'verbs': ['delete'] }] } elif kwargs['version'] == '/apis': data = { 'groups': [{ 'preferredVersion': { 'groupVersion': 'srcco.de/v1' } }] } else: data = {} response = MagicMock() response.json.return_value = data return response api_mock.get = get counter = clean_up(api_mock, ALL, [], ALL, [], [rule], None, dry_run=False) # namespace ns-1 and object foo-1 assert counter['resources-processed'] == 2 assert counter['rule-r1-matches'] == 1 assert counter['customfoos-with-ttl'] == 1 assert counter['customfoos-deleted'] == 1 api_mock.post.assert_called_once() _, kwargs = api_mock.post.call_args assert kwargs['url'] == 'events' data = json.loads(kwargs['data']) assert data['reason'] == 'TimeToLiveExpired' assert 'rule r1 matches' in data['message'] involvedObject = { 'kind': 'CustomFoo', 'name': 'foo-1', 'namespace': 'ns-1', 'apiVersion': 'srcco.de/v1', 'resourceVersion': None, 'uid': None } assert data['involvedObject'] == involvedObject # verify that the delete call happened api_mock.delete.assert_called_once_with( data='{"propagationPolicy": "Foreground"}', namespace='ns-1', url='customfoos/foo-1', version='srcco.de/v1')
def test_clean_up_by_rule(): api_mock = MagicMock(name="APIMock") rule = Rule.from_entry( { "id": "r1", "resources": ["customfoos"], "jmespath": "metadata.namespace == 'ns-1'", "ttl": "10m", } ) def get(**kwargs): if kwargs.get("url") == "namespaces": data = {"items": [{"metadata": {"name": "ns-1"}}]} elif kwargs.get("url") == "customfoos": data = { "items": [ { "metadata": { "name": "foo-1", "namespace": "ns-1", "creationTimestamp": "2019-01-17T15:14:38Z", } } ] } elif kwargs["version"] == "v1": data = {"resources": []} elif kwargs["version"] == "srcco.de/v1": data = { "resources": [ { "kind": "CustomFoo", "name": "customfoos", "namespaced": True, "verbs": ["delete"], } ] } elif kwargs["version"] == "/apis": data = {"groups": [{"preferredVersion": {"groupVersion": "srcco.de/v1"}}]} else: data = {} response = MagicMock() response.json.return_value = data return response api_mock.get = get counter = clean_up( api_mock, ALL, [], ALL, [], [rule], 0, deployment_time_annotation=None, dry_run=False, ) # namespace ns-1 and object foo-1 assert counter["resources-processed"] == 2 assert counter["rule-r1-matches"] == 1 assert counter["customfoos-with-ttl"] == 1 assert counter["customfoos-deleted"] == 1 api_mock.post.assert_called_once() _, kwargs = api_mock.post.call_args assert kwargs["url"] == "events" data = json.loads(kwargs["data"]) assert data["reason"] == "TimeToLiveExpired" assert "rule r1 matches" in data["message"] involvedObject = { "kind": "CustomFoo", "name": "foo-1", "namespace": "ns-1", "apiVersion": "srcco.de/v1", "resourceVersion": None, "uid": None, } assert data["involvedObject"] == involvedObject # verify that the delete call happened api_mock.delete.assert_called_once_with( data='{"propagationPolicy": "Background"}', namespace="ns-1", url="/customfoos/foo-1", version="srcco.de/v1", )
def test_rule_invalid_id(): with pytest.raises(ValueError): Rule.from_entry({"id": "X", "resources": [], "jmespath": "a.b", "ttl": "1s"})