Skip to content

Commit

Permalink
MINOR: check GW API crd version
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanmatmati authored and oktalz committed May 26, 2023
1 parent 530b75a commit 8617e75
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 19 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/valyala/fasthttp v1.47.0
go.uber.org/automaxprocs v1.5.2
k8s.io/api v0.27.2
k8s.io/apiextensions-apiserver v0.27.2
k8s.io/apimachinery v0.27.2
k8s.io/client-go v0.27.2
sigs.k8s.io/controller-runtime v0.15.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo=
k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4=
k8s.io/apiextensions-apiserver v0.27.2 h1:iwhyoeS4xj9Y7v8YExhUwbVuBhMr3Q4bd/laClBV6Bo=
k8s.io/apiextensions-apiserver v0.27.2/go.mod h1:Oz9UdvGguL3ULgRdY9QMUzL2RZImotgxvGjdWRq6ZXQ=
k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg=
k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE=
Expand Down
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,12 @@ func main() {
WithRestClientSet(k.GetRestClientset()).
WithArgs(osArgs).Build()

go k.MonitorChanges(eventChan, stop, osArgs)
go c.Start()
isGatewayAPIInstalled := k.IsGatewayAPIInstalled(osArgs.GatewayControllerName)

c.SetGatewayAPIInstalled(isGatewayAPIInstalled)

go k.MonitorChanges(eventChan, stop, osArgs, isGatewayAPIInstalled)
go c.Start()
// Catch QUIT signals
signalC := make(chan os.Signal, 1)
signal.Notify(signalC, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
Expand Down
4 changes: 4 additions & 0 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,7 @@ func (c *HAProxyController) clean(failedSync bool) {
c.reload = false
c.restart = false
}

func (c *HAProxyController) SetGatewayAPIInstalled(gatewayAPIInstalled bool) {
c.gatewayManager.SetGatewayAPIInstalled(gatewayAPIInstalled)
}
29 changes: 19 additions & 10 deletions pkg/gateways/gateways.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ const (
//nolint:golint
type GatewayManager interface {
ManageGateway() bool
SetGatewayAPIInstalled(bool)
}

func New(k8sStore store.K8s,
haproxyClient api.HAProxyClient,
osArgs utils.OSArgs,
k8sRestClient client.Client,
) GatewayManager {
return GatewayManagerImpl{
return &GatewayManagerImpl{
k8sStore: k8sStore,
haproxyClient: haproxyClient,
osArgs: osArgs,
Expand All @@ -69,18 +70,22 @@ func New(k8sStore store.K8s,

//nolint:golint
type GatewayManagerImpl struct {
haproxyClient api.HAProxyClient
statusManager StatusManager
frontends map[string]struct{}
gateways map[string]struct{}
listenersByRoute map[string][]store.Listener
backends map[string]struct{}
serversByBackend map[string][]string
k8sStore store.K8s
osArgs utils.OSArgs
haproxyClient api.HAProxyClient
statusManager StatusManager
frontends map[string]struct{}
gateways map[string]struct{}
listenersByRoute map[string][]store.Listener
backends map[string]struct{}
serversByBackend map[string][]string
k8sStore store.K8s
osArgs utils.OSArgs
gatewayAPIInstalled bool
}

func (gm GatewayManagerImpl) ManageGateway() bool {
if gm.osArgs.GatewayControllerName == "" || !gm.gatewayAPIInstalled {
return false
}
gm.clean()
gm.manageGatewayClass()

Expand Down Expand Up @@ -669,3 +674,7 @@ func (gm *GatewayManagerImpl) resetStatuses() {
}
}
}

func (gm *GatewayManagerImpl) SetGatewayAPIInstalled(gatewayAPIInstalled bool) {
gm.gatewayAPIInstalled = gatewayAPIInstalled
}
63 changes: 56 additions & 7 deletions pkg/k8s/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package k8s

import (
"context"
"errors"
"os"
"path/filepath"
Expand All @@ -31,6 +32,9 @@ import (
crinformers "github.com/haproxytech/kubernetes-ingress/crs/generated/informers/externalversions"
"github.com/haproxytech/kubernetes-ingress/pkg/ingress"
"github.com/haproxytech/kubernetes-ingress/pkg/utils"
crdclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
errGw "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
gatewayclientset "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
scheme "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/scheme"
Expand All @@ -44,15 +48,17 @@ const (
TRACE_API = false //nolint:golint,stylecheck
CRSGroupVersionV1alpha1 = "core.haproxy.org/v1alpha1"
CRSGroupVersionV1alpha2 = "core.haproxy.org/v1alpha2"
GATEWAY_API_VERSION = "v0.5.1" //nolint:golint,stylecheck
)

var ErrIgnored = errors.New("ignored resource")

type K8s interface {
GetRestClientset() client.Client
GetClientset() *k8sclientset.Clientset
MonitorChanges(eventChan chan SyncDataEvent, stop chan struct{}, osArgs utils.OSArgs)
MonitorChanges(eventChan chan SyncDataEvent, stop chan struct{}, osArgs utils.OSArgs, gatewayAPIInstalled bool)
UpdatePublishService(ingresses []*ingress.Ingress, publishServiceAddresses []string)
IsGatewayAPIInstalled(gatewayControllerName string) bool
}

// A Custom Resource interface
Expand All @@ -77,6 +83,8 @@ type k8s struct {
syncPeriod time.Duration
cacheResyncPeriod time.Duration
disableSvcExternalName bool // CVE-2021-25740
crdClient *crdclientset.Clientset
gatewayAPIInstalled bool
}

func New(osArgs utils.OSArgs, whitelist map[string]struct{}, publishSvc *utils.NamespaceValue) K8s { //nolint:ireturn
Expand Down Expand Up @@ -104,6 +112,11 @@ func New(osArgs utils.OSArgs, whitelist map[string]struct{}, publishSvc *utils.N
logger.Print("Gateway API not present")
}

crdClient, err := crdclientset.NewForConfig(restconfig)
if err != nil {
logger.Error("CRD API client not present")
}

prefix, _ := utils.GetPodPrefix(os.Getenv("POD_NAME"))
k := k8s{
builtInClient: builtInClient,
Expand All @@ -118,6 +131,7 @@ func New(osArgs utils.OSArgs, whitelist map[string]struct{}, publishSvc *utils.N
disableSvcExternalName: osArgs.DisableServiceExternalName,
gatewayClient: gatewayClient,
gatewayRestClient: gatewayRestClient,
crdClient: crdClient,
}
// alpha1 is deprecated
k.registerCoreCR(NewGlobalCRV1Alpha1(), CRSGroupVersionV1alpha1)
Expand Down Expand Up @@ -145,14 +159,13 @@ func (k k8s) UpdatePublishService(ingresses []*ingress.Ingress, publishServiceAd
}
}

func (k k8s) MonitorChanges(eventChan chan SyncDataEvent, stop chan struct{}, osArgs utils.OSArgs) {
func (k k8s) MonitorChanges(eventChan chan SyncDataEvent, stop chan struct{}, osArgs utils.OSArgs, gatewayAPIInstalled bool) {
informersSynced := &[]cache.InformerSynced{}
needGatewayAPIInformers := k.isGatewayAPIInstalled() && osArgs.GatewayControllerName != ""
k.runPodInformer(eventChan, stop, informersSynced)
for _, namespace := range k.whiteListedNS {
k.runInformers(eventChan, stop, namespace, informersSynced)
k.runCRInformers(eventChan, stop, namespace, informersSynced)
if needGatewayAPIInformers {
if gatewayAPIInstalled {
k.runInformersGwAPI(eventChan, stop, namespace, informersSynced)
}
}
Expand Down Expand Up @@ -320,7 +333,43 @@ func getWhitelistedNS(whitelist map[string]struct{}, cfgMapNS string) []string {
return namespaces
}

func (k k8s) isGatewayAPIInstalled() bool {
_, err := k.crClient.DiscoveryClient.ServerResourcesForGroupVersion("gateway.networking.k8s.io/v1beta1")
return err == nil
func (k k8s) IsGatewayAPIInstalled(gatewayControllerName string) (installed bool) {
installed = true
defer func() {
k.gatewayAPIInstalled = installed
}()
gatewayCrd, err := k.crdClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), "gateways.gateway.networking.k8s.io", metav1.GetOptions{})
if err != nil {
var errStatus *errGw.StatusError
if !errors.As(err, &errStatus) || errStatus.ErrStatus.Code != 404 {
logger.Error(err)
return false
}
}

if gatewayCrd.Name == "" {
if gatewayControllerName != "" {
logger.Errorf("No gateway api is installed, please install experimental yaml version %s", GATEWAY_API_VERSION)
}
return false
}

log := logger.Warningf
if gatewayControllerName != "" {
log = logger.Errorf
}

version := gatewayCrd.Annotations["gateway.networking.k8s.io/bundle-version"]
if version != GATEWAY_API_VERSION {
log("Unsupported version '%s' of gateway api is installed, please install experimental yaml version %s", version, GATEWAY_API_VERSION)
installed = false
}

// gatewayCrd is not nil so gateway API is present
tcprouteCrd, err := k.crdClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.Background(), "tcproutes.gateway.networking.k8s.io", metav1.GetOptions{})
if tcprouteCrd == nil || err != nil {
log("No tcproute crd is installed, please install experimental yaml version %s", GATEWAY_API_VERSION)
installed = false
}
return
}

0 comments on commit 8617e75

Please sign in to comment.