Beispiel #1
0
def test_rule_invalid_id():
    with pytest.raises(ValueError):
        Rule.from_entry({
            'id': 'X',
            'resources': [],
            'jmespath': 'a.b',
            'ttl': '1s'
        })
Beispiel #2
0
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)
Beispiel #3
0
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')
Beispiel #5
0
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",
    )
Beispiel #6
0
def test_rule_invalid_id():
    with pytest.raises(ValueError):
        Rule.from_entry({"id": "X", "resources": [], "jmespath": "a.b", "ttl": "1s"})