diff --git a/config/300-serving-v1alpha1-knativeserving-crd.yaml b/config/300-serving-v1alpha1-knativeserving-crd.yaml index d5365653..53572f79 100644 --- a/config/300-serving-v1alpha1-knativeserving-crd.yaml +++ b/config/300-serving-v1alpha1-knativeserving-crd.yaml @@ -58,6 +58,108 @@ spec: type: object additionalProperties: type: string + servers: + description: A list of server specifications. + items: + properties: + bind: + format: string + type: string + defaultEndpoint: + format: string + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + format: string + type: string + type: array + port: + properties: + name: + description: Label assigned to the port. + format: string + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + format: string + type: string + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL`. + format: string + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + format: string + type: string + type: array + credentialName: + format: string + type: string + httpsRedirect: + type: boolean + maxProtocolVersion: + description: 'Optional: Maximum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: 'Optional: Minimum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + format: string + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + format: string + type: string + subjectAltNames: + items: + format: string + type: string + type: array + verifyCertificateHash: + items: + format: string + type: string + type: array + verifyCertificateSpki: + items: + format: string + type: string + type: array + type: object + type: object + type: array cluster-local-gateway: description: A means to override the cluster-local-gateway type: object diff --git a/pkg/apis/serving/v1alpha1/knativeserving_types.go b/pkg/apis/serving/v1alpha1/knativeserving_types.go index 80065546..17003f7c 100644 --- a/pkg/apis/serving/v1alpha1/knativeserving_types.go +++ b/pkg/apis/serving/v1alpha1/knativeserving_types.go @@ -16,6 +16,7 @@ limitations under the License. package v1alpha1 import ( + istiov1alpha3 "istio.io/api/networking/v1alpha3" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" @@ -56,6 +57,8 @@ type Registry struct { type IstioGatewayOverride struct { // A map of values to replace the "selector" values in the knative-ingress-gateway and cluster-local-gateway Selector map[string]string `json:"selector,omitempty"` + // A list of server specifications. + Servers []istiov1alpha3.Server `json:"servers,omitempty"` } // CustomCerts refers to either a ConfigMap or Secret containing valid diff --git a/pkg/reconciler/knativeserving/common/gateway.go b/pkg/reconciler/knativeserving/common/gateway.go index 8c9a8ced..68cb2ec2 100644 --- a/pkg/reconciler/knativeserving/common/gateway.go +++ b/pkg/reconciler/knativeserving/common/gateway.go @@ -1,9 +1,26 @@ package common +/* +Copyright 2020 The Knative 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. +*/ + import ( + "fmt" + mf "github.com/jcrossley3/manifestival" "go.uber.org/zap" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" servingv1alpha1 "knative.dev/serving-operator/pkg/apis/serving/v1alpha1" ) @@ -24,9 +41,24 @@ func GatewayTransform(instance *servingv1alpha1.KnativeServing, log *zap.Sugared func updateKnativeIngressGateway(gatewayOverrides servingv1alpha1.IstioGatewayOverride, u *unstructured.Unstructured) error { if len(gatewayOverrides.Selector) > 0 { - log.Debugw("Updating Gateway", "name", u.GetName(), "gatewayOverrides", gatewayOverrides) + log.Debugw("Updating Selector Section for Gateway", "name", u.GetName(), "gatewayOverrides", gatewayOverrides) unstructured.SetNestedStringMap(u.Object, gatewayOverrides.Selector, "spec", "selector") - log.Debugw("Finished conversion", "name", u.GetName(), "unstructured", u.Object) + log.Debugw("Finished Selector Section conversion for Gateway", "name", u.GetName(), "unstructured", u.Object) + } + if len(gatewayOverrides.Servers) > 0 { + log.Debugw("Updating Servers section for Gateway", "name", u.GetName(), "gatewayOverrides", gatewayOverrides) + + newReferences := make([]interface{}, 0, len(gatewayOverrides.Servers)) + for _, reference := range gatewayOverrides.Servers { + out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&reference) + if err != nil { + utilruntime.HandleError(fmt.Errorf("unable to convert Server Reference: %v", err)) + continue + } + newReferences = append(newReferences, out) + } + unstructured.SetNestedSlice(u.Object, newReferences, "spec", "servers") + log.Debugw("Finished Servers Section conversion for Gateway", "name", u.GetName(), "unstructured", u.Object) } return nil } diff --git a/pkg/reconciler/knativeserving/common/gateway_test.go b/pkg/reconciler/knativeserving/common/gateway_test.go index 8509adc9..3b18d0f9 100644 --- a/pkg/reconciler/knativeserving/common/gateway_test.go +++ b/pkg/reconciler/knativeserving/common/gateway_test.go @@ -37,6 +37,7 @@ type updateGatewayTest struct { knativeIngressGateway servingv1alpha1.IstioGatewayOverride clusterLocalGateway servingv1alpha1.IstioGatewayOverride expected map[string]string + expectedServers []istiov1alpha3.Server } var updateGatewayTests = []updateGatewayTest{ @@ -60,6 +61,83 @@ var updateGatewayTests = []updateGatewayTest{ "istio": "knative-ingress", }, }, + { + name: "UpdatesKnativeIngressGatewayTlsNoSelector", + gatewayName: "knative-ingress-gateway", + in: map[string]string{ + "istio": "old-istio", + }, + knativeIngressGateway: servingv1alpha1.IstioGatewayOverride{ + Servers: []istiov1alpha3.Server{ + { + Hosts: []string{"*"}, + Port: &istiov1alpha3.Port{ + Name: "https", + Number: 443, + Protocol: "HTTPS", + }, + }, + }, + }, + clusterLocalGateway: servingv1alpha1.IstioGatewayOverride{ + Selector: map[string]string{ + "istio": "cluster-local", + }, + }, + expected: map[string]string{ + "istio": "old-istio", + }, + expectedServers: []istiov1alpha3.Server{ + { + Hosts: []string{"*"}, + Port: &istiov1alpha3.Port{ + Name: "https", + Number: 443, + Protocol: "HTTPS", + }, + }, + }, + }, + { + name: "UpdatesKnativeIngressGatewayTls", + gatewayName: "knative-ingress-gateway", + in: map[string]string{ + "istio": "old-istio", + }, + knativeIngressGateway: servingv1alpha1.IstioGatewayOverride{ + Selector: map[string]string{ + "istio": "knative-ingress", + }, + Servers: []istiov1alpha3.Server{ + { + Hosts: []string{"*"}, + Port: &istiov1alpha3.Port{ + Name: "https", + Number: 443, + Protocol: "HTTPS", + }, + }, + }, + }, + clusterLocalGateway: servingv1alpha1.IstioGatewayOverride{ + Selector: map[string]string{ + "istio": "cluster-local", + }, + }, + expected: map[string]string{ + "istio": "knative-ingress", + }, + expectedServers: []istiov1alpha3.Server{ + { + Hosts: []string{"*"}, + Port: &istiov1alpha3.Port{ + Name: "https", + Number: 443, + Protocol: "HTTPS", + }, + }, + }, + }, { name: "UpdatesClusterLocalGateway", gatewayName: "cluster-local-gateway", @@ -129,6 +207,13 @@ func validateUnstructedGatewayChanged(t *testing.T, tt *updateGatewayTest, u *un for expectedKey, expectedValue := range tt.expected { assertEqual(t, gateway.Spec.Selector[expectedKey], expectedValue) } + if len(tt.expectedServers) > 0 { + assertEqual(t, len(tt.expectedServers), len(gateway.Spec.Servers)) + for index := range tt.expectedServers { + expectedServer := &tt.expectedServers[index] + assertDeepEqual(t, gateway.Spec.Servers[index], expectedServer) + } + } } func makeUnstructuredGateway(t *testing.T, tt *updateGatewayTest) unstructured.Unstructured {