Skip to content

Commit

Permalink
chore: deprecate KongIngress entirely
Browse files Browse the repository at this point in the history
  • Loading branch information
czeslavo committed Oct 30, 2023
1 parent 513db87 commit d730bb1
Show file tree
Hide file tree
Showing 22 changed files with 130 additions and 571 deletions.
11 changes: 10 additions & 1 deletion config/crd/bases/configuration.konghq.com_kongingresses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ spec:
- name: v1
schema:
openAPIV3Schema:
description: KongIngress is the Schema for the kongingresses API.
description: 'KongIngress is the Schema for the kongingresses API. Deprecated:
use Service''s annotations, Ingress''s annotations, or KongUpstreamPolicy
instead.'
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
Expand Down Expand Up @@ -351,6 +353,13 @@ spec:
type: integer
type: object
type: object
x-kubernetes-validations:
- message: '''proxy'' field is no longer supported, use Service''s annotations
instead'
rule: '!has(self.proxy)'
- message: '''route'' field is no longer supported, use Ingress'' annotations
instead'
rule: '!has(self.route)'
served: true
storage: true
subresources:
Expand Down
14 changes: 0 additions & 14 deletions hack/generators/controllers/networking/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,6 @@ var inputControllersNeeded = &typesNeeded{
AcceptsIngressClassNameSpec: false,
RBACVerbs: []string{"get", "list", "watch"},
},
typeNeeded{
Group: "configuration.konghq.com",
Version: "v1",
Kind: "KongIngress",
PackageImportAlias: "kongv1",
PackageAlias: "KongV1",
Package: kongv1,
Plural: "kongingresses",
CacheType: "KongIngress",
NeedsStatusPermissions: true,
AcceptsIngressClassNameAnnotation: false,
AcceptsIngressClassNameSpec: false,
RBACVerbs: []string{"get", "list", "watch"},
},
typeNeeded{
Group: "configuration.konghq.com",
Version: "v1beta1",
Expand Down
10 changes: 4 additions & 6 deletions internal/admission/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,16 +299,14 @@ func (h RequestHandler) handleKongIngress(_ context.Context, request admissionv1
// KongIngress is always allowed.
responseBuilder = responseBuilder.Allowed(true)

if kongIngress.Proxy != nil {
const warning = "'proxy' is DEPRECATED. It will have no effect. Use Service's annotations instead."
responseBuilder = responseBuilder.WithWarning(warning)
}

if kongIngress.Route != nil {
const warning = "'route' is DEPRECATED. It will have no effect. Use Ingress' annotations instead."
const warning = "'upstream' is DEPRECATED. It will have no effect. Use KongUpstreamPolicy instead."
responseBuilder = responseBuilder.WithWarning(warning)
}

// Both Service and Route are required to be absent on the API server CRD validations level so we don't need to
// check for them here.

return responseBuilder.Build(), nil
}

Expand Down
11 changes: 2 additions & 9 deletions internal/dataplane/kongstate/kongstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ func (ks *KongState) FillConsumerGroups(_ logr.Logger, s store.Storer) {
}
}

func (ks *KongState) FillOverrides(logger logr.Logger, s store.Storer) {
func (ks *KongState) FillOverrides(logger logr.Logger) {
for i := 0; i < len(ks.Services); i++ {
// Services
ks.Services[i].override()
Expand All @@ -198,15 +198,8 @@ func (ks *KongState) FillOverrides(logger logr.Logger, s store.Storer) {

// Upstreams
for i := 0; i < len(ks.Upstreams); i++ {
kongIngress, err := getKongIngressForServices(s, ks.Upstreams[i].Service.K8sServices)
if err != nil {
logger.Error(err, "failed to fetch KongIngress resource for Services",
"names", PrettyPrintServiceList(ks.Upstreams[i].Service.K8sServices))
continue
}

for _, svc := range ks.Upstreams[i].Service.K8sServices {
ks.Upstreams[i].override(kongIngress, svc)
ks.Upstreams[i].override(svc)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/dataplane/kongstate/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func TestNormalizeProtocols(t *testing.T) {

assert.NotPanics(func() {
var nilUpstream *Upstream
nilUpstream.override(nil, nil)
nilUpstream.override(nil)
})
}

Expand Down
80 changes: 2 additions & 78 deletions internal/dataplane/kongstate/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package kongstate
import (
"github.com/kong/go-kong/kong"
corev1 "k8s.io/api/core/v1"
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"

"github.com/kong/kubernetes-ingress-controller/v3/internal/annotations"
kongv1 "github.com/kong/kubernetes-ingress-controller/v3/pkg/apis/configuration/v1"
)

// Upstream is a wrapper around Upstream object in Kong.
Expand Down Expand Up @@ -37,87 +35,13 @@ func (u *Upstream) overrideByAnnotation(anns map[string]string) {
u.overrideHostHeader(anns)
}

// overrideByKongIngress modifies the Kong upstream based on KongIngresses
// associated with the Kubernetes service.
func (u *Upstream) overrideByKongIngress(kongIngress *kongv1.KongIngress) {
if u == nil {
return
}

if kongIngress == nil || kongIngress.Upstream == nil {
return
}
k := kongIngress.Upstream
if k.HostHeader != nil {
u.HostHeader = kong.String(*k.HostHeader)
}
if k.Algorithm != nil {
u.Algorithm = kong.String(*k.Algorithm)
}
if k.Slots != nil {
u.Slots = kong.Int(*k.Slots)
}
if k.Healthchecks != nil {
u.Healthchecks = k.Healthchecks
}
if k.HashOn != nil {
u.HashOn = kong.String(*k.HashOn)
}
if k.HashFallback != nil {
u.HashFallback = kong.String(*k.HashFallback)
}
if k.HashOnHeader != nil {
u.HashOnHeader = kong.String(*k.HashOnHeader)
}
if k.HashFallbackHeader != nil {
u.HashFallbackHeader = kong.String(*k.HashFallbackHeader)
}
if k.HashOnCookie != nil {
u.HashOnCookie = kong.String(*k.HashOnCookie)
}
if k.HashOnCookiePath != nil {
u.HashOnCookiePath = kong.String(*k.HashOnCookiePath)
}
if k.HashOnQueryArg != nil {
u.HashOnQueryArg = kong.String(*k.HashOnQueryArg)
}
if k.HashFallbackQueryArg != nil {
u.HashFallbackQueryArg = kong.String(*k.HashFallbackQueryArg)
}
if k.HashOnURICapture != nil {
u.HashOnURICapture = kong.String(*k.HashOnURICapture)
}
if k.HashFallbackURICapture != nil {
u.HashFallbackURICapture = kong.String(*k.HashFallbackURICapture)
}
}

// override sets Upstream fields by KongIngress first, then by k8s Service's annotations.
func (u *Upstream) override(
kongIngress *kongv1.KongIngress,
svc *corev1.Service,
) {
if u == nil {
if u == nil || svc == nil {
return
}

if u.Service.Parent != nil && kongIngress != nil {
// If the parent object behind Kong Upstream's is a Gateway API object
// (probably *Route) then check if we're trying to override said Service
// configuration with a KongIngress object and if that's the case then
// skip it since those should not be affected.
gvk := u.Service.Parent.GetObjectKind().GroupVersionKind()
if gvk.Group == gatewayv1alpha2.GroupName {
// No log needed here as there will be one issued already from Kong's
// Service override. The reason for this is that there is no other
// object in Kubernetes that creates a Kong's Upstream and Kubernetes
// Service will already trigger Kong's Service creation and log issuance.
return
}
}

u.overrideByKongIngress(kongIngress)
if svc != nil {
u.overrideByAnnotation(svc.Annotations)
}
u.overrideByAnnotation(svc.Annotations)
}
58 changes: 13 additions & 45 deletions internal/dataplane/kongstate/upstream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,20 @@ import (
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

kongv1 "github.com/kong/kubernetes-ingress-controller/v3/pkg/apis/configuration/v1"
)

func TestOverrideUpstream(t *testing.T) {
assert := assert.New(t)

testTable := []struct {
inUpstream Upstream
inKongIngresss *kongv1.KongIngress
outUpstream Upstream
svc *corev1.Service
inUpstream Upstream
outUpstream Upstream
svc *corev1.Service
}{
{
inUpstream: Upstream{
Upstream: kong.Upstream{
Name: kong.String("foo.com"),
},
},
inKongIngresss: nil,
outUpstream: Upstream{
Upstream: kong.Upstream{
Name: kong.String("foo.com"),
Expand All @@ -39,55 +33,29 @@ func TestOverrideUpstream(t *testing.T) {
Name: kong.String("foo.com"),
},
},
inKongIngresss: &kongv1.KongIngress{
Upstream: &kongv1.KongIngressUpstream{
HashOn: kong.String("HashOn"),
HashOnCookie: kong.String("HashOnCookie"),
HashOnCookiePath: kong.String("HashOnCookiePath"),
HashOnHeader: kong.String("HashOnHeader"),
HashFallback: kong.String("HashFallback"),
HashFallbackHeader: kong.String("HashFallbackHeader"),
HashOnQueryArg: kong.String("HashOnQueryArg"),
HashFallbackQueryArg: kong.String("HashFallbackQueryArg"),
HashOnURICapture: kong.String("HashOnURICapture"),
HashFallbackURICapture: kong.String("HashFallbackURICapture"),
Slots: kong.Int(42),
},
},
outUpstream: Upstream{
Upstream: kong.Upstream{
Name: kong.String("foo.com"),
HashOn: kong.String("HashOn"),
HashOnCookie: kong.String("HashOnCookie"),
HashOnCookiePath: kong.String("HashOnCookiePath"),
HashOnHeader: kong.String("HashOnHeader"),
HashFallback: kong.String("HashFallback"),
HashFallbackHeader: kong.String("HashFallbackHeader"),
HostHeader: kong.String("foo.com"),
HashOnQueryArg: kong.String("HashOnQueryArg"),
HashFallbackQueryArg: kong.String("HashFallbackQueryArg"),
HashOnURICapture: kong.String("HashOnURICapture"),
HashFallbackURICapture: kong.String("HashFallbackURICapture"),
Slots: kong.Int(42),
},
},
svc: &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
"konghq.com/host-header": "foo.com",
},
},
},
outUpstream: Upstream{
Upstream: kong.Upstream{
Name: kong.String("foo.com"),
HostHeader: kong.String("foo.com"),
},
},
},
}

for _, testcase := range testTable {
testcase.inUpstream.override(testcase.inKongIngresss, testcase.svc)
assert.Equal(testcase.inUpstream, testcase.outUpstream)
testcase.inUpstream.override(testcase.svc)
assert.Equal(t, testcase.inUpstream, testcase.outUpstream)
}

assert.NotPanics(func() {
assert.NotPanics(t, func() {
var nilUpstream *Upstream
nilUpstream.override(nil, nil)
nilUpstream.override(nil)
})
}
63 changes: 0 additions & 63 deletions internal/dataplane/kongstate/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,74 +10,11 @@ import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"sigs.k8s.io/yaml"

"github.com/kong/kubernetes-ingress-controller/v3/internal/annotations"
"github.com/kong/kubernetes-ingress-controller/v3/internal/store"
"github.com/kong/kubernetes-ingress-controller/v3/internal/util"
kongv1 "github.com/kong/kubernetes-ingress-controller/v3/pkg/apis/configuration/v1"
)

func getKongIngressForServices(
s store.Storer,
services map[string]*corev1.Service,
) (*kongv1.KongIngress, error) {
// loop through each service and retrieve the attached KongIngress resources.
// there can only be one KongIngress for a group of services: either one of
// them is configured with a KongIngress and this configures the Kong Service
// or Upstream OR all of them can be configured but they must be configured
// with the same KongIngress.
for _, svc := range services {
// check if the service is even configured with a KongIngress
confName := annotations.ExtractConfigurationName(svc.Annotations)
if confName == "" {
continue // some other service in the group may yet have a KongIngress attachment
}

// retrieve the attached KongIngress for the service
kongIngress, err := s.GetKongIngress(svc.Namespace, confName)
if err != nil {
return nil, err
}

// we found the KongIngress for these services. We don't have to check any
// further services as validation is expected to ensure all these Services
// already are annotated with the exact same overrides.
return kongIngress, nil
}

// there are no KongIngress resources for these services.
return nil, nil
}

func getKongIngressFromObjectMeta(
s store.Storer,
obj util.K8sObjectInfo,
) (
*kongv1.KongIngress, error,
) {
return getKongIngressFromObjAnnotations(s, obj)
}

func getKongIngressFromObjAnnotations(
s store.Storer,
obj util.K8sObjectInfo,
) (
*kongv1.KongIngress, error,
) {
confName := annotations.ExtractConfigurationName(obj.Annotations)
if confName != "" {
ki, err := s.GetKongIngress(obj.Namespace, confName)
if err == nil {
return ki, nil
}
}

ki, err := s.GetKongIngress(obj.Namespace, obj.Name)
if err == nil {
return ki, nil
}
return nil, nil
}

// getKongPluginOrKongClusterPlugin fetches a KongPlugin or KongClusterPlugin (as fallback) from the store.
// If both are not found, an error is returned.
func getKongPluginOrKongClusterPlugin(s store.Storer, namespace, name string) (
Expand Down
Loading

0 comments on commit d730bb1

Please sign in to comment.