istio

Форк
0
/
autoserviceexportcontroller_test.go 
158 строк · 4.9 Кб
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
	"strings"
21
	"testing"
22
	"time"
23

24
	v1 "k8s.io/api/core/v1"
25
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
	"k8s.io/apimachinery/pkg/runtime"
27
	mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
28

29
	meshconfig "istio.io/api/mesh/v1alpha1"
30
	"istio.io/istio/pilot/pkg/features"
31
	"istio.io/istio/pilot/pkg/model"
32
	"istio.io/istio/pkg/config/mesh"
33
	"istio.io/istio/pkg/kube"
34
	"istio.io/istio/pkg/kube/kclient/clienttest"
35
	"istio.io/istio/pkg/kube/mcs"
36
	"istio.io/istio/pkg/test"
37
	"istio.io/istio/pkg/test/util/retry"
38
)
39

40
var serviceExportTimeout = retry.Timeout(time.Second * 2)
41

42
func TestServiceExportController(t *testing.T) {
43
	client := kube.NewFakeClient()
44

45
	// Configure the environment with cluster-local hosts.
46
	m := meshconfig.MeshConfig{
47
		ServiceSettings: []*meshconfig.MeshConfig_ServiceSettings{
48
			{
49
				Settings: &meshconfig.MeshConfig_ServiceSettings_Settings{
50
					ClusterLocal: true,
51
				},
52
				Hosts: []string{"*.unexportable-ns.svc.cluster.local", "unexportable-svc.*.svc.cluster.local"},
53
			},
54
		},
55
	}
56
	env := model.Environment{Watcher: mesh.NewFixedWatcher(&m)}
57
	env.Init()
58

59
	sc := newAutoServiceExportController(autoServiceExportOptions{
60
		Client:       client,
61
		ClusterID:    "",
62
		DomainSuffix: env.DomainSuffix,
63
		ClusterLocal: env.ClusterLocal(),
64
	})
65

66
	stop := test.NewStop(t)
67
	client.RunAndWait(stop)
68
	go sc.Run(stop)
69

70
	t.Run("exportable", func(t *testing.T) {
71
		createSimpleService(t, client, "exportable-ns", "foo")
72
		assertServiceExport(t, client, "exportable-ns", "foo", true)
73
	})
74

75
	t.Run("unexportable", func(t *testing.T) {
76
		createSimpleService(t, client, "unexportable-ns", "foo")
77
		assertServiceExport(t, client, "unexportable-ns", "foo", false)
78
	})
79

80
	t.Run("no overwrite", func(t *testing.T) {
81
		// manually create serviceexport
82
		export := mcsapi.ServiceExport{
83
			TypeMeta: metav1.TypeMeta{
84
				Kind:       "ServiceExport",
85
				APIVersion: features.MCSAPIVersion,
86
			},
87
			ObjectMeta: metav1.ObjectMeta{
88
				Namespace: "exportable-ns",
89
				Name:      "manual-export",
90
			},
91
			Status: mcsapi.ServiceExportStatus{
92
				Conditions: []mcsapi.ServiceExportCondition{
93
					{
94
						Type: mcsapi.ServiceExportValid,
95
					},
96
				},
97
			},
98
		}
99

100
		_, err := client.Dynamic().Resource(mcs.ServiceExportGVR).Namespace("exportable-ns").Create(
101
			context.TODO(), toUnstructured(&export), metav1.CreateOptions{})
102
		if err != nil {
103
			t.Fatalf("Unexpected error %v", err)
104
		}
105

106
		// create the associated service
107
		// no need for assertions, just trying to ensure no errors
108
		createSimpleService(t, client, "exportable-ns", "manual-export")
109

110
		// assert that we didn't wipe out the pre-existing serviceexport status
111
		assertServiceExportHasCondition(t, client, "exportable-ns", "manual-export",
112
			mcsapi.ServiceExportValid)
113
	})
114
}
115

116
func createSimpleService(t *testing.T, client kube.Client, ns string, name string) {
117
	t.Helper()
118
	clienttest.NewWriter[*v1.Service](t, client).Create(&v1.Service{
119
		ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns},
120
	})
121
}
122

123
func assertServiceExport(t *testing.T, client kube.Client, ns, name string, shouldBePresent bool) {
124
	t.Helper()
125
	retry.UntilSuccessOrFail(t, func() error {
126
		got, err := client.Dynamic().Resource(mcs.ServiceExportGVR).Namespace(ns).Get(context.TODO(), name, metav1.GetOptions{})
127

128
		if err != nil && !strings.Contains(err.Error(), "not found") {
129
			return fmt.Errorf("unexpected error %v", err)
130
		}
131
		isPresent := got != nil
132
		if isPresent != shouldBePresent {
133
			return fmt.Errorf("unexpected serviceexport state. IsPresent: %v, ShouldBePresent: %v, name: %v, namespace: %v", isPresent, shouldBePresent, name, ns)
134
		}
135
		return nil
136
	}, serviceExportTimeout)
137
}
138

139
func assertServiceExportHasCondition(t *testing.T, client kube.Client, ns, name string, condition mcsapi.ServiceExportConditionType) {
140
	t.Helper()
141
	retry.UntilSuccessOrFail(t, func() error {
142
		gotU, err := client.Dynamic().Resource(mcs.ServiceExportGVR).Namespace(ns).Get(context.TODO(), name, metav1.GetOptions{})
143
		if err != nil {
144
			return fmt.Errorf("unexpected error %v", err)
145
		}
146

147
		got := &mcsapi.ServiceExport{}
148
		if err := runtime.DefaultUnstructuredConverter.FromUnstructured(gotU.Object, got); err != nil {
149
			return err
150
		}
151

152
		if got.Status.Conditions == nil || len(got.Status.Conditions) == 0 || got.Status.Conditions[0].Type != condition {
153
			return fmt.Errorf("condition incorrect or not found")
154
		}
155

156
		return nil
157
	}, serviceExportTimeout)
158
}
159

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

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

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

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