Files
higress/pkg/ingress/kube/gateway/istio/gatewayclass.go
澄潭 f7a419770d upgrade to istio 1.19 (#1211)
Co-authored-by: CH3CHO <ch3cho@qq.com>
Co-authored-by: rinfx <893383980@qq.com>
2024-08-26 09:51:47 +08:00

122 lines
4.1 KiB
Go

// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Updated based on Istio codebase by Higress
package istio
import (
"github.com/hashicorp/go-multierror"
"istio.io/istio/pilot/pkg/model/kstatus"
"istio.io/istio/pkg/kube"
"istio.io/istio/pkg/kube/controllers"
"istio.io/istio/pkg/kube/kclient"
"istio.io/istio/pkg/util/istiomultierror"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
k8s "sigs.k8s.io/gateway-api/apis/v1alpha2"
gateway "sigs.k8s.io/gateway-api/apis/v1beta1"
)
// ClassController is a controller that creates the default Istio GatewayClass(s). This will not
// continually reconcile the full state of the GatewayClass object, and instead only create the class
// if it doesn't exist. This allows users to manage it through other means or modify it as they wish.
// If it is deleted, however, it will be added back.
// This controller intentionally does not do leader election for simplicity. Because we only create
// and not update there is no need; the first controller to create the GatewayClass wins.
type ClassController struct {
queue controllers.Queue
classes kclient.Client[*gateway.GatewayClass]
}
func NewClassController(kc kube.Client) *ClassController {
gc := &ClassController{}
gc.queue = controllers.NewQueue("gateway class",
controllers.WithReconciler(gc.Reconcile),
controllers.WithMaxAttempts(25))
gc.classes = kclient.New[*gateway.GatewayClass](kc)
gc.classes.AddEventHandler(controllers.FilteredObjectHandler(gc.queue.AddObject, func(o controllers.Object) bool {
_, f := builtinClasses[gateway.ObjectName(o.GetName())]
return f
}))
return gc
}
func (c *ClassController) Run(stop <-chan struct{}) {
// Ensure we initially reconcile the current state
c.queue.Add(types.NamespacedName{})
c.queue.Run(stop)
}
func (c *ClassController) Reconcile(types.NamespacedName) error {
err := istiomultierror.New()
for class := range builtinClasses {
err = multierror.Append(err, c.reconcileClass(class))
}
return err.ErrorOrNil()
}
func (c *ClassController) reconcileClass(class gateway.ObjectName) error {
if c.classes.Get(string(class), "") != nil {
log.Debugf("GatewayClass/%v already exists, no action", class)
return nil
}
controller := builtinClasses[class]
classInfo, f := classInfos[controller]
if !f {
// Should only happen when ambient is disabled; otherwise builtinClasses and classInfos should be consistent
return nil
}
gc := &gateway.GatewayClass{
ObjectMeta: metav1.ObjectMeta{
Name: string(class),
},
Spec: gateway.GatewayClassSpec{
ControllerName: gateway.GatewayController(classInfo.controller),
Description: &classInfo.description,
},
}
_, err := c.classes.Create(gc)
if err != nil && !kerrors.IsConflict(err) {
return err
} else if err != nil && kerrors.IsConflict(err) {
// This is not really an error, just a race condition
log.Infof("Attempted to create GatewayClass/%v, but it was already created", class)
}
if err != nil {
return err
}
return nil
}
func GetClassStatus(existing *k8s.GatewayClassStatus, gen int64) k8s.GatewayClassStatus {
if existing == nil {
existing = &k8s.GatewayClassStatus{}
}
existing.Conditions = kstatus.UpdateConditionIfChanged(existing.Conditions, metav1.Condition{
Type: string(gateway.GatewayClassConditionStatusAccepted),
Status: kstatus.StatusTrue,
ObservedGeneration: gen,
LastTransitionTime: metav1.Now(),
Reason: string(gateway.GatewayClassConditionStatusAccepted),
// Start - Updated by Higress
Message: "Handled by Higress controller",
// End - Updated by Higress
})
return *existing
}