diff --git a/docs/gitbook/tutorials/gloo-progressive-delivery.md b/docs/gitbook/tutorials/gloo-progressive-delivery.md index a661f0a12..f32ed976a 100644 --- a/docs/gitbook/tutorials/gloo-progressive-delivery.md +++ b/docs/gitbook/tutorials/gloo-progressive-delivery.md @@ -160,6 +160,8 @@ spec: cmd: "hey -z 2m -q 5 -c 2 -host app.example.com http://gateway-proxy.gloo-system" ``` +*Note: when using upstreamRef the following fields are copied over from the original upstream: `Labels, SslConfig, CircuitBreakers, ConnectionConfig, UseHttp2, InitialStreamWindowSize`* + Save the above resource as podinfo-canary.yaml and then apply it: ```bash diff --git a/pkg/apis/gloo/gloo/v1/types.go b/pkg/apis/gloo/gloo/v1/types.go index 7348f338d..e37ba5d55 100644 --- a/pkg/apis/gloo/gloo/v1/types.go +++ b/pkg/apis/gloo/gloo/v1/types.go @@ -18,6 +18,7 @@ type Upstream struct { type UpstreamSpec struct { Kube *KubeUpstream `json:"kube,omitempty"` + Labels map[string]string `json:"labels,omitempty"` SslConfig *UpstreamSslConfig `json:"sslConfig,omitempty"` CircuitBreakers *CircuitBreakerConfig `json:"circuitBreakers,omitempty"` ConnectionConfig *ConnectionConfig `json:"connectionConfig,omitempty"` diff --git a/pkg/apis/gloo/gloo/v1/zz_generated.deepcopy.go b/pkg/apis/gloo/gloo/v1/zz_generated.deepcopy.go index edf426224..0b305b255 100644 --- a/pkg/apis/gloo/gloo/v1/zz_generated.deepcopy.go +++ b/pkg/apis/gloo/gloo/v1/zz_generated.deepcopy.go @@ -294,6 +294,13 @@ func (in *UpstreamSpec) DeepCopyInto(out *UpstreamSpec) { *out = new(KubeUpstream) (*in).DeepCopyInto(*out) } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.SslConfig != nil { in, out := &in.SslConfig, &out.SslConfig *out = new(UpstreamSslConfig) diff --git a/pkg/router/gloo.go b/pkg/router/gloo.go index e5dc9bcd4..823a16b50 100644 --- a/pkg/router/gloo.go +++ b/pkg/router/gloo.go @@ -38,10 +38,11 @@ import ( // GlooRouter is managing Gloo route tables type GlooRouter struct { - kubeClient kubernetes.Interface - glooClient clientset.Interface - flaggerClient clientset.Interface - logger *zap.SugaredLogger + kubeClient kubernetes.Interface + glooClient clientset.Interface + flaggerClient clientset.Interface + logger *zap.SugaredLogger + includeLabelPrefix []string } // Reconcile creates or updates the Gloo Edge route table @@ -276,6 +277,7 @@ func (gr *GlooRouter) getGlooUpstreamKubeService(canary *flaggerv1.Canary, svc * if glooUpstreamWithConfig != nil { configSpec := glooUpstreamWithConfig.Spec upstreamSpec = gloov1.UpstreamSpec{ + Labels: configSpec.Labels, SslConfig: configSpec.SslConfig, CircuitBreakers: configSpec.CircuitBreakers, ConnectionConfig: configSpec.ConnectionConfig, @@ -293,10 +295,13 @@ func (gr *GlooRouter) getGlooUpstreamKubeService(canary *flaggerv1.Canary, svc * Selector: svc.Spec.Selector, } + upstreamLabels := includeLabelsByPrefix(upstreamSpec.Labels, gr.includeLabelPrefix) + return &gloov1.Upstream{ ObjectMeta: metav1.ObjectMeta{ Name: upstreamName, Namespace: canary.Namespace, + Labels: upstreamLabels, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(canary, schema.GroupVersionKind{ Group: flaggerv1.SchemeGroupVersion.Group, diff --git a/pkg/router/util.go b/pkg/router/util.go new file mode 100644 index 000000000..e2bb04ee3 --- /dev/null +++ b/pkg/router/util.go @@ -0,0 +1,19 @@ +package router + +import ( + "strings" +) + +func includeLabelsByPrefix(labels map[string]string, includeLabelPrefixes []string) map[string]string { + filteredLabels := make(map[string]string) + for key, value := range labels { + for _, includeLabelPrefix := range includeLabelPrefixes { + if includeLabelPrefix == "*" || strings.HasPrefix(key, includeLabelPrefix) { + filteredLabels[key] = value + break + } + } + } + + return filteredLabels +} diff --git a/pkg/router/util_test.go b/pkg/router/util_test.go new file mode 100644 index 000000000..2069810ee --- /dev/null +++ b/pkg/router/util_test.go @@ -0,0 +1,57 @@ +/* +Copyright 2020 The Flux 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 router + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIncludeLabelsByPrefix(t *testing.T) { + labels := map[string]string{ + "foo": "foo-value", + "bar": "bar-value", + "lorem": "ipsum", + } + includeLabelPrefix := []string{"foo", "lor"} + + filteredLabels := includeLabelsByPrefix(labels, includeLabelPrefix) + + assert.Equal(t, filteredLabels, map[string]string{ + "foo": "foo-value", + "lorem": "ipsum", + // bar excluded + }) +} + +func TestIncludeLabelsByPrefixWithWildcard(t *testing.T) { + labels := map[string]string{ + "foo": "foo-value", + "bar": "bar-value", + "lorem": "ipsum", + } + includeLabelPrefix := []string{"*"} + + filteredLabels := includeLabelsByPrefix(labels, includeLabelPrefix) + + assert.Equal(t, filteredLabels, map[string]string{ + "foo": "foo-value", + "bar": "bar-value", + "lorem": "ipsum", + }) +}