istio

Форк
0
/
gatewayclass.go 
118 строк · 4.0 Кб
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 gateway
16

17
import (
18
	"github.com/hashicorp/go-multierror"
19
	kerrors "k8s.io/apimachinery/pkg/api/errors"
20
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21
	"k8s.io/apimachinery/pkg/types"
22
	k8sv1 "sigs.k8s.io/gateway-api/apis/v1"
23
	gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
24

25
	"istio.io/istio/pilot/pkg/model/kstatus"
26
	"istio.io/istio/pkg/kube"
27
	"istio.io/istio/pkg/kube/controllers"
28
	"istio.io/istio/pkg/kube/kclient"
29
	"istio.io/istio/pkg/util/istiomultierror"
30
)
31

32
// ClassController is a controller that creates the default Istio GatewayClass(s). This will not
33
// continually reconcile the full state of the GatewayClass object, and instead only create the class
34
// if it doesn't exist. This allows users to manage it through other means or modify it as they wish.
35
// If it is deleted, however, it will be added back.
36
// This controller intentionally does not do leader election for simplicity. Because we only create
37
// and not update there is no need; the first controller to create the GatewayClass wins.
38
type ClassController struct {
39
	queue   controllers.Queue
40
	classes kclient.Client[*gateway.GatewayClass]
41
}
42

43
func NewClassController(kc kube.Client) *ClassController {
44
	gc := &ClassController{}
45
	gc.queue = controllers.NewQueue("gateway class",
46
		controllers.WithReconciler(gc.Reconcile),
47
		controllers.WithMaxAttempts(25))
48

49
	gc.classes = kclient.New[*gateway.GatewayClass](kc)
50
	gc.classes.AddEventHandler(controllers.FilteredObjectHandler(gc.queue.AddObject, func(o controllers.Object) bool {
51
		_, f := builtinClasses[gateway.ObjectName(o.GetName())]
52
		return f
53
	}))
54
	return gc
55
}
56

57
func (c *ClassController) Run(stop <-chan struct{}) {
58
	// Ensure we initially reconcile the current state
59
	c.queue.Add(types.NamespacedName{})
60
	c.queue.Run(stop)
61
}
62

63
func (c *ClassController) Reconcile(types.NamespacedName) error {
64
	err := istiomultierror.New()
65
	for class := range builtinClasses {
66
		err = multierror.Append(err, c.reconcileClass(class))
67
	}
68
	return err.ErrorOrNil()
69
}
70

71
func (c *ClassController) reconcileClass(class gateway.ObjectName) error {
72
	if c.classes.Get(string(class), "") != nil {
73
		log.Debugf("GatewayClass/%v already exists, no action", class)
74
		return nil
75
	}
76
	controller := builtinClasses[class]
77
	classInfo, f := classInfos[controller]
78
	if !f {
79
		// Should only happen when ambient is disabled; otherwise builtinClasses and classInfos should be consistent
80
		return nil
81
	}
82
	gc := &gateway.GatewayClass{
83
		ObjectMeta: metav1.ObjectMeta{
84
			Name: string(class),
85
		},
86
		Spec: gateway.GatewayClassSpec{
87
			ControllerName: gateway.GatewayController(classInfo.controller),
88
			Description:    &classInfo.description,
89
		},
90
	}
91
	_, err := c.classes.Create(gc)
92
	if err != nil && !kerrors.IsConflict(err) {
93
		return err
94
	} else if err != nil && kerrors.IsConflict(err) {
95
		// This is not really an error, just a race condition
96
		log.Infof("Attempted to create GatewayClass/%v, but it was already created", class)
97
	}
98
	if err != nil {
99
		return err
100
	}
101

102
	return nil
103
}
104

105
func GetClassStatus(existing *k8sv1.GatewayClassStatus, gen int64) k8sv1.GatewayClassStatus {
106
	if existing == nil {
107
		existing = &k8sv1.GatewayClassStatus{}
108
	}
109
	existing.Conditions = kstatus.UpdateConditionIfChanged(existing.Conditions, metav1.Condition{
110
		Type:               string(k8sv1.GatewayClassConditionStatusAccepted),
111
		Status:             kstatus.StatusTrue,
112
		ObservedGeneration: gen,
113
		LastTransitionTime: metav1.Now(),
114
		Reason:             string(k8sv1.GatewayClassConditionStatusAccepted),
115
		Message:            "Handled by Istio controller",
116
	})
117
	return *existing
118
}
119

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

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

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

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