예제 #1
0
def test_patch_namespaced(client: lightkube.Client):
    # Default PatchType.STRATEGIC
    req = respx.patch("https://localhost:9443/api/v1/namespaces/default/pods/xx").respond(json={'metadata': {'name': 'xx'}})
    pod = client.patch(Pod, "xx", Pod(metadata=ObjectMeta(labels={'l': 'ok'})))
    assert pod.metadata.name == 'xx'
    assert req.calls[0][0].headers['Content-Type'] == "application/strategic-merge-patch+json"

    # PatchType.MERGE
    req = respx.patch("https://localhost:9443/api/v1/namespaces/other/pods/xx").respond(json={'metadata': {'name': 'xx'}})
    pod = client.patch(Pod, "xx", Pod(metadata=ObjectMeta(labels={'l': 'ok'})), namespace='other',
                       patch_type=types.PatchType.MERGE, force=True)
    assert pod.metadata.name == 'xx'
    assert req.calls[0][0].headers['Content-Type'] == "application/merge-patch+json"
    assert 'force' not in str(req.calls[0][0].url)  # force is ignored for non APPLY patch types

    # PatchType.APPLY
    req = respx.patch("https://localhost:9443/api/v1/namespaces/other/pods/xy?fieldManager=test").respond(
        json={'metadata': {'name': 'xy'}})
    pod = client.patch(Pod, "xy", Pod(metadata=ObjectMeta(labels={'l': 'ok'})), namespace='other',
                       patch_type=types.PatchType.APPLY, field_manager='test')
    assert pod.metadata.name == 'xy'
    assert req.calls[0][0].headers['Content-Type'] == "application/apply-patch+yaml"

    # PatchType.APPLY + force
    req = respx.patch("https://localhost:9443/api/v1/namespaces/other/pods/xz?fieldManager=test&force=true").respond(
        json={'metadata': {'name': 'xz'}})
    pod = client.patch(Pod, "xz", Pod(metadata=ObjectMeta(labels={'l': 'ok'})), namespace='other',
                       patch_type=types.PatchType.APPLY, field_manager='test', force=True)
    assert pod.metadata.name == 'xz'
    assert req.calls[0][0].headers['Content-Type'] == "application/apply-patch+yaml"

    # PatchType.APPLY without field_manager
    with pytest.raises(ValueError, match="field_manager"):
        client.patch(Pod, "xz", Pod(metadata=ObjectMeta(labels={'l': 'ok'})), namespace='other',
                     patch_type=types.PatchType.APPLY)
예제 #2
0
def test_replace_namespaced(client: lightkube.Client):
    req = respx.put("https://localhost:9443/api/v1/namespaces/default/pods/xy").respond(json={'metadata': {'name': 'xy'}})
    pod = client.replace(Pod(metadata=ObjectMeta(name="xy")))
    assert req.calls[0][0].read() == b'{"metadata": {"name": "xy"}}'
    assert pod.metadata.name == 'xy'

    respx.put("https://localhost:9443/api/v1/namespaces/other/pods/xz").respond(json={'metadata': {'name': 'xz'}})
    pod = client.replace(Pod(metadata=ObjectMeta(name="xz")), namespace='other')
    assert pod.metadata.name == 'xz'

    # namespace inside object definition need to match with provided namespace parameter.
    with pytest.raises(ValueError):
        client.replace(Pod(metadata=ObjectMeta(name="xx", namespace='ns1')), namespace='ns2')
def generate_pod_resource_list(pod_names):
    resources = [
        Pod(kind="Pod", metadata=ObjectMeta(name=str(name)))
        for name in pod_names
    ]

    return resources
예제 #4
0
async def test_patch_global(client: lightkube.AsyncClient):
    req = respx.patch("https://localhost:9443/api/v1/nodes/xx").respond(
        json={'metadata': {
            'name': 'xx'
        }})
    pod = await client.patch(Node,
                             "xx", [{
                                 "op": "add",
                                 "path": "/metadata/labels/x",
                                 "value": "y"
                             }],
                             patch_type=types.PatchType.JSON)
    assert pod.metadata.name == 'xx'
    assert req.calls[0][0].headers[
        'Content-Type'] == "application/json-patch+json"

    # PatchType.APPLY + force
    req = respx.patch(
        "https://localhost:9443/api/v1/nodes/xy?fieldManager=test&force=true"
    ).respond(json={'metadata': {
        'name': 'xy'
    }})
    node = await client.patch(Node,
                              "xy",
                              Pod(metadata=ObjectMeta(labels={'l': 'ok'})),
                              patch_type=types.PatchType.APPLY,
                              field_manager='test',
                              force=True)
    assert node.metadata.name == 'xy'
    assert req.calls[0][0].headers[
        'Content-Type'] == "application/apply-patch+yaml"

    await client.close()
예제 #5
0
def test_field_manager(kubeconfig):
    config = KubeConfig.from_file(str(kubeconfig))
    client = lightkube.Client(config=config, field_manager='lightkube')
    respx.patch("https://localhost:9443/api/v1/nodes/xx?fieldManager=lightkube").respond(json={'metadata': {'name': 'xx'}})
    client.patch(Node, "xx", [{"op": "add", "path": "/metadata/labels/x", "value": "y"}],
                       patch_type=types.PatchType.JSON)

    respx.post("https://localhost:9443/api/v1/namespaces/default/pods?fieldManager=lightkube").respond(json={'metadata': {'name': 'xx'}})
    client.create(Pod(metadata=ObjectMeta(name="xx", labels={'l': 'ok'})))

    respx.put("https://localhost:9443/api/v1/namespaces/default/pods/xy?fieldManager=lightkube").respond(
        json={'metadata': {'name': 'xy'}})
    client.replace(Pod(metadata=ObjectMeta(name="xy")))

    respx.put("https://localhost:9443/api/v1/namespaces/default/pods/xy?fieldManager=override").respond(
        json={'metadata': {'name': 'xy'}})
    client.replace(Pod(metadata=ObjectMeta(name="xy")), field_manager='override')
예제 #6
0
def test_create_namespaced(client: lightkube.Client):
    req = respx.post("https://localhost:9443/api/v1/namespaces/default/pods").respond(json={'metadata': {'name': 'xx'}})
    pod = client.create(Pod(metadata=ObjectMeta(name="xx", labels={'l': 'ok'})))
    assert req.calls[0][0].read() == b'{"metadata": {"labels": {"l": "ok"}, "name": "xx"}}'
    assert pod.metadata.name == 'xx'

    req2 = respx.post("https://localhost:9443/api/v1/namespaces/other/pods").respond(json={'metadata': {'name': 'yy'}})
    pod = client.create(Pod(metadata=ObjectMeta(name="xx", labels={'l': 'ok'})), namespace='other')
    assert pod.metadata.name == 'yy'
    assert req2.calls[0][0].read() == b'{"metadata": {"labels": {"l": "ok"}, "name": "xx"}}'

    respx.post("https://localhost:9443/api/v1/namespaces/ns2/pods").respond(
        json={'metadata': {'name': 'yy'}})
    pod = client.create(Pod(metadata=ObjectMeta(name="xx", labels={'l': 'ok'}, namespace='ns2')))
    assert pod.metadata.name == 'yy'

    # namespace inside object definition need to match with provided namespace parameter.
    with pytest.raises(ValueError):
        client.create(Pod(metadata=ObjectMeta(name="xx", namespace='ns1')), namespace='ns2')
예제 #7
0
def test_apply_namespaced(client: lightkube.Client):
    req = respx.patch("https://localhost:9443/api/v1/namespaces/default/pods/xy?fieldManager=test").respond(
        json={'metadata': {'name': 'xy'}})
    pod = client.apply(Pod(metadata=ObjectMeta(name='xy')), field_manager='test')
    assert pod.metadata.name == 'xy'
    assert req.calls[0][0].headers['Content-Type'] == "application/apply-patch+yaml"

    # custom namespace, force
    req = respx.patch("https://localhost:9443/api/v1/namespaces/other/pods/xz?fieldManager=a&force=true").respond(
        json={'metadata': {'name': 'xz'}})
    pod = client.apply(Pod(metadata=ObjectMeta(name='xz', namespace='other')), field_manager='a', force=True)
    assert pod.metadata.name == 'xz'
    assert req.calls[0][0].headers['Content-Type'] == "application/apply-patch+yaml"

    # sub-resource
    req = respx.patch("https://localhost:9443/api/v1/namespaces/default/pods/xx/status?fieldManager=a").respond(
        json={'metadata': {'name': 'xx'}})
    pod = client.apply(Pod.Status(), name='xx', field_manager='a')
    assert pod.metadata.name == 'xx'
    assert req.calls[0][0].headers['Content-Type'] == "application/apply-patch+yaml"
예제 #8
0
def create_pod(name, command) -> Pod:
    return Pod(
        metadata=ObjectMeta(name=name, labels={'app-name': name}),
        spec=PodSpec(containers=[Container(
            name='main',
            image='busybox',
            args=[
                "/bin/sh",
                "-c",
                command
            ],
        )], terminationGracePeriodSeconds=1)
    )
        delete_calls = tuple()
    names_deleted = tuple(c.args[0].metadata.name for c in delete_calls)
    assert sorted(names_deleted) == sorted(expected_resources_deleted_names)

    # Assert apply called if it should have been called
    assert rh.apply_manifest.call_count == 1
    resources_applied = mocked_load_all_yaml.return_value
    if resources_applied is None:
        resources_applied = tuple()
    names_applied = tuple(r.metadata.name for r in resources_applied)
    assert sorted(names_applied) == sorted(desired_resource_names)


# Resources for below tests
POD_LIST_1 = [
    Pod(kind="Pod",
        metadata=ObjectMeta(name=f"pod-{n}", namespace="some-namespace"))
    for n in range(5)
]
POD_TUPLES_1 = [("Pod", f"pod-{n}") for n in range(0, 5)]
POD_LIST_2 = [
    Pod(kind="Pod",
        metadata=ObjectMeta(name=f"pod-{n}", namespace="some-namespace"))
    for n in range(3, 7)
]
POD_TUPLES_IN_1_NOT_2 = [("Pod", f"pod-{n}") for n in range(0, 3)]


@pytest.mark.parametrize(
    "left,right,expected_result",
    [
        (POD_LIST_1, POD_LIST_1, []),