diff --git a/README.md b/README.md index 6b27dbd50..3d45c4e6f 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ For more details on how the canary analysis and promotion works please [read the | Feature | Contour | Gloo | NGINX | Skipper | Traefik | | ------------------------------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | | Canary deployments (weighted traffic) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| A/B testing (headers and cookies routing) | :heavy_check_mark: | :heavy_minus_sign: | :heavy_check_mark: | :heavy_minus_sign: | :heavy_minus_sign: | +| A/B testing (headers and cookies routing) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_minus_sign: | :heavy_minus_sign: | | Blue/Green deployments (traffic switch) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Webhooks (acceptance/load testing) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | Manual gating (approve/pause/resume) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | diff --git a/artifacts/flagger/account.yaml b/artifacts/flagger/account.yaml index 22c304474..c8ed98336 100644 --- a/artifacts/flagger/account.yaml +++ b/artifacts/flagger/account.yaml @@ -153,8 +153,19 @@ rules: resources: - upstreams - upstreams/finalizers - - upstreamgroups - - upstreamgroups/finalizers + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - gateway.solo.io + resources: + - routetables + - routetables/finalizers verbs: - get - list diff --git a/charts/flagger/templates/rbac.yaml b/charts/flagger/templates/rbac.yaml index 16a9151f7..afd0d6118 100644 --- a/charts/flagger/templates/rbac.yaml +++ b/charts/flagger/templates/rbac.yaml @@ -149,8 +149,19 @@ rules: resources: - upstreams - upstreams/finalizers - - upstreamgroups - - upstreamgroups/finalizers + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - gateway.solo.io + resources: + - routetables + - routetables/finalizers verbs: - get - list diff --git a/docs/gitbook/tutorials/gloo-progressive-delivery.md b/docs/gitbook/tutorials/gloo-progressive-delivery.md index 041de1b0a..d5a323009 100644 --- a/docs/gitbook/tutorials/gloo-progressive-delivery.md +++ b/docs/gitbook/tutorials/gloo-progressive-delivery.md @@ -1,12 +1,15 @@ # Gloo Canary Deployments -This guide shows you how to use the [Gloo](https://gloo.solo.io/) ingress controller and Flagger to automate canary deployments. +This guide shows you how to use the [Gloo Edge](https://gloo.solo.io/) ingress controller and Flagger to automate canary deployments. ![Flagger Gloo Ingress Controller](https://raw.githubusercontent.com/weaveworks/flagger/master/docs/diagrams/flagger-gloo-overview.png) ## Prerequisites -Flagger requires a Kubernetes cluster **v1.11** or newer and Gloo ingress **1.3.5** or newer. +This guide was written for Flagger version **1.5.0** or higher. Prior versions of Flagger used Gloo upstream groups to handle +canaries, but newer versions of Flagger use Gloo route tables to handle canaries as well as A/B testing. + +Flagger requires a Kubernetes cluster **v1.11** or newer and Gloo Edge ingress **1.6.0** or newer. Install Gloo with Helm v3: @@ -30,7 +33,7 @@ helm upgrade -i flagger flagger/flagger \ ## Bootstrap -Flagger takes a Kubernetes deployment and optionally a horizontal pod autoscaler \(HPA\), then creates a series of objects \(Kubernetes deployments, ClusterIP services and Gloo upstream groups\). These objects expose the application outside the cluster and drive the canary analysis and promotion. +Flagger takes a Kubernetes deployment and optionally a horizontal pod autoscaler \(HPA\), then creates a series of objects \(Kubernetes deployments, ClusterIP services and Gloo route tables groups\). These objects expose the application outside the cluster and drive the canary analysis and promotion. Create a test namespace: @@ -50,7 +53,7 @@ Deploy the load testing service to generate traffic during the canary analysis: kubectl -n test apply -k github.com/weaveworks/flagger//kustomize/tester ``` -Create an virtual service definition that references an upstream group that will be generated by Flagger \(replace `app.example.com` with your own domain\): +Create a virtual service definition that references a route table that will be generated by Flagger \(replace `app.example.com` with your own domain\): ```yaml apiVersion: gateway.solo.io/v1 @@ -65,8 +68,8 @@ spec: routes: - matchers: - prefix: / - routeAction: - upstreamGroup: + delegateAction: + ref: name: podinfo namespace: test ``` @@ -165,7 +168,7 @@ horizontalpodautoscaler.autoscaling/podinfo-primary service/podinfo service/podinfo-canary service/podinfo-primary -upstreamgroups.gloo.solo.io/podinfo +routetables.gateway.solo.io/podinfo ``` When the bootstrap finishes Flagger will set the canary status to initialized: @@ -247,13 +250,13 @@ podinfod=stefanprodan/podinfo:3.1.2 Generate HTTP 500 errors: ```bash -watch curl -H 'Host: app.example.com' http://gateway-proxy-v2.gloo-system/status/500 +watch curl -H 'Host: app.example.com' http://gateway-proxy.gloo-system/status/500 ``` Generate high latency: ```bash -watch curl -H 'Host: app.example.com' http://gateway-proxy-v2.gloo-system/delay/2 +watch curl -H 'Host: app.example.com' http://gateway-proxy.gloo-system/delay/2 ``` When the number of failed checks reaches the canary analysis threshold, the traffic is routed back to the primary, the canary is scaled to zero and the rollout is marked as failed. @@ -345,7 +348,7 @@ podinfod=stefanprodan/podinfo:3.1.3 Generate 404s: ```bash -watch curl -H 'Host: app.example.com' http://gateway-proxy.gloo-system/status/400 +watch curl -H 'Host: app.example.com' http://gateway-proxy.gloo-system/status/404 ``` Watch Flagger logs: diff --git a/docs/gitbook/usage/deployment-strategies.md b/docs/gitbook/usage/deployment-strategies.md index 5835cf903..2b42bbbe6 100644 --- a/docs/gitbook/usage/deployment-strategies.md +++ b/docs/gitbook/usage/deployment-strategies.md @@ -3,11 +3,11 @@ Flagger can run automated application analysis, promotion and rollback for the following deployment strategies: * **Canary Release** \(progressive traffic shifting\) - * Istio, Linkerd, App Mesh, NGINX, Skipper, Contour, Gloo, Traefik + * Istio, Linkerd, App Mesh, NGINX, Skipper, Contour, Gloo Edge, Traefik * **A/B Testing** \(HTTP headers and cookies traffic routing\) - * Istio, App Mesh, NGINX, Contour + * Istio, App Mesh, NGINX, Contour, Gloo Edge * **Blue/Green** \(traffic switching\) - * Kubernetes CNI, Istio, Linkerd, App Mesh, NGINX, Contour, Gloo + * Kubernetes CNI, Istio, Linkerd, App Mesh, NGINX, Contour, Gloo Edge * **Blue/Green Mirroring** \(traffic shadowing\) * Istio diff --git a/kustomize/base/flagger/rbac.yaml b/kustomize/base/flagger/rbac.yaml index e2a6b48d7..f4db1403a 100644 --- a/kustomize/base/flagger/rbac.yaml +++ b/kustomize/base/flagger/rbac.yaml @@ -143,8 +143,19 @@ rules: resources: - upstreams - upstreams/finalizers - - upstreamgroups - - upstreamgroups/finalizers + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - gateway.solo.io + resources: + - routetables + - routetables/finalizers verbs: - get - list diff --git a/pkg/apis/gloo/register.go b/pkg/apis/gloo/register.go index 1e6e90165..0d7175074 100644 --- a/pkg/apis/gloo/register.go +++ b/pkg/apis/gloo/register.go @@ -1,5 +1,5 @@ package gloo const ( - GroupName = "gloo.solo.io" + GroupName = "gateway.solo.io" ) diff --git a/pkg/apis/gloo/v1/doc.go b/pkg/apis/gloo/v1/doc.go index 0c6413321..75ed100f7 100644 --- a/pkg/apis/gloo/v1/doc.go +++ b/pkg/apis/gloo/v1/doc.go @@ -1,5 +1,5 @@ // +k8s:deepcopy-gen=package // Package v1 is the v1 version of the API. -// +groupName=gloo.solo.io +// +groupName=gateway.solo.io package v1 diff --git a/pkg/apis/gloo/v1/register.go b/pkg/apis/gloo/v1/register.go index d06961fb3..46c167ae1 100755 --- a/pkg/apis/gloo/v1/register.go +++ b/pkg/apis/gloo/v1/register.go @@ -28,8 +28,8 @@ var ( // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &UpstreamGroup{}, - &UpstreamGroupList{}, + &RouteTable{}, + &RouteTableList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/apis/gloo/v1/types.go b/pkg/apis/gloo/v1/types.go index 5209206c6..c9f54abcf 100644 --- a/pkg/apis/gloo/v1/types.go +++ b/pkg/apis/gloo/v1/types.go @@ -7,15 +7,48 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// UpstreamGroup is a specification for a Gloo UpstreamGroup resource -type UpstreamGroup struct { +// RouteTable is a specification for a Gloo RouteTable resource +type RouteTable struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec UpstreamGroupSpec `json:"spec"` + Spec RouteTableSpec `json:"spec"` } -type UpstreamGroupSpec struct { +type RouteTableSpec struct { + Routes []Route `json:"routes,omitempty"` +} + +type Route struct { + Matchers []Matcher `json:"matchers,omitempty"` + Action RouteAction `json:"routeAction,omitempty"` + InheritablePathMatchers bool `json:"inheritablePathMatchers,omitempty"` +} + +type Matcher struct { + Headers []HeaderMatcher `json:"headers,omitempty"` + QueryParameterMatchers []QueryParameterMatcher `json:"queryParameters,omitempty"` + Methods []string `json:"methods,omitempty"` +} + +type HeaderMatcher struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + Regex bool `json:"regex,omitempty"` + InvertMatch bool `json:"invertMatch,omitempty"` +} + +type QueryParameterMatcher struct { + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + Regex bool `json:"regex,omitempty"` +} + +type RouteAction struct { + Destination MultiDestination `json:"multi,omitempty"` +} + +type MultiDestination struct { Destinations []WeightedDestination `json:"destinations,omitempty"` } @@ -40,10 +73,10 @@ type ResourceRef struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// UpstreamGroupList is a list of UpstreamGroup resources -type UpstreamGroupList struct { +// RouteTableList is a list of RouteTable resources +type RouteTableList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata"` - Items []UpstreamGroup `json:"items"` + Items []RouteTable `json:"items"` } diff --git a/pkg/apis/gloo/v1/zz_generated.deepcopy.go b/pkg/apis/gloo/v1/zz_generated.deepcopy.go index db498aef8..44a00d9a7 100644 --- a/pkg/apis/gloo/v1/zz_generated.deepcopy.go +++ b/pkg/apis/gloo/v1/zz_generated.deepcopy.go @@ -41,6 +41,90 @@ func (in *Destination) DeepCopy() *Destination { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HeaderMatcher) DeepCopyInto(out *HeaderMatcher) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatcher. +func (in *HeaderMatcher) DeepCopy() *HeaderMatcher { + if in == nil { + return nil + } + out := new(HeaderMatcher) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Matcher) DeepCopyInto(out *Matcher) { + *out = *in + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = make([]HeaderMatcher, len(*in)) + copy(*out, *in) + } + if in.QueryParameterMatchers != nil { + in, out := &in.QueryParameterMatchers, &out.QueryParameterMatchers + *out = make([]QueryParameterMatcher, len(*in)) + copy(*out, *in) + } + if in.Methods != nil { + in, out := &in.Methods, &out.Methods + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Matcher. +func (in *Matcher) DeepCopy() *Matcher { + if in == nil { + return nil + } + out := new(Matcher) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiDestination) DeepCopyInto(out *MultiDestination) { + *out = *in + if in.Destinations != nil { + in, out := &in.Destinations, &out.Destinations + *out = make([]WeightedDestination, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiDestination. +func (in *MultiDestination) DeepCopy() *MultiDestination { + if in == nil { + return nil + } + out := new(MultiDestination) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *QueryParameterMatcher) DeepCopyInto(out *QueryParameterMatcher) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterMatcher. +func (in *QueryParameterMatcher) DeepCopy() *QueryParameterMatcher { + if in == nil { + return nil + } + out := new(QueryParameterMatcher) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceRef) DeepCopyInto(out *ResourceRef) { *out = *in @@ -58,7 +142,48 @@ func (in *ResourceRef) DeepCopy() *ResourceRef { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UpstreamGroup) DeepCopyInto(out *UpstreamGroup) { +func (in *Route) DeepCopyInto(out *Route) { + *out = *in + if in.Matchers != nil { + in, out := &in.Matchers, &out.Matchers + *out = make([]Matcher, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Action.DeepCopyInto(&out.Action) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route. +func (in *Route) DeepCopy() *Route { + if in == nil { + return nil + } + out := new(Route) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteAction) DeepCopyInto(out *RouteAction) { + *out = *in + in.Destination.DeepCopyInto(&out.Destination) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteAction. +func (in *RouteAction) DeepCopy() *RouteAction { + if in == nil { + return nil + } + out := new(RouteAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteTable) DeepCopyInto(out *RouteTable) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -66,18 +191,18 @@ func (in *UpstreamGroup) DeepCopyInto(out *UpstreamGroup) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamGroup. -func (in *UpstreamGroup) DeepCopy() *UpstreamGroup { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTable. +func (in *RouteTable) DeepCopy() *RouteTable { if in == nil { return nil } - out := new(UpstreamGroup) + out := new(RouteTable) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *UpstreamGroup) DeepCopyObject() runtime.Object { +func (in *RouteTable) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -85,13 +210,13 @@ func (in *UpstreamGroup) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UpstreamGroupList) DeepCopyInto(out *UpstreamGroupList) { +func (in *RouteTableList) DeepCopyInto(out *RouteTableList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]UpstreamGroup, len(*in)) + *out = make([]RouteTable, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -99,18 +224,18 @@ func (in *UpstreamGroupList) DeepCopyInto(out *UpstreamGroupList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamGroupList. -func (in *UpstreamGroupList) DeepCopy() *UpstreamGroupList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTableList. +func (in *RouteTableList) DeepCopy() *RouteTableList { if in == nil { return nil } - out := new(UpstreamGroupList) + out := new(RouteTableList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *UpstreamGroupList) DeepCopyObject() runtime.Object { +func (in *RouteTableList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -118,22 +243,24 @@ func (in *UpstreamGroupList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UpstreamGroupSpec) DeepCopyInto(out *UpstreamGroupSpec) { +func (in *RouteTableSpec) DeepCopyInto(out *RouteTableSpec) { *out = *in - if in.Destinations != nil { - in, out := &in.Destinations, &out.Destinations - *out = make([]WeightedDestination, len(*in)) - copy(*out, *in) + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = make([]Route, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamGroupSpec. -func (in *UpstreamGroupSpec) DeepCopy() *UpstreamGroupSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteTableSpec. +func (in *RouteTableSpec) DeepCopy() *RouteTableSpec { if in == nil { return nil } - out := new(UpstreamGroupSpec) + out := new(RouteTableSpec) in.DeepCopyInto(out) return out } diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index c8b0a2aea..4ec16141e 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -24,7 +24,7 @@ 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" - gloov1 "github.com/fluxcd/flagger/pkg/client/clientset/versioned/typed/gloo/v1" + gatewayv1 "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" @@ -40,7 +40,7 @@ type Interface interface { AppmeshV1beta2() appmeshv1beta2.AppmeshV1beta2Interface AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface - GlooV1() gloov1.GlooV1Interface + GatewayV1() gatewayv1.GatewayV1Interface NetworkingV1alpha3() networkingv1alpha3.NetworkingV1alpha3Interface ProjectcontourV1() projectcontourv1.ProjectcontourV1Interface SplitV1alpha1() splitv1alpha1.SplitV1alpha1Interface @@ -55,7 +55,7 @@ type Clientset struct { appmeshV1beta2 *appmeshv1beta2.AppmeshV1beta2Client appmeshV1beta1 *appmeshv1beta1.AppmeshV1beta1Client flaggerV1beta1 *flaggerv1beta1.FlaggerV1beta1Client - glooV1 *gloov1.GlooV1Client + gatewayV1 *gatewayv1.GatewayV1Client networkingV1alpha3 *networkingv1alpha3.NetworkingV1alpha3Client projectcontourV1 *projectcontourv1.ProjectcontourV1Client splitV1alpha1 *splitv1alpha1.SplitV1alpha1Client @@ -78,9 +78,9 @@ func (c *Clientset) FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface { return c.flaggerV1beta1 } -// GlooV1 retrieves the GlooV1Client -func (c *Clientset) GlooV1() gloov1.GlooV1Interface { - return c.glooV1 +// GatewayV1 retrieves the GatewayV1Client +func (c *Clientset) GatewayV1() gatewayv1.GatewayV1Interface { + return c.gatewayV1 } // NetworkingV1alpha3 retrieves the NetworkingV1alpha3Client @@ -141,7 +141,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { if err != nil { return nil, err } - cs.glooV1, err = gloov1.NewForConfig(&configShallowCopy) + cs.gatewayV1, err = gatewayv1.NewForConfig(&configShallowCopy) if err != nil { return nil, err } @@ -180,7 +180,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { cs.appmeshV1beta2 = appmeshv1beta2.NewForConfigOrDie(c) cs.appmeshV1beta1 = appmeshv1beta1.NewForConfigOrDie(c) cs.flaggerV1beta1 = flaggerv1beta1.NewForConfigOrDie(c) - cs.glooV1 = gloov1.NewForConfigOrDie(c) + cs.gatewayV1 = gatewayv1.NewForConfigOrDie(c) cs.networkingV1alpha3 = networkingv1alpha3.NewForConfigOrDie(c) cs.projectcontourV1 = projectcontourv1.NewForConfigOrDie(c) cs.splitV1alpha1 = splitv1alpha1.NewForConfigOrDie(c) @@ -197,7 +197,7 @@ func New(c rest.Interface) *Clientset { cs.appmeshV1beta2 = appmeshv1beta2.New(c) cs.appmeshV1beta1 = appmeshv1beta1.New(c) cs.flaggerV1beta1 = flaggerv1beta1.New(c) - cs.glooV1 = gloov1.New(c) + cs.gatewayV1 = gatewayv1.New(c) cs.networkingV1alpha3 = networkingv1alpha3.New(c) cs.projectcontourV1 = projectcontourv1.New(c) cs.splitV1alpha1 = splitv1alpha1.New(c) diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index bb5e26c72..2edd507e1 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -26,8 +26,8 @@ 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" - 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" + 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" 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" @@ -107,9 +107,9 @@ func (c *Clientset) FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface { return &fakeflaggerv1beta1.FakeFlaggerV1beta1{Fake: &c.Fake} } -// GlooV1 retrieves the GlooV1Client -func (c *Clientset) GlooV1() gloov1.GlooV1Interface { - return &fakegloov1.FakeGlooV1{Fake: &c.Fake} +// GatewayV1 retrieves the GatewayV1Client +func (c *Clientset) GatewayV1() gatewayv1.GatewayV1Interface { + return &fakegatewayv1.FakeGatewayV1{Fake: &c.Fake} } // NetworkingV1alpha3 retrieves the NetworkingV1alpha3Client diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index b67c97ea4..594564dfd 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -22,7 +22,7 @@ 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" - gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1" + gatewayv1 "github.com/fluxcd/flagger/pkg/apis/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" @@ -42,7 +42,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ appmeshv1beta2.AddToScheme, appmeshv1beta1.AddToScheme, flaggerv1beta1.AddToScheme, - gloov1.AddToScheme, + gatewayv1.AddToScheme, networkingv1alpha3.AddToScheme, projectcontourv1.AddToScheme, splitv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 25d23a6d7..069b7f0fc 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -22,7 +22,7 @@ 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" - gloov1 "github.com/fluxcd/flagger/pkg/apis/gloo/v1" + gatewayv1 "github.com/fluxcd/flagger/pkg/apis/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" @@ -42,7 +42,7 @@ var localSchemeBuilder = runtime.SchemeBuilder{ appmeshv1beta2.AddToScheme, appmeshv1beta1.AddToScheme, flaggerv1beta1.AddToScheme, - gloov1.AddToScheme, + gatewayv1.AddToScheme, networkingv1alpha3.AddToScheme, projectcontourv1.AddToScheme, splitv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_gloo_client.go b/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_gloo_client.go index ad0765f75..f2815d437 100644 --- a/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_gloo_client.go +++ b/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_gloo_client.go @@ -24,17 +24,17 @@ import ( testing "k8s.io/client-go/testing" ) -type FakeGlooV1 struct { +type FakeGatewayV1 struct { *testing.Fake } -func (c *FakeGlooV1) UpstreamGroups(namespace string) v1.UpstreamGroupInterface { - return &FakeUpstreamGroups{c, namespace} +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 *FakeGlooV1) RESTClient() rest.Interface { +func (c *FakeGatewayV1) RESTClient() rest.Interface { var ret *rest.RESTClient return ret } diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_routetable.go b/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_routetable.go new file mode 100644 index 000000000..0d9d62179 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_routetable.go @@ -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/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" +) + +// FakeRouteTables implements RouteTableInterface +type FakeRouteTables struct { + Fake *FakeGatewayV1 + ns string +} + +var routetablesResource = schema.GroupVersionResource{Group: "gateway.solo.io", Version: "v1", Resource: "routetables"} + +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) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(routetablesResource, c.ns, name), &gloov1.RouteTable{}) + + if obj == nil { + return nil, err + } + return obj.(*gloov1.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) { + obj, err := c.Fake. + Invokes(testing.NewListAction(routetablesResource, routetablesKind, c.ns, opts), &gloov1.RouteTableList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &gloov1.RouteTableList{ListMeta: obj.(*gloov1.RouteTableList).ListMeta} + for _, item := range obj.(*gloov1.RouteTableList).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 routeTables. +func (c *FakeRouteTables) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(routetablesResource, c.ns, opts)) + +} + +// 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) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(routetablesResource, c.ns, routeTable), &gloov1.RouteTable{}) + + if obj == nil { + return nil, err + } + return obj.(*gloov1.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) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(routetablesResource, c.ns, routeTable), &gloov1.RouteTable{}) + + if obj == nil { + return nil, err + } + return obj.(*gloov1.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{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +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{}) + 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) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(routetablesResource, c.ns, name, pt, data, subresources...), &gloov1.RouteTable{}) + + if obj == nil { + return nil, err + } + return obj.(*gloov1.RouteTable), err +} diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_upstreamgroup.go b/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_upstreamgroup.go deleted file mode 100644 index efc808000..000000000 --- a/pkg/client/clientset/versioned/typed/gloo/v1/fake/fake_upstreamgroup.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -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/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" -) - -// FakeUpstreamGroups implements UpstreamGroupInterface -type FakeUpstreamGroups struct { - Fake *FakeGlooV1 - ns string -} - -var upstreamgroupsResource = schema.GroupVersionResource{Group: "gloo.solo.io", Version: "v1", Resource: "upstreamgroups"} - -var upstreamgroupsKind = schema.GroupVersionKind{Group: "gloo.solo.io", Version: "v1", Kind: "UpstreamGroup"} - -// Get takes name of the upstreamGroup, and returns the corresponding upstreamGroup object, and an error if there is any. -func (c *FakeUpstreamGroups) Get(ctx context.Context, name string, options v1.GetOptions) (result *gloov1.UpstreamGroup, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetAction(upstreamgroupsResource, c.ns, name), &gloov1.UpstreamGroup{}) - - if obj == nil { - return nil, err - } - return obj.(*gloov1.UpstreamGroup), err -} - -// List takes label and field selectors, and returns the list of UpstreamGroups that match those selectors. -func (c *FakeUpstreamGroups) List(ctx context.Context, opts v1.ListOptions) (result *gloov1.UpstreamGroupList, err error) { - obj, err := c.Fake. - Invokes(testing.NewListAction(upstreamgroupsResource, upstreamgroupsKind, c.ns, opts), &gloov1.UpstreamGroupList{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &gloov1.UpstreamGroupList{ListMeta: obj.(*gloov1.UpstreamGroupList).ListMeta} - for _, item := range obj.(*gloov1.UpstreamGroupList).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 upstreamGroups. -func (c *FakeUpstreamGroups) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchAction(upstreamgroupsResource, c.ns, opts)) - -} - -// Create takes the representation of a upstreamGroup and creates it. Returns the server's representation of the upstreamGroup, and an error, if there is any. -func (c *FakeUpstreamGroups) Create(ctx context.Context, upstreamGroup *gloov1.UpstreamGroup, opts v1.CreateOptions) (result *gloov1.UpstreamGroup, err error) { - obj, err := c.Fake. - Invokes(testing.NewCreateAction(upstreamgroupsResource, c.ns, upstreamGroup), &gloov1.UpstreamGroup{}) - - if obj == nil { - return nil, err - } - return obj.(*gloov1.UpstreamGroup), err -} - -// Update takes the representation of a upstreamGroup and updates it. Returns the server's representation of the upstreamGroup, and an error, if there is any. -func (c *FakeUpstreamGroups) Update(ctx context.Context, upstreamGroup *gloov1.UpstreamGroup, opts v1.UpdateOptions) (result *gloov1.UpstreamGroup, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateAction(upstreamgroupsResource, c.ns, upstreamGroup), &gloov1.UpstreamGroup{}) - - if obj == nil { - return nil, err - } - return obj.(*gloov1.UpstreamGroup), err -} - -// Delete takes name of the upstreamGroup and deletes it. Returns an error if one occurs. -func (c *FakeUpstreamGroups) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteAction(upstreamgroupsResource, c.ns, name), &gloov1.UpstreamGroup{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeUpstreamGroups) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(upstreamgroupsResource, c.ns, listOpts) - - _, err := c.Fake.Invokes(action, &gloov1.UpstreamGroupList{}) - return err -} - -// Patch applies the patch and returns the patched upstreamGroup. -func (c *FakeUpstreamGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *gloov1.UpstreamGroup, err error) { - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(upstreamgroupsResource, c.ns, name, pt, data, subresources...), &gloov1.UpstreamGroup{}) - - if obj == nil { - return nil, err - } - return obj.(*gloov1.UpstreamGroup), err -} diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/gloo/v1/generated_expansion.go index 6f7081579..972af2a93 100644 --- a/pkg/client/clientset/versioned/typed/gloo/v1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/gloo/v1/generated_expansion.go @@ -18,4 +18,4 @@ limitations under the License. package v1 -type UpstreamGroupExpansion interface{} +type RouteTableExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/gloo_client.go b/pkg/client/clientset/versioned/typed/gloo/v1/gloo_client.go index b952e19c3..10e1fe2a5 100644 --- a/pkg/client/clientset/versioned/typed/gloo/v1/gloo_client.go +++ b/pkg/client/clientset/versioned/typed/gloo/v1/gloo_client.go @@ -24,22 +24,22 @@ import ( rest "k8s.io/client-go/rest" ) -type GlooV1Interface interface { +type GatewayV1Interface interface { RESTClient() rest.Interface - UpstreamGroupsGetter + RouteTablesGetter } -// GlooV1Client is used to interact with features provided by the gloo.solo.io group. -type GlooV1Client struct { +// GatewayV1Client is used to interact with features provided by the gateway.solo.io group. +type GatewayV1Client struct { restClient rest.Interface } -func (c *GlooV1Client) UpstreamGroups(namespace string) UpstreamGroupInterface { - return newUpstreamGroups(c, namespace) +func (c *GatewayV1Client) RouteTables(namespace string) RouteTableInterface { + return newRouteTables(c, namespace) } -// NewForConfig creates a new GlooV1Client for the given config. -func NewForConfig(c *rest.Config) (*GlooV1Client, error) { +// 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 @@ -48,12 +48,12 @@ func NewForConfig(c *rest.Config) (*GlooV1Client, error) { if err != nil { return nil, err } - return &GlooV1Client{client}, nil + return &GatewayV1Client{client}, nil } -// NewForConfigOrDie creates a new GlooV1Client for the given config and +// NewForConfigOrDie creates a new GatewayV1Client for the given config and // panics if there is an error in the config. -func NewForConfigOrDie(c *rest.Config) *GlooV1Client { +func NewForConfigOrDie(c *rest.Config) *GatewayV1Client { client, err := NewForConfig(c) if err != nil { panic(err) @@ -61,9 +61,9 @@ func NewForConfigOrDie(c *rest.Config) *GlooV1Client { return client } -// New creates a new GlooV1Client for the given RESTClient. -func New(c rest.Interface) *GlooV1Client { - return &GlooV1Client{c} +// New creates a new GatewayV1Client for the given RESTClient. +func New(c rest.Interface) *GatewayV1Client { + return &GatewayV1Client{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 *GlooV1Client) RESTClient() rest.Interface { +func (c *GatewayV1Client) RESTClient() rest.Interface { if c == nil { return nil } diff --git a/pkg/client/clientset/versioned/typed/gloo/v1/upstreamgroup.go b/pkg/client/clientset/versioned/typed/gloo/v1/routetable.go similarity index 50% rename from pkg/client/clientset/versioned/typed/gloo/v1/upstreamgroup.go rename to pkg/client/clientset/versioned/typed/gloo/v1/routetable.go index 767fe3dbb..11936cbfd 100644 --- a/pkg/client/clientset/versioned/typed/gloo/v1/upstreamgroup.go +++ b/pkg/client/clientset/versioned/typed/gloo/v1/routetable.go @@ -30,45 +30,45 @@ import ( rest "k8s.io/client-go/rest" ) -// UpstreamGroupsGetter has a method to return a UpstreamGroupInterface. +// RouteTablesGetter has a method to return a RouteTableInterface. // A group's client should implement this interface. -type UpstreamGroupsGetter interface { - UpstreamGroups(namespace string) UpstreamGroupInterface +type RouteTablesGetter interface { + RouteTables(namespace string) RouteTableInterface } -// UpstreamGroupInterface has methods to work with UpstreamGroup resources. -type UpstreamGroupInterface interface { - Create(ctx context.Context, upstreamGroup *v1.UpstreamGroup, opts metav1.CreateOptions) (*v1.UpstreamGroup, error) - Update(ctx context.Context, upstreamGroup *v1.UpstreamGroup, opts metav1.UpdateOptions) (*v1.UpstreamGroup, error) +// RouteTableInterface has methods to work with RouteTable resources. +type RouteTableInterface interface { + Create(ctx context.Context, routeTable *v1.RouteTable, opts metav1.CreateOptions) (*v1.RouteTable, error) + Update(ctx context.Context, routeTable *v1.RouteTable, opts metav1.UpdateOptions) (*v1.RouteTable, 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.UpstreamGroup, error) - List(ctx context.Context, opts metav1.ListOptions) (*v1.UpstreamGroupList, error) + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RouteTable, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RouteTableList, 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.UpstreamGroup, err error) - UpstreamGroupExpansion + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RouteTable, err error) + RouteTableExpansion } -// upstreamGroups implements UpstreamGroupInterface -type upstreamGroups struct { +// routeTables implements RouteTableInterface +type routeTables struct { client rest.Interface ns string } -// newUpstreamGroups returns a UpstreamGroups -func newUpstreamGroups(c *GlooV1Client, namespace string) *upstreamGroups { - return &upstreamGroups{ +// newRouteTables returns a RouteTables +func newRouteTables(c *GatewayV1Client, namespace string) *routeTables { + return &routeTables{ client: c.RESTClient(), ns: namespace, } } -// Get takes name of the upstreamGroup, and returns the corresponding upstreamGroup object, and an error if there is any. -func (c *upstreamGroups) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.UpstreamGroup, err error) { - result = &v1.UpstreamGroup{} +// Get takes name of the routeTable, and returns the corresponding routeTable object, and an error if there is any. +func (c *routeTables) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RouteTable, err error) { + result = &v1.RouteTable{} err = c.client.Get(). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). Name(name). VersionedParams(&options, scheme.ParameterCodec). Do(ctx). @@ -76,16 +76,16 @@ func (c *upstreamGroups) Get(ctx context.Context, name string, options metav1.Ge return } -// List takes label and field selectors, and returns the list of UpstreamGroups that match those selectors. -func (c *upstreamGroups) List(ctx context.Context, opts metav1.ListOptions) (result *v1.UpstreamGroupList, err error) { +// List takes label and field selectors, and returns the list of RouteTables that match those selectors. +func (c *routeTables) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RouteTableList, err error) { var timeout time.Duration if opts.TimeoutSeconds != nil { timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } - result = &v1.UpstreamGroupList{} + result = &v1.RouteTableList{} err = c.client.Get(). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). Do(ctx). @@ -93,8 +93,8 @@ func (c *upstreamGroups) List(ctx context.Context, opts metav1.ListOptions) (res return } -// Watch returns a watch.Interface that watches the requested upstreamGroups. -func (c *upstreamGroups) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { +// Watch returns a watch.Interface that watches the requested routeTables. +func (c *routeTables) 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 @@ -102,44 +102,44 @@ func (c *upstreamGroups) Watch(ctx context.Context, opts metav1.ListOptions) (wa opts.Watch = true return c.client.Get(). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). VersionedParams(&opts, scheme.ParameterCodec). Timeout(timeout). Watch(ctx) } -// Create takes the representation of a upstreamGroup and creates it. Returns the server's representation of the upstreamGroup, and an error, if there is any. -func (c *upstreamGroups) Create(ctx context.Context, upstreamGroup *v1.UpstreamGroup, opts metav1.CreateOptions) (result *v1.UpstreamGroup, err error) { - result = &v1.UpstreamGroup{} +// 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 *routeTables) Create(ctx context.Context, routeTable *v1.RouteTable, opts metav1.CreateOptions) (result *v1.RouteTable, err error) { + result = &v1.RouteTable{} err = c.client.Post(). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). VersionedParams(&opts, scheme.ParameterCodec). - Body(upstreamGroup). + Body(routeTable). Do(ctx). Into(result) return } -// Update takes the representation of a upstreamGroup and updates it. Returns the server's representation of the upstreamGroup, and an error, if there is any. -func (c *upstreamGroups) Update(ctx context.Context, upstreamGroup *v1.UpstreamGroup, opts metav1.UpdateOptions) (result *v1.UpstreamGroup, err error) { - result = &v1.UpstreamGroup{} +// 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 *routeTables) Update(ctx context.Context, routeTable *v1.RouteTable, opts metav1.UpdateOptions) (result *v1.RouteTable, err error) { + result = &v1.RouteTable{} err = c.client.Put(). Namespace(c.ns). - Resource("upstreamgroups"). - Name(upstreamGroup.Name). + Resource("routetables"). + Name(routeTable.Name). VersionedParams(&opts, scheme.ParameterCodec). - Body(upstreamGroup). + Body(routeTable). Do(ctx). Into(result) return } -// Delete takes name of the upstreamGroup and deletes it. Returns an error if one occurs. -func (c *upstreamGroups) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { +// Delete takes name of the routeTable and deletes it. Returns an error if one occurs. +func (c *routeTables) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { return c.client.Delete(). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). Name(name). Body(&opts). Do(ctx). @@ -147,14 +147,14 @@ func (c *upstreamGroups) Delete(ctx context.Context, name string, opts metav1.De } // DeleteCollection deletes a collection of objects. -func (c *upstreamGroups) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { +func (c *routeTables) 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("upstreamgroups"). + Resource("routetables"). VersionedParams(&listOpts, scheme.ParameterCodec). Timeout(timeout). Body(&opts). @@ -162,12 +162,12 @@ func (c *upstreamGroups) DeleteCollection(ctx context.Context, opts metav1.Delet Error() } -// Patch applies the patch and returns the patched upstreamGroup. -func (c *upstreamGroups) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.UpstreamGroup, err error) { - result = &v1.UpstreamGroup{} +// Patch applies the patch and returns the patched routeTable. +func (c *routeTables) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RouteTable, err error) { + result = &v1.RouteTable{} err = c.client.Patch(pt). Namespace(c.ns). - Resource("upstreamgroups"). + Resource("routetables"). Name(name). SubResource(subresources...). VersionedParams(&opts, scheme.ParameterCodec). diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index cd9df5562..c744ac0e9 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -180,7 +180,7 @@ type SharedInformerFactory interface { Appmesh() appmesh.Interface Flagger() flagger.Interface - Gloo() gloo.Interface + Gateway() gloo.Interface Networking() istio.Interface Projectcontour() projectcontour.Interface Split() smi.Interface @@ -195,7 +195,7 @@ func (f *sharedInformerFactory) Flagger() flagger.Interface { return flagger.New(f, f.namespace, f.tweakListOptions) } -func (f *sharedInformerFactory) Gloo() gloo.Interface { +func (f *sharedInformerFactory) Gateway() gloo.Interface { return gloo.New(f, f.namespace, f.tweakListOptions) } diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index efc6c50e7..5182a4e12 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -84,9 +84,9 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case flaggerv1beta1.SchemeGroupVersion.WithResource("metrictemplates"): return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1beta1().MetricTemplates().Informer()}, nil - // Group=gloo.solo.io, Version=v1 - case v1.SchemeGroupVersion.WithResource("upstreamgroups"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Gloo().V1().UpstreamGroups().Informer()}, nil + // Group=gateway.solo.io, Version=v1 + case v1.SchemeGroupVersion.WithResource("routetables"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Gateway().V1().RouteTables().Informer()}, nil // Group=networking.istio.io, Version=v1alpha3 case v1alpha3.SchemeGroupVersion.WithResource("destinationrules"): diff --git a/pkg/client/informers/externalversions/gloo/v1/interface.go b/pkg/client/informers/externalversions/gloo/v1/interface.go index 84676e080..1b5a8391a 100644 --- a/pkg/client/informers/externalversions/gloo/v1/interface.go +++ b/pkg/client/informers/externalversions/gloo/v1/interface.go @@ -24,8 +24,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // UpstreamGroups returns a UpstreamGroupInformer. - UpstreamGroups() UpstreamGroupInformer + // RouteTables returns a RouteTableInformer. + RouteTables() RouteTableInformer } type version struct { @@ -39,7 +39,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// UpstreamGroups returns a UpstreamGroupInformer. -func (v *version) UpstreamGroups() UpstreamGroupInformer { - return &upstreamGroupInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +// RouteTables returns a RouteTableInformer. +func (v *version) RouteTables() RouteTableInformer { + return &routeTableInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } diff --git a/pkg/client/informers/externalversions/gloo/v1/upstreamgroup.go b/pkg/client/informers/externalversions/gloo/v1/routetable.go similarity index 57% rename from pkg/client/informers/externalversions/gloo/v1/upstreamgroup.go rename to pkg/client/informers/externalversions/gloo/v1/routetable.go index 74faa191f..38cafeaa3 100644 --- a/pkg/client/informers/externalversions/gloo/v1/upstreamgroup.go +++ b/pkg/client/informers/externalversions/gloo/v1/routetable.go @@ -32,59 +32,59 @@ import ( cache "k8s.io/client-go/tools/cache" ) -// UpstreamGroupInformer provides access to a shared informer and lister for -// UpstreamGroups. -type UpstreamGroupInformer interface { +// RouteTableInformer provides access to a shared informer and lister for +// RouteTables. +type RouteTableInformer interface { Informer() cache.SharedIndexInformer - Lister() v1.UpstreamGroupLister + Lister() v1.RouteTableLister } -type upstreamGroupInformer struct { +type routeTableInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc namespace string } -// NewUpstreamGroupInformer constructs a new informer for UpstreamGroup type. +// NewRouteTableInformer constructs a new informer for RouteTable 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 NewUpstreamGroupInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredUpstreamGroupInformer(client, namespace, resyncPeriod, indexers, nil) +func NewRouteTableInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRouteTableInformer(client, namespace, resyncPeriod, indexers, nil) } -// NewFilteredUpstreamGroupInformer constructs a new informer for UpstreamGroup type. +// NewFilteredRouteTableInformer constructs a new informer for RouteTable 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 NewFilteredUpstreamGroupInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredRouteTableInformer(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().UpstreamGroups(namespace).List(context.TODO(), options) + return client.GatewayV1().RouteTables(namespace).List(context.TODO(), options) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.GlooV1().UpstreamGroups(namespace).Watch(context.TODO(), options) + return client.GatewayV1().RouteTables(namespace).Watch(context.TODO(), options) }, }, - &gloov1.UpstreamGroup{}, + &gloov1.RouteTable{}, resyncPeriod, indexers, ) } -func (f *upstreamGroupInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredUpstreamGroupInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *routeTableInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRouteTableInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *upstreamGroupInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&gloov1.UpstreamGroup{}, f.defaultInformer) +func (f *routeTableInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&gloov1.RouteTable{}, f.defaultInformer) } -func (f *upstreamGroupInformer) Lister() v1.UpstreamGroupLister { - return v1.NewUpstreamGroupLister(f.Informer().GetIndexer()) +func (f *routeTableInformer) Lister() v1.RouteTableLister { + return v1.NewRouteTableLister(f.Informer().GetIndexer()) } diff --git a/pkg/client/listers/gloo/v1/expansion_generated.go b/pkg/client/listers/gloo/v1/expansion_generated.go index 3e8810ccc..4902c03fc 100644 --- a/pkg/client/listers/gloo/v1/expansion_generated.go +++ b/pkg/client/listers/gloo/v1/expansion_generated.go @@ -18,10 +18,10 @@ limitations under the License. package v1 -// UpstreamGroupListerExpansion allows custom methods to be added to -// UpstreamGroupLister. -type UpstreamGroupListerExpansion interface{} +// RouteTableListerExpansion allows custom methods to be added to +// RouteTableLister. +type RouteTableListerExpansion interface{} -// UpstreamGroupNamespaceListerExpansion allows custom methods to be added to -// UpstreamGroupNamespaceLister. -type UpstreamGroupNamespaceListerExpansion interface{} +// RouteTableNamespaceListerExpansion allows custom methods to be added to +// RouteTableNamespaceLister. +type RouteTableNamespaceListerExpansion interface{} diff --git a/pkg/client/listers/gloo/v1/routetable.go b/pkg/client/listers/gloo/v1/routetable.go new file mode 100644 index 000000000..6e2fb30b9 --- /dev/null +++ b/pkg/client/listers/gloo/v1/routetable.go @@ -0,0 +1,94 @@ +/* +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/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RouteTableLister helps list RouteTables. +type RouteTableLister interface { + // List lists all RouteTables in the indexer. + List(selector labels.Selector) (ret []*v1.RouteTable, err error) + // RouteTables returns an object that can list and get RouteTables. + RouteTables(namespace string) RouteTableNamespaceLister + RouteTableListerExpansion +} + +// routeTableLister implements the RouteTableLister interface. +type routeTableLister struct { + indexer cache.Indexer +} + +// NewRouteTableLister returns a new RouteTableLister. +func NewRouteTableLister(indexer cache.Indexer) RouteTableLister { + return &routeTableLister{indexer: indexer} +} + +// List lists all RouteTables in the indexer. +func (s *routeTableLister) List(selector labels.Selector) (ret []*v1.RouteTable, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RouteTable)) + }) + return ret, err +} + +// RouteTables returns an object that can list and get RouteTables. +func (s *routeTableLister) RouteTables(namespace string) RouteTableNamespaceLister { + return routeTableNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RouteTableNamespaceLister helps list and get RouteTables. +type RouteTableNamespaceLister interface { + // List lists all RouteTables in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1.RouteTable, err error) + // Get retrieves the RouteTable from the indexer for a given namespace and name. + Get(name string) (*v1.RouteTable, error) + RouteTableNamespaceListerExpansion +} + +// routeTableNamespaceLister implements the RouteTableNamespaceLister +// interface. +type routeTableNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all RouteTables in the indexer for a given namespace. +func (s routeTableNamespaceLister) List(selector labels.Selector) (ret []*v1.RouteTable, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RouteTable)) + }) + return ret, err +} + +// Get retrieves the RouteTable from the indexer for a given namespace and name. +func (s routeTableNamespaceLister) Get(name string) (*v1.RouteTable, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("routetable"), name) + } + return obj.(*v1.RouteTable), nil +} diff --git a/pkg/client/listers/gloo/v1/upstreamgroup.go b/pkg/client/listers/gloo/v1/upstreamgroup.go deleted file mode 100644 index 430a31e53..000000000 --- a/pkg/client/listers/gloo/v1/upstreamgroup.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -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/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// UpstreamGroupLister helps list UpstreamGroups. -type UpstreamGroupLister interface { - // List lists all UpstreamGroups in the indexer. - List(selector labels.Selector) (ret []*v1.UpstreamGroup, err error) - // UpstreamGroups returns an object that can list and get UpstreamGroups. - UpstreamGroups(namespace string) UpstreamGroupNamespaceLister - UpstreamGroupListerExpansion -} - -// upstreamGroupLister implements the UpstreamGroupLister interface. -type upstreamGroupLister struct { - indexer cache.Indexer -} - -// NewUpstreamGroupLister returns a new UpstreamGroupLister. -func NewUpstreamGroupLister(indexer cache.Indexer) UpstreamGroupLister { - return &upstreamGroupLister{indexer: indexer} -} - -// List lists all UpstreamGroups in the indexer. -func (s *upstreamGroupLister) List(selector labels.Selector) (ret []*v1.UpstreamGroup, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1.UpstreamGroup)) - }) - return ret, err -} - -// UpstreamGroups returns an object that can list and get UpstreamGroups. -func (s *upstreamGroupLister) UpstreamGroups(namespace string) UpstreamGroupNamespaceLister { - return upstreamGroupNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// UpstreamGroupNamespaceLister helps list and get UpstreamGroups. -type UpstreamGroupNamespaceLister interface { - // List lists all UpstreamGroups in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1.UpstreamGroup, err error) - // Get retrieves the UpstreamGroup from the indexer for a given namespace and name. - Get(name string) (*v1.UpstreamGroup, error) - UpstreamGroupNamespaceListerExpansion -} - -// upstreamGroupNamespaceLister implements the UpstreamGroupNamespaceLister -// interface. -type upstreamGroupNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all UpstreamGroups in the indexer for a given namespace. -func (s upstreamGroupNamespaceLister) List(selector labels.Selector) (ret []*v1.UpstreamGroup, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1.UpstreamGroup)) - }) - return ret, err -} - -// Get retrieves the UpstreamGroup from the indexer for a given namespace and name. -func (s upstreamGroupNamespaceLister) Get(name string) (*v1.UpstreamGroup, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1.Resource("upstreamgroup"), name) - } - return obj.(*v1.UpstreamGroup), nil -} diff --git a/pkg/router/gloo.go b/pkg/router/gloo.go index 86e97193f..3e849be37 100644 --- a/pkg/router/gloo.go +++ b/pkg/router/gloo.go @@ -33,7 +33,7 @@ import ( clientset "github.com/fluxcd/flagger/pkg/client/clientset/versioned" ) -// GlooRouter is managing Istio virtual services +// GlooRouter is managing Gloo route tables type GlooRouter struct { kubeClient kubernetes.Interface glooClient clientset.Interface @@ -42,38 +42,49 @@ type GlooRouter struct { upstreamDiscoveryNs string } -// Reconcile creates or updates the Istio virtual service +// 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) - newSpec := gloov1.UpstreamGroupSpec{ - Destinations: []gloov1.WeightedDestination{ + newSpec := gloov1.RouteTableSpec{ + Routes: []gloov1.Route{ { - Destination: gloov1.Destination{ - Upstream: gloov1.ResourceRef{ - Name: primaryName, - Namespace: gr.upstreamDiscoveryNs, + InheritablePathMatchers: true, + Matchers: getMatchers(canary), + Action: gloov1.RouteAction{ + Destination: gloov1.MultiDestination{ + Destinations: []gloov1.WeightedDestination{ + { + Destination: gloov1.Destination{ + Upstream: gloov1.ResourceRef{ + Name: primaryName, + Namespace: gr.upstreamDiscoveryNs, + }, + }, + Weight: 100, + }, + { + Destination: gloov1.Destination{ + Upstream: gloov1.ResourceRef{ + Name: canaryName, + Namespace: gr.upstreamDiscoveryNs, + }, + }, + Weight: 0, + }, + }, }, }, - Weight: 100, - }, - { - Destination: gloov1.Destination{ - Upstream: gloov1.ResourceRef{ - Name: canaryName, - Namespace: gr.upstreamDiscoveryNs, - }, - }, - Weight: 0, }, }, } - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) + routeTable, err := gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) if errors.IsNotFound(err) { - upstreamGroup = &gloov1.UpstreamGroup{ + + routeTable = &gloov1.RouteTable{ ObjectMeta: metav1.ObjectMeta{ Name: apexName, Namespace: canary.Namespace, @@ -88,33 +99,33 @@ func (gr *GlooRouter) Reconcile(canary *flaggerv1.Canary) error { Spec: newSpec, } - _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Create(context.TODO(), upstreamGroup, metav1.CreateOptions{}) + _, err = gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Create(context.TODO(), routeTable, metav1.CreateOptions{}) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s create error: %w", apexName, canary.Namespace, err) + return fmt.Errorf("RouteTable %s.%s create error: %w", apexName, canary.Namespace, err) } gr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). - Infof("UpstreamGroup %s.%s created", upstreamGroup.GetName(), canary.Namespace) + Infof("RouteTable %s.%s created", routeTable.GetName(), canary.Namespace) return nil } else if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s get query error: %w", apexName, canary.Namespace, err) + return fmt.Errorf("RouteTable %s.%s get query error: %w", apexName, canary.Namespace, err) } - // update upstreamGroup but keep the original destination weights - if upstreamGroup != nil { + // update routeTable but keep the original destination weights + if routeTable != nil { if diff := cmp.Diff( newSpec, - upstreamGroup.Spec, + routeTable.Spec, cmpopts.IgnoreFields(gloov1.WeightedDestination{}, "Weight"), ); diff != "" { - clone := upstreamGroup.DeepCopy() + clone := routeTable.DeepCopy() clone.Spec = newSpec - _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Update(context.TODO(), clone, metav1.UpdateOptions{}) + _, err = gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Update(context.TODO(), clone, metav1.UpdateOptions{}) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s update error: %w", apexName, canary.Namespace, err) + return fmt.Errorf("RouteTable %s.%s update error: %w", apexName, canary.Namespace, err) } gr.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). - Infof("UpstreamGroup %s.%s updated", upstreamGroup.GetName(), canary.Namespace) + Infof("RouteTable %s.%s updated", routeTable.GetName(), canary.Namespace) } } @@ -131,18 +142,18 @@ func (gr *GlooRouter) GetRoutes(canary *flaggerv1.Canary) ( apexName := canary.Spec.TargetRef.Name primaryName := fmt.Sprintf("%s-%s-primary-%v", canary.Namespace, canary.Spec.TargetRef.Name, canary.Spec.Service.Port) - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) + routeTable, err := gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) if err != nil { - err = fmt.Errorf("UpstreamGroup %s.%s get query error: %w", apexName, canary.Namespace, err) + err = fmt.Errorf("RouteTable %s.%s get query error: %w", apexName, canary.Namespace, err) return } - if len(upstreamGroup.Spec.Destinations) < 2 { - err = fmt.Errorf("UpstreamGroup %s.%s destinations not found", apexName, canary.Namespace) + if len(routeTable.Spec.Routes[0].Action.Destination.Destinations) < 2 { + err = fmt.Errorf("RouteTable %s.%s destinations not found", apexName, canary.Namespace) return } - for _, dst := range upstreamGroup.Spec.Destinations { + for _, dst := range routeTable.Spec.Routes[0].Action.Destination.Destinations { if dst.Destination.Upstream.Name == primaryName { primaryWeight = int(dst.Weight) canaryWeight = 100 - primaryWeight @@ -168,37 +179,47 @@ func (gr *GlooRouter) SetRoutes( return fmt.Errorf("RoutingRule %s.%s update failed: no valid weights", apexName, canary.Namespace) } - upstreamGroup, err := gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) + routeTable, err := gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{}) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s query error: %w", apexName, canary.Namespace, err) + return fmt.Errorf("RouteTable %s.%s query error: %w", apexName, canary.Namespace, err) } - upstreamGroup.Spec = gloov1.UpstreamGroupSpec{ - Destinations: []gloov1.WeightedDestination{ - { - Destination: gloov1.Destination{ - Upstream: gloov1.ResourceRef{ - Name: primaryName, - Namespace: gr.upstreamDiscoveryNs, - }, - }, - Weight: uint32(primaryWeight), - }, + routeTable.Spec = gloov1.RouteTableSpec{ + Routes: []gloov1.Route{ { - Destination: gloov1.Destination{ - Upstream: gloov1.ResourceRef{ - Name: canaryName, - Namespace: gr.upstreamDiscoveryNs, + InheritablePathMatchers: true, + Matchers: getMatchers(canary), + Action: gloov1.RouteAction{ + Destination: gloov1.MultiDestination{ + Destinations: []gloov1.WeightedDestination{ + { + Destination: gloov1.Destination{ + Upstream: gloov1.ResourceRef{ + Name: primaryName, + Namespace: gr.upstreamDiscoveryNs, + }, + }, + Weight: uint32(primaryWeight), + }, + { + Destination: gloov1.Destination{ + Upstream: gloov1.ResourceRef{ + Name: canaryName, + Namespace: gr.upstreamDiscoveryNs, + }, + }, + Weight: uint32(canaryWeight), + }, + }, }, }, - Weight: uint32(canaryWeight), }, }, } - _, err = gr.glooClient.GlooV1().UpstreamGroups(canary.Namespace).Update(context.TODO(), upstreamGroup, metav1.UpdateOptions{}) + _, err = gr.glooClient.GatewayV1().RouteTables(canary.Namespace).Update(context.TODO(), routeTable, metav1.UpdateOptions{}) if err != nil { - return fmt.Errorf("UpstreamGroup %s.%s update error: %w", apexName, canary.Namespace, err) + return fmt.Errorf("RouteTable %s.%s update error: %w", apexName, canary.Namespace, err) } return nil } @@ -206,3 +227,51 @@ func (gr *GlooRouter) SetRoutes( func (gr *GlooRouter) Finalize(_ *flaggerv1.Canary) error { return nil } + +func getMatchers(canary *flaggerv1.Canary) []gloov1.Matcher { + + headerMatchers := getHeaderMatchers(canary) + methods := getMethods(canary) + + if len(headerMatchers) == 0 && len(methods) == 0 { + return nil + } + + return []gloov1.Matcher{ + { + Headers: headerMatchers, + Methods: methods, + }, + } +} + +func getHeaderMatchers(canary *flaggerv1.Canary) []gloov1.HeaderMatcher { + var headerMatchers []gloov1.HeaderMatcher + for _, match := range canary.GetAnalysis().Match { + for s, stringMatch := range match.Headers { + h := gloov1.HeaderMatcher{ + Name: s, + Value: stringMatch.Exact, + } + if stringMatch.Regex != "" { + h = gloov1.HeaderMatcher{ + Name: s, + Value: stringMatch.Regex, + Regex: true, + } + } + headerMatchers = append(headerMatchers, h) + } + } + return headerMatchers +} + +func getMethods(canary *flaggerv1.Canary) []string { + var methods []string + for _, match := range canary.GetAnalysis().Match { + if stringMatch := match.Method; stringMatch != nil { + methods = append(methods, stringMatch.Exact) + } + } + return methods +} diff --git a/pkg/router/gloo_test.go b/pkg/router/gloo_test.go index 13f97e419..dcf1a6c4c 100644 --- a/pkg/router/gloo_test.go +++ b/pkg/router/gloo_test.go @@ -37,16 +37,36 @@ func TestGlooRouter_Sync(t *testing.T) { kubeClient: mocks.kubeClient, } + // init err := router.Reconcile(mocks.canary) require.NoError(t, err) // test insert - ug, err := router.glooClient.GlooV1().UpstreamGroups("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + rt, err := router.glooClient.GatewayV1().RouteTables("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) require.NoError(t, err) - dests := ug.Spec.Destinations + dests := rt.Spec.Routes[0].Action.Destination.Destinations assert.Len(t, dests, 2) assert.Equal(t, uint32(100), dests[0].Weight) assert.Equal(t, uint32(0), dests[1].Weight) + + // test headers update + cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + require.NoError(t, err) + + cdClone := cd.DeepCopy() + cdClone.Spec.Analysis.Iterations = 5 + cdClone.Spec.Analysis.Match = newTestABTest().Spec.Analysis.Match + canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(context.TODO(), cdClone, metav1.UpdateOptions{}) + require.NoError(t, err) + + // apply change + err = router.Reconcile(canary) + require.NoError(t, err) + + rt, err = router.glooClient.GatewayV1().RouteTables("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "x-user-type", rt.Spec.Routes[0].Matchers[0].Headers[0].Name) + assert.Equal(t, "test", rt.Spec.Routes[0].Matchers[0].Headers[0].Value) } func TestGlooRouter_SetRoutes(t *testing.T) { @@ -71,7 +91,7 @@ func TestGlooRouter_SetRoutes(t *testing.T) { err = router.SetRoutes(mocks.canary, p, c, m) require.NoError(t, err) - ug, err := router.glooClient.GlooV1().UpstreamGroups("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + rt, err := router.glooClient.GatewayV1().RouteTables("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) require.NoError(t, err) var pRoute gloov1.WeightedDestination @@ -79,7 +99,7 @@ func TestGlooRouter_SetRoutes(t *testing.T) { 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) - for _, dest := range ug.Spec.Destinations { + for _, dest := range rt.Spec.Routes[0].Action.Destination.Destinations { if dest.Destination.Upstream.Name == primaryName { pRoute = dest } @@ -90,6 +110,25 @@ func TestGlooRouter_SetRoutes(t *testing.T) { assert.Equal(t, uint32(p), pRoute.Weight) assert.Equal(t, uint32(c), cRoute.Weight) + + cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + require.NoError(t, err) + + // test update to A/B + cdClone := cd.DeepCopy() + cdClone.Spec.Analysis.Iterations = 5 + cdClone.Spec.Analysis.Match = newTestABTest().Spec.Analysis.Match + canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(context.TODO(), cdClone, metav1.UpdateOptions{}) + require.NoError(t, err) + + // test set routes for A/B + err = router.SetRoutes(canary, 0, 100, false) + require.NoError(t, err) + + rt, err = router.glooClient.GatewayV1().RouteTables("default").Get(context.TODO(), "podinfo", metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, "x-user-type", rt.Spec.Routes[0].Matchers[0].Headers[0].Name) + assert.Equal(t, "test", rt.Spec.Routes[0].Matchers[0].Headers[0].Value) } func TestGlooRouter_GetRoutes(t *testing.T) { diff --git a/test/gloo/install.sh b/test/gloo/install.sh index b68a60790..98cbfe063 100755 --- a/test/gloo/install.sh +++ b/test/gloo/install.sh @@ -2,7 +2,7 @@ set -o errexit -GLOO_VER="1.3.28" +GLOO_VER="1.6.0" REPO_ROOT=$(git rev-parse --show-toplevel) mkdir -p ${REPO_ROOT}/bin diff --git a/test/gloo/test-canary.sh b/test/gloo/test-canary.sh index 72ea019ac..95932b48b 100755 --- a/test/gloo/test-canary.sh +++ b/test/gloo/test-canary.sh @@ -19,8 +19,8 @@ spec: routes: - matchers: - prefix: / - routeAction: - upstreamGroup: + delegateAction: + ref: name: podinfo namespace: test EOF @@ -110,4 +110,85 @@ until ${ok}; do fi done +echo '>>> Waiting for canary finalization' +retries=50 +count=0 +ok=false +until ${ok}; do + kubectl -n test get canary/podinfo | grep 'Succeeded' && ok=true || ok=false + sleep 5 + count=$(($count + 1)) + if [[ ${count} -eq ${retries} ]]; then + kubectl -n ingress-nginx logs deployment/flagger + echo "No more retries left" + exit 1 + fi +done + echo '✔ Canary promotion test passed' + +cat <>> Triggering A/B testing' +kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.2 + +echo '>>> Waiting for A/B testing promotion' +retries=50 +count=0 +ok=false +until ${ok}; do + kubectl -n test describe deployment/podinfo-primary | grep '3.1.2' && ok=true || ok=false + sleep 10 + kubectl -n gloo-system logs deployment/flagger --tail 1 + count=$(($count + 1)) + if [[ ${count} -eq ${retries} ]]; then + kubectl -n gloo-system logs deployment/flagger + echo "No more retries left" + exit 1 + fi +done + +echo '✔ A/B testing promotion test passed' + +kubectl -n gloo-system logs deployment/flagger + +echo '✔ All tests passed' \ No newline at end of file