mirror of
https://github.com/fluxcd/flagger.git
synced 2026-04-15 06:57:34 +00:00
Merge pull request #20 from stefanprodan/scheduler
Add canary analysis schedule interval to CRD
This commit is contained in:
@@ -25,8 +25,7 @@ helm repo add flagger https://flagger.app
|
||||
# install or upgrade
|
||||
helm upgrade -i flagger flagger/flagger \
|
||||
--namespace=istio-system \
|
||||
--set metricsServer=http://prometheus.istio-system:9090 \
|
||||
--set controlLoopInterval=1m
|
||||
--set metricsServer=http://prometheus.istio-system:9090
|
||||
```
|
||||
|
||||
Flagger is compatible with Kubernetes >1.10.0 and Istio >1.0.0.
|
||||
@@ -75,7 +74,7 @@ You can change the canary analysis _max weight_ and the _step weight_ percentage
|
||||
For a deployment named _podinfo_, a canary promotion can be defined using Flagger's custom resource:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1alpha2
|
||||
apiVersion: flagger.app/v1alpha3
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
@@ -102,8 +101,10 @@ spec:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
# Istio virtual service host names (optional)
|
||||
hosts:
|
||||
- app.iowa.weavedx.com
|
||||
- podinfo.example.com
|
||||
canaryAnalysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: flagger.app/v1alpha2
|
||||
apiVersion: flagger.app/v1alpha3
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
@@ -27,6 +27,8 @@ spec:
|
||||
hosts:
|
||||
- app.iowa.weavedx.com
|
||||
canaryAnalysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 10s
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
@@ -50,7 +52,7 @@ spec:
|
||||
# external checks (optional)
|
||||
webhooks:
|
||||
- name: integration-tests
|
||||
url: http://podinfo.test:9898/echo
|
||||
url: https://httpbin.org/post
|
||||
timeout: 1m
|
||||
metadata:
|
||||
test: "all"
|
||||
|
||||
@@ -4,11 +4,14 @@ metadata:
|
||||
name: canaries.flagger.app
|
||||
spec:
|
||||
group: flagger.app
|
||||
version: v1alpha2
|
||||
version: v1alpha3
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
- name: v1alpha3
|
||||
served: true
|
||||
storage: true
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: false
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: false
|
||||
@@ -39,7 +42,9 @@ spec:
|
||||
name:
|
||||
type: string
|
||||
autoscalerRef:
|
||||
type: object
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: object
|
||||
required: ['apiVersion', 'kind', 'name']
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -56,6 +61,9 @@ spec:
|
||||
type: number
|
||||
canaryAnalysis:
|
||||
properties:
|
||||
interval:
|
||||
type: string
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
threshold:
|
||||
type: number
|
||||
maxWeight:
|
||||
@@ -73,7 +81,7 @@ spec:
|
||||
type: string
|
||||
interval:
|
||||
type: string
|
||||
pattern: "^[0-9]+(m)"
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
threshold:
|
||||
type: number
|
||||
webhooks:
|
||||
@@ -90,4 +98,4 @@ spec:
|
||||
format: url
|
||||
timeout:
|
||||
type: string
|
||||
pattern: "^[0-9]+(s)"
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
|
||||
@@ -22,7 +22,7 @@ spec:
|
||||
serviceAccountName: flagger
|
||||
containers:
|
||||
- name: flagger
|
||||
image: quay.io/stefanprodan/flagger:0.2.0
|
||||
image: quay.io/stefanprodan/flagger:0.3.0-beta.1
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
apiVersion: v1
|
||||
name: flagger
|
||||
version: 0.2.0
|
||||
appVersion: 0.2.0
|
||||
appVersion: 0.3.0-beta.1
|
||||
kubeVersion: ">=1.9.0-0"
|
||||
engine: gotpl
|
||||
description: Flagger is a Kubernetes operator that automates the promotion of canary deployments using Istio routing for traffic shifting and Prometheus metrics for canary analysis.
|
||||
home: https://flagger.app
|
||||
home: https://docs.flagger.app
|
||||
icon: https://raw.githubusercontent.com/stefanprodan/flagger/master/docs/logo/flagger-icon.png
|
||||
sources:
|
||||
- https://github.com/stefanprodan/flagger
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Flagger
|
||||
|
||||
[Flagger](https://flagger.app) is a Kubernetes operator that automates the promotion of canary deployments
|
||||
using Istio routing for traffic shifting and Prometheus metrics for canary analysis.
|
||||
[Flagger](https://github.com/stefanprodan/flagger) is a Kubernetes operator that automates the promotion of
|
||||
canary deployments using Istio routing for traffic shifting and Prometheus metrics for canary analysis.
|
||||
Flagger implements a control loop that gradually shifts traffic to the canary while measuring key performance indicators
|
||||
like HTTP requests success rate, requests average duration and pods health.
|
||||
Based on the KPIs analysis a canary is promoted or aborted and the analysis result is published to Slack.
|
||||
@@ -48,7 +48,6 @@ Parameter | Description | Default
|
||||
`image.repository` | image repository | `quay.io/stefanprodan/flagger`
|
||||
`image.tag` | image tag | `<VERSION>`
|
||||
`image.pullPolicy` | image pull policy | `IfNotPresent`
|
||||
`controlLoopInterval` | wait interval between checks | `10s`
|
||||
`metricsServer` | Prometheus URL | `http://prometheus.istio-system:9090`
|
||||
`slack.url` | Slack incoming webhook | None
|
||||
`slack.channel` | Slack channel | None
|
||||
@@ -68,7 +67,8 @@ Specify each parameter using the `--set key=value[,key=value]` argument to `helm
|
||||
```console
|
||||
$ helm upgrade -i flagger flagger/flagger \
|
||||
--namespace istio-system \
|
||||
--set controlLoopInterval=1m
|
||||
--set slack.url=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK \
|
||||
--set slack.channel=general
|
||||
```
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,
|
||||
@@ -80,5 +80,5 @@ $ helm upgrade -i flagger flagger/flagger \
|
||||
```
|
||||
|
||||
> **Tip**: You can use the default [values.yaml](values.yaml)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ metadata:
|
||||
name: canaries.flagger.app
|
||||
spec:
|
||||
group: flagger.app
|
||||
version: v1alpha2
|
||||
version: v1alpha3
|
||||
versions:
|
||||
- name: v1alpha2
|
||||
- name: v1alpha3
|
||||
served: true
|
||||
storage: true
|
||||
- name: v1alpha2
|
||||
served: true
|
||||
storage: false
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: false
|
||||
@@ -40,7 +43,9 @@ spec:
|
||||
name:
|
||||
type: string
|
||||
autoscalerRef:
|
||||
type: object
|
||||
anyOf:
|
||||
- type: string
|
||||
- type: object
|
||||
required: ['apiVersion', 'kind', 'name']
|
||||
properties:
|
||||
apiVersion:
|
||||
@@ -57,6 +62,9 @@ spec:
|
||||
type: number
|
||||
canaryAnalysis:
|
||||
properties:
|
||||
interval:
|
||||
type: string
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
threshold:
|
||||
type: number
|
||||
maxWeight:
|
||||
@@ -74,7 +82,7 @@ spec:
|
||||
type: string
|
||||
interval:
|
||||
type: string
|
||||
pattern: "^[0-9]+(m)"
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
threshold:
|
||||
type: number
|
||||
webhooks:
|
||||
@@ -91,6 +99,5 @@ spec:
|
||||
format: url
|
||||
timeout:
|
||||
type: string
|
||||
pattern: "^[0-9]+(s)"
|
||||
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
{{- end }}
|
||||
|
||||
@@ -35,7 +35,6 @@ spec:
|
||||
command:
|
||||
- ./flagger
|
||||
- -log-level=info
|
||||
- -control-loop-interval={{ .Values.controlLoopInterval }}
|
||||
- -metrics-server={{ .Values.metricsServer }}
|
||||
{{- if .Values.slack.url }}
|
||||
- -slack-url={{ .Values.slack.url }}
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
image:
|
||||
repository: quay.io/stefanprodan/flagger
|
||||
tag: 0.2.0
|
||||
tag: 0.3.0-beta.1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
controlLoopInterval: "1m"
|
||||
metricsServer: "http://prometheus.istio-system.svc.cluster.local:9090"
|
||||
|
||||
slack:
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ func init() {
|
||||
flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
|
||||
flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
|
||||
flag.StringVar(&metricsServer, "metrics-server", "http://prometheus:9090", "Prometheus URL")
|
||||
flag.DurationVar(&controlLoopInterval, "control-loop-interval", 10*time.Second, "wait interval between rollouts")
|
||||
flag.DurationVar(&controlLoopInterval, "control-loop-interval", 10*time.Second, "Kubernetes API sync interval")
|
||||
flag.StringVar(&logLevel, "log-level", "debug", "Log level can be: debug, info, warning, error.")
|
||||
flag.StringVar(&port, "port", "8080", "Port to listen on.")
|
||||
flag.StringVar(&slackURL, "slack-url", "", "Slack hook URL.")
|
||||
@@ -77,7 +77,7 @@ func main() {
|
||||
}
|
||||
|
||||
flaggerInformerFactory := informers.NewSharedInformerFactory(flaggerClient, time.Second*30)
|
||||
canaryInformer := flaggerInformerFactory.Flagger().V1alpha2().Canaries()
|
||||
canaryInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
|
||||
|
||||
logger.Infof("Starting flagger version %s revision %s", version.VERSION, version.REVISION)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
For a deployment named _podinfo_, a canary promotion can be defined using Flagger's custom resource:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1alpha2
|
||||
apiVersion: flagger.app/v1alpha3
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
@@ -38,6 +38,8 @@ spec:
|
||||
hosts:
|
||||
- podinfo.example.com
|
||||
canaryAnalysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
@@ -128,12 +130,13 @@ You can change the canary analysis _max weight_ and the _step weight_ percentage
|
||||
### Canary Analysis
|
||||
|
||||
The canary analysis runs periodically until it reaches the maximum traffic weight or the failed checks threshold.
|
||||
By default the analysis interval is set to one minute and can be configured with the `controlLoopInterval` command flag.
|
||||
|
||||
Spec:
|
||||
|
||||
```yaml
|
||||
canaryAnalysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 10
|
||||
# max traffic percentage routed to canary
|
||||
@@ -148,13 +151,13 @@ The above analysis, if it succeeds, will run for 25 minutes while validating the
|
||||
You can determine the minimum time that it takes to validate and promote a canary deployment using this formula:
|
||||
|
||||
```
|
||||
controlLoopInterval * (maxWeight / stepWeight)
|
||||
interval * (maxWeight / stepWeight)
|
||||
```
|
||||
|
||||
And the time it takes for a canary to be rollback:
|
||||
And the time it takes for a canary to be rollback when the metrics or webhook checks are failing:
|
||||
|
||||
```
|
||||
controlLoopInterval * threshold
|
||||
interval * threshold
|
||||
```
|
||||
|
||||
### HTTP Metrics
|
||||
|
||||
@@ -23,8 +23,7 @@ Deploy Flagger in the _**istio-system**_ namespace:
|
||||
```bash
|
||||
helm upgrade -i flagger flagger/flagger \
|
||||
--namespace=istio-system \
|
||||
--set metricsServer=http://prometheus.istio-system:9090 \
|
||||
--set controlLoopInterval=1m
|
||||
--set metricsServer=http://prometheus.istio-system:9090
|
||||
```
|
||||
|
||||
Enable **Slack** notifications:
|
||||
|
||||
@@ -20,7 +20,7 @@ kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml
|
||||
Create a canary custom resource \(replace example.com with your own domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: v1alpha2
|
||||
apiVersion: flagger.app/v1alpha3
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
@@ -49,6 +49,8 @@ spec:
|
||||
hosts:
|
||||
- app.example.com
|
||||
canaryAnalysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 5
|
||||
# max traffic percentage routed to canary
|
||||
|
||||
@@ -23,6 +23,6 @@ CODEGEN_PKG=${CODEGEN_PKG:-$(cd ${SCRIPT_ROOT}; ls -d -1 ./vendor/k8s.io/code-ge
|
||||
|
||||
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
|
||||
github.com/stefanprodan/flagger/pkg/client github.com/stefanprodan/flagger/pkg/apis \
|
||||
flagger:v1alpha2 \
|
||||
flagger:v1alpha3 \
|
||||
--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
|
||||
|
||||
|
||||
@@ -16,6 +16,6 @@ limitations under the License.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1alpha2 is the v1alpha2 version of the API.
|
||||
// Package v1alpha3 is the v1alpha3 version of the API.
|
||||
// +groupName=flagger.app
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: rollout.GroupName, Version: "v1alpha2"}
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: rollout.GroupName, Version: "v1alpha3"}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
@@ -14,16 +14,18 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
hpav1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
CanaryKind = "Canary"
|
||||
ProgressDeadlineSeconds = 600
|
||||
AnalysisInterval = 60 * time.Second
|
||||
)
|
||||
|
||||
// +genclient
|
||||
@@ -44,7 +46,8 @@ type CanarySpec struct {
|
||||
TargetRef hpav1.CrossVersionObjectReference `json:"targetRef"`
|
||||
|
||||
// reference to autoscaling resource
|
||||
AutoscalerRef hpav1.CrossVersionObjectReference `json:"autoscalerRef"`
|
||||
// +optional
|
||||
AutoscalerRef *hpav1.CrossVersionObjectReference `json:"autoscalerRef,omitempty"`
|
||||
|
||||
// virtual service spec
|
||||
Service CanaryService `json:"service"`
|
||||
@@ -96,6 +99,7 @@ type CanaryService struct {
|
||||
|
||||
// CanaryAnalysis is used to describe how the analysis should be done
|
||||
type CanaryAnalysis struct {
|
||||
Interval string `json:"interval"`
|
||||
Threshold int `json:"threshold"`
|
||||
MaxWeight int `json:"maxWeight"`
|
||||
StepWeight int `json:"stepWeight"`
|
||||
@@ -134,3 +138,16 @@ func (c *Canary) GetProgressDeadlineSeconds() int {
|
||||
|
||||
return ProgressDeadlineSeconds
|
||||
}
|
||||
|
||||
func (c *Canary) GetAnalysisInterval() time.Duration {
|
||||
if c.Spec.CanaryAnalysis.Interval == "" {
|
||||
return AnalysisInterval
|
||||
}
|
||||
|
||||
interval, err := time.ParseDuration(c.Spec.CanaryAnalysis.Interval)
|
||||
if err != nil {
|
||||
return AnalysisInterval
|
||||
}
|
||||
|
||||
return interval
|
||||
}
|
||||
+7
-2
@@ -18,9 +18,10 @@ limitations under the License.
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
@@ -159,7 +160,11 @@ func (in *CanaryService) DeepCopy() *CanaryService {
|
||||
func (in *CanarySpec) DeepCopyInto(out *CanarySpec) {
|
||||
*out = *in
|
||||
out.TargetRef = in.TargetRef
|
||||
out.AutoscalerRef = in.AutoscalerRef
|
||||
if in.AutoscalerRef != nil {
|
||||
in, out := &in.AutoscalerRef, &out.AutoscalerRef
|
||||
*out = new(v1.CrossVersionObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
in.Service.DeepCopyInto(&out.Service)
|
||||
in.CanaryAnalysis.DeepCopyInto(&out.CanaryAnalysis)
|
||||
if in.ProgressDeadlineSeconds != nil {
|
||||
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
package versioned
|
||||
|
||||
import (
|
||||
flaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha2"
|
||||
flaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
|
||||
discovery "k8s.io/client-go/discovery"
|
||||
rest "k8s.io/client-go/rest"
|
||||
flowcontrol "k8s.io/client-go/util/flowcontrol"
|
||||
@@ -27,27 +27,27 @@ import (
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
FlaggerV1alpha2() flaggerv1alpha2.FlaggerV1alpha2Interface
|
||||
FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface
|
||||
// Deprecated: please explicitly pick a version if possible.
|
||||
Flagger() flaggerv1alpha2.FlaggerV1alpha2Interface
|
||||
Flagger() flaggerv1alpha3.FlaggerV1alpha3Interface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
flaggerV1alpha2 *flaggerv1alpha2.FlaggerV1alpha2Client
|
||||
flaggerV1alpha3 *flaggerv1alpha3.FlaggerV1alpha3Client
|
||||
}
|
||||
|
||||
// FlaggerV1alpha2 retrieves the FlaggerV1alpha2Client
|
||||
func (c *Clientset) FlaggerV1alpha2() flaggerv1alpha2.FlaggerV1alpha2Interface {
|
||||
return c.flaggerV1alpha2
|
||||
// FlaggerV1alpha3 retrieves the FlaggerV1alpha3Client
|
||||
func (c *Clientset) FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface {
|
||||
return c.flaggerV1alpha3
|
||||
}
|
||||
|
||||
// Deprecated: Flagger retrieves the default version of FlaggerClient.
|
||||
// Please explicitly pick a version.
|
||||
func (c *Clientset) Flagger() flaggerv1alpha2.FlaggerV1alpha2Interface {
|
||||
return c.flaggerV1alpha2
|
||||
func (c *Clientset) Flagger() flaggerv1alpha3.FlaggerV1alpha3Interface {
|
||||
return c.flaggerV1alpha3
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
@@ -66,7 +66,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
}
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.flaggerV1alpha2, err = flaggerv1alpha2.NewForConfig(&configShallowCopy)
|
||||
cs.flaggerV1alpha3, err = flaggerv1alpha3.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.flaggerV1alpha2 = flaggerv1alpha2.NewForConfigOrDie(c)
|
||||
cs.flaggerV1alpha3 = flaggerv1alpha3.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &cs
|
||||
@@ -91,7 +91,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.flaggerV1alpha2 = flaggerv1alpha2.New(c)
|
||||
cs.flaggerV1alpha3 = flaggerv1alpha3.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &cs
|
||||
|
||||
@@ -20,8 +20,8 @@ package fake
|
||||
|
||||
import (
|
||||
clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
|
||||
flaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha2"
|
||||
fakeflaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha2/fake"
|
||||
flaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
|
||||
fakeflaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
@@ -71,12 +71,12 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// FlaggerV1alpha2 retrieves the FlaggerV1alpha2Client
|
||||
func (c *Clientset) FlaggerV1alpha2() flaggerv1alpha2.FlaggerV1alpha2Interface {
|
||||
return &fakeflaggerv1alpha2.FakeFlaggerV1alpha2{Fake: &c.Fake}
|
||||
// FlaggerV1alpha3 retrieves the FlaggerV1alpha3Client
|
||||
func (c *Clientset) FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface {
|
||||
return &fakeflaggerv1alpha3.FakeFlaggerV1alpha3{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Flagger retrieves the FlaggerV1alpha2Client
|
||||
func (c *Clientset) Flagger() flaggerv1alpha2.FlaggerV1alpha2Interface {
|
||||
return &fakeflaggerv1alpha2.FakeFlaggerV1alpha2{Fake: &c.Fake}
|
||||
// Flagger retrieves the FlaggerV1alpha3Client
|
||||
func (c *Clientset) Flagger() flaggerv1alpha3.FlaggerV1alpha3Interface {
|
||||
return &fakeflaggerv1alpha3.FakeFlaggerV1alpha3{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
flaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -50,5 +50,5 @@ func init() {
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
func AddToScheme(scheme *runtime.Scheme) {
|
||||
flaggerv1alpha2.AddToScheme(scheme)
|
||||
flaggerv1alpha3.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
package scheme
|
||||
|
||||
import (
|
||||
flaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -50,5 +50,5 @@ func init() {
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
func AddToScheme(scheme *runtime.Scheme) {
|
||||
flaggerv1alpha2.AddToScheme(scheme)
|
||||
flaggerv1alpha3.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
+21
-21
@@ -16,10 +16,10 @@ limitations under the License.
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
scheme "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/scheme"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
@@ -35,15 +35,15 @@ type CanariesGetter interface {
|
||||
|
||||
// CanaryInterface has methods to work with Canary resources.
|
||||
type CanaryInterface interface {
|
||||
Create(*v1alpha2.Canary) (*v1alpha2.Canary, error)
|
||||
Update(*v1alpha2.Canary) (*v1alpha2.Canary, error)
|
||||
UpdateStatus(*v1alpha2.Canary) (*v1alpha2.Canary, error)
|
||||
Create(*v1alpha3.Canary) (*v1alpha3.Canary, error)
|
||||
Update(*v1alpha3.Canary) (*v1alpha3.Canary, error)
|
||||
UpdateStatus(*v1alpha3.Canary) (*v1alpha3.Canary, error)
|
||||
Delete(name string, options *v1.DeleteOptions) error
|
||||
DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
|
||||
Get(name string, options v1.GetOptions) (*v1alpha2.Canary, error)
|
||||
List(opts v1.ListOptions) (*v1alpha2.CanaryList, error)
|
||||
Get(name string, options v1.GetOptions) (*v1alpha3.Canary, error)
|
||||
List(opts v1.ListOptions) (*v1alpha3.CanaryList, error)
|
||||
Watch(opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Canary, err error)
|
||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Canary, err error)
|
||||
CanaryExpansion
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ type canaries struct {
|
||||
}
|
||||
|
||||
// newCanaries returns a Canaries
|
||||
func newCanaries(c *FlaggerV1alpha2Client, namespace string) *canaries {
|
||||
func newCanaries(c *FlaggerV1alpha3Client, namespace string) *canaries {
|
||||
return &canaries{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
@@ -62,8 +62,8 @@ func newCanaries(c *FlaggerV1alpha2Client, namespace string) *canaries {
|
||||
}
|
||||
|
||||
// Get takes name of the canary, and returns the corresponding canary object, and an error if there is any.
|
||||
func (c *canaries) Get(name string, options v1.GetOptions) (result *v1alpha2.Canary, err error) {
|
||||
result = &v1alpha2.Canary{}
|
||||
func (c *canaries) Get(name string, options v1.GetOptions) (result *v1alpha3.Canary, err error) {
|
||||
result = &v1alpha3.Canary{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
@@ -75,8 +75,8 @@ func (c *canaries) Get(name string, options v1.GetOptions) (result *v1alpha2.Can
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Canaries that match those selectors.
|
||||
func (c *canaries) List(opts v1.ListOptions) (result *v1alpha2.CanaryList, err error) {
|
||||
result = &v1alpha2.CanaryList{}
|
||||
func (c *canaries) List(opts v1.ListOptions) (result *v1alpha3.CanaryList, err error) {
|
||||
result = &v1alpha3.CanaryList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
@@ -97,8 +97,8 @@ func (c *canaries) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
}
|
||||
|
||||
// Create takes the representation of a canary and creates it. Returns the server's representation of the canary, and an error, if there is any.
|
||||
func (c *canaries) Create(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err error) {
|
||||
result = &v1alpha2.Canary{}
|
||||
func (c *canaries) Create(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
|
||||
result = &v1alpha3.Canary{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
@@ -109,8 +109,8 @@ func (c *canaries) Create(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err
|
||||
}
|
||||
|
||||
// Update takes the representation of a canary and updates it. Returns the server's representation of the canary, and an error, if there is any.
|
||||
func (c *canaries) Update(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err error) {
|
||||
result = &v1alpha2.Canary{}
|
||||
func (c *canaries) Update(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
|
||||
result = &v1alpha3.Canary{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
@@ -124,8 +124,8 @@ func (c *canaries) Update(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
|
||||
func (c *canaries) UpdateStatus(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err error) {
|
||||
result = &v1alpha2.Canary{}
|
||||
func (c *canaries) UpdateStatus(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
|
||||
result = &v1alpha3.Canary{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
@@ -160,8 +160,8 @@ func (c *canaries) DeleteCollection(options *v1.DeleteOptions, listOptions v1.Li
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched canary.
|
||||
func (c *canaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Canary, err error) {
|
||||
result = &v1alpha2.Canary{}
|
||||
func (c *canaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Canary, err error) {
|
||||
result = &v1alpha3.Canary{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("canaries").
|
||||
+1
-1
@@ -17,4 +17,4 @@ limitations under the License.
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
+25
-25
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@@ -30,29 +30,29 @@ import (
|
||||
|
||||
// FakeCanaries implements CanaryInterface
|
||||
type FakeCanaries struct {
|
||||
Fake *FakeFlaggerV1alpha2
|
||||
Fake *FakeFlaggerV1alpha3
|
||||
ns string
|
||||
}
|
||||
|
||||
var canariesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1alpha2", Resource: "canaries"}
|
||||
var canariesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1alpha3", Resource: "canaries"}
|
||||
|
||||
var canariesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1alpha2", Kind: "Canary"}
|
||||
var canariesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1alpha3", Kind: "Canary"}
|
||||
|
||||
// Get takes name of the canary, and returns the corresponding canary object, and an error if there is any.
|
||||
func (c *FakeCanaries) Get(name string, options v1.GetOptions) (result *v1alpha2.Canary, err error) {
|
||||
func (c *FakeCanaries) Get(name string, options v1.GetOptions) (result *v1alpha3.Canary, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(canariesResource, c.ns, name), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewGetAction(canariesResource, c.ns, name), &v1alpha3.Canary{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), err
|
||||
return obj.(*v1alpha3.Canary), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Canaries that match those selectors.
|
||||
func (c *FakeCanaries) List(opts v1.ListOptions) (result *v1alpha2.CanaryList, err error) {
|
||||
func (c *FakeCanaries) List(opts v1.ListOptions) (result *v1alpha3.CanaryList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(canariesResource, canariesKind, c.ns, opts), &v1alpha2.CanaryList{})
|
||||
Invokes(testing.NewListAction(canariesResource, canariesKind, c.ns, opts), &v1alpha3.CanaryList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
@@ -62,8 +62,8 @@ func (c *FakeCanaries) List(opts v1.ListOptions) (result *v1alpha2.CanaryList, e
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha2.CanaryList{ListMeta: obj.(*v1alpha2.CanaryList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha2.CanaryList).Items {
|
||||
list := &v1alpha3.CanaryList{ListMeta: obj.(*v1alpha3.CanaryList).ListMeta}
|
||||
for _, item := range obj.(*v1alpha3.CanaryList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
@@ -79,43 +79,43 @@ func (c *FakeCanaries) Watch(opts v1.ListOptions) (watch.Interface, error) {
|
||||
}
|
||||
|
||||
// Create takes the representation of a canary and creates it. Returns the server's representation of the canary, and an error, if there is any.
|
||||
func (c *FakeCanaries) Create(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err error) {
|
||||
func (c *FakeCanaries) Create(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(canariesResource, c.ns, canary), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewCreateAction(canariesResource, c.ns, canary), &v1alpha3.Canary{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), err
|
||||
return obj.(*v1alpha3.Canary), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a canary and updates it. Returns the server's representation of the canary, and an error, if there is any.
|
||||
func (c *FakeCanaries) Update(canary *v1alpha2.Canary) (result *v1alpha2.Canary, err error) {
|
||||
func (c *FakeCanaries) Update(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(canariesResource, c.ns, canary), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewUpdateAction(canariesResource, c.ns, canary), &v1alpha3.Canary{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), err
|
||||
return obj.(*v1alpha3.Canary), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeCanaries) UpdateStatus(canary *v1alpha2.Canary) (*v1alpha2.Canary, error) {
|
||||
func (c *FakeCanaries) UpdateStatus(canary *v1alpha3.Canary) (*v1alpha3.Canary, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(canariesResource, "status", c.ns, canary), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewUpdateSubresourceAction(canariesResource, "status", c.ns, canary), &v1alpha3.Canary{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), err
|
||||
return obj.(*v1alpha3.Canary), err
|
||||
}
|
||||
|
||||
// Delete takes name of the canary and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeCanaries) Delete(name string, options *v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(canariesResource, c.ns, name), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewDeleteAction(canariesResource, c.ns, name), &v1alpha3.Canary{})
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -124,17 +124,17 @@ func (c *FakeCanaries) Delete(name string, options *v1.DeleteOptions) error {
|
||||
func (c *FakeCanaries) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(canariesResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha2.CanaryList{})
|
||||
_, err := c.Fake.Invokes(action, &v1alpha3.CanaryList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched canary.
|
||||
func (c *FakeCanaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha2.Canary, err error) {
|
||||
func (c *FakeCanaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Canary, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(canariesResource, c.ns, name, data, subresources...), &v1alpha2.Canary{})
|
||||
Invokes(testing.NewPatchSubresourceAction(canariesResource, c.ns, name, data, subresources...), &v1alpha3.Canary{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), err
|
||||
return obj.(*v1alpha3.Canary), err
|
||||
}
|
||||
+4
-4
@@ -19,22 +19,22 @@ limitations under the License.
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeFlaggerV1alpha2 struct {
|
||||
type FakeFlaggerV1alpha3 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeFlaggerV1alpha2) Canaries(namespace string) v1alpha2.CanaryInterface {
|
||||
func (c *FakeFlaggerV1alpha3) Canaries(namespace string) v1alpha3.CanaryInterface {
|
||||
return &FakeCanaries{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeFlaggerV1alpha2) RESTClient() rest.Interface {
|
||||
func (c *FakeFlaggerV1alpha3) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
+16
-16
@@ -16,31 +16,31 @@ limitations under the License.
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
"github.com/stefanprodan/flagger/pkg/client/clientset/versioned/scheme"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type FlaggerV1alpha2Interface interface {
|
||||
type FlaggerV1alpha3Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
CanariesGetter
|
||||
}
|
||||
|
||||
// FlaggerV1alpha2Client is used to interact with features provided by the flagger.app group.
|
||||
type FlaggerV1alpha2Client struct {
|
||||
// FlaggerV1alpha3Client is used to interact with features provided by the flagger.app group.
|
||||
type FlaggerV1alpha3Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *FlaggerV1alpha2Client) Canaries(namespace string) CanaryInterface {
|
||||
func (c *FlaggerV1alpha3Client) Canaries(namespace string) CanaryInterface {
|
||||
return newCanaries(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new FlaggerV1alpha2Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*FlaggerV1alpha2Client, error) {
|
||||
// NewForConfig creates a new FlaggerV1alpha3Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*FlaggerV1alpha3Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
@@ -49,12 +49,12 @@ func NewForConfig(c *rest.Config) (*FlaggerV1alpha2Client, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &FlaggerV1alpha2Client{client}, nil
|
||||
return &FlaggerV1alpha3Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new FlaggerV1alpha2Client for the given config and
|
||||
// NewForConfigOrDie creates a new FlaggerV1alpha3Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha2Client {
|
||||
func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha3Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -62,13 +62,13 @@ func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha2Client {
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new FlaggerV1alpha2Client for the given RESTClient.
|
||||
func New(c rest.Interface) *FlaggerV1alpha2Client {
|
||||
return &FlaggerV1alpha2Client{c}
|
||||
// New creates a new FlaggerV1alpha3Client for the given RESTClient.
|
||||
func New(c rest.Interface) *FlaggerV1alpha3Client {
|
||||
return &FlaggerV1alpha3Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1alpha2.SchemeGroupVersion
|
||||
gv := v1alpha3.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
||||
@@ -82,7 +82,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 *FlaggerV1alpha2Client) RESTClient() rest.Interface {
|
||||
func (c *FlaggerV1alpha3Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
+1
-1
@@ -16,6 +16,6 @@ limitations under the License.
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
type CanaryExpansion interface{}
|
||||
@@ -19,14 +19,14 @@ limitations under the License.
|
||||
package flagger
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/flagger/v1alpha3"
|
||||
internalinterfaces "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1alpha2 provides access to shared informers for resources in V1alpha2.
|
||||
V1alpha2() v1alpha2.Interface
|
||||
// V1alpha3 provides access to shared informers for resources in V1alpha3.
|
||||
V1alpha3() v1alpha3.Interface
|
||||
}
|
||||
|
||||
type group struct {
|
||||
@@ -40,7 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1alpha2 returns a new v1alpha2.Interface.
|
||||
func (g *group) V1alpha2() v1alpha2.Interface {
|
||||
return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
// V1alpha3 returns a new v1alpha3.Interface.
|
||||
func (g *group) V1alpha3() v1alpha3.Interface {
|
||||
return v1alpha3.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
+10
-10
@@ -16,15 +16,15 @@ limitations under the License.
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
time "time"
|
||||
|
||||
flaggerv1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
versioned "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/client/listers/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/client/listers/flagger/v1alpha3"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
// Canaries.
|
||||
type CanaryInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1alpha2.CanaryLister
|
||||
Lister() v1alpha3.CanaryLister
|
||||
}
|
||||
|
||||
type canaryInformer struct {
|
||||
@@ -61,16 +61,16 @@ func NewFilteredCanaryInformer(client versioned.Interface, namespace string, res
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FlaggerV1alpha2().Canaries(namespace).List(options)
|
||||
return client.FlaggerV1alpha3().Canaries(namespace).List(options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.FlaggerV1alpha2().Canaries(namespace).Watch(options)
|
||||
return client.FlaggerV1alpha3().Canaries(namespace).Watch(options)
|
||||
},
|
||||
},
|
||||
&flaggerv1alpha2.Canary{},
|
||||
&flaggerv1alpha3.Canary{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
@@ -81,9 +81,9 @@ func (f *canaryInformer) defaultInformer(client versioned.Interface, resyncPerio
|
||||
}
|
||||
|
||||
func (f *canaryInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&flaggerv1alpha2.Canary{}, f.defaultInformer)
|
||||
return f.factory.InformerFor(&flaggerv1alpha3.Canary{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *canaryInformer) Lister() v1alpha2.CanaryLister {
|
||||
return v1alpha2.NewCanaryLister(f.Informer().GetIndexer())
|
||||
func (f *canaryInformer) Lister() v1alpha3.CanaryLister {
|
||||
return v1alpha3.NewCanaryLister(f.Informer().GetIndexer())
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
@@ -21,7 +21,7 @@ package externalversions
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
@@ -52,9 +52,9 @@ func (f *genericInformer) Lister() cache.GenericLister {
|
||||
// TODO extend this to unknown resources with a client pool
|
||||
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
|
||||
switch resource {
|
||||
// Group=flagger.app, Version=v1alpha2
|
||||
case v1alpha2.SchemeGroupVersion.WithResource("canaries"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1alpha2().Canaries().Informer()}, nil
|
||||
// Group=flagger.app, Version=v1alpha3
|
||||
case v1alpha3.SchemeGroupVersion.WithResource("canaries"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1alpha3().Canaries().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -16,10 +16,10 @@ limitations under the License.
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
import (
|
||||
v1alpha2 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
v1alpha3 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
// CanaryLister helps list Canaries.
|
||||
type CanaryLister interface {
|
||||
// List lists all Canaries in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.Canary, err error)
|
||||
List(selector labels.Selector) (ret []*v1alpha3.Canary, err error)
|
||||
// Canaries returns an object that can list and get Canaries.
|
||||
Canaries(namespace string) CanaryNamespaceLister
|
||||
CanaryListerExpansion
|
||||
@@ -45,9 +45,9 @@ func NewCanaryLister(indexer cache.Indexer) CanaryLister {
|
||||
}
|
||||
|
||||
// List lists all Canaries in the indexer.
|
||||
func (s *canaryLister) List(selector labels.Selector) (ret []*v1alpha2.Canary, err error) {
|
||||
func (s *canaryLister) List(selector labels.Selector) (ret []*v1alpha3.Canary, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.Canary))
|
||||
ret = append(ret, m.(*v1alpha3.Canary))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
@@ -60,9 +60,9 @@ func (s *canaryLister) Canaries(namespace string) CanaryNamespaceLister {
|
||||
// CanaryNamespaceLister helps list and get Canaries.
|
||||
type CanaryNamespaceLister interface {
|
||||
// List lists all Canaries in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1alpha2.Canary, err error)
|
||||
List(selector labels.Selector) (ret []*v1alpha3.Canary, err error)
|
||||
// Get retrieves the Canary from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1alpha2.Canary, error)
|
||||
Get(name string) (*v1alpha3.Canary, error)
|
||||
CanaryNamespaceListerExpansion
|
||||
}
|
||||
|
||||
@@ -74,21 +74,21 @@ type canaryNamespaceLister struct {
|
||||
}
|
||||
|
||||
// List lists all Canaries in the indexer for a given namespace.
|
||||
func (s canaryNamespaceLister) List(selector labels.Selector) (ret []*v1alpha2.Canary, err error) {
|
||||
func (s canaryNamespaceLister) List(selector labels.Selector) (ret []*v1alpha3.Canary, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1alpha2.Canary))
|
||||
ret = append(ret, m.(*v1alpha3.Canary))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the Canary from the indexer for a given namespace and name.
|
||||
func (s canaryNamespaceLister) Get(name string) (*v1alpha2.Canary, error) {
|
||||
func (s canaryNamespaceLister) Get(name string) (*v1alpha3.Canary, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1alpha2.Resource("canary"), name)
|
||||
return nil, errors.NewNotFound(v1alpha3.Resource("canary"), name)
|
||||
}
|
||||
return obj.(*v1alpha2.Canary), nil
|
||||
return obj.(*v1alpha3.Canary), nil
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1alpha3
|
||||
|
||||
// CanaryListerExpansion allows custom methods to be added to
|
||||
// CanaryLister.
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
istioclientset "github.com/knative/pkg/client/clientset/versioned"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
|
||||
flaggerscheme "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/scheme"
|
||||
flaggerinformers "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/flagger/v1alpha2"
|
||||
flaggerlisters "github.com/stefanprodan/flagger/pkg/client/listers/flagger/v1alpha2"
|
||||
flaggerinformers "github.com/stefanprodan/flagger/pkg/client/informers/externalversions/flagger/v1alpha3"
|
||||
flaggerlisters "github.com/stefanprodan/flagger/pkg/client/listers/flagger/v1alpha3"
|
||||
"github.com/stefanprodan/flagger/pkg/notifier"
|
||||
"go.uber.org/zap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -40,6 +40,7 @@ type Controller struct {
|
||||
eventRecorder record.EventRecorder
|
||||
logger *zap.SugaredLogger
|
||||
canaries *sync.Map
|
||||
jobs map[string]CanaryJob
|
||||
deployer CanaryDeployer
|
||||
router CanaryRouter
|
||||
observer CanaryObserver
|
||||
@@ -98,6 +99,7 @@ func NewController(
|
||||
eventRecorder: eventRecorder,
|
||||
logger: logger,
|
||||
canaries: new(sync.Map),
|
||||
jobs: map[string]CanaryJob{},
|
||||
flaggerWindow: flaggerWindow,
|
||||
deployer: deployer,
|
||||
router: router,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
istioclientset "github.com/knative/pkg/client/clientset/versioned"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
|
||||
"go.uber.org/zap"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@@ -154,7 +154,7 @@ func (c *CanaryDeployer) IsNewSpec(cd *flaggerv1.Canary) (bool, error) {
|
||||
func (c *CanaryDeployer) SetFailedChecks(cd *flaggerv1.Canary, val int) error {
|
||||
cd.Status.FailedChecks = val
|
||||
cd.Status.LastTransitionTime = metav1.Now()
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha2().Canaries(cd.Namespace).Update(cd)
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Update(cd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deployment %s.%s update error %v", cd.Spec.TargetRef.Name, cd.Namespace, err)
|
||||
}
|
||||
@@ -165,7 +165,7 @@ func (c *CanaryDeployer) SetFailedChecks(cd *flaggerv1.Canary, val int) error {
|
||||
func (c *CanaryDeployer) SetState(cd *flaggerv1.Canary, state flaggerv1.CanaryState) error {
|
||||
cd.Status.State = state
|
||||
cd.Status.LastTransitionTime = metav1.Now()
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha2().Canaries(cd.Namespace).Update(cd)
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Update(cd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deployment %s.%s update error %v", cd.Spec.TargetRef.Name, cd.Namespace, err)
|
||||
}
|
||||
@@ -192,7 +192,7 @@ func (c *CanaryDeployer) SyncStatus(cd *flaggerv1.Canary, status flaggerv1.Canar
|
||||
cd.Status.FailedChecks = status.FailedChecks
|
||||
cd.Status.CanaryRevision = specEnc
|
||||
cd.Status.LastTransitionTime = metav1.Now()
|
||||
_, err = c.flaggerClient.FlaggerV1alpha2().Canaries(cd.Namespace).Update(cd)
|
||||
_, err = c.flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Update(cd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deployment %s.%s update error %v", cd.Spec.TargetRef.Name, cd.Namespace, err)
|
||||
}
|
||||
@@ -231,7 +231,7 @@ func (c *CanaryDeployer) Sync(cd *flaggerv1.Canary) error {
|
||||
}
|
||||
}
|
||||
|
||||
if cd.Spec.AutoscalerRef.Kind == "HorizontalPodAutoscaler" {
|
||||
if cd.Spec.AutoscalerRef != nil && cd.Spec.AutoscalerRef.Kind == "HorizontalPodAutoscaler" {
|
||||
if err := c.createPrimaryHpa(cd); err != nil {
|
||||
return fmt.Errorf("creating hpa %s.%s failed: %v", primaryName, cd.Namespace, err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package controller
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
"github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
fakeFlagger "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/fake"
|
||||
"github.com/stefanprodan/flagger/pkg/logging"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@@ -14,30 +14,30 @@ import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
func newTestCanary() *v1alpha2.Canary {
|
||||
cd := &v1alpha2.Canary{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: v1alpha2.SchemeGroupVersion.String()},
|
||||
func newTestCanary() *v1alpha3.Canary {
|
||||
cd := &v1alpha3.Canary{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: v1alpha3.SchemeGroupVersion.String()},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "podinfo",
|
||||
},
|
||||
Spec: v1alpha2.CanarySpec{
|
||||
Spec: v1alpha3.CanarySpec{
|
||||
TargetRef: hpav1.CrossVersionObjectReference{
|
||||
Name: "podinfo",
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
AutoscalerRef: hpav1.CrossVersionObjectReference{
|
||||
AutoscalerRef: &hpav1.CrossVersionObjectReference{
|
||||
Name: "podinfo",
|
||||
APIVersion: "autoscaling/v2beta1",
|
||||
Kind: "HorizontalPodAutoscaler",
|
||||
}, Service: v1alpha2.CanaryService{
|
||||
}, Service: v1alpha3.CanaryService{
|
||||
Port: 9898,
|
||||
}, CanaryAnalysis: v1alpha2.CanaryAnalysis{
|
||||
}, CanaryAnalysis: v1alpha3.CanaryAnalysis{
|
||||
Threshold: 10,
|
||||
StepWeight: 10,
|
||||
MaxWeight: 50,
|
||||
Metrics: []v1alpha2.CanaryMetric{
|
||||
Metrics: []v1alpha3.CanaryMetric{
|
||||
{
|
||||
Name: "istio_requests_total",
|
||||
Threshold: 99,
|
||||
@@ -356,7 +356,7 @@ func TestCanaryDeployer_SetFailedChecks(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
res, err := flaggerClient.FlaggerV1alpha2().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
res, err := flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
@@ -387,18 +387,18 @@ func TestCanaryDeployer_SetState(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
err = deployer.SetState(canary, v1alpha2.CanaryRunning)
|
||||
err = deployer.SetState(canary, v1alpha3.CanaryRunning)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
res, err := flaggerClient.FlaggerV1alpha2().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
res, err := flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if res.Status.State != v1alpha2.CanaryRunning {
|
||||
t.Errorf("Got %v wanted %v", res.Status.State, v1alpha2.CanaryRunning)
|
||||
if res.Status.State != v1alpha3.CanaryRunning {
|
||||
t.Errorf("Got %v wanted %v", res.Status.State, v1alpha3.CanaryRunning)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,8 +423,8 @@ func TestCanaryDeployer_SyncStatus(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
status := v1alpha2.CanaryStatus{
|
||||
State: v1alpha2.CanaryRunning,
|
||||
status := v1alpha3.CanaryStatus{
|
||||
State: v1alpha3.CanaryRunning,
|
||||
FailedChecks: 2,
|
||||
}
|
||||
err = deployer.SyncStatus(canary, status)
|
||||
@@ -432,7 +432,7 @@ func TestCanaryDeployer_SyncStatus(t *testing.T) {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
res, err := flaggerClient.FlaggerV1alpha2().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
res, err := flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package controller
|
||||
|
||||
import "time"
|
||||
|
||||
// CanaryJob holds the reference to a canary deployment schedule
|
||||
type CanaryJob struct {
|
||||
Name string
|
||||
Namespace string
|
||||
function func(name string, namespace string)
|
||||
done chan bool
|
||||
ticker *time.Ticker
|
||||
}
|
||||
|
||||
// Start runs the canary analysis on a schedule
|
||||
func (j CanaryJob) Start() {
|
||||
go func() {
|
||||
// run the infra bootstrap on job creation
|
||||
j.function(j.Name, j.Namespace)
|
||||
for {
|
||||
select {
|
||||
case <-j.ticker.C:
|
||||
j.function(j.Name, j.Namespace)
|
||||
case <-j.done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop closes the job channel and stops the ticker
|
||||
func (j CanaryJob) Stop() {
|
||||
close(j.done)
|
||||
j.ticker.Stop()
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
)
|
||||
|
||||
// CanaryRecorder records the canary analysis as Prometheus metrics
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
istiov1alpha3 "github.com/knative/pkg/apis/istio/v1alpha3"
|
||||
istioclientset "github.com/knative/pkg/client/clientset/versioned"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
|
||||
"go.uber.org/zap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
@@ -4,26 +4,57 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// scheduleCanaries synchronises the canary map with the jobs map,
|
||||
// for new canaries new jobs are created and started
|
||||
// for the removed canaries the jobs are stopped and deleted
|
||||
func (c *Controller) scheduleCanaries() {
|
||||
current := make(map[string]bool)
|
||||
stats := make(map[string]int)
|
||||
|
||||
c.canaries.Range(func(key interface{}, value interface{}) bool {
|
||||
r := value.(*flaggerv1.Canary)
|
||||
if r.Spec.TargetRef.Kind == "Deployment" {
|
||||
go c.advanceCanary(r.Name, r.Namespace)
|
||||
canary := value.(*flaggerv1.Canary)
|
||||
|
||||
// format: <name>.<namespace>
|
||||
name := key.(string)
|
||||
current[name] = true
|
||||
|
||||
// schedule new jobs
|
||||
if _, exists := c.jobs[name]; !exists {
|
||||
job := CanaryJob{
|
||||
Name: canary.Name,
|
||||
Namespace: canary.Namespace,
|
||||
function: c.advanceCanary,
|
||||
done: make(chan bool),
|
||||
ticker: time.NewTicker(canary.GetAnalysisInterval()),
|
||||
}
|
||||
|
||||
c.jobs[name] = job
|
||||
job.Start()
|
||||
}
|
||||
|
||||
t, ok := stats[r.Namespace]
|
||||
// compute canaries per namespace total
|
||||
t, ok := stats[canary.Namespace]
|
||||
if !ok {
|
||||
stats[r.Namespace] = 1
|
||||
stats[canary.Namespace] = 1
|
||||
} else {
|
||||
stats[r.Namespace] = t + 1
|
||||
stats[canary.Namespace] = t + 1
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
// cleanup deleted jobs
|
||||
for job := range c.jobs {
|
||||
if _, exists := current[job]; !exists {
|
||||
c.jobs[job].Stop()
|
||||
delete(c.jobs, job)
|
||||
}
|
||||
}
|
||||
|
||||
// set total canaries per namespace metric
|
||||
for k, v := range stats {
|
||||
c.recorder.SetTotal(k, v)
|
||||
}
|
||||
@@ -32,7 +63,7 @@ func (c *Controller) scheduleCanaries() {
|
||||
func (c *Controller) advanceCanary(name string, namespace string) {
|
||||
begin := time.Now()
|
||||
// check if the canary exists
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha2().Canaries(namespace).Get(name, v1.GetOptions{})
|
||||
cd, err := c.flaggerClient.FlaggerV1alpha3().Canaries(namespace).Get(name, v1.GetOptions{})
|
||||
if err != nil {
|
||||
c.logger.Errorf("Canary %s.%s not found", name, namespace)
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
fakeIstio "github.com/knative/pkg/client/clientset/versioned/fake"
|
||||
"github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
"github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
fakeFlagger "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/fake"
|
||||
informers "github.com/stefanprodan/flagger/pkg/client/informers/externalversions"
|
||||
"github.com/stefanprodan/flagger/pkg/logging"
|
||||
@@ -47,7 +47,7 @@ func TestScheduler_Init(t *testing.T) {
|
||||
}
|
||||
|
||||
flaggerInformerFactory := informers.NewSharedInformerFactory(flaggerClient, noResyncPeriodFunc())
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha2().Canaries()
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
|
||||
|
||||
ctrl := &Controller{
|
||||
kubeClient: kubeClient,
|
||||
@@ -101,7 +101,7 @@ func TestScheduler_NewRevision(t *testing.T) {
|
||||
}
|
||||
|
||||
flaggerInformerFactory := informers.NewSharedInformerFactory(flaggerClient, noResyncPeriodFunc())
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha2().Canaries()
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
|
||||
|
||||
ctrl := &Controller{
|
||||
kubeClient: kubeClient,
|
||||
@@ -170,7 +170,7 @@ func TestScheduler_Rollback(t *testing.T) {
|
||||
}
|
||||
|
||||
flaggerInformerFactory := informers.NewSharedInformerFactory(flaggerClient, noResyncPeriodFunc())
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha2().Canaries()
|
||||
flaggerInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
|
||||
|
||||
ctrl := &Controller{
|
||||
kubeClient: kubeClient,
|
||||
@@ -194,7 +194,7 @@ func TestScheduler_Rollback(t *testing.T) {
|
||||
ctrl.advanceCanary("podinfo", "default")
|
||||
|
||||
// update failed checks to max
|
||||
err := deployer.SyncStatus(canary, v1alpha2.CanaryStatus{State: v1alpha2.CanaryRunning, FailedChecks: 11})
|
||||
err := deployer.SyncStatus(canary, v1alpha3.CanaryStatus{State: v1alpha3.CanaryRunning, FailedChecks: 11})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
@@ -202,12 +202,12 @@ func TestScheduler_Rollback(t *testing.T) {
|
||||
// detect changes
|
||||
ctrl.advanceCanary("podinfo", "default")
|
||||
|
||||
c, err := flaggerClient.FlaggerV1alpha2().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
c, err := flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if c.Status.State != v1alpha2.CanaryFailed {
|
||||
t.Errorf("Got canary state %v wanted %v", c.Status.State, v1alpha2.CanaryFailed)
|
||||
if c.Status.State != v1alpha3.CanaryFailed {
|
||||
t.Errorf("Got canary state %v wanted %v", c.Status.State, v1alpha3.CanaryFailed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha2"
|
||||
flaggerv1 "github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package version
|
||||
|
||||
var VERSION = "0.2.0"
|
||||
var VERSION = "0.3.0-beta.1"
|
||||
var REVISION = "unknown"
|
||||
|
||||
Reference in New Issue
Block a user