Merge pull request #894 from saiskee/create-non-discovered-gloo-upstreams

Gloo: Create gloo upstreams from non-discovered services
This commit is contained in:
Stefan Prodan
2021-05-11 18:42:20 +03:00
committed by GitHub
45 changed files with 1268 additions and 138 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ $ helm upgrade -i flagger flagger/flagger \
--set prometheus.install=true
```
To install Flagger and Prometheus for **Gloo** (requires Gloo discovery enabled):
To install Flagger and Prometheus for **Gloo** (no longer requires Gloo discovery):
```console
$ helm upgrade -i flagger flagger/flagger \
@@ -174,6 +174,8 @@ service/podinfo
service/podinfo-canary
service/podinfo-primary
routetables.gateway.solo.io/podinfo
upstreams.gloo.solo.io/test-podinfo-canaryupstream-9898
upstreams.gloo.solo.io/test-podinfo-primaryupstream-9898
```
When the bootstrap finishes Flagger will set the canary status to initialized:
+1 -1
View File
@@ -30,7 +30,7 @@ chmod +x ${CODEGEN_PKG}/generate-groups.sh
${CODEGEN_PKG}/generate-groups.sh all \
github.com/fluxcd/flagger/pkg/client github.com/fluxcd/flagger/pkg/apis \
"flagger:v1beta1 appmesh:v1beta2 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 smi:v1alpha2 smi:v1alpha3 gloo:v1 projectcontour:v1 traefik:v1alpha1" \
"flagger:v1beta1 appmesh:v1beta2 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 smi:v1alpha2 smi:v1alpha3 gloo/gloo:v1 gloo/gateway:v1 projectcontour:v1 traefik:v1alpha1" \
--output-base "${TEMP_DIR}" \
--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
@@ -8,7 +8,7 @@ import (
)
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: gloo.GroupName, Version: "v1"}
var SchemeGroupVersion = schema.GroupVersion{Group: gloo.GatewayGroupName, Version: "v1"}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
+5
View File
@@ -0,0 +1,5 @@
// +k8s:deepcopy-gen=package
// Package v1 is the v1 version of the API.
// +groupName=gloo.solo.io
package v1
+36
View File
@@ -0,0 +1,36 @@
package v1
import (
"github.com/fluxcd/flagger/pkg/apis/gloo"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: gloo.GlooGroupName, Version: "v1"}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Upstream{},
&UpstreamList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
+37
View File
@@ -0,0 +1,37 @@
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Upstream is a specification for a Gloo Upstream resource
type Upstream struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec UpstreamSpec `json:"spec"`
}
type UpstreamSpec struct {
Kube KubeUpstream `json:"kube,omitempty"`
}
type KubeUpstream struct {
ServiceName string `json:"service_name,omitempty"`
ServiceNamespace string `json:"service_namespace,omitempty"`
ServicePort int32 `json:"service_port,omitempty"`
Selector map[string]string `json:"selector,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// UpstreamList is a list of Upstream resources
type UpstreamList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []Upstream `json:"items"`
}
@@ -0,0 +1,125 @@
// +build !ignore_autogenerated
/*
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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubeUpstream) DeepCopyInto(out *KubeUpstream) {
*out = *in
if in.Selector != nil {
in, out := &in.Selector, &out.Selector
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeUpstream.
func (in *KubeUpstream) DeepCopy() *KubeUpstream {
if in == nil {
return nil
}
out := new(KubeUpstream)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Upstream) DeepCopyInto(out *Upstream) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Upstream.
func (in *Upstream) DeepCopy() *Upstream {
if in == nil {
return nil
}
out := new(Upstream)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Upstream) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *UpstreamList) DeepCopyInto(out *UpstreamList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Upstream, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamList.
func (in *UpstreamList) DeepCopy() *UpstreamList {
if in == nil {
return nil
}
out := new(UpstreamList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *UpstreamList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *UpstreamSpec) DeepCopyInto(out *UpstreamSpec) {
*out = *in
in.Kube.DeepCopyInto(&out.Kube)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamSpec.
func (in *UpstreamSpec) DeepCopy() *UpstreamSpec {
if in == nil {
return nil
}
out := new(UpstreamSpec)
in.DeepCopyInto(out)
return out
}
+2 -1
View File
@@ -1,5 +1,6 @@
package gloo
const (
GroupName = "gateway.solo.io"
GlooGroupName = "gloo.solo.io"
GatewayGroupName = "gateway.solo.io"
)
+15 -1
View File
@@ -24,7 +24,8 @@ import (
appmeshv1beta1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1"
appmeshv1beta2 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2"
flaggerv1beta1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
gatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gateway/v1"
gloov1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
networkingv1alpha3 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3"
projectcontourv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/projectcontour/v1"
splitv1alpha1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/smi/v1alpha1"
@@ -42,6 +43,7 @@ type Interface interface {
AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface
FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface
GatewayV1() gatewayv1.GatewayV1Interface
GlooV1() gloov1.GlooV1Interface
NetworkingV1alpha3() networkingv1alpha3.NetworkingV1alpha3Interface
ProjectcontourV1() projectcontourv1.ProjectcontourV1Interface
SplitV1alpha1() splitv1alpha1.SplitV1alpha1Interface
@@ -58,6 +60,7 @@ type Clientset struct {
appmeshV1beta1 *appmeshv1beta1.AppmeshV1beta1Client
flaggerV1beta1 *flaggerv1beta1.FlaggerV1beta1Client
gatewayV1 *gatewayv1.GatewayV1Client
glooV1 *gloov1.GlooV1Client
networkingV1alpha3 *networkingv1alpha3.NetworkingV1alpha3Client
projectcontourV1 *projectcontourv1.ProjectcontourV1Client
splitV1alpha1 *splitv1alpha1.SplitV1alpha1Client
@@ -86,6 +89,11 @@ func (c *Clientset) GatewayV1() gatewayv1.GatewayV1Interface {
return c.gatewayV1
}
// GlooV1 retrieves the GlooV1Client
func (c *Clientset) GlooV1() gloov1.GlooV1Interface {
return c.glooV1
}
// NetworkingV1alpha3 retrieves the NetworkingV1alpha3Client
func (c *Clientset) NetworkingV1alpha3() networkingv1alpha3.NetworkingV1alpha3Interface {
return c.networkingV1alpha3
@@ -153,6 +161,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
if err != nil {
return nil, err
}
cs.glooV1, err = gloov1.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
}
cs.networkingV1alpha3, err = networkingv1alpha3.NewForConfig(&configShallowCopy)
if err != nil {
return nil, err
@@ -193,6 +205,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
cs.appmeshV1beta1 = appmeshv1beta1.NewForConfigOrDie(c)
cs.flaggerV1beta1 = flaggerv1beta1.NewForConfigOrDie(c)
cs.gatewayV1 = gatewayv1.NewForConfigOrDie(c)
cs.glooV1 = gloov1.NewForConfigOrDie(c)
cs.networkingV1alpha3 = networkingv1alpha3.NewForConfigOrDie(c)
cs.projectcontourV1 = projectcontourv1.NewForConfigOrDie(c)
cs.splitV1alpha1 = splitv1alpha1.NewForConfigOrDie(c)
@@ -211,6 +224,7 @@ func New(c rest.Interface) *Clientset {
cs.appmeshV1beta1 = appmeshv1beta1.New(c)
cs.flaggerV1beta1 = flaggerv1beta1.New(c)
cs.gatewayV1 = gatewayv1.New(c)
cs.glooV1 = gloov1.New(c)
cs.networkingV1alpha3 = networkingv1alpha3.New(c)
cs.projectcontourV1 = projectcontourv1.New(c)
cs.splitV1alpha1 = splitv1alpha1.New(c)
@@ -26,8 +26,10 @@ import (
fakeappmeshv1beta2 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2/fake"
flaggerv1beta1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
fakeflaggerv1beta1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake"
gatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
fakegatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1/fake"
gatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gateway/v1"
fakegatewayv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gateway/v1/fake"
gloov1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
fakegloov1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1/fake"
networkingv1alpha3 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3"
fakenetworkingv1alpha3 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3/fake"
projectcontourv1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/projectcontour/v1"
@@ -114,6 +116,11 @@ func (c *Clientset) GatewayV1() gatewayv1.GatewayV1Interface {
return &fakegatewayv1.FakeGatewayV1{Fake: &c.Fake}
}
// GlooV1 retrieves the GlooV1Client
func (c *Clientset) GlooV1() gloov1.GlooV1Interface {
return &fakegloov1.FakeGlooV1{Fake: &c.Fake}
}
// NetworkingV1alpha3 retrieves the NetworkingV1alpha3Client
func (c *Clientset) NetworkingV1alpha3() networkingv1alpha3.NetworkingV1alpha3Interface {
return &fakenetworkingv1alpha3.FakeNetworkingV1alpha3{Fake: &c.Fake}
@@ -22,7 +22,8 @@ import (
appmeshv1beta1 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta1"
appmeshv1beta2 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta2"
flaggerv1beta1 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
networkingv1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
projectcontourv1 "github.com/fluxcd/flagger/pkg/apis/projectcontour/v1"
splitv1alpha1 "github.com/fluxcd/flagger/pkg/apis/smi/v1alpha1"
@@ -44,6 +45,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
appmeshv1beta1.AddToScheme,
flaggerv1beta1.AddToScheme,
gatewayv1.AddToScheme,
gloov1.AddToScheme,
networkingv1alpha3.AddToScheme,
projectcontourv1.AddToScheme,
splitv1alpha1.AddToScheme,
@@ -22,7 +22,8 @@ import (
appmeshv1beta1 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta1"
appmeshv1beta2 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta2"
flaggerv1beta1 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
networkingv1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
projectcontourv1 "github.com/fluxcd/flagger/pkg/apis/projectcontour/v1"
splitv1alpha1 "github.com/fluxcd/flagger/pkg/apis/smi/v1alpha1"
@@ -44,6 +45,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{
appmeshv1beta1.AddToScheme,
flaggerv1beta1.AddToScheme,
gatewayv1.AddToScheme,
gloov1.AddToScheme,
networkingv1alpha3.AddToScheme,
projectcontourv1.AddToScheme,
splitv1alpha1.AddToScheme,
@@ -0,0 +1,20 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated typed clients.
package v1
@@ -0,0 +1,20 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake
@@ -0,0 +1,40 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gateway/v1"
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
)
type FakeGatewayV1 struct {
*testing.Fake
}
func (c *FakeGatewayV1) RouteTables(namespace string) v1.RouteTableInterface {
return &FakeRouteTables{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeGatewayV1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}
@@ -21,7 +21,7 @@ package fake
import (
"context"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
@@ -41,20 +41,20 @@ var routetablesResource = schema.GroupVersionResource{Group: "gateway.solo.io",
var routetablesKind = schema.GroupVersionKind{Group: "gateway.solo.io", Version: "v1", Kind: "RouteTable"}
// Get takes name of the routeTable, and returns the corresponding routeTable object, and an error if there is any.
func (c *FakeRouteTables) Get(ctx context.Context, name string, options v1.GetOptions) (result *gloov1.RouteTable, err error) {
func (c *FakeRouteTables) Get(ctx context.Context, name string, options v1.GetOptions) (result *gatewayv1.RouteTable, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(routetablesResource, c.ns, name), &gloov1.RouteTable{})
Invokes(testing.NewGetAction(routetablesResource, c.ns, name), &gatewayv1.RouteTable{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.RouteTable), err
return obj.(*gatewayv1.RouteTable), err
}
// List takes label and field selectors, and returns the list of RouteTables that match those selectors.
func (c *FakeRouteTables) List(ctx context.Context, opts v1.ListOptions) (result *gloov1.RouteTableList, err error) {
func (c *FakeRouteTables) List(ctx context.Context, opts v1.ListOptions) (result *gatewayv1.RouteTableList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(routetablesResource, routetablesKind, c.ns, opts), &gloov1.RouteTableList{})
Invokes(testing.NewListAction(routetablesResource, routetablesKind, c.ns, opts), &gatewayv1.RouteTableList{})
if obj == nil {
return nil, err
@@ -64,8 +64,8 @@ func (c *FakeRouteTables) List(ctx context.Context, opts v1.ListOptions) (result
if label == nil {
label = labels.Everything()
}
list := &gloov1.RouteTableList{ListMeta: obj.(*gloov1.RouteTableList).ListMeta}
for _, item := range obj.(*gloov1.RouteTableList).Items {
list := &gatewayv1.RouteTableList{ListMeta: obj.(*gatewayv1.RouteTableList).ListMeta}
for _, item := range obj.(*gatewayv1.RouteTableList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
@@ -81,31 +81,31 @@ func (c *FakeRouteTables) Watch(ctx context.Context, opts v1.ListOptions) (watch
}
// Create takes the representation of a routeTable and creates it. Returns the server's representation of the routeTable, and an error, if there is any.
func (c *FakeRouteTables) Create(ctx context.Context, routeTable *gloov1.RouteTable, opts v1.CreateOptions) (result *gloov1.RouteTable, err error) {
func (c *FakeRouteTables) Create(ctx context.Context, routeTable *gatewayv1.RouteTable, opts v1.CreateOptions) (result *gatewayv1.RouteTable, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(routetablesResource, c.ns, routeTable), &gloov1.RouteTable{})
Invokes(testing.NewCreateAction(routetablesResource, c.ns, routeTable), &gatewayv1.RouteTable{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.RouteTable), err
return obj.(*gatewayv1.RouteTable), err
}
// Update takes the representation of a routeTable and updates it. Returns the server's representation of the routeTable, and an error, if there is any.
func (c *FakeRouteTables) Update(ctx context.Context, routeTable *gloov1.RouteTable, opts v1.UpdateOptions) (result *gloov1.RouteTable, err error) {
func (c *FakeRouteTables) Update(ctx context.Context, routeTable *gatewayv1.RouteTable, opts v1.UpdateOptions) (result *gatewayv1.RouteTable, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(routetablesResource, c.ns, routeTable), &gloov1.RouteTable{})
Invokes(testing.NewUpdateAction(routetablesResource, c.ns, routeTable), &gatewayv1.RouteTable{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.RouteTable), err
return obj.(*gatewayv1.RouteTable), err
}
// Delete takes name of the routeTable and deletes it. Returns an error if one occurs.
func (c *FakeRouteTables) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(routetablesResource, c.ns, name), &gloov1.RouteTable{})
Invokes(testing.NewDeleteAction(routetablesResource, c.ns, name), &gatewayv1.RouteTable{})
return err
}
@@ -114,17 +114,17 @@ func (c *FakeRouteTables) Delete(ctx context.Context, name string, opts v1.Delet
func (c *FakeRouteTables) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(routetablesResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &gloov1.RouteTableList{})
_, err := c.Fake.Invokes(action, &gatewayv1.RouteTableList{})
return err
}
// Patch applies the patch and returns the patched routeTable.
func (c *FakeRouteTables) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *gloov1.RouteTable, err error) {
func (c *FakeRouteTables) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *gatewayv1.RouteTable, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(routetablesResource, c.ns, name, pt, data, subresources...), &gloov1.RouteTable{})
Invokes(testing.NewPatchSubresourceAction(routetablesResource, c.ns, name, pt, data, subresources...), &gatewayv1.RouteTable{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.RouteTable), err
return obj.(*gatewayv1.RouteTable), err
}
@@ -0,0 +1,89 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1
import (
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
"github.com/fluxcd/flagger/pkg/client/clientset/versioned/scheme"
rest "k8s.io/client-go/rest"
)
type GatewayV1Interface interface {
RESTClient() rest.Interface
RouteTablesGetter
}
// GatewayV1Client is used to interact with features provided by the gateway.solo.io group.
type GatewayV1Client struct {
restClient rest.Interface
}
func (c *GatewayV1Client) RouteTables(namespace string) RouteTableInterface {
return newRouteTables(c, namespace)
}
// NewForConfig creates a new GatewayV1Client for the given config.
func NewForConfig(c *rest.Config) (*GatewayV1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
}
client, err := rest.RESTClientFor(&config)
if err != nil {
return nil, err
}
return &GatewayV1Client{client}, nil
}
// NewForConfigOrDie creates a new GatewayV1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *GatewayV1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
}
return client
}
// New creates a new GatewayV1Client for the given RESTClient.
func New(c rest.Interface) *GatewayV1Client {
return &GatewayV1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
gv := v1.SchemeGroupVersion
config.GroupVersion = &gv
config.APIPath = "/apis"
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
return nil
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *GatewayV1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
return c.restClient
}
@@ -0,0 +1,21 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1
type RouteTableExpansion interface{}
@@ -22,7 +22,7 @@ import (
"context"
"time"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
scheme "github.com/fluxcd/flagger/pkg/client/clientset/versioned/scheme"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
@@ -24,17 +24,17 @@ import (
testing "k8s.io/client-go/testing"
)
type FakeGatewayV1 struct {
type FakeGlooV1 struct {
*testing.Fake
}
func (c *FakeGatewayV1) RouteTables(namespace string) v1.RouteTableInterface {
return &FakeRouteTables{c, namespace}
func (c *FakeGlooV1) Upstreams(namespace string) v1.UpstreamInterface {
return &FakeUpstreams{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeGatewayV1) RESTClient() rest.Interface {
func (c *FakeGlooV1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}
@@ -0,0 +1,130 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
)
// FakeUpstreams implements UpstreamInterface
type FakeUpstreams struct {
Fake *FakeGlooV1
ns string
}
var upstreamsResource = schema.GroupVersionResource{Group: "gloo.solo.io", Version: "v1", Resource: "upstreams"}
var upstreamsKind = schema.GroupVersionKind{Group: "gloo.solo.io", Version: "v1", Kind: "Upstream"}
// Get takes name of the upstream, and returns the corresponding upstream object, and an error if there is any.
func (c *FakeUpstreams) Get(ctx context.Context, name string, options v1.GetOptions) (result *gloov1.Upstream, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(upstreamsResource, c.ns, name), &gloov1.Upstream{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.Upstream), err
}
// List takes label and field selectors, and returns the list of Upstreams that match those selectors.
func (c *FakeUpstreams) List(ctx context.Context, opts v1.ListOptions) (result *gloov1.UpstreamList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(upstreamsResource, upstreamsKind, c.ns, opts), &gloov1.UpstreamList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &gloov1.UpstreamList{ListMeta: obj.(*gloov1.UpstreamList).ListMeta}
for _, item := range obj.(*gloov1.UpstreamList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested upstreams.
func (c *FakeUpstreams) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(upstreamsResource, c.ns, opts))
}
// Create takes the representation of a upstream and creates it. Returns the server's representation of the upstream, and an error, if there is any.
func (c *FakeUpstreams) Create(ctx context.Context, upstream *gloov1.Upstream, opts v1.CreateOptions) (result *gloov1.Upstream, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(upstreamsResource, c.ns, upstream), &gloov1.Upstream{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.Upstream), err
}
// Update takes the representation of a upstream and updates it. Returns the server's representation of the upstream, and an error, if there is any.
func (c *FakeUpstreams) Update(ctx context.Context, upstream *gloov1.Upstream, opts v1.UpdateOptions) (result *gloov1.Upstream, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(upstreamsResource, c.ns, upstream), &gloov1.Upstream{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.Upstream), err
}
// Delete takes name of the upstream and deletes it. Returns an error if one occurs.
func (c *FakeUpstreams) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(upstreamsResource, c.ns, name), &gloov1.Upstream{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeUpstreams) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(upstreamsResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &gloov1.UpstreamList{})
return err
}
// Patch applies the patch and returns the patched upstream.
func (c *FakeUpstreams) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *gloov1.Upstream, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(upstreamsResource, c.ns, name, pt, data, subresources...), &gloov1.Upstream{})
if obj == nil {
return nil, err
}
return obj.(*gloov1.Upstream), err
}
@@ -18,4 +18,4 @@ limitations under the License.
package v1
type RouteTableExpansion interface{}
type UpstreamExpansion interface{}
@@ -19,27 +19,27 @@ limitations under the License.
package v1
import (
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
"github.com/fluxcd/flagger/pkg/client/clientset/versioned/scheme"
rest "k8s.io/client-go/rest"
)
type GatewayV1Interface interface {
type GlooV1Interface interface {
RESTClient() rest.Interface
RouteTablesGetter
UpstreamsGetter
}
// GatewayV1Client is used to interact with features provided by the gateway.solo.io group.
type GatewayV1Client struct {
// GlooV1Client is used to interact with features provided by the gloo.solo.io group.
type GlooV1Client struct {
restClient rest.Interface
}
func (c *GatewayV1Client) RouteTables(namespace string) RouteTableInterface {
return newRouteTables(c, namespace)
func (c *GlooV1Client) Upstreams(namespace string) UpstreamInterface {
return newUpstreams(c, namespace)
}
// NewForConfig creates a new GatewayV1Client for the given config.
func NewForConfig(c *rest.Config) (*GatewayV1Client, error) {
// NewForConfig creates a new GlooV1Client for the given config.
func NewForConfig(c *rest.Config) (*GlooV1Client, error) {
config := *c
if err := setConfigDefaults(&config); err != nil {
return nil, err
@@ -48,12 +48,12 @@ func NewForConfig(c *rest.Config) (*GatewayV1Client, error) {
if err != nil {
return nil, err
}
return &GatewayV1Client{client}, nil
return &GlooV1Client{client}, nil
}
// NewForConfigOrDie creates a new GatewayV1Client for the given config and
// NewForConfigOrDie creates a new GlooV1Client for the given config and
// panics if there is an error in the config.
func NewForConfigOrDie(c *rest.Config) *GatewayV1Client {
func NewForConfigOrDie(c *rest.Config) *GlooV1Client {
client, err := NewForConfig(c)
if err != nil {
panic(err)
@@ -61,9 +61,9 @@ func NewForConfigOrDie(c *rest.Config) *GatewayV1Client {
return client
}
// New creates a new GatewayV1Client for the given RESTClient.
func New(c rest.Interface) *GatewayV1Client {
return &GatewayV1Client{c}
// New creates a new GlooV1Client for the given RESTClient.
func New(c rest.Interface) *GlooV1Client {
return &GlooV1Client{c}
}
func setConfigDefaults(config *rest.Config) error {
@@ -81,7 +81,7 @@ func setConfigDefaults(config *rest.Config) error {
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *GatewayV1Client) RESTClient() rest.Interface {
func (c *GlooV1Client) RESTClient() rest.Interface {
if c == nil {
return nil
}
@@ -0,0 +1,178 @@
/*
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.
*/
// Code generated by client-gen. DO NOT EDIT.
package v1
import (
"context"
"time"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
scheme "github.com/fluxcd/flagger/pkg/client/clientset/versioned/scheme"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// UpstreamsGetter has a method to return a UpstreamInterface.
// A group's client should implement this interface.
type UpstreamsGetter interface {
Upstreams(namespace string) UpstreamInterface
}
// UpstreamInterface has methods to work with Upstream resources.
type UpstreamInterface interface {
Create(ctx context.Context, upstream *v1.Upstream, opts metav1.CreateOptions) (*v1.Upstream, error)
Update(ctx context.Context, upstream *v1.Upstream, opts metav1.UpdateOptions) (*v1.Upstream, error)
Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Upstream, error)
List(ctx context.Context, opts metav1.ListOptions) (*v1.UpstreamList, error)
Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Upstream, err error)
UpstreamExpansion
}
// upstreams implements UpstreamInterface
type upstreams struct {
client rest.Interface
ns string
}
// newUpstreams returns a Upstreams
func newUpstreams(c *GlooV1Client, namespace string) *upstreams {
return &upstreams{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the upstream, and returns the corresponding upstream object, and an error if there is any.
func (c *upstreams) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Upstream, err error) {
result = &v1.Upstream{}
err = c.client.Get().
Namespace(c.ns).
Resource("upstreams").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of Upstreams that match those selectors.
func (c *upstreams) List(ctx context.Context, opts metav1.ListOptions) (result *v1.UpstreamList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1.UpstreamList{}
err = c.client.Get().
Namespace(c.ns).
Resource("upstreams").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested upstreams.
func (c *upstreams) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("upstreams").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a upstream and creates it. Returns the server's representation of the upstream, and an error, if there is any.
func (c *upstreams) Create(ctx context.Context, upstream *v1.Upstream, opts metav1.CreateOptions) (result *v1.Upstream, err error) {
result = &v1.Upstream{}
err = c.client.Post().
Namespace(c.ns).
Resource("upstreams").
VersionedParams(&opts, scheme.ParameterCodec).
Body(upstream).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a upstream and updates it. Returns the server's representation of the upstream, and an error, if there is any.
func (c *upstreams) Update(ctx context.Context, upstream *v1.Upstream, opts metav1.UpdateOptions) (result *v1.Upstream, err error) {
result = &v1.Upstream{}
err = c.client.Put().
Namespace(c.ns).
Resource("upstreams").
Name(upstream.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(upstream).
Do(ctx).
Into(result)
return
}
// Delete takes name of the upstream and deletes it. Returns an error if one occurs.
func (c *upstreams) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("upstreams").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *upstreams) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("upstreams").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched upstream.
func (c *upstreams) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Upstream, err error) {
result = &v1.Upstream{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("upstreams").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}
@@ -26,6 +26,7 @@ import (
versioned "github.com/fluxcd/flagger/pkg/client/clientset/versioned"
appmesh "github.com/fluxcd/flagger/pkg/client/informers/externalversions/appmesh"
flagger "github.com/fluxcd/flagger/pkg/client/informers/externalversions/flagger"
gateway "github.com/fluxcd/flagger/pkg/client/informers/externalversions/gateway"
gloo "github.com/fluxcd/flagger/pkg/client/informers/externalversions/gloo"
internalinterfaces "github.com/fluxcd/flagger/pkg/client/informers/externalversions/internalinterfaces"
istio "github.com/fluxcd/flagger/pkg/client/informers/externalversions/istio"
@@ -180,7 +181,8 @@ type SharedInformerFactory interface {
Appmesh() appmesh.Interface
Flagger() flagger.Interface
Gateway() gloo.Interface
Gateway() gateway.Interface
Gloo() gloo.Interface
Networking() istio.Interface
Projectcontour() projectcontour.Interface
Split() smi.Interface
@@ -195,7 +197,11 @@ func (f *sharedInformerFactory) Flagger() flagger.Interface {
return flagger.New(f, f.namespace, f.tweakListOptions)
}
func (f *sharedInformerFactory) Gateway() gloo.Interface {
func (f *sharedInformerFactory) Gateway() gateway.Interface {
return gateway.New(f, f.namespace, f.tweakListOptions)
}
func (f *sharedInformerFactory) Gloo() gloo.Interface {
return gloo.New(f, f.namespace, f.tweakListOptions)
}
@@ -0,0 +1,46 @@
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package gateway
import (
v1 "github.com/fluxcd/flagger/pkg/client/informers/externalversions/gateway/v1"
internalinterfaces "github.com/fluxcd/flagger/pkg/client/informers/externalversions/internalinterfaces"
)
// Interface provides access to each of this group's versions.
type Interface interface {
// V1 provides access to shared informers for resources in V1.
V1() v1.Interface
}
type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// V1 returns a new v1.Interface.
func (g *group) V1() v1.Interface {
return v1.New(g.factory, g.namespace, g.tweakListOptions)
}
@@ -0,0 +1,45 @@
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1
import (
internalinterfaces "github.com/fluxcd/flagger/pkg/client/informers/externalversions/internalinterfaces"
)
// Interface provides access to all the informers in this group version.
type Interface interface {
// RouteTables returns a RouteTableInformer.
RouteTables() RouteTableInformer
}
type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// RouteTables returns a RouteTableInformer.
func (v *version) RouteTables() RouteTableInformer {
return &routeTableInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
@@ -22,10 +22,10 @@ import (
"context"
time "time"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
versioned "github.com/fluxcd/flagger/pkg/client/clientset/versioned"
internalinterfaces "github.com/fluxcd/flagger/pkg/client/informers/externalversions/internalinterfaces"
v1 "github.com/fluxcd/flagger/pkg/client/listers/gloo/v1"
v1 "github.com/fluxcd/flagger/pkg/client/listers/gateway/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
@@ -71,7 +71,7 @@ func NewFilteredRouteTableInformer(client versioned.Interface, namespace string,
return client.GatewayV1().RouteTables(namespace).Watch(context.TODO(), options)
},
},
&gloov1.RouteTable{},
&gatewayv1.RouteTable{},
resyncPeriod,
indexers,
)
@@ -82,7 +82,7 @@ func (f *routeTableInformer) defaultInformer(client versioned.Interface, resyncP
}
func (f *routeTableInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&gloov1.RouteTable{}, f.defaultInformer)
return f.factory.InformerFor(&gatewayv1.RouteTable{}, f.defaultInformer)
}
func (f *routeTableInformer) Lister() v1.RouteTableLister {
@@ -24,7 +24,8 @@ import (
v1beta1 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta1"
v1beta2 "github.com/fluxcd/flagger/pkg/apis/appmesh/v1beta2"
flaggerv1beta1 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
v1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
projectcontourv1 "github.com/fluxcd/flagger/pkg/apis/projectcontour/v1"
v1alpha1 "github.com/fluxcd/flagger/pkg/apis/smi/v1alpha1"
@@ -89,6 +90,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
case v1.SchemeGroupVersion.WithResource("routetables"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Gateway().V1().RouteTables().Informer()}, nil
// Group=gloo.solo.io, Version=v1
case gloov1.SchemeGroupVersion.WithResource("upstreams"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Gloo().V1().Upstreams().Informer()}, nil
// Group=networking.istio.io, Version=v1alpha3
case v1alpha3.SchemeGroupVersion.WithResource("destinationrules"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha3().DestinationRules().Informer()}, nil
@@ -24,8 +24,8 @@ import (
// Interface provides access to all the informers in this group version.
type Interface interface {
// RouteTables returns a RouteTableInformer.
RouteTables() RouteTableInformer
// Upstreams returns a UpstreamInformer.
Upstreams() UpstreamInformer
}
type version struct {
@@ -39,7 +39,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// RouteTables returns a RouteTableInformer.
func (v *version) RouteTables() RouteTableInformer {
return &routeTableInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
// Upstreams returns a UpstreamInformer.
func (v *version) Upstreams() UpstreamInformer {
return &upstreamInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
@@ -0,0 +1,90 @@
/*
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.
*/
// Code generated by informer-gen. DO NOT EDIT.
package v1
import (
"context"
time "time"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
versioned "github.com/fluxcd/flagger/pkg/client/clientset/versioned"
internalinterfaces "github.com/fluxcd/flagger/pkg/client/informers/externalversions/internalinterfaces"
v1 "github.com/fluxcd/flagger/pkg/client/listers/gloo/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
)
// UpstreamInformer provides access to a shared informer and lister for
// Upstreams.
type UpstreamInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1.UpstreamLister
}
type upstreamInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewUpstreamInformer constructs a new informer for Upstream type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewUpstreamInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredUpstreamInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredUpstreamInformer constructs a new informer for Upstream type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredUpstreamInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.GlooV1().Upstreams(namespace).List(context.TODO(), options)
},
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.GlooV1().Upstreams(namespace).Watch(context.TODO(), options)
},
},
&gloov1.Upstream{},
resyncPeriod,
indexers,
)
}
func (f *upstreamInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredUpstreamInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *upstreamInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&gloov1.Upstream{}, f.defaultInformer)
}
func (f *upstreamInformer) Lister() v1.UpstreamLister {
return v1.NewUpstreamLister(f.Informer().GetIndexer())
}
@@ -0,0 +1,27 @@
/*
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1
// RouteTableListerExpansion allows custom methods to be added to
// RouteTableLister.
type RouteTableListerExpansion interface{}
// RouteTableNamespaceListerExpansion allows custom methods to be added to
// RouteTableNamespaceLister.
type RouteTableNamespaceListerExpansion interface{}
@@ -19,7 +19,7 @@ limitations under the License.
package v1
import (
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
@@ -18,10 +18,10 @@ limitations under the License.
package v1
// RouteTableListerExpansion allows custom methods to be added to
// RouteTableLister.
type RouteTableListerExpansion interface{}
// UpstreamListerExpansion allows custom methods to be added to
// UpstreamLister.
type UpstreamListerExpansion interface{}
// RouteTableNamespaceListerExpansion allows custom methods to be added to
// RouteTableNamespaceLister.
type RouteTableNamespaceListerExpansion interface{}
// UpstreamNamespaceListerExpansion allows custom methods to be added to
// UpstreamNamespaceLister.
type UpstreamNamespaceListerExpansion interface{}
+99
View File
@@ -0,0 +1,99 @@
/*
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.
*/
// Code generated by lister-gen. DO NOT EDIT.
package v1
import (
v1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
// UpstreamLister helps list Upstreams.
// All objects returned here must be treated as read-only.
type UpstreamLister interface {
// List lists all Upstreams in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1.Upstream, err error)
// Upstreams returns an object that can list and get Upstreams.
Upstreams(namespace string) UpstreamNamespaceLister
UpstreamListerExpansion
}
// upstreamLister implements the UpstreamLister interface.
type upstreamLister struct {
indexer cache.Indexer
}
// NewUpstreamLister returns a new UpstreamLister.
func NewUpstreamLister(indexer cache.Indexer) UpstreamLister {
return &upstreamLister{indexer: indexer}
}
// List lists all Upstreams in the indexer.
func (s *upstreamLister) List(selector labels.Selector) (ret []*v1.Upstream, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Upstream))
})
return ret, err
}
// Upstreams returns an object that can list and get Upstreams.
func (s *upstreamLister) Upstreams(namespace string) UpstreamNamespaceLister {
return upstreamNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// UpstreamNamespaceLister helps list and get Upstreams.
// All objects returned here must be treated as read-only.
type UpstreamNamespaceLister interface {
// List lists all Upstreams in the indexer for a given namespace.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1.Upstream, err error)
// Get retrieves the Upstream from the indexer for a given namespace and name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1.Upstream, error)
UpstreamNamespaceListerExpansion
}
// upstreamNamespaceLister implements the UpstreamNamespaceLister
// interface.
type upstreamNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all Upstreams in the indexer for a given namespace.
func (s upstreamNamespaceLister) List(selector labels.Selector) (ret []*v1.Upstream, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1.Upstream))
})
return ret, err
}
// Get retrieves the Upstream from the indexer for a given namespace and name.
func (s upstreamNamespaceLister) Get(name string) (*v1.Upstream, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1.Resource("upstream"), name)
}
return obj.(*v1.Upstream), nil
}
+3 -3
View File
@@ -31,7 +31,7 @@ var glooQueries = map[string]string{
sum(
rate(
envoy_cluster_upstream_rq{
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
envoy_response_code!~"5.*"
}[{{ interval }}]
)
@@ -40,7 +40,7 @@ var glooQueries = map[string]string{
sum(
rate(
envoy_cluster_upstream_rq{
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
}[{{ interval }}]
)
)
@@ -51,7 +51,7 @@ var glooQueries = map[string]string{
sum(
rate(
envoy_cluster_upstream_rq_time_bucket{
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
envoy_cluster_name=~"{{ namespace }}-{{ target }}-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+",
}[{{ interval }}]
)
) by (le)
+2 -2
View File
@@ -30,7 +30,7 @@ import (
)
func TestGlooObserver_GetRequestSuccessRate(t *testing.T) {
expected := ` sum( rate( envoy_cluster_upstream_rq{ envoy_cluster_name=~"default-podinfo-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", envoy_response_code!~"5.*" }[1m] ) ) / sum( rate( envoy_cluster_upstream_rq{ envoy_cluster_name=~"default-podinfo-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", }[1m] ) ) * 100`
expected := ` sum( rate( envoy_cluster_upstream_rq{ envoy_cluster_name=~"default-podinfo-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", envoy_response_code!~"5.*" }[1m] ) ) / sum( rate( envoy_cluster_upstream_rq{ envoy_cluster_name=~"default-podinfo-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", }[1m] ) ) * 100`
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
promql := r.URL.Query()["query"][0]
@@ -64,7 +64,7 @@ func TestGlooObserver_GetRequestSuccessRate(t *testing.T) {
}
func TestGlooObserver_GetRequestDuration(t *testing.T) {
expected := ` histogram_quantile( 0.99, sum( rate( envoy_cluster_upstream_rq_time_bucket{ envoy_cluster_name=~"default-podinfo-canary-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", }[1m] ) ) by (le) )`
expected := ` histogram_quantile( 0.99, sum( rate( envoy_cluster_upstream_rq_time_bucket{ envoy_cluster_name=~"default-podinfo-canaryupstream-[0-9a-zA-Z-]+_[0-9a-zA-Z-]+", }[1m] ) ) by (le) )`
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
promql := r.URL.Query()["query"][0]
+4 -9
View File
@@ -140,16 +140,11 @@ func (factory *Factory) MeshRouter(provider string, labelSelector string) Interf
ingressClass: factory.ingressClass,
}
case strings.HasPrefix(provider, flaggerv1.GlooProvider):
upstreamDiscoveryNs := flaggerv1.GlooProvider + "-system"
if strings.HasPrefix(provider, flaggerv1.GlooProvider+":") {
upstreamDiscoveryNs = strings.TrimPrefix(provider, flaggerv1.GlooProvider+":")
}
return &GlooRouter{
logger: factory.logger,
flaggerClient: factory.flaggerClient,
kubeClient: factory.kubeClient,
glooClient: factory.meshClient,
upstreamDiscoveryNs: upstreamDiscoveryNs,
logger: factory.logger,
flaggerClient: factory.flaggerClient,
kubeClient: factory.kubeClient,
glooClient: factory.meshClient,
}
case provider == flaggerv1.NGINXProvider:
return &IngressRouter{
+106 -44
View File
@@ -20,7 +20,10 @@ import (
"context"
"fmt"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
corev1 "k8s.io/api/core/v1"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/gloo/v1"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"go.uber.org/zap"
@@ -35,41 +38,53 @@ import (
// GlooRouter is managing Gloo route tables
type GlooRouter struct {
kubeClient kubernetes.Interface
glooClient clientset.Interface
flaggerClient clientset.Interface
logger *zap.SugaredLogger
upstreamDiscoveryNs string
kubeClient kubernetes.Interface
glooClient clientset.Interface
flaggerClient clientset.Interface
logger *zap.SugaredLogger
}
// Reconcile creates or updates the Gloo Edge route table
func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error {
apexName, _, _ := canary.GetServiceNames()
canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
canaryUpstreamName := fmt.Sprintf("%s-%s-canaryupstream-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
primaryUpstreamName := fmt.Sprintf("%s-%s-primaryupstream-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
newSpec := gloov1.RouteTableSpec{
Routes: []gloov1.Route{
// Create upstreams for the canary/primary services created by flagger.
// Previously, we relied on gloo discovery to automaticallycreate these upstreams, but this would no longer work if
// discovery was turned off.
// KubeServiceDestinations can be disabled in gloo configuration, so we don't use those either.
err := gr.createFlaggerUpstream(canary, primaryUpstreamName, false)
if err != nil {
return fmt.Errorf("error creating flagger primary upstream: %w", err)
}
err = gr.createFlaggerUpstream(canary, canaryUpstreamName, true)
if err != nil {
return fmt.Errorf("error creating flagger canary upstream: %w", err)
}
newSpec := gatewayv1.RouteTableSpec{
Routes: []gatewayv1.Route{
{
InheritablePathMatchers: true,
Matchers: getMatchers(canary),
Action: gloov1.RouteAction{
Destination: gloov1.MultiDestination{
Destinations: []gloov1.WeightedDestination{
Action: gatewayv1.RouteAction{
Destination: gatewayv1.MultiDestination{
Destinations: []gatewayv1.WeightedDestination{
{
Destination: gloov1.Destination{
Upstream: gloov1.ResourceRef{
Name: primaryName,
Namespace: gr.upstreamDiscoveryNs,
Destination: gatewayv1.Destination{
Upstream: gatewayv1.ResourceRef{
Name: primaryUpstreamName,
Namespace: canary.Namespace,
},
},
Weight: 100,
},
{
Destination: gloov1.Destination{
Upstream: gloov1.ResourceRef{
Name: canaryName,
Namespace: gr.upstreamDiscoveryNs,
Destination: gatewayv1.Destination{
Upstream: gatewayv1.ResourceRef{
Name: canaryUpstreamName,
Namespace: canary.Namespace,
},
},
Weight: 0,
@@ -83,8 +98,7 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error {
routeTable, err := gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{})
if errors.IsNotFound(err) {
routeTable = &gloov1.RouteTable{
routeTable = &gatewayv1.RouteTable{
ObjectMeta: metav1.ObjectMeta{
Name: apexName,
Namespace: canary.Namespace,
@@ -115,7 +129,7 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error {
if diff := cmp.Diff(
newSpec,
routeTable.Spec,
cmpopts.IgnoreFields(gloov1.WeightedDestination{}, "Weight"),
cmpopts.IgnoreFields(gatewayv1.WeightedDestination{}, "Weight"),
); diff != "" {
clone := routeTable.DeepCopy()
clone.Spec = newSpec
@@ -140,7 +154,7 @@ func (gr *GlooRouter) GetRoutes(canary *flaggerv1.Canary) (
err error,
) {
apexName := canary.Spec.TargetRef.Name
primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primaryupstream-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port)
routeTable, err := gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{})
if err != nil {
@@ -172,8 +186,8 @@ func (gr *GlooRouter) SetRoutes(
_ bool,
) error {
apexName, _, _ := canary.GetServiceNames()
canaryName := fmt.Sprintf("%s-%s-canary-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
canaryName := fmt.Sprintf("%s-%s-canaryupstream-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primaryupstream-%v", canary.Namespace, apexName, canary.Spec.Service.Port)
if primaryWeight == 0 && canaryWeight == 0 {
return fmt.Errorf("RoutingRule %s.%s update failed: no valid weights", apexName, canary.Namespace)
@@ -184,28 +198,28 @@ func (gr *GlooRouter) SetRoutes(
return fmt.Errorf("RouteTable %s.%s query error: %w", apexName, canary.Namespace, err)
}
routeTable.Spec = gloov1.RouteTableSpec{
Routes: []gloov1.Route{
routeTable.Spec = gatewayv1.RouteTableSpec{
Routes: []gatewayv1.Route{
{
InheritablePathMatchers: true,
Matchers: getMatchers(canary),
Action: gloov1.RouteAction{
Destination: gloov1.MultiDestination{
Destinations: []gloov1.WeightedDestination{
Action: gatewayv1.RouteAction{
Destination: gatewayv1.MultiDestination{
Destinations: []gatewayv1.WeightedDestination{
{
Destination: gloov1.Destination{
Upstream: gloov1.ResourceRef{
Destination: gatewayv1.Destination{
Upstream: gatewayv1.ResourceRef{
Name: primaryName,
Namespace: gr.upstreamDiscoveryNs,
Namespace: canary.Namespace,
},
},
Weight: uint32(primaryWeight),
},
{
Destination: gloov1.Destination{
Upstream: gloov1.ResourceRef{
Destination: gatewayv1.Destination{
Upstream: gatewayv1.ResourceRef{
Name: canaryName,
Namespace: gr.upstreamDiscoveryNs,
Namespace: canary.Namespace,
},
},
Weight: uint32(canaryWeight),
@@ -228,7 +242,55 @@ func (gr *GlooRouter) Finalize(_ *flaggerv1.Canary) error {
return nil
}
func getMatchers(canary *flaggerv1.Canary) []gloov1.Matcher {
func (gr *GlooRouter) createFlaggerUpstream(canary *flaggerv1.Canary, upstreamName string, isCanary bool) error {
_, primaryName, canaryName := canary.GetServiceNames()
upstreamClient := gr.glooClient.GlooV1().Upstreams(canary.Namespace)
svcName := primaryName
if isCanary {
svcName = canaryName
}
svc, err := gr.kubeClient.CoreV1().Services(canary.Namespace).Get(context.TODO(), svcName, metav1.GetOptions{})
if err != nil {
return fmt.Errorf("service %s.%s get query error: %w", svcName, canary.Namespace, err)
}
_, err = upstreamClient.Get(context.TODO(), upstreamName, metav1.GetOptions{})
if errors.IsNotFound(err) {
canaryUs := gr.getGlooUpstreamKubeService(canary, svc, upstreamName)
_, err := gr.glooClient.GlooV1().Upstreams(canary.Namespace).Create(context.TODO(), canaryUs, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("upstream %s.%s create query error: %w", upstreamName, canary.Namespace, err)
}
} else if err != nil {
return fmt.Errorf("upstream %s.%s get query error: %w", upstreamName, canary.Namespace, err)
}
return nil
}
func (gr *GlooRouter) getGlooUpstreamKubeService(canary *flaggerv1.Canary, svc *corev1.Service, upstreamName string) *gloov1.Upstream {
return &gloov1.Upstream{
ObjectMeta: metav1.ObjectMeta{
Name: upstreamName,
Namespace: canary.Namespace,
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(canary, schema.GroupVersionKind{
Group: flaggerv1.SchemeGroupVersion.Group,
Version: flaggerv1.SchemeGroupVersion.Version,
Kind: flaggerv1.CanaryKind,
}),
},
},
Spec: gloov1.UpstreamSpec{
Kube: gloov1.KubeUpstream{
ServiceName: svc.GetName(),
ServiceNamespace: canary.Namespace,
ServicePort: canary.Spec.Service.Port,
Selector: svc.Spec.Selector,
},
},
}
}
func getMatchers(canary *flaggerv1.Canary) []gatewayv1.Matcher {
headerMatchers := getHeaderMatchers(canary)
methods := getMethods(canary)
@@ -237,7 +299,7 @@ func getMatchers(canary *flaggerv1.Canary) []gloov1.Matcher {
return nil
}
return []gloov1.Matcher{
return []gatewayv1.Matcher{
{
Headers: headerMatchers,
Methods: methods,
@@ -245,16 +307,16 @@ func getMatchers(canary *flaggerv1.Canary) []gloov1.Matcher {
}
}
func getHeaderMatchers(canary *flaggerv1.Canary) []gloov1.HeaderMatcher {
var headerMatchers []gloov1.HeaderMatcher
func getHeaderMatchers(canary *flaggerv1.Canary) []gatewayv1.HeaderMatcher {
var headerMatchers []gatewayv1.HeaderMatcher
for _, match := range canary.GetAnalysis().Match {
for s, stringMatch := range match.Headers {
h := gloov1.HeaderMatcher{
h := gatewayv1.HeaderMatcher{
Name: s,
Value: stringMatch.Exact,
}
if stringMatch.Regex != "" {
h = gloov1.HeaderMatcher{
h = gatewayv1.HeaderMatcher{
Name: s,
Value: stringMatch.Regex,
Regex: true,
+36 -10
View File
@@ -21,11 +21,11 @@ import (
"fmt"
"testing"
gatewayv1 "github.com/fluxcd/flagger/pkg/apis/gloo/gateway/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1"
)
func TestGlooRouter_Sync(t *testing.T) {
@@ -36,9 +36,17 @@ func TestGlooRouter_Sync(t *testing.T) {
glooClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
svcRouter := &KubernetesDefaultRouter{
kubeClient: mocks.kubeClient,
flaggerClient: mocks.flaggerClient,
logger: mocks.logger,
}
err := svcRouter.Initialize(mocks.canary)
require.NoError(t, err)
err = svcRouter.Reconcile(mocks.canary)
require.NoError(t, err)
// init
err := router.Reconcile(mocks.canary)
err = router.Reconcile(mocks.canary)
require.NoError(t, err)
// test insert
@@ -77,8 +85,17 @@ func TestGlooRouter_SetRoutes(t *testing.T) {
glooClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
svcRouter := &KubernetesDefaultRouter{
kubeClient: mocks.kubeClient,
flaggerClient: mocks.flaggerClient,
logger: mocks.logger,
}
err := svcRouter.Initialize(mocks.canary)
require.NoError(t, err)
err = svcRouter.Reconcile(mocks.canary)
require.NoError(t, err)
err := router.Reconcile(mocks.canary)
err = router.Reconcile(mocks.canary)
require.NoError(t, err)
_, _, _, err = router.GetRoutes(mocks.canary)
@@ -94,10 +111,10 @@ func TestGlooRouter_SetRoutes(t *testing.T) {
rt, err := router.glooClient.GatewayV1().RouteTables("default").Get(context.TODO(), "podinfo", metav1.GetOptions{})
require.NoError(t, err)
var pRoute gloov1.WeightedDestination
var cRoute gloov1.WeightedDestination
canaryName := fmt.Sprintf("%s-%s-canary-%v", mocks.canary.Namespace, mocks.canary.Spec.TargetRef.Name, mocks.canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primary-%v", mocks.canary.Namespace, mocks.canary.Spec.TargetRef.Name, mocks.canary.Spec.Service.Port)
var pRoute gatewayv1.WeightedDestination
var cRoute gatewayv1.WeightedDestination
canaryName := fmt.Sprintf("%s-%s-canaryupstream-%v", mocks.canary.Namespace, mocks.canary.Spec.TargetRef.Name, mocks.canary.Spec.Service.Port)
primaryName := fmt.Sprintf("%s-%s-primaryupstream-%v", mocks.canary.Namespace, mocks.canary.Spec.TargetRef.Name, mocks.canary.Spec.Service.Port)
for _, dest := range rt.Spec.Routes[0].Action.Destination.Destinations {
if dest.Destination.Upstream.Name == primaryName {
@@ -139,8 +156,17 @@ func TestGlooRouter_GetRoutes(t *testing.T) {
glooClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
svcRouter := &KubernetesDefaultRouter{
kubeClient: mocks.kubeClient,
flaggerClient: mocks.flaggerClient,
logger: mocks.logger,
}
err := svcRouter.Initialize(mocks.canary)
require.NoError(t, err)
err = svcRouter.Reconcile(mocks.canary)
require.NoError(t, err)
err := router.Reconcile(mocks.canary)
err = router.Reconcile(mocks.canary)
require.NoError(t, err)
p, c, m, err := router.GetRoutes(mocks.canary)
+1 -1
View File
@@ -12,7 +12,7 @@ kubectl create ns gloo-system
helm repo add gloo https://storage.googleapis.com/solo-public-helm
helm upgrade -i gloo gloo/gloo --version ${GLOO_VER} \
--namespace gloo-system \
--set discovery.enabled=true
--set discovery.enabled=false
kubectl -n gloo-system rollout status deployment/gloo
kubectl -n gloo-system rollout status deployment/gateway