Skip to content

Commit f5d4a0f

Browse files
authored
Replace partition labels with ranges, validate lenght (#44)
Label values are limited to 63 characters in K8s. Replace the list of all partitions in the label with the range e.g. `partitions="0-1-2-3-4-5-6-7-8-10-12"` => `partitions="0-12"` Make sure that when we create new Deployments/Pods we conform to the limits.
1 parent a996568 commit f5d4a0f

3 files changed

Lines changed: 88 additions & 3 deletions

File tree

controllers/operator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,9 @@ func (o *operator) updateDeploy(deploy *appsv1.Deployment) (*appsv1.Deployment,
499499
func (o *operator) constructDeploy(consumerId int32) *appsv1.Deployment {
500500
partitionIds := o.assignments[consumerId]
501501
deployLabels := map[string]string{
502-
"app": o.consumer.Spec.Name,
503-
"controller": o.consumer.Name,
504-
"partitions": strings.Join(helpers.Int2Str(partitionIds), "-"),
502+
"app": helpers.EnsureValidLabelValue(o.consumer.Spec.Name),
503+
"controller": helpers.EnsureValidLabelValue(o.consumer.Name),
504+
"partitions": helpers.EnsureValidLabelValue(helpers.ConsecutiveIntsToRange(partitionIds)),
505505
}
506506
deployAnnotations := make(map[string]string)
507507
deploy := &appsv1.Deployment{

pkg/helpers/util.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
corev1 "k8s.io/api/core/v1"
1111
"k8s.io/apimachinery/pkg/api/resource"
12+
"k8s.io/apimachinery/pkg/util/validation"
1213
)
1314

1415
const (
@@ -186,3 +187,36 @@ func Int2Str(ints []int32) []string {
186187
}
187188
return result
188189
}
190+
191+
// ConsecutiveIntsToRange takes a list of sorted integers and returns
192+
// string representation of its range
193+
// ConsecutiveIntsToRange(0,1,2,3,4,5,6) -> 0-6
194+
// ConsecutiveIntsToRange(12,13,14,15,16) -> 12-16
195+
func ConsecutiveIntsToRange(ints []int32) string {
196+
res := make([]int32, 2)
197+
if len(ints) < 3 {
198+
res = ints
199+
} else {
200+
res = []int32{ints[0], ints[len(ints)-1]}
201+
}
202+
return strings.Join(Int2Str(res), "-")
203+
}
204+
205+
func EnsureValidLabelValue(s string) string {
206+
/*
207+
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
208+
Valid label value:
209+
* must be 63 characters or less (cannot be empty),
210+
* must begin and end with an alphanumeric character ([a-z0-9A-Z]),
211+
* could contain dashes (-), underscores (_), dots (.), and alphanumerics between.
212+
213+
For now we only ensure the max length here
214+
TODO: decide what to do with labels containing incompatible chars. At the moment having bad name will break in
215+
many places, not only in labels.
216+
217+
*/
218+
if len(s) > validation.LabelValueMaxLength {
219+
return s[:validation.LabelValueMaxLength]
220+
}
221+
return s
222+
}

pkg/helpers/util_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,54 @@ func TestParsePartitionsListAnnotation(t *testing.T) {
303303
})
304304
}
305305
}
306+
307+
func TestConsecutiveIntsToRange(t *testing.T) {
308+
testCases := map[string]struct {
309+
in []int32
310+
exp string
311+
}{
312+
"single digits not a range": {
313+
[]int32{0},
314+
"0",
315+
},
316+
"double digit is a range": {
317+
[]int32{0, 1},
318+
"0-1",
319+
},
320+
"many digits making range": {
321+
[]int32{0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12},
322+
"0-12",
323+
},
324+
"vary many digits still make range": {
325+
[]int32{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
326+
"2-29",
327+
},
328+
}
329+
for testName, tc := range testCases {
330+
if res := ConsecutiveIntsToRange(tc.in); res != tc.exp {
331+
t.Fatalf("%s: expected to get `%s`, got `%s`", testName, tc.exp, res)
332+
}
333+
}
334+
335+
}
336+
337+
func TestEnsureValidLabelValue(t *testing.T) {
338+
testCases := map[string]struct {
339+
in string
340+
exp string
341+
}{
342+
"short label value is OK": {
343+
"0-1-2-3-4-5-6-7-8-10-12",
344+
"0-1-2-3-4-5-6-7-8-10-12",
345+
},
346+
"long name should be cut up to the limit": {
347+
"0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29",
348+
"0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-2",
349+
},
350+
}
351+
for testName, tc := range testCases {
352+
if res := EnsureValidLabelValue(tc.in); res != tc.exp {
353+
t.Fatalf("%s: expected to get `%s`, got `%s`", testName, tc.exp, res)
354+
}
355+
}
356+
}

0 commit comments

Comments
 (0)