Skip to content

Commit 70df82f

Browse files
committed
cartridge roles: read roles from annotations, fallback to labels
1 parent 005ebd6 commit 70df82f

File tree

3 files changed

+191
-8
lines changed

3 files changed

+191
-8
lines changed

examples/kv/helm-chart/values.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,3 @@ RoleConfig:
3535
MemtxMemoryMB: 256
3636
RolesToAssign:
3737
- storage
38-
- vshard.storage

pkg/topology/builtin.go

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,42 @@ var getServerStatQuery = `query serverList {
152152
}
153153
}`
154154

155+
// GetRoles comment
156+
func GetRoles(pod *corev1.Pod) ([]string, error) {
157+
thisPodLabels := pod.GetLabels()
158+
thisPodAnnotations := pod.GetAnnotations()
159+
160+
rolesFromAnnotations, ok := thisPodAnnotations["tarantool.io/rolesToAssign"]
161+
if !ok {
162+
rolesFromLabels, ok := thisPodLabels["tarantool.io/rolesToAssign"]
163+
if !ok {
164+
return nil, errors.New("role undefined")
165+
}
166+
167+
roles := strings.Split(rolesFromLabels, ".")
168+
log.Info("roles", "roles", roles)
169+
170+
return roles, nil
171+
}
172+
173+
var singleRole string
174+
var roleArray []string
175+
176+
err := json.Unmarshal([]byte(rolesFromAnnotations), &singleRole)
177+
if err == nil {
178+
log.Info("roles", "roles", singleRole)
179+
return []string{singleRole}, nil
180+
}
181+
182+
err = json.Unmarshal([]byte(rolesFromAnnotations), &roleArray)
183+
if err == nil {
184+
log.Info("roles", "roles", roleArray)
185+
return roleArray, nil
186+
}
187+
188+
return nil, errors.New("failed to parse roles from annotations")
189+
}
190+
155191
// Join comment
156192
func (s *BuiltInTopologyService) Join(pod *corev1.Pod) error {
157193

@@ -171,10 +207,11 @@ func (s *BuiltInTopologyService) Join(pod *corev1.Pod) error {
171207
return errors.New("instance uuid empty")
172208
}
173209

174-
role, ok := thisPodLabels["tarantool.io/rolesToAssign"]
175-
if !ok {
176-
return errors.New("role undefined")
210+
roles, err := GetRoles(pod)
211+
if err != nil {
212+
return err
177213
}
214+
log.Info("roles", "roles", roles)
178215

179216
vshardGroup := "default"
180217
useVshardGroups, ok := thisPodLabels["tarantool.io/useVshardGroups"]
@@ -189,10 +226,6 @@ func (s *BuiltInTopologyService) Join(pod *corev1.Pod) error {
189226
}
190227
}
191228

192-
roles := strings.Split(role, ".")
193-
194-
log.Info("roles", "roles", roles)
195-
196229
client := graphql.NewClient(s.serviceHost, graphql.WithHTTPClient(&http.Client{Timeout: time.Duration(time.Second * 5)}))
197230
req := graphql.NewRequest(joinMutation)
198231

pkg/topology/builtin_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package topology
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
func Contains(a []string, x string) bool {
12+
for _, n := range a {
13+
if x == n {
14+
return true
15+
}
16+
}
17+
return false
18+
}
19+
20+
type errorTestCase struct {
21+
pod *corev1.Pod
22+
expectedErr string
23+
}
24+
25+
func TestGetRoles_ErrorCases(t *testing.T) {
26+
cases := []errorTestCase{
27+
{
28+
pod: &corev1.Pod{},
29+
expectedErr: "role undefined",
30+
},
31+
{
32+
pod: &corev1.Pod{
33+
ObjectMeta: metav1.ObjectMeta{
34+
Labels: map[string]string{},
35+
},
36+
},
37+
expectedErr: "role undefined",
38+
},
39+
{
40+
pod: &corev1.Pod{
41+
ObjectMeta: metav1.ObjectMeta{
42+
Labels: map[string]string{
43+
"tarantool.io/someLabel": "some value",
44+
},
45+
},
46+
},
47+
expectedErr: "role undefined",
48+
},
49+
{
50+
pod: &corev1.Pod{
51+
ObjectMeta: metav1.ObjectMeta{
52+
Annotations: map[string]string{},
53+
Labels: map[string]string{},
54+
},
55+
},
56+
expectedErr: "role undefined",
57+
},
58+
}
59+
for i, c := range cases {
60+
roles, err := GetRoles(c.pod)
61+
62+
if roles != nil {
63+
t.Fatalf("%d: roles must be nil", i)
64+
}
65+
66+
if strings.Contains(err.Error(), c.expectedErr) == false {
67+
t.Fatalf("%d: expected error %s, got %s", i, c.expectedErr, err.Error())
68+
}
69+
}
70+
}
71+
72+
type parseRolesTestCase struct {
73+
pod *corev1.Pod
74+
expectedRoles []string
75+
}
76+
77+
func TestGetRoles_ParsesRolesFromLabels(t *testing.T) {
78+
cases := []parseRolesTestCase{
79+
{
80+
pod: &corev1.Pod{
81+
ObjectMeta: metav1.ObjectMeta{
82+
Labels: map[string]string{
83+
"tarantool.io/rolesToAssign": "router",
84+
},
85+
},
86+
},
87+
expectedRoles: []string{"router"},
88+
},
89+
{
90+
pod: &corev1.Pod{
91+
ObjectMeta: metav1.ObjectMeta{
92+
Labels: map[string]string{
93+
"tarantool.io/rolesToAssign": "router.storage",
94+
},
95+
},
96+
},
97+
expectedRoles: []string{"router", "storage"},
98+
},
99+
}
100+
101+
for i, c := range cases {
102+
roles, _ := GetRoles(c.pod)
103+
if len(roles) != len(c.expectedRoles) {
104+
t.Fatalf("%d: expected %d roles, got %d", i, len(c.expectedRoles), len(roles))
105+
}
106+
107+
for _, v := range c.expectedRoles {
108+
if Contains(roles, v) == false {
109+
t.Fatalf("%d: roles must contain %s", i, v)
110+
}
111+
}
112+
}
113+
}
114+
115+
func TestGetRoles_ParseRolesFromAnnotations(t *testing.T) {
116+
cases := []parseRolesTestCase{
117+
{
118+
pod: &corev1.Pod{
119+
ObjectMeta: metav1.ObjectMeta{
120+
Annotations: map[string]string{
121+
"tarantool.io/rolesToAssign": `"router"`,
122+
},
123+
},
124+
},
125+
expectedRoles: []string{"router"},
126+
},
127+
{
128+
pod: &corev1.Pod{
129+
ObjectMeta: metav1.ObjectMeta{
130+
Annotations: map[string]string{
131+
"tarantool.io/rolesToAssign": `["router", "vshard.storage"]`,
132+
},
133+
},
134+
},
135+
expectedRoles: []string{"router", "vshard.storage"},
136+
},
137+
}
138+
139+
for i, c := range cases {
140+
roles, _ := GetRoles(c.pod)
141+
if len(roles) != len(c.expectedRoles) {
142+
t.Fatalf("%d: expected %d roles, got %d", i, len(c.expectedRoles), len(roles))
143+
}
144+
145+
for _, v := range c.expectedRoles {
146+
if Contains(roles, v) == false {
147+
t.Fatalf("%d: roles must contain %s", i, v)
148+
}
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)