Repository: schemahero/schemahero
Pull request #123 (2020-03-21 15:54:44)

Cleaning up some leftover v1alpha2 bits


Patch:
diff --git a/Makefile b/Makefile
index a5166fef..22322455 100644
--- a/Makefile
+++ b/Makefile
@@ -87,6 +87,8 @@ vet:
 generate: controller-gen client-gen
 	$(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths=./pkg/apis/...
 	$(CLIENT_GEN) --output-package=github.com/schemahero/schemahero/pkg/client --clientset-name schemaheroclientset --input-base github.com/schemahero/schemahero/pkg/apis --input databases/v1alpha3 --input schemas/v1alpha3 -h ./hack/boilerplate.go.txt
+	@if [ -d "github.com/schemahero/schemahero/pkg/client" ]; then rm -rf pkg/client && mv github.com/schemahero/schemahero/pkg/client pkg && rm -rf github.com; fi
+	@## ^^ this doesn't appear right.  it produces the right results, but this rm and mv shouldn't be necessary...
 
 .PHONY: bin/schemahero
 bin/schemahero:
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/clientset.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/clientset.go
deleted file mode 100644
index 88dbc16a..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/clientset.go
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 schemaheroclientset
-
-import (
-	"fmt"
-
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3"
-	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3"
-	discovery "k8s.io/client-go/discovery"
-	rest "k8s.io/client-go/rest"
-	flowcontrol "k8s.io/client-go/util/flowcontrol"
-)
-
-type Interface interface {
-	Discovery() discovery.DiscoveryInterface
-	DatabasesV1alpha3() databasesv1alpha3.DatabasesV1alpha3Interface
-	SchemasV1alpha3() schemasv1alpha3.SchemasV1alpha3Interface
-}
-
-// Clientset contains the clients for groups. Each group has exactly one
-// version included in a Clientset.
-type Clientset struct {
-	*discovery.DiscoveryClient
-	databasesV1alpha3 *databasesv1alpha3.DatabasesV1alpha3Client
-	schemasV1alpha3   *schemasv1alpha3.SchemasV1alpha3Client
-}
-
-// DatabasesV1alpha3 retrieves the DatabasesV1alpha3Client
-func (c *Clientset) DatabasesV1alpha3() databasesv1alpha3.DatabasesV1alpha3Interface {
-	return c.databasesV1alpha3
-}
-
-// SchemasV1alpha3 retrieves the SchemasV1alpha3Client
-func (c *Clientset) SchemasV1alpha3() schemasv1alpha3.SchemasV1alpha3Interface {
-	return c.schemasV1alpha3
-}
-
-// Discovery retrieves the DiscoveryClient
-func (c *Clientset) Discovery() discovery.DiscoveryInterface {
-	if c == nil {
-		return nil
-	}
-	return c.DiscoveryClient
-}
-
-// NewForConfig creates a new Clientset for the given config.
-// If config's RateLimiter is not set and QPS and Burst are acceptable,
-// NewForConfig will generate a rate-limiter in configShallowCopy.
-func NewForConfig(c *rest.Config) (*Clientset, error) {
-	configShallowCopy := *c
-	if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
-		if configShallowCopy.Burst <= 0 {
-			return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
-		}
-		configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
-	}
-	var cs Clientset
-	var err error
-	cs.databasesV1alpha3, err = databasesv1alpha3.NewForConfig(&configShallowCopy)
-	if err != nil {
-		return nil, err
-	}
-	cs.schemasV1alpha3, err = schemasv1alpha3.NewForConfig(&configShallowCopy)
-	if err != nil {
-		return nil, err
-	}
-
-	cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
-	if err != nil {
-		return nil, err
-	}
-	return &cs, nil
-}
-
-// NewForConfigOrDie creates a new Clientset for the given config and
-// panics if there is an error in the config.
-func NewForConfigOrDie(c *rest.Config) *Clientset {
-	var cs Clientset
-	cs.databasesV1alpha3 = databasesv1alpha3.NewForConfigOrDie(c)
-	cs.schemasV1alpha3 = schemasv1alpha3.NewForConfigOrDie(c)
-
-	cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
-	return &cs
-}
-
-// New creates a new Clientset for the given RESTClient.
-func New(c rest.Interface) *Clientset {
-	var cs Clientset
-	cs.databasesV1alpha3 = databasesv1alpha3.New(c)
-	cs.schemasV1alpha3 = schemasv1alpha3.New(c)
-
-	cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
-	return &cs
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/doc.go
deleted file mode 100644
index 16f45b61..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 clientset.
-package schemaheroclientset
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/clientset_generated.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/clientset_generated.go
deleted file mode 100644
index d3e4b0d5..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/clientset_generated.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 (
-	clientset "github.com/schemahero/schemahero/pkg/client/schemaheroclientset"
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3"
-	fakedatabasesv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake"
-	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3"
-	fakeschemasv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/watch"
-	"k8s.io/client-go/discovery"
-	fakediscovery "k8s.io/client-go/discovery/fake"
-	"k8s.io/client-go/testing"
-)
-
-// NewSimpleClientset returns a clientset that will respond with the provided objects.
-// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
-// without applying any validations and/or defaults. It shouldn't be considered a replacement
-// for a real clientset and is mostly useful in simple unit tests.
-func NewSimpleClientset(objects ...runtime.Object) *Clientset {
-	o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
-	for _, obj := range objects {
-		if err := o.Add(obj); err != nil {
-			panic(err)
-		}
-	}
-
-	cs := &Clientset{tracker: o}
-	cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
-	cs.AddReactor("*", "*", testing.ObjectReaction(o))
-	cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
-		gvr := action.GetResource()
-		ns := action.GetNamespace()
-		watch, err := o.Watch(gvr, ns)
-		if err != nil {
-			return false, nil, err
-		}
-		return true, watch, nil
-	})
-
-	return cs
-}
-
-// Clientset implements clientset.Interface. Meant to be embedded into a
-// struct to get a default implementation. This makes faking out just the method
-// you want to test easier.
-type Clientset struct {
-	testing.Fake
-	discovery *fakediscovery.FakeDiscovery
-	tracker   testing.ObjectTracker
-}
-
-func (c *Clientset) Discovery() discovery.DiscoveryInterface {
-	return c.discovery
-}
-
-func (c *Clientset) Tracker() testing.ObjectTracker {
-	return c.tracker
-}
-
-var _ clientset.Interface = &Clientset{}
-
-// DatabasesV1alpha3 retrieves the DatabasesV1alpha3Client
-func (c *Clientset) DatabasesV1alpha3() databasesv1alpha3.DatabasesV1alpha3Interface {
-	return &fakedatabasesv1alpha3.FakeDatabasesV1alpha3{Fake: &c.Fake}
-}
-
-// SchemasV1alpha3 retrieves the SchemasV1alpha3Client
-func (c *Clientset) SchemasV1alpha3() schemasv1alpha3.SchemasV1alpha3Interface {
-	return &fakeschemasv1alpha3.FakeSchemasV1alpha3{Fake: &c.Fake}
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/doc.go
deleted file mode 100644
index 82828fec..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 fake clientset.
-package fake
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/register.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/register.go
deleted file mode 100644
index 3b581f99..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/fake/register.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 (
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	runtime "k8s.io/apimachinery/pkg/runtime"
-	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
-	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-)
-
-var scheme = runtime.NewScheme()
-var codecs = serializer.NewCodecFactory(scheme)
-var parameterCodec = runtime.NewParameterCodec(scheme)
-var localSchemeBuilder = runtime.SchemeBuilder{
-	databasesv1alpha3.AddToScheme,
-	schemasv1alpha3.AddToScheme,
-}
-
-// AddToScheme adds all types of this clientset into the given scheme. This allows composition
-// of clientsets, like in:
-//
-//   import (
-//     "k8s.io/client-go/kubernetes"
-//     clientsetscheme "k8s.io/client-go/kubernetes/scheme"
-//     aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
-//   )
-//
-//   kclientset, _ := kubernetes.NewForConfig(c)
-//   _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
-//
-// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
-// correctly.
-var AddToScheme = localSchemeBuilder.AddToScheme
-
-func init() {
-	v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
-	utilruntime.Must(AddToScheme(scheme))
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/doc.go
deleted file mode 100644
index b9e1b9ae..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 contains the scheme of the automatically generated clientset.
-package scheme
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/register.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/register.go
deleted file mode 100644
index 83dbb7ba..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme/register.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 scheme
-
-import (
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	runtime "k8s.io/apimachinery/pkg/runtime"
-	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	serializer "k8s.io/apimachinery/pkg/runtime/serializer"
-	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
-)
-
-var Scheme = runtime.NewScheme()
-var Codecs = serializer.NewCodecFactory(Scheme)
-var ParameterCodec = runtime.NewParameterCodec(Scheme)
-var localSchemeBuilder = runtime.SchemeBuilder{
-	databasesv1alpha3.AddToScheme,
-	schemasv1alpha3.AddToScheme,
-}
-
-// AddToScheme adds all types of this clientset into the given scheme. This allows composition
-// of clientsets, like in:
-//
-//   import (
-//     "k8s.io/client-go/kubernetes"
-//     clientsetscheme "k8s.io/client-go/kubernetes/scheme"
-//     aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
-//   )
-//
-//   kclientset, _ := kubernetes.NewForConfig(c)
-//   _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
-//
-// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
-// correctly.
-var AddToScheme = localSchemeBuilder.AddToScheme
-
-func init() {
-	v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
-	utilruntime.Must(AddToScheme(Scheme))
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/database.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/database.go
deleted file mode 100644
index 9ea4898c..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/database.go
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 (
-	"time"
-
-	v1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	scheme "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	rest "k8s.io/client-go/rest"
-)
-
-// DatabasesGetter has a method to return a DatabaseInterface.
-// A group's client should implement this interface.
-type DatabasesGetter interface {
-	Databases(namespace string) DatabaseInterface
-}
-
-// DatabaseInterface has methods to work with Database resources.
-type DatabaseInterface interface {
-	Create(*v1alpha3.Database) (*v1alpha3.Database, error)
-	Update(*v1alpha3.Database) (*v1alpha3.Database, error)
-	UpdateStatus(*v1alpha3.Database) (*v1alpha3.Database, error)
-	Delete(name string, options *v1.DeleteOptions) error
-	DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
-	Get(name string, options v1.GetOptions) (*v1alpha3.Database, error)
-	List(opts v1.ListOptions) (*v1alpha3.DatabaseList, error)
-	Watch(opts v1.ListOptions) (watch.Interface, error)
-	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Database, err error)
-	DatabaseExpansion
-}
-
-// databases implements DatabaseInterface
-type databases struct {
-	client rest.Interface
-	ns     string
-}
-
-// newDatabases returns a Databases
-func newDatabases(c *DatabasesV1alpha3Client, namespace string) *databases {
-	return &databases{
-		client: c.RESTClient(),
-		ns:     namespace,
-	}
-}
-
-// Get takes name of the database, and returns the corresponding database object, and an error if there is any.
-func (c *databases) Get(name string, options v1.GetOptions) (result *v1alpha3.Database, err error) {
-	result = &v1alpha3.Database{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("databases").
-		Name(name).
-		VersionedParams(&options, scheme.ParameterCodec).
-		Do().
-		Into(result)
-	return
-}
-
-// List takes label and field selectors, and returns the list of Databases that match those selectors.
-func (c *databases) List(opts v1.ListOptions) (result *v1alpha3.DatabaseList, err error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	result = &v1alpha3.DatabaseList{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("databases").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Do().
-		Into(result)
-	return
-}
-
-// Watch returns a watch.Interface that watches the requested databases.
-func (c *databases) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	opts.Watch = true
-	return c.client.Get().
-		Namespace(c.ns).
-		Resource("databases").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Watch()
-}
-
-// Create takes the representation of a database and creates it.  Returns the server's representation of the database, and an error, if there is any.
-func (c *databases) Create(database *v1alpha3.Database) (result *v1alpha3.Database, err error) {
-	result = &v1alpha3.Database{}
-	err = c.client.Post().
-		Namespace(c.ns).
-		Resource("databases").
-		Body(database).
-		Do().
-		Into(result)
-	return
-}
-
-// Update takes the representation of a database and updates it. Returns the server's representation of the database, and an error, if there is any.
-func (c *databases) Update(database *v1alpha3.Database) (result *v1alpha3.Database, err error) {
-	result = &v1alpha3.Database{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("databases").
-		Name(database.Name).
-		Body(database).
-		Do().
-		Into(result)
-	return
-}
-
-// UpdateStatus was generated because the type contains a Status member.
-// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
-
-func (c *databases) UpdateStatus(database *v1alpha3.Database) (result *v1alpha3.Database, err error) {
-	result = &v1alpha3.Database{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("databases").
-		Name(database.Name).
-		SubResource("status").
-		Body(database).
-		Do().
-		Into(result)
-	return
-}
-
-// Delete takes name of the database and deletes it. Returns an error if one occurs.
-func (c *databases) Delete(name string, options *v1.DeleteOptions) error {
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("databases").
-		Name(name).
-		Body(options).
-		Do().
-		Error()
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *databases) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	var timeout time.Duration
-	if listOptions.TimeoutSeconds != nil {
-		timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
-	}
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("databases").
-		VersionedParams(&listOptions, scheme.ParameterCodec).
-		Timeout(timeout).
-		Body(options).
-		Do().
-		Error()
-}
-
-// Patch applies the patch and returns the patched database.
-func (c *databases) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Database, err error) {
-	result = &v1alpha3.Database{}
-	err = c.client.Patch(pt).
-		Namespace(c.ns).
-		Resource("databases").
-		SubResource(subresources...).
-		Name(name).
-		Body(data).
-		Do().
-		Into(result)
-	return
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/databases_client.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/databases_client.go
deleted file mode 100644
index c68ca8a4..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/databases_client.go
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	"github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme"
-	rest "k8s.io/client-go/rest"
-)
-
-type DatabasesV1alpha3Interface interface {
-	RESTClient() rest.Interface
-	DatabasesGetter
-}
-
-// DatabasesV1alpha3Client is used to interact with features provided by the databases.schemahero.io group.
-type DatabasesV1alpha3Client struct {
-	restClient rest.Interface
-}
-
-func (c *DatabasesV1alpha3Client) Databases(namespace string) DatabaseInterface {
-	return newDatabases(c, namespace)
-}
-
-// NewForConfig creates a new DatabasesV1alpha3Client for the given config.
-func NewForConfig(c *rest.Config) (*DatabasesV1alpha3Client, error) {
-	config := *c
-	if err := setConfigDefaults(&config); err != nil {
-		return nil, err
-	}
-	client, err := rest.RESTClientFor(&config)
-	if err != nil {
-		return nil, err
-	}
-	return &DatabasesV1alpha3Client{client}, nil
-}
-
-// NewForConfigOrDie creates a new DatabasesV1alpha3Client for the given config and
-// panics if there is an error in the config.
-func NewForConfigOrDie(c *rest.Config) *DatabasesV1alpha3Client {
-	client, err := NewForConfig(c)
-	if err != nil {
-		panic(err)
-	}
-	return client
-}
-
-// New creates a new DatabasesV1alpha3Client for the given RESTClient.
-func New(c rest.Interface) *DatabasesV1alpha3Client {
-	return &DatabasesV1alpha3Client{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 *DatabasesV1alpha3Client) RESTClient() rest.Interface {
-	if c == nil {
-		return nil
-	}
-	return c.restClient
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/doc.go
deleted file mode 100644
index f9ad2888..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/doc.go
deleted file mode 100644
index d38bbc14..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_database.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_database.go
deleted file mode 100644
index fc0656ae..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_database.go
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	labels "k8s.io/apimachinery/pkg/labels"
-	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	testing "k8s.io/client-go/testing"
-)
-
-// FakeDatabases implements DatabaseInterface
-type FakeDatabases struct {
-	Fake *FakeDatabasesV1alpha3
-	ns   string
-}
-
-var databasesResource = schema.GroupVersionResource{Group: "databases.schemahero.io", Version: "v1alpha3", Resource: "databases"}
-
-var databasesKind = schema.GroupVersionKind{Group: "databases.schemahero.io", Version: "v1alpha3", Kind: "Database"}
-
-// Get takes name of the database, and returns the corresponding database object, and an error if there is any.
-func (c *FakeDatabases) Get(name string, options v1.GetOptions) (result *v1alpha3.Database, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(databasesResource, c.ns, name), &v1alpha3.Database{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Database), err
-}
-
-// List takes label and field selectors, and returns the list of Databases that match those selectors.
-func (c *FakeDatabases) List(opts v1.ListOptions) (result *v1alpha3.DatabaseList, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewListAction(databasesResource, databasesKind, c.ns, opts), &v1alpha3.DatabaseList{})
-
-	if obj == nil {
-		return nil, err
-	}
-
-	label, _, _ := testing.ExtractFromListOptions(opts)
-	if label == nil {
-		label = labels.Everything()
-	}
-	list := &v1alpha3.DatabaseList{ListMeta: obj.(*v1alpha3.DatabaseList).ListMeta}
-	for _, item := range obj.(*v1alpha3.DatabaseList).Items {
-		if label.Matches(labels.Set(item.Labels)) {
-			list.Items = append(list.Items, item)
-		}
-	}
-	return list, err
-}
-
-// Watch returns a watch.Interface that watches the requested databases.
-func (c *FakeDatabases) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	return c.Fake.
-		InvokesWatch(testing.NewWatchAction(databasesResource, c.ns, opts))
-
-}
-
-// Create takes the representation of a database and creates it.  Returns the server's representation of the database, and an error, if there is any.
-func (c *FakeDatabases) Create(database *v1alpha3.Database) (result *v1alpha3.Database, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(databasesResource, c.ns, database), &v1alpha3.Database{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Database), err
-}
-
-// Update takes the representation of a database and updates it. Returns the server's representation of the database, and an error, if there is any.
-func (c *FakeDatabases) Update(database *v1alpha3.Database) (result *v1alpha3.Database, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(databasesResource, c.ns, database), &v1alpha3.Database{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Database), 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 *FakeDatabases) UpdateStatus(database *v1alpha3.Database) (*v1alpha3.Database, error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateSubresourceAction(databasesResource, "status", c.ns, database), &v1alpha3.Database{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Database), err
-}
-
-// Delete takes name of the database and deletes it. Returns an error if one occurs.
-func (c *FakeDatabases) Delete(name string, options *v1.DeleteOptions) error {
-	_, err := c.Fake.
-		Invokes(testing.NewDeleteAction(databasesResource, c.ns, name), &v1alpha3.Database{})
-
-	return err
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *FakeDatabases) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	action := testing.NewDeleteCollectionAction(databasesResource, c.ns, listOptions)
-
-	_, err := c.Fake.Invokes(action, &v1alpha3.DatabaseList{})
-	return err
-}
-
-// Patch applies the patch and returns the patched database.
-func (c *FakeDatabases) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Database, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(databasesResource, c.ns, name, pt, data, subresources...), &v1alpha3.Database{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Database), err
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_databases_client.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_databases_client.go
deleted file mode 100644
index e953dbf2..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/fake/fake_databases_client.go
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3"
-	rest "k8s.io/client-go/rest"
-	testing "k8s.io/client-go/testing"
-)
-
-type FakeDatabasesV1alpha3 struct {
-	*testing.Fake
-}
-
-func (c *FakeDatabasesV1alpha3) Databases(namespace string) v1alpha3.DatabaseInterface {
-	return &FakeDatabases{c, namespace}
-}
-
-// RESTClient returns a RESTClient that is used to communicate
-// with API server by this client implementation.
-func (c *FakeDatabasesV1alpha3) RESTClient() rest.Interface {
-	var ret *rest.RESTClient
-	return ret
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/generated_expansion.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/generated_expansion.go
deleted file mode 100644
index b9ad1037..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3/generated_expansion.go
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 DatabaseExpansion interface{}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/doc.go
deleted file mode 100644
index f9ad2888..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/doc.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/doc.go
deleted file mode 100644
index d38bbc14..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/doc.go
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_migration.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_migration.go
deleted file mode 100644
index 1f1f3ffc..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_migration.go
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	labels "k8s.io/apimachinery/pkg/labels"
-	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	testing "k8s.io/client-go/testing"
-)
-
-// FakeMigrations implements MigrationInterface
-type FakeMigrations struct {
-	Fake *FakeSchemasV1alpha3
-	ns   string
-}
-
-var migrationsResource = schema.GroupVersionResource{Group: "schemas.schemahero.io", Version: "v1alpha3", Resource: "migrations"}
-
-var migrationsKind = schema.GroupVersionKind{Group: "schemas.schemahero.io", Version: "v1alpha3", Kind: "Migration"}
-
-// Get takes name of the migration, and returns the corresponding migration object, and an error if there is any.
-func (c *FakeMigrations) Get(name string, options v1.GetOptions) (result *v1alpha3.Migration, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(migrationsResource, c.ns, name), &v1alpha3.Migration{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Migration), err
-}
-
-// List takes label and field selectors, and returns the list of Migrations that match those selectors.
-func (c *FakeMigrations) List(opts v1.ListOptions) (result *v1alpha3.MigrationList, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewListAction(migrationsResource, migrationsKind, c.ns, opts), &v1alpha3.MigrationList{})
-
-	if obj == nil {
-		return nil, err
-	}
-
-	label, _, _ := testing.ExtractFromListOptions(opts)
-	if label == nil {
-		label = labels.Everything()
-	}
-	list := &v1alpha3.MigrationList{ListMeta: obj.(*v1alpha3.MigrationList).ListMeta}
-	for _, item := range obj.(*v1alpha3.MigrationList).Items {
-		if label.Matches(labels.Set(item.Labels)) {
-			list.Items = append(list.Items, item)
-		}
-	}
-	return list, err
-}
-
-// Watch returns a watch.Interface that watches the requested migrations.
-func (c *FakeMigrations) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	return c.Fake.
-		InvokesWatch(testing.NewWatchAction(migrationsResource, c.ns, opts))
-
-}
-
-// Create takes the representation of a migration and creates it.  Returns the server's representation of the migration, and an error, if there is any.
-func (c *FakeMigrations) Create(migration *v1alpha3.Migration) (result *v1alpha3.Migration, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(migrationsResource, c.ns, migration), &v1alpha3.Migration{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Migration), err
-}
-
-// Update takes the representation of a migration and updates it. Returns the server's representation of the migration, and an error, if there is any.
-func (c *FakeMigrations) Update(migration *v1alpha3.Migration) (result *v1alpha3.Migration, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(migrationsResource, c.ns, migration), &v1alpha3.Migration{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Migration), 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 *FakeMigrations) UpdateStatus(migration *v1alpha3.Migration) (*v1alpha3.Migration, error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateSubresourceAction(migrationsResource, "status", c.ns, migration), &v1alpha3.Migration{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Migration), err
-}
-
-// Delete takes name of the migration and deletes it. Returns an error if one occurs.
-func (c *FakeMigrations) Delete(name string, options *v1.DeleteOptions) error {
-	_, err := c.Fake.
-		Invokes(testing.NewDeleteAction(migrationsResource, c.ns, name), &v1alpha3.Migration{})
-
-	return err
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *FakeMigrations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	action := testing.NewDeleteCollectionAction(migrationsResource, c.ns, listOptions)
-
-	_, err := c.Fake.Invokes(action, &v1alpha3.MigrationList{})
-	return err
-}
-
-// Patch applies the patch and returns the patched migration.
-func (c *FakeMigrations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Migration, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(migrationsResource, c.ns, name, pt, data, subresources...), &v1alpha3.Migration{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Migration), err
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_schemas_client.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_schemas_client.go
deleted file mode 100644
index 58914de8..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_schemas_client.go
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3"
-	rest "k8s.io/client-go/rest"
-	testing "k8s.io/client-go/testing"
-)
-
-type FakeSchemasV1alpha3 struct {
-	*testing.Fake
-}
-
-func (c *FakeSchemasV1alpha3) Migrations(namespace string) v1alpha3.MigrationInterface {
-	return &FakeMigrations{c, namespace}
-}
-
-func (c *FakeSchemasV1alpha3) Tables(namespace string) v1alpha3.TableInterface {
-	return &FakeTables{c, namespace}
-}
-
-// RESTClient returns a RESTClient that is used to communicate
-// with API server by this client implementation.
-func (c *FakeSchemasV1alpha3) RESTClient() rest.Interface {
-	var ret *rest.RESTClient
-	return ret
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_table.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_table.go
deleted file mode 100644
index b4c438ae..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/fake/fake_table.go
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	labels "k8s.io/apimachinery/pkg/labels"
-	schema "k8s.io/apimachinery/pkg/runtime/schema"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	testing "k8s.io/client-go/testing"
-)
-
-// FakeTables implements TableInterface
-type FakeTables struct {
-	Fake *FakeSchemasV1alpha3
-	ns   string
-}
-
-var tablesResource = schema.GroupVersionResource{Group: "schemas.schemahero.io", Version: "v1alpha3", Resource: "tables"}
-
-var tablesKind = schema.GroupVersionKind{Group: "schemas.schemahero.io", Version: "v1alpha3", Kind: "Table"}
-
-// Get takes name of the table, and returns the corresponding table object, and an error if there is any.
-func (c *FakeTables) Get(name string, options v1.GetOptions) (result *v1alpha3.Table, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewGetAction(tablesResource, c.ns, name), &v1alpha3.Table{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Table), err
-}
-
-// List takes label and field selectors, and returns the list of Tables that match those selectors.
-func (c *FakeTables) List(opts v1.ListOptions) (result *v1alpha3.TableList, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewListAction(tablesResource, tablesKind, c.ns, opts), &v1alpha3.TableList{})
-
-	if obj == nil {
-		return nil, err
-	}
-
-	label, _, _ := testing.ExtractFromListOptions(opts)
-	if label == nil {
-		label = labels.Everything()
-	}
-	list := &v1alpha3.TableList{ListMeta: obj.(*v1alpha3.TableList).ListMeta}
-	for _, item := range obj.(*v1alpha3.TableList).Items {
-		if label.Matches(labels.Set(item.Labels)) {
-			list.Items = append(list.Items, item)
-		}
-	}
-	return list, err
-}
-
-// Watch returns a watch.Interface that watches the requested tables.
-func (c *FakeTables) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	return c.Fake.
-		InvokesWatch(testing.NewWatchAction(tablesResource, c.ns, opts))
-
-}
-
-// Create takes the representation of a table and creates it.  Returns the server's representation of the table, and an error, if there is any.
-func (c *FakeTables) Create(table *v1alpha3.Table) (result *v1alpha3.Table, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewCreateAction(tablesResource, c.ns, table), &v1alpha3.Table{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Table), err
-}
-
-// Update takes the representation of a table and updates it. Returns the server's representation of the table, and an error, if there is any.
-func (c *FakeTables) Update(table *v1alpha3.Table) (result *v1alpha3.Table, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateAction(tablesResource, c.ns, table), &v1alpha3.Table{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Table), 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 *FakeTables) UpdateStatus(table *v1alpha3.Table) (*v1alpha3.Table, error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewUpdateSubresourceAction(tablesResource, "status", c.ns, table), &v1alpha3.Table{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Table), err
-}
-
-// Delete takes name of the table and deletes it. Returns an error if one occurs.
-func (c *FakeTables) Delete(name string, options *v1.DeleteOptions) error {
-	_, err := c.Fake.
-		Invokes(testing.NewDeleteAction(tablesResource, c.ns, name), &v1alpha3.Table{})
-
-	return err
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *FakeTables) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	action := testing.NewDeleteCollectionAction(tablesResource, c.ns, listOptions)
-
-	_, err := c.Fake.Invokes(action, &v1alpha3.TableList{})
-	return err
-}
-
-// Patch applies the patch and returns the patched table.
-func (c *FakeTables) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Table, err error) {
-	obj, err := c.Fake.
-		Invokes(testing.NewPatchSubresourceAction(tablesResource, c.ns, name, pt, data, subresources...), &v1alpha3.Table{})
-
-	if obj == nil {
-		return nil, err
-	}
-	return obj.(*v1alpha3.Table), err
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/generated_expansion.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/generated_expansion.go
deleted file mode 100644
index a9034b27..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/generated_expansion.go
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 MigrationExpansion interface{}
-
-type TableExpansion interface{}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/migration.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/migration.go
deleted file mode 100644
index 899a689f..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/migration.go
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 (
-	"time"
-
-	v1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	scheme "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	rest "k8s.io/client-go/rest"
-)
-
-// MigrationsGetter has a method to return a MigrationInterface.
-// A group's client should implement this interface.
-type MigrationsGetter interface {
-	Migrations(namespace string) MigrationInterface
-}
-
-// MigrationInterface has methods to work with Migration resources.
-type MigrationInterface interface {
-	Create(*v1alpha3.Migration) (*v1alpha3.Migration, error)
-	Update(*v1alpha3.Migration) (*v1alpha3.Migration, error)
-	UpdateStatus(*v1alpha3.Migration) (*v1alpha3.Migration, error)
-	Delete(name string, options *v1.DeleteOptions) error
-	DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
-	Get(name string, options v1.GetOptions) (*v1alpha3.Migration, error)
-	List(opts v1.ListOptions) (*v1alpha3.MigrationList, error)
-	Watch(opts v1.ListOptions) (watch.Interface, error)
-	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Migration, err error)
-	MigrationExpansion
-}
-
-// migrations implements MigrationInterface
-type migrations struct {
-	client rest.Interface
-	ns     string
-}
-
-// newMigrations returns a Migrations
-func newMigrations(c *SchemasV1alpha3Client, namespace string) *migrations {
-	return &migrations{
-		client: c.RESTClient(),
-		ns:     namespace,
-	}
-}
-
-// Get takes name of the migration, and returns the corresponding migration object, and an error if there is any.
-func (c *migrations) Get(name string, options v1.GetOptions) (result *v1alpha3.Migration, err error) {
-	result = &v1alpha3.Migration{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("migrations").
-		Name(name).
-		VersionedParams(&options, scheme.ParameterCodec).
-		Do().
-		Into(result)
-	return
-}
-
-// List takes label and field selectors, and returns the list of Migrations that match those selectors.
-func (c *migrations) List(opts v1.ListOptions) (result *v1alpha3.MigrationList, err error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	result = &v1alpha3.MigrationList{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("migrations").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Do().
-		Into(result)
-	return
-}
-
-// Watch returns a watch.Interface that watches the requested migrations.
-func (c *migrations) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	opts.Watch = true
-	return c.client.Get().
-		Namespace(c.ns).
-		Resource("migrations").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Watch()
-}
-
-// Create takes the representation of a migration and creates it.  Returns the server's representation of the migration, and an error, if there is any.
-func (c *migrations) Create(migration *v1alpha3.Migration) (result *v1alpha3.Migration, err error) {
-	result = &v1alpha3.Migration{}
-	err = c.client.Post().
-		Namespace(c.ns).
-		Resource("migrations").
-		Body(migration).
-		Do().
-		Into(result)
-	return
-}
-
-// Update takes the representation of a migration and updates it. Returns the server's representation of the migration, and an error, if there is any.
-func (c *migrations) Update(migration *v1alpha3.Migration) (result *v1alpha3.Migration, err error) {
-	result = &v1alpha3.Migration{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("migrations").
-		Name(migration.Name).
-		Body(migration).
-		Do().
-		Into(result)
-	return
-}
-
-// UpdateStatus was generated because the type contains a Status member.
-// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
-
-func (c *migrations) UpdateStatus(migration *v1alpha3.Migration) (result *v1alpha3.Migration, err error) {
-	result = &v1alpha3.Migration{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("migrations").
-		Name(migration.Name).
-		SubResource("status").
-		Body(migration).
-		Do().
-		Into(result)
-	return
-}
-
-// Delete takes name of the migration and deletes it. Returns an error if one occurs.
-func (c *migrations) Delete(name string, options *v1.DeleteOptions) error {
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("migrations").
-		Name(name).
-		Body(options).
-		Do().
-		Error()
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *migrations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	var timeout time.Duration
-	if listOptions.TimeoutSeconds != nil {
-		timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
-	}
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("migrations").
-		VersionedParams(&listOptions, scheme.ParameterCodec).
-		Timeout(timeout).
-		Body(options).
-		Do().
-		Error()
-}
-
-// Patch applies the patch and returns the patched migration.
-func (c *migrations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Migration, err error) {
-	result = &v1alpha3.Migration{}
-	err = c.client.Patch(pt).
-		Namespace(c.ns).
-		Resource("migrations").
-		SubResource(subresources...).
-		Name(name).
-		Body(data).
-		Do().
-		Into(result)
-	return
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/schemas_client.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/schemas_client.go
deleted file mode 100644
index 1758d928..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/schemas_client.go
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	"github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme"
-	rest "k8s.io/client-go/rest"
-)
-
-type SchemasV1alpha3Interface interface {
-	RESTClient() rest.Interface
-	MigrationsGetter
-	TablesGetter
-}
-
-// SchemasV1alpha3Client is used to interact with features provided by the schemas.schemahero.io group.
-type SchemasV1alpha3Client struct {
-	restClient rest.Interface
-}
-
-func (c *SchemasV1alpha3Client) Migrations(namespace string) MigrationInterface {
-	return newMigrations(c, namespace)
-}
-
-func (c *SchemasV1alpha3Client) Tables(namespace string) TableInterface {
-	return newTables(c, namespace)
-}
-
-// NewForConfig creates a new SchemasV1alpha3Client for the given config.
-func NewForConfig(c *rest.Config) (*SchemasV1alpha3Client, error) {
-	config := *c
-	if err := setConfigDefaults(&config); err != nil {
-		return nil, err
-	}
-	client, err := rest.RESTClientFor(&config)
-	if err != nil {
-		return nil, err
-	}
-	return &SchemasV1alpha3Client{client}, nil
-}
-
-// NewForConfigOrDie creates a new SchemasV1alpha3Client for the given config and
-// panics if there is an error in the config.
-func NewForConfigOrDie(c *rest.Config) *SchemasV1alpha3Client {
-	client, err := NewForConfig(c)
-	if err != nil {
-		panic(err)
-	}
-	return client
-}
-
-// New creates a new SchemasV1alpha3Client for the given RESTClient.
-func New(c rest.Interface) *SchemasV1alpha3Client {
-	return &SchemasV1alpha3Client{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 *SchemasV1alpha3Client) RESTClient() rest.Interface {
-	if c == nil {
-		return nil
-	}
-	return c.restClient
-}
diff --git a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/table.go b/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/table.go
deleted file mode 100644
index d2997860..00000000
--- a/github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3/table.go
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-Copyright 2019 Replicated, Inc.
-
-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 (
-	"time"
-
-	v1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
-	scheme "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/scheme"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	types "k8s.io/apimachinery/pkg/types"
-	watch "k8s.io/apimachinery/pkg/watch"
-	rest "k8s.io/client-go/rest"
-)
-
-// TablesGetter has a method to return a TableInterface.
-// A group's client should implement this interface.
-type TablesGetter interface {
-	Tables(namespace string) TableInterface
-}
-
-// TableInterface has methods to work with Table resources.
-type TableInterface interface {
-	Create(*v1alpha3.Table) (*v1alpha3.Table, error)
-	Update(*v1alpha3.Table) (*v1alpha3.Table, error)
-	UpdateStatus(*v1alpha3.Table) (*v1alpha3.Table, error)
-	Delete(name string, options *v1.DeleteOptions) error
-	DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error
-	Get(name string, options v1.GetOptions) (*v1alpha3.Table, error)
-	List(opts v1.ListOptions) (*v1alpha3.TableList, error)
-	Watch(opts v1.ListOptions) (watch.Interface, error)
-	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Table, err error)
-	TableExpansion
-}
-
-// tables implements TableInterface
-type tables struct {
-	client rest.Interface
-	ns     string
-}
-
-// newTables returns a Tables
-func newTables(c *SchemasV1alpha3Client, namespace string) *tables {
-	return &tables{
-		client: c.RESTClient(),
-		ns:     namespace,
-	}
-}
-
-// Get takes name of the table, and returns the corresponding table object, and an error if there is any.
-func (c *tables) Get(name string, options v1.GetOptions) (result *v1alpha3.Table, err error) {
-	result = &v1alpha3.Table{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("tables").
-		Name(name).
-		VersionedParams(&options, scheme.ParameterCodec).
-		Do().
-		Into(result)
-	return
-}
-
-// List takes label and field selectors, and returns the list of Tables that match those selectors.
-func (c *tables) List(opts v1.ListOptions) (result *v1alpha3.TableList, err error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	result = &v1alpha3.TableList{}
-	err = c.client.Get().
-		Namespace(c.ns).
-		Resource("tables").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Do().
-		Into(result)
-	return
-}
-
-// Watch returns a watch.Interface that watches the requested tables.
-func (c *tables) Watch(opts v1.ListOptions) (watch.Interface, error) {
-	var timeout time.Duration
-	if opts.TimeoutSeconds != nil {
-		timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
-	}
-	opts.Watch = true
-	return c.client.Get().
-		Namespace(c.ns).
-		Resource("tables").
-		VersionedParams(&opts, scheme.ParameterCodec).
-		Timeout(timeout).
-		Watch()
-}
-
-// Create takes the representation of a table and creates it.  Returns the server's representation of the table, and an error, if there is any.
-func (c *tables) Create(table *v1alpha3.Table) (result *v1alpha3.Table, err error) {
-	result = &v1alpha3.Table{}
-	err = c.client.Post().
-		Namespace(c.ns).
-		Resource("tables").
-		Body(table).
-		Do().
-		Into(result)
-	return
-}
-
-// Update takes the representation of a table and updates it. Returns the server's representation of the table, and an error, if there is any.
-func (c *tables) Update(table *v1alpha3.Table) (result *v1alpha3.Table, err error) {
-	result = &v1alpha3.Table{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("tables").
-		Name(table.Name).
-		Body(table).
-		Do().
-		Into(result)
-	return
-}
-
-// UpdateStatus was generated because the type contains a Status member.
-// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
-
-func (c *tables) UpdateStatus(table *v1alpha3.Table) (result *v1alpha3.Table, err error) {
-	result = &v1alpha3.Table{}
-	err = c.client.Put().
-		Namespace(c.ns).
-		Resource("tables").
-		Name(table.Name).
-		SubResource("status").
-		Body(table).
-		Do().
-		Into(result)
-	return
-}
-
-// Delete takes name of the table and deletes it. Returns an error if one occurs.
-func (c *tables) Delete(name string, options *v1.DeleteOptions) error {
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("tables").
-		Name(name).
-		Body(options).
-		Do().
-		Error()
-}
-
-// DeleteCollection deletes a collection of objects.
-func (c *tables) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error {
-	var timeout time.Duration
-	if listOptions.TimeoutSeconds != nil {
-		timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second
-	}
-	return c.client.Delete().
-		Namespace(c.ns).
-		Resource("tables").
-		VersionedParams(&listOptions, scheme.ParameterCodec).
-		Timeout(timeout).
-		Body(options).
-		Do().
-		Error()
-}
-
-// Patch applies the patch and returns the patched table.
-func (c *tables) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha3.Table, err error) {
-	result = &v1alpha3.Table{}
-	err = c.client.Patch(pt).
-		Namespace(c.ns).
-		Resource("tables").
-		SubResource(subresources...).
-		Name(name).
-		Body(data).
-		Do().
-		Into(result)
-	return
-}
diff --git a/pkg/cli/schemaherocli/watch.go b/pkg/cli/schemaherocli/watch.go
deleted file mode 100644
index 44096e62..00000000
--- a/pkg/cli/schemaherocli/watch.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package schemaherocli
-
-import (
-	"github.com/schemahero/schemahero/pkg/watcher"
-
-	"github.com/spf13/cobra"
-	"github.com/spf13/viper"
-)
-
-func Watch() *cobra.Command {
-	cmd := &cobra.Command{
-		Use:   "watch",
-		Short: "watch a database for any changes",
-		Long:  `...`,
-		PreRun: func(cmd *cobra.Command, args []string) {
-			viper.BindPFlags(cmd.Flags())
-		},
-		RunE: func(cmd *cobra.Command, args []string) error {
-			w := watcher.NewWatcher()
-			return w.RunSync()
-		},
-	}
-
-	cmd.Flags().String("driver", "", "name of the database driver to use")
-	cmd.Flags().String("uri", "", "connection string uri")
-	cmd.Flags().String("namespace", "default", "namespace of the spawning object")
-	cmd.Flags().String("instance", "", "instance name of the spawning object")
-
-	cmd.MarkFlagRequired("driver")
-	cmd.MarkFlagRequired("uri")
-	cmd.MarkFlagRequired("namespace")
-	cmd.MarkFlagRequired("instance")
-
-	return cmd
-}
diff --git a/pkg/controller/database/database_controller.go b/pkg/controller/database/database_controller.go
index fd6fd07a..33ca3f2e 100644
--- a/pkg/controller/database/database_controller.go
+++ b/pkg/controller/database/database_controller.go
@@ -18,17 +18,12 @@ package database
 
 import (
 	"context"
-	goerrors "errors"
-	"fmt"
 
 	"github.com/pkg/errors"
 	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
 	"github.com/schemahero/schemahero/pkg/logger"
 	"go.uber.org/zap"
-	corev1 "k8s.io/api/core/v1"
-	kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/types"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -94,16 +89,6 @@ func (r *ReconcileDatabase) Reconcile(request reconcile.Request) (reconcile.Resu
 
 	// TODO add watches back in if we need them.  Today they aren't used for anything
 
-	if instance.Spec.Connection.Postgres != nil {
-		if err = r.ensurePostgresWatch(instance); err != nil {
-			return reconcile.Result{}, err
-		}
-	} else if instance.Spec.Connection.Mysql != nil {
-		if err := r.ensureMysqlWatch(instance); err != nil {
-			return reconcile.Result{}, err
-		}
-	}
-
 	return reconcile.Result{}, nil
 }
 
@@ -116,33 +101,3 @@ func (r *ReconcileDatabase) getInstance(request reconcile.Request) (*databasesv1
 
 	return instance, nil
 }
-
-func (r *ReconcileDatabase) readConnectionURI(namespace string, valueOrValueFrom databasesv1alpha3.ValueOrValueFrom) (string, error) {
-	if valueOrValueFrom.Value != "" {
-		return valueOrValueFrom.Value, nil
-	}
-
-	if valueOrValueFrom.ValueFrom == nil {
-		return "", goerrors.New("value and valueFrom cannot both be nil/empty")
-	}
-
-	if valueOrValueFrom.ValueFrom.SecretKeyRef != nil {
-		secret := corev1.Secret{}
-		secretNamespacedName := types.NamespacedName{
-			Name:      valueOrValueFrom.ValueFrom.SecretKeyRef.Name,
-			Namespace: namespace,
-		}
-
-		if err := r.Get(context.TODO(), secretNamespacedName, &secret); err != nil {
-			if kuberneteserrors.IsNotFound(err) {
-				return "", fmt.Errorf("database secret (%s/%s) not found", secretNamespacedName.Namespace, secretNamespacedName.Name)
-			} else {
-				return "", err
-			}
-		}
-
-		return string(secret.Data[valueOrValueFrom.ValueFrom.SecretKeyRef.Key]), nil
-	}
-
-	return "", goerrors.New("unable to find supported valueFrom")
-}
diff --git a/pkg/controller/database/mysql.go b/pkg/controller/database/mysql.go
deleted file mode 100644
index 748d4a0f..00000000
--- a/pkg/controller/database/mysql.go
+++ /dev/null
@@ -1,95 +0,0 @@
-package database
-
-import (
-	"context"
-	"fmt"
-
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	appsv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-func (r *ReconcileDatabase) ensureMysqlWatch(instance *databasesv1alpha3.Database) error {
-	imageName := "schemahero/schemahero:alpha"
-	nodeSelector := make(map[string]string)
-
-	if instance.Spec.SchemaHero != nil {
-		if instance.Spec.SchemaHero.Image != "" {
-			imageName = instance.Spec.SchemaHero.Image
-		}
-
-		nodeSelector = instance.Spec.SchemaHero.NodeSelector
-	}
-
-	driver := "mysql"
-	connectionURI, err := r.readConnectionURI(instance.Namespace, instance.Spec.Connection.Mysql.URI)
-	if err != nil {
-		return err
-	}
-
-	// The pod created by this deployment will require access to the database object
-	// defined in instance.Name. By default, RBAC will likely prevent this, so we need
-	// to create a role and assign a service account to to pod
-	if err := r.ensureWatchRBAC(instance); err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	deploy := &appsv1.Deployment{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      instance.Name + "-watch",
-			Namespace: instance.Namespace,
-		},
-		Spec: appsv1.DeploymentSpec{
-			Selector: &metav1.LabelSelector{
-				MatchLabels: map[string]string{"deployment": instance.Name + "watch"},
-			},
-			Template: corev1.PodTemplateSpec{
-				ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "watch"}},
-				Spec: corev1.PodSpec{
-					NodeSelector:       nodeSelector,
-					ServiceAccountName: instance.Name,
-					Containers: []corev1.Container{
-						{
-							Name:            "schemahero",
-							Image:           imageName,
-							ImagePullPolicy: corev1.PullAlways,
-							Args: []string{
-								"watch",
-								"--driver",
-								driver,
-								"--uri",
-								connectionURI,
-								"--namespace",
-								instance.Namespace,
-								"--instance",
-								instance.Name,
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil {
-		return err
-	}
-
-	found := &appsv1.Deployment{}
-	err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found)
-	if err != nil && errors.IsNotFound(err) {
-		err = r.Create(context.Background(), deploy)
-		return err
-	} else if err != nil {
-		return err
-	}
-
-	// TODO diff and update!
-
-	return nil
-}
diff --git a/pkg/controller/database/postgres.go b/pkg/controller/database/postgres.go
deleted file mode 100644
index 43eacb4a..00000000
--- a/pkg/controller/database/postgres.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package database
-
-import (
-	"context"
-	"fmt"
-
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	appsv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-func (r *ReconcileDatabase) ensurePostgresWatch(instance *databasesv1alpha3.Database) error {
-	imageName := "schemahero/schemahero:alpha"
-	nodeSelector := make(map[string]string)
-
-	if instance.Spec.SchemaHero != nil {
-		if instance.Spec.SchemaHero.Image != "" {
-			imageName = instance.Spec.SchemaHero.Image
-		}
-
-		nodeSelector = instance.Spec.SchemaHero.NodeSelector
-	}
-
-	driver := "postgres"
-	connectionURI, err := r.readConnectionURI(instance.Namespace, instance.Spec.Connection.Postgres.URI)
-	if err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	// The pod created by this deployment will require access to the database object
-	// defined in instance.Name. By default, RBAC will likely prevent this, so we need
-	// to create a role and assign a service account to to pod
-	if err := r.ensureWatchRBAC(instance); err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	deploy := &appsv1.Deployment{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      instance.Name + "-watch",
-			Namespace: instance.Namespace,
-		},
-		Spec: appsv1.DeploymentSpec{
-			Selector: &metav1.LabelSelector{
-				MatchLabels: map[string]string{"deployment": instance.Name + "watch"},
-			},
-			Template: corev1.PodTemplateSpec{
-				ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "watch"}},
-				Spec: corev1.PodSpec{
-					NodeSelector:       nodeSelector,
-					ServiceAccountName: instance.Name,
-					Containers: []corev1.Container{
-						{
-							Name:            "schemahero",
-							Image:           imageName,
-							ImagePullPolicy: corev1.PullAlways,
-							Args: []string{
-								"watch",
-								"--driver",
-								driver,
-								"--uri",
-								connectionURI,
-								"--namespace",
-								instance.Namespace,
-								"--instance",
-								instance.Name,
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-
-	if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil {
-		return err
-	}
-
-	found := &appsv1.Deployment{}
-	err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found)
-	if err != nil && errors.IsNotFound(err) {
-		err = r.Create(context.Background(), deploy)
-		return err
-	} else if err != nil {
-		return err
-	}
-
-	// TODO diff and update!
-
-	return nil
-}
diff --git a/pkg/controller/database/rbac.go b/pkg/controller/database/rbac.go
deleted file mode 100644
index 1aa86fd5..00000000
--- a/pkg/controller/database/rbac.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package database
-
-import (
-	"context"
-	"fmt"
-
-	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
-	corev1 "k8s.io/api/core/v1"
-	rbacv1 "k8s.io/api/rbac/v1"
-	kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-func (r *ReconcileDatabase) ensureWatchRBAC(instance *databasesv1alpha3.Database) error {
-	err := r.ensureRoleInNamespaceForInstance(instance)
-	if err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	err = r.ensureRoleBindingInNamespaceForInstance(instance)
-	if err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	err = r.ensureServiceAccountInNamespaceForInstance(instance)
-	if err != nil {
-		fmt.Printf("%#v\n", err)
-		return err
-	}
-
-	return nil
-}
-
-func (r *ReconcileDatabase) ensureRoleInNamespaceForInstance(instance *databasesv1alpha3.Database) error {
-	namespacedName := types.NamespacedName{
-		Name:      instance.Name,
-		Namespace: instance.Namespace,
-	}
-	existing := rbacv1.Role{}
-
-	err := r.Get(context.TODO(), namespacedName, &existing)
-	if err != nil {
-		if kuberneteserrors.IsNotFound(err) {
-			role := getRoleSpecForInstance(context.TODO(), namespacedName)
-			if err := r.Create(context.Background(), role); err != nil {
-				return err
-			}
-			if err := controllerutil.SetControllerReference(instance, role, r.scheme); err != nil {
-				return err
-			}
-		} else {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (r *ReconcileDatabase) ensureRoleBindingInNamespaceForInstance(instance *databasesv1alpha3.Database) error {
-	namespacedName := types.NamespacedName{
-		Name:      instance.Name,
-		Namespace: instance.Namespace,
-	}
-	existing := rbacv1.RoleBinding{}
-
-	err := r.Get(context.TODO(), namespacedName, &existing)
-	if err != nil {
-		if kuberneteserrors.IsNotFound(err) {
-			roleBinding := getRoleBindingSpecForInstance(context.TODO(), namespacedName)
-			if err := r.Create(context.Background(), roleBinding); err != nil {
-				return err
-			}
-			if err := controllerutil.SetControllerReference(instance, roleBinding, r.scheme); err != nil {
-				return err
-			}
-		} else {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (r *ReconcileDatabase) ensureServiceAccountInNamespaceForInstance(instance *databasesv1alpha3.Database) error {
-	namespacedName := types.NamespacedName{
-		Name:      instance.Name,
-		Namespace: instance.Namespace,
-	}
-	existing := corev1.ServiceAccount{}
-
-	err := r.Get(context.TODO(), namespacedName, &existing)
-	if err != nil {
-		if kuberneteserrors.IsNotFound(err) {
-			serviceAccount := getServiceAccountSpecForInstance(context.TODO(), namespacedName)
-			if err := r.Create(context.Background(), serviceAccount); err != nil {
-				return err
-			}
-			if err := controllerutil.SetControllerReference(instance, serviceAccount, r.scheme); err != nil {
-				return err
-			}
-		} else {
-			return err
-		}
-	}
-
-	return nil
-}
-
-func getRoleSpecForInstance(ctx context.Context, namespacedName types.NamespacedName) *rbacv1.Role {
-	role := rbacv1.Role{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: "v1",
-			Kind:       "Role",
-		},
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      namespacedName.Name,
-			Namespace: namespacedName.Namespace,
-		},
-		Rules: []rbacv1.PolicyRule{
-			{
-				APIGroups:     []string{"databases.schemahero.io"},
-				Resources:     []string{"databases"},
-				ResourceNames: []string{namespacedName.Name},
-				Verbs:         metav1.Verbs{"get", "list", "update"},
-			},
-		},
-	}
-
-	return &role
-}
-
-func getRoleBindingSpecForInstance(ctx context.Context, namespacedName types.NamespacedName) *rbacv1.RoleBinding {
-	roleBinding := rbacv1.RoleBinding{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: "v1",
-			Kind:       "RoleBinding",
-		},
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      namespacedName.Name,
-			Namespace: namespacedName.Namespace,
-		},
-		Subjects: []rbacv1.Subject{
-			{
-				Kind:      "ServiceAccount",
-				Name:      namespacedName.Name,
-				Namespace: namespacedName.Namespace,
-			},
-		},
-		RoleRef: rbacv1.RoleRef{
-			APIGroup: "rbac.authorization.k8s.io",
-			Kind:     "Role",
-			Name:     namespacedName.Name,
-		},
-	}
-
-	return &roleBinding
-}
-
-func getServiceAccountSpecForInstance(ctx context.Context, namespacedName types.NamespacedName) *corev1.ServiceAccount {
-	serviceAccount := corev1.ServiceAccount{
-		TypeMeta: metav1.TypeMeta{
-			APIVersion: "v1",
-			Kind:       "ServiceAccount",
-		},
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      namespacedName.Name,
-			Namespace: namespacedName.Namespace,
-		},
-	}
-
-	return &serviceAccount
-}
diff --git a/pkg/controller/migration/lookup.go b/pkg/controller/migration/lookup.go
new file mode 100644
index 00000000..2401c727
--- /dev/null
+++ b/pkg/controller/migration/lookup.go
@@ -0,0 +1,49 @@
+package migration
+
+import (
+	"github.com/pkg/errors"
+	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
+	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	databasesclientv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3"
+	schemasclientv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client/config"
+)
+
+func tableFromMigration(migration *schemasv1alpha3.Migration) (*schemasv1alpha3.Table, error) {
+	cfg, err := config.GetConfig()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to get config")
+	}
+
+	schemasClient, err := schemasclientv1alpha3.NewForConfig(cfg)
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to create schemas client")
+	}
+
+	table, err := schemasClient.Tables(migration.Spec.TableNamespace).Get(migration.Spec.TableName, metav1.GetOptions{})
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to get table")
+	}
+
+	return table, nil
+}
+
+func databaseFromTable(table *schemasv1alpha3.Table) (*databasesv1alpha3.Database, error) {
+	cfg, err := config.GetConfig()
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to get config")
+	}
+
+	databasesClient, err := databasesclientv1alpha3.NewForConfig(cfg)
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to create databases client")
+	}
+
+	database, err := databasesClient.Databases(table.Namespace).Get(table.Spec.Database, metav1.GetOptions{})
+	if err != nil {
+		return nil, errors.Wrap(err, "failed to get database")
+	}
+
+	return database, nil
+}
diff --git a/pkg/controller/migration/migration_controller.go b/pkg/controller/migration/migration_controller.go
index 3d2c844b..2b3925b5 100644
--- a/pkg/controller/migration/migration_controller.go
+++ b/pkg/controller/migration/migration_controller.go
@@ -18,14 +18,18 @@ package migration
 
 import (
 	"context"
+	"time"
 
 	"github.com/pkg/errors"
 	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
 	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	"github.com/schemahero/schemahero/pkg/logger"
 	corev1 "k8s.io/api/core/v1"
 	kuberneteserrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
+	kubeinformers "k8s.io/client-go/informers"
+	"k8s.io/client-go/kubernetes"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller"
 	"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -55,10 +59,29 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
 
 	// Watch for changes to Migration
 	err = c.Watch(&source.Kind{Type: &schemasv1alpha3.Migration{}}, &handler.EnqueueRequestForObject{})
+	if err != nil {
+		return errors.Wrap(err, "failed to start watch on migrations")
+	}
+
+	// Migrations are executed as pods, so we should also watch pod lifecycle
+	generatedClient := kubernetes.NewForConfigOrDie(mgr.GetConfig())
+	generatedInformers := kubeinformers.NewSharedInformerFactory(generatedClient, time.Minute)
+	err = mgr.Add(manager.RunnableFunc(func(s <-chan struct{}) error {
+		generatedInformers.Start(s)
+		<-s
+		return nil
+	}))
 	if err != nil {
 		return err
 	}
 
+	err = c.Watch(&source.Informer{
+		Informer: generatedInformers.Core().V1().Pods().Informer(),
+	}, &handler.EnqueueRequestForObject{})
+	if err != nil {
+		return errors.Wrap(err, "failed to start watch on pods")
+	}
+
 	return nil
 }
 
@@ -78,23 +101,45 @@ type ReconcileMigration struct {
 // +kubebuilder:rbac:groups=schemas.schemahero.io,resources=migrations,verbs=get;list;watch;create;update;patch;delete
 // +kubebuilder:rbac:groups=schemas.schemahero.io,resources=migrations/status,verbs=get;update;patch
 func (r *ReconcileMigration) Reconcile(request reconcile.Request) (reconcile.Result, error) {
-	// Fetch the Migration instance
-	instance := &schemasv1alpha3.Migration{}
-	err := r.Get(context.TODO(), request.NamespacedName, instance)
-	if err != nil {
-		if kuberneteserrors.IsNotFound(err) {
-			// Object not found, return.  Created objects are automatically garbage collected.
-			// For additional cleanup logic use finalizers.
-			return reconcile.Result{}, nil
+	// This reconcile loop will be called for all Migration objects and all pods
+	// because of the informer that we have set up
+	// The behavior here is pretty different depending on the type
+	// so this function is simply an entrypoint that executes the right reconcile loop
+	instance, instanceErr := r.getInstance(request)
+	if instanceErr == nil {
+		result, err := r.reconcileInstance(instance)
+		if err != nil {
+			logger.Error(err)
 		}
-		// Error reading the object - requeue the request.
-		return reconcile.Result{}, err
+		return result, err
 	}
 
-	return reconcile.Result{}, nil
+	pod := &corev1.Pod{}
+	podErr := r.Get(context.Background(), request.NamespacedName, pod)
+	if podErr == nil {
+		result, err := r.reconcilePod(pod)
+		if err != nil {
+			logger.Error(err)
+		}
+		return result, err
+	}
+
+	return reconcile.Result{}, errors.New("unknown error in migration reconciler")
 }
 
-func (r *ReconcileMigration) readConnectionURI(namespace string, valueOrValueFrom databasesv1alpha3.ValueOrValueFrom) (string, error) {
+func (r *ReconcileMigration) readConnectionURI(database *databasesv1alpha3.Database) (string, error) {
+	var valueOrValueFrom *databasesv1alpha3.ValueOrValueFrom
+
+	if database.Spec.Connection.Postgres != nil {
+		valueOrValueFrom = &database.Spec.Connection.Postgres.URI
+	} else if database.Spec.Connection.Mysql != nil {
+		valueOrValueFrom = &database.Spec.Connection.Mysql.URI
+	}
+
+	if valueOrValueFrom == nil {
+		return "", errors.New("cannnot get value from unknown type")
+	}
+
 	if valueOrValueFrom.Value != "" {
 		return valueOrValueFrom.Value, nil
 	}
@@ -107,7 +152,7 @@ func (r *ReconcileMigration) readConnectionURI(namespace string, valueOrValueFro
 		secret := &corev1.Secret{}
 		secretNamespacedName := types.NamespacedName{
 			Name:      valueOrValueFrom.ValueFrom.SecretKeyRef.Name,
-			Namespace: namespace,
+			Namespace: database.Namespace,
 		}
 
 		if err := r.Get(context.Background(), secretNamespacedName, secret); err != nil {
diff --git a/pkg/controller/migration/objects.go b/pkg/controller/migration/objects.go
index 28823d3f..0fed7742 100644
--- a/pkg/controller/migration/objects.go
+++ b/pkg/controller/migration/objects.go
@@ -3,18 +3,34 @@ package migration
 import (
 	"fmt"
 
-	"github.com/pkg/errors"
 	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
 	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-func (r *ReconcileMigration) applyPod(database *databasesv1alpha3.Database, table *schemasv1alpha3.Table) (*corev1.Pod, error) {
+func getApplyConfigMap(migrationID string, namespace string, preparedStatement string) (*corev1.ConfigMap, error) {
+	data := make(map[string]string)
+	data["ddl.sql"] = preparedStatement
+
+	configMap := &corev1.ConfigMap{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      migrationID,
+			Namespace: namespace,
+		},
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: "v1",
+			Kind:       "ConfigMap",
+		},
+		Data: data,
+	}
+
+	return configMap, nil
+}
+
+func getApplyPod(migrationID string, namespace string, connectionURI string, database *databasesv1alpha3.Database, table *schemasv1alpha3.Table) (*corev1.Pod, error) {
 	imageName := "schemahero/schemahero:alpha"
 	nodeSelector := make(map[string]string)
-	driver := ""
-	connectionURI := ""
 
 	if database.Spec.SchemaHero != nil {
 		if database.Spec.SchemaHero.Image != "" {
@@ -24,33 +40,19 @@ func (r *ReconcileMigration) applyPod(database *databasesv1alpha3.Database, tabl
 		nodeSelector = database.Spec.SchemaHero.NodeSelector
 	}
 
-	if database.Spec.Connection.Postgres != nil {
-		driver = "postgres"
-		uri, err := r.readConnectionURI(database.Namespace, database.Spec.Connection.Postgres.URI)
-		if err != nil {
-			return nil, errors.Wrap(err, "failed to read postgres connection uri")
-		}
-		connectionURI = uri
-	} else if database.Spec.Connection.Mysql != nil {
-		driver = "mysql"
-		uri, err := r.readConnectionURI(database.Namespace, database.Spec.Connection.Mysql.URI)
-		if err != nil {
-			return nil, errors.Wrap(err, "failed to read mysql connection uri")
-		}
-		connectionURI = uri
-	}
-
-	if driver == "" {
-		return nil, errors.New("unknown database driver")
-	}
-
 	labels := make(map[string]string)
 	labels["schemahero-name"] = table.Name
 	labels["schemahero-namespace"] = table.Namespace
 	labels["schemahero-role"] = "apply"
 
 	name := fmt.Sprintf("%s-apply", table.Name)
-	configMapName := table.Name
+
+	driver := ""
+	if database.Spec.Connection.Postgres != nil {
+		driver = "postgres"
+	} else if database.Spec.Connection.Mysql != nil {
+		driver = "mysql"
+	}
 
 	args := []string{
 		"apply",
@@ -96,7 +98,7 @@ func (r *ReconcileMigration) applyPod(database *databasesv1alpha3.Database, tabl
 					VolumeSource: corev1.VolumeSource{
 						ConfigMap: &corev1.ConfigMapVolumeSource{
 							LocalObjectReference: corev1.LocalObjectReference{
-								Name: configMapName,
+								Name: migrationID,
 							},
 						},
 					},
diff --git a/pkg/controller/migration/reconcile.go b/pkg/controller/migration/reconcile.go
new file mode 100644
index 00000000..a8df8314
--- /dev/null
+++ b/pkg/controller/migration/reconcile.go
@@ -0,0 +1,76 @@
+package migration
+
+import (
+	"context"
+
+	"github.com/pkg/errors"
+	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	"github.com/schemahero/schemahero/pkg/logger"
+	"go.uber.org/zap"
+	corev1 "k8s.io/api/core/v1"
+	"sigs.k8s.io/controller-runtime/pkg/reconcile"
+)
+
+func (r *ReconcileMigration) getInstance(request reconcile.Request) (*schemasv1alpha3.Migration, error) {
+	v1alpha3instance := &schemasv1alpha3.Migration{}
+	err := r.Get(context.Background(), request.NamespacedName, v1alpha3instance)
+	if err != nil {
+		return nil, err // don't wrap
+	}
+
+	return v1alpha3instance, nil
+}
+
+func (r *ReconcileMigration) reconcileInstance(instance *schemasv1alpha3.Migration) (reconcile.Result, error) {
+	logger.Debug("reconciling migration",
+		zap.String("kind", instance.Kind),
+		zap.String("name", instance.Name),
+		zap.String("tableName", instance.Spec.TableName))
+
+	if instance.Status.ApprovedAt > 0 && instance.Status.ExecutedAt == 0 {
+		configMap, err := getApplyConfigMap(instance.Name, instance.Namespace, instance.Spec.GeneratedDDL)
+		if err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to get apply config map")
+		}
+		if err := r.Create(context.Background(), configMap); err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to create config map")
+		}
+
+		table, err := tableFromMigration(instance)
+		if err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to get table")
+		}
+		database, err := databaseFromTable(table)
+		if err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to get database")
+		}
+
+		connectionURI, err := r.readConnectionURI(database)
+		if err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to get connection uri")
+		}
+
+		pod, err := getApplyPod(instance.Name, instance.Namespace, connectionURI, database, table)
+		if err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to get apply pod")
+		}
+
+		if err := r.Create(context.Background(), pod); err != nil {
+			return reconcile.Result{}, errors.Wrap(err, "failed to create apply pod")
+		}
+
+		return reconcile.Result{}, nil
+	}
+
+	return reconcile.Result{}, nil
+}
+
+func (r *ReconcileMigration) reconcilePod(pod *corev1.Pod) (reconcile.Result, error) {
+	// podLabels := pod.GetObjectMeta().GetLabels()
+	// role, ok := podLabels["schemahero-role"]
+	// if !ok {
+	// 	return reconcile.Result{}, nil
+	// }
+
+	return reconcile.Result{}, nil
+}
diff --git a/pkg/controller/table/objects.go b/pkg/controller/table/objects.go
index c69e5fff..104c031b 100644
--- a/pkg/controller/table/objects.go
+++ b/pkg/controller/table/objects.go
@@ -14,8 +14,8 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 )
 
-func (r *ReconcileTable) planConfigMap(database *databasesv1alpha3.Database, table *schemasv1alpha3.Table) (*corev1.ConfigMap, error) {
-	b, err := yaml.Marshal(table.Spec)
+func planConfigMap(namespace string, tableName string, tableSpec schemasv1alpha3.TableSpec) (*corev1.ConfigMap, error) {
+	b, err := yaml.Marshal(tableSpec)
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to marshal yaml spec")
 	}
@@ -23,11 +23,11 @@ func (r *ReconcileTable) planConfigMap(database *databasesv1alpha3.Database, tab
 	tableData := make(map[string]string)
 	tableData["table.yaml"] = string(b)
 
-	name := table.Name
+	name := tableName
 	configMap := &corev1.ConfigMap{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      name,
-			Namespace: database.Namespace,
+			Namespace: namespace,
 		},
 		TypeMeta: metav1.TypeMeta{
 			APIVersion: "v1",
@@ -139,7 +139,7 @@ func (r *ReconcileTable) planPod(database *databasesv1alpha3.Database, table *sc
 
 func (r *ReconcileTable) ensureTableConfigMap(desiredConfigMap *corev1.ConfigMap) error {
 	existingConfigMap := corev1.ConfigMap{}
-	if err := r.Get(context.TODO(), types.NamespacedName{Name: desiredConfigMap.Name, Namespace: desiredConfigMap.Namespace}, &existingConfigMap); err != nil {
+	if err := r.Get(context.Background(), types.NamespacedName{Name: desiredConfigMap.Name, Namespace: desiredConfigMap.Namespace}, &existingConfigMap); err != nil {
 		if kuberneteserrors.IsNotFound(err) {
 			err = r.Create(context.Background(), desiredConfigMap)
 			if err != nil {
@@ -155,7 +155,7 @@ func (r *ReconcileTable) ensureTableConfigMap(desiredConfigMap *corev1.ConfigMap
 
 func (r *ReconcileTable) ensureTablePod(desiredPod *corev1.Pod) error {
 	existingPod := corev1.Pod{}
-	if err := r.Get(context.TODO(), types.NamespacedName{Name: desiredPod.Name, Namespace: desiredPod.Namespace}, &existingPod); err != nil {
+	if err := r.Get(context.Background(), types.NamespacedName{Name: desiredPod.Name, Namespace: desiredPod.Namespace}, &existingPod); err != nil {
 		if kuberneteserrors.IsNotFound(err) {
 			err = r.Create(context.Background(), desiredPod)
 			if err != nil {
diff --git a/pkg/controller/table/plan.go b/pkg/controller/table/plan.go
index 60dd3dd1..d95043b4 100644
--- a/pkg/controller/table/plan.go
+++ b/pkg/controller/table/plan.go
@@ -10,6 +10,7 @@ import (
 	"github.com/pkg/errors"
 	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
 	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	databasesclientv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/databases/v1alpha3"
 	schemasclientv1alpha3 "github.com/schemahero/schemahero/pkg/client/schemaheroclientset/typed/schemas/v1alpha3"
 	"github.com/schemahero/schemahero/pkg/logger"
 	"go.uber.org/zap"
@@ -122,6 +123,21 @@ func (r *ReconcileTable) reconcilePod(pod *corev1.Pod) (reconcile.Result, error)
 		},
 	}
 
+	// If the database is set to immediate deploy, then set it as approved also
+	databasesClient, err := databasesclientv1alpha3.NewForConfig(cfg)
+	if err != nil {
+		return reconcile.Result{}, errors.Wrap(err, "Failed to create database client")
+	}
+
+	database, err := databasesClient.Databases(tableNamespace).Get(table.Spec.Database, metav1.GetOptions{})
+	if err != nil {
+		return reconcile.Result{}, errors.Wrap(err, "failed to get database")
+	}
+
+	if database.Spec.ImmediateDeploy {
+		migration.Status.ApprovedAt = time.Now().Unix()
+	}
+
 	if err := r.Create(context.Background(), &migration); err != nil {
 		return reconcile.Result{}, errors.Wrap(err, "failed to create migration resource")
 	}
@@ -153,7 +169,7 @@ func (r *ReconcileTable) reconcilePod(pod *corev1.Pod) (reconcile.Result, error)
 func (r *ReconcileTable) plan(database *databasesv1alpha3.Database, table *schemasv1alpha3.Table) error {
 	logger.Debug("deploying plan")
 
-	configMap, err := r.planConfigMap(database, table)
+	configMap, err := planConfigMap(database.Namespace, table.Name, table.Spec)
 	if err != nil {
 		return errors.Wrap(err, "failed to get config map object for plan")
 	}
diff --git a/pkg/controller/table/reconile.go b/pkg/controller/table/reconile.go
index 4d4c6c04..94252854 100644
--- a/pkg/controller/table/reconile.go
+++ b/pkg/controller/table/reconile.go
@@ -39,7 +39,7 @@ func (r *ReconcileTable) reconcileInstance(instance *schemasv1alpha3.Table) (rec
 		}, nil
 	}
 
-	matchingType := r.checkDatabaseTypeMatches(&database.Spec.Connection, instance.Spec.Schema)
+	matchingType := checkDatabaseTypeMatches(&database.Spec.Connection, instance.Spec.Schema)
 	if !matchingType {
 		// TODO add a status field with this state
 		return reconcile.Result{}, errors.New("unable to deploy table to connection of different type")
@@ -131,7 +131,7 @@ func (r *ReconcileTable) getDatabaseSpec(namespace string, name string) (*databa
 	return database, nil
 }
 
-func (r *ReconcileTable) checkDatabaseTypeMatches(connection *databasesv1alpha3.DatabaseConnection, tableSchema *schemasv1alpha3.TableSchema) bool {
+func checkDatabaseTypeMatches(connection *databasesv1alpha3.DatabaseConnection, tableSchema *schemasv1alpha3.TableSchema) bool {
 	if connection.Postgres != nil {
 		return tableSchema.Postgres != nil
 	} else if connection.Mysql != nil {
diff --git a/pkg/controller/table/table_controller.go b/pkg/controller/table/table_controller.go
index d7c367c5..716b1de2 100644
--- a/pkg/controller/table/table_controller.go
+++ b/pkg/controller/table/table_controller.go
@@ -18,7 +18,6 @@ package table
 
 import (
 	"context"
-	"fmt"
 	"time"
 
 	"github.com/pkg/errors"
@@ -58,7 +57,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
 	// Watch for changes to Table
 	err = c.Watch(&source.Kind{Type: &schemasv1alpha3.Table{}}, &handler.EnqueueRequestForObject{})
 	if err != nil {
-		return err
+		return errors.Wrap(err, "failed to start watch on tables")
 	}
 
 	// Add an informer on pods, which are created to deploy schemas. the informer will
@@ -80,7 +79,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
 		Informer: generatedInformers.Core().V1().Pods().Informer(),
 	}, &handler.EnqueueRequestForObject{})
 	if err != nil {
-		return err
+		return errors.Wrap(err, "failed to start watch on pods")
 	}
 
 	return nil
@@ -102,9 +101,12 @@ type ReconcileTable struct {
 // +kubebuilder:rbac:groups=schemas.schemahero.io,resources=tables,verbs=get;list;watch;create;update;patch;delete
 // +kubebuilder:rbac:groups=schemas.schemahero.io,resources=tables/status,verbs=get;update;patch
 func (r *ReconcileTable) Reconcile(request reconcile.Request) (reconcile.Result, error) {
+	// This reconcile loop will be called for all Table objects and all pods
+	// because of the informer that we have set up
+	// The behavior here is pretty different depending on the type
+	// so this function is simply an entrypoint that executes the right reconcile loop
 	instance, instanceErr := r.getInstance(request)
 	if instanceErr == nil {
-		fmt.Printf("instance\n")
 		result, err := r.reconcileInstance(instance)
 		if err != nil {
 			logger.Error(err)
diff --git a/pkg/database/database.go b/pkg/database/database.go
index c118feb1..353d7f6f 100644
--- a/pkg/database/database.go
+++ b/pkg/database/database.go
@@ -11,7 +11,9 @@ import (
 	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
 	"github.com/schemahero/schemahero/pkg/database/mysql"
 	"github.com/schemahero/schemahero/pkg/database/postgres"
+	"github.com/schemahero/schemahero/pkg/logger"
 	"github.com/spf13/viper"
+	"go.uber.org/zap"
 	"gopkg.in/yaml.v2"
 )
 
@@ -26,7 +28,8 @@ func NewDatabase() *Database {
 }
 
 func (d *Database) CreateFixturesSync() error {
-	fmt.Printf("generating fixtures for resources in %s\n", d.Viper.GetString("input-dir"))
+	logger.Infof("generating fixtures",
+		zap.String("input-dir", d.Viper.GetString("input-dir")))
 
 	statements := []string{}
 	handleFile := func(path string, info os.FileInfo, err error) error {
diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go
index e195f45f..a011e421 100644
--- a/pkg/logger/logger.go
+++ b/pkg/logger/logger.go
@@ -7,7 +7,7 @@ import (
 var log *zap.Logger
 
 func init() {
-	l, err := zap.NewDevelopment()
+	l, err := zap.NewDevelopment(zap.AddCallerSkip(1))
 	if err != nil {
 		panic(err)
 	}
@@ -21,6 +21,12 @@ func Error(err error) {
 	sugar.Error(err)
 }
 
+func Info(msg string, fields ...zap.Field) {
+	defer log.Sync()
+	sugar := log.Sugar()
+	sugar.Info(msg, fields)
+}
+
 func Infof(template string, args ...interface{}) {
 	defer log.Sync()
 	sugar := log.Sugar()
diff --git a/pkg/watcher/watcher.go b/pkg/watcher/watcher.go
deleted file mode 100644
index 263a3c38..00000000
--- a/pkg/watcher/watcher.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package watcher
-
-import (
-	"fmt"
-	"time"
-
-	"github.com/schemahero/schemahero/pkg/database/interfaces"
-	"github.com/schemahero/schemahero/pkg/database/mysql"
-	"github.com/schemahero/schemahero/pkg/database/postgres"
-
-	"github.com/spf13/viper"
-)
-
-type Watcher struct {
-	Viper *viper.Viper
-}
-
-func NewWatcher() *Watcher {
-	return &Watcher{
-		Viper: viper.GetViper(),
-	}
-}
-
-func (w *Watcher) RunSync() error {
-	fmt.Printf("connecting to %s\n", w.Viper.GetString("uri"))
-
-	var conn interfaces.SchemaHeroDatabaseConnection
-
-	if w.Viper.GetString("driver") == "postgres" {
-		c, err := postgres.Connect(w.Viper.GetString("uri"))
-		if err != nil {
-			return err
-		}
-
-		conn = c
-	} else if w.Viper.GetString("driver") == "mysql" {
-		c, err := mysql.Connect(w.Viper.GetString("uri"))
-		if err != nil {
-			return err
-		}
-
-		conn = c
-	}
-
-	for {
-		if _, err := conn.CheckAlive(w.Viper.GetString("namespace"), w.Viper.GetString("instance")); err != nil {
-			fmt.Printf("%#v\n", err)
-			return err
-		}
-
-		time.Sleep(time.Second * 10)
-	}
-}


Test patch:
diff --git a/pkg/controller/table/objects_test.go b/pkg/controller/table/objects_test.go
new file mode 100644
index 00000000..ad43ef81
--- /dev/null
+++ b/pkg/controller/table/objects_test.go
@@ -0,0 +1,47 @@
+package table
+
+import (
+	"testing"
+
+	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
+)
+
+func Test_planConfigMap(t *testing.T) {
+	tests := []struct {
+		name      string
+		namespace string
+		tableName string
+		tableSpec schemasv1alpha3.TableSpec
+		expect    corev1.ConfigMap
+	}{
+		{
+			name:      "basic test",
+			namespace: "foo",
+			tableName: "name",
+			tableSpec: schemasv1alpha3.TableSpec{
+				Database: "db",
+				Name:     "name",
+				Schema: &schemasv1alpha3.TableSchema{
+					Postgres: &schemasv1alpha3.SQLTableSchema{},
+				},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			req := require.New(t)
+
+			actual, err := planConfigMap(test.namespace, test.tableName, test.tableSpec)
+			req.NoError(err)
+
+			// check some of the fields on the config map
+			assert.Equal(t, test.tableName, actual.Name)
+			assert.Len(t, actual.Data, 1)
+			assert.NotNil(t, actual.Data["table.yaml"], actual.Data["table.yaml"])
+		})
+	}
+}
diff --git a/pkg/controller/table/reconcile_test.go b/pkg/controller/table/reconcile_test.go
new file mode 100644
index 00000000..8dd5f1c7
--- /dev/null
+++ b/pkg/controller/table/reconcile_test.go
@@ -0,0 +1,82 @@
+package table
+
+import (
+	"testing"
+
+	databasesv1alpha3 "github.com/schemahero/schemahero/pkg/apis/databases/v1alpha3"
+	schemasv1alpha3 "github.com/schemahero/schemahero/pkg/apis/schemas/v1alpha3"
+	"github.com/stretchr/testify/assert"
+)
+
+func Test_checkDatabaseTypeMatches(t *testing.T) {
+	tests := []struct {
+		name        string
+		connection  databasesv1alpha3.DatabaseConnection
+		tableSchema schemasv1alpha3.TableSchema
+		expect      bool
+	}{
+		{
+			name: "is postgres",
+			connection: databasesv1alpha3.DatabaseConnection{
+				Postgres: &databasesv1alpha3.PostgresConnection{
+					URI: databasesv1alpha3.ValueOrValueFrom{
+						Value: "test",
+					},
+				},
+			},
+			tableSchema: schemasv1alpha3.TableSchema{
+				Postgres: &schemasv1alpha3.SQLTableSchema{},
+			},
+			expect: true,
+		},
+		{
+			name: "is mysql",
+			connection: databasesv1alpha3.DatabaseConnection{
+				Mysql: &databasesv1alpha3.MysqlConnection{
+					URI: databasesv1alpha3.ValueOrValueFrom{
+						Value: "test",
+					},
+				},
+			},
+			tableSchema: schemasv1alpha3.TableSchema{
+				Mysql: &schemasv1alpha3.SQLTableSchema{},
+			},
+			expect: true,
+		},
+		{
+			name: "is mysql, expect postgres",
+			connection: databasesv1alpha3.DatabaseConnection{
+				Mysql: &databasesv1alpha3.MysqlConnection{
+					URI: databasesv1alpha3.ValueOrValueFrom{
+						Value: "test",
+					},
+				},
+			},
+			tableSchema: schemasv1alpha3.TableSchema{
+				Postgres: &schemasv1alpha3.SQLTableSchema{},
+			},
+			expect: false,
+		},
+		{
+			name: "is postgres, expect mysql",
+			connection: databasesv1alpha3.DatabaseConnection{
+				Postgres: &databasesv1alpha3.PostgresConnection{
+					URI: databasesv1alpha3.ValueOrValueFrom{
+						Value: "test",
+					},
+				},
+			},
+			tableSchema: schemasv1alpha3.TableSchema{
+				Mysql: &schemasv1alpha3.SQLTableSchema{},
+			},
+			expect: false,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			actual := checkDatabaseTypeMatches(&test.connection, &test.tableSchema)
+			assert.Equal(t, test.expect, actual)
+		})
+	}
+}