Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Gateway Selection using Ingress Labels #1250

Merged
merged 5 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
go.uber.org/zap v1.27.0
golang.org/x/sync v0.6.0
google.golang.org/protobuf v1.33.0
gopkg.in/yaml.v3 v3.0.1
istio.io/api v1.20.2
istio.io/client-go v1.20.2
k8s.io/api v0.29.2
Expand All @@ -16,6 +15,7 @@ require (
knative.dev/hack v0.0.0-20240318013248-424e75ed769a
knative.dev/networking v0.0.0-20240326200906-419ebf9a1d87
knative.dev/pkg v0.0.0-20240325103648-fd7cc2153e6a
sigs.k8s.io/yaml v1.4.0
)

require (
Expand Down Expand Up @@ -83,6 +83,7 @@ require (
google.golang.org/grpc v1.62.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.29.2 // indirect
k8s.io/code-generator v0.29.2 // indirect
k8s.io/gengo v0.0.0-20240129211411-f967bbeff4b4 // indirect
Expand All @@ -91,5 +92,4 @@ require (
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
66 changes: 53 additions & 13 deletions pkg/reconciler/ingress/config/istio.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import (
"sort"
"strings"

"gopkg.in/yaml.v3"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation"
"knative.dev/pkg/network"
"knative.dev/pkg/system"
"sigs.k8s.io/yaml"
)

const (
Expand Down Expand Up @@ -76,9 +77,10 @@ func defaultLocalGateways() []Gateway {

// Gateway specifies the name of the Gateway and the K8s Service backing it.
type Gateway struct {
Namespace string
Name string
ServiceURL string `yaml:"service"`
Namespace string
Name string
ServiceURL string `json:"service"`
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
}

// QualifiedName returns gateway name in '{namespace}/{name}' format.
Expand All @@ -103,35 +105,63 @@ func (g Gateway) Validate() error {
return fmt.Errorf("invalid gateway service format: %v", errs)
}

if _, err := metav1.LabelSelectorAsSelector(g.LabelSelector); err != nil {
return fmt.Errorf("failed to create selector from label selector: %w", err)
}

return nil
}

// Istio contains istio related configuration defined in the
// istio config map.
type Istio struct {
// IngressGateway specifies the gateway urls for public Ingress.
// IngressGateways specifies the gateway urls for public Ingress.
IngressGateways []Gateway

// LocalGateway specifies the gateway urls for public & private Ingress.
// LocalGateways specifies the gateway urls for public & private Ingress.
LocalGateways []Gateway
}

func (i Istio) Validate() error {
for _, gtw := range i.IngressGateways {
if err := gtw.Validate(); err != nil {
return fmt.Errorf("invalid gateway: %w", err)
return fmt.Errorf("invalid gateway %s: %w", gtw.QualifiedName(), err)
}
}

for _, gtw := range i.LocalGateways {
if err := gtw.Validate(); err != nil {
return fmt.Errorf("invalid local gateway: %w", err)
return fmt.Errorf("invalid local gateway %s: %w", gtw.QualifiedName(), err)
}
}

return nil
}

// DefaultExternalGateways returns the external gateway without any label selector
func (i Istio) DefaultExternalGateways() []Gateway {
pastequo marked this conversation as resolved.
Show resolved Hide resolved
return defaultGateways(i.IngressGateways)
}

// DefaultLocalGateways returns the local gateway without any label selector
func (i Istio) DefaultLocalGateways() []Gateway {
return defaultGateways(i.LocalGateways)
}

func defaultGateways(gtws []Gateway) []Gateway {
ret := make([]Gateway, 0)

for _, gtw := range gtws {
gateway := gtw

if gtw.LabelSelector == nil {
ret = append(ret, gateway)
}
}

return ret
}

// NewIstioFromConfigMap creates an Istio config from the supplied ConfigMap
func NewIstioFromConfigMap(configMap *corev1.ConfigMap) (*Istio, error) {
ret := &Istio{}
Expand All @@ -153,10 +183,10 @@ func NewIstioFromConfigMap(configMap *corev1.ConfigMap) (*Istio, error) {
}
case oldFormatDefined:
ret = parseOldFormat(configMap)
default:
defaultValues(ret)
}

defaultValues(ret)

err = ret.Validate()
if err != nil {
return nil, fmt.Errorf("invalid configuration: %w", err)
Expand Down Expand Up @@ -207,8 +237,14 @@ func parseNewFormat(configMap *corev1.ConfigMap) (*Istio, error) {
ret.LocalGateways = localGateways
}

if len(ret.LocalGateways) > 1 {
dprotaso marked this conversation as resolved.
Show resolved Hide resolved
return ret, fmt.Errorf("only one local gateway can be defined: current %q value is %q", localGatewaysKey, localGatewaysStr)
defaultValues(ret)

if len(ret.DefaultExternalGateways()) != 1 {
return ret, fmt.Errorf("exactly one external gateway with no selector can be defined, here: %v", ret.DefaultExternalGateways())
}

if len(ret.DefaultLocalGateways()) != 1 {
return ret, fmt.Errorf("exactly one local gateway with no selector can be defined, here: %v", ret.DefaultLocalGateways())
}

return ret, nil
Expand All @@ -226,10 +262,14 @@ func parseNewFormatGateways(data string) ([]Gateway, error) {
}

func parseOldFormat(configMap *corev1.ConfigMap) *Istio {
return &Istio{
ret := &Istio{
IngressGateways: parseOldFormatGateways(configMap, gatewayKeyPrefix),
LocalGateways: parseOldFormatGateways(configMap, localGatewayKeyPrefix),
}

defaultValues(ret)

return ret
}

func parseOldFormatGateways(configMap *corev1.ConfigMap, prefix string) []Gateway {
Expand Down
Loading
Loading