generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
385 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
Copyright 2024 The Kubernetes 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. | ||
*/ | ||
|
||
package gce | ||
|
||
const ( | ||
gceIngressClass = "gce" | ||
gceL7ILBIngressClass = "gce-internal" | ||
|
||
gceL7GlobalExternalManagedGatewayClass = "gke-l7-global-external-managed" | ||
gceL7RegionalInternalGatewayClass = "gke-l7-rilb" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/* | ||
Copyright 2024 The Kubernetes 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. | ||
*/ | ||
|
||
package gce | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/kubernetes-sigs/ingress2gateway/pkg/i2gw" | ||
"github.com/kubernetes-sigs/ingress2gateway/pkg/i2gw/providers/common" | ||
networkingv1 "k8s.io/api/networking/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/apimachinery/pkg/util/validation/field" | ||
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" | ||
) | ||
|
||
// isSupportedGCEIngressClass verifies if the given ingress is supported by | ||
// GCE. | ||
// `kubernetes.io/ingress.class` annotation is still used by GCE to specify the | ||
// type of ingresses. | ||
// If the value of this annotation is one of the supported values(`gce` or | ||
// `gce-internal`), `ingressClassName` is ignored by GKE Ingress controller. | ||
// If the annotation is not set, the GKE Ingress controller will only process | ||
// the ingress if its ingressClassName is one of the supported values(`gce` or | ||
// `gce-internal`) or empty. | ||
func isSupportedGCEIngressClass(ingress networkingv1.Ingress) bool { | ||
legacyIngressClass := common.GetIngressClass(ingress) | ||
if legacyIngressClass != "" { | ||
return legacyIngressClass == gceIngressClass || legacyIngressClass == gceL7ILBIngressClass | ||
} | ||
if ingress.Spec.IngressClassName == nil { | ||
return true | ||
} | ||
ingressClass := *ingress.Spec.IngressClassName | ||
return ingressClass == gceIngressClass || ingressClass == gceL7ILBIngressClass | ||
} | ||
|
||
// toGceGatewayClass updates the Gateway to use GCE GatewayClass. | ||
func toGceGatewayClass(ingresses []networkingv1.Ingress, gatewayResources *i2gw.GatewayResources) field.ErrorList { | ||
var errs field.ErrorList | ||
|
||
// Since we already validated ingress resources when reading, there are | ||
// only two cases here: | ||
// 1. `kubernetes.io/ingress.class` exists in ingress anntation. In this | ||
// case, we use it to map to the corresponding gateway class. | ||
// 2. Annotation does not exist. In this case, the ingress is defaulted | ||
// to use the GCE external ingress implementation, and should be | ||
// mapped to `gke-l7-gxlb`. | ||
for _, ingress := range ingresses { | ||
gwKey := types.NamespacedName{Namespace: ingress.Namespace, Name: common.GetIngressClass(ingress)} | ||
existingGateway := gatewayResources.Gateways[gwKey] | ||
|
||
newGateway, err := setGCEGatewayClass(ingress, existingGateway) | ||
if err != nil { | ||
errs = append(errs, err) | ||
} | ||
gatewayResources.Gateways[gwKey] = newGateway | ||
} | ||
if len(errs) > 0 { | ||
return errs | ||
} | ||
return nil | ||
} | ||
|
||
// setGCEGatewayClass sets the Gateway to the corresponding GCE GatewayClass. | ||
func setGCEGatewayClass(ingress networkingv1.Ingress, gateway gatewayv1.Gateway) (gatewayv1.Gateway, *field.Error) { | ||
ingressClass := common.GetIngressClass(ingress) | ||
|
||
ingressName := fmt.Sprintf("%s/%s", ingress.Namespace, ingress.Name) | ||
// Get GCE GatewayClass from from GCE Ingress class. | ||
newGatewayClass, err := ingClassToGwyClassGCE(ingressClass) | ||
if err != nil { | ||
return gateway, field.NotSupported(field.NewPath(ingressName).Child("ObjectMeta", "Annotations", "kubernetes.io/ingress.class"), ingressClass, []string{gceIngressClass, gceL7ILBIngressClass}) | ||
} | ||
gateway.Spec.GatewayClassName = gatewayv1.ObjectName(newGatewayClass) | ||
return gateway, nil | ||
} | ||
|
||
// ingClassToGwyClassGCE returns the corresponding GCE Gateway Class based on the | ||
// given GCE ingress class. | ||
func ingClassToGwyClassGCE(ingressClass string) (string, error) { | ||
switch ingressClass { | ||
case gceIngressClass: | ||
return gceL7GlobalExternalManagedGatewayClass, nil | ||
case gceL7ILBIngressClass: | ||
return gceL7RegionalInternalGatewayClass, nil | ||
case "": | ||
return gceL7GlobalExternalManagedGatewayClass, nil | ||
default: | ||
return "", fmt.Errorf("Given GCE Ingress Class not supported") | ||
} | ||
} | ||
|
||
// checkImplementationSpecificPath checks if this ingress contains a | ||
// ImplementationSpecific path with * and throws an error if it does. | ||
func checkImplementationSpecificPath(ingress *networkingv1.Ingress) *field.Error { | ||
for _, rule := range ingress.Spec.Rules { | ||
for _, path := range rule.HTTP.Paths { | ||
if path.PathType != nil && *path.PathType == networkingv1.PathTypeImplementationSpecific && strings.HasSuffix(path.Path, "/*") { | ||
ingressName := fmt.Sprintf("%s/%s", ingress.Namespace, ingress.Name) | ||
detail := "ImplementationSpecific Path with * is not supported for GCE ingress2gateway conversion" | ||
return field.Invalid(field.NewPath(ingressName).Child("Spec", "Rules", "HTTP", "Paths", "Path"), path.Path, detail) | ||
} | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.