Skip to content
This repository has been archived by the owner on Sep 14, 2020. It is now read-only.

Watch for changes in array items. #373

Open
2 tasks done
MarkusH opened this issue Jun 11, 2020 · 0 comments
Open
2 tasks done

Watch for changes in array items. #373

MarkusH opened this issue Jun 11, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@MarkusH
Copy link

MarkusH commented Jun 11, 2020

Thank you for the great library. It's a pleasure to work with.

Problem

I have a custom resource with an array of objects somewhere in the spec. Say, like this:

spec:
  a:
    b:
    - foo: lorem
      nested:
        bar: ipsum
    - foo: dolor
      nested:
        bar: sit

I would like to be able to use @kopf.on.update to watch on individual changes of fields within array items and have these changes automatically in the diff argument of the handler.

The case at hand: I use kopf to build an operator that will create multiple StatefulSets where some specs for the StatefulSets are defined in the custom resource, such as the number of replicas:

spec:
  types:
  - name: type-a
    replicas: 2
  - name: type-b
    replicas: 4

The feature would allow me to neatly detect when the replicas for type-a are changed to e.g. 3.

Proposal

I see a few different implementation options. I'll demonstrate them here:

@kopf.on.update(...)
async def replicas_change(diff, **_):
    print(diff)
    # [("change", ("spec", "types", "0", "replicas"), 2, 3)]

Alternatively, one could want to watch for changes to the n-th array item in @kopf.on.field:

@kopf.on.field(..., field="spec.types.0.replicas")
async def type_b_change(diff, **_):
    print(diff)
    # [("change", (), 2, 3)]

Or watch for each array element and get its index.

@kopf.on.field(..., field="spec.types[]")
async def type_b_change(diff, **_):
    print(diff)
    # [("change", ("0"), {"name": "type-a", "replicas": 2}, {"name": "type-a", "replicas": 3})]

An interesting question in the last context would be how adding / removing items is going to be handled. E.g., what would the diff look like if one were to add a type-c as first item in the array and remove the type-b:

    [
        ("add", ("0"), None, {"name": "type-c", "replicas": 5}),
        ("remove", ("1"), {"name": "type-b", "replicas": 4}, None),
    ]
    # or
    [
        ("add", ("0"), None, {"name": "type-c", "replicas": 5}),
        ("remove", ("2"), {"name": "type-b", "replicas": 4}, None),
    ]
    # or
    [
        ("change", ("0"), {"name": "type-a", "replicas": 2}, {"name": "type-c", "replicas": 5}),
        ("change", ("2"), {"name": "type-b", "replicas": 4}, {"name": "type-a", "replicas": 2}),
    ]
    # or ...?

Checklist

  • Many users can benefit from this feature, it is not a one-time case
  • The proposal is related to the K8s operator framework, not to the K8s client libraries
@MarkusH MarkusH added the enhancement New feature or request label Jun 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant