istio

Форк
0
/
namespacecontroller_test.go 
243 строки · 8.1 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package controller
16

17
import (
18
	"context"
19
	"fmt"
20
	"reflect"
21
	"testing"
22
	"time"
23

24
	v1 "k8s.io/api/core/v1"
25
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
	"k8s.io/client-go/kubernetes"
27

28
	meshconfig "istio.io/api/mesh/v1alpha1"
29
	"istio.io/istio/pilot/pkg/keycertbundle"
30
	"istio.io/istio/pkg/config/constants"
31
	"istio.io/istio/pkg/config/mesh"
32
	"istio.io/istio/pkg/kube"
33
	"istio.io/istio/pkg/kube/inject"
34
	"istio.io/istio/pkg/kube/kclient"
35
	filter "istio.io/istio/pkg/kube/namespace"
36
	"istio.io/istio/pkg/test"
37
	"istio.io/istio/pkg/test/util/retry"
38
)
39

40
func TestNamespaceController(t *testing.T) {
41
	client := kube.NewFakeClient()
42
	t.Cleanup(client.Shutdown)
43
	watcher := keycertbundle.NewWatcher()
44
	caBundle := []byte("caBundle")
45
	watcher.SetAndNotify(nil, nil, caBundle)
46
	meshWatcher := mesh.NewTestWatcher(&meshconfig.MeshConfig{})
47
	stop := test.NewStop(t)
48
	discoveryNamespacesFilter := filter.NewDiscoveryNamespacesFilter(
49
		kclient.New[*v1.Namespace](client),
50
		meshWatcher,
51
		stop,
52
	)
53
	kube.SetObjectFilter(client, discoveryNamespacesFilter)
54
	nc := NewNamespaceController(client, watcher)
55
	client.RunAndWait(stop)
56
	go nc.Run(stop)
57
	retry.UntilOrFail(t, nc.queue.HasSynced)
58

59
	expectedData := map[string]string{
60
		constants.CACertNamespaceConfigMapDataName: string(caBundle),
61
	}
62
	createNamespace(t, client.Kube(), "foo", nil)
63
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, "foo", expectedData)
64

65
	// Make sure random configmap does not get updated
66
	cmData := createConfigMap(t, client.Kube(), "not-root", "foo", "k")
67
	expectConfigMap(t, nc.configmaps, "not-root", "foo", cmData)
68

69
	newCaBundle := []byte("caBundle-new")
70
	watcher.SetAndNotify(nil, nil, newCaBundle)
71
	newData := map[string]string{
72
		constants.CACertNamespaceConfigMapDataName: string(newCaBundle),
73
	}
74
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, "foo", newData)
75

76
	deleteConfigMap(t, client.Kube(), "foo")
77
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, "foo", newData)
78

79
	ignoredNamespaces := inject.IgnoredNamespaces.Copy().Delete(constants.KubeSystemNamespace)
80
	for _, namespace := range ignoredNamespaces.UnsortedList() {
81
		// Create namespace in ignored list, make sure its not created
82
		createNamespace(t, client.Kube(), namespace, newData)
83
		// Configmap in that namespace should not do anything either
84
		createConfigMap(t, client.Kube(), "not-root", namespace, "k")
85
		expectConfigMapNotExist(t, nc.configmaps, namespace)
86
	}
87
}
88

89
func TestNamespaceControllerWithDiscoverySelectors(t *testing.T) {
90
	client := kube.NewFakeClient()
91
	t.Cleanup(client.Shutdown)
92
	watcher := keycertbundle.NewWatcher()
93
	caBundle := []byte("caBundle")
94
	watcher.SetAndNotify(nil, nil, caBundle)
95
	meshWatcher := mesh.NewTestWatcher(&meshconfig.MeshConfig{
96
		DiscoverySelectors: []*metav1.LabelSelector{
97
			{
98
				MatchLabels: map[string]string{
99
					"discovery-selectors": "enabled",
100
				},
101
			},
102
		},
103
	})
104
	stop := test.NewStop(t)
105
	discoveryNamespacesFilter := filter.NewDiscoveryNamespacesFilter(
106
		kclient.New[*v1.Namespace](client),
107
		meshWatcher,
108
		stop,
109
	)
110
	kube.SetObjectFilter(client, discoveryNamespacesFilter)
111
	nc := NewNamespaceController(client, watcher)
112
	client.RunAndWait(stop)
113
	go nc.Run(stop)
114
	retry.UntilOrFail(t, nc.queue.HasSynced)
115

116
	expectedData := map[string]string{
117
		constants.CACertNamespaceConfigMapDataName: string(caBundle),
118
	}
119

120
	nsA := "nsA"
121
	nsB := "nsB"
122

123
	// Create a namespace with discovery selector enabled
124
	createNamespace(t, client.Kube(), nsA, map[string]string{"discovery-selectors": "enabled"})
125
	// Create a namespace without discovery selector enabled
126
	createNamespace(t, client.Kube(), nsB, map[string]string{})
127
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, nsA, expectedData)
128
	// config map should not be created for discovery selector disabled namespace
129
	expectConfigMapNotExist(t, nc.configmaps, nsB)
130
}
131

132
func TestNamespaceControllerDiscovery(t *testing.T) {
133
	client := kube.NewFakeClient()
134
	t.Cleanup(client.Shutdown)
135
	watcher := keycertbundle.NewWatcher()
136
	caBundle := []byte("caBundle")
137
	watcher.SetAndNotify(nil, nil, caBundle)
138
	meshWatcher := mesh.NewTestWatcher(&meshconfig.MeshConfig{
139
		DiscoverySelectors: []*metav1.LabelSelector{{
140
			MatchLabels: map[string]string{"kubernetes.io/metadata.name": "selected"},
141
		}},
142
	})
143
	stop := test.NewStop(t)
144
	discoveryNamespacesFilter := filter.NewDiscoveryNamespacesFilter(
145
		kclient.New[*v1.Namespace](client),
146
		meshWatcher,
147
		stop,
148
	)
149
	kube.SetObjectFilter(client, discoveryNamespacesFilter)
150
	nc := NewNamespaceController(client, watcher)
151
	client.RunAndWait(stop)
152
	go nc.Run(stop)
153
	retry.UntilOrFail(t, nc.queue.HasSynced)
154

155
	expectedData := map[string]string{
156
		constants.CACertNamespaceConfigMapDataName: string(caBundle),
157
	}
158
	createNamespace(t, client.Kube(), "not-selected", map[string]string{"kubernetes.io/metadata.name": "not-selected"})
159
	createNamespace(t, client.Kube(), "selected", map[string]string{"kubernetes.io/metadata.name": "selected"})
160

161
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, "selected", expectedData)
162
	expectConfigMapNotExist(t, nc.configmaps, "not-selected")
163

164
	meshWatcher.Update(&meshconfig.MeshConfig{
165
		DiscoverySelectors: []*metav1.LabelSelector{{
166
			MatchLabels: map[string]string{"kubernetes.io/metadata.name": "not-selected"},
167
		}},
168
	}, time.Second)
169
	expectConfigMap(t, nc.configmaps, CACertNamespaceConfigMap, "not-selected", expectedData)
170
	expectConfigMapNotExist(t, nc.configmaps, "selected")
171
}
172

173
func deleteConfigMap(t *testing.T, client kubernetes.Interface, ns string) {
174
	t.Helper()
175
	_, err := client.CoreV1().ConfigMaps(ns).Get(context.TODO(), CACertNamespaceConfigMap, metav1.GetOptions{})
176
	if err != nil {
177
		t.Fatal(err)
178
	}
179
	if err := client.CoreV1().ConfigMaps(ns).Delete(context.TODO(), CACertNamespaceConfigMap, metav1.DeleteOptions{}); err != nil {
180
		t.Fatal(err)
181
	}
182
}
183

184
func createConfigMap(t *testing.T, client kubernetes.Interface, name, ns, key string) map[string]string {
185
	t.Helper()
186
	data := map[string]string{key: "v"}
187
	_, err := client.CoreV1().ConfigMaps(ns).Create(context.Background(), &v1.ConfigMap{
188
		ObjectMeta: metav1.ObjectMeta{
189
			Name:      name,
190
			Namespace: ns,
191
		},
192
		Data: data,
193
	}, metav1.CreateOptions{})
194
	if err != nil {
195
		t.Fatal(err)
196
	}
197
	return data
198
}
199

200
func createNamespace(t *testing.T, client kubernetes.Interface, ns string, labels map[string]string) {
201
	t.Helper()
202
	if _, err := client.CoreV1().Namespaces().Create(context.TODO(), &v1.Namespace{
203
		ObjectMeta: metav1.ObjectMeta{Name: ns, Labels: labels},
204
	}, metav1.CreateOptions{}); err != nil {
205
		t.Fatal(err)
206
	}
207
}
208

209
func updateNamespace(t *testing.T, client kubernetes.Interface, ns string, labels map[string]string) {
210
	t.Helper()
211
	if _, err := client.CoreV1().Namespaces().Update(context.TODO(), &v1.Namespace{
212
		ObjectMeta: metav1.ObjectMeta{Name: ns, Labels: labels},
213
	}, metav1.UpdateOptions{}); err != nil {
214
		t.Fatal(err)
215
	}
216
}
217

218
// nolint:unparam
219
func expectConfigMap(t *testing.T, configmaps kclient.Client[*v1.ConfigMap], name, ns string, data map[string]string) {
220
	t.Helper()
221
	retry.UntilSuccessOrFail(t, func() error {
222
		cm := configmaps.Get(name, ns)
223
		if cm == nil {
224
			return fmt.Errorf("not found")
225
		}
226
		if !reflect.DeepEqual(cm.Data, data) {
227
			return fmt.Errorf("data mismatch, expected %+v got %+v", data, cm.Data)
228
		}
229
		return nil
230
	}, retry.Timeout(time.Second*10))
231
}
232

233
func expectConfigMapNotExist(t *testing.T, configmaps kclient.Client[*v1.ConfigMap], ns string) {
234
	t.Helper()
235
	err := retry.Until(func() bool {
236
		cm := configmaps.Get(CACertNamespaceConfigMap, ns)
237
		return cm != nil
238
	}, retry.Timeout(time.Millisecond*25))
239

240
	if err == nil {
241
		t.Fatalf("%s namespace should not have istio-ca-root-cert configmap.", ns)
242
	}
243
}
244

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.