Repository: weaveworks/flagger
Pull request #423 (2020-02-07 10:34:20)

crd: Release flagger.app/v1beta1
- promote the Canary and MetricTemplate APIs to v1beta1
- maintain backwards compatibility with `canaries.flagger.app/v1alpha3`
- maintain backwards compatibility with `metrictemplate.flagger.app/v1alpha1`
- implement in-cluster upgrade for the alpha resources
- improve CRD validation


Patch:
diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml
index c8092d8c..1189b830 100644
--- a/artifacts/flagger/crd.yaml
+++ b/artifacts/flagger/crd.yaml
@@ -6,16 +6,19 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha3
+  version: v1beta1
   versions:
-    - name: v1alpha3
+    - name: v1beta1
       served: true
       storage: true
-    - name: v1alpha2
+    - name: v1alpha3
       served: true
       storage: false
+    - name: v1alpha2
+      served: false
+      storage: false
     - name: v1alpha1
-      served: true
+      served: false
       storage: false
   names:
     plural: canaries
@@ -112,6 +115,7 @@ spec:
                 name:
                   type: string
             service:
+              description: Kubernetes Service spec
               type: object
               required: ["port"]
               properties:
@@ -137,53 +141,48 @@ spec:
                   type: string
                 backends:
                   description: AppMesh backend array
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: string
                 timeout:
                   description: Istio HTTP or gRPC request timeout
                   type: string
                 trafficPolicy:
                   description: Istio traffic policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  type: object
                 match:
-                  description: Istio URL match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: URL match conditions
+                  type: array
+                  items:
+                    type: object
                 rewrite:
-                  description: Istio URL rewrite
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: URL rewrite
+                  type: object
                 headers:
-                  description: Istio headers operations
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: Headers operations
+                  type: object
                 corsPolicy:
-                  description: Istio CORS policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: CORS policy
+                  type: object
                 gateways:
-                  description: Istio gateways list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Gateway list
+                  type: array
+                  items:
+                    type: string
                 hosts:
-                  description: Istio hosts list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Host list
+                  type: array
+                  items:
+                    type: string
             skipAnalysis:
+              description: Skip analysis and promote canary
               type: boolean
             canaryAnalysis:
+              description: Canary analysis for this canary
+              type: object
               properties:
                 interval:
-                  description: Canary schedule interval
+                  description: Schedule interval for this canary
                   type: string
                   pattern: "^[0-9]+(m|s)"
                 iterations:
@@ -196,84 +195,82 @@ spec:
                   description: Max traffic percentage routed to canary
                   type: number
                 stepWeight:
-                  description: Canary incremental traffic percentage step
+                  description: Incremental traffic percentage step
                   type: number
                 mirror:
                   description: Mirror traffic to canary before shifting
                   type: boolean
                 match:
                   description: A/B testing match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: object
                 metrics:
-                  description: Prometheus query list for this canary
+                  description: Metric check list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "threshold"]
-                      properties:
-                        name:
-                          description: Name of the metric
-                          type: string
-                        interval:
-                          description: Interval of the query
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        threshold:
-                          description: Max value accepted for this metric
-                          type: number
-                        query:
-                          description: Prometheus query
-                          type: string
-                        templateRef:
-                          description: Metric template reference
-                          type: object
-                          required: ["name"]
-                          properties:
-                            name:
-                              description: Name of this metric template
-                              type: string
-                            namespace:
-                              description: Namespace of this metric template
-                              type: string
+                  items:
+                    type: object
+                    required: ["name", "threshold"]
+                    properties:
+                      name:
+                        description: Name of the metric
+                        type: string
+                      interval:
+                        description: Interval of the query
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      threshold:
+                        description: Max value accepted for this metric
+                        type: number
+                      query:
+                        description: Prometheus query
+                        type: string
+                      templateRef:
+                        description: Metric template reference
+                        type: object
+                        required: ["name"]
+                        properties:
+                          name:
+                            description: Name of this metric template
+                            type: string
+                          namespace:
+                            description: Namespace of this metric template
+                            type: string
                 webhooks:
                   description: Webhook list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "url"]
-                      properties:
-                        name:
-                          description: Name of the webhook
-                          type: string
-                        type:
-                          description: Type of the webhook pre, post or during rollout
-                          type: string
-                          enum:
-                            - ""
-                            - confirm-rollout
-                            - pre-rollout
-                            - rollout
-                            - confirm-promotion
-                            - post-rollout
-                            - event
-                            - rollback
-                        url:
-                          description: URL address of this webhook
-                          type: string
-                          format: url
-                        timeout:
-                          description: Request timeout for this webhook
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        metadata:
-                          description: Metadata (key-value pairs) for this webhook
-                          anyOf:
-                            - type: string
-                            - type: object
+                  items:
+                    type: object
+                    required: ["name", "url"]
+                    properties:
+                      name:
+                        description: Name of the webhook
+                        type: string
+                      type:
+                        description: Type of the webhook pre, post or during rollout
+                        type: string
+                        enum:
+                          - ""
+                          - confirm-rollout
+                          - pre-rollout
+                          - rollout
+                          - confirm-promotion
+                          - post-rollout
+                          - event
+                          - rollback
+                      url:
+                        description: URL address of this webhook
+                        type: string
+                        format: url
+                      timeout:
+                        description: Request timeout for this webhook
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      metadata:
+                        description: Metadata (key-value pairs) for this webhook
+                        anyOf:
+                          - type: string
+                          - type: object
         status:
           properties:
             phase:
@@ -308,31 +305,30 @@ spec:
             conditions:
               description: Status conditions of this canary
               type: array
-              properties:
-                items:
-                  type: object
-                  required: ["type", "status", "reason"]
-                  properties:
-                    lastTransitionTime:
-                      description: LastTransitionTime of this condition
-                      format: date-time
-                      type: string
-                    lastUpdateTime:
-                      description: LastUpdateTime of this condition
-                      format: date-time
-                      type: string
-                    message:
-                      description: Message associated with this condition
-                      type: string
-                    reason:
-                      description: Reason for the current status of this condition
-                      type: string
-                    status:
-                      description: Status of this condition
-                      type: string
-                    type:
-                      description: Type of this condition
-                      type: string
+              items:
+                type: object
+                required: ["type", "status", "reason"]
+                properties:
+                  lastTransitionTime:
+                    description: LastTransitionTime of this condition
+                    format: date-time
+                    type: string
+                  lastUpdateTime:
+                    description: LastUpdateTime of this condition
+                    format: date-time
+                    type: string
+                  message:
+                    description: Message associated with this condition
+                    type: string
+                  reason:
+                    description: Reason for the current status of this condition
+                    type: string
+                  status:
+                    description: Status of this condition
+                    type: string
+                  type:
+                    description: Type of this condition
+                    type: string
 ---
 apiVersion: apiextensions.k8s.io/v1beta1
 kind: CustomResourceDefinition
@@ -342,11 +338,14 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha1
+  version: v1beta1
   versions:
-    - name: v1alpha1
+    - name: v1beta1
       served: true
       storage: true
+    - name: v1alpha1
+      served: true
+      storage: false
   names:
     plural: metrictemplates
     singular: metrictemplate
@@ -356,6 +355,10 @@ spec:
   scope: Namespaced
   subresources:
     status: {}
+  additionalPrinterColumns:
+    - name: Provider
+      type: string
+      JSONPath: .spec.provider.type
   validation:
     openAPIV3Schema:
       properties:
diff --git a/charts/flagger/templates/crd.yaml b/charts/flagger/templates/crd.yaml
index 3bfc48bd..bbeec6fc 100644
--- a/charts/flagger/templates/crd.yaml
+++ b/charts/flagger/templates/crd.yaml
@@ -7,16 +7,19 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha3
+  version: v1beta1
   versions:
-    - name: v1alpha3
+    - name: v1beta1
       served: true
       storage: true
-    - name: v1alpha2
+    - name: v1alpha3
       served: true
       storage: false
+    - name: v1alpha2
+      served: false
+      storage: false
     - name: v1alpha1
-      served: true
+      served: false
       storage: false
   names:
     plural: canaries
@@ -113,6 +116,7 @@ spec:
                 name:
                   type: string
             service:
+              description: Kubernetes Service spec
               type: object
               required: ["port"]
               properties:
@@ -138,53 +142,48 @@ spec:
                   type: string
                 backends:
                   description: AppMesh backend array
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: string
                 timeout:
                   description: Istio HTTP or gRPC request timeout
                   type: string
                 trafficPolicy:
                   description: Istio traffic policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  type: object
                 match:
-                  description: Istio URL match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: URL match conditions
+                  type: array
+                  items:
+                    type: object
                 rewrite:
-                  description: Istio URL rewrite
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: URL rewrite
+                  type: object
                 headers:
-                  description: Istio headers operations
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: Headers operations
+                  type: object
                 corsPolicy:
-                  description: Istio CORS policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: CORS policy
+                  type: object
                 gateways:
-                  description: Istio gateways list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Gateway list
+                  type: array
+                  items:
+                    type: string
                 hosts:
-                  description: Istio hosts list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Host list
+                  type: array
+                  items:
+                    type: string
             skipAnalysis:
+              description: Skip analysis and promote canary
               type: boolean
             canaryAnalysis:
+              description: Canary analysis for this canary
+              type: object
               properties:
                 interval:
-                  description: Canary schedule interval
+                  description: Schedule interval for this canary
                   type: string
                   pattern: "^[0-9]+(m|s)"
                 iterations:
@@ -197,84 +196,82 @@ spec:
                   description: Max traffic percentage routed to canary
                   type: number
                 stepWeight:
-                  description: Canary incremental traffic percentage step
+                  description: Incremental traffic percentage step
                   type: number
                 mirror:
                   description: Mirror traffic to canary before shifting
                   type: boolean
                 match:
                   description: A/B testing match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: object
                 metrics:
-                  description: Prometheus query list for this canary
+                  description: Metric check list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "threshold"]
-                      properties:
-                        name:
-                          description: Name of the metric
-                          type: string
-                        interval:
-                          description: Interval of the query
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        threshold:
-                          description: Max value accepted for this metric
-                          type: number
-                        query:
-                          description: Prometheus query
-                          type: string
-                        templateRef:
-                          description: Metric template reference
-                          type: object
-                          required: ["name"]
-                          properties:
-                            name:
-                              description: Name of this metric template
-                              type: string
-                            namespace:
-                              description: Namespace of this metric template
-                              type: string
+                  items:
+                    type: object
+                    required: ["name", "threshold"]
+                    properties:
+                      name:
+                        description: Name of the metric
+                        type: string
+                      interval:
+                        description: Interval of the query
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      threshold:
+                        description: Max value accepted for this metric
+                        type: number
+                      query:
+                        description: Prometheus query
+                        type: string
+                      templateRef:
+                        description: Metric template reference
+                        type: object
+                        required: ["name"]
+                        properties:
+                          name:
+                            description: Name of this metric template
+                            type: string
+                          namespace:
+                            description: Namespace of this metric template
+                            type: string
                 webhooks:
                   description: Webhook list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "url"]
-                      properties:
-                        name:
-                          description: Name of the webhook
-                          type: string
-                        type:
-                          description: Type of the webhook pre, post or during rollout
-                          type: string
-                          enum:
-                            - ""
-                            - confirm-rollout
-                            - pre-rollout
-                            - rollout
-                            - confirm-promotion
-                            - post-rollout
-                            - event
-                            - rollback
-                        url:
-                          description: URL address of this webhook
-                          type: string
-                          format: url
-                        timeout:
-                          description: Request timeout for this webhook
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        metadata:
-                          description: Metadata (key-value pairs) for this webhook
-                          anyOf:
-                            - type: string
-                            - type: object
+                  items:
+                    type: object
+                    required: ["name", "url"]
+                    properties:
+                      name:
+                        description: Name of the webhook
+                        type: string
+                      type:
+                        description: Type of the webhook pre, post or during rollout
+                        type: string
+                        enum:
+                          - ""
+                          - confirm-rollout
+                          - pre-rollout
+                          - rollout
+                          - confirm-promotion
+                          - post-rollout
+                          - event
+                          - rollback
+                      url:
+                        description: URL address of this webhook
+                        type: string
+                        format: url
+                      timeout:
+                        description: Request timeout for this webhook
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      metadata:
+                        description: Metadata (key-value pairs) for this webhook
+                        anyOf:
+                          - type: string
+                          - type: object
         status:
           properties:
             phase:
@@ -309,31 +306,30 @@ spec:
             conditions:
               description: Status conditions of this canary
               type: array
-              properties:
-                items:
-                  type: object
-                  required: ["type", "status", "reason"]
-                  properties:
-                    lastTransitionTime:
-                      description: LastTransitionTime of this condition
-                      format: date-time
-                      type: string
-                    lastUpdateTime:
-                      description: LastUpdateTime of this condition
-                      format: date-time
-                      type: string
-                    message:
-                      description: Message associated with this condition
-                      type: string
-                    reason:
-                      description: Reason for the current status of this condition
-                      type: string
-                    status:
-                      description: Status of this condition
-                      type: string
-                    type:
-                      description: Type of this condition
-                      type: string
+              items:
+                type: object
+                required: ["type", "status", "reason"]
+                properties:
+                  lastTransitionTime:
+                    description: LastTransitionTime of this condition
+                    format: date-time
+                    type: string
+                  lastUpdateTime:
+                    description: LastUpdateTime of this condition
+                    format: date-time
+                    type: string
+                  message:
+                    description: Message associated with this condition
+                    type: string
+                  reason:
+                    description: Reason for the current status of this condition
+                    type: string
+                  status:
+                    description: Status of this condition
+                    type: string
+                  type:
+                    description: Type of this condition
+                    type: string
 ---
 apiVersion: apiextensions.k8s.io/v1beta1
 kind: CustomResourceDefinition
@@ -343,11 +339,14 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha1
+  version: v1beta1
   versions:
-    - name: v1alpha1
+    - name: v1beta1
       served: true
       storage: true
+    - name: v1alpha1
+      served: true
+      storage: false
   names:
     plural: metrictemplates
     singular: metrictemplate
@@ -357,6 +356,10 @@ spec:
   scope: Namespaced
   subresources:
     status: {}
+  additionalPrinterColumns:
+    - name: Provider
+      type: string
+      JSONPath: .spec.provider.type
   validation:
     openAPIV3Schema:
       properties:
diff --git a/cmd/flagger/main.go b/cmd/flagger/main.go
index d394c5c1..e8e29e6b 100644
--- a/cmd/flagger/main.go
+++ b/cmd/flagger/main.go
@@ -159,14 +159,14 @@ func main() {
 	flaggerInformerFactory := informers.NewSharedInformerFactoryWithOptions(flaggerClient, time.Second*30, informers.WithNamespace(namespace))
 
 	logger.Info("Waiting for canary informer cache to sync")
-	canaryInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
+	canaryInformer := flaggerInformerFactory.Flagger().V1beta1().Canaries()
 	go canaryInformer.Informer().Run(stopCh)
 	if ok := cache.WaitForNamedCacheSync("flagger", stopCh, canaryInformer.Informer().HasSynced); !ok {
 		logger.Fatalf("failed to wait for cache to sync")
 	}
 
 	logger.Info("Waiting for metric template informer cache to sync")
-	metricInformer := flaggerInformerFactory.Flagger().V1alpha1().MetricTemplates()
+	metricInformer := flaggerInformerFactory.Flagger().V1beta1().MetricTemplates()
 	go metricInformer.Informer().Run(stopCh)
 	if ok := cache.WaitForNamedCacheSync("flagger", stopCh, metricInformer.Informer().HasSynced); !ok {
 		logger.Fatalf("failed to wait for cache to sync")
@@ -304,12 +304,12 @@ func fromEnv(envVar string, defaultVal string) string {
 }
 
 func verifyCRDs(flaggerClient clientset.Interface, logger *zap.SugaredLogger) {
-	_, err := flaggerClient.FlaggerV1alpha3().Canaries(namespace).List(metav1.ListOptions{Limit: 1})
+	_, err := flaggerClient.FlaggerV1beta1().Canaries(namespace).List(metav1.ListOptions{Limit: 1})
 	if err != nil {
 		logger.Fatalf("Canary CRD is not registered %v", err)
 	}
 
-	_, err = flaggerClient.FlaggerV1alpha1().MetricTemplates(namespace).List(metav1.ListOptions{Limit: 1})
+	_, err = flaggerClient.FlaggerV1beta1().MetricTemplates(namespace).List(metav1.ListOptions{Limit: 1})
 	if err != nil {
 		logger.Fatalf("MetricTemplate CRD is not registered %v", err)
 	}
diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh
index d9f7d575..68508e50 100755
--- a/hack/update-codegen.sh
+++ b/hack/update-codegen.sh
@@ -4,7 +4,7 @@ set -o errexit
 set -o nounset
 set -o pipefail
 
-SCRIPT_ROOT=$(realpath $(dirname ${BASH_SOURCE})/..)
+SCRIPT_ROOT=$(git rev-parse --show-toplevel)
 
 # Grab code-generator version from go.sum.
 CODEGEN_VERSION=$(grep 'k8s.io/code-generator' go.sum | awk '{print $2}' | head -1)
@@ -30,7 +30,7 @@ chmod +x ${CODEGEN_PKG}/generate-groups.sh
 
 ${CODEGEN_PKG}/generate-groups.sh all \
     github.com/weaveworks/flagger/pkg/client github.com/weaveworks/flagger/pkg/apis \
-    "flagger:v1alpha3 flagger:v1alpha1 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 gloo:v1 projectcontour:v1" \
+    "flagger:v1beta1 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 gloo:v1 projectcontour:v1" \
     --output-base "${TEMP_DIR}" \
     --go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
 
diff --git a/hack/verify-codegen.sh b/hack/verify-codegen.sh
index d02a6fa3..0bee0bd7 100755
--- a/hack/verify-codegen.sh
+++ b/hack/verify-codegen.sh
@@ -18,7 +18,7 @@ set -o errexit
 set -o nounset
 set -o pipefail
 
-SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
+SCRIPT_ROOT=$(git rev-parse --show-toplevel)
 
 DIFFROOT="${SCRIPT_ROOT}/pkg"
 TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/pkg"
diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml
index c8092d8c..1189b830 100644
--- a/kustomize/base/flagger/crd.yaml
+++ b/kustomize/base/flagger/crd.yaml
@@ -6,16 +6,19 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha3
+  version: v1beta1
   versions:
-    - name: v1alpha3
+    - name: v1beta1
       served: true
       storage: true
-    - name: v1alpha2
+    - name: v1alpha3
       served: true
       storage: false
+    - name: v1alpha2
+      served: false
+      storage: false
     - name: v1alpha1
-      served: true
+      served: false
       storage: false
   names:
     plural: canaries
@@ -112,6 +115,7 @@ spec:
                 name:
                   type: string
             service:
+              description: Kubernetes Service spec
               type: object
               required: ["port"]
               properties:
@@ -137,53 +141,48 @@ spec:
                   type: string
                 backends:
                   description: AppMesh backend array
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: string
                 timeout:
                   description: Istio HTTP or gRPC request timeout
                   type: string
                 trafficPolicy:
                   description: Istio traffic policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  type: object
                 match:
-                  description: Istio URL match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: URL match conditions
+                  type: array
+                  items:
+                    type: object
                 rewrite:
-                  description: Istio URL rewrite
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: URL rewrite
+                  type: object
                 headers:
-                  description: Istio headers operations
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: Headers operations
+                  type: object
                 corsPolicy:
-                  description: Istio CORS policy
-                  anyOf:
-                    - type: string
-                    - type: object
+                  description: CORS policy
+                  type: object
                 gateways:
-                  description: Istio gateways list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Gateway list
+                  type: array
+                  items:
+                    type: string
                 hosts:
-                  description: Istio hosts list
-                  anyOf:
-                    - type: string
-                    - type: array
+                  description: Host list
+                  type: array
+                  items:
+                    type: string
             skipAnalysis:
+              description: Skip analysis and promote canary
               type: boolean
             canaryAnalysis:
+              description: Canary analysis for this canary
+              type: object
               properties:
                 interval:
-                  description: Canary schedule interval
+                  description: Schedule interval for this canary
                   type: string
                   pattern: "^[0-9]+(m|s)"
                 iterations:
@@ -196,84 +195,82 @@ spec:
                   description: Max traffic percentage routed to canary
                   type: number
                 stepWeight:
-                  description: Canary incremental traffic percentage step
+                  description: Incremental traffic percentage step
                   type: number
                 mirror:
                   description: Mirror traffic to canary before shifting
                   type: boolean
                 match:
                   description: A/B testing match conditions
-                  anyOf:
-                    - type: string
-                    - type: array
+                  type: array
+                  items:
+                    type: object
                 metrics:
-                  description: Prometheus query list for this canary
+                  description: Metric check list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "threshold"]
-                      properties:
-                        name:
-                          description: Name of the metric
-                          type: string
-                        interval:
-                          description: Interval of the query
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        threshold:
-                          description: Max value accepted for this metric
-                          type: number
-                        query:
-                          description: Prometheus query
-                          type: string
-                        templateRef:
-                          description: Metric template reference
-                          type: object
-                          required: ["name"]
-                          properties:
-                            name:
-                              description: Name of this metric template
-                              type: string
-                            namespace:
-                              description: Namespace of this metric template
-                              type: string
+                  items:
+                    type: object
+                    required: ["name", "threshold"]
+                    properties:
+                      name:
+                        description: Name of the metric
+                        type: string
+                      interval:
+                        description: Interval of the query
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      threshold:
+                        description: Max value accepted for this metric
+                        type: number
+                      query:
+                        description: Prometheus query
+                        type: string
+                      templateRef:
+                        description: Metric template reference
+                        type: object
+                        required: ["name"]
+                        properties:
+                          name:
+                            description: Name of this metric template
+                            type: string
+                          namespace:
+                            description: Namespace of this metric template
+                            type: string
                 webhooks:
                   description: Webhook list for this canary
                   type: array
-                  properties:
-                    items:
-                      type: object
-                      required: ["name", "url"]
-                      properties:
-                        name:
-                          description: Name of the webhook
-                          type: string
-                        type:
-                          description: Type of the webhook pre, post or during rollout
-                          type: string
-                          enum:
-                            - ""
-                            - confirm-rollout
-                            - pre-rollout
-                            - rollout
-                            - confirm-promotion
-                            - post-rollout
-                            - event
-                            - rollback
-                        url:
-                          description: URL address of this webhook
-                          type: string
-                          format: url
-                        timeout:
-                          description: Request timeout for this webhook
-                          type: string
-                          pattern: "^[0-9]+(m|s)"
-                        metadata:
-                          description: Metadata (key-value pairs) for this webhook
-                          anyOf:
-                            - type: string
-                            - type: object
+                  items:
+                    type: object
+                    required: ["name", "url"]
+                    properties:
+                      name:
+                        description: Name of the webhook
+                        type: string
+                      type:
+                        description: Type of the webhook pre, post or during rollout
+                        type: string
+                        enum:
+                          - ""
+                          - confirm-rollout
+                          - pre-rollout
+                          - rollout
+                          - confirm-promotion
+                          - post-rollout
+                          - event
+                          - rollback
+                      url:
+                        description: URL address of this webhook
+                        type: string
+                        format: url
+                      timeout:
+                        description: Request timeout for this webhook
+                        type: string
+                        pattern: "^[0-9]+(m|s)"
+                      metadata:
+                        description: Metadata (key-value pairs) for this webhook
+                        anyOf:
+                          - type: string
+                          - type: object
         status:
           properties:
             phase:
@@ -308,31 +305,30 @@ spec:
             conditions:
               description: Status conditions of this canary
               type: array
-              properties:
-                items:
-                  type: object
-                  required: ["type", "status", "reason"]
-                  properties:
-                    lastTransitionTime:
-                      description: LastTransitionTime of this condition
-                      format: date-time
-                      type: string
-                    lastUpdateTime:
-                      description: LastUpdateTime of this condition
-                      format: date-time
-                      type: string
-                    message:
-                      description: Message associated with this condition
-                      type: string
-                    reason:
-                      description: Reason for the current status of this condition
-                      type: string
-                    status:
-                      description: Status of this condition
-                      type: string
-                    type:
-                      description: Type of this condition
-                      type: string
+              items:
+                type: object
+                required: ["type", "status", "reason"]
+                properties:
+                  lastTransitionTime:
+                    description: LastTransitionTime of this condition
+                    format: date-time
+                    type: string
+                  lastUpdateTime:
+                    description: LastUpdateTime of this condition
+                    format: date-time
+                    type: string
+                  message:
+                    description: Message associated with this condition
+                    type: string
+                  reason:
+                    description: Reason for the current status of this condition
+                    type: string
+                  status:
+                    description: Status of this condition
+                    type: string
+                  type:
+                    description: Type of this condition
+                    type: string
 ---
 apiVersion: apiextensions.k8s.io/v1beta1
 kind: CustomResourceDefinition
@@ -342,11 +338,14 @@ metadata:
     helm.sh/resource-policy: keep
 spec:
   group: flagger.app
-  version: v1alpha1
+  version: v1beta1
   versions:
-    - name: v1alpha1
+    - name: v1beta1
       served: true
       storage: true
+    - name: v1alpha1
+      served: true
+      storage: false
   names:
     plural: metrictemplates
     singular: metrictemplate
@@ -356,6 +355,10 @@ spec:
   scope: Namespaced
   subresources:
     status: {}
+  additionalPrinterColumns:
+    - name: Provider
+      type: string
+      JSONPath: .spec.provider.type
   validation:
     openAPIV3Schema:
       properties:
diff --git a/pkg/apis/flagger/v1alpha1/doc.go b/pkg/apis/flagger/v1alpha1/doc.go
deleted file mode 100755
index c019ac47..00000000
--- a/pkg/apis/flagger/v1alpha1/doc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// +k8s:deepcopy-gen=package
-
-// Package v1alpha1 is the v1alpha1 version of the API.
-// +groupName=flagger.app
-package v1alpha1
diff --git a/pkg/apis/flagger/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/flagger/v1alpha1/zz_generated.deepcopy.go
deleted file mode 100644
index f114c902..00000000
--- a/pkg/apis/flagger/v1alpha1/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// +build !ignore_autogenerated
-
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by deepcopy-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
-	v1 "k8s.io/api/core/v1"
-	runtime "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplate) DeepCopyInto(out *MetricTemplate) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
-	in.Status.DeepCopyInto(&out.Status)
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplate.
-func (in *MetricTemplate) DeepCopy() *MetricTemplate {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplate)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *MetricTemplate) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateCondition) DeepCopyInto(out *MetricTemplateCondition) {
-	*out = *in
-	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
-	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateCondition.
-func (in *MetricTemplateCondition) DeepCopy() *MetricTemplateCondition {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateCondition)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateList) DeepCopyInto(out *MetricTemplateList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]MetricTemplate, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateList.
-func (in *MetricTemplateList) DeepCopy() *MetricTemplateList {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *MetricTemplateList) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateModel) DeepCopyInto(out *MetricTemplateModel) {
-	*out = *in
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateModel.
-func (in *MetricTemplateModel) DeepCopy() *MetricTemplateModel {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateModel)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateProvider) DeepCopyInto(out *MetricTemplateProvider) {
-	*out = *in
-	if in.SecretRef != nil {
-		in, out := &in.SecretRef, &out.SecretRef
-		*out = new(v1.LocalObjectReference)
-		**out = **in
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateProvider.
-func (in *MetricTemplateProvider) DeepCopy() *MetricTemplateProvider {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateProvider)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateSpec) DeepCopyInto(out *MetricTemplateSpec) {
-	*out = *in
-	in.Provider.DeepCopyInto(&out.Provider)
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateSpec.
-func (in *MetricTemplateSpec) DeepCopy() *MetricTemplateSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *MetricTemplateStatus) DeepCopyInto(out *MetricTemplateStatus) {
-	*out = *in
-	if in.Conditions != nil {
-		in, out := &in.Conditions, &out.Conditions
-		*out = make([]MetricTemplateCondition, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	return
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateStatus.
-func (in *MetricTemplateStatus) DeepCopy() *MetricTemplateStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(MetricTemplateStatus)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/pkg/apis/flagger/v1alpha3/register.go b/pkg/apis/flagger/v1alpha3/register.go
deleted file mode 100755
index 092e0602..00000000
--- a/pkg/apis/flagger/v1alpha3/register.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Copyright 2018 The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha3
-
-import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-
-	rollout "github.com/weaveworks/flagger/pkg/apis/flagger"
-)
-
-// SchemeGroupVersion is group version used to register these objects
-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 {
-	return SchemeGroupVersion.WithKind(kind).GroupKind()
-}
-
-// Resource takes an unqualified resource and returns a Group qualified GroupResource
-func Resource(resource string) schema.GroupResource {
-	return SchemeGroupVersion.WithResource(resource).GroupResource()
-}
-
-var (
-	SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
-	AddToScheme   = SchemeBuilder.AddToScheme
-)
-
-// Adds the list of known types to Scheme.
-func addKnownTypes(scheme *runtime.Scheme) error {
-	scheme.AddKnownTypes(SchemeGroupVersion,
-		&Canary{},
-		&CanaryList{},
-	)
-	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
-	return nil
-}
diff --git a/pkg/apis/flagger/v1alpha3/types.go b/pkg/apis/flagger/v1beta1/canary.go
similarity index 98%
rename from pkg/apis/flagger/v1alpha3/types.go
rename to pkg/apis/flagger/v1beta1/canary.go
index f281240c..9cd4c619 100644
--- a/pkg/apis/flagger/v1alpha3/types.go
+++ b/pkg/apis/flagger/v1beta1/canary.go
@@ -14,17 +14,16 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package v1alpha3
+package v1beta1
 
 import (
 	"fmt"
 	"time"
 
+	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	hpav1 "k8s.io/api/autoscaling/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
-
-	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 )
 
 const (
@@ -122,7 +121,7 @@ type CanaryAnalysis struct {
 	MaxWeight  int                              `json:"maxWeight"`
 	Mirror     bool                             `json:"mirror,omitempty"`
 	StepWeight int                              `json:"stepWeight"`
-	Metrics    []CanaryMetric                   `json:"metrics"`
+	Metrics    []CanaryMetric                   `json:"metrics,omitempty"`
 	Webhooks   []CanaryWebhook                  `json:"webhooks,omitempty"`
 	Match      []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"`
 	Iterations int                              `json:"iterations,omitempty"`
diff --git a/pkg/apis/flagger/v1alpha3/doc.go b/pkg/apis/flagger/v1beta1/doc.go
similarity index 89%
rename from pkg/apis/flagger/v1alpha3/doc.go
rename to pkg/apis/flagger/v1beta1/doc.go
index d7f493af..9dbc5368 100755
--- a/pkg/apis/flagger/v1alpha3/doc.go
+++ b/pkg/apis/flagger/v1beta1/doc.go
@@ -16,6 +16,6 @@ limitations under the License.
 
 // +k8s:deepcopy-gen=package
 
-// Package v1alpha3 is the v1alpha3 version of the API.
+// Package v1beta1 is the v1alpha3 version of the API.
 // +groupName=flagger.app
-package v1alpha3
+package v1beta1
diff --git a/pkg/apis/flagger/v1alpha1/metric.go b/pkg/apis/flagger/v1beta1/metric.go
similarity index 98%
rename from pkg/apis/flagger/v1alpha1/metric.go
rename to pkg/apis/flagger/v1beta1/metric.go
index 657f997d..a2bbdb32 100644
--- a/pkg/apis/flagger/v1alpha1/metric.go
+++ b/pkg/apis/flagger/v1beta1/metric.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package v1alpha1
+package v1beta1
 
 import (
 	"text/template"
@@ -25,7 +25,6 @@ import (
 
 const (
 	MetricTemplateKind = "MetricTemplate"
-	MetricInterval     = "1m"
 )
 
 // +genclient
diff --git a/pkg/apis/flagger/v1alpha1/register.go b/pkg/apis/flagger/v1beta1/register.go
similarity index 93%
rename from pkg/apis/flagger/v1alpha1/register.go
rename to pkg/apis/flagger/v1beta1/register.go
index c400a280..d883b692 100755
--- a/pkg/apis/flagger/v1alpha1/register.go
+++ b/pkg/apis/flagger/v1beta1/register.go
@@ -1,5 +1,5 @@
 /*
-Copyright The Flagger Authors.
+Copyright 2018 The Flagger Authors.
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package v1alpha1
+package v1beta1
 
 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: flagger.GroupName, Version: "v1alpha1"}
+var SchemeGroupVersion = schema.GroupVersion{Group: flagger.GroupName, Version: "v1beta1"}
 
 // Kind takes an unqualified kind and returns back a Group qualified GroupKind
 func Kind(kind string) schema.GroupKind {
@@ -45,6 +45,8 @@ var (
 // Adds the list of known types to Scheme.
 func addKnownTypes(scheme *runtime.Scheme) error {
 	scheme.AddKnownTypes(SchemeGroupVersion,
+		&Canary{},
+		&CanaryList{},
 		&MetricTemplate{},
 		&MetricTemplateList{},
 	)
diff --git a/pkg/apis/flagger/v1alpha3/status.go b/pkg/apis/flagger/v1beta1/status.go
similarity index 99%
rename from pkg/apis/flagger/v1alpha3/status.go
rename to pkg/apis/flagger/v1beta1/status.go
index 9a614f6c..b44341e4 100644
--- a/pkg/apis/flagger/v1alpha3/status.go
+++ b/pkg/apis/flagger/v1beta1/status.go
@@ -1,4 +1,4 @@
-package v1alpha3
+package v1beta1
 
 import (
 	corev1 "k8s.io/api/core/v1"
diff --git a/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go
similarity index 65%
rename from pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go
rename to pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go
index e6fa5689..92afeef7 100644
--- a/pkg/apis/flagger/v1alpha3/zz_generated.deepcopy.go
+++ b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go
@@ -18,11 +18,12 @@ limitations under the License.
 
 // Code generated by deepcopy-gen. DO NOT EDIT.
 
-package v1alpha3
+package v1beta1
 
 import (
-	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
+	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	v1 "k8s.io/api/autoscaling/v1"
+	corev1 "k8s.io/api/core/v1"
 	runtime "k8s.io/apimachinery/pkg/runtime"
 )
 
@@ -73,7 +74,7 @@ func (in *CanaryAnalysis) DeepCopyInto(out *CanaryAnalysis) {
 	}
 	if in.Match != nil {
 		in, out := &in.Match, &out.Match
-		*out = make([]istiov1alpha3.HTTPMatchRequest, len(*in))
+		*out = make([]v1alpha3.HTTPMatchRequest, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
@@ -179,34 +180,34 @@ func (in *CanaryService) DeepCopyInto(out *CanaryService) {
 	}
 	if in.TrafficPolicy != nil {
 		in, out := &in.TrafficPolicy, &out.TrafficPolicy
-		*out = new(istiov1alpha3.TrafficPolicy)
+		*out = new(v1alpha3.TrafficPolicy)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Match != nil {
 		in, out := &in.Match, &out.Match
-		*out = make([]istiov1alpha3.HTTPMatchRequest, len(*in))
+		*out = make([]v1alpha3.HTTPMatchRequest, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
 	if in.Rewrite != nil {
 		in, out := &in.Rewrite, &out.Rewrite
-		*out = new(istiov1alpha3.HTTPRewrite)
+		*out = new(v1alpha3.HTTPRewrite)
 		**out = **in
 	}
 	if in.Retries != nil {
 		in, out := &in.Retries, &out.Retries
-		*out = new(istiov1alpha3.HTTPRetry)
+		*out = new(v1alpha3.HTTPRetry)
 		**out = **in
 	}
 	if in.Headers != nil {
 		in, out := &in.Headers, &out.Headers
-		*out = new(istiov1alpha3.Headers)
+		*out = new(v1alpha3.Headers)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.CorsPolicy != nil {
 		in, out := &in.CorsPolicy, &out.CorsPolicy
-		*out = new(istiov1alpha3.CorsPolicy)
+		*out = new(v1alpha3.CorsPolicy)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Backends != nil {
@@ -346,6 +347,122 @@ func (in *CanaryWebhookPayload) DeepCopy() *CanaryWebhookPayload {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplate) DeepCopyInto(out *MetricTemplate) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+	in.Status.DeepCopyInto(&out.Status)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplate.
+func (in *MetricTemplate) DeepCopy() *MetricTemplate {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplate)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MetricTemplate) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateCondition) DeepCopyInto(out *MetricTemplateCondition) {
+	*out = *in
+	in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime)
+	in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateCondition.
+func (in *MetricTemplateCondition) DeepCopy() *MetricTemplateCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateCondition)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateList) DeepCopyInto(out *MetricTemplateList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]MetricTemplate, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateList.
+func (in *MetricTemplateList) DeepCopy() *MetricTemplateList {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *MetricTemplateList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateModel) DeepCopyInto(out *MetricTemplateModel) {
+	*out = *in
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateModel.
+func (in *MetricTemplateModel) DeepCopy() *MetricTemplateModel {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateModel)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateProvider) DeepCopyInto(out *MetricTemplateProvider) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(corev1.LocalObjectReference)
+		**out = **in
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateProvider.
+func (in *MetricTemplateProvider) DeepCopy() *MetricTemplateProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *MetricTemplateRef) DeepCopyInto(out *MetricTemplateRef) {
 	*out = *in
@@ -361,3 +478,43 @@ func (in *MetricTemplateRef) DeepCopy() *MetricTemplateRef {
 	in.DeepCopyInto(out)
 	return out
 }
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateSpec) DeepCopyInto(out *MetricTemplateSpec) {
+	*out = *in
+	in.Provider.DeepCopyInto(&out.Provider)
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateSpec.
+func (in *MetricTemplateSpec) DeepCopy() *MetricTemplateSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *MetricTemplateStatus) DeepCopyInto(out *MetricTemplateStatus) {
+	*out = *in
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]MetricTemplateCondition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricTemplateStatus.
+func (in *MetricTemplateStatus) DeepCopy() *MetricTemplateStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(MetricTemplateStatus)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/pkg/canary/controller.go b/pkg/canary/controller.go
index afdd7d19..c615cc5e 100644
--- a/pkg/canary/controller.go
+++ b/pkg/canary/controller.go
@@ -1,7 +1,7 @@
 package canary
 
 import (
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 type Controller interface {
diff --git a/pkg/canary/deployment_controller.go b/pkg/canary/deployment_controller.go
index f730c214..2ab7358c 100644
--- a/pkg/canary/deployment_controller.go
+++ b/pkg/canary/deployment_controller.go
@@ -16,7 +16,7 @@ import (
 	"k8s.io/apimachinery/pkg/util/intstr"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/canary/mock.go b/pkg/canary/mock.go
index f80361e3..b3f99dc2 100644
--- a/pkg/canary/mock.go
+++ b/pkg/canary/mock.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/fake"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	fakeFlagger "github.com/weaveworks/flagger/pkg/client/clientset/versioned/fake"
 )
diff --git a/pkg/canary/ready.go b/pkg/canary/ready.go
index cfd2377e..4f29cd11 100644
--- a/pkg/canary/ready.go
+++ b/pkg/canary/ready.go
@@ -8,7 +8,7 @@ import (
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // IsPrimaryReady checks the primary deployment status and returns an error if
diff --git a/pkg/canary/service_controller.go b/pkg/canary/service_controller.go
index c6f4b015..3e3724d2 100644
--- a/pkg/canary/service_controller.go
+++ b/pkg/canary/service_controller.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/canary/spec.go b/pkg/canary/spec.go
index 1eb73aa3..4da124f3 100644
--- a/pkg/canary/spec.go
+++ b/pkg/canary/spec.go
@@ -4,10 +4,10 @@ import (
 	"fmt"
 
 	"github.com/mitchellh/hashstructure"
-	"github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
-func hasSpecChanged(cd *v1alpha3.Canary, spec interface{}) (bool, error) {
+func hasSpecChanged(cd *flaggerv1.Canary, spec interface{}) (bool, error) {
 	if cd.Status.LastAppliedSpec == "" {
 		return true, nil
 	}
diff --git a/pkg/canary/status.go b/pkg/canary/status.go
index 5a0a9868..3872e1ae 100644
--- a/pkg/canary/status.go
+++ b/pkg/canary/status.go
@@ -2,16 +2,17 @@ package canary
 
 import (
 	"fmt"
+	"strings"
 
 	"github.com/mitchellh/hashstructure"
 	ex "github.com/pkg/errors"
-	"github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/util/retry"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
+	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
 // SyncStatus encodes the canary pod spec and updates the canary status
@@ -34,7 +35,7 @@ func (c *DeploymentController) SyncStatus(cd *flaggerv1.Canary, status flaggerv1
 	})
 }
 
-func syncCanaryStatus(flaggerClient versioned.Interface, cd *flaggerv1.Canary, status flaggerv1.CanaryStatus, canaryResource interface{}, setAll func(cdCopy *flaggerv1.Canary)) error {
+func syncCanaryStatus(flaggerClient clientset.Interface, cd *flaggerv1.Canary, status flaggerv1.CanaryStatus, canaryResource interface{}, setAll func(cdCopy *flaggerv1.Canary)) error {
 	hash, err := hashstructure.Hash(canaryResource, nil)
 	if err != nil {
 		return ex.Wrap(err, "SyncStatus hash error")
@@ -44,11 +45,12 @@ func syncCanaryStatus(flaggerClient versioned.Interface, cd *flaggerv1.Canary, s
 	err = retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
 		var selErr error
 		if !firstTry {
-			cd, selErr = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
+			cd, selErr = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
 			if selErr != nil {
 				return selErr
 			}
 		}
+
 		cdCopy := cd.DeepCopy()
 		cdCopy.Status.Phase = status.Phase
 		cdCopy.Status.CanaryWeight = status.CanaryWeight
@@ -62,7 +64,7 @@ func syncCanaryStatus(flaggerClient versioned.Interface, cd *flaggerv1.Canary, s
 			cdCopy.Status.Conditions = conditions
 		}
 
-		_, err = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+		err = updateStatusWithUpgrade(flaggerClient, cdCopy)
 		firstTry = false
 		return
 	})
@@ -77,12 +79,12 @@ func (c *DeploymentController) SetStatusFailedChecks(cd *flaggerv1.Canary, val i
 	return setStatusFailedChecks(c.flaggerClient, cd, val)
 }
 
-func setStatusFailedChecks(flaggerClient versioned.Interface, cd *flaggerv1.Canary, val int) error {
+func setStatusFailedChecks(flaggerClient clientset.Interface, cd *flaggerv1.Canary, val int) error {
 	firstTry := true
 	err := retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
 		var selErr error
 		if !firstTry {
-			cd, selErr = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
+			cd, selErr = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
 			if selErr != nil {
 				return selErr
 			}
@@ -91,7 +93,7 @@ func setStatusFailedChecks(flaggerClient versioned.Interface, cd *flaggerv1.Cana
 		cdCopy.Status.FailedChecks = val
 		cdCopy.Status.LastTransitionTime = metav1.Now()
 
-		_, err = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+		err = updateStatusWithUpgrade(flaggerClient, cdCopy)
 		firstTry = false
 		return
 	})
@@ -106,12 +108,12 @@ func (c *DeploymentController) SetStatusWeight(cd *flaggerv1.Canary, val int) er
 	return setStatusWeight(c.flaggerClient, cd, val)
 }
 
-func setStatusWeight(flaggerClient versioned.Interface, cd *flaggerv1.Canary, val int) error {
+func setStatusWeight(flaggerClient clientset.Interface, cd *flaggerv1.Canary, val int) error {
 	firstTry := true
 	err := retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
 		var selErr error
 		if !firstTry {
-			cd, selErr = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
+			cd, selErr = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
 			if selErr != nil {
 				return selErr
 			}
@@ -120,7 +122,7 @@ func setStatusWeight(flaggerClient versioned.Interface, cd *flaggerv1.Canary, va
 		cdCopy.Status.CanaryWeight = val
 		cdCopy.Status.LastTransitionTime = metav1.Now()
 
-		_, err = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+		err = updateStatusWithUpgrade(flaggerClient, cdCopy)
 		firstTry = false
 		return
 	})
@@ -135,12 +137,12 @@ func (c *DeploymentController) SetStatusIterations(cd *flaggerv1.Canary, val int
 	return setStatusIterations(c.flaggerClient, cd, val)
 }
 
-func setStatusIterations(flaggerClient versioned.Interface, cd *flaggerv1.Canary, val int) error {
+func setStatusIterations(flaggerClient clientset.Interface, cd *flaggerv1.Canary, val int) error {
 	firstTry := true
 	err := retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
 		var selErr error
 		if !firstTry {
-			cd, selErr = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
+			cd, selErr = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
 			if selErr != nil {
 				return selErr
 			}
@@ -150,7 +152,7 @@ func setStatusIterations(flaggerClient versioned.Interface, cd *flaggerv1.Canary
 		cdCopy.Status.Iterations = val
 		cdCopy.Status.LastTransitionTime = metav1.Now()
 
-		_, err = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+		err = updateStatusWithUpgrade(flaggerClient, cdCopy)
 		firstTry = false
 		return
 	})
@@ -166,16 +168,17 @@ func (c *DeploymentController) SetStatusPhase(cd *flaggerv1.Canary, phase flagge
 	return setStatusPhase(c.flaggerClient, cd, phase)
 }
 
-func setStatusPhase(flaggerClient versioned.Interface, cd *flaggerv1.Canary, phase flaggerv1.CanaryPhase) error {
+func setStatusPhase(flaggerClient clientset.Interface, cd *flaggerv1.Canary, phase flaggerv1.CanaryPhase) error {
 	firstTry := true
 	err := retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
 		var selErr error
 		if !firstTry {
-			cd, selErr = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
+			cd, selErr = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Get(cd.GetName(), metav1.GetOptions{})
 			if selErr != nil {
 				return selErr
 			}
 		}
+
 		cdCopy := cd.DeepCopy()
 		cdCopy.Status.Phase = phase
 		cdCopy.Status.LastTransitionTime = metav1.Now()
@@ -194,7 +197,7 @@ func setStatusPhase(flaggerClient versioned.Interface, cd *flaggerv1.Canary, pha
 			cdCopy.Status.Conditions = conditions
 		}
 
-		_, err = flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+		err = updateStatusWithUpgrade(flaggerClient, cdCopy)
 		firstTry = false
 		return
 	})
@@ -270,3 +273,22 @@ func MakeStatusConditions(canaryStatus flaggerv1.CanaryStatus,
 
 	return true, []flaggerv1.CanaryCondition{*newCondition}
 }
+
+// updateStatusWithUpgrade tries to update the status sub-resource
+// if the status update fails with:
+// Canary.flagger.app is invalid: apiVersion: Invalid value: flagger.app/v1alpha3: must be flagger.app/v1beta1
+// then the canary object will be updated to the latest API version
+func updateStatusWithUpgrade(flaggerClient clientset.Interface, cd *flaggerv1.Canary) error {
+	_, err := flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).UpdateStatus(cd)
+	if err != nil && strings.Contains(err.Error(), "flagger.app/v1alpha") {
+		// upgrade alpha resource
+		_, updateErr := flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).Update(cd)
+		if updateErr != nil {
+			return updateErr
+		}
+
+		// retry status update
+		_, err = flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).UpdateStatus(cd)
+	}
+	return err
+}
diff --git a/pkg/canary/tracker.go b/pkg/canary/tracker.go
index 57fb1f78..072c4b97 100644
--- a/pkg/canary/tracker.go
+++ b/pkg/canary/tracker.go
@@ -12,7 +12,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go
index c31899f2..db936d92 100644
--- a/pkg/client/clientset/versioned/clientset.go
+++ b/pkg/client/clientset/versioned/clientset.go
@@ -22,8 +22,7 @@ import (
 	"fmt"
 
 	appmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1"
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha1"
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
 	gloov1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
 	networkingv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3"
 	projectcontourv1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/projectcontour/v1"
@@ -36,8 +35,7 @@ import (
 type Interface interface {
 	Discovery() discovery.DiscoveryInterface
 	AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface
-	FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface
-	FlaggerV1alpha1() flaggerv1alpha1.FlaggerV1alpha1Interface
+	FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface
 	GlooV1() gloov1.GlooV1Interface
 	NetworkingV1alpha3() networkingv1alpha3.NetworkingV1alpha3Interface
 	ProjectcontourV1() projectcontourv1.ProjectcontourV1Interface
@@ -49,8 +47,7 @@ type Interface interface {
 type Clientset struct {
 	*discovery.DiscoveryClient
 	appmeshV1beta1     *appmeshv1beta1.AppmeshV1beta1Client
-	flaggerV1alpha3    *flaggerv1alpha3.FlaggerV1alpha3Client
-	flaggerV1alpha1    *flaggerv1alpha1.FlaggerV1alpha1Client
+	flaggerV1beta1     *flaggerv1beta1.FlaggerV1beta1Client
 	glooV1             *gloov1.GlooV1Client
 	networkingV1alpha3 *networkingv1alpha3.NetworkingV1alpha3Client
 	projectcontourV1   *projectcontourv1.ProjectcontourV1Client
@@ -62,14 +59,9 @@ func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface {
 	return c.appmeshV1beta1
 }
 
-// FlaggerV1alpha3 retrieves the FlaggerV1alpha3Client
-func (c *Clientset) FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface {
-	return c.flaggerV1alpha3
-}
-
-// FlaggerV1alpha1 retrieves the FlaggerV1alpha1Client
-func (c *Clientset) FlaggerV1alpha1() flaggerv1alpha1.FlaggerV1alpha1Interface {
-	return c.flaggerV1alpha1
+// FlaggerV1beta1 retrieves the FlaggerV1beta1Client
+func (c *Clientset) FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface {
+	return c.flaggerV1beta1
 }
 
 // GlooV1 retrieves the GlooV1Client
@@ -117,11 +109,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
 	if err != nil {
 		return nil, err
 	}
-	cs.flaggerV1alpha3, err = flaggerv1alpha3.NewForConfig(&configShallowCopy)
-	if err != nil {
-		return nil, err
-	}
-	cs.flaggerV1alpha1, err = flaggerv1alpha1.NewForConfig(&configShallowCopy)
+	cs.flaggerV1beta1, err = flaggerv1beta1.NewForConfig(&configShallowCopy)
 	if err != nil {
 		return nil, err
 	}
@@ -154,8 +142,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
 func NewForConfigOrDie(c *rest.Config) *Clientset {
 	var cs Clientset
 	cs.appmeshV1beta1 = appmeshv1beta1.NewForConfigOrDie(c)
-	cs.flaggerV1alpha3 = flaggerv1alpha3.NewForConfigOrDie(c)
-	cs.flaggerV1alpha1 = flaggerv1alpha1.NewForConfigOrDie(c)
+	cs.flaggerV1beta1 = flaggerv1beta1.NewForConfigOrDie(c)
 	cs.glooV1 = gloov1.NewForConfigOrDie(c)
 	cs.networkingV1alpha3 = networkingv1alpha3.NewForConfigOrDie(c)
 	cs.projectcontourV1 = projectcontourv1.NewForConfigOrDie(c)
@@ -169,8 +156,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
 func New(c rest.Interface) *Clientset {
 	var cs Clientset
 	cs.appmeshV1beta1 = appmeshv1beta1.New(c)
-	cs.flaggerV1alpha3 = flaggerv1alpha3.New(c)
-	cs.flaggerV1alpha1 = flaggerv1alpha1.New(c)
+	cs.flaggerV1beta1 = flaggerv1beta1.New(c)
 	cs.glooV1 = gloov1.New(c)
 	cs.networkingV1alpha3 = networkingv1alpha3.New(c)
 	cs.projectcontourV1 = projectcontourv1.New(c)
diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go
index ffc967ea..f5d146ed 100644
--- a/pkg/client/clientset/versioned/fake/clientset_generated.go
+++ b/pkg/client/clientset/versioned/fake/clientset_generated.go
@@ -22,10 +22,8 @@ import (
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	appmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1"
 	fakeappmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1/fake"
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha1"
-	fakeflaggerv1alpha1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake"
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
-	fakeflaggerv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
+	fakeflaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake"
 	gloov1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
 	fakegloov1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/gloo/v1/fake"
 	networkingv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3"
@@ -93,14 +91,9 @@ func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface {
 	return &fakeappmeshv1beta1.FakeAppmeshV1beta1{Fake: &c.Fake}
 }
 
-// FlaggerV1alpha3 retrieves the FlaggerV1alpha3Client
-func (c *Clientset) FlaggerV1alpha3() flaggerv1alpha3.FlaggerV1alpha3Interface {
-	return &fakeflaggerv1alpha3.FakeFlaggerV1alpha3{Fake: &c.Fake}
-}
-
-// FlaggerV1alpha1 retrieves the FlaggerV1alpha1Client
-func (c *Clientset) FlaggerV1alpha1() flaggerv1alpha1.FlaggerV1alpha1Interface {
-	return &fakeflaggerv1alpha1.FakeFlaggerV1alpha1{Fake: &c.Fake}
+// FlaggerV1beta1 retrieves the FlaggerV1beta1Client
+func (c *Clientset) FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface {
+	return &fakeflaggerv1beta1.FakeFlaggerV1beta1{Fake: &c.Fake}
 }
 
 // GlooV1 retrieves the GlooV1Client
diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go
index a43d9d4f..aafbfbfa 100644
--- a/pkg/client/clientset/versioned/fake/register.go
+++ b/pkg/client/clientset/versioned/fake/register.go
@@ -20,8 +20,7 @@ package fake
 
 import (
 	appmeshv1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	gloov1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
 	networkingv1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	projectcontourv1 "github.com/weaveworks/flagger/pkg/apis/projectcontour/v1"
@@ -38,8 +37,7 @@ var codecs = serializer.NewCodecFactory(scheme)
 var parameterCodec = runtime.NewParameterCodec(scheme)
 var localSchemeBuilder = runtime.SchemeBuilder{
 	appmeshv1beta1.AddToScheme,
-	flaggerv1alpha3.AddToScheme,
-	flaggerv1alpha1.AddToScheme,
+	flaggerv1beta1.AddToScheme,
 	gloov1.AddToScheme,
 	networkingv1alpha3.AddToScheme,
 	projectcontourv1.AddToScheme,
diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go
index fb03079e..51c83899 100644
--- a/pkg/client/clientset/versioned/scheme/register.go
+++ b/pkg/client/clientset/versioned/scheme/register.go
@@ -20,8 +20,7 @@ package scheme
 
 import (
 	appmeshv1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	gloov1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
 	networkingv1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	projectcontourv1 "github.com/weaveworks/flagger/pkg/apis/projectcontour/v1"
@@ -38,8 +37,7 @@ var Codecs = serializer.NewCodecFactory(Scheme)
 var ParameterCodec = runtime.NewParameterCodec(Scheme)
 var localSchemeBuilder = runtime.SchemeBuilder{
 	appmeshv1beta1.AddToScheme,
-	flaggerv1alpha3.AddToScheme,
-	flaggerv1alpha1.AddToScheme,
+	flaggerv1beta1.AddToScheme,
 	gloov1.AddToScheme,
 	networkingv1alpha3.AddToScheme,
 	projectcontourv1.AddToScheme,
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/doc.go b/pkg/client/clientset/versioned/typed/flagger/v1alpha3/doc.go
deleted file mode 100644
index d49e3fd3..00000000
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by client-gen. DO NOT EDIT.
-
-// This package has the automatically generated typed clients.
-package v1alpha3
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/doc.go b/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/doc.go
deleted file mode 100644
index 7a3b19cb..00000000
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by client-gen. DO NOT EDIT.
-
-// Package fake has the automatically generated clients.
-package fake
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_flagger_client.go b/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_flagger_client.go
deleted file mode 100644
index d26224ea..00000000
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_flagger_client.go
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by client-gen. DO NOT EDIT.
-
-package fake
-
-import (
-	v1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha3"
-	rest "k8s.io/client-go/rest"
-	testing "k8s.io/client-go/testing"
-)
-
-type FakeFlaggerV1alpha3 struct {
-	*testing.Fake
-}
-
-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 *FakeFlaggerV1alpha3) RESTClient() rest.Interface {
-	var ret *rest.RESTClient
-	return ret
-}
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/flagger_client.go b/pkg/client/clientset/versioned/typed/flagger/v1alpha3/flagger_client.go
deleted file mode 100644
index 75765dac..00000000
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/flagger_client.go
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by client-gen. DO NOT EDIT.
-
-package v1alpha3
-
-import (
-	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
-	"github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
-	rest "k8s.io/client-go/rest"
-)
-
-type FlaggerV1alpha3Interface interface {
-	RESTClient() rest.Interface
-	CanariesGetter
-}
-
-// FlaggerV1alpha3Client is used to interact with features provided by the flagger.app group.
-type FlaggerV1alpha3Client struct {
-	restClient rest.Interface
-}
-
-func (c *FlaggerV1alpha3Client) Canaries(namespace string) CanaryInterface {
-	return newCanaries(c, namespace)
-}
-
-// 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
-	}
-	client, err := rest.RESTClientFor(&config)
-	if err != nil {
-		return nil, err
-	}
-	return &FlaggerV1alpha3Client{client}, nil
-}
-
-// NewForConfigOrDie creates a new FlaggerV1alpha3Client for the given config and
-// panics if there is an error in the config.
-func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha3Client {
-	client, err := NewForConfig(c)
-	if err != nil {
-		panic(err)
-	}
-	return client
-}
-
-// 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 := v1alpha3.SchemeGroupVersion
-	config.GroupVersion = &gv
-	config.APIPath = "/apis"
-	config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
-
-	if config.UserAgent == "" {
-		config.UserAgent = rest.DefaultKubernetesUserAgent()
-	}
-
-	return nil
-}
-
-// RESTClient returns a RESTClient that is used to communicate
-// with API server by this client implementation.
-func (c *FlaggerV1alpha3Client) RESTClient() rest.Interface {
-	if c == nil {
-		return nil
-	}
-	return c.restClient
-}
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/generated_expansion.go b/pkg/client/clientset/versioned/typed/flagger/v1alpha3/generated_expansion.go
deleted file mode 100644
index b6e80265..00000000
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/generated_expansion.go
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by client-gen. DO NOT EDIT.
-
-package v1alpha3
-
-type CanaryExpansion interface{}
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/canary.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/canary.go
similarity index 80%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha3/canary.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/canary.go
index 047a0d14..58415d4a 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/canary.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/canary.go
@@ -16,12 +16,12 @@ limitations under the License.
 
 // Code generated by client-gen. DO NOT EDIT.
 
-package v1alpha3
+package v1beta1
 
 import (
 	"time"
 
-	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	scheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	types "k8s.io/apimachinery/pkg/types"
@@ -37,15 +37,15 @@ type CanariesGetter interface {
 
 // CanaryInterface has methods to work with Canary resources.
 type CanaryInterface interface {
-	Create(*v1alpha3.Canary) (*v1alpha3.Canary, error)
-	Update(*v1alpha3.Canary) (*v1alpha3.Canary, error)
-	UpdateStatus(*v1alpha3.Canary) (*v1alpha3.Canary, error)
+	Create(*v1beta1.Canary) (*v1beta1.Canary, error)
+	Update(*v1beta1.Canary) (*v1beta1.Canary, error)
+	UpdateStatus(*v1beta1.Canary) (*v1beta1.Canary, error)
 	Delete(name string, options *v1.DeleteOptions) error
 	DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
-	Get(name string, options v1.GetOptions) (*v1alpha3.Canary, error)
-	List(opts v1.ListOptions) (*v1alpha3.CanaryList, error)
+	Get(name string, options v1.GetOptions) (*v1beta1.Canary, error)
+	List(opts v1.ListOptions) (*v1beta1.CanaryList, error)
 	Watch(opts v1.ListOptions) (watch.Interface, error)
-	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Canary, err error)
+	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Canary, err error)
 	CanaryExpansion
 }
 
@@ -56,7 +56,7 @@ type canaries struct {
 }
 
 // newCanaries returns a Canaries
-func newCanaries(c *FlaggerV1alpha3Client, namespace string) *canaries {
+func newCanaries(c *FlaggerV1beta1Client, namespace string) *canaries {
 	return &canaries{
 		client: c.RESTClient(),
 		ns:     namespace,
@@ -64,8 +64,8 @@ func newCanaries(c *FlaggerV1alpha3Client, 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 *v1alpha3.Canary, err error) {
-	result = &v1alpha3.Canary{}
+func (c *canaries) Get(name string, options v1.GetOptions) (result *v1beta1.Canary, err error) {
+	result = &v1beta1.Canary{}
 	err = c.client.Get().
 		Namespace(c.ns).
 		Resource("canaries").
@@ -77,12 +77,12 @@ func (c *canaries) Get(name string, options v1.GetOptions) (result *v1alpha3.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 *v1alpha3.CanaryList, err error) {
+func (c *canaries) List(opts v1.ListOptions) (result *v1beta1.CanaryList, err error) {
 	var timeout time.Duration
 	if opts.TimeoutSeconds != nil {
 		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
 	}
-	result = &v1alpha3.CanaryList{}
+	result = &v1beta1.CanaryList{}
 	err = c.client.Get().
 		Namespace(c.ns).
 		Resource("canaries").
@@ -109,8 +109,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 *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
-	result = &v1alpha3.Canary{}
+func (c *canaries) Create(canary *v1beta1.Canary) (result *v1beta1.Canary, err error) {
+	result = &v1beta1.Canary{}
 	err = c.client.Post().
 		Namespace(c.ns).
 		Resource("canaries").
@@ -121,8 +121,8 @@ func (c *canaries) Create(canary *v1alpha3.Canary) (result *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 *canaries) Update(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
-	result = &v1alpha3.Canary{}
+func (c *canaries) Update(canary *v1beta1.Canary) (result *v1beta1.Canary, err error) {
+	result = &v1beta1.Canary{}
 	err = c.client.Put().
 		Namespace(c.ns).
 		Resource("canaries").
@@ -136,8 +136,8 @@ func (c *canaries) Update(canary *v1alpha3.Canary) (result *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 *canaries) UpdateStatus(canary *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
-	result = &v1alpha3.Canary{}
+func (c *canaries) UpdateStatus(canary *v1beta1.Canary) (result *v1beta1.Canary, err error) {
+	result = &v1beta1.Canary{}
 	err = c.client.Put().
 		Namespace(c.ns).
 		Resource("canaries").
@@ -177,8 +177,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 *v1alpha3.Canary, err error) {
-	result = &v1alpha3.Canary{}
+func (c *canaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Canary, err error) {
+	result = &v1beta1.Canary{}
 	err = c.client.Patch(pt).
 		Namespace(c.ns).
 		Resource("canaries").
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/doc.go
similarity index 97%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/doc.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/doc.go
index 20b3d7fd..4796e182 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/doc.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/doc.go
@@ -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 v1alpha1
+package v1beta1
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/doc.go
similarity index 100%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/doc.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/doc.go
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_canary.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_canary.go
similarity index 74%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_canary.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_canary.go
index 33f461f7..9b37eab5 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha3/fake/fake_canary.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_canary.go
@@ -19,7 +19,7 @@ limitations under the License.
 package fake
 
 import (
-	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	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 *FakeFlaggerV1alpha3
+	Fake *FakeFlaggerV1beta1
 	ns   string
 }
 
-var canariesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1alpha3", Resource: "canaries"}
+var canariesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1beta1", Resource: "canaries"}
 
-var canariesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1alpha3", Kind: "Canary"}
+var canariesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1beta1", 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 *v1alpha3.Canary, err error) {
+func (c *FakeCanaries) Get(name string, options v1.GetOptions) (result *v1beta1.Canary, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(canariesResource, c.ns, name), &v1alpha3.Canary{})
+		Invokes(testing.NewGetAction(canariesResource, c.ns, name), &v1beta1.Canary{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha3.Canary), err
+	return obj.(*v1beta1.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 *v1alpha3.CanaryList, err error) {
+func (c *FakeCanaries) List(opts v1.ListOptions) (result *v1beta1.CanaryList, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewListAction(canariesResource, canariesKind, c.ns, opts), &v1alpha3.CanaryList{})
+		Invokes(testing.NewListAction(canariesResource, canariesKind, c.ns, opts), &v1beta1.CanaryList{})
 
 	if obj == nil {
 		return nil, err
@@ -62,8 +62,8 @@ func (c *FakeCanaries) List(opts v1.ListOptions) (result *v1alpha3.CanaryList, e
 	if label == nil {
 		label = labels.Everything()
 	}
-	list := &v1alpha3.CanaryList{ListMeta: obj.(*v1alpha3.CanaryList).ListMeta}
-	for _, item := range obj.(*v1alpha3.CanaryList).Items {
+	list := &v1beta1.CanaryList{ListMeta: obj.(*v1beta1.CanaryList).ListMeta}
+	for _, item := range obj.(*v1beta1.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 *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
+func (c *FakeCanaries) Create(canary *v1beta1.Canary) (result *v1beta1.Canary, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(canariesResource, c.ns, canary), &v1alpha3.Canary{})
+		Invokes(testing.NewCreateAction(canariesResource, c.ns, canary), &v1beta1.Canary{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha3.Canary), err
+	return obj.(*v1beta1.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 *v1alpha3.Canary) (result *v1alpha3.Canary, err error) {
+func (c *FakeCanaries) Update(canary *v1beta1.Canary) (result *v1beta1.Canary, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(canariesResource, c.ns, canary), &v1alpha3.Canary{})
+		Invokes(testing.NewUpdateAction(canariesResource, c.ns, canary), &v1beta1.Canary{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha3.Canary), err
+	return obj.(*v1beta1.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 *v1alpha3.Canary) (*v1alpha3.Canary, error) {
+func (c *FakeCanaries) UpdateStatus(canary *v1beta1.Canary) (*v1beta1.Canary, error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewUpdateSubresourceAction(canariesResource, "status", c.ns, canary), &v1alpha3.Canary{})
+		Invokes(testing.NewUpdateSubresourceAction(canariesResource, "status", c.ns, canary), &v1beta1.Canary{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha3.Canary), err
+	return obj.(*v1beta1.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), &v1alpha3.Canary{})
+		Invokes(testing.NewDeleteAction(canariesResource, c.ns, name), &v1beta1.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, &v1alpha3.CanaryList{})
+	_, err := c.Fake.Invokes(action, &v1beta1.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 *v1alpha3.Canary, err error) {
+func (c *FakeCanaries) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.Canary, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(canariesResource, c.ns, name, pt, data, subresources...), &v1alpha3.Canary{})
+		Invokes(testing.NewPatchSubresourceAction(canariesResource, c.ns, name, pt, data, subresources...), &v1beta1.Canary{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha3.Canary), err
+	return obj.(*v1beta1.Canary), err
 }
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_flagger_client.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_flagger_client.go
similarity index 69%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_flagger_client.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_flagger_client.go
index c2e07626..7655b98a 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_flagger_client.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_flagger_client.go
@@ -19,22 +19,26 @@ limitations under the License.
 package fake
 
 import (
-	v1alpha1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
 	rest "k8s.io/client-go/rest"
 	testing "k8s.io/client-go/testing"
 )
 
-type FakeFlaggerV1alpha1 struct {
+type FakeFlaggerV1beta1 struct {
 	*testing.Fake
 }
 
-func (c *FakeFlaggerV1alpha1) MetricTemplates(namespace string) v1alpha1.MetricTemplateInterface {
+func (c *FakeFlaggerV1beta1) Canaries(namespace string) v1beta1.CanaryInterface {
+	return &FakeCanaries{c, namespace}
+}
+
+func (c *FakeFlaggerV1beta1) MetricTemplates(namespace string) v1beta1.MetricTemplateInterface {
 	return &FakeMetricTemplates{c, namespace}
 }
 
 // RESTClient returns a RESTClient that is used to communicate
 // with API server by this client implementation.
-func (c *FakeFlaggerV1alpha1) RESTClient() rest.Interface {
+func (c *FakeFlaggerV1beta1) RESTClient() rest.Interface {
 	var ret *rest.RESTClient
 	return ret
 }
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_metrictemplate.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_metrictemplate.go
similarity index 71%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_metrictemplate.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_metrictemplate.go
index 452becbd..7bb5702c 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/fake/fake_metrictemplate.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake/fake_metrictemplate.go
@@ -19,7 +19,7 @@ limitations under the License.
 package fake
 
 import (
-	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	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 (
 
 // FakeMetricTemplates implements MetricTemplateInterface
 type FakeMetricTemplates struct {
-	Fake *FakeFlaggerV1alpha1
+	Fake *FakeFlaggerV1beta1
 	ns   string
 }
 
-var metrictemplatesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1alpha1", Resource: "metrictemplates"}
+var metrictemplatesResource = schema.GroupVersionResource{Group: "flagger.app", Version: "v1beta1", Resource: "metrictemplates"}
 
-var metrictemplatesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1alpha1", Kind: "MetricTemplate"}
+var metrictemplatesKind = schema.GroupVersionKind{Group: "flagger.app", Version: "v1beta1", Kind: "MetricTemplate"}
 
 // Get takes name of the metricTemplate, and returns the corresponding metricTemplate object, and an error if there is any.
-func (c *FakeMetricTemplates) Get(name string, options v1.GetOptions) (result *v1alpha1.MetricTemplate, err error) {
+func (c *FakeMetricTemplates) Get(name string, options v1.GetOptions) (result *v1beta1.MetricTemplate, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(metrictemplatesResource, c.ns, name), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewGetAction(metrictemplatesResource, c.ns, name), &v1beta1.MetricTemplate{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha1.MetricTemplate), err
+	return obj.(*v1beta1.MetricTemplate), err
 }
 
 // List takes label and field selectors, and returns the list of MetricTemplates that match those selectors.
-func (c *FakeMetricTemplates) List(opts v1.ListOptions) (result *v1alpha1.MetricTemplateList, err error) {
+func (c *FakeMetricTemplates) List(opts v1.ListOptions) (result *v1beta1.MetricTemplateList, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewListAction(metrictemplatesResource, metrictemplatesKind, c.ns, opts), &v1alpha1.MetricTemplateList{})
+		Invokes(testing.NewListAction(metrictemplatesResource, metrictemplatesKind, c.ns, opts), &v1beta1.MetricTemplateList{})
 
 	if obj == nil {
 		return nil, err
@@ -62,8 +62,8 @@ func (c *FakeMetricTemplates) List(opts v1.ListOptions) (result *v1alpha1.Metric
 	if label == nil {
 		label = labels.Everything()
 	}
-	list := &v1alpha1.MetricTemplateList{ListMeta: obj.(*v1alpha1.MetricTemplateList).ListMeta}
-	for _, item := range obj.(*v1alpha1.MetricTemplateList).Items {
+	list := &v1beta1.MetricTemplateList{ListMeta: obj.(*v1beta1.MetricTemplateList).ListMeta}
+	for _, item := range obj.(*v1beta1.MetricTemplateList).Items {
 		if label.Matches(labels.Set(item.Labels)) {
 			list.Items = append(list.Items, item)
 		}
@@ -79,43 +79,43 @@ func (c *FakeMetricTemplates) Watch(opts v1.ListOptions) (watch.Interface, error
 }
 
 // Create takes the representation of a metricTemplate and creates it.  Returns the server's representation of the metricTemplate, and an error, if there is any.
-func (c *FakeMetricTemplates) Create(metricTemplate *v1alpha1.MetricTemplate) (result *v1alpha1.MetricTemplate, err error) {
+func (c *FakeMetricTemplates) Create(metricTemplate *v1beta1.MetricTemplate) (result *v1beta1.MetricTemplate, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(metrictemplatesResource, c.ns, metricTemplate), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewCreateAction(metrictemplatesResource, c.ns, metricTemplate), &v1beta1.MetricTemplate{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha1.MetricTemplate), err
+	return obj.(*v1beta1.MetricTemplate), err
 }
 
 // Update takes the representation of a metricTemplate and updates it. Returns the server's representation of the metricTemplate, and an error, if there is any.
-func (c *FakeMetricTemplates) Update(metricTemplate *v1alpha1.MetricTemplate) (result *v1alpha1.MetricTemplate, err error) {
+func (c *FakeMetricTemplates) Update(metricTemplate *v1beta1.MetricTemplate) (result *v1beta1.MetricTemplate, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(metrictemplatesResource, c.ns, metricTemplate), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewUpdateAction(metrictemplatesResource, c.ns, metricTemplate), &v1beta1.MetricTemplate{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha1.MetricTemplate), err
+	return obj.(*v1beta1.MetricTemplate), 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 *FakeMetricTemplates) UpdateStatus(metricTemplate *v1alpha1.MetricTemplate) (*v1alpha1.MetricTemplate, error) {
+func (c *FakeMetricTemplates) UpdateStatus(metricTemplate *v1beta1.MetricTemplate) (*v1beta1.MetricTemplate, error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewUpdateSubresourceAction(metrictemplatesResource, "status", c.ns, metricTemplate), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewUpdateSubresourceAction(metrictemplatesResource, "status", c.ns, metricTemplate), &v1beta1.MetricTemplate{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha1.MetricTemplate), err
+	return obj.(*v1beta1.MetricTemplate), err
 }
 
 // Delete takes name of the metricTemplate and deletes it. Returns an error if one occurs.
 func (c *FakeMetricTemplates) Delete(name string, options *v1.DeleteOptions) error {
 	_, err := c.Fake.
-		Invokes(testing.NewDeleteAction(metrictemplatesResource, c.ns, name), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewDeleteAction(metrictemplatesResource, c.ns, name), &v1beta1.MetricTemplate{})
 
 	return err
 }
@@ -124,17 +124,17 @@ func (c *FakeMetricTemplates) Delete(name string, options *v1.DeleteOptions) err
 func (c *FakeMetricTemplates) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
 	action := testing.NewDeleteCollectionAction(metrictemplatesResource, c.ns, listOptions)
 
-	_, err := c.Fake.Invokes(action, &v1alpha1.MetricTemplateList{})
+	_, err := c.Fake.Invokes(action, &v1beta1.MetricTemplateList{})
 	return err
 }
 
 // Patch applies the patch and returns the patched metricTemplate.
-func (c *FakeMetricTemplates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MetricTemplate, err error) {
+func (c *FakeMetricTemplates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.MetricTemplate, err error) {
 	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(metrictemplatesResource, c.ns, name, pt, data, subresources...), &v1alpha1.MetricTemplate{})
+		Invokes(testing.NewPatchSubresourceAction(metrictemplatesResource, c.ns, name, pt, data, subresources...), &v1beta1.MetricTemplate{})
 
 	if obj == nil {
 		return nil, err
 	}
-	return obj.(*v1alpha1.MetricTemplate), err
+	return obj.(*v1beta1.MetricTemplate), err
 }
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/flagger_client.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/flagger_client.go
similarity index 60%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/flagger_client.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/flagger_client.go
index fc8a6062..3caaafa3 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/flagger_client.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/flagger_client.go
@@ -16,30 +16,35 @@ limitations under the License.
 
 // Code generated by client-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
 
 import (
-	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
 	rest "k8s.io/client-go/rest"
 )
 
-type FlaggerV1alpha1Interface interface {
+type FlaggerV1beta1Interface interface {
 	RESTClient() rest.Interface
+	CanariesGetter
 	MetricTemplatesGetter
 }
 
-// FlaggerV1alpha1Client is used to interact with features provided by the flagger.app group.
-type FlaggerV1alpha1Client struct {
+// FlaggerV1beta1Client is used to interact with features provided by the flagger.app group.
+type FlaggerV1beta1Client struct {
 	restClient rest.Interface
 }
 
-func (c *FlaggerV1alpha1Client) MetricTemplates(namespace string) MetricTemplateInterface {
+func (c *FlaggerV1beta1Client) Canaries(namespace string) CanaryInterface {
+	return newCanaries(c, namespace)
+}
+
+func (c *FlaggerV1beta1Client) MetricTemplates(namespace string) MetricTemplateInterface {
 	return newMetricTemplates(c, namespace)
 }
 
-// NewForConfig creates a new FlaggerV1alpha1Client for the given config.
-func NewForConfig(c *rest.Config) (*FlaggerV1alpha1Client, error) {
+// NewForConfig creates a new FlaggerV1beta1Client for the given config.
+func NewForConfig(c *rest.Config) (*FlaggerV1beta1Client, error) {
 	config := *c
 	if err := setConfigDefaults(&config); err != nil {
 		return nil, err
@@ -48,12 +53,12 @@ func NewForConfig(c *rest.Config) (*FlaggerV1alpha1Client, error) {
 	if err != nil {
 		return nil, err
 	}
-	return &FlaggerV1alpha1Client{client}, nil
+	return &FlaggerV1beta1Client{client}, nil
 }
 
-// NewForConfigOrDie creates a new FlaggerV1alpha1Client for the given config and
+// NewForConfigOrDie creates a new FlaggerV1beta1Client for the given config and
 // panics if there is an error in the config.
-func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha1Client {
+func NewForConfigOrDie(c *rest.Config) *FlaggerV1beta1Client {
 	client, err := NewForConfig(c)
 	if err != nil {
 		panic(err)
@@ -61,13 +66,13 @@ func NewForConfigOrDie(c *rest.Config) *FlaggerV1alpha1Client {
 	return client
 }
 
-// New creates a new FlaggerV1alpha1Client for the given RESTClient.
-func New(c rest.Interface) *FlaggerV1alpha1Client {
-	return &FlaggerV1alpha1Client{c}
+// New creates a new FlaggerV1beta1Client for the given RESTClient.
+func New(c rest.Interface) *FlaggerV1beta1Client {
+	return &FlaggerV1beta1Client{c}
 }
 
 func setConfigDefaults(config *rest.Config) error {
-	gv := v1alpha1.SchemeGroupVersion
+	gv := v1beta1.SchemeGroupVersion
 	config.GroupVersion = &gv
 	config.APIPath = "/apis"
 	config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
@@ -81,7 +86,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 *FlaggerV1alpha1Client) RESTClient() rest.Interface {
+func (c *FlaggerV1beta1Client) RESTClient() rest.Interface {
 	if c == nil {
 		return nil
 	}
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/generated_expansion.go
similarity index 92%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/generated_expansion.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/generated_expansion.go
index 15b3fbce..08afc9e4 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/generated_expansion.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/generated_expansion.go
@@ -16,6 +16,8 @@ limitations under the License.
 
 // Code generated by client-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
+
+type CanaryExpansion interface{}
 
 type MetricTemplateExpansion interface{}
diff --git a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/metrictemplate.go b/pkg/client/clientset/versioned/typed/flagger/v1beta1/metrictemplate.go
similarity index 78%
rename from pkg/client/clientset/versioned/typed/flagger/v1alpha1/metrictemplate.go
rename to pkg/client/clientset/versioned/typed/flagger/v1beta1/metrictemplate.go
index 1d2f8731..41037829 100644
--- a/pkg/client/clientset/versioned/typed/flagger/v1alpha1/metrictemplate.go
+++ b/pkg/client/clientset/versioned/typed/flagger/v1beta1/metrictemplate.go
@@ -16,12 +16,12 @@ limitations under the License.
 
 // Code generated by client-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
 
 import (
 	"time"
 
-	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	scheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	types "k8s.io/apimachinery/pkg/types"
@@ -37,15 +37,15 @@ type MetricTemplatesGetter interface {
 
 // MetricTemplateInterface has methods to work with MetricTemplate resources.
 type MetricTemplateInterface interface {
-	Create(*v1alpha1.MetricTemplate) (*v1alpha1.MetricTemplate, error)
-	Update(*v1alpha1.MetricTemplate) (*v1alpha1.MetricTemplate, error)
-	UpdateStatus(*v1alpha1.MetricTemplate) (*v1alpha1.MetricTemplate, error)
+	Create(*v1beta1.MetricTemplate) (*v1beta1.MetricTemplate, error)
+	Update(*v1beta1.MetricTemplate) (*v1beta1.MetricTemplate, error)
+	UpdateStatus(*v1beta1.MetricTemplate) (*v1beta1.MetricTemplate, error)
 	Delete(name string, options *v1.DeleteOptions) error
 	DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
-	Get(name string, options v1.GetOptions) (*v1alpha1.MetricTemplate, error)
-	List(opts v1.ListOptions) (*v1alpha1.MetricTemplateList, error)
+	Get(name string, options v1.GetOptions) (*v1beta1.MetricTemplate, error)
+	List(opts v1.ListOptions) (*v1beta1.MetricTemplateList, error)
 	Watch(opts v1.ListOptions) (watch.Interface, error)
-	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MetricTemplate, err error)
+	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.MetricTemplate, err error)
 	MetricTemplateExpansion
 }
 
@@ -56,7 +56,7 @@ type metricTemplates struct {
 }
 
 // newMetricTemplates returns a MetricTemplates
-func newMetricTemplates(c *FlaggerV1alpha1Client, namespace string) *metricTemplates {
+func newMetricTemplates(c *FlaggerV1beta1Client, namespace string) *metricTemplates {
 	return &metricTemplates{
 		client: c.RESTClient(),
 		ns:     namespace,
@@ -64,8 +64,8 @@ func newMetricTemplates(c *FlaggerV1alpha1Client, namespace string) *metricTempl
 }
 
 // Get takes name of the metricTemplate, and returns the corresponding metricTemplate object, and an error if there is any.
-func (c *metricTemplates) Get(name string, options v1.GetOptions) (result *v1alpha1.MetricTemplate, err error) {
-	result = &v1alpha1.MetricTemplate{}
+func (c *metricTemplates) Get(name string, options v1.GetOptions) (result *v1beta1.MetricTemplate, err error) {
+	result = &v1beta1.MetricTemplate{}
 	err = c.client.Get().
 		Namespace(c.ns).
 		Resource("metrictemplates").
@@ -77,12 +77,12 @@ func (c *metricTemplates) Get(name string, options v1.GetOptions) (result *v1alp
 }
 
 // List takes label and field selectors, and returns the list of MetricTemplates that match those selectors.
-func (c *metricTemplates) List(opts v1.ListOptions) (result *v1alpha1.MetricTemplateList, err error) {
+func (c *metricTemplates) List(opts v1.ListOptions) (result *v1beta1.MetricTemplateList, err error) {
 	var timeout time.Duration
 	if opts.TimeoutSeconds != nil {
 		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
 	}
-	result = &v1alpha1.MetricTemplateList{}
+	result = &v1beta1.MetricTemplateList{}
 	err = c.client.Get().
 		Namespace(c.ns).
 		Resource("metrictemplates").
@@ -109,8 +109,8 @@ func (c *metricTemplates) Watch(opts v1.ListOptions) (watch.Interface, error) {
 }
 
 // Create takes the representation of a metricTemplate and creates it.  Returns the server's representation of the metricTemplate, and an error, if there is any.
-func (c *metricTemplates) Create(metricTemplate *v1alpha1.MetricTemplate) (result *v1alpha1.MetricTemplate, err error) {
-	result = &v1alpha1.MetricTemplate{}
+func (c *metricTemplates) Create(metricTemplate *v1beta1.MetricTemplate) (result *v1beta1.MetricTemplate, err error) {
+	result = &v1beta1.MetricTemplate{}
 	err = c.client.Post().
 		Namespace(c.ns).
 		Resource("metrictemplates").
@@ -121,8 +121,8 @@ func (c *metricTemplates) Create(metricTemplate *v1alpha1.MetricTemplate) (resul
 }
 
 // Update takes the representation of a metricTemplate and updates it. Returns the server's representation of the metricTemplate, and an error, if there is any.
-func (c *metricTemplates) Update(metricTemplate *v1alpha1.MetricTemplate) (result *v1alpha1.MetricTemplate, err error) {
-	result = &v1alpha1.MetricTemplate{}
+func (c *metricTemplates) Update(metricTemplate *v1beta1.MetricTemplate) (result *v1beta1.MetricTemplate, err error) {
+	result = &v1beta1.MetricTemplate{}
 	err = c.client.Put().
 		Namespace(c.ns).
 		Resource("metrictemplates").
@@ -136,8 +136,8 @@ func (c *metricTemplates) Update(metricTemplate *v1alpha1.MetricTemplate) (resul
 // UpdateStatus was generated because the type contains a Status member.
 // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
 
-func (c *metricTemplates) UpdateStatus(metricTemplate *v1alpha1.MetricTemplate) (result *v1alpha1.MetricTemplate, err error) {
-	result = &v1alpha1.MetricTemplate{}
+func (c *metricTemplates) UpdateStatus(metricTemplate *v1beta1.MetricTemplate) (result *v1beta1.MetricTemplate, err error) {
+	result = &v1beta1.MetricTemplate{}
 	err = c.client.Put().
 		Namespace(c.ns).
 		Resource("metrictemplates").
@@ -177,8 +177,8 @@ func (c *metricTemplates) DeleteCollection(options *v1.DeleteOptions, listOption
 }
 
 // Patch applies the patch and returns the patched metricTemplate.
-func (c *metricTemplates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.MetricTemplate, err error) {
-	result = &v1alpha1.MetricTemplate{}
+func (c *metricTemplates) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1beta1.MetricTemplate, err error) {
+	result = &v1beta1.MetricTemplate{}
 	err = c.client.Patch(pt).
 		Namespace(c.ns).
 		Resource("metrictemplates").
diff --git a/pkg/client/informers/externalversions/flagger/interface.go b/pkg/client/informers/externalversions/flagger/interface.go
index b2e39442..6a9b098e 100644
--- a/pkg/client/informers/externalversions/flagger/interface.go
+++ b/pkg/client/informers/externalversions/flagger/interface.go
@@ -19,17 +19,14 @@ limitations under the License.
 package flagger
 
 import (
-	v1alpha1 "github.com/weaveworks/flagger/pkg/client/informers/externalversions/flagger/v1alpha1"
-	v1alpha3 "github.com/weaveworks/flagger/pkg/client/informers/externalversions/flagger/v1alpha3"
+	v1beta1 "github.com/weaveworks/flagger/pkg/client/informers/externalversions/flagger/v1beta1"
 	internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
 )
 
 // Interface provides access to each of this group's versions.
 type Interface interface {
-	// V1alpha3 provides access to shared informers for resources in V1alpha3.
-	V1alpha3() v1alpha3.Interface
-	// V1alpha1 provides access to shared informers for resources in V1alpha1.
-	V1alpha1() v1alpha1.Interface
+	// V1beta1 provides access to shared informers for resources in V1beta1.
+	V1beta1() v1beta1.Interface
 }
 
 type group struct {
@@ -43,12 +40,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
 	return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
 }
 
-// V1alpha3 returns a new v1alpha3.Interface.
-func (g *group) V1alpha3() v1alpha3.Interface {
-	return v1alpha3.New(g.factory, g.namespace, g.tweakListOptions)
-}
-
-// V1alpha1 returns a new v1alpha1.Interface.
-func (g *group) V1alpha1() v1alpha1.Interface {
-	return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
+// V1beta1 returns a new v1beta1.Interface.
+func (g *group) V1beta1() v1beta1.Interface {
+	return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
 }
diff --git a/pkg/client/informers/externalversions/flagger/v1alpha3/interface.go b/pkg/client/informers/externalversions/flagger/v1alpha3/interface.go
deleted file mode 100644
index ff8598b7..00000000
--- a/pkg/client/informers/externalversions/flagger/v1alpha3/interface.go
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by informer-gen. DO NOT EDIT.
-
-package v1alpha3
-
-import (
-	internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
-)
-
-// Interface provides access to all the informers in this group version.
-type Interface interface {
-	// Canaries returns a CanaryInformer.
-	Canaries() CanaryInformer
-}
-
-type version struct {
-	factory          internalinterfaces.SharedInformerFactory
-	namespace        string
-	tweakListOptions internalinterfaces.TweakListOptionsFunc
-}
-
-// New returns a new Interface.
-func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
-	return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
-}
-
-// Canaries returns a CanaryInformer.
-func (v *version) Canaries() CanaryInformer {
-	return &canaryInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
-}
diff --git a/pkg/client/informers/externalversions/flagger/v1alpha3/canary.go b/pkg/client/informers/externalversions/flagger/v1beta1/canary.go
similarity index 84%
rename from pkg/client/informers/externalversions/flagger/v1alpha3/canary.go
rename to pkg/client/informers/externalversions/flagger/v1beta1/canary.go
index e5cc80de..884b0063 100644
--- a/pkg/client/informers/externalversions/flagger/v1alpha3/canary.go
+++ b/pkg/client/informers/externalversions/flagger/v1beta1/canary.go
@@ -16,15 +16,15 @@ limitations under the License.
 
 // Code generated by informer-gen. DO NOT EDIT.
 
-package v1alpha3
+package v1beta1
 
 import (
 	time "time"
 
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	versioned "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
-	v1alpha3 "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1alpha3"
+	v1beta1 "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1beta1"
 	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() v1alpha3.CanaryLister
+	Lister() v1beta1.CanaryLister
 }
 
 type canaryInformer struct {
@@ -61,16 +61,16 @@ func NewFilteredCanaryInformer(client versioned.Interface, namespace string, res
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.FlaggerV1alpha3().Canaries(namespace).List(options)
+				return client.FlaggerV1beta1().Canaries(namespace).List(options)
 			},
 			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.FlaggerV1alpha3().Canaries(namespace).Watch(options)
+				return client.FlaggerV1beta1().Canaries(namespace).Watch(options)
 			},
 		},
-		&flaggerv1alpha3.Canary{},
+		&flaggerv1beta1.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(&flaggerv1alpha3.Canary{}, f.defaultInformer)
+	return f.factory.InformerFor(&flaggerv1beta1.Canary{}, f.defaultInformer)
 }
 
-func (f *canaryInformer) Lister() v1alpha3.CanaryLister {
-	return v1alpha3.NewCanaryLister(f.Informer().GetIndexer())
+func (f *canaryInformer) Lister() v1beta1.CanaryLister {
+	return v1beta1.NewCanaryLister(f.Informer().GetIndexer())
 }
diff --git a/pkg/client/informers/externalversions/flagger/v1alpha1/interface.go b/pkg/client/informers/externalversions/flagger/v1beta1/interface.go
similarity index 85%
rename from pkg/client/informers/externalversions/flagger/v1alpha1/interface.go
rename to pkg/client/informers/externalversions/flagger/v1beta1/interface.go
index 0340df59..a15b3589 100644
--- a/pkg/client/informers/externalversions/flagger/v1alpha1/interface.go
+++ b/pkg/client/informers/externalversions/flagger/v1beta1/interface.go
@@ -16,7 +16,7 @@ limitations under the License.
 
 // Code generated by informer-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
 
 import (
 	internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
@@ -24,6 +24,8 @@ import (
 
 // Interface provides access to all the informers in this group version.
 type Interface interface {
+	// Canaries returns a CanaryInformer.
+	Canaries() CanaryInformer
 	// MetricTemplates returns a MetricTemplateInformer.
 	MetricTemplates() MetricTemplateInformer
 }
@@ -39,6 +41,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
 	return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
 }
 
+// Canaries returns a CanaryInformer.
+func (v *version) Canaries() CanaryInformer {
+	return &canaryInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
+
 // MetricTemplates returns a MetricTemplateInformer.
 func (v *version) MetricTemplates() MetricTemplateInformer {
 	return &metricTemplateInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
diff --git a/pkg/client/informers/externalversions/flagger/v1alpha1/metrictemplate.go b/pkg/client/informers/externalversions/flagger/v1beta1/metrictemplate.go
similarity index 83%
rename from pkg/client/informers/externalversions/flagger/v1alpha1/metrictemplate.go
rename to pkg/client/informers/externalversions/flagger/v1beta1/metrictemplate.go
index 6d11021b..43f965cb 100644
--- a/pkg/client/informers/externalversions/flagger/v1alpha1/metrictemplate.go
+++ b/pkg/client/informers/externalversions/flagger/v1beta1/metrictemplate.go
@@ -16,15 +16,15 @@ limitations under the License.
 
 // Code generated by informer-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
 
 import (
 	time "time"
 
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	versioned "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
-	v1alpha1 "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1beta1"
 	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 (
 // MetricTemplates.
 type MetricTemplateInformer interface {
 	Informer() cache.SharedIndexInformer
-	Lister() v1alpha1.MetricTemplateLister
+	Lister() v1beta1.MetricTemplateLister
 }
 
 type metricTemplateInformer struct {
@@ -61,16 +61,16 @@ func NewFilteredMetricTemplateInformer(client versioned.Interface, namespace str
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.FlaggerV1alpha1().MetricTemplates(namespace).List(options)
+				return client.FlaggerV1beta1().MetricTemplates(namespace).List(options)
 			},
 			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
 				if tweakListOptions != nil {
 					tweakListOptions(&options)
 				}
-				return client.FlaggerV1alpha1().MetricTemplates(namespace).Watch(options)
+				return client.FlaggerV1beta1().MetricTemplates(namespace).Watch(options)
 			},
 		},
-		&flaggerv1alpha1.MetricTemplate{},
+		&flaggerv1beta1.MetricTemplate{},
 		resyncPeriod,
 		indexers,
 	)
@@ -81,9 +81,9 @@ func (f *metricTemplateInformer) defaultInformer(client versioned.Interface, res
 }
 
 func (f *metricTemplateInformer) Informer() cache.SharedIndexInformer {
-	return f.factory.InformerFor(&flaggerv1alpha1.MetricTemplate{}, f.defaultInformer)
+	return f.factory.InformerFor(&flaggerv1beta1.MetricTemplate{}, f.defaultInformer)
 }
 
-func (f *metricTemplateInformer) Lister() v1alpha1.MetricTemplateLister {
-	return v1alpha1.NewMetricTemplateLister(f.Informer().GetIndexer())
+func (f *metricTemplateInformer) Lister() v1beta1.MetricTemplateLister {
+	return v1beta1.NewMetricTemplateLister(f.Informer().GetIndexer())
 }
diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go
index 38c6dad1..deb747c3 100644
--- a/pkg/client/informers/externalversions/generic.go
+++ b/pkg/client/informers/externalversions/generic.go
@@ -22,12 +22,11 @@ import (
 	"fmt"
 
 	v1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
-	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
-	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	v1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
-	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
+	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	projectcontourv1 "github.com/weaveworks/flagger/pkg/apis/projectcontour/v1"
-	smiv1alpha1 "github.com/weaveworks/flagger/pkg/apis/smi/v1alpha1"
+	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/smi/v1alpha1"
 	schema "k8s.io/apimachinery/pkg/runtime/schema"
 	cache "k8s.io/client-go/tools/cache"
 )
@@ -66,22 +65,20 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
 	case v1beta1.SchemeGroupVersion.WithResource("virtualservices"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Appmesh().V1beta1().VirtualServices().Informer()}, nil
 
-		// Group=flagger.app, Version=v1alpha1
-	case v1alpha1.SchemeGroupVersion.WithResource("metrictemplates"):
-		return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1alpha1().MetricTemplates().Informer()}, nil
-
-		// Group=flagger.app, Version=v1alpha3
-	case v1alpha3.SchemeGroupVersion.WithResource("canaries"):
-		return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1alpha3().Canaries().Informer()}, nil
+		// Group=flagger.app, Version=v1beta1
+	case flaggerv1beta1.SchemeGroupVersion.WithResource("canaries"):
+		return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1beta1().Canaries().Informer()}, nil
+	case flaggerv1beta1.SchemeGroupVersion.WithResource("metrictemplates"):
+		return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1beta1().MetricTemplates().Informer()}, nil
 
 		// Group=gloo.solo.io, Version=v1
 	case v1.SchemeGroupVersion.WithResource("upstreamgroups"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Gloo().V1().UpstreamGroups().Informer()}, nil
 
 		// Group=networking.istio.io, Version=v1alpha3
-	case istiov1alpha3.SchemeGroupVersion.WithResource("destinationrules"):
+	case v1alpha3.SchemeGroupVersion.WithResource("destinationrules"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha3().DestinationRules().Informer()}, nil
-	case istiov1alpha3.SchemeGroupVersion.WithResource("virtualservices"):
+	case v1alpha3.SchemeGroupVersion.WithResource("virtualservices"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Networking().V1alpha3().VirtualServices().Informer()}, nil
 
 		// Group=projectcontour.io, Version=v1
@@ -89,7 +86,7 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Projectcontour().V1().HTTPProxies().Informer()}, nil
 
 		// Group=split.smi-spec.io, Version=v1alpha1
-	case smiv1alpha1.SchemeGroupVersion.WithResource("trafficsplits"):
+	case v1alpha1.SchemeGroupVersion.WithResource("trafficsplits"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Split().V1alpha1().TrafficSplits().Informer()}, nil
 
 	}
diff --git a/pkg/client/listers/flagger/v1alpha3/expansion_generated.go b/pkg/client/listers/flagger/v1alpha3/expansion_generated.go
deleted file mode 100644
index 632464cf..00000000
--- a/pkg/client/listers/flagger/v1alpha3/expansion_generated.go
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Copyright The Flagger Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Code generated by lister-gen. DO NOT EDIT.
-
-package v1alpha3
-
-// CanaryListerExpansion allows custom methods to be added to
-// CanaryLister.
-type CanaryListerExpansion interface{}
-
-// CanaryNamespaceListerExpansion allows custom methods to be added to
-// CanaryNamespaceLister.
-type CanaryNamespaceListerExpansion interface{}
diff --git a/pkg/client/listers/flagger/v1alpha3/canary.go b/pkg/client/listers/flagger/v1beta1/canary.go
similarity index 80%
rename from pkg/client/listers/flagger/v1alpha3/canary.go
rename to pkg/client/listers/flagger/v1beta1/canary.go
index d5a050bf..5df0dcf5 100644
--- a/pkg/client/listers/flagger/v1alpha3/canary.go
+++ b/pkg/client/listers/flagger/v1beta1/canary.go
@@ -16,10 +16,10 @@ limitations under the License.
 
 // Code generated by lister-gen. DO NOT EDIT.
 
-package v1alpha3
+package v1beta1
 
 import (
-	v1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"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 []*v1alpha3.Canary, err error)
+	List(selector labels.Selector) (ret []*v1beta1.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 []*v1alpha3.Canary, err error) {
+func (s *canaryLister) List(selector labels.Selector) (ret []*v1beta1.Canary, err error) {
 	err = cache.ListAll(s.indexer, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1alpha3.Canary))
+		ret = append(ret, m.(*v1beta1.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 []*v1alpha3.Canary, err error)
+	List(selector labels.Selector) (ret []*v1beta1.Canary, err error)
 	// Get retrieves the Canary from the indexer for a given namespace and name.
-	Get(name string) (*v1alpha3.Canary, error)
+	Get(name string) (*v1beta1.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 []*v1alpha3.Canary, err error) {
+func (s canaryNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.Canary, err error) {
 	err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1alpha3.Canary))
+		ret = append(ret, m.(*v1beta1.Canary))
 	})
 	return ret, err
 }
 
 // Get retrieves the Canary from the indexer for a given namespace and name.
-func (s canaryNamespaceLister) Get(name string) (*v1alpha3.Canary, error) {
+func (s canaryNamespaceLister) Get(name string) (*v1beta1.Canary, error) {
 	obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
 	if err != nil {
 		return nil, err
 	}
 	if !exists {
-		return nil, errors.NewNotFound(v1alpha3.Resource("canary"), name)
+		return nil, errors.NewNotFound(v1beta1.Resource("canary"), name)
 	}
-	return obj.(*v1alpha3.Canary), nil
+	return obj.(*v1beta1.Canary), nil
 }
diff --git a/pkg/client/listers/flagger/v1alpha1/expansion_generated.go b/pkg/client/listers/flagger/v1beta1/expansion_generated.go
similarity index 76%
rename from pkg/client/listers/flagger/v1alpha1/expansion_generated.go
rename to pkg/client/listers/flagger/v1beta1/expansion_generated.go
index 8a9bb44d..625cbd66 100644
--- a/pkg/client/listers/flagger/v1alpha1/expansion_generated.go
+++ b/pkg/client/listers/flagger/v1beta1/expansion_generated.go
@@ -16,7 +16,15 @@ limitations under the License.
 
 // Code generated by lister-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
+
+// CanaryListerExpansion allows custom methods to be added to
+// CanaryLister.
+type CanaryListerExpansion interface{}
+
+// CanaryNamespaceListerExpansion allows custom methods to be added to
+// CanaryNamespaceLister.
+type CanaryNamespaceListerExpansion interface{}
 
 // MetricTemplateListerExpansion allows custom methods to be added to
 // MetricTemplateLister.
diff --git a/pkg/client/listers/flagger/v1alpha1/metrictemplate.go b/pkg/client/listers/flagger/v1beta1/metrictemplate.go
similarity index 79%
rename from pkg/client/listers/flagger/v1alpha1/metrictemplate.go
rename to pkg/client/listers/flagger/v1beta1/metrictemplate.go
index 35766ae0..f9cf0c42 100644
--- a/pkg/client/listers/flagger/v1alpha1/metrictemplate.go
+++ b/pkg/client/listers/flagger/v1beta1/metrictemplate.go
@@ -16,10 +16,10 @@ limitations under the License.
 
 // Code generated by lister-gen. DO NOT EDIT.
 
-package v1alpha1
+package v1beta1
 
 import (
-	v1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	v1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/tools/cache"
@@ -28,7 +28,7 @@ import (
 // MetricTemplateLister helps list MetricTemplates.
 type MetricTemplateLister interface {
 	// List lists all MetricTemplates in the indexer.
-	List(selector labels.Selector) (ret []*v1alpha1.MetricTemplate, err error)
+	List(selector labels.Selector) (ret []*v1beta1.MetricTemplate, err error)
 	// MetricTemplates returns an object that can list and get MetricTemplates.
 	MetricTemplates(namespace string) MetricTemplateNamespaceLister
 	MetricTemplateListerExpansion
@@ -45,9 +45,9 @@ func NewMetricTemplateLister(indexer cache.Indexer) MetricTemplateLister {
 }
 
 // List lists all MetricTemplates in the indexer.
-func (s *metricTemplateLister) List(selector labels.Selector) (ret []*v1alpha1.MetricTemplate, err error) {
+func (s *metricTemplateLister) List(selector labels.Selector) (ret []*v1beta1.MetricTemplate, err error) {
 	err = cache.ListAll(s.indexer, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1alpha1.MetricTemplate))
+		ret = append(ret, m.(*v1beta1.MetricTemplate))
 	})
 	return ret, err
 }
@@ -60,9 +60,9 @@ func (s *metricTemplateLister) MetricTemplates(namespace string) MetricTemplateN
 // MetricTemplateNamespaceLister helps list and get MetricTemplates.
 type MetricTemplateNamespaceLister interface {
 	// List lists all MetricTemplates in the indexer for a given namespace.
-	List(selector labels.Selector) (ret []*v1alpha1.MetricTemplate, err error)
+	List(selector labels.Selector) (ret []*v1beta1.MetricTemplate, err error)
 	// Get retrieves the MetricTemplate from the indexer for a given namespace and name.
-	Get(name string) (*v1alpha1.MetricTemplate, error)
+	Get(name string) (*v1beta1.MetricTemplate, error)
 	MetricTemplateNamespaceListerExpansion
 }
 
@@ -74,21 +74,21 @@ type metricTemplateNamespaceLister struct {
 }
 
 // List lists all MetricTemplates in the indexer for a given namespace.
-func (s metricTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.MetricTemplate, err error) {
+func (s metricTemplateNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.MetricTemplate, err error) {
 	err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
-		ret = append(ret, m.(*v1alpha1.MetricTemplate))
+		ret = append(ret, m.(*v1beta1.MetricTemplate))
 	})
 	return ret, err
 }
 
 // Get retrieves the MetricTemplate from the indexer for a given namespace and name.
-func (s metricTemplateNamespaceLister) Get(name string) (*v1alpha1.MetricTemplate, error) {
+func (s metricTemplateNamespaceLister) Get(name string) (*v1beta1.MetricTemplate, error) {
 	obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
 	if err != nil {
 		return nil, err
 	}
 	if !exists {
-		return nil, errors.NewNotFound(v1alpha1.Resource("metrictemplate"), name)
+		return nil, errors.NewNotFound(v1beta1.Resource("metrictemplate"), name)
 	}
-	return obj.(*v1alpha1.MetricTemplate), nil
+	return obj.(*v1beta1.MetricTemplate), nil
 }
diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go
index e46b228d..6239ecbd 100644
--- a/pkg/controller/controller.go
+++ b/pkg/controller/controller.go
@@ -19,12 +19,12 @@ import (
 	"k8s.io/client-go/tools/record"
 	"k8s.io/client-go/util/workqueue"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/canary"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	flaggerscheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
-	flaggerinformers "github.com/weaveworks/flagger/pkg/client/informers/externalversions/flagger/v1alpha3"
-	flaggerlisters "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1alpha3"
+	flaggerinformers "github.com/weaveworks/flagger/pkg/client/informers/externalversions/flagger/v1beta1"
+	flaggerlisters "github.com/weaveworks/flagger/pkg/client/listers/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics"
 	"github.com/weaveworks/flagger/pkg/metrics/observers"
 	"github.com/weaveworks/flagger/pkg/notifier"
@@ -222,7 +222,7 @@ func (c *Controller) syncHandler(key string) error {
 			cdCopy.Status.Conditions = conditions
 			cdCopy.Status.LastTransitionTime = metav1.Now()
 			cdCopy.Status.Phase = flaggerv1.CanaryPhaseInitializing
-			_, err := c.flaggerClient.FlaggerV1alpha3().Canaries(cd.Namespace).UpdateStatus(cdCopy)
+			_, err := c.flaggerClient.FlaggerV1beta1().Canaries(cd.Namespace).UpdateStatus(cdCopy)
 			if err != nil {
 				c.logger.Errorf("%s status condition update error: %v", key, err)
 				return fmt.Errorf("%s status condition update error: %v", key, err)
diff --git a/pkg/controller/scheduler.go b/pkg/controller/scheduler.go
index 8f9692af..a499af33 100644
--- a/pkg/controller/scheduler.go
+++ b/pkg/controller/scheduler.go
@@ -7,8 +7,7 @@ import (
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	flaggerv1alpha1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
-	flaggerv1alpha3 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/canary"
 	"github.com/weaveworks/flagger/pkg/metrics/observers"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
@@ -27,7 +26,7 @@ func (c *Controller) scheduleCanaries() {
 	stats := make(map[string]int)
 
 	c.canaries.Range(func(key interface{}, value interface{}) bool {
-		canary := value.(*flaggerv1alpha3.Canary)
+		canary := value.(*flaggerv1.Canary)
 
 		// format: <name>.<namespace>
 		name := key.(string)
@@ -89,7 +88,7 @@ func (c *Controller) scheduleCanaries() {
 func (c *Controller) advanceCanary(name string, namespace string, skipLivenessChecks bool) {
 	begin := time.Now()
 	// check if the canary exists
-	cd, err := c.flaggerClient.FlaggerV1alpha3().Canaries(namespace).Get(name, metav1.GetOptions{})
+	cd, err := c.flaggerClient.FlaggerV1beta1().Canaries(namespace).Get(name, metav1.GetOptions{})
 	if err != nil {
 		c.logger.With("canary", fmt.Sprintf("%s.%s", name, namespace)).
 			Errorf("Canary %s.%s not found", name, namespace)
@@ -198,8 +197,8 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 		}
 
 		// reset status
-		status := flaggerv1alpha3.CanaryStatus{
-			Phase:        flaggerv1alpha3.CanaryPhaseProgressing,
+		status := flaggerv1.CanaryStatus{
+			Phase:        flaggerv1.CanaryPhaseProgressing,
 			CanaryWeight: 0,
 			FailedChecks: 0,
 			Iterations:   0,
@@ -227,8 +226,8 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 	}
 
 	// check if we should rollback
-	if cd.Status.Phase == flaggerv1alpha3.CanaryPhaseProgressing ||
-		cd.Status.Phase == flaggerv1alpha3.CanaryPhaseWaiting {
+	if cd.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
+		cd.Status.Phase == flaggerv1.CanaryPhaseWaiting {
 		if ok := c.runRollbackHooks(cd, cd.Status.Phase); ok {
 			c.recordEventWarningf(cd, "Rolling back %s.%s manual webhook invoked", cd.Name, cd.Namespace)
 			c.sendNotification(cd, "Rolling back manual webhook invoked", false, true)
@@ -238,7 +237,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 	}
 
 	// route all traffic to primary if analysis has succeeded
-	if cd.Status.Phase == flaggerv1alpha3.CanaryPhasePromoting {
+	if cd.Status.Phase == flaggerv1.CanaryPhasePromoting {
 		if provider != "kubernetes" {
 			c.recordEventInfof(cd, "Routing all traffic to primary")
 			if err := meshRouter.SetRoutes(cd, 100, 0, false); err != nil {
@@ -249,7 +248,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 		}
 
 		// update status phase
-		if err := canaryController.SetStatusPhase(cd, flaggerv1alpha3.CanaryPhaseFinalising); err != nil {
+		if err := canaryController.SetStatusPhase(cd, flaggerv1.CanaryPhaseFinalising); err != nil {
 			c.recordEventWarningf(cd, "%v", err)
 			return
 		}
@@ -258,19 +257,19 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 	}
 
 	// scale canary to zero if promotion has finished
-	if cd.Status.Phase == flaggerv1alpha3.CanaryPhaseFinalising {
+	if cd.Status.Phase == flaggerv1.CanaryPhaseFinalising {
 		if err := canaryController.Scale(cd, 0); err != nil {
 			c.recordEventWarningf(cd, "%v", err)
 			return
 		}
 
 		// set status to succeeded
-		if err := canaryController.SetStatusPhase(cd, flaggerv1alpha3.CanaryPhaseSucceeded); err != nil {
+		if err := canaryController.SetStatusPhase(cd, flaggerv1.CanaryPhaseSucceeded); err != nil {
 			c.recordEventWarningf(cd, "%v", err)
 			return
 		}
-		c.recorder.SetStatus(cd, flaggerv1alpha3.CanaryPhaseSucceeded)
-		c.runPostRolloutHooks(cd, flaggerv1alpha3.CanaryPhaseSucceeded)
+		c.recorder.SetStatus(cd, flaggerv1.CanaryPhaseSucceeded)
+		c.runPostRolloutHooks(cd, flaggerv1.CanaryPhaseSucceeded)
 		c.recordEventInfof(cd, "Promotion completed! Scaling down %s.%s", cd.Spec.TargetRef.Name, cd.Namespace)
 		c.sendNotification(cd, "Canary analysis completed successfully, promotion finished.",
 			false, false)
@@ -278,7 +277,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 	}
 
 	// check if the number of failed checks reached the threshold
-	if cd.Status.Phase == flaggerv1alpha3.CanaryPhaseProgressing &&
+	if cd.Status.Phase == flaggerv1.CanaryPhaseProgressing &&
 		(!retriable || cd.Status.FailedChecks >= cd.Spec.CanaryAnalysis.Threshold) {
 		if !retriable {
 			c.recordEventWarningf(cd, "Rolling back %s.%s progress deadline exceeded %v",
@@ -351,7 +350,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
 
 }
 
-func (c *Controller) runCanary(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string, mirrored bool, canaryWeight int, primaryWeight int, maxWeight int) {
+func (c *Controller) runCanary(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string, mirrored bool, canaryWeight int, primaryWeight int, maxWeight int) {
 	primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name)
 
 	// increase traffic weight
@@ -414,14 +413,14 @@ func (c *Controller) runCanary(canary *flaggerv1alpha3.Canary, canaryController
 		}
 
 		// update status phase
-		if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhasePromoting); err != nil {
+		if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhasePromoting); err != nil {
 			c.recordEventWarningf(canary, "%v", err)
 			return
 		}
 	}
 }
 
-func (c *Controller) runAB(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string) {
+func (c *Controller) runAB(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string) {
 	primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name)
 
 	// route traffic to canary and increment iterations
@@ -456,14 +455,14 @@ func (c *Controller) runAB(canary *flaggerv1alpha3.Canary, canaryController cana
 		}
 
 		// update status phase
-		if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhasePromoting); err != nil {
+		if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhasePromoting); err != nil {
 			c.recordEventWarningf(canary, "%v", err)
 			return
 		}
 	}
 }
 
-func (c *Controller) runBlueGreen(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string, mirrored bool) {
+func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface, provider string, mirrored bool) {
 	primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name)
 
 	// increment iterations
@@ -524,7 +523,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1alpha3.Canary, canaryControll
 		}
 
 		// update status phase
-		if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhasePromoting); err != nil {
+		if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhasePromoting); err != nil {
 			c.recordEventWarningf(canary, "%v", err)
 			return
 		}
@@ -532,7 +531,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1alpha3.Canary, canaryControll
 
 }
 
-func (c *Controller) shouldSkipAnalysis(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, meshRouter router.Interface, primaryWeight int, canaryWeight int) bool {
+func (c *Controller) shouldSkipAnalysis(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface, primaryWeight int, canaryWeight int) bool {
 	if !canary.Spec.SkipAnalysis {
 		return false
 	}
@@ -561,13 +560,13 @@ func (c *Controller) shouldSkipAnalysis(canary *flaggerv1alpha3.Canary, canaryCo
 	}
 
 	// update status phase
-	if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhaseSucceeded); err != nil {
+	if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhaseSucceeded); err != nil {
 		c.recordEventWarningf(canary, "%v", err)
 		return false
 	}
 
 	// notify
-	c.recorder.SetStatus(canary, flaggerv1alpha3.CanaryPhaseSucceeded)
+	c.recorder.SetStatus(canary, flaggerv1.CanaryPhaseSucceeded)
 	c.recordEventInfof(canary, "Promotion completed! Canary analysis was skipped for %s.%s",
 		canary.Spec.TargetRef.Name, canary.Namespace)
 	c.sendNotification(canary, "Canary analysis was skipped, promotion finished.",
@@ -576,13 +575,13 @@ func (c *Controller) shouldSkipAnalysis(canary *flaggerv1alpha3.Canary, canaryCo
 	return true
 }
 
-func (c *Controller) shouldAdvance(canary *flaggerv1alpha3.Canary, canaryController canary.Controller) (bool, error) {
+func (c *Controller) shouldAdvance(canary *flaggerv1.Canary, canaryController canary.Controller) (bool, error) {
 	if canary.Status.LastAppliedSpec == "" ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhaseInitializing ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhaseProgressing ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhaseWaiting ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhasePromoting ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhaseFinalising {
+		canary.Status.Phase == flaggerv1.CanaryPhaseInitializing ||
+		canary.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
+		canary.Status.Phase == flaggerv1.CanaryPhaseWaiting ||
+		canary.Status.Phase == flaggerv1.CanaryPhasePromoting ||
+		canary.Status.Phase == flaggerv1.CanaryPhaseFinalising {
 		return true, nil
 	}
 
@@ -603,20 +602,20 @@ func (c *Controller) shouldAdvance(canary *flaggerv1alpha3.Canary, canaryControl
 
 }
 
-func (c *Controller) checkCanaryStatus(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, shouldAdvance bool) bool {
+func (c *Controller) checkCanaryStatus(canary *flaggerv1.Canary, canaryController canary.Controller, shouldAdvance bool) bool {
 	c.recorder.SetStatus(canary, canary.Status.Phase)
-	if canary.Status.Phase == flaggerv1alpha3.CanaryPhaseProgressing ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhasePromoting ||
-		canary.Status.Phase == flaggerv1alpha3.CanaryPhaseFinalising {
+	if canary.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
+		canary.Status.Phase == flaggerv1.CanaryPhasePromoting ||
+		canary.Status.Phase == flaggerv1.CanaryPhaseFinalising {
 		return true
 	}
 
-	if canary.Status.Phase == "" || canary.Status.Phase == flaggerv1alpha3.CanaryPhaseInitializing {
-		if err := canaryController.SyncStatus(canary, flaggerv1alpha3.CanaryStatus{Phase: flaggerv1alpha3.CanaryPhaseInitialized}); err != nil {
+	if canary.Status.Phase == "" || canary.Status.Phase == flaggerv1.CanaryPhaseInitializing {
+		if err := canaryController.SyncStatus(canary, flaggerv1.CanaryStatus{Phase: flaggerv1.CanaryPhaseInitialized}); err != nil {
 			c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
 			return false
 		}
-		c.recorder.SetStatus(canary, flaggerv1alpha3.CanaryPhaseInitialized)
+		c.recorder.SetStatus(canary, flaggerv1.CanaryPhaseInitialized)
 		c.recordEventInfof(canary, "Initialization done! %s.%s", canary.Name, canary.Namespace)
 		c.sendNotification(canary, "New deployment detected, initialization completed.",
 			true, false)
@@ -625,7 +624,7 @@ func (c *Controller) checkCanaryStatus(canary *flaggerv1alpha3.Canary, canaryCon
 
 	if shouldAdvance {
 		canaryPhaseProgressing := canary.DeepCopy()
-		canaryPhaseProgressing.Status.Phase = flaggerv1alpha3.CanaryPhaseProgressing
+		canaryPhaseProgressing.Status.Phase = flaggerv1.CanaryPhaseProgressing
 		c.recordEventInfof(canaryPhaseProgressing, "New revision detected! Scaling up %s.%s", canaryPhaseProgressing.Spec.TargetRef.Name, canaryPhaseProgressing.Namespace)
 		c.sendNotification(canaryPhaseProgressing, "New revision detected, starting canary analysis.",
 			true, false)
@@ -634,18 +633,18 @@ func (c *Controller) checkCanaryStatus(canary *flaggerv1alpha3.Canary, canaryCon
 			c.recordEventErrorf(canary, "%v", err)
 			return false
 		}
-		if err := canaryController.SyncStatus(canary, flaggerv1alpha3.CanaryStatus{Phase: flaggerv1alpha3.CanaryPhaseProgressing}); err != nil {
+		if err := canaryController.SyncStatus(canary, flaggerv1.CanaryStatus{Phase: flaggerv1.CanaryPhaseProgressing}); err != nil {
 			c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
 			return false
 		}
-		c.recorder.SetStatus(canary, flaggerv1alpha3.CanaryPhaseProgressing)
+		c.recorder.SetStatus(canary, flaggerv1.CanaryPhaseProgressing)
 		return false
 	}
 	return false
 }
 
-func (c *Controller) hasCanaryRevisionChanged(canary *flaggerv1alpha3.Canary, canaryController canary.Controller) bool {
-	if canary.Status.Phase == flaggerv1alpha3.CanaryPhaseProgressing {
+func (c *Controller) hasCanaryRevisionChanged(canary *flaggerv1.Canary, canaryController canary.Controller) bool {
+	if canary.Status.Phase == flaggerv1.CanaryPhaseProgressing {
 		if diff, _ := canaryController.HasTargetChanged(canary); diff {
 			return true
 		}
@@ -656,13 +655,13 @@ func (c *Controller) hasCanaryRevisionChanged(canary *flaggerv1alpha3.Canary, ca
 	return false
 }
 
-func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1alpha3.Canary, canaryController canary.Controller) bool {
+func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1.Canary, canaryController canary.Controller) bool {
 	for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == flaggerv1alpha3.ConfirmRolloutHook {
-			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1alpha3.CanaryPhaseProgressing, webhook)
+		if webhook.Type == flaggerv1.ConfirmRolloutHook {
+			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
 			if err != nil {
-				if canary.Status.Phase != flaggerv1alpha3.CanaryPhaseWaiting {
-					if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhaseWaiting); err != nil {
+				if canary.Status.Phase != flaggerv1.CanaryPhaseWaiting {
+					if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhaseWaiting); err != nil {
 						c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
 					}
 					c.recordEventWarningf(canary, "Halt %s.%s advancement waiting for approval %s",
@@ -671,8 +670,8 @@ func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1alpha3.Canary, cana
 				}
 				return false
 			} else {
-				if canary.Status.Phase == flaggerv1alpha3.CanaryPhaseWaiting {
-					if err := canaryController.SetStatusPhase(canary, flaggerv1alpha3.CanaryPhaseProgressing); err != nil {
+				if canary.Status.Phase == flaggerv1.CanaryPhaseWaiting {
+					if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryPhaseProgressing); err != nil {
 						c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
 						return false
 					}
@@ -685,10 +684,10 @@ func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1alpha3.Canary, cana
 	return true
 }
 
-func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1alpha3.Canary) bool {
+func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary) bool {
 	for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == flaggerv1alpha3.ConfirmPromotionHook {
-			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1alpha3.CanaryPhaseProgressing, webhook)
+		if webhook.Type == flaggerv1.ConfirmPromotionHook {
+			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
 			if err != nil {
 				c.recordEventWarningf(canary, "Halt %s.%s advancement waiting for promotion approval %s",
 					canary.Name, canary.Namespace, webhook.Name)
@@ -702,10 +701,10 @@ func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1alpha3.Canary) bo
 	return true
 }
 
-func (c *Controller) runPreRolloutHooks(canary *flaggerv1alpha3.Canary) bool {
+func (c *Controller) runPreRolloutHooks(canary *flaggerv1.Canary) bool {
 	for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == flaggerv1alpha3.PreRolloutHook {
-			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1alpha3.CanaryPhaseProgressing, webhook)
+		if webhook.Type == flaggerv1.PreRolloutHook {
+			err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
 			if err != nil {
 				c.recordEventWarningf(canary, "Halt %s.%s advancement pre-rollout check %s failed %v",
 					canary.Name, canary.Namespace, webhook.Name, err)
@@ -718,9 +717,9 @@ func (c *Controller) runPreRolloutHooks(canary *flaggerv1alpha3.Canary) bool {
 	return true
 }
 
-func (c *Controller) runPostRolloutHooks(canary *flaggerv1alpha3.Canary, phase flaggerv1alpha3.CanaryPhase) bool {
+func (c *Controller) runPostRolloutHooks(canary *flaggerv1.Canary, phase flaggerv1.CanaryPhase) bool {
 	for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == flaggerv1alpha3.PostRolloutHook {
+		if webhook.Type == flaggerv1.PostRolloutHook {
 			err := CallWebhook(canary.Name, canary.Namespace, phase, webhook)
 			if err != nil {
 				c.recordEventWarningf(canary, "Post-rollout hook %s failed %v", webhook.Name, err)
@@ -733,9 +732,9 @@ func (c *Controller) runPostRolloutHooks(canary *flaggerv1alpha3.Canary, phase f
 	return true
 }
 
-func (c *Controller) runRollbackHooks(canary *flaggerv1alpha3.Canary, phase flaggerv1alpha3.CanaryPhase) bool {
+func (c *Controller) runRollbackHooks(canary *flaggerv1.Canary, phase flaggerv1.CanaryPhase) bool {
 	for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == flaggerv1alpha3.RollbackHook {
+		if webhook.Type == flaggerv1.RollbackHook {
 			err := CallWebhook(canary.Name, canary.Namespace, phase, webhook)
 			if err != nil {
 				c.recordEventInfof(canary, "Rollback hook %s not signaling a rollback", webhook.Name)
@@ -748,11 +747,11 @@ func (c *Controller) runRollbackHooks(canary *flaggerv1alpha3.Canary, phase flag
 	return false
 }
 
-func (c *Controller) runAnalysis(r *flaggerv1alpha3.Canary) bool {
+func (c *Controller) runAnalysis(r *flaggerv1.Canary) bool {
 	// run external checks
 	for _, webhook := range r.Spec.CanaryAnalysis.Webhooks {
-		if webhook.Type == "" || webhook.Type == flaggerv1alpha3.RolloutHook {
-			err := CallWebhook(r.Name, r.Namespace, flaggerv1alpha3.CanaryPhaseProgressing, webhook)
+		if webhook.Type == "" || webhook.Type == flaggerv1.RolloutHook {
+			err := CallWebhook(r.Name, r.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
 			if err != nil {
 				c.recordEventWarningf(r, "Halt %s.%s advancement external check %s failed %v",
 					r.Name, r.Namespace, webhook.Name, err)
@@ -774,7 +773,7 @@ func (c *Controller) runAnalysis(r *flaggerv1alpha3.Canary) bool {
 	return true
 }
 
-func (c *Controller) runBuiltinMetricChecks(r *flaggerv1alpha3.Canary) bool {
+func (c *Controller) runBuiltinMetricChecks(r *flaggerv1.Canary) bool {
 	// override the global provider if one is specified in the canary spec
 	var metricsProvider string
 	// set the metrics provider to Crossover Prometheus when Crossover is the mesh provider
@@ -882,7 +881,7 @@ func (c *Controller) runBuiltinMetricChecks(r *flaggerv1alpha3.Canary) bool {
 	return true
 }
 
-func (c *Controller) runMetricChecks(r *flaggerv1alpha3.Canary) bool {
+func (c *Controller) runMetricChecks(r *flaggerv1.Canary) bool {
 	for _, metric := range r.Spec.CanaryAnalysis.Metrics {
 		if metric.TemplateRef != nil {
 			namespace := r.Namespace
@@ -890,7 +889,7 @@ func (c *Controller) runMetricChecks(r *flaggerv1alpha3.Canary) bool {
 				namespace = metric.TemplateRef.Namespace
 			}
 
-			template, err := c.flaggerClient.FlaggerV1alpha1().MetricTemplates(namespace).Get(metric.TemplateRef.Name, metav1.GetOptions{})
+			template, err := c.flaggerClient.FlaggerV1beta1().MetricTemplates(namespace).Get(metric.TemplateRef.Name, metav1.GetOptions{})
 			if err != nil {
 				c.recordEventErrorf(r, "Metric template %s.%s error: %v", metric.TemplateRef.Name, namespace, err)
 				return false
@@ -944,7 +943,7 @@ func (c *Controller) runMetricChecks(r *flaggerv1alpha3.Canary) bool {
 	return true
 }
 
-func toMetricModel(r *flaggerv1alpha3.Canary, interval string) flaggerv1alpha1.MetricTemplateModel {
+func toMetricModel(r *flaggerv1.Canary, interval string) flaggerv1.MetricTemplateModel {
 	service := r.Spec.TargetRef.Name
 	if r.Spec.Service.Name != "" {
 		service = r.Spec.Service.Name
@@ -953,7 +952,7 @@ func toMetricModel(r *flaggerv1alpha3.Canary, interval string) flaggerv1alpha1.M
 	if r.Spec.IngressRef != nil {
 		ingress = r.Spec.IngressRef.Name
 	}
-	return flaggerv1alpha1.MetricTemplateModel{
+	return flaggerv1.MetricTemplateModel{
 		Name:      r.Name,
 		Namespace: r.Namespace,
 		Target:    r.Spec.TargetRef.Name,
@@ -963,7 +962,7 @@ func toMetricModel(r *flaggerv1alpha3.Canary, interval string) flaggerv1alpha1.M
 	}
 }
 
-func (c *Controller) rollback(canary *flaggerv1alpha3.Canary, canaryController canary.Controller, meshRouter router.Interface) {
+func (c *Controller) rollback(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface) {
 	if canary.Status.FailedChecks >= canary.Spec.CanaryAnalysis.Threshold {
 		c.recordEventWarningf(canary, "Rolling back %s.%s failed checks threshold reached %v",
 			canary.Name, canary.Namespace, canary.Status.FailedChecks)
@@ -980,7 +979,7 @@ func (c *Controller) rollback(canary *flaggerv1alpha3.Canary, canaryController c
 	}
 
 	canaryPhaseFailed := canary.DeepCopy()
-	canaryPhaseFailed.Status.Phase = flaggerv1alpha3.CanaryPhaseFailed
+	canaryPhaseFailed.Status.Phase = flaggerv1.CanaryPhaseFailed
 	c.recordEventWarningf(canaryPhaseFailed, "Canary failed! Scaling down %s.%s",
 		canaryPhaseFailed.Name, canaryPhaseFailed.Namespace)
 
@@ -993,11 +992,11 @@ func (c *Controller) rollback(canary *flaggerv1alpha3.Canary, canaryController c
 	}
 
 	// mark canary as failed
-	if err := canaryController.SyncStatus(canary, flaggerv1alpha3.CanaryStatus{Phase: flaggerv1alpha3.CanaryPhaseFailed, CanaryWeight: 0}); err != nil {
+	if err := canaryController.SyncStatus(canary, flaggerv1.CanaryStatus{Phase: flaggerv1.CanaryPhaseFailed, CanaryWeight: 0}); err != nil {
 		c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
 		return
 	}
 
-	c.recorder.SetStatus(canary, flaggerv1alpha3.CanaryPhaseFailed)
-	c.runPostRolloutHooks(canary, flaggerv1alpha3.CanaryPhaseFailed)
+	c.recorder.SetStatus(canary, flaggerv1.CanaryPhaseFailed)
+	c.runPostRolloutHooks(canary, flaggerv1.CanaryPhaseFailed)
 }
diff --git a/pkg/controller/webhook.go b/pkg/controller/webhook.go
index 6501efd2..ed5316c7 100644
--- a/pkg/controller/webhook.go
+++ b/pkg/controller/webhook.go
@@ -13,7 +13,7 @@ import (
 	"strconv"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func callWebhook(webhook string, payload interface{}, timeout string) error {
diff --git a/pkg/metrics/observers/appmesh.go b/pkg/metrics/observers/appmesh.go
index 9bd3de22..4d4a0362 100644
--- a/pkg/metrics/observers/appmesh.go
+++ b/pkg/metrics/observers/appmesh.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/contour.go b/pkg/metrics/observers/contour.go
index 408a84c1..919797bf 100644
--- a/pkg/metrics/observers/contour.go
+++ b/pkg/metrics/observers/contour.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/crossover.go b/pkg/metrics/observers/crossover.go
index f0cee774..ac985201 100644
--- a/pkg/metrics/observers/crossover.go
+++ b/pkg/metrics/observers/crossover.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/crossover_service.go b/pkg/metrics/observers/crossover_service.go
index 35c0412e..c8c3565f 100644
--- a/pkg/metrics/observers/crossover_service.go
+++ b/pkg/metrics/observers/crossover_service.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/factory.go b/pkg/metrics/observers/factory.go
index b6f02902..f335354f 100644
--- a/pkg/metrics/observers/factory.go
+++ b/pkg/metrics/observers/factory.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"strings"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/gloo.go b/pkg/metrics/observers/gloo.go
index cbde1239..116787a0 100644
--- a/pkg/metrics/observers/gloo.go
+++ b/pkg/metrics/observers/gloo.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/http.go b/pkg/metrics/observers/http.go
index 476ae3ba..632fa72c 100644
--- a/pkg/metrics/observers/http.go
+++ b/pkg/metrics/observers/http.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/istio.go b/pkg/metrics/observers/istio.go
index 9c9df838..52945ea4 100644
--- a/pkg/metrics/observers/istio.go
+++ b/pkg/metrics/observers/istio.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/linkerd.go b/pkg/metrics/observers/linkerd.go
index e54fd844..5257a7c6 100644
--- a/pkg/metrics/observers/linkerd.go
+++ b/pkg/metrics/observers/linkerd.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/nginx.go b/pkg/metrics/observers/nginx.go
index f74a41df..442dc5d1 100644
--- a/pkg/metrics/observers/nginx.go
+++ b/pkg/metrics/observers/nginx.go
@@ -3,7 +3,7 @@ package observers
 import (
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/observer.go b/pkg/metrics/observers/observer.go
index 59cb0b70..a2e90658 100644
--- a/pkg/metrics/observers/observer.go
+++ b/pkg/metrics/observers/observer.go
@@ -1,7 +1,7 @@
 package observers
 
 import (
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"time"
 )
 
diff --git a/pkg/metrics/observers/render.go b/pkg/metrics/observers/render.go
index a59917c9..ca3aadd4 100644
--- a/pkg/metrics/observers/render.go
+++ b/pkg/metrics/observers/render.go
@@ -5,7 +5,7 @@ import (
 	"bytes"
 	"text/template"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func RenderQuery(queryTemplate string, model flaggerv1.MetricTemplateModel) (string, error) {
diff --git a/pkg/metrics/providers/factory.go b/pkg/metrics/providers/factory.go
index e03b2aee..a9d5057d 100644
--- a/pkg/metrics/providers/factory.go
+++ b/pkg/metrics/providers/factory.go
@@ -1,6 +1,6 @@
 package providers
 
-import flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+import flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 
 type Factory struct {
 }
diff --git a/pkg/metrics/providers/prometheus.go b/pkg/metrics/providers/prometheus.go
index e04c03d2..9823cb61 100644
--- a/pkg/metrics/providers/prometheus.go
+++ b/pkg/metrics/providers/prometheus.go
@@ -12,7 +12,7 @@ import (
 	"strconv"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // PrometheusProvider executes promQL queries
diff --git a/pkg/metrics/recorder.go b/pkg/metrics/recorder.go
index d798bc65..51abd155 100644
--- a/pkg/metrics/recorder.go
+++ b/pkg/metrics/recorder.go
@@ -5,7 +5,7 @@ import (
 	"time"
 
 	"github.com/prometheus/client_golang/prometheus"
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // Recorder records the canary analysis as Prometheus metrics
diff --git a/pkg/router/appmesh.go b/pkg/router/appmesh.go
index 50876004..1d13fff8 100644
--- a/pkg/router/appmesh.go
+++ b/pkg/router/appmesh.go
@@ -15,7 +15,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 
 	appmeshv1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/router/contour.go b/pkg/router/contour.go
index 9e994409..8d540441 100644
--- a/pkg/router/contour.go
+++ b/pkg/router/contour.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	contourv1 "github.com/weaveworks/flagger/pkg/apis/projectcontour/v1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
diff --git a/pkg/router/gloo.go b/pkg/router/gloo.go
index 516c7043..8648a7e3 100644
--- a/pkg/router/gloo.go
+++ b/pkg/router/gloo.go
@@ -12,7 +12,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/router/ingress.go b/pkg/router/ingress.go
index 3eebf620..22e8b9b8 100644
--- a/pkg/router/ingress.go
+++ b/pkg/router/ingress.go
@@ -13,7 +13,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 type IngressRouter struct {
diff --git a/pkg/router/istio.go b/pkg/router/istio.go
index 2f774698..4a87b8fa 100644
--- a/pkg/router/istio.go
+++ b/pkg/router/istio.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
diff --git a/pkg/router/kubernetes.go b/pkg/router/kubernetes.go
index a293ed3d..a81a3f68 100644
--- a/pkg/router/kubernetes.go
+++ b/pkg/router/kubernetes.go
@@ -1,7 +1,7 @@
 package router
 
 import (
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // KubernetesRouter manages Kubernetes services
diff --git a/pkg/router/kubernetes_deployment.go b/pkg/router/kubernetes_deployment.go
index 9ea6756b..112a2be2 100644
--- a/pkg/router/kubernetes_deployment.go
+++ b/pkg/router/kubernetes_deployment.go
@@ -13,7 +13,7 @@ import (
 	"k8s.io/apimachinery/pkg/util/intstr"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )
 
diff --git a/pkg/router/kubernetes_noop.go b/pkg/router/kubernetes_noop.go
index 4da4a35b..3a66249c 100644
--- a/pkg/router/kubernetes_noop.go
+++ b/pkg/router/kubernetes_noop.go
@@ -1,7 +1,7 @@
 package router
 
 import (
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // KubernetesNoopRouter manages nothing. This is useful when one uses Flagger for progressive delivery of
diff --git a/pkg/router/nop.go b/pkg/router/nop.go
index d7ec6721..665389d3 100644
--- a/pkg/router/nop.go
+++ b/pkg/router/nop.go
@@ -1,7 +1,7 @@
 package router
 
 import (
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 // NopRouter no-operation router
diff --git a/pkg/router/router.go b/pkg/router/router.go
index f506bd1c..bd72e583 100644
--- a/pkg/router/router.go
+++ b/pkg/router/router.go
@@ -1,6 +1,6 @@
 package router
 
-import flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+import flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 
 type Interface interface {
 	Reconcile(canary *flaggerv1.Canary) error
diff --git a/pkg/router/smi.go b/pkg/router/smi.go
index 2da06cc6..e2099c36 100644
--- a/pkg/router/smi.go
+++ b/pkg/router/smi.go
@@ -13,7 +13,7 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/kubernetes"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	smiv1 "github.com/weaveworks/flagger/pkg/apis/smi/v1alpha1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 )


Test patch:
diff --git a/pkg/canary/deployment_controller_test.go b/pkg/canary/deployment_controller_test.go
index d143a5b0..e042f120 100644
--- a/pkg/canary/deployment_controller_test.go
+++ b/pkg/canary/deployment_controller_test.go
@@ -5,7 +5,7 @@ import (
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func TestCanaryDeployer_Sync(t *testing.T) {
@@ -213,7 +213,7 @@ func TestCanaryDeployer_SetFailedChecks(t *testing.T) {
 		t.Fatal(err.Error())
 	}
 
-	res, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	res, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -235,7 +235,7 @@ func TestCanaryDeployer_SetState(t *testing.T) {
 		t.Fatal(err.Error())
 	}
 
-	res, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	res, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -261,7 +261,7 @@ func TestCanaryDeployer_SyncStatus(t *testing.T) {
 		t.Fatal(err.Error())
 	}
 
-	res, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	res, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go
index ce90d748..49c0ef5b 100644
--- a/pkg/controller/controller_test.go
+++ b/pkg/controller/controller_test.go
@@ -17,7 +17,7 @@ import (
 	"k8s.io/client-go/tools/record"
 	"k8s.io/client-go/util/workqueue"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	istiov1alpha1 "github.com/weaveworks/flagger/pkg/apis/istio/common/v1alpha1"
 	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	"github.com/weaveworks/flagger/pkg/canary"
@@ -68,7 +68,7 @@ func SetupMocks(c *flaggerv1.Canary) Mocks {
 
 	// init controller
 	flaggerInformerFactory := informers.NewSharedInformerFactory(flaggerClient, noResyncPeriodFunc())
-	flaggerInformer := flaggerInformerFactory.Flagger().V1alpha3().Canaries()
+	flaggerInformer := flaggerInformerFactory.Flagger().V1beta1().Canaries()
 
 	// init router
 	rf := router.NewFactory(nil, kubeClient, flaggerClient, "annotationsPrefix", logger, flaggerClient)
diff --git a/pkg/controller/scheduler_svc_test.go b/pkg/controller/scheduler_svc_test.go
index 89011fcd..bbe41a6c 100644
--- a/pkg/controller/scheduler_svc_test.go
+++ b/pkg/controller/scheduler_svc_test.go
@@ -6,7 +6,7 @@ import (
 	hpav1 "k8s.io/api/autoscaling/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func TestScheduler_ServicePromotion(t *testing.T) {
@@ -16,7 +16,7 @@ func TestScheduler_ServicePromotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check initialized status
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -51,7 +51,7 @@ func TestScheduler_ServicePromotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check progressing status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -64,7 +64,7 @@ func TestScheduler_ServicePromotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check promoting status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -105,7 +105,7 @@ func TestScheduler_ServicePromotion(t *testing.T) {
 	}
 
 	// check finalising status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -117,7 +117,7 @@ func TestScheduler_ServicePromotion(t *testing.T) {
 	// scale canary to zero
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/controller/scheduler_test.go b/pkg/controller/scheduler_test.go
index 083f6e97..5d66f641 100644
--- a/pkg/controller/scheduler_test.go
+++ b/pkg/controller/scheduler_test.go
@@ -7,7 +7,7 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func TestScheduler_Init(t *testing.T) {
@@ -58,7 +58,7 @@ func TestScheduler_Rollback(t *testing.T) {
 	// detect changes
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -74,12 +74,12 @@ func TestScheduler_SkipAnalysis(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// enable skip
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
 	cd.Spec.SkipAnalysis = true
-	_, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cd)
+	_, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cd)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -96,7 +96,7 @@ func TestScheduler_SkipAnalysis(t *testing.T) {
 	// advance
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -178,7 +178,7 @@ func TestScheduler_Promotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check initialized status
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -228,7 +228,7 @@ func TestScheduler_Promotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check progressing status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -241,7 +241,7 @@ func TestScheduler_Promotion(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check promoting status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -300,7 +300,7 @@ func TestScheduler_Promotion(t *testing.T) {
 	}
 
 	// check finalising status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -312,7 +312,7 @@ func TestScheduler_Promotion(t *testing.T) {
 	// scale canary to zero
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -416,7 +416,7 @@ func TestScheduler_ABTesting(t *testing.T) {
 		t.Errorf("Got mirrored %v wanted %v", mirrored, false)
 	}
 
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -433,7 +433,7 @@ func TestScheduler_ABTesting(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check finalising status
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -458,7 +458,7 @@ func TestScheduler_ABTesting(t *testing.T) {
 	mocks.ctrl.advanceCanary("podinfo", "default", true)
 
 	// check rollout status
-	c, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	c, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -472,12 +472,12 @@ func TestScheduler_PortDiscovery(t *testing.T) {
 	mocks := SetupMocks(nil)
 
 	// enable port discovery
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
 	cd.Spec.Service.PortDiscovery = true
-	_, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cd)
+	_, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cd)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -515,14 +515,14 @@ func TestScheduler_PortDiscovery(t *testing.T) {
 func TestScheduler_TargetPortNumber(t *testing.T) {
 	mocks := SetupMocks(nil)
 
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
 	cd.Spec.Service.Port = 80
 	cd.Spec.Service.TargetPort = intstr.FromInt(9898)
 	cd.Spec.Service.PortDiscovery = true
-	_, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cd)
+	_, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cd)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -560,14 +560,14 @@ func TestScheduler_TargetPortNumber(t *testing.T) {
 func TestScheduler_TargetPortName(t *testing.T) {
 	mocks := SetupMocks(nil)
 
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
 	cd.Spec.Service.Port = 8080
 	cd.Spec.Service.TargetPort = intstr.FromString("http")
 	cd.Spec.Service.PortDiscovery = true
-	_, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cd)
+	_, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cd)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/controller/webhook_test.go b/pkg/controller/webhook_test.go
index a5635e0d..43143441 100644
--- a/pkg/controller/webhook_test.go
+++ b/pkg/controller/webhook_test.go
@@ -9,7 +9,7 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 )
 
 func TestCallWebhook(t *testing.T) {
diff --git a/pkg/loadtester/server.go b/pkg/loadtester/server.go
index b91af494..657cb452 100644
--- a/pkg/loadtester/server.go
+++ b/pkg/loadtester/server.go
@@ -9,7 +9,7 @@ import (
 	"time"
 
 	"github.com/prometheus/client_golang/prometheus/promhttp"
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"go.uber.org/zap"
 )
 
diff --git a/pkg/metrics/observers/appmesh_test.go b/pkg/metrics/observers/appmesh_test.go
index a3114f91..22154201 100644
--- a/pkg/metrics/observers/appmesh_test.go
+++ b/pkg/metrics/observers/appmesh_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/contour_test.go b/pkg/metrics/observers/contour_test.go
index 7b743da2..4afdb69f 100644
--- a/pkg/metrics/observers/contour_test.go
+++ b/pkg/metrics/observers/contour_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/crossover_service_test.go b/pkg/metrics/observers/crossover_service_test.go
index d1503506..efae05aa 100644
--- a/pkg/metrics/observers/crossover_service_test.go
+++ b/pkg/metrics/observers/crossover_service_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/crossover_test.go b/pkg/metrics/observers/crossover_test.go
index 0ab2cbee..218fbecd 100644
--- a/pkg/metrics/observers/crossover_test.go
+++ b/pkg/metrics/observers/crossover_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/gloo_test.go b/pkg/metrics/observers/gloo_test.go
index 52ad4512..27045b7b 100644
--- a/pkg/metrics/observers/gloo_test.go
+++ b/pkg/metrics/observers/gloo_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/http_test.go b/pkg/metrics/observers/http_test.go
index 3daf8dbd..53612b51 100644
--- a/pkg/metrics/observers/http_test.go
+++ b/pkg/metrics/observers/http_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/istio_test.go b/pkg/metrics/observers/istio_test.go
index f3dd62a9..107b34c7 100644
--- a/pkg/metrics/observers/istio_test.go
+++ b/pkg/metrics/observers/istio_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/linkerd_test.go b/pkg/metrics/observers/linkerd_test.go
index 94d54c4c..a66a69d6 100644
--- a/pkg/metrics/observers/linkerd_test.go
+++ b/pkg/metrics/observers/linkerd_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/observers/nginx_test.go b/pkg/metrics/observers/nginx_test.go
index b51fcded..974ec66f 100644
--- a/pkg/metrics/observers/nginx_test.go
+++ b/pkg/metrics/observers/nginx_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 	"time"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	"github.com/weaveworks/flagger/pkg/metrics/providers"
 )
 
diff --git a/pkg/metrics/providers/prometheus_test.go b/pkg/metrics/providers/prometheus_test.go
index 09d1f139..2c23d785 100644
--- a/pkg/metrics/providers/prometheus_test.go
+++ b/pkg/metrics/providers/prometheus_test.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/fake"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha1"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
 	fakeFlagger "github.com/weaveworks/flagger/pkg/client/clientset/versioned/fake"
 )
@@ -66,7 +66,7 @@ func prometheusFake() fakeClients {
 func TestNewPrometheusProvider(t *testing.T) {
 	clients := prometheusFake()
 
-	template, err := clients.flaggerClient.FlaggerV1alpha1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
+	template, err := clients.flaggerClient.FlaggerV1beta1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -113,7 +113,7 @@ func TestPrometheusProvider_RunQueryWithBasicAuth(t *testing.T) {
 
 	clients := prometheusFake()
 
-	template, err := clients.flaggerClient.FlaggerV1alpha1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
+	template, err := clients.flaggerClient.FlaggerV1beta1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -147,7 +147,7 @@ func TestPrometheusProvider_IsOnline(t *testing.T) {
 
 	clients := prometheusFake()
 
-	template, err := clients.flaggerClient.FlaggerV1alpha1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
+	template, err := clients.flaggerClient.FlaggerV1beta1().MetricTemplates("default").Get("prometheus", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/router/appmesh_test.go b/pkg/router/appmesh_test.go
index e5509033..2f036c4f 100644
--- a/pkg/router/appmesh_test.go
+++ b/pkg/router/appmesh_test.go
@@ -71,7 +71,7 @@ func TestAppmeshRouter_Reconcile(t *testing.T) {
 	}
 
 	// test backends update
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("appmesh", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("appmesh", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -80,7 +80,7 @@ func TestAppmeshRouter_Reconcile(t *testing.T) {
 	hosts := cdClone.Spec.Service.Backends
 	hosts = append(hosts, "test.example.com")
 	cdClone.Spec.Service.Backends = hosts
-	canary, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cdClone)
+	canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/router/contour_test.go b/pkg/router/contour_test.go
index f6d37bca..54b69a39 100644
--- a/pkg/router/contour_test.go
+++ b/pkg/router/contour_test.go
@@ -40,7 +40,7 @@ func TestContourRouter_Reconcile(t *testing.T) {
 	}
 
 	// test update
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -48,7 +48,7 @@ func TestContourRouter_Reconcile(t *testing.T) {
 	cdClone := cd.DeepCopy()
 	cdClone.Spec.Service.Port = 8080
 	cdClone.Spec.Service.Timeout = "1m"
-	canary, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cdClone)
+	canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -85,7 +85,7 @@ func TestContourRouter_Reconcile(t *testing.T) {
 	}
 
 	// test headers update
-	cd, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -93,7 +93,7 @@ func TestContourRouter_Reconcile(t *testing.T) {
 	cdClone = cd.DeepCopy()
 	cdClone.Spec.CanaryAnalysis.Iterations = 5
 	cdClone.Spec.CanaryAnalysis.Match = newMockABTest().Spec.CanaryAnalysis.Match
-	canary, err = mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cdClone)
+	canary, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -146,7 +146,7 @@ func TestContourRouter_Routes(t *testing.T) {
 		t.Errorf("Got primary weight %v wanted %v", primary.Weight, 50)
 	}
 
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -165,7 +165,7 @@ func TestContourRouter_Routes(t *testing.T) {
 	cdClone := cd.DeepCopy()
 	cdClone.Spec.CanaryAnalysis.Iterations = 5
 	cdClone.Spec.CanaryAnalysis.Match = newMockABTest().Spec.CanaryAnalysis.Match
-	canary, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cdClone)
+	canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/router/istio_test.go b/pkg/router/istio_test.go
index 13f7a6a1..1e24b99e 100644
--- a/pkg/router/istio_test.go
+++ b/pkg/router/istio_test.go
@@ -48,7 +48,7 @@ func TestIstioRouter_Sync(t *testing.T) {
 	}
 
 	// test update
-	cd, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -57,7 +57,7 @@ func TestIstioRouter_Sync(t *testing.T) {
 	hosts := cdClone.Spec.Service.Hosts
 	hosts = append(hosts, "test.example.com")
 	cdClone.Spec.Service.Hosts = hosts
-	canary, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(cdClone)
+	canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/router/kubernetes_deployment_test.go b/pkg/router/kubernetes_deployment_test.go
index d02410d5..8268f3ec 100644
--- a/pkg/router/kubernetes_deployment_test.go
+++ b/pkg/router/kubernetes_deployment_test.go
@@ -69,7 +69,7 @@ func TestServiceRouter_Update(t *testing.T) {
 		t.Fatal(err.Error())
 	}
 
-	canary, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Get("podinfo", metav1.GetOptions{})
+	canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{})
 	if err != nil {
 		t.Fatal(err.Error())
 	}
@@ -77,7 +77,7 @@ func TestServiceRouter_Update(t *testing.T) {
 	canaryClone := canary.DeepCopy()
 	canaryClone.Spec.Service.PortName = "grpc"
 
-	c, err := mocks.flaggerClient.FlaggerV1alpha3().Canaries("default").Update(canaryClone)
+	c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(canaryClone)
 	if err != nil {
 		t.Fatal(err.Error())
 	}
diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go
index 0d0cae9e..fbe9fc43 100644
--- a/pkg/router/router_test.go
+++ b/pkg/router/router_test.go
@@ -11,7 +11,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/fake"
 
-	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3"
+	flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
 	istiov1alpha1 "github.com/weaveworks/flagger/pkg/apis/istio/common/v1alpha1"
 	istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
 	clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"