mirror of
https://github.com/fluxcd/flagger.git
synced 2026-02-15 18:40:12 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7e675144d | ||
|
|
3bff2c339b | ||
|
|
b035c1e7fb | ||
|
|
7ae0d49e80 | ||
|
|
07f66e849d | ||
|
|
06c29051eb | ||
|
|
83118faeb3 | ||
|
|
aa2c28c733 | ||
|
|
10185407f6 | ||
|
|
c1bde57c17 | ||
|
|
882b4b2d23 | ||
|
|
cac585157f | ||
|
|
cc2860a49f | ||
|
|
bec96356ec | ||
|
|
b5c648ea54 | ||
|
|
e6e3e500be | ||
|
|
537e8fdaf7 | ||
|
|
322c83bdad | ||
|
|
41f0ba0247 | ||
|
|
b67b49fde6 |
@@ -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
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
apiVersion: v1
|
||||
name: flagger
|
||||
version: 0.2.0
|
||||
appVersion: 0.2.0
|
||||
version: 0.3.0
|
||||
appVersion: 0.3.0
|
||||
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
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
controlLoopInterval: "10s"
|
||||
metricsServer: "http://prometheus.istio-system.svc.cluster.local:9090"
|
||||
|
||||
slack:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
BIN
docs/flagger-0.3.0.tgz
Normal file
BIN
docs/flagger-0.3.0.tgz
Normal file
Binary file not shown.
@@ -5,8 +5,8 @@
|
||||
|
||||
## Install
|
||||
|
||||
* [Install Flagger](install/installing-flagger.md)
|
||||
* [Install Grafana](install/installing-grafana.md)
|
||||
* [Install Flagger](install/install-flagger.md)
|
||||
* [Install Grafana](install/install-grafana.md)
|
||||
* [Install Istio](install/install-istio.md)
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
[Flagger](https://github.com/stefanprodan/flagger) takes a Kubernetes deployment and optionally a horizontal pod autoscaler \(HPA\) and creates a series of objects \(Kubernetes deployments, ClusterIP services and Istio virtual services\) to drive the canary analysis and promotion.
|
||||
|
||||

|
||||

|
||||
|
||||
### Canary Custom Resource
|
||||
|
||||
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
|
||||
@@ -36,8 +36,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
|
||||
@@ -63,14 +65,35 @@ spec:
|
||||
- name: integration-tests
|
||||
url: http://podinfo.test:9898/echo
|
||||
timeout: 1m
|
||||
# key-value pairs (optional)
|
||||
metadata:
|
||||
test: "all"
|
||||
token: "16688eb5e9f289f1991c"
|
||||
```
|
||||
|
||||
**Note** that the target deployment must have a single label selector in the format `app: <DEPLOYMENT-NAME>`:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: podinfo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: podinfo
|
||||
```
|
||||
|
||||
The target deployment should expose a TCP port that will be used by Flagger to create the ClusterIP Service and
|
||||
the Istio Virtual Service. The container port from the target deployment should match the `service.port` value.
|
||||
|
||||
### Canary Deployment
|
||||
|
||||

|
||||

|
||||
|
||||
Gated canary promotion stages:
|
||||
|
||||
@@ -99,17 +122,21 @@ Gated canary promotion stages:
|
||||
* halt advancement if pods are unhealthy
|
||||
* route all traffic to primary
|
||||
* scale to zero the canary deployment
|
||||
* mark rollout as finished
|
||||
* mark the canary deployment as finished
|
||||
* wait for the canary deployment to be updated \(revision bump\) and start over
|
||||
|
||||
You can change the canary analysis _max weight_ and the _step weight_ percentage in the Flagger's custom resource.
|
||||
|
||||
### Canary Analysis
|
||||
|
||||
The canary analysis runs periodically until it reaches the maximum traffic weight or the failed checks threshold.
|
||||
|
||||
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
|
||||
@@ -117,19 +144,20 @@ Spec:
|
||||
maxWeight: 50
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 5
|
||||
stepWeight: 2
|
||||
```
|
||||
|
||||
The above analysis, if it succeeds, will run for 25 minutes while validating the HTTP metrics and webhooks every minute.
|
||||
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
|
||||
@@ -205,10 +233,12 @@ histogram_quantile(0.99,
|
||||
)
|
||||
```
|
||||
|
||||
> **Note** that the metric interval should be lower or equal to the control loop interval.
|
||||
|
||||
### Webhooks
|
||||
|
||||
The canary analysis can be extended with webhooks.
|
||||
Flagger would call a URL (HTTP POST) and determine from the response status code (HTTP 2xx) if the canary is failing or not.
|
||||
Flagger will call each webhook URL and determine from the response status code (HTTP 2xx) if the canary is failing or not.
|
||||
|
||||
Spec:
|
||||
|
||||
@@ -217,13 +247,21 @@ Spec:
|
||||
webhooks:
|
||||
- name: integration-tests
|
||||
url: http://podinfo.test:9898/echo
|
||||
timeout: 1m
|
||||
timeout: 30s
|
||||
metadata:
|
||||
test: "all"
|
||||
token: "16688eb5e9f289f1991c"
|
||||
- name: load-tests
|
||||
url: http://podinfo.test:9898/echo
|
||||
timeout: 30s
|
||||
metadata:
|
||||
key1: "val1"
|
||||
key2: "val2"
|
||||
```
|
||||
|
||||
Webhook payload:
|
||||
> **Note** that the sum of all webhooks timeouts should be lower than the control loop interval.
|
||||
|
||||
Webhook payload (HTTP POST):
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Install Flagger
|
||||
|
||||
Before installing Flagger make sure you have [Istio](https://istio.io) running with Prometheus enabled. If you are new to Istio you can follow this GKE guide [Istio service mesh walk-through](https://docs.flagger.app/install/install-istio).
|
||||
Before installing Flagger make sure you have [Istio](https://istio.io) running with Prometheus enabled.
|
||||
If you are new to Istio you can follow this GKE guide
|
||||
[Istio service mesh walk-through](https://docs.flagger.app/install/install-istio).
|
||||
|
||||
**Prerequisites**
|
||||
|
||||
@@ -21,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:
|
||||
@@ -61,11 +62,12 @@ helm delete --purge flagger
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
{% hint style="info" %}
|
||||
On uninstall the Flagger CRD will not be removed. Deleting the CRD will make Kubernetes remove all the objects owned by the CRD like Istio virtual services, Kubernetes deployments and ClusterIP services.
|
||||
{% endhint %}
|
||||
> **Note** that on uninstall the Canary CRD will not be removed.
|
||||
Deleting the CRD will make Kubernetes remove all the objects owned by Flagger like Istio virtual services,
|
||||
Kubernetes deployments and ClusterIP services.
|
||||
|
||||
If you want to remove all the objects created by Flagger you have delete the canary CRD with kubectl:
|
||||
|
||||
If you want to remove all the objects created by Flagger you have delete the Canary CRD with kubectl:
|
||||
|
||||
```text
|
||||
kubectl delete crd canaries.flagger.app
|
||||
@@ -1,12 +1,14 @@
|
||||
# Install Istio
|
||||
|
||||
This guide walks you through setting up Istio with Jaeger, Prometheus, Grafana and Let’s Encrypt TLS for ingress gateway on Google Kubernetes Engine.
|
||||
This guide walks you through setting up Istio with Jaeger, Prometheus, Grafana and
|
||||
Let’s Encrypt TLS for ingress gateway on Google Kubernetes Engine.
|
||||
|
||||

|
||||
|
||||
### Prerequisites
|
||||
|
||||
You will be creating a cluster on Google’s Kubernetes Engine \(GKE\), if you don’t have an account you can sign up [here](https://cloud.google.com/free/) for free credits.
|
||||
You will be creating a cluster on Google’s Kubernetes Engine \(GKE\),
|
||||
if you don’t have an account you can sign up [here](https://cloud.google.com/free/) for free credits.
|
||||
|
||||
Login into GCP, create a project and enable billing for it.
|
||||
|
||||
@@ -64,7 +66,9 @@ gcloud container clusters create istio \
|
||||
--scopes=gke-default,compute-rw,storage-rw
|
||||
```
|
||||
|
||||
The above command will create a default node pool consisting of `n1-highcpu-4` \(vCPU: 4, RAM 3.60GB, DISK: 30GB\) preemptible VMs. Preemptible VMs are up to 80% cheaper than regular instances and are terminated and replaced after a maximum of 24 hours.
|
||||
The above command will create a default node pool consisting of `n1-highcpu-4` \(vCPU: 4, RAM 3.60GB, DISK: 30GB\)
|
||||
preemptible VMs. Preemptible VMs are up to 80% cheaper than regular instances and are terminated and replaced
|
||||
after a maximum of 24 hours.
|
||||
|
||||
Set up credentials for `kubectl`:
|
||||
|
||||
@@ -330,10 +334,11 @@ kubectl create secret generic cert-manager-credentials \
|
||||
--namespace=istio-system
|
||||
```
|
||||
|
||||
Create a letsencrypt issuer for CloudDNS \(replace `email@example.com` with a valid email address and `my-gcp-project`with your project ID\):
|
||||
Create a letsencrypt issuer for CloudDNS \(replace `email@example.com` with a valid email address and
|
||||
`my-gcp-project`with your project ID\):
|
||||
|
||||
```yaml
|
||||
apiVersion: v1alpha2
|
||||
apiVersion: certmanager.k8s.io/v1alpha1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: letsencrypt-prod
|
||||
@@ -363,7 +368,7 @@ kubectl apply -f ./letsencrypt-issuer.yaml
|
||||
Create a wildcard certificate \(replace `example.com` with your domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: v1alpha2
|
||||
apiVersion: certmanager.k8s.io/v1alpha1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: istio-gateway
|
||||
@@ -403,7 +408,10 @@ Recreate Istio ingress gateway pods:
|
||||
kubectl -n istio-system delete pods -l istio=ingressgateway
|
||||
```
|
||||
|
||||
Note that Istio gateway doesn't reload the certificates from the TLS secret on cert-manager renewal. Since the GKE cluster is made out of preemptible VMs the gateway pods will be replaced once every 24h, if your not using preemptible nodes then you need to manually kill the gateway pods every two months before the certificate expires.
|
||||
Note that Istio gateway doesn't reload the certificates from the TLS secret on cert-manager renewal.
|
||||
Since the GKE cluster is made out of preemptible VMs the gateway pods will be replaced once every 24h,
|
||||
if your not using preemptible nodes then you need to manually kill the gateway pods every two months
|
||||
before the certificate expires.
|
||||
|
||||
### Expose services outside the service mesh
|
||||
|
||||
|
||||
@@ -12,11 +12,13 @@ helm upgrade -i flagger flagger/flagger \
|
||||
--set slack.user=flagger
|
||||
```
|
||||
|
||||
Once configured with a Slack incoming **webhook**, Flagger will post messages when a canary deployment has been initialised, when a new revision has been detected and if the canary analysis failed or succeeded.
|
||||
Once configured with a Slack incoming **webhook**, Flagger will post messages when a canary deployment
|
||||
has been initialised, when a new revision has been detected and if the canary analysis failed or succeeded.
|
||||
|
||||

|
||||
|
||||
A canary deployment will be rolled back if the progress deadline exceeded or if the analysis reached the maximum number of failed checks:
|
||||
A canary deployment will be rolled back if the progress deadline exceeded or if the analysis reached the
|
||||
maximum number of failed checks:
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ Promotion completed! podinfo.test
|
||||
|
||||
### Metrics
|
||||
|
||||
Flagger exposes Prometheus metrics that can be used to determine the canary analysis status and the destination weight values:
|
||||
Flagger exposes Prometheus metrics that can be used to determine the canary analysis status and
|
||||
the destination weight values:
|
||||
|
||||
```bash
|
||||
# Canaries total gauge
|
||||
@@ -65,5 +66,4 @@ flagger_canary_duration_seconds_sum{name="podinfo",namespace="test"} 17.3561329
|
||||
flagger_canary_duration_seconds_count{name="podinfo",namespace="test"} 6
|
||||
```
|
||||
|
||||
####
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -1,9 +1,34 @@
|
||||
apiVersion: v1
|
||||
entries:
|
||||
flagger:
|
||||
- apiVersion: v1
|
||||
appVersion: 0.3.0
|
||||
created: 2019-01-11T20:08:47.476526+02:00
|
||||
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.
|
||||
digest: 8baa478cc802f4e6b7593934483359b8f70ec34413ca3b8de3a692e347a9bda4
|
||||
engine: gotpl
|
||||
home: https://docs.flagger.app
|
||||
icon: https://raw.githubusercontent.com/stefanprodan/flagger/master/docs/logo/flagger-icon.png
|
||||
keywords:
|
||||
- canary
|
||||
- istio
|
||||
- gitops
|
||||
kubeVersion: '>=1.9.0-0'
|
||||
maintainers:
|
||||
- email: stefanprodan@users.noreply.github.com
|
||||
name: stefanprodan
|
||||
url: https://github.com/stefanprodan
|
||||
name: flagger
|
||||
sources:
|
||||
- https://github.com/stefanprodan/flagger
|
||||
urls:
|
||||
- https://stefanprodan.github.io/flagger/flagger-0.3.0.tgz
|
||||
version: 0.3.0
|
||||
- apiVersion: v1
|
||||
appVersion: 0.2.0
|
||||
created: 2019-01-04T13:38:42.239798+02:00
|
||||
created: 2019-01-11T20:08:47.476127+02:00
|
||||
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.
|
||||
@@ -28,7 +53,7 @@ entries:
|
||||
version: 0.2.0
|
||||
- apiVersion: v1
|
||||
appVersion: 0.1.2
|
||||
created: 2019-01-04T13:38:42.239389+02:00
|
||||
created: 2019-01-11T20:08:47.475257+02:00
|
||||
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.
|
||||
@@ -53,7 +78,7 @@ entries:
|
||||
version: 0.1.2
|
||||
- apiVersion: v1
|
||||
appVersion: 0.1.1
|
||||
created: 2019-01-04T13:38:42.238504+02:00
|
||||
created: 2019-01-11T20:08:47.474547+02:00
|
||||
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.
|
||||
@@ -65,7 +90,7 @@ entries:
|
||||
version: 0.1.1
|
||||
- apiVersion: v1
|
||||
appVersion: 0.1.0
|
||||
created: 2019-01-04T13:38:42.237702+02:00
|
||||
created: 2019-01-11T20:08:47.473757+02:00
|
||||
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.
|
||||
@@ -78,9 +103,9 @@ entries:
|
||||
grafana:
|
||||
- apiVersion: v1
|
||||
appVersion: 5.4.2
|
||||
created: 2019-01-04T13:38:42.24034+02:00
|
||||
created: 2019-01-11T20:08:47.477041+02:00
|
||||
description: Grafana dashboards for monitoring Flagger canary deployments
|
||||
digest: f94c0c2eaf7a7db7ef070575d280c37f93922c0e11ebdf203482c9f43603a1c9
|
||||
digest: 1c929348357ea747405308125d9c7969cf743de5ab9e8adff6fa83943593b2f0
|
||||
home: https://flagger.app
|
||||
icon: https://raw.githubusercontent.com/stefanprodan/flagger/master/docs/logo/flagger-icon.png
|
||||
maintainers:
|
||||
@@ -93,4 +118,4 @@ entries:
|
||||
urls:
|
||||
- https://stefanprodan.github.io/flagger/grafana-0.1.0.tgz
|
||||
version: 0.1.0
|
||||
generated: 2019-01-04T13:38:42.236727+02:00
|
||||
generated: 2019-01-11T20:08:47.472865+02:00
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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").
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
cd, 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())
|
||||
}
|
||||
|
||||
34
pkg/controller/job.go
Normal file
34
pkg/controller/job.go
Normal file
@@ -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"
|
||||
@@ -164,12 +164,13 @@ func (c *CanaryRouter) createServices(cd *flaggerv1.Canary) error {
|
||||
}
|
||||
|
||||
func (c *CanaryRouter) createVirtualService(cd *flaggerv1.Canary) error {
|
||||
canaryName := cd.Spec.TargetRef.Name
|
||||
canaryName := cd.Name
|
||||
primaryName := fmt.Sprintf("%s-primary", canaryName)
|
||||
hosts := append(cd.Spec.Service.Hosts, canaryName)
|
||||
gateways := append(cd.Spec.Service.Gateways, "mesh")
|
||||
virtualService, err := c.istioClient.NetworkingV1alpha3().VirtualServices(cd.Namespace).Get(canaryName, metav1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
c.logger.Debugf("VirtualService %s.%s not found", canaryName, cd.Namespace)
|
||||
virtualService = &istiov1alpha3.VirtualService{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cd.Name,
|
||||
@@ -212,6 +213,7 @@ func (c *CanaryRouter) createVirtualService(cd *flaggerv1.Canary) error {
|
||||
},
|
||||
}
|
||||
|
||||
c.logger.Debugf("Creating VirtualService %s.%s", virtualService.GetName(), cd.Namespace)
|
||||
_, err = c.istioClient.NetworkingV1alpha3().VirtualServices(cd.Namespace).Create(virtualService)
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualService %s.%s create error %v", cd.Name, cd.Namespace, err)
|
||||
|
||||
@@ -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"
|
||||
var REVISION = "unknown"
|
||||
|
||||
Reference in New Issue
Block a user