Skip to content

Commit a8a2ae2

Browse files
author
ymqytw
committed
support multi-fields merge key
1 parent ea894bc commit a8a2ae2

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Multi-fields Merge Key in Strategic Merge Patch
2+
3+
## Abstract
4+
5+
Support multi-fields merge key in Strategic Merge Patch.
6+
7+
## Background
8+
9+
Strategic Merge Patch is covered in this [doc](https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md).
10+
In Strategic Merge Patch, we use Merge Key to identify the entries in the list of non-primitive types.
11+
It must always be present and unique to perform the merge on the list of non-primitive types,
12+
and will be preserved.
13+
14+
The merge key exists in the struct tag (e.g. in [types.go](https://github.com/kubernetes/kubernetes/blob/5a9759b0b41d5e9bbd90d5a8f3a4e0a6c0b23b47/pkg/api/v1/types.go#L2831))
15+
and the [OpenAPI spec](https://github.com/kubernetes/kubernetes/blob/master/api/openapi-spec/swagger.json).
16+
17+
## Motivation
18+
19+
The current implementation requires a single field that uniquely identifies each element in a list.
20+
For some element Kinds, the identity is defined using multiple fields.
21+
An [example](https://github.com/kubernetes/kubernetes/issues/39188) is the service.spec.ports,
22+
which is identified by both `protocol` and `port`.
23+
24+
As a result we need to support multi-fields Merge Key.
25+
26+
## Scope
27+
28+
This proposal only covers how we introduce ability to support multi-fields merge key for strategic merge patch.
29+
It will cover how we support new APIs with multi-fields merge key.
30+
31+
This proposal does NOT cover how we change the merge keys from one single field to multi-fields
32+
for existing APIs without breaking backward compatibility.
33+
That part will be addressed by [#476](https://github.com/kubernetes/community/pull/476).
34+
35+
## Proposed Change
36+
37+
### API Change
38+
39+
If a merge key has multiple fields, it will be a string of merge key fields seperated by ",", i.e. `patchMergeKey:"<key1>,<key2>,<key3>"`.
40+
41+
If a merge key only has one field, it will be the same as before, i.e. `patchMergeKey:"<key1>"`.
42+
43+
There are no patch format changes.
44+
Additional fields are just extra fields in the patch.
45+
46+
E.g.
47+
foo and bar are the merge keys.
48+
49+
Live list:
50+
```yaml
51+
list:
52+
- foo: a
53+
bar: x
54+
other: 1
55+
- foo: a
56+
bar: y
57+
other: 2
58+
- foo: b
59+
bar: x
60+
other: 3
61+
```
62+
63+
Patch 1:
64+
```yaml
65+
list:
66+
- foo: a # field 1 of merge key
67+
bar: x # field 2 of merge key
68+
other: 4
69+
another: val
70+
```
71+
72+
Result after merging patch 1:
73+
```yaml
74+
list:
75+
- foo: a
76+
bar: x
77+
other: 4
78+
another: val
79+
- foo: a
80+
bar: y
81+
other: 2
82+
- foo: b
83+
bar: x
84+
other: 3
85+
```
86+
87+
Patch 2:
88+
```yaml
89+
list:
90+
- $patch: delete
91+
foo: a # field 1 of merge key
92+
bar: x # field 2 of merge key
93+
```
94+
95+
Result after merging patch 2:
96+
```yaml
97+
list:
98+
- foo: a
99+
bar: y
100+
other: 2
101+
- foo: b
102+
bar: x
103+
other: 3
104+
```
105+
106+
### Strategic Merge Patch pkg
107+
108+
We will add logic to support
109+
- returning a list of fields instead of one single field when looking up merge key.
110+
- merging list respecting a list of fields as merge key.
111+
112+
### Open API
113+
114+
Open API will not be affected,
115+
since multi-fields merge key is still in one single string as an extension in Open API spec.
116+
117+
### Docs
118+
119+
Document that the developer should make sure the merge key can uniquely identify an entry in all cases.
120+
121+
## Version Skew and Backward Compatibility
122+
123+
It is fully backward compatibility,
124+
because there are no patch format changes and no changes to the existing APIs.

0 commit comments

Comments
 (0)