3.3 KiB
Multi-fields Merge Key in Strategic Merge Patch
Abstract
Support multi-fields merge key in Strategic Merge Patch.
Background
Strategic Merge Patch is covered in this doc. In Strategic Merge Patch, we use Merge Key to identify the entries in the list of non-primitive types. It must always be present and unique to perform the merge on the list of non-primitive types, and will be preserved.
The merge key exists in the struct tag (e.g. in types.go) and the OpenAPI spec.
Motivation
The current implementation only support a single field as merge key. For some element Kinds, the identity is actually defined using multiple fields. Service port is an evidence indicating that we need to support multi-fields Merge Key.
Scope
This proposal only covers how we introduce ability to support multi-fields merge key for strategic merge patch. It will cover how we support new APIs with multi-fields merge key.
This proposal does NOT cover how we change the merge keys from one single field to multi-fields for existing APIs without breaking backward compatibility, e.g. we are not addressing the service port issue mentioned above. That part will be addressed by #476.
Proposed Change
API Change
If a merge key has multiple fields, it will be a string of merge key fields separated by ",", i.e. patchMergeKey:"<key1>,<key2>,<key3>"
.
If a merge key only has one field, it will be the same as before, i.e. patchMergeKey:"<key1>"
.
There are no patch format changes. Patches for fields that have multiple fields in the merge key must include all of the fields of the merge key in the patch.
If a new API uses multi-fields merge key, all the fields of the merge key are required to present. Otherwise, the server will reject the patch.
E.g. foo and bar are the merge keys.
Live list:
list:
- foo: a
bar: x
other: 1
- foo: a
bar: y
other: 2
- foo: b
bar: x
other: 3
Patch 1:
list:
- foo: a # field 1 of merge key
bar: x # field 2 of merge key
other: 4
another: val
Result after merging patch 1:
list:
- foo: a
bar: x
other: 4
another: val
- foo: a
bar: y
other: 2
- foo: b
bar: x
other: 3
Patch 2:
list:
- $patch: delete
foo: a # field 1 of merge key
bar: x # field 2 of merge key
Result after merging patch 2:
list:
- foo: a
bar: y
other: 2
- foo: b
bar: x
other: 3
Strategic Merge Patch pkg
We will add logic to support
- returning a list of fields instead of one single field when looking up merge key.
- merging list respecting a list of fields as merge key.
Open API
Open API will not be affected, since multi-fields merge key is still in one single string as an extension in Open API spec.
Docs
Document that the developer should make sure the merge key can uniquely identify an entry in all cases.
Version Skew and Backward Compatibility
It is fully backward compatibility, because there are no patch format changes and no changes to the existing APIs.