Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace zalando.org → kopf.dev for peering #644

Merged
merged 2 commits into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/continuity.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ All information is retrieved and stored via Kubernetes API.
Specifically:

* The cross-operator exchange is performed via peering objects of type
``KopfPeering`` or ``ClusterKopfPeering`` (API version: ``zalando.org/v1``).
``KopfPeering`` or ``ClusterKopfPeering``
(API versions: either ``kopf.dev/v1`` or ``zalando.org/v1``).
See :doc:`peering` for more info.
* The last handled state of the object is stored in ``metadata.annotations``
(the ``kopf.zalando.org/last-handled-configuration`` annotation).
Expand Down
4 changes: 2 additions & 2 deletions docs/deployment-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ metadata:
rules:

# Framework: knowing which other operators are running (i.e. peering).
- apiGroups: [zalando.org]
- apiGroups: [kopf.dev]
resources: [clusterkopfpeerings]
verbs: [list, watch, patch, get]

Expand All @@ -37,7 +37,7 @@ metadata:
rules:

# Framework: knowing which other operators are running (i.e. peering).
- apiGroups: [zalando.org]
- apiGroups: [kopf.dev]
resources: [kopfpeerings]
verbs: [list, watch, patch, get]

Expand Down
18 changes: 14 additions & 4 deletions docs/peering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ Create the peering objects as needed with one of:

.. code-block:: yaml

apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: ClusterKopfPeering
metadata:
name: example

.. code-block:: yaml

apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: KopfPeering
metadata:
namespace: default
Expand All @@ -69,11 +69,21 @@ Create the peering objects as needed with one of:
.. note::

In ``kopf<0.11`` (until May'2019), ``KopfPeering`` was the only CRD,
and it was cluster-scoped. In ``kopf>=0.11,<0.29`` (until Oct'2020),
and it was cluster-scoped. In ``kopf>=0.11,<1.29`` (until Dec'2020),
this mode was deprecated but supported if the old CRD existed.
Since ``kopf>=0.29`` (Nov'2020), it is not supported anymore.
Since ``kopf>=1.29`` (Jan'2021), it is not supported anymore.
To upgrade, delete and re-create the peering CRDs to the new ones.

.. note::

In ``kopf<1.29``, all peering CRDs used the API group ``kopf.zalando.org``.
Since ``kopf>=1.29`` (Jan'2021), they belong to the API group ``kopf.dev``.

At runtime, both API groups are supported. However, these resources
of different API groups are mutually exclusive and cannot co-exist
in the same cluster since they use the same names. Whenever possible,
re-create them with the new API group after the operator/framework upgrade.


Custom peering
==============
Expand Down
6 changes: 4 additions & 2 deletions kopf/structs/references.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,14 @@ def select(self, resources: Collection[Resource]) -> Collection[Resource]:
# Some predefined API endpoints that we use in the framework itself (not exposed to the operators).
# Note: the CRDs are versionless: we do not look into its ``spec`` stanza, we only watch for
# the fact of changes, so the schema does not matter, any cluster-preferred API version would work.
# Note: the peering resources are either zalando.org/v1 or kopf.dev/v1; both cannot co-exist because
# they would share the names, so K8s will not let this. It is done for domain name transitioning.
CRDS = Selector('apiextensions.k8s.io', 'customresourcedefinitions')
EVENTS = Selector('v1', 'events')
EVENTS_K8S = Selector('events.k8s.io', 'events') # only for exclusion from EVERYTHING
NAMESPACES = Selector('v1', 'namespaces')
CLUSTER_PEERINGS = Selector('zalando.org/v1', 'clusterkopfpeerings')
NAMESPACED_PEERINGS = Selector('zalando.org/v1', 'kopfpeerings')
CLUSTER_PEERINGS = Selector('clusterkopfpeerings')
NAMESPACED_PEERINGS = Selector('kopfpeerings')


class Backbone(Mapping[Selector, Resource]):
Expand Down
12 changes: 6 additions & 6 deletions peering-v1beta1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: clusterkopfpeerings.zalando.org
name: clusterkopfpeerings.kopf.dev
spec:
scope: Cluster
group: zalando.org
group: kopf.dev
names:
kind: ClusterKopfPeering
plural: clusterkopfpeerings
Expand All @@ -20,10 +20,10 @@ spec:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: kopfpeerings.zalando.org
name: kopfpeerings.kopf.dev
spec:
scope: Namespaced
group: zalando.org
group: kopf.dev
names:
kind: KopfPeering
plural: kopfpeerings
Expand All @@ -33,12 +33,12 @@ spec:
served: true
storage: true
---
apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: ClusterKopfPeering
metadata:
name: default
---
apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: KopfPeering
metadata:
namespace: default
Expand Down
12 changes: 6 additions & 6 deletions peering.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: clusterkopfpeerings.zalando.org
name: clusterkopfpeerings.kopf.dev
spec:
scope: Cluster
group: zalando.org
group: kopf.dev
names:
kind: ClusterKopfPeering
plural: clusterkopfpeerings
Expand All @@ -27,10 +27,10 @@ spec:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: kopfpeerings.zalando.org
name: kopfpeerings.kopf.dev
spec:
scope: Namespaced
group: zalando.org
group: kopf.dev
names:
kind: KopfPeering
plural: kopfpeerings
Expand All @@ -47,12 +47,12 @@ spec:
type: object
x-kubernetes-preserve-unknown-fields: true
---
apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: ClusterKopfPeering
metadata:
name: default
---
apiVersion: zalando.org/v1
apiVersion: kopf.dev/v1
kind: KopfPeering
metadata:
namespace: default
Expand Down
31 changes: 31 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,32 @@ def enforce_asyncio_mocker(pytestconfig):
assert fixture.mock_module is asynctest, "Mock replacement failed!"


@pytest.fixture(params=[
('kopf.dev', 'v1', 'clusterkopfpeerings'),
('zalando.org', 'v1', 'clusterkopfpeerings'),
], ids=['kopf-dev-namespaced', 'zalando-org-namespaced'])
def namespaced_peering_resource(request):
return Resource(*request.param[:3], namespaced=True)


@pytest.fixture(params=[
('kopf.dev', 'v1', 'kopfpeerings'),
('zalando.org', 'v1', 'kopfpeerings'),
], ids=['kopf-dev-cluster', 'zalando-org-cluster'])
def cluster_peering_resource(request):
return Resource(*request.param[:3], namespaced=False)


@pytest.fixture(params=[
('kopf.dev', 'v1', 'clusterkopfpeerings', False),
('zalando.org', 'v1', 'clusterkopfpeerings', False),
('kopf.dev', 'v1', 'kopfpeerings', True),
('zalando.org', 'v1', 'kopfpeerings', True),
], ids=['kopf-dev-cluster', 'zalando-org-cluster', 'kopf-dev-namespaced', 'zalando-org-namespaced'])
def peering_resource(request):
return Resource(*request.param[:3], namespaced=request.param[3])


@pytest.fixture()
def namespaced_resource():
""" The resource used in the tests. Usually mocked, so it does not matter. """
Expand All @@ -115,6 +141,11 @@ def selector(resource):
return Selector(group=resource.group, version=resource.version, plural=resource.plural)


@pytest.fixture()
def peering_namespace(peering_resource):
return 'ns' if peering_resource.namespaced else None


@pytest.fixture()
def namespace(resource):
return 'ns' if resource.namespaced else None
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ def no_crd():

@pytest.fixture()
def no_peering():
subprocess.run("kubectl delete customresourcedefinition kopfpeerings.zalando.org",
subprocess.run("kubectl delete customresourcedefinition kopfpeerings.kopf.dev",
shell=True, check=True, timeout=10, capture_output=True)
14 changes: 4 additions & 10 deletions tests/orchestration/test_task_adjustments.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ async def processor(*, raw_event: bodies.RawEvent, replenished: asyncio.Event) -
pass



@dataclasses.dataclass(frozen=True, eq=False)
class K8sMocks:
patch_obj: Mock
Expand All @@ -29,15 +28,6 @@ def k8s_mocked(mocker, resp_mocker):
)


@pytest.fixture(params=[
(False, 'clusterkopfpeerings'),
(True, 'kopfpeerings'),
], ids=['cluster-peering', 'namespaced-peering'])
def peering_resource(request, settings):
settings.peering.namespaced = request.param[0]
return Resource('zalando.org', 'v1', request.param[1], namespaced=request.param[0])


@pytest.fixture()
async def insights(settings, peering_resource):
insights = Insights()
Expand Down Expand Up @@ -77,6 +67,7 @@ async def test_empty_insights_cause_no_adjustments(

async def test_new_resources_and_namespaces_spawn_new_tasks(
settings, ensemble: Ensemble, insights: Insights, peering_resource):
settings.peering.namespaced = peering_resource.namespaced

r1 = Resource(group='group1', version='version1', plural='plural1', namespaced=True)
r2 = Resource(group='group2', version='version2', plural='plural2', namespaced=True)
Expand Down Expand Up @@ -107,6 +98,7 @@ async def test_new_resources_and_namespaces_spawn_new_tasks(

async def test_gone_resources_and_namespaces_stop_running_tasks(
settings, ensemble: Ensemble, insights: Insights, peering_resource):
settings.peering.namespaced = peering_resource.namespaced

r1 = Resource(group='group1', version='version1', plural='plural1', namespaced=True)
r2 = Resource(group='group2', version='version2', plural='plural2', namespaced=True)
Expand Down Expand Up @@ -154,6 +146,7 @@ async def test_gone_resources_and_namespaces_stop_running_tasks(

async def test_cluster_tasks_continue_running_on_namespace_deletion(
settings, ensemble: Ensemble, insights: Insights, peering_resource):
settings.peering.namespaced = peering_resource.namespaced

r1 = Resource(group='group1', version='version1', plural='plural1', namespaced=True)
r2 = Resource(group='group2', version='version2', plural='plural2', namespaced=True)
Expand Down Expand Up @@ -242,6 +235,7 @@ async def test_frozen_with_mandatory_peering_but_absent_peering_resource(

async def test_unfrozen_with_mandatory_peering_and_existing_peering_resource(
settings, ensemble: Ensemble, insights: Insights, peering_resource):
settings.peering.namespaced = peering_resource.namespaced

await ensemble.freeze_blocker.turn_to(True) # prerequisite
assert ensemble.freeze_blocker.is_on() # prerequisite
Expand Down
50 changes: 0 additions & 50 deletions tests/peering/conftest.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,6 @@
import pytest

from kopf.structs.references import Resource

NAMESPACED_PEERING_RESOURCE = Resource('zalando.org', 'v1', 'kopfpeerings', namespaced=True)
CLUSTER_PEERING_RESOURCE = Resource('zalando.org', 'v1', 'clusterkopfpeerings', namespaced=False)


@pytest.fixture(autouse=True)
def _autouse_fake_vault(fake_vault):
pass


@pytest.fixture()
def with_cluster_crd(hostname, aresponses):
result = {'resources': [{
'group': CLUSTER_PEERING_RESOURCE.group,
'version': CLUSTER_PEERING_RESOURCE.version,
'name': CLUSTER_PEERING_RESOURCE.plural,
'namespaced': False,
}]}
url = CLUSTER_PEERING_RESOURCE.get_version_url()
aresponses.add(hostname, url, 'get', result)


@pytest.fixture()
def with_namespaced_crd(hostname, aresponses):
result = {'resources': [{
'group': NAMESPACED_PEERING_RESOURCE.group,
'version': NAMESPACED_PEERING_RESOURCE.version,
'name': NAMESPACED_PEERING_RESOURCE.plural,
'namespaced': True,
}]}
url = NAMESPACED_PEERING_RESOURCE.get_version_url()
aresponses.add(hostname, url, 'get', result)


@pytest.fixture()
def with_both_crds(hostname, aresponses):
result = {'resources': [{
'group': CLUSTER_PEERING_RESOURCE.group,
'version': CLUSTER_PEERING_RESOURCE.version,
'name': CLUSTER_PEERING_RESOURCE.plural,
'namespaced': False,
}, {
'group': NAMESPACED_PEERING_RESOURCE.group,
'version': NAMESPACED_PEERING_RESOURCE.version,
'name': NAMESPACED_PEERING_RESOURCE.plural,
'namespaced': True,
}]}
urls = {
CLUSTER_PEERING_RESOURCE.get_version_url(),
NAMESPACED_PEERING_RESOURCE.get_version_url(),
}
for url in urls:
aresponses.add(hostname, url, 'get', result)
Loading