1
// Copyright Istio Authors
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
7
// http://www.apache.org/licenses/LICENSE-2.0
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.
20
corev1 "k8s.io/api/core/v1"
21
knetworking "k8s.io/api/networking/v1"
22
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23
"k8s.io/apimachinery/pkg/runtime"
25
"istio.io/api/annotation"
26
"istio.io/istio/pkg/config/mesh"
27
kubelib "istio.io/istio/pkg/kube"
28
"istio.io/istio/pkg/kube/kclient/clienttest"
29
istiolog "istio.io/istio/pkg/log"
30
"istio.io/istio/pkg/test"
31
"istio.io/istio/pkg/test/util/assert"
36
hostname = "foo.bar.com"
40
var ingressService = &corev1.Service{
41
ObjectMeta: metav1.ObjectMeta{
42
Name: "istio-ingress",
43
Namespace: IngressNamespace,
45
Status: corev1.ServiceStatus{
46
LoadBalancer: corev1.LoadBalancerStatus{
47
Ingress: []corev1.LoadBalancerIngress{{
54
var testObjects = []runtime.Object{
56
ObjectMeta: metav1.ObjectMeta{
57
Name: "ingressgateway",
58
Namespace: "istio-system",
59
Labels: map[string]string{
60
"istio": "ingressgateway",
66
Status: corev1.PodStatus{
67
Phase: corev1.PodRunning,
72
ObjectMeta: metav1.ObjectMeta{
73
Name: "istio-ingress-hostname",
74
Namespace: IngressNamespace,
76
Status: corev1.ServiceStatus{
77
LoadBalancer: corev1.LoadBalancerStatus{
78
Ingress: []corev1.LoadBalancerIngress{{
85
ObjectMeta: metav1.ObjectMeta{
88
Status: corev1.NodeStatus{
89
Addresses: []corev1.NodeAddress{
91
Type: corev1.NodeExternalIP,
99
func fakeMeshHolder(ingressService string) mesh.Watcher {
100
config := mesh.DefaultMeshConfig()
101
config.IngressService = ingressService
102
return mesh.NewFixedWatcher(config)
105
func makeStatusSyncer(t *testing.T, name string) *StatusSyncer {
106
client := kubelib.NewFakeClient(testObjects...)
107
sync := NewStatusSyncer(fakeMeshHolder(name), client)
108
client.RunAndWait(test.NewStop(t))
109
go sync.Run(test.NewStop(t))
114
func getIPs(ing clienttest.TestClient[*knetworking.Ingress], name string, ns string) func() []string {
115
return func() []string {
116
i := ing.Get(name, ns)
121
for _, v := range i.Status.LoadBalancer.Ingress {
123
res = append(res, v.IP)
125
res = append(res, v.Hostname)
132
func TestStatusController(t *testing.T) {
133
statusLog.SetOutputLevel(istiolog.DebugLevel)
134
c := makeStatusSyncer(t, "istio-ingress")
135
ing := clienttest.Wrap(t, c.ingresses)
136
svc := clienttest.Wrap(t, c.services)
137
ingc := clienttest.Wrap(t, c.ingressClasses)
138
ing.Create(&knetworking.Ingress{
139
ObjectMeta: metav1.ObjectMeta{
141
Namespace: "default",
142
Annotations: map[string]string{annotation.IoKubernetesIngressClass.Name: "istio"},
146
// Test initial state
147
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{serviceIP})
150
updated := ingressService.DeepCopy()
151
updated.Status.LoadBalancer.Ingress = []corev1.LoadBalancerIngress{{IP: "5.6.7.8"}}
153
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{"5.6.7.8"})
156
svc.Delete(ingressService.Name, ingressService.Namespace)
157
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{})
161
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{"5.6.7.8"})
163
// Remove ingress class
164
ing.Update(&knetworking.Ingress{
165
ObjectMeta: metav1.ObjectMeta{
167
Namespace: "default",
170
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{})
172
ingressClassName := "istio"
173
// Set IngressClassName
174
ing.Update(&knetworking.Ingress{
175
ObjectMeta: metav1.ObjectMeta{
177
Namespace: "default",
179
Spec: knetworking.IngressSpec{
180
IngressClassName: &ingressClassName,
183
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{})
185
// Create IngressClass
186
ingc.Create(&knetworking.IngressClass{
187
ObjectMeta: metav1.ObjectMeta{
188
Name: ingressClassName,
190
Spec: knetworking.IngressClassSpec{
191
Controller: IstioIngressController,
194
assert.EventuallyEqual(t, getIPs(ing, "ingress", "default"), []string{"5.6.7.8"})
197
func TestRunningAddresses(t *testing.T) {
198
t.Run("service", testRunningAddressesWithService)
199
t.Run("hostname", testRunningAddressesWithHostname)
202
func testRunningAddressesWithService(t *testing.T) {
203
syncer := makeStatusSyncer(t, "istio-ingress")
204
address := syncer.runningAddresses()
206
if len(address) != 1 || address[0] != serviceIP {
207
t.Errorf("Address is not correctly set to service ip")
211
func testRunningAddressesWithHostname(t *testing.T) {
212
syncer := makeStatusSyncer(t, "istio-ingress-hostname")
214
address := syncer.runningAddresses()
216
if len(address) != 1 || address[0] != hostname {
217
t.Errorf("Address is not correctly set to hostname")
221
func TestRunningAddressesWithPod(t *testing.T) {
222
syncer := makeStatusSyncer(t, "")
224
address := syncer.runningAddresses()
226
if len(address) != 1 || address[0] != nodeIP {
227
t.Errorf("Address is not correctly set to node ip %v %v", address, nodeIP)