From 12e96256318cf933b7e0afbc608997c565322edd Mon Sep 17 00:00:00 2001 From: Vince Prignano Date: Tue, 3 Mar 2020 08:50:32 -0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=20Add=20exp/=20package=20wit?= =?UTF-8?q?h=20MachinePool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Vince Prignano --- Makefile | 5 +- api/v1alpha3/conversion.go | 2 - api/v1alpha3/zz_generated.deepcopy.go | 125 ----- bootstrap/kubeadm/config/rbac/role.yaml | 11 +- .../controllers/kubeadmconfig_controller.go | 31 +- .../kubeadmconfig_controller_test.go | 29 +- bootstrap/kubeadm/main.go | 30 +- bootstrap/util/configowner.go | 34 +- bootstrap/util/configowner_test.go | 13 +- cmd/clusterctl/client/cluster/mover_test.go | 2 +- .../client/cluster/objectgraph_test.go | 2 +- cmd/clusterctl/internal/test/fake_objects.go | 9 +- cmd/clusterctl/internal/test/fake_proxy.go | 2 + ...=> exp.cluster.x-k8s.io_machinepools.yaml} | 4 +- config/crd/kustomization.yaml | 4 +- .../patches/cainjection_in_machinepools.yaml | 8 - .../crd/patches/webhook_in_machinepools.yaml | 19 - config/kustomization.yaml | 6 - config/rbac/role.yaml | 36 +- config/webhook/manifests.yaml | 28 +- .../providers/v1alpha2-to-v1alpha3.md | 14 +- exp/PROJECT | 7 + exp/README.md | 9 + exp/api/v1alpha3/groupversion_info.go | 36 ++ .../api}/v1alpha3/machinepool_types.go | 7 +- .../api}/v1alpha3/machinepool_webhook.go | 4 +- .../api}/v1alpha3/machinepool_webhook_test.go | 45 +- exp/api/v1alpha3/zz_generated.deepcopy.go | 153 ++++++ exp/controllers/exp.go | 21 + .../controllers}/machinepool_controller.go | 21 +- .../machinepool_controller_noderef.go | 3 +- .../machinepool_controller_noderef_test.go | 0 .../machinepool_controller_phases.go | 28 +- .../machinepool_controller_phases_test.go | 71 +-- .../machinepool_controller_test.go | 70 +-- exp/controllers/suite_test.go | 130 +++++ exp/doc.go | 17 + exp/hack/boilerplate.go.txt | 16 + features/features.go => feature/feature.go | 22 +- .../featuregate.go => feature/gates.go | 10 +- go.mod | 4 +- go.sum | 10 + main.go | 39 +- test/framework/control_plane.go | 3 +- test/framework/convenience.go | 4 + test/framework/dump_resources.go | 3 +- test/framework/go.mod | 17 - test/framework/go.sum | 487 ------------------ test/helpers/scheme/scheme.go | 2 + test/infrastructure/docker/go.mod | 6 +- 50 files changed, 747 insertions(+), 912 deletions(-) rename config/crd/bases/{cluster.x-k8s.io_machinepools.yaml => exp.cluster.x-k8s.io_machinepools.yaml} (99%) delete mode 100644 config/crd/patches/cainjection_in_machinepools.yaml delete mode 100644 config/crd/patches/webhook_in_machinepools.yaml create mode 100644 exp/PROJECT create mode 100644 exp/README.md create mode 100644 exp/api/v1alpha3/groupversion_info.go rename {api => exp/api}/v1alpha3/machinepool_types.go (96%) rename {api => exp/api}/v1alpha3/machinepool_webhook.go (87%) rename {api => exp/api}/v1alpha3/machinepool_webhook_test.go (76%) create mode 100644 exp/api/v1alpha3/zz_generated.deepcopy.go create mode 100644 exp/controllers/exp.go rename {controllers => exp/controllers}/machinepool_controller.go (91%) rename {controllers => exp/controllers}/machinepool_controller_noderef.go (98%) rename {controllers => exp/controllers}/machinepool_controller_noderef_test.go (100%) rename {controllers => exp/controllers}/machinepool_controller_phases.go (91%) rename {controllers => exp/controllers}/machinepool_controller_phases_test.go (92%) rename {controllers => exp/controllers}/machinepool_controller_test.go (90%) create mode 100644 exp/controllers/suite_test.go create mode 100644 exp/doc.go create mode 100644 exp/hack/boilerplate.go.txt rename features/features.go => feature/feature.go (71%) rename util/featuregate/featuregate.go => feature/gates.go (77%) delete mode 100644 test/framework/go.mod delete mode 100644 test/framework/go.sum diff --git a/Makefile b/Makefile index b80ff73a7aed..49d37f603412 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ export KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT ?=60s export DOCKER_CLI_EXPERIMENTAL := enabled # Directories. +EXP_DIR := exp TOOLS_DIR := hack/tools TOOLS_BIN_DIR := $(TOOLS_DIR)/bin BIN_DIR := bin @@ -209,6 +210,7 @@ generate-go-core: $(CONTROLLER_GEN) $(CONVERSION_GEN) $(CONTROLLER_GEN) \ object:headerFile=./hack/boilerplate/boilerplate.generatego.txt \ paths=./api/... \ + paths=./$(EXP_DIR)/api/... \ paths=./cmd/clusterctl/... $(CONVERSION_GEN) \ --input-dirs=./api/v1alpha2 \ @@ -256,6 +258,8 @@ generate-core-manifests: $(CONTROLLER_GEN) ## Generate manifests for the core pr $(CONTROLLER_GEN) \ paths=./api/... \ paths=./controllers/... \ + paths=./$(EXP_DIR)/api/... \ + paths=./$(EXP_DIR)/controllers/... \ crd:crdVersions=v1 \ rbac:roleName=manager-role \ output:crd:dir=./config/crd/bases \ @@ -297,7 +301,6 @@ generate-kubeadm-control-plane-manifests: $(CONTROLLER_GEN) ## Generate manifest modules: ## Runs go mod to ensure modules are up to date. go mod tidy cd $(TOOLS_DIR); go mod tidy - cd $(E2E_FRAMEWORK_DIR); go mod tidy cd $(CAPD_DIR); $(MAKE) modules ## -------------------------------------- diff --git a/api/v1alpha3/conversion.go b/api/v1alpha3/conversion.go index 8d2bf9f28172..99dbce979afb 100644 --- a/api/v1alpha3/conversion.go +++ b/api/v1alpha3/conversion.go @@ -26,5 +26,3 @@ func (*MachineDeployment) Hub() {} func (*MachineDeploymentList) Hub() {} func (*MachineHealthCheck) Hub() {} func (*MachineHealthCheckList) Hub() {} -func (*MachinePool) Hub() {} -func (*MachinePoolList) Hub() {} diff --git a/api/v1alpha3/zz_generated.deepcopy.go b/api/v1alpha3/zz_generated.deepcopy.go index 29417392e51f..c84b6fb816cc 100644 --- a/api/v1alpha3/zz_generated.deepcopy.go +++ b/api/v1alpha3/zz_generated.deepcopy.go @@ -602,131 +602,6 @@ func (in *MachineList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MachinePool) DeepCopyInto(out *MachinePool) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePool. -func (in *MachinePool) DeepCopy() *MachinePool { - if in == nil { - return nil - } - out := new(MachinePool) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MachinePool) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MachinePoolList) DeepCopyInto(out *MachinePoolList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]MachinePool, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolList. -func (in *MachinePoolList) DeepCopy() *MachinePoolList { - if in == nil { - return nil - } - out := new(MachinePoolList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MachinePoolList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MachinePoolSpec) DeepCopyInto(out *MachinePoolSpec) { - *out = *in - if in.Replicas != nil { - in, out := &in.Replicas, &out.Replicas - *out = new(int32) - **out = **in - } - in.Template.DeepCopyInto(&out.Template) - if in.Strategy != nil { - in, out := &in.Strategy, &out.Strategy - *out = new(MachineDeploymentStrategy) - (*in).DeepCopyInto(*out) - } - if in.MinReadySeconds != nil { - in, out := &in.MinReadySeconds, &out.MinReadySeconds - *out = new(int32) - **out = **in - } - if in.ProviderIDList != nil { - in, out := &in.ProviderIDList, &out.ProviderIDList - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolSpec. -func (in *MachinePoolSpec) DeepCopy() *MachinePoolSpec { - if in == nil { - return nil - } - out := new(MachinePoolSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MachinePoolStatus) DeepCopyInto(out *MachinePoolStatus) { - *out = *in - if in.NodeRefs != nil { - in, out := &in.NodeRefs, &out.NodeRefs - *out = make([]v1.ObjectReference, len(*in)) - copy(*out, *in) - } - if in.FailureReason != nil { - in, out := &in.FailureReason, &out.FailureReason - *out = new(errors.MachinePoolStatusFailure) - **out = **in - } - if in.FailureMessage != nil { - in, out := &in.FailureMessage, &out.FailureMessage - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolStatus. -func (in *MachinePoolStatus) DeepCopy() *MachinePoolStatus { - if in == nil { - return nil - } - out := new(MachinePoolStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MachineRollingUpdateDeployment) DeepCopyInto(out *MachineRollingUpdateDeployment) { *out = *in diff --git a/bootstrap/kubeadm/config/rbac/role.yaml b/bootstrap/kubeadm/config/rbac/role.yaml index ef7d2c8cb945..424d4a050965 100644 --- a/bootstrap/kubeadm/config/rbac/role.yaml +++ b/bootstrap/kubeadm/config/rbac/role.yaml @@ -38,11 +38,18 @@ rules: resources: - clusters - clusters/status - - machinepools - - machinepools/status - machines - machines/status verbs: - get - list - watch +- apiGroups: + - exp.cluster.x-k8s.io + resources: + - machinepools + - machinepools/status + verbs: + - get + - list + - watch diff --git a/bootstrap/kubeadm/controllers/kubeadmconfig_controller.go b/bootstrap/kubeadm/controllers/kubeadmconfig_controller.go index 31ff9fd657a8..0e613b88c2b0 100644 --- a/bootstrap/kubeadm/controllers/kubeadmconfig_controller.go +++ b/bootstrap/kubeadm/controllers/kubeadmconfig_controller.go @@ -39,6 +39,8 @@ import ( bsutil "sigs.k8s.io/cluster-api/bootstrap/util" "sigs.k8s.io/cluster-api/controllers/remote" capierrors "sigs.k8s.io/cluster-api/errors" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/patch" "sigs.k8s.io/cluster-api/util/secret" @@ -56,7 +58,8 @@ type InitLocker interface { } // +kubebuilder:rbac:groups=bootstrap.cluster.x-k8s.io,resources=kubeadmconfigs;kubeadmconfigs/status,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status;machines;machines/status;machinepools;machinepools/status,verbs=get;list;watch +// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters;clusters/status;machines;machines/status,verbs=get;list;watch +// +kubebuilder:rbac:groups=exp.cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch // +kubebuilder:rbac:groups="",resources=secrets;events;configmaps,verbs=get;list;watch;create;update;patch;delete // KubeadmConfigReconciler reconciles a KubeadmConfig object @@ -87,30 +90,32 @@ func (r *KubeadmConfigReconciler) SetupWithManager(mgr ctrl.Manager, option cont r.scheme = mgr.GetScheme() - err := ctrl.NewControllerManagedBy(mgr). + builder := ctrl.NewControllerManagedBy(mgr). For(&bootstrapv1.KubeadmConfig{}). + WithOptions(option). Watches( &source.Kind{Type: &clusterv1.Machine{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(r.MachineToBootstrapMapFunc), }, ). - Watches( - &source.Kind{Type: &clusterv1.MachinePool{}}, - &handler.EnqueueRequestsFromMapFunc{ - ToRequests: handler.ToRequestsFunc(r.MachinePoolToBootstrapMapFunc), - }, - ). Watches( &source.Kind{Type: &clusterv1.Cluster{}}, &handler.EnqueueRequestsFromMapFunc{ ToRequests: handler.ToRequestsFunc(r.ClusterToKubeadmConfigs), }, - ). - WithOptions(option). - Complete(r) + ) - if err != nil { + if feature.Gates.Enabled(feature.MachinePool) { + builder = builder.Watches( + &source.Kind{Type: &expv1.MachinePool{}}, + &handler.EnqueueRequestsFromMapFunc{ + ToRequests: handler.ToRequestsFunc(r.MachinePoolToBootstrapMapFunc), + }, + ) + } + + if err := builder.Complete(r); err != nil { return errors.Wrap(err, "failed setting up with a controller manager") } @@ -564,7 +569,7 @@ func (r *KubeadmConfigReconciler) MachineToBootstrapMapFunc(o handler.MapObject) func (r *KubeadmConfigReconciler) MachinePoolToBootstrapMapFunc(o handler.MapObject) []ctrl.Request { result := []ctrl.Request{} - m, ok := o.Object.(*clusterv1.MachinePool) + m, ok := o.Object.(*expv1.MachinePool) if !ok { return nil } diff --git a/bootstrap/kubeadm/controllers/kubeadmconfig_controller_test.go b/bootstrap/kubeadm/controllers/kubeadmconfig_controller_test.go index 0fac69976ab8..bbd7a30dcab5 100644 --- a/bootstrap/kubeadm/controllers/kubeadmconfig_controller_test.go +++ b/bootstrap/kubeadm/controllers/kubeadmconfig_controller_test.go @@ -36,6 +36,8 @@ import ( bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" kubeadmv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/v1beta1" fakeremote "sigs.k8s.io/cluster-api/controllers/remote/fake" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/secret" ctrl "sigs.k8s.io/controller-runtime" @@ -51,6 +53,9 @@ func setupScheme() *runtime.Scheme { if err := clusterv1.AddToScheme(scheme); err != nil { panic(err) } + if err := expv1.AddToScheme(scheme); err != nil { + panic(err) + } if err := bootstrapv1.AddToScheme(scheme); err != nil { panic(err) } @@ -702,6 +707,8 @@ func TestReconcileIfJoinNodesAndControlPlaneIsReady(t *testing.T) { } func TestReconcileIfJoinNodePoolsAndControlPlaneIsReady(t *testing.T) { + _ = feature.MutableGates.Set("MachinePool=true") + cluster := newCluster("cluster") cluster.Status.InfrastructureReady = true cluster.Status.ControlPlaneInitialized = true @@ -709,15 +716,15 @@ func TestReconcileIfJoinNodePoolsAndControlPlaneIsReady(t *testing.T) { var useCases = []struct { name string - machinePool *clusterv1.MachinePool + machinePool *expv1.MachinePool configName string - configBuilder func(*clusterv1.MachinePool, string) *bootstrapv1.KubeadmConfig + configBuilder func(*expv1.MachinePool, string) *bootstrapv1.KubeadmConfig }{ { name: "Join a worker node with a fully compiled kubeadm config object", machinePool: newWorkerMachinePool(cluster), configName: "workerpool-join-cfg", - configBuilder: func(machinePool *clusterv1.MachinePool, name string) *bootstrapv1.KubeadmConfig { + configBuilder: func(machinePool *expv1.MachinePool, name string) *bootstrapv1.KubeadmConfig { return newWorkerPoolJoinKubeadmConfig(machinePool) }, }, @@ -1622,17 +1629,17 @@ func newControlPlaneMachine(cluster *clusterv1.Cluster, name string) *clusterv1. } // newMachinePool return a CAPI machine pool object; if cluster is not nil, the machine pool is linked to the cluster as well -func newMachinePool(cluster *clusterv1.Cluster, name string) *clusterv1.MachinePool { - machine := &clusterv1.MachinePool{ +func newMachinePool(cluster *clusterv1.Cluster, name string) *expv1.MachinePool { + machine := &expv1.MachinePool{ TypeMeta: metav1.TypeMeta{ Kind: "MachinePool", - APIVersion: clusterv1.GroupVersion.String(), + APIVersion: expv1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: name, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -1654,7 +1661,7 @@ func newMachinePool(cluster *clusterv1.Cluster, name string) *clusterv1.MachineP return machine } -func newWorkerMachinePool(cluster *clusterv1.Cluster) *clusterv1.MachinePool { +func newWorkerMachinePool(cluster *clusterv1.Cluster) *expv1.MachinePool { return newMachinePool(cluster, "worker-machinepool") } @@ -1710,7 +1717,7 @@ func newControlPlaneInitKubeadmConfig(machine *clusterv1.Machine, name string) * // newMachinePoolKubeadmConfig return a CABPK KubeadmConfig object; if machine pool is not nil, // the KubeadmConfig is linked to the machine pool as well -func newMachinePoolKubeadmConfig(machinePool *clusterv1.MachinePool, name string) *bootstrapv1.KubeadmConfig { +func newMachinePoolKubeadmConfig(machinePool *expv1.MachinePool, name string) *bootstrapv1.KubeadmConfig { config := &bootstrapv1.KubeadmConfig{ TypeMeta: metav1.TypeMeta{ Kind: "KubeadmConfig", @@ -1725,7 +1732,7 @@ func newMachinePoolKubeadmConfig(machinePool *clusterv1.MachinePool, name string config.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ { Kind: "MachinePool", - APIVersion: clusterv1.GroupVersion.String(), + APIVersion: expv1.GroupVersion.String(), Name: machinePool.Name, UID: types.UID(fmt.Sprintf("%s uid", machinePool.Name)), }, @@ -1736,7 +1743,7 @@ func newMachinePoolKubeadmConfig(machinePool *clusterv1.MachinePool, name string return config } -func newWorkerPoolJoinKubeadmConfig(machinePool *clusterv1.MachinePool) *bootstrapv1.KubeadmConfig { +func newWorkerPoolJoinKubeadmConfig(machinePool *expv1.MachinePool) *bootstrapv1.KubeadmConfig { c := newMachinePoolKubeadmConfig(machinePool, "workerpool-join-cfg") c.Spec.JoinConfiguration = &kubeadmv1beta1.JoinConfiguration{ ControlPlane: nil, diff --git a/bootstrap/kubeadm/main.go b/bootstrap/kubeadm/main.go index 51e55ffc9f03..6dc9b07b0f0f 100644 --- a/bootstrap/kubeadm/main.go +++ b/bootstrap/kubeadm/main.go @@ -23,6 +23,7 @@ import ( "os" "time" + "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" @@ -32,6 +33,8 @@ import ( kubeadmbootstrapv1alpha2 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha2" kubeadmbootstrapv1alpha3 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" kubeadmbootstrapcontrollers "sigs.k8s.io/cluster-api/bootstrap/kubeadm/controllers" + expv1alpha3 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + "sigs.k8s.io/cluster-api/feature" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" @@ -49,6 +52,7 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = clusterv1alpha3.AddToScheme(scheme) + _ = expv1alpha3.AddToScheme(scheme) _ = kubeadmbootstrapv1alpha2.AddToScheme(scheme) _ = kubeadmbootstrapv1alpha3.AddToScheme(scheme) // +kubebuilder:scaffold:scheme @@ -64,32 +68,38 @@ var ( webhookPort int ) -func main() { - flag.StringVar(&metricsAddr, "metrics-addr", ":8080", +func InitFlags(fs *pflag.FlagSet) { + fs.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") - flag.BoolVar(&enableLeaderElection, "enable-leader-election", false, + fs.BoolVar(&enableLeaderElection, "enable-leader-election", false, "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.") - flag.StringVar(&watchNamespace, "namespace", "", + fs.StringVar(&watchNamespace, "namespace", "", "Namespace that the controller watches to reconcile cluster-api objects. If unspecified, the controller watches for cluster-api objects across all namespaces.") - flag.StringVar(&profilerAddress, "profiler-address", "", + fs.StringVar(&profilerAddress, "profiler-address", "", "Bind address to expose the pprof profiler (e.g. localhost:6060)") - flag.IntVar(&kubeadmConfigConcurrency, "kubeadmconfig-concurrency", 10, + fs.IntVar(&kubeadmConfigConcurrency, "kubeadmconfig-concurrency", 10, "Number of kubeadm configs to process simultaneously") - flag.DurationVar(&syncPeriod, "sync-period", 10*time.Minute, + fs.DurationVar(&syncPeriod, "sync-period", 10*time.Minute, "The minimum interval at which watched resources are reconciled (e.g. 15m)") - flag.DurationVar(&kubeadmbootstrapcontrollers.DefaultTokenTTL, "bootstrap-token-ttl", 15*time.Minute, + fs.DurationVar(&kubeadmbootstrapcontrollers.DefaultTokenTTL, "bootstrap-token-ttl", 15*time.Minute, "The amount of time the bootstrap token will be valid") - flag.IntVar(&webhookPort, "webhook-port", 0, + fs.IntVar(&webhookPort, "webhook-port", 0, "Webhook Server port, disabled by default. When enabled, the manager will only work as webhook server, no reconcilers are installed.") - flag.Parse() + feature.MutableGates.AddFlag(fs) +} + +func main() { + InitFlags(pflag.CommandLine) + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) + pflag.Parse() ctrl.SetLogger(klogr.New()) diff --git a/bootstrap/util/configowner.go b/bootstrap/util/configowner.go index 69f2697bd2d6..962764db5415 100644 --- a/bootstrap/util/configowner.go +++ b/bootstrap/util/configowner.go @@ -26,6 +26,8 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" "sigs.k8s.io/cluster-api/controllers/external" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -77,20 +79,36 @@ func (co ConfigOwner) IsControlPlaneMachine() bool { // GetConfigOwner returns the Unstructured object owning the current resource. func GetConfigOwner(ctx context.Context, c client.Client, obj metav1.Object) (*ConfigOwner, error) { for _, ref := range obj.GetOwnerReferences() { - refgvk, err := schema.ParseGroupVersion(ref.APIVersion) + refGV, err := schema.ParseGroupVersion(ref.APIVersion) if err != nil { return nil, errors.Wrapf(err, "failed to parse GroupVersion from %q", ref.APIVersion) } + refGVK := refGV.WithKind(ref.Kind) - if (ref.Kind == "Machine" || ref.Kind == "MachinePool") && - refgvk.Group == clusterv1.GroupVersion.Group { - return GetOwnerByRef(ctx, c, &corev1.ObjectReference{ - APIVersion: ref.APIVersion, - Kind: ref.Kind, - Name: ref.Name, - Namespace: obj.GetNamespace(), + allowedGKs := []schema.GroupKind{ + { + Group: clusterv1.GroupVersion.Group, + Kind: "Machine", + }, + } + + if feature.Gates.Enabled(feature.MachinePool) { + allowedGKs = append(allowedGKs, schema.GroupKind{ + Group: expv1.GroupVersion.Group, + Kind: "MachinePool", }) } + + for _, gk := range allowedGKs { + if refGVK.Group == gk.Group && refGVK.Kind == gk.Kind { + return GetOwnerByRef(ctx, c, &corev1.ObjectReference{ + APIVersion: ref.APIVersion, + Kind: ref.Kind, + Name: ref.Name, + Namespace: obj.GetNamespace(), + }) + } + } } return nil, nil } diff --git a/bootstrap/util/configowner_test.go b/bootstrap/util/configowner_test.go index 4b16f99bbe1d..930fcdac0001 100644 --- a/bootstrap/util/configowner_test.go +++ b/bootstrap/util/configowner_test.go @@ -26,6 +26,8 @@ import ( "k8s.io/utils/pointer" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) @@ -34,6 +36,7 @@ func TestGetConfigOwner(t *testing.T) { scheme := runtime.NewScheme() g.Expect(clusterv1.AddToScheme(scheme)).To(Succeed()) + g.Expect(expv1.AddToScheme(scheme)).To(Succeed()) t.Run("should get the owner when present (Machine)", func(t *testing.T) { g := NewWithT(t) @@ -80,8 +83,10 @@ func TestGetConfigOwner(t *testing.T) { }) t.Run("should get the owner when present (MachinePool)", func(t *testing.T) { + _ = feature.MutableGates.Set("MachinePool=true") + g := NewWithT(t) - myPool := &clusterv1.MachinePool{ + myPool := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "my-machine-pool", Namespace: "my-ns", @@ -89,10 +94,10 @@ func TestGetConfigOwner(t *testing.T) { clusterv1.MachineControlPlaneLabelName: "", }, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "my-cluster", }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ InfrastructureReady: true, }, } @@ -103,7 +108,7 @@ func TestGetConfigOwner(t *testing.T) { OwnerReferences: []metav1.OwnerReference{ { Kind: "MachinePool", - APIVersion: clusterv1.GroupVersion.String(), + APIVersion: expv1.GroupVersion.String(), Name: "my-machine-pool", }, }, diff --git a/cmd/clusterctl/client/cluster/mover_test.go b/cmd/clusterctl/client/cluster/mover_test.go index 4310f820622c..a91b791ebc1c 100644 --- a/cmd/clusterctl/client/cluster/mover_test.go +++ b/cmd/clusterctl/client/cluster/mover_test.go @@ -255,7 +255,7 @@ var moveTests = []struct { "/v1, Kind=Secret, ns1/cluster1-ca", "/v1, Kind=Secret, ns1/cluster1-kubeconfig", "bootstrap.cluster.x-k8s.io/v1alpha3, Kind=DummyBootstrapConfigTemplate, ns1/mp1", - "cluster.x-k8s.io/v1alpha3, Kind=MachinePool, ns1/mp1", + "exp.cluster.x-k8s.io/v1alpha3, Kind=MachinePool, ns1/mp1", "infrastructure.cluster.x-k8s.io/v1alpha3, Kind=DummyInfrastructureCluster, ns1/cluster1", "infrastructure.cluster.x-k8s.io/v1alpha3, Kind=DummyInfrastructureMachineTemplate, ns1/mp1", }, diff --git a/cmd/clusterctl/client/cluster/objectgraph_test.go b/cmd/clusterctl/client/cluster/objectgraph_test.go index 2181f921a939..fb33766ab1da 100644 --- a/cmd/clusterctl/client/cluster/objectgraph_test.go +++ b/cmd/clusterctl/client/cluster/objectgraph_test.go @@ -712,7 +712,7 @@ var objectGraphsTests = []struct { }, }, - "cluster.x-k8s.io/v1alpha3, Kind=MachinePool, ns1/mp1": { + "exp.cluster.x-k8s.io/v1alpha3, Kind=MachinePool, ns1/mp1": { owners: []string{ "cluster.x-k8s.io/v1alpha3, Kind=Cluster, ns1/cluster1", }, diff --git a/cmd/clusterctl/internal/test/fake_objects.go b/cmd/clusterctl/internal/test/fake_objects.go index 2020a20f5b5a..50c161e0cca8 100644 --- a/cmd/clusterctl/internal/test/fake_objects.go +++ b/cmd/clusterctl/internal/test/fake_objects.go @@ -31,6 +31,7 @@ import ( fakebootstrap "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/bootstrap" fakecontrolplane "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/controlplane" fakeinfrastructure "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/infrastructure" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" ) type FakeCluster struct { @@ -390,10 +391,10 @@ func (f *FakeMachinePool) Objs(cluster *clusterv1.Cluster) []runtime.Object { }, } - machinePool := &clusterv1.MachinePool{ + machinePool := &expv1.MachinePool{ TypeMeta: metav1.TypeMeta{ Kind: "MachinePool", - APIVersion: clusterv1.GroupVersion.String(), + APIVersion: expv1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Name: f.name, @@ -410,7 +411,7 @@ func (f *FakeMachinePool) Objs(cluster *clusterv1.Cluster) []runtime.Object { clusterv1.ClusterLabelName: cluster.Name, // Added by the machinePool controller (mirrors machinePoolt.spec.ClusterName) -- RECONCILED }, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ InfrastructureRef: corev1.ObjectReference{ @@ -955,7 +956,7 @@ func FakeCRDList() []*apiextensionslv1.CustomResourceDefinition { FakeCustomResourceDefinition(clusterv1.GroupVersion.Group, "Machine", version), FakeCustomResourceDefinition(clusterv1.GroupVersion.Group, "MachineDeployment", version), FakeCustomResourceDefinition(clusterv1.GroupVersion.Group, "MachineSet", version), - FakeCustomResourceDefinition(clusterv1.GroupVersion.Group, "MachinePool", version), + FakeCustomResourceDefinition(expv1.GroupVersion.Group, "MachinePool", version), FakeCustomResourceDefinition(fakecontrolplane.GroupVersion.Group, "DummyControlPlane", version), FakeCustomResourceDefinition(fakeinfrastructure.GroupVersion.Group, "DummyInfrastructureCluster", version), FakeCustomResourceDefinition(fakeinfrastructure.GroupVersion.Group, "DummyInfrastructureMachine", version), diff --git a/cmd/clusterctl/internal/test/fake_proxy.go b/cmd/clusterctl/internal/test/fake_proxy.go index 2fb4fc468df1..21338dc95eb7 100644 --- a/cmd/clusterctl/internal/test/fake_proxy.go +++ b/cmd/clusterctl/internal/test/fake_proxy.go @@ -27,6 +27,7 @@ import ( fakebootstrap "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/bootstrap" fakecontrolplane "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/controlplane" fakeinfrastructure "sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test/providers/infrastructure" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) @@ -44,6 +45,7 @@ func init() { _ = clientgoscheme.AddToScheme(FakeScheme) _ = clusterctlv1.AddToScheme(FakeScheme) _ = clusterv1.AddToScheme(FakeScheme) + _ = expv1.AddToScheme(FakeScheme) _ = apiextensionslv1.AddToScheme(FakeScheme) _ = fakebootstrap.AddToScheme(FakeScheme) diff --git a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml b/config/crd/bases/exp.cluster.x-k8s.io_machinepools.yaml similarity index 99% rename from config/crd/bases/cluster.x-k8s.io_machinepools.yaml rename to config/crd/bases/exp.cluster.x-k8s.io_machinepools.yaml index 1a875ddb822e..53a2fbc470d1 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml +++ b/config/crd/bases/exp.cluster.x-k8s.io_machinepools.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.2.5 creationTimestamp: null - name: machinepools.cluster.x-k8s.io + name: machinepools.exp.cluster.x-k8s.io spec: - group: cluster.x-k8s.io + group: exp.cluster.x-k8s.io names: categories: - cluster-api diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 9e95dcf098b7..95d7f7ca07cc 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -6,7 +6,7 @@ resources: - bases/cluster.x-k8s.io_machines.yaml - bases/cluster.x-k8s.io_machinesets.yaml - bases/cluster.x-k8s.io_machinedeployments.yaml -- bases/cluster.x-k8s.io_machinepools.yaml +- bases/exp.cluster.x-k8s.io_machinepools.yaml # +kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -16,7 +16,6 @@ patchesStrategicMerge: - patches/webhook_in_machines.yaml - patches/webhook_in_machinesets.yaml - patches/webhook_in_machinedeployments.yaml -- patches/webhook_in_machinepools.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. @@ -25,7 +24,6 @@ patchesStrategicMerge: - patches/cainjection_in_machines.yaml - patches/cainjection_in_machinesets.yaml - patches/cainjection_in_machinedeployments.yaml -- patches/cainjection_in_machinepools.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_machinepools.yaml b/config/crd/patches/cainjection_in_machinepools.yaml deleted file mode 100644 index b5329a85f8ba..000000000000 --- a/config/crd/patches/cainjection_in_machinepools.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: machinepools.cluster.x-k8s.io diff --git a/config/crd/patches/webhook_in_machinepools.yaml b/config/crd/patches/webhook_in_machinepools.yaml deleted file mode 100644 index 44ddf9ddc36a..000000000000 --- a/config/crd/patches/webhook_in_machinepools.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# The following patch enables conversion webhook for CRD -# CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: machinepools.cluster.x-k8s.io -spec: - conversion: - strategy: Webhook - webhook: - conversionReviewVersions: ["v1", "v1beta1"] - clientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert diff --git a/config/kustomization.yaml b/config/kustomization.yaml index 5d714e2bb5ba..1643fe7df625 100644 --- a/config/kustomization.yaml +++ b/config/kustomization.yaml @@ -21,12 +21,6 @@ patchesJson6902: kind: CustomResourceDefinition name: machinedeployments.cluster.x-k8s.io path: patch_crd_webhook_namespace.yaml -- target: - group: apiextensions.k8s.io - version: v1 - kind: CustomResourceDefinition - name: machinepools.cluster.x-k8s.io - path: patch_crd_webhook_namespace.yaml - target: group: apiextensions.k8s.io version: v1 diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index c25c3e8aa361..537796441df1 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -70,8 +70,8 @@ rules: - apiGroups: - cluster.x-k8s.io resources: - - machinepools - - machinepools/status + - machines + - machines/status verbs: - create - delete @@ -83,8 +83,8 @@ rules: - apiGroups: - cluster.x-k8s.io resources: - - machines - - machines/status + - machinesets + - machinesets/status verbs: - create - delete @@ -94,10 +94,19 @@ rules: - update - watch - apiGroups: - - cluster.x-k8s.io + - "" resources: - - machinesets - - machinesets/status + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - nodes verbs: - create - delete @@ -109,7 +118,7 @@ rules: - apiGroups: - "" resources: - - events + - secrets verbs: - create - get @@ -117,9 +126,9 @@ rules: - patch - watch - apiGroups: - - "" + - exp.cluster.x-k8s.io resources: - - nodes + - '*' verbs: - create - delete @@ -129,12 +138,15 @@ rules: - update - watch - apiGroups: - - "" + - exp.cluster.x-k8s.io resources: - - secrets + - machinepools + - machinepools/status verbs: - create + - delete - get - list - patch + - update - watch diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml index 21e8e771518d..6c2dc8a277aa 100644 --- a/config/webhook/manifests.yaml +++ b/config/webhook/manifests.yaml @@ -83,9 +83,9 @@ webhooks: service: name: webhook-service namespace: system - path: /mutate-cluster-x-k8s-io-v1alpha3-machinepool + path: /mutate-cluster-x-k8s-io-v1alpha3-machineset failurePolicy: Fail - name: default.machinepool.cluster.x-k8s.io + name: default.machineset.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -95,25 +95,25 @@ webhooks: - CREATE - UPDATE resources: - - machinepools + - machinesets - clientConfig: caBundle: Cg== service: name: webhook-service namespace: system - path: /mutate-cluster-x-k8s-io-v1alpha3-machineset + path: /mutate-exp-cluster-x-k8s-io-v1alpha3-machinepool failurePolicy: Fail - name: default.machineset.cluster.x-k8s.io + name: default.exp.machinepool.cluster.x-k8s.io rules: - apiGroups: - - cluster.x-k8s.io + - exp.cluster.x-k8s.io apiVersions: - v1alpha3 operations: - CREATE - UPDATE resources: - - machinesets + - machinepools --- apiVersion: admissionregistration.k8s.io/v1beta1 @@ -199,9 +199,9 @@ webhooks: service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1alpha3-machinepool + path: /validate-cluster-x-k8s-io-v1alpha3-machineset failurePolicy: Fail - name: validation.machinepool.cluster.x-k8s.io + name: validation.machineset.cluster.x-k8s.io rules: - apiGroups: - cluster.x-k8s.io @@ -211,22 +211,22 @@ webhooks: - CREATE - UPDATE resources: - - machinepools + - machinesets - clientConfig: caBundle: Cg== service: name: webhook-service namespace: system - path: /validate-cluster-x-k8s-io-v1alpha3-machineset + path: /validate-exp-cluster-x-k8s-io-v1alpha3-machinepool failurePolicy: Fail - name: validation.machineset.cluster.x-k8s.io + name: validation.exp.machinepool.cluster.x-k8s.io rules: - apiGroups: - - cluster.x-k8s.io + - exp.cluster.x-k8s.io apiVersions: - v1alpha3 operations: - CREATE - UPDATE resources: - - machinesets + - machinepools diff --git a/docs/book/src/developer/providers/v1alpha2-to-v1alpha3.md b/docs/book/src/developer/providers/v1alpha2-to-v1alpha3.md index 56a3cc875786..f683a2a7a20f 100644 --- a/docs/book/src/developer/providers/v1alpha2-to-v1alpha3.md +++ b/docs/book/src/developer/providers/v1alpha2-to-v1alpha3.md @@ -155,7 +155,7 @@ outside of the existing module. - A new field `Cluster.Spec.Paused` provides the ability to pause reconciliation on a Cluster and all associated objects. - A helper function `util.IsPaused` can be used on any Kubernetes object associated with a Cluster. -## Optional support for failure domains. +## [OPTIONAL] Support failure domains. An infrastructure provider may or may not implement the failure domains feature. Failure domains gives Cluster API just enough information to spread machines out reducing the risk of a target cluster failing due to a domain outage. @@ -370,3 +370,15 @@ commonLabels: cluster.x-k8s.io/v1alpha3: v1alpha2 cluster.x-k8s.io/v1beta1: v1alphaX,v1beta1 ``` + +# [OPTIONAL] Implement `--feature-gates` flag in main.go + +- Cluster API now ships with a new experimental package that lives under `exp/` containing both API types and controllers. +- Controller and types should always live behind a gate defined under the `feature/` package. +- If you're planning to support experimental features or API types in your provider or codebase, you can add + `feature.MutableGates.AddFlag(fs)` to your main.go when initializing command line flags. + For a full example, you can refer to the `main.go` in Cluster API or under `bootstrap/kubeadm/`. + +> NOTE: To enable experimental features users are required to set the same `--feature-gates` flag across providers. +> For example, if you want to enable MachinePool, you'll have to enable in both Cluster API deployment and the Kubeadm Bootstrap Provider. +> In the future, we'll revisit this user experience and provide a centralized way to configure gates across all Cluster API (inc. providers) controllers. diff --git a/exp/PROJECT b/exp/PROJECT new file mode 100644 index 000000000000..8f70fdaaaf57 --- /dev/null +++ b/exp/PROJECT @@ -0,0 +1,7 @@ +domain: cluster.x-k8s.io +repo: sigs.k8s.io/cluster-api/exp +version: "2" +resources: +- group: exp + kind: MachinePool + version: v1alpha3 diff --git a/exp/README.md b/exp/README.md new file mode 100644 index 000000000000..f4cf08c0e747 --- /dev/null +++ b/exp/README.md @@ -0,0 +1,9 @@ +# exp + +This subrepository holds experimental code and API types. + +**Warning**: Packages here are experimental and unreliable. Some may one day be promoted to the main repository, or they may be modified arbitrarily or even disappear altogether. + +In short, code in this subrepository is not subject to any compatibility or deprecation promise. + +TODO: Write policy around graduation and timelines. diff --git a/exp/api/v1alpha3/groupversion_info.go b/exp/api/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..832a031e9ff5 --- /dev/null +++ b/exp/api/v1alpha3/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2020 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha3 contains API Schema definitions for the exp v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=exp.cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "exp.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1alpha3/machinepool_types.go b/exp/api/v1alpha3/machinepool_types.go similarity index 96% rename from api/v1alpha3/machinepool_types.go rename to exp/api/v1alpha3/machinepool_types.go index 30a9b39e3abd..55662b118236 100644 --- a/api/v1alpha3/machinepool_types.go +++ b/exp/api/v1alpha3/machinepool_types.go @@ -19,12 +19,13 @@ package v1alpha3 import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" capierrors "sigs.k8s.io/cluster-api/errors" ) const ( // MachinePoolFinalizer is used to ensure deletion of dependencies (nodes, infra). - MachinePoolFinalizer = "machinepool.cluster.x-k8s.io" + MachinePoolFinalizer = "machinepool.exp.cluster.x-k8s.io" ) // ANCHOR: MachinePoolSpec @@ -40,12 +41,12 @@ type MachinePoolSpec struct { Replicas *int32 `json:"replicas,omitempty"` // Template describes the machines that will be created. - Template MachineTemplateSpec `json:"template"` + Template clusterv1.MachineTemplateSpec `json:"template"` // The deployment strategy to use to replace existing machine instances with // new ones. // +optional - Strategy *MachineDeploymentStrategy `json:"strategy,omitempty"` + Strategy *clusterv1.MachineDeploymentStrategy `json:"strategy,omitempty"` // Minimum number of seconds for which a newly created machine instances should // be ready. diff --git a/api/v1alpha3/machinepool_webhook.go b/exp/api/v1alpha3/machinepool_webhook.go similarity index 87% rename from api/v1alpha3/machinepool_webhook.go rename to exp/api/v1alpha3/machinepool_webhook.go index e93861646914..9a227ca19734 100644 --- a/api/v1alpha3/machinepool_webhook.go +++ b/exp/api/v1alpha3/machinepool_webhook.go @@ -32,8 +32,8 @@ func (m *MachinePool) SetupWebhookWithManager(mgr ctrl.Manager) error { Complete() } -// +kubebuilder:webhook:verbs=create;update,path=/validate-cluster-x-k8s-io-v1alpha3-machinepool,mutating=false,failurePolicy=fail,groups=cluster.x-k8s.io,resources=machinepools,versions=v1alpha3,name=validation.machinepool.cluster.x-k8s.io -// +kubebuilder:webhook:verbs=create;update,path=/mutate-cluster-x-k8s-io-v1alpha3-machinepool,mutating=true,failurePolicy=fail,groups=cluster.x-k8s.io,resources=machinepools,versions=v1alpha3,name=default.machinepool.cluster.x-k8s.io +// +kubebuilder:webhook:verbs=create;update,path=/validate-exp-cluster-x-k8s-io-v1alpha3-machinepool,mutating=false,failurePolicy=fail,groups=exp.cluster.x-k8s.io,resources=machinepools,versions=v1alpha3,name=validation.exp.machinepool.cluster.x-k8s.io +// +kubebuilder:webhook:verbs=create;update,path=/mutate-exp-cluster-x-k8s-io-v1alpha3-machinepool,mutating=true,failurePolicy=fail,groups=exp.cluster.x-k8s.io,resources=machinepools,versions=v1alpha3,name=default.exp.machinepool.cluster.x-k8s.io var _ webhook.Defaulter = &MachinePool{} var _ webhook.Validator = &MachinePool{} diff --git a/api/v1alpha3/machinepool_webhook_test.go b/exp/api/v1alpha3/machinepool_webhook_test.go similarity index 76% rename from api/v1alpha3/machinepool_webhook_test.go rename to exp/api/v1alpha3/machinepool_webhook_test.go index 2d9aca7bcebb..2c29c68c355f 100644 --- a/api/v1alpha3/machinepool_webhook_test.go +++ b/exp/api/v1alpha3/machinepool_webhook_test.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" + clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" ) func TestMachinePoolDefault(t *testing.T) { @@ -33,9 +34,9 @@ func TestMachinePoolDefault(t *testing.T) { Namespace: "foobar", }, Spec: MachinePoolSpec{ - Template: MachineTemplateSpec{ - Spec: MachineSpec{ - Bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{}}, + Template: clusterv1.MachineTemplateSpec{ + Spec: clusterv1.MachineSpec{ + Bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{}}, }, }, }, @@ -50,22 +51,22 @@ func TestMachinePoolDefault(t *testing.T) { func TestMachinePoolBootstrapValidation(t *testing.T) { tests := []struct { name string - bootstrap Bootstrap + bootstrap clusterv1.Bootstrap expectErr bool }{ { name: "should return error if configref and data are nil", - bootstrap: Bootstrap{ConfigRef: nil, DataSecretName: nil}, + bootstrap: clusterv1.Bootstrap{ConfigRef: nil, DataSecretName: nil}, expectErr: true, }, { name: "should not return error if dataSecretName is set", - bootstrap: Bootstrap{ConfigRef: nil, DataSecretName: pointer.StringPtr("test")}, + bootstrap: clusterv1.Bootstrap{ConfigRef: nil, DataSecretName: pointer.StringPtr("test")}, expectErr: false, }, { name: "should not return error if config ref is set", - bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{}, Data: nil}, + bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{}, Data: nil}, expectErr: false, }, } @@ -75,8 +76,8 @@ func TestMachinePoolBootstrapValidation(t *testing.T) { g := NewWithT(t) m := &MachinePool{ Spec: MachinePoolSpec{ - Template: MachineTemplateSpec{ - Spec: MachineSpec{ + Template: clusterv1.MachineTemplateSpec{ + Spec: clusterv1.MachineSpec{ Bootstrap: tt.bootstrap, }, }, @@ -97,7 +98,7 @@ func TestMachinePoolNamespaceValidation(t *testing.T) { tests := []struct { name string expectErr bool - bootstrap Bootstrap + bootstrap clusterv1.Bootstrap infraRef corev1.ObjectReference namespace string }{ @@ -105,28 +106,28 @@ func TestMachinePoolNamespaceValidation(t *testing.T) { name: "should succeed if all namespaces match", expectErr: false, namespace: "foobar", - bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar"}}, + bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar"}}, infraRef: corev1.ObjectReference{Namespace: "foobar"}, }, { name: "should return error if namespace and bootstrap namespace don't match", expectErr: true, namespace: "foobar", - bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar123"}}, + bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar123"}}, infraRef: corev1.ObjectReference{Namespace: "foobar"}, }, { name: "should return error if namespace and infrastructure ref namespace don't match", expectErr: true, namespace: "foobar", - bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar"}}, + bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar"}}, infraRef: corev1.ObjectReference{Namespace: "foobar123"}, }, { name: "should return error if no namespaces match", expectErr: true, namespace: "foobar1", - bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar2"}}, + bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{Namespace: "foobar2"}}, infraRef: corev1.ObjectReference{Namespace: "foobar3"}, }, } @@ -138,8 +139,8 @@ func TestMachinePoolNamespaceValidation(t *testing.T) { m := &MachinePool{ ObjectMeta: metav1.ObjectMeta{Namespace: tt.namespace}, Spec: MachinePoolSpec{ - Template: MachineTemplateSpec{ - Spec: MachineSpec{ + Template: clusterv1.MachineTemplateSpec{ + Spec: clusterv1.MachineSpec{ Bootstrap: tt.bootstrap, InfrastructureRef: tt.infraRef, }, @@ -186,9 +187,9 @@ func TestMachinePoolClusterNameImmutable(t *testing.T) { newMP := &MachinePool{ Spec: MachinePoolSpec{ ClusterName: tt.newClusterName, - Template: MachineTemplateSpec{ - Spec: MachineSpec{ - Bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{}}, + Template: clusterv1.MachineTemplateSpec{ + Spec: clusterv1.MachineSpec{ + Bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{}}, }, }, }, @@ -197,9 +198,9 @@ func TestMachinePoolClusterNameImmutable(t *testing.T) { oldMP := &MachinePool{ Spec: MachinePoolSpec{ ClusterName: tt.oldClusterName, - Template: MachineTemplateSpec{ - Spec: MachineSpec{ - Bootstrap: Bootstrap{ConfigRef: &corev1.ObjectReference{}}, + Template: clusterv1.MachineTemplateSpec{ + Spec: clusterv1.MachineSpec{ + Bootstrap: clusterv1.Bootstrap{ConfigRef: &corev1.ObjectReference{}}, }, }, }, diff --git a/exp/api/v1alpha3/zz_generated.deepcopy.go b/exp/api/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..1204c841d48b --- /dev/null +++ b/exp/api/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,153 @@ +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + apiv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" + "sigs.k8s.io/cluster-api/errors" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePool) DeepCopyInto(out *MachinePool) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePool. +func (in *MachinePool) DeepCopy() *MachinePool { + if in == nil { + return nil + } + out := new(MachinePool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachinePool) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolList) DeepCopyInto(out *MachinePoolList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachinePool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolList. +func (in *MachinePoolList) DeepCopy() *MachinePoolList { + if in == nil { + return nil + } + out := new(MachinePoolList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachinePoolList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolSpec) DeepCopyInto(out *MachinePoolSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Template.DeepCopyInto(&out.Template) + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(apiv1alpha3.MachineDeploymentStrategy) + (*in).DeepCopyInto(*out) + } + if in.MinReadySeconds != nil { + in, out := &in.MinReadySeconds, &out.MinReadySeconds + *out = new(int32) + **out = **in + } + if in.ProviderIDList != nil { + in, out := &in.ProviderIDList, &out.ProviderIDList + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolSpec. +func (in *MachinePoolSpec) DeepCopy() *MachinePoolSpec { + if in == nil { + return nil + } + out := new(MachinePoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolStatus) DeepCopyInto(out *MachinePoolStatus) { + *out = *in + if in.NodeRefs != nil { + in, out := &in.NodeRefs, &out.NodeRefs + *out = make([]v1.ObjectReference, len(*in)) + copy(*out, *in) + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachinePoolStatusFailure) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolStatus. +func (in *MachinePoolStatus) DeepCopy() *MachinePoolStatus { + if in == nil { + return nil + } + out := new(MachinePoolStatus) + in.DeepCopyInto(out) + return out +} diff --git a/exp/controllers/exp.go b/exp/controllers/exp.go new file mode 100644 index 000000000000..e3944040dcdf --- /dev/null +++ b/exp/controllers/exp.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +// This file adds RBAC permissions to the Cluster API manager to operate on all objects in the experimental API group. + +// +kubebuilder:rbac:groups=exp.cluster.x-k8s.io,resources=*,verbs=get;list;watch;create;update;patch;delete diff --git a/controllers/machinepool_controller.go b/exp/controllers/machinepool_controller.go similarity index 91% rename from controllers/machinepool_controller.go rename to exp/controllers/machinepool_controller.go index ddb6adf25c66..db70093b1aea 100644 --- a/controllers/machinepool_controller.go +++ b/exp/controllers/machinepool_controller.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Kubernetes Authors. +Copyright 2020 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ import ( "sigs.k8s.io/cluster-api/controllers/external" "sigs.k8s.io/cluster-api/controllers/remote" capierrors "sigs.k8s.io/cluster-api/errors" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/patch" ctrl "sigs.k8s.io/controller-runtime" @@ -46,7 +47,7 @@ import ( // +kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch // +kubebuilder:rbac:groups=core,resources=nodes,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io;bootstrap.cluster.x-k8s.io,resources=*,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=exp.cluster.x-k8s.io,resources=machinepools;machinepools/status,verbs=get;list;watch;create;update;patch;delete // MachinePoolReconciler reconciles a MachinePool object type MachinePoolReconciler struct { @@ -62,7 +63,7 @@ type MachinePoolReconciler struct { func (r *MachinePoolReconciler) SetupWithManager(mgr ctrl.Manager, options controller.Options) error { c, err := ctrl.NewControllerManagedBy(mgr). - For(&clusterv1.MachinePool{}). + For(&expv1.MachinePool{}). WithOptions(options). Build(r) if err != nil { @@ -80,7 +81,7 @@ func (r *MachinePoolReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, rete ctx := context.Background() logger := r.Log.WithValues("machinepool", req.NamespacedName) - mp := &clusterv1.MachinePool{} + mp := &expv1.MachinePool{} if err := r.Client.Get(ctx, req.NamespacedName, mp); err != nil { if apierrors.IsNotFound(err) { // Object not found, return. Created objects are automatically garbage collected. @@ -135,7 +136,7 @@ func (r *MachinePoolReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, rete return r.reconcile(ctx, cluster, mp) } -func (r *MachinePoolReconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, mp *clusterv1.MachinePool) (ctrl.Result, error) { +func (r *MachinePoolReconciler) reconcile(ctx context.Context, cluster *clusterv1.Cluster, mp *expv1.MachinePool) (ctrl.Result, error) { logger := r.Log.WithValues("machinepool", mp.Name, "namespace", mp.Namespace) logger = logger.WithValues("cluster", cluster.Name) @@ -148,7 +149,7 @@ func (r *MachinePoolReconciler) reconcile(ctx context.Context, cluster *clusterv }) // If the MachinePool doesn't have a finalizer, add one. - controllerutil.AddFinalizer(mp, clusterv1.MachinePoolFinalizer) + controllerutil.AddFinalizer(mp, expv1.MachinePoolFinalizer) // Call the inner reconciliation methods. reconciliationErrors := []error{ @@ -176,7 +177,7 @@ func (r *MachinePoolReconciler) reconcile(ctx context.Context, cluster *clusterv return res, kerrors.NewAggregate(errs) } -func (r *MachinePoolReconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Cluster, mp *clusterv1.MachinePool) (ctrl.Result, error) { +func (r *MachinePoolReconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Cluster, mp *expv1.MachinePool) (ctrl.Result, error) { if ok, err := r.reconcileDeleteExternal(ctx, mp); !ok || err != nil { // Return early and don't remove the finalizer if we got an error or // the external reconciliation deletion isn't ready. @@ -188,11 +189,11 @@ func (r *MachinePoolReconciler) reconcileDelete(ctx context.Context, cluster *cl return ctrl.Result{}, err } - controllerutil.RemoveFinalizer(mp, clusterv1.MachinePoolFinalizer) + controllerutil.RemoveFinalizer(mp, expv1.MachinePoolFinalizer) return ctrl.Result{}, nil } -func (r *MachinePoolReconciler) reconcileDeleteNodes(ctx context.Context, cluster *clusterv1.Cluster, machinepool *clusterv1.MachinePool) error { +func (r *MachinePoolReconciler) reconcileDeleteNodes(ctx context.Context, cluster *clusterv1.Cluster, machinepool *expv1.MachinePool) error { if len(machinepool.Status.NodeRefs) == 0 { return nil } @@ -209,7 +210,7 @@ func (r *MachinePoolReconciler) reconcileDeleteNodes(ctx context.Context, cluste } // reconcileDeleteExternal tries to delete external references, returning true if it cannot find any. -func (r *MachinePoolReconciler) reconcileDeleteExternal(ctx context.Context, m *clusterv1.MachinePool) (bool, error) { +func (r *MachinePoolReconciler) reconcileDeleteExternal(ctx context.Context, m *expv1.MachinePool) (bool, error) { objects := []*unstructured.Unstructured{} references := []*corev1.ObjectReference{ m.Spec.Template.Spec.Bootstrap.ConfigRef, diff --git a/controllers/machinepool_controller_noderef.go b/exp/controllers/machinepool_controller_noderef.go similarity index 98% rename from controllers/machinepool_controller_noderef.go rename to exp/controllers/machinepool_controller_noderef.go index 1266f521fa65..9b9852be5033 100644 --- a/controllers/machinepool_controller_noderef.go +++ b/exp/controllers/machinepool_controller_noderef.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/cluster-api/controllers/noderefutil" "sigs.k8s.io/cluster-api/controllers/remote" capierrors "sigs.k8s.io/cluster-api/errors" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -42,7 +43,7 @@ type getNodeReferencesResult struct { ready int } -func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, cluster *clusterv1.Cluster, mp *clusterv1.MachinePool) error { +func (r *MachinePoolReconciler) reconcileNodeRefs(ctx context.Context, cluster *clusterv1.Cluster, mp *expv1.MachinePool) error { logger := r.Log.WithValues("machinepool", mp.Name, "namespace", mp.Namespace) // Check that the MachinePool hasn't been deleted or in the process. if !mp.DeletionTimestamp.IsZero() { diff --git a/controllers/machinepool_controller_noderef_test.go b/exp/controllers/machinepool_controller_noderef_test.go similarity index 100% rename from controllers/machinepool_controller_noderef_test.go rename to exp/controllers/machinepool_controller_noderef_test.go diff --git a/controllers/machinepool_controller_phases.go b/exp/controllers/machinepool_controller_phases.go similarity index 91% rename from controllers/machinepool_controller_phases.go rename to exp/controllers/machinepool_controller_phases.go index 09105388af76..7ed61f1f0b16 100644 --- a/controllers/machinepool_controller_phases.go +++ b/exp/controllers/machinepool_controller_phases.go @@ -21,6 +21,7 @@ import ( "fmt" "reflect" "strings" + "time" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" @@ -30,6 +31,7 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" "sigs.k8s.io/cluster-api/controllers/external" capierrors "sigs.k8s.io/cluster-api/errors" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/patch" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -37,40 +39,44 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" ) -func (r *MachinePoolReconciler) reconcilePhase(mp *clusterv1.MachinePool) { +var ( + externalReadyWait = 30 * time.Second +) + +func (r *MachinePoolReconciler) reconcilePhase(mp *expv1.MachinePool) { // Set the phase to "pending" if nil. if mp.Status.Phase == "" { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhasePending) + mp.Status.SetTypedPhase(expv1.MachinePoolPhasePending) } // Set the phase to "provisioning" if bootstrap is ready and the infrastructure isn't. if mp.Status.BootstrapReady && !mp.Status.InfrastructureReady { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhaseProvisioning) + mp.Status.SetTypedPhase(expv1.MachinePoolPhaseProvisioning) } // Set the phase to "provisioned" if the infrastructure is ready. if len(mp.Status.NodeRefs) != 0 { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhaseProvisioned) + mp.Status.SetTypedPhase(expv1.MachinePoolPhaseProvisioned) } // Set the phase to "running" if there is a NodeRef field. if mp.Status.InfrastructureReady && len(mp.Status.NodeRefs) == int(mp.Status.ReadyReplicas) { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhaseRunning) + mp.Status.SetTypedPhase(expv1.MachinePoolPhaseRunning) } // Set the phase to "failed" if any of Status.FailureReason or Status.FailureMessage is not-nil. if mp.Status.FailureReason != nil || mp.Status.FailureMessage != nil { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhaseFailed) + mp.Status.SetTypedPhase(expv1.MachinePoolPhaseFailed) } // Set the phase to "deleting" if the deletion timestamp is set. if !mp.DeletionTimestamp.IsZero() { - mp.Status.SetTypedPhase(clusterv1.MachinePoolPhaseDeleting) + mp.Status.SetTypedPhase(expv1.MachinePoolPhaseDeleting) } } // reconcileExternal handles generic unstructured objects referenced by a MachinePool. -func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.MachinePool, ref *corev1.ObjectReference) (external.ReconcileOutput, error) { +func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, cluster *clusterv1.Cluster, m *expv1.MachinePool, ref *corev1.ObjectReference) (external.ReconcileOutput, error) { logger := r.Log.WithValues("machinepool", m.Name, "namespace", m.Namespace) obj, err := external.Get(ctx, r.Client, ref, m.Namespace) @@ -119,7 +125,7 @@ func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, cluster * logger.Info("Adding watcher on external object", "gvk", obj.GroupVersionKind()) err := r.controller.Watch( &source.Kind{Type: obj}, - &handler.EnqueueRequestForOwner{OwnerType: &clusterv1.MachinePool{}}, + &handler.EnqueueRequestForOwner{OwnerType: &expv1.MachinePool{}}, ) if err != nil { r.externalWatchers.Delete(obj.GroupVersionKind().String()) @@ -147,7 +153,7 @@ func (r *MachinePoolReconciler) reconcileExternal(ctx context.Context, cluster * } // reconcileBootstrap reconciles the Spec.Bootstrap.ConfigRef object on a MachinePool. -func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.MachinePool) error { +func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, cluster *clusterv1.Cluster, m *expv1.MachinePool) error { // Call generic external reconciler if we have an external reference. var bootstrapConfig *unstructured.Unstructured if m.Spec.Template.Spec.Bootstrap.ConfigRef != nil { @@ -196,7 +202,7 @@ func (r *MachinePoolReconciler) reconcileBootstrap(ctx context.Context, cluster } // reconcileInfrastructure reconciles the Spec.InfrastructureRef object on a MachinePool. -func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, cluster *clusterv1.Cluster, mp *clusterv1.MachinePool) error { +func (r *MachinePoolReconciler) reconcileInfrastructure(ctx context.Context, cluster *clusterv1.Cluster, mp *expv1.MachinePool) error { // Call generic external reconciler. infraReconcileResult, err := r.reconcileExternal(ctx, cluster, mp, &mp.Spec.Template.Spec.InfrastructureRef) if err != nil { diff --git a/controllers/machinepool_controller_phases_test.go b/exp/controllers/machinepool_controller_phases_test.go similarity index 92% rename from controllers/machinepool_controller_phases_test.go rename to exp/controllers/machinepool_controller_phases_test.go index d7943610742b..92a17f5659ee 100644 --- a/controllers/machinepool_controller_phases_test.go +++ b/exp/controllers/machinepool_controller_phases_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/cluster-api/util/kubeconfig" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/log" @@ -50,12 +51,12 @@ var _ = Describe("Reconcile MachinePool Phases", func() { }, } - defaultMachinePool := clusterv1.MachinePool{ + defaultMachinePool := expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinepool-test", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: defaultCluster.Name, Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ @@ -154,7 +155,7 @@ var _ = Describe("Reconcile MachinePool Phases", func() { Expect(res.Requeue).To(BeTrue()) r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhasePending)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhasePending)) }) It("Should set `Provisioning` when bootstrap is ready", func() { @@ -180,7 +181,7 @@ var _ = Describe("Reconcile MachinePool Phases", func() { Expect(res.Requeue).To(BeTrue()) r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseProvisioning)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseProvisioning)) }) It("Should set `Running` when bootstrap and infra is ready", func() { @@ -225,7 +226,7 @@ var _ = Describe("Reconcile MachinePool Phases", func() { machinepool.Status.ReadyReplicas = 1 r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseRunning)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseRunning)) }) It("Should set `Running` when bootstrap, infra, and NodeRef is ready", func() { @@ -279,7 +280,7 @@ var _ = Describe("Reconcile MachinePool Phases", func() { machinepool.Status.ReadyReplicas = 1 r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseRunning)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseRunning)) }) It("Should set `Provisioned` when there is a NodeRef but infra is not ready ", func() { @@ -308,7 +309,7 @@ var _ = Describe("Reconcile MachinePool Phases", func() { Expect(res.Requeue).To(BeTrue()) r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseProvisioned)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseProvisioned)) }) It("Should set `Deleting` when MachinePool is being deleted", func() { @@ -359,12 +360,12 @@ var _ = Describe("Reconcile MachinePool Phases", func() { Expect(res.Requeue).To(BeFalse()) r.reconcilePhase(machinepool) - Expect(machinepool.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseDeleting)) + Expect(machinepool.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseDeleting)) }) }) func TestReconcileMachinePoolBootstrap(t *testing.T) { - defaultMachinePool := clusterv1.MachinePool{ + defaultMachinePool := expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinepool-test", Namespace: "default", @@ -372,7 +373,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { clusterv1.ClusterLabelName: "test-cluster", }, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -397,9 +398,9 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { testCases := []struct { name string bootstrapConfig map[string]interface{} - machinepool *clusterv1.MachinePool + machinepool *expv1.MachinePool expectError bool - expected func(g *WithT, m *clusterv1.MachinePool) + expected func(g *WithT, m *expv1.MachinePool) }{ { name: "new machinepool, bootstrap config ready with data", @@ -417,7 +418,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { }, }, expectError: false, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeTrue()) g.Expect(m.Spec.Template.Spec.Bootstrap.DataSecretName).ToNot(BeNil()) g.Expect(*m.Spec.Template.Spec.Bootstrap.DataSecretName).To(ContainSubstring("secret-data")) @@ -438,7 +439,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { }, }, expectError: true, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeFalse()) g.Expect(m.Spec.Template.Spec.Bootstrap.Data).To(BeNil()) }, @@ -456,7 +457,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { "status": map[string]interface{}{}, }, expectError: true, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeFalse()) }, }, @@ -473,7 +474,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { "status": map[string]interface{}{}, }, expectError: true, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeFalse()) }, }, @@ -506,12 +507,12 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { "dataSecretName": "secret-data", }, }, - machinepool: &clusterv1.MachinePool{ + machinepool: &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "bootstrap-test-existing", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -525,12 +526,12 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { }, }, }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ BootstrapReady: true, }, }, expectError: false, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeTrue()) g.Expect(*m.Spec.Template.Spec.Bootstrap.Data).To(Equal("#!/bin/bash ... data")) }, @@ -550,12 +551,12 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { "data": "#!/bin/bash ... data", }, }, - machinepool: &clusterv1.MachinePool{ + machinepool: &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "bootstrap-test-existing", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -569,12 +570,12 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { }, }, }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ BootstrapReady: true, }, }, expectError: false, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.BootstrapReady).To(BeTrue()) }, }, @@ -612,7 +613,7 @@ func TestReconcileMachinePoolBootstrap(t *testing.T) { } func TestReconcileMachinePoolInfrastructure(t *testing.T) { - defaultMachinePool := clusterv1.MachinePool{ + defaultMachinePool := expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinepool-test", Namespace: "default", @@ -620,7 +621,7 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { clusterv1.ClusterLabelName: "test-cluster", }, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -651,11 +652,11 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { name string bootstrapConfig map[string]interface{} infraConfig map[string]interface{} - machinepool *clusterv1.MachinePool + machinepool *expv1.MachinePool expectError bool expectChanged bool expectRequeueAfter bool - expected func(g *WithT, m *clusterv1.MachinePool) + expected func(g *WithT, m *expv1.MachinePool) }{ { name: "new machinepool, infrastructure config ready", @@ -687,18 +688,18 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { }, expectError: false, expectChanged: true, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.InfrastructureReady).To(BeTrue()) }, }, { name: "ready bootstrap, infra, and nodeRef, machinepool is running, infra object is deleted, expect failed", - machinepool: &clusterv1.MachinePool{ + machinepool: &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinepool-test", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -716,7 +717,7 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { }, }, }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ BootstrapReady: true, InfrastructureReady: true, NodeRefs: []corev1.ObjectReference{{Kind: "Node", Name: "machinepool-test-node"}}, @@ -742,11 +743,11 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { }, expectError: true, expectRequeueAfter: true, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.InfrastructureReady).To(BeTrue()) g.Expect(m.Status.FailureMessage).ToNot(BeNil()) g.Expect(m.Status.FailureReason).ToNot(BeNil()) - g.Expect(m.Status.GetTypedPhase()).To(Equal(clusterv1.MachinePoolPhaseFailed)) + g.Expect(m.Status.GetTypedPhase()).To(Equal(expv1.MachinePoolPhaseFailed)) }, }, { @@ -782,7 +783,7 @@ func TestReconcileMachinePoolInfrastructure(t *testing.T) { }, expectError: false, expectChanged: false, - expected: func(g *WithT, m *clusterv1.MachinePool) { + expected: func(g *WithT, m *expv1.MachinePool) { g.Expect(m.Status.InfrastructureReady).To(BeFalse()) }, }, diff --git a/controllers/machinepool_controller_test.go b/exp/controllers/machinepool_controller_test.go similarity index 90% rename from controllers/machinepool_controller_test.go rename to exp/controllers/machinepool_controller_test.go index e01442f23ee1..31b27040208c 100644 --- a/controllers/machinepool_controller_test.go +++ b/exp/controllers/machinepool_controller_test.go @@ -27,12 +27,12 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" + clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - - clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" ) func TestMachinePoolFinalizer(t *testing.T) { @@ -44,12 +44,12 @@ func TestMachinePoolFinalizer(t *testing.T) { }, } - machinePoolValidCluster := &clusterv1.MachinePool{ + machinePoolValidCluster := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinePool1", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Replicas: pointer.Int32Ptr(1), Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ @@ -62,13 +62,13 @@ func TestMachinePoolFinalizer(t *testing.T) { }, } - machinePoolWithFinalizer := &clusterv1.MachinePool{ + machinePoolWithFinalizer := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinePool2", Namespace: "default", Finalizers: []string{"some-other-finalizer"}, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Replicas: pointer.Int32Ptr(1), Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ @@ -84,7 +84,7 @@ func TestMachinePoolFinalizer(t *testing.T) { testCases := []struct { name string request reconcile.Request - m *clusterv1.MachinePool + m *expv1.MachinePool expectedFinalizers []string }{ { @@ -93,7 +93,7 @@ func TestMachinePoolFinalizer(t *testing.T) { NamespacedName: util.ObjectKey(machinePoolValidCluster), }, m: machinePoolValidCluster, - expectedFinalizers: []string{clusterv1.MachinePoolFinalizer}, + expectedFinalizers: []string{expv1.MachinePoolFinalizer}, }, { name: "should append the machinePool finalizer to the machinePool if it already has a finalizer", @@ -101,7 +101,7 @@ func TestMachinePoolFinalizer(t *testing.T) { NamespacedName: util.ObjectKey(machinePoolWithFinalizer), }, m: machinePoolWithFinalizer, - expectedFinalizers: []string{"some-other-finalizer", clusterv1.MachinePoolFinalizer}, + expectedFinalizers: []string{"some-other-finalizer", expv1.MachinePoolFinalizer}, }, } @@ -125,7 +125,7 @@ func TestMachinePoolFinalizer(t *testing.T) { _, _ = mr.Reconcile(tc.request) key := client.ObjectKey{Namespace: tc.m.Namespace, Name: tc.m.Name} - var actual clusterv1.MachinePool + var actual expv1.MachinePool if len(tc.expectedFinalizers) > 0 { g.Expect(mr.Client.Get(ctx, key, &actual)).To(Succeed()) g.Expect(actual.Finalizers).ToNot(BeEmpty()) @@ -144,22 +144,22 @@ func TestMachinePoolOwnerReference(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "test-cluster"}, } - machinePoolInvalidCluster := &clusterv1.MachinePool{ + machinePoolInvalidCluster := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinePool1", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "invalid", }, } - machinePoolValidCluster := &clusterv1.MachinePool{ + machinePoolValidCluster := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinePool2", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -171,7 +171,7 @@ func TestMachinePoolOwnerReference(t *testing.T) { }, } - machinePoolValidMachinePool := &clusterv1.MachinePool{ + machinePoolValidMachinePool := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "machinePool3", Namespace: "default", @@ -179,7 +179,7 @@ func TestMachinePoolOwnerReference(t *testing.T) { clusterv1.ClusterLabelName: "valid-cluster", }, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ Template: clusterv1.MachineTemplateSpec{ Spec: clusterv1.MachineSpec{ Bootstrap: clusterv1.Bootstrap{ @@ -194,7 +194,7 @@ func TestMachinePoolOwnerReference(t *testing.T) { testCases := []struct { name string request reconcile.Request - m *clusterv1.MachinePool + m *expv1.MachinePool expectedOR []metav1.OwnerReference }{ { @@ -235,7 +235,7 @@ func TestMachinePoolOwnerReference(t *testing.T) { _, _ = mr.Reconcile(tc.request) key := client.ObjectKey{Namespace: tc.m.Namespace, Name: tc.m.Name} - var actual clusterv1.MachinePool + var actual expv1.MachinePool if len(tc.expectedOR) > 0 { g.Expect(mr.Client.Get(ctx, key, &actual)).To(Succeed()) g.Expect(actual.OwnerReferences).To(Equal(tc.expectedOR)) @@ -295,17 +295,17 @@ func TestReconcileMachinePoolRequest(t *testing.T) { err bool } testCases := []struct { - machinePool clusterv1.MachinePool + machinePool expv1.MachinePool expected expected }{ { - machinePool: clusterv1.MachinePool{ + machinePool: expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "created", Namespace: "default", - Finalizers: []string{clusterv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, + Finalizers: []string{expv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "test-cluster", ProviderIDList: []string{"test://id-1"}, Replicas: pointer.Int32Ptr(1), @@ -321,7 +321,7 @@ func TestReconcileMachinePoolRequest(t *testing.T) { }, }, }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ Replicas: 1, ReadyReplicas: 1, NodeRefs: []corev1.ObjectReference{ @@ -335,13 +335,13 @@ func TestReconcileMachinePoolRequest(t *testing.T) { }, }, { - machinePool: clusterv1.MachinePool{ + machinePool: expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "updated", Namespace: "default", - Finalizers: []string{clusterv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, + Finalizers: []string{expv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "test-cluster", ProviderIDList: []string{"test://id-1"}, Replicas: pointer.Int32Ptr(1), @@ -356,7 +356,7 @@ func TestReconcileMachinePoolRequest(t *testing.T) { }, }, }, - Status: clusterv1.MachinePoolStatus{ + Status: expv1.MachinePoolStatus{ Replicas: 1, ReadyReplicas: 1, NodeRefs: []corev1.ObjectReference{ @@ -370,17 +370,17 @@ func TestReconcileMachinePoolRequest(t *testing.T) { }, }, { - machinePool: clusterv1.MachinePool{ + machinePool: expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "deleted", Namespace: "default", Labels: map[string]string{ clusterv1.MachineControlPlaneLabelName: "", }, - Finalizers: []string{clusterv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, + Finalizers: []string{expv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, DeletionTimestamp: &time, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "test-cluster", Replicas: pointer.Int32Ptr(1), Template: clusterv1.MachineTemplateSpec{ @@ -461,12 +461,12 @@ func TestReconcileMachinePoolDeleteExternal(t *testing.T) { }, } - machinePool := &clusterv1.MachinePool{ + machinePool := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "delete", Namespace: "default", }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "test-cluster", Replicas: pointer.Int32Ptr(1), Template: clusterv1.MachineTemplateSpec{ @@ -569,14 +569,14 @@ func TestRemoveMachinePoolFinalizerAfterDeleteReconcile(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Namespace: "default", Name: "test-cluster"}, } - m := &clusterv1.MachinePool{ + m := &expv1.MachinePool{ ObjectMeta: metav1.ObjectMeta{ Name: "delete123", Namespace: "default", - Finalizers: []string{clusterv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, + Finalizers: []string{expv1.MachinePoolFinalizer, metav1.FinalizerDeleteDependents}, DeletionTimestamp: &dt, }, - Spec: clusterv1.MachinePoolSpec{ + Spec: expv1.MachinePoolSpec{ ClusterName: "test-cluster", Replicas: pointer.Int32Ptr(1), Template: clusterv1.MachineTemplateSpec{ diff --git a/exp/controllers/suite_test.go b/exp/controllers/suite_test.go new file mode 100644 index 000000000000..d90d1e1dfac3 --- /dev/null +++ b/exp/controllers/suite_test.go @@ -0,0 +1,130 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "path/filepath" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/klog" + "k8s.io/klog/klogr" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + "sigs.k8s.io/controller-runtime/pkg/log" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/manager" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" + "sigs.k8s.io/cluster-api/controllers/external" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + // +kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +func init() { + klog.InitFlags(nil) + logf.SetLogger(klogr.New()) + + // Register required object kinds with global scheme. + _ = apiextensionsv1.AddToScheme(scheme.Scheme) + _ = clusterv1.AddToScheme(scheme.Scheme) + _ = expv1.AddToScheme(scheme.Scheme) +} + +var ( + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + mgr manager.Manager + doneMgr = make(chan struct{}) + ctx = context.Background() +) + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +var _ = BeforeSuite(func(done Done) { + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDs: []runtime.Object{ + external.TestGenericBootstrapCRD, + external.TestGenericBootstrapTemplateCRD, + external.TestGenericInfrastructureCRD, + external.TestGenericInfrastructureTemplateCRD, + }, + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + } + + var err error + cfg, err = testEnv.Start() + Expect(err).ToNot(HaveOccurred()) + Expect(cfg).ToNot(BeNil()) + + // +kubebuilder:scaffold:scheme + + By("setting up a new manager") + mgr, err = manager.New(cfg, manager.Options{ + Scheme: scheme.Scheme, + MetricsBindAddress: "0", + NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) { + syncPeriod := 1 * time.Second + opts.Resync = &syncPeriod + return cache.New(config, opts) + }, + }) + Expect(err).NotTo(HaveOccurred()) + + k8sClient = mgr.GetClient() + + Expect((&MachinePoolReconciler{ + Client: k8sClient, + Log: log.Log, + recorder: mgr.GetEventRecorderFor("machinepool-controller"), + }).SetupWithManager(mgr, controller.Options{MaxConcurrentReconciles: 1})).To(Succeed()) + + By("starting the manager") + go func() { + Expect(mgr.Start(doneMgr)).To(Succeed()) + }() + + close(done) +}, 60) + +var _ = AfterSuite(func() { + By("closing the manager") + close(doneMgr) + By("tearing down the test environment") + Expect(testEnv.Stop()).To(Succeed()) +}) diff --git a/exp/doc.go b/exp/doc.go new file mode 100644 index 000000000000..68e7b8738c84 --- /dev/null +++ b/exp/doc.go @@ -0,0 +1,17 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package exp diff --git a/exp/hack/boilerplate.go.txt b/exp/hack/boilerplate.go.txt new file mode 100644 index 000000000000..b7c650da4701 --- /dev/null +++ b/exp/hack/boilerplate.go.txt @@ -0,0 +1,16 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + diff --git a/features/features.go b/feature/feature.go similarity index 71% rename from features/features.go rename to feature/feature.go index 54e93e4efb06..9dfc03586b88 100644 --- a/features/features.go +++ b/feature/feature.go @@ -14,30 +14,32 @@ See the License for the specific language governing permissions and limitations under the License. */ -package features +package feature import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/component-base/featuregate" - - utilfeature "sigs.k8s.io/cluster-api/util/featuregate" ) const ( -// Every feature gate should add method here following this template: -// -// // owner: @username -// // alpha: v1.X -// MyFeature featuregate.Feature = "MyFeature" + // Every feature gate should add method here following this template: + // + // // owner: @username + // // alpha: v1.X + // MyFeature featuregate.Feature = "MyFeature" + + // owner: @ + // alpha: v0.3 + MachinePool featuregate.Feature = "MachinePool" ) func init() { - runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultClusterAPIFeatureGates)) + runtime.Must(MutableGates.Add(defaultClusterAPIFeatureGates)) } // defaultClusterAPIFeatureGates consists of all known cluster-api-specific feature keys. // To add a new feature, define a key for it above and add it here. var defaultClusterAPIFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ // Every feature should be initiated here: - // MyFeature: {Default: false, PreRelease: featuregate.Alpha}, + MachinePool: {Default: false, PreRelease: featuregate.Alpha}, } diff --git a/util/featuregate/featuregate.go b/feature/gates.go similarity index 77% rename from util/featuregate/featuregate.go rename to feature/gates.go index e3c89f152d44..1d3d9ec03030 100644 --- a/util/featuregate/featuregate.go +++ b/feature/gates.go @@ -14,20 +14,20 @@ See the License for the specific language governing permissions and limitations under the License. */ -package featuregate +package feature import ( "k8s.io/component-base/featuregate" ) var ( - // DefaultMutableFeatureGate is a mutable version of DefaultFeatureGate. + // MutableGates is a mutable version of DefaultFeatureGate. // Only top-level commands/options setup and the k8s.io/component-base/featuregate/testing package should make use of this. // Tests that need to modify featuregate gates for the duration of their test should use: // defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features., )() - DefaultMutableFeatureGate featuregate.MutableFeatureGate = featuregate.NewFeatureGate() + MutableGates featuregate.MutableFeatureGate = featuregate.NewFeatureGate() - // DefaultFeatureGate is a shared global FeatureGate. + // Gates is a shared global FeatureGate. // Top-level commands/options setup that needs to modify this featuregate gate should use DefaultMutableFeatureGate. - DefaultFeatureGate featuregate.FeatureGate = DefaultMutableFeatureGate + Gates featuregate.FeatureGate = MutableGates ) diff --git a/go.mod b/go.mod index 84c2b8201eeb..0e46a6a53da8 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/imdario/mergo v0.3.8 // indirect github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 - github.com/pelletier/go-toml v1.6.0 // indirect github.com/pkg/errors v0.9.0 github.com/prometheus/client_golang v1.1.0 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 @@ -30,11 +29,9 @@ require ( golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 // indirect golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect google.golang.org/grpc v1.23.1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect - gopkg.in/yaml.v2 v2.2.7 // indirect k8s.io/api v0.17.2 k8s.io/apiextensions-apiserver v0.17.2 k8s.io/apimachinery v0.17.2 @@ -45,5 +42,6 @@ require ( k8s.io/klog v1.0.0 k8s.io/utils v0.0.0-20191114184206-e782cd3c129f sigs.k8s.io/controller-runtime v0.5.0 + sigs.k8s.io/kind v0.7.0 sigs.k8s.io/yaml v1.1.0 ) diff --git a/go.sum b/go.sum index 937a999ed913..3f59b20700ef 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053 h1:H/GMMKYPkEIC3DF/JWQz8Pdd+Feifov2EIgGfNpeogI= +github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053/go.mod h1:xW8sBma2LE3QxFSzCnH9qe6gAE2yO9GvQaWwX89HxbE= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -228,6 +230,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -404,6 +408,7 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -472,6 +477,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -480,6 +487,7 @@ k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc= k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6Kolpss= k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs= +k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4= k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apiserver v0.17.2 h1:NssVvPALll6SSeNgo1Wk1h2myU1UHNwmhxV0Oxbcl8Y= @@ -508,6 +516,8 @@ modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= sigs.k8s.io/controller-runtime v0.5.0 h1:CbqIy5fbUX+4E9bpnBFd204YAzRYlM9SWW77BbrcDQo= sigs.k8s.io/controller-runtime v0.5.0/go.mod h1:REiJzC7Y00U+2YkMbT8wxgrsX5USpXKGhb2sCtAXiT8= +sigs.k8s.io/kind v0.7.0 h1:7y7a8EYtGHM+auHmsvzuK5o84SrxPYGidlvfql7j/k4= +sigs.k8s.io/kind v0.7.0/go.mod h1:An/AbWHT6pA/Lm0Og8j3ukGhfJP3RiVN/IBU6Lo3zl8= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= diff --git a/main.go b/main.go index b60535944ced..beef6197c58c 100644 --- a/main.go +++ b/main.go @@ -29,16 +29,16 @@ import ( "k8s.io/client-go/rest" "k8s.io/klog" "k8s.io/klog/klogr" - _ "sigs.k8s.io/cluster-api/features" - "sigs.k8s.io/cluster-api/util/featuregate" + clusterv1alpha2 "sigs.k8s.io/cluster-api/api/v1alpha2" + clusterv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" + "sigs.k8s.io/cluster-api/controllers" + expv1alpha3 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" + expcontrollers "sigs.k8s.io/cluster-api/exp/controllers" + "sigs.k8s.io/cluster-api/feature" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" - - clusterv1alpha2 "sigs.k8s.io/cluster-api/api/v1alpha2" - clusterv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3" - "sigs.k8s.io/cluster-api/controllers" "sigs.k8s.io/controller-runtime/pkg/healthz" // +kubebuilder:scaffold:imports ) @@ -68,6 +68,7 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = clusterv1alpha2.AddToScheme(scheme) _ = clusterv1alpha3.AddToScheme(scheme) + _ = expv1alpha3.AddToScheme(scheme) _ = apiextensionsv1.AddToScheme(scheme) // +kubebuilder:scaffold:scheme } @@ -110,8 +111,7 @@ func InitFlags(fs *pflag.FlagSet) { fs.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.") - // Add --feature-gates flag - featuregate.DefaultMutableFeatureGate.AddFlag(fs) + feature.MutableGates.AddFlag(fs) } func main() { @@ -200,12 +200,15 @@ func setupReconcilers(mgr ctrl.Manager) { setupLog.Error(err, "unable to create controller", "controller", "MachineDeployment") os.Exit(1) } - if err := (&controllers.MachinePoolReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("MachinePool"), - }).SetupWithManager(mgr, concurrency(machinePoolConcurrency)); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "MachinePool") - os.Exit(1) + + if feature.Gates.Enabled(feature.MachinePool) { + if err := (&expcontrollers.MachinePoolReconciler{ + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("MachinePool"), + }).SetupWithManager(mgr, concurrency(machinePoolConcurrency)); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "MachinePool") + os.Exit(1) + } } } @@ -270,9 +273,11 @@ func setupWebhooks(mgr ctrl.Manager) { os.Exit(1) } - if err := (&clusterv1alpha3.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "MachinePool") - os.Exit(1) + if feature.Gates.Enabled(feature.MachinePool) { + if err := (&expv1alpha3.MachinePool{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "MachinePool") + os.Exit(1) + } } } diff --git a/test/framework/control_plane.go b/test/framework/control_plane.go index c9fcb11beec5..c74c45ecba0c 100644 --- a/test/framework/control_plane.go +++ b/test/framework/control_plane.go @@ -31,6 +31,7 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" cabpkv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/cluster-api/test/framework/options" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -335,7 +336,7 @@ func AssertAllClusterAPIResourcesAreGone(ctx context.Context, input AssertAllClu Expect(input.Lister.List(ctx, mdl, opt)).To(Succeed()) Expect(mdl.Items).To(HaveLen(0)) - mpl := &clusterv1.MachinePoolList{} + mpl := &expv1.MachinePoolList{} Expect(input.Lister.List(ctx, mpl, opt)).To(Succeed()) Expect(mpl.Items).To(HaveLen(0)) diff --git a/test/framework/convenience.go b/test/framework/convenience.go index 69f9cf2b86d5..e36b68b1a2fa 100644 --- a/test/framework/convenience.go +++ b/test/framework/convenience.go @@ -32,6 +32,7 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -98,6 +99,9 @@ func TryAddDefaultSchemes(scheme *runtime.Scheme) { // Add the core CAPI scheme. _ = clusterv1.AddToScheme(scheme) + // Add the experiments CAPI scheme. + _ = expv1.AddToScheme(scheme) + // Add the kubeadm bootstrapper scheme. _ = bootstrapv1.AddToScheme(scheme) diff --git a/test/framework/dump_resources.go b/test/framework/dump_resources.go index f67eec61d7d4..3510191e704f 100644 --- a/test/framework/dump_resources.go +++ b/test/framework/dump_resources.go @@ -32,6 +32,7 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" "sigs.k8s.io/yaml" ) @@ -41,7 +42,7 @@ func DumpResources(mgmt ManagementCluster, resourcePath string, writer io.Writer "Cluster": &clusterv1.ClusterList{}, "MachineDeployment": &clusterv1.MachineDeploymentList{}, "MachineSet": &clusterv1.MachineSetList{}, - "MachinePool": &clusterv1.MachinePoolList{}, + "MachinePool": &expv1.MachinePoolList{}, "Machine": &clusterv1.MachineList{}, "KubeadmControlPlane": &controlplanev1.KubeadmControlPlaneList{}, "KubeadmConfig": &bootstrapv1.KubeadmConfigList{}, diff --git a/test/framework/go.mod b/test/framework/go.mod deleted file mode 100644 index 06809e8d6a19..000000000000 --- a/test/framework/go.mod +++ /dev/null @@ -1,17 +0,0 @@ -module sigs.k8s.io/cluster-api/test/framework - -go 1.13 - -require ( - github.com/onsi/ginkgo v1.11.0 - github.com/onsi/gomega v1.8.1 - github.com/pkg/errors v0.9.0 - k8s.io/api v0.17.2 - k8s.io/apiextensions-apiserver v0.17.2 - k8s.io/apimachinery v0.17.2 - k8s.io/client-go v0.17.2 - sigs.k8s.io/cluster-api v0.3.0-rc.2.0.20200302175844-3011d8c2580c - sigs.k8s.io/controller-runtime v0.5.0 - sigs.k8s.io/kind v0.7.0 - sigs.k8s.io/yaml v1.1.0 -) diff --git a/test/framework/go.sum b/test/framework/go.sum deleted file mode 100644 index 86e23ad1f612..000000000000 --- a/test/framework/go.sum +++ /dev/null @@ -1,487 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053 h1:H/GMMKYPkEIC3DF/JWQz8Pdd+Feifov2EIgGfNpeogI= -github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053/go.mod h1:xW8sBma2LE3QxFSzCnH9qe6gAE2yO9GvQaWwX89HxbE= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= -github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= -github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= -github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= -github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= -github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= -github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= -github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k= -github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0= -gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc= -k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= -k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6Kolpss= -k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs= -k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4= -k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= -k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo= -k8s.io/client-go v0.17.2 h1:ndIfkfXEGrNhLIgkr0+qhRguSD3u6DCmonepn1O6NYc= -k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI= -k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7 h1:5wvjieVoU4oovHlkeD256q2M2YYi2P01zk6wxSR2zk0= -k8s.io/cluster-bootstrap v0.0.0-20190516232516-d7d78ab2cfe7/go.mod h1:iBSm2nwo3OaiuW8VDvc3ySDXK5SKfUrxwPvBloKG7zg= -k8s.io/code-generator v0.17.2/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= -k8s.io/component-base v0.17.2/go.mod h1:zMPW3g5aH7cHJpKYQ/ZsGMcgbsA/VyhEugF3QT1awLs= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo= -k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= -sigs.k8s.io/cluster-api v0.3.0-rc.2.0.20200302175844-3011d8c2580c h1:0KHkVMjju7JV66FQEEdAX1HlR3arbYCLZEaMvp/Zp5k= -sigs.k8s.io/cluster-api v0.3.0-rc.2.0.20200302175844-3011d8c2580c/go.mod h1:tEmR4U35yNstvuMH/3SF7TqdVw1FyyI8XAVcMyczEYE= -sigs.k8s.io/controller-runtime v0.5.0 h1:CbqIy5fbUX+4E9bpnBFd204YAzRYlM9SWW77BbrcDQo= -sigs.k8s.io/controller-runtime v0.5.0/go.mod h1:REiJzC7Y00U+2YkMbT8wxgrsX5USpXKGhb2sCtAXiT8= -sigs.k8s.io/kind v0.7.0 h1:7y7a8EYtGHM+auHmsvzuK5o84SrxPYGidlvfql7j/k4= -sigs.k8s.io/kind v0.7.0/go.mod h1:An/AbWHT6pA/Lm0Og8j3ukGhfJP3RiVN/IBU6Lo3zl8= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/test/helpers/scheme/scheme.go b/test/helpers/scheme/scheme.go index ba8d9e45e948..bf6a5d37129f 100644 --- a/test/helpers/scheme/scheme.go +++ b/test/helpers/scheme/scheme.go @@ -21,11 +21,13 @@ import ( "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" + expv1 "sigs.k8s.io/cluster-api/exp/api/v1alpha3" ) func SetupScheme() *runtime.Scheme { scheme := runtime.NewScheme() Expect(clientgoscheme.AddToScheme(scheme)).To(Succeed()) Expect(clusterv1.AddToScheme(scheme)).To(Succeed()) + Expect(expv1.AddToScheme(scheme)).To(Succeed()) return scheme } diff --git a/test/infrastructure/docker/go.mod b/test/infrastructure/docker/go.mod index 1c507e00a5f8..bb13714ad5c2 100644 --- a/test/infrastructure/docker/go.mod +++ b/test/infrastructure/docker/go.mod @@ -14,12 +14,8 @@ require ( k8s.io/client-go v0.17.2 k8s.io/klog v1.0.0 sigs.k8s.io/cluster-api v0.3.0-rc.2.0.20200302175844-3011d8c2580c - sigs.k8s.io/cluster-api/test/framework v0.0.0-20200212174651-13d44c484542 sigs.k8s.io/controller-runtime v0.5.0 sigs.k8s.io/kind v0.7.0 ) -replace ( - sigs.k8s.io/cluster-api => ../../.. - sigs.k8s.io/cluster-api/test/framework => ../../framework -) +replace sigs.k8s.io/cluster-api => ../../..