mirror of
https://github.com/alibaba/higress.git
synced 2026-02-25 21:21:01 +08:00
218 lines
7.5 KiB
Go
218 lines
7.5 KiB
Go
// Copyright (c) 2022 Alibaba Group Holding Ltd.
|
|
//
|
|
// 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.
|
|
|
|
package configmap
|
|
|
|
import (
|
|
"reflect"
|
|
"sync/atomic"
|
|
|
|
"istio.io/istio/pilot/pkg/model"
|
|
"istio.io/istio/pkg/cluster"
|
|
"istio.io/istio/pkg/config"
|
|
"istio.io/istio/pkg/config/schema/gvr"
|
|
"istio.io/istio/pkg/config/schema/kind"
|
|
schemakubeclient "istio.io/istio/pkg/config/schema/kubeclient"
|
|
kubeclient "istio.io/istio/pkg/kube"
|
|
"istio.io/istio/pkg/kube/controllers"
|
|
ktypes "istio.io/istio/pkg/kube/kubetypes"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
listersv1 "k8s.io/client-go/listers/core/v1"
|
|
"sigs.k8s.io/yaml"
|
|
|
|
"github.com/alibaba/higress/pkg/ingress/kube/controller"
|
|
"github.com/alibaba/higress/pkg/ingress/kube/util"
|
|
. "github.com/alibaba/higress/pkg/ingress/log"
|
|
)
|
|
|
|
type HigressConfigController controller.Controller[listersv1.ConfigMapNamespaceLister]
|
|
|
|
func NewController(client kubeclient.Client, clusterId cluster.ID, namespace string) HigressConfigController {
|
|
opts := ktypes.InformerOptions{
|
|
Namespace: namespace,
|
|
Cluster: clusterId,
|
|
}
|
|
informer := schemakubeclient.GetInformerFilteredFromGVR(client, opts, gvr.ConfigMap)
|
|
lister := listersv1.NewConfigMapLister(informer.Informer.GetIndexer()).ConfigMaps(namespace)
|
|
return controller.NewCommonController("higressConfig", lister, informer.Informer, GetConfigmap, clusterId)
|
|
}
|
|
|
|
func GetConfigmap(lister listersv1.ConfigMapNamespaceLister, namespacedName types.NamespacedName) (controllers.Object, error) {
|
|
return lister.Get(namespacedName.Name)
|
|
}
|
|
|
|
type ItemController interface {
|
|
GetName() string
|
|
AddOrUpdateHigressConfig(name util.ClusterNamespacedName, old *HigressConfig, new *HigressConfig) error
|
|
ValidHigressConfig(higressConfig *HigressConfig) error
|
|
ConstructEnvoyFilters() ([]*config.Config, error)
|
|
RegisterItemEventHandler(eventHandler ItemEventHandler)
|
|
}
|
|
|
|
type ConfigmapMgr struct {
|
|
Namespace string
|
|
HigressConfigController HigressConfigController
|
|
HigressConfigLister listersv1.ConfigMapNamespaceLister
|
|
higressConfig atomic.Value
|
|
ItemControllers []ItemController
|
|
XDSUpdater model.XDSUpdater
|
|
}
|
|
|
|
func NewConfigmapMgr(XDSUpdater model.XDSUpdater, namespace string, higressConfigController HigressConfigController, higressConfigLister listersv1.ConfigMapNamespaceLister) *ConfigmapMgr {
|
|
configmapMgr := &ConfigmapMgr{
|
|
XDSUpdater: XDSUpdater,
|
|
Namespace: namespace,
|
|
HigressConfigController: higressConfigController,
|
|
HigressConfigLister: higressConfigLister,
|
|
higressConfig: atomic.Value{},
|
|
}
|
|
configmapMgr.HigressConfigController.AddEventHandler(configmapMgr.AddOrUpdateHigressConfig)
|
|
configmapMgr.SetHigressConfig(NewDefaultHigressConfig())
|
|
|
|
tracingController := NewTracingController(namespace)
|
|
configmapMgr.AddItemControllers(tracingController)
|
|
|
|
gzipController := NewGzipController(namespace)
|
|
configmapMgr.AddItemControllers(gzipController)
|
|
|
|
globalOptionController := NewGlobalOptionController(namespace)
|
|
configmapMgr.AddItemControllers(globalOptionController)
|
|
|
|
configmapMgr.initEventHandlers()
|
|
|
|
return configmapMgr
|
|
}
|
|
|
|
func (c *ConfigmapMgr) SetHigressConfig(higressConfig *HigressConfig) {
|
|
c.higressConfig.Store(higressConfig)
|
|
}
|
|
|
|
func (c *ConfigmapMgr) GetHigressConfig() *HigressConfig {
|
|
value := c.higressConfig.Load()
|
|
if value != nil {
|
|
if higressConfig, ok := value.(*HigressConfig); ok {
|
|
return higressConfig
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *ConfigmapMgr) AddItemControllers(controllers ...ItemController) {
|
|
c.ItemControllers = append(c.ItemControllers, controllers...)
|
|
}
|
|
|
|
func (c *ConfigmapMgr) AddOrUpdateHigressConfig(name util.ClusterNamespacedName) {
|
|
if name.Namespace != c.Namespace || name.Name != HigressConfigMapName {
|
|
return
|
|
}
|
|
|
|
IngressLog.Infof("configmapMgr AddOrUpdateHigressConfig")
|
|
higressConfigmap, err := c.HigressConfigLister.Get(HigressConfigMapName)
|
|
if err != nil {
|
|
IngressLog.Errorf("higress-config configmap is not found, namespace:%s, name:%s",
|
|
name.Namespace, name.Name)
|
|
return
|
|
}
|
|
|
|
if _, ok := higressConfigmap.Data[HigressConfigMapKey]; !ok {
|
|
return
|
|
}
|
|
|
|
newHigressConfig := NewDefaultHigressConfig()
|
|
if err = yaml.Unmarshal([]byte(higressConfigmap.Data[HigressConfigMapKey]), newHigressConfig); err != nil {
|
|
IngressLog.Errorf("data:%s, convert to higress config error, error: %+v", higressConfigmap.Data[HigressConfigMapKey], err)
|
|
return
|
|
}
|
|
|
|
for _, itemController := range c.ItemControllers {
|
|
if itemErr := itemController.ValidHigressConfig(newHigressConfig); itemErr != nil {
|
|
IngressLog.Errorf("configmap %s controller valid higress config error, error: %+v", itemController.GetName(), itemErr)
|
|
return
|
|
}
|
|
}
|
|
|
|
oldHigressConfig := c.GetHigressConfig()
|
|
IngressLog.Infof("configmapMgr oldHigressConfig: %s", GetHigressConfigString(oldHigressConfig))
|
|
IngressLog.Infof("configmapMgr newHigressConfig: %s", GetHigressConfigString(newHigressConfig))
|
|
result, _ := c.CompareHigressConfig(oldHigressConfig, newHigressConfig)
|
|
IngressLog.Infof("configmapMgr CompareHigressConfig reuslt is %d", result)
|
|
|
|
if result == ResultNothing {
|
|
return
|
|
}
|
|
|
|
if result == ResultDelete {
|
|
newHigressConfig = NewDefaultHigressConfig()
|
|
}
|
|
|
|
if result == ResultReplace || result == ResultDelete {
|
|
// Pass AddOrUpdateHigressConfig to itemControllers
|
|
for _, itemController := range c.ItemControllers {
|
|
IngressLog.Infof("configmap %s controller AddOrUpdateHigressConfig", itemController.GetName())
|
|
if itemErr := itemController.AddOrUpdateHigressConfig(name, oldHigressConfig, newHigressConfig); itemErr != nil {
|
|
IngressLog.Errorf("configmap %s controller AddOrUpdateHigressConfig error, error: %+v", itemController.GetName(), itemErr)
|
|
}
|
|
}
|
|
c.SetHigressConfig(newHigressConfig)
|
|
IngressLog.Infof("configmapMgr higress config AddOrUpdate success, reuslt is %d", result)
|
|
// Call updateConfig
|
|
}
|
|
|
|
}
|
|
|
|
func (c *ConfigmapMgr) ConstructEnvoyFilters() ([]*config.Config, error) {
|
|
configs := make([]*config.Config, 0)
|
|
for _, itemController := range c.ItemControllers {
|
|
IngressLog.Infof("controller %s ConstructEnvoyFilters", itemController.GetName())
|
|
if itemConfigs, err := itemController.ConstructEnvoyFilters(); err != nil {
|
|
IngressLog.Errorf("controller %s ConstructEnvoyFilters error, error: %+v", itemController.GetName(), err)
|
|
} else {
|
|
configs = append(configs, itemConfigs...)
|
|
}
|
|
}
|
|
return configs, nil
|
|
}
|
|
|
|
func (c *ConfigmapMgr) CompareHigressConfig(old *HigressConfig, new *HigressConfig) (Result, error) {
|
|
if old == nil || new == nil {
|
|
return ResultNothing, nil
|
|
}
|
|
|
|
if !reflect.DeepEqual(old, new) {
|
|
return ResultReplace, nil
|
|
}
|
|
|
|
return ResultNothing, nil
|
|
}
|
|
|
|
func (c *ConfigmapMgr) initEventHandlers() error {
|
|
itemEventHandler := func(name string) {
|
|
c.XDSUpdater.ConfigUpdate(&model.PushRequest{
|
|
Full: true,
|
|
ConfigsUpdated: map[model.ConfigKey]struct{}{{
|
|
Kind: kind.EnvoyFilter,
|
|
Name: name,
|
|
Namespace: c.Namespace,
|
|
}: {}},
|
|
Reason: model.NewReasonStats(ModelUpdatedReason),
|
|
})
|
|
}
|
|
|
|
for _, itemController := range c.ItemControllers {
|
|
itemController.RegisterItemEventHandler(itemEventHandler)
|
|
}
|
|
|
|
return nil
|
|
}
|