From 2b97e524e38e0264888315bb9b209e30c4deadcc Mon Sep 17 00:00:00 2001 From: Marc Campbell Date: Tue, 24 Dec 2019 19:38:47 +0000 Subject: [PATCH] No more controllers --- pkg/analyze/text_analyze_test.go | 12 +- pkg/controller/add_analyzer.go | 26 -- pkg/controller/add_analyzerjob.go | 26 -- pkg/controller/add_collector.go | 26 -- pkg/controller/add_collectorjob.go | 26 -- pkg/controller/add_preflight.go | 26 -- pkg/controller/add_preflightjob.go | 26 -- .../analyzer/analyzer_controller.go | 167 ------- .../analyzer_controller_suite_test.go | 75 --- .../analyzer/analyzer_controller_test.go | 25 - .../analyzerjob/analyzerjob_controller.go | 167 ------- .../analyzerjob_controller_suite_test.go | 75 --- .../analyzerjob_controller_test.go | 25 - .../collector/collector_controller.go | 105 ----- .../collector_controller_suite_test.go | 75 --- .../collector/collector_controller_test.go | 25 - .../collectorjob/collector_server.go | 127 ----- .../collectorjob/collectorjob_controller.go | 439 ------------------ .../collectorjob_controller_suite_test.go | 75 --- .../collectorjob_controller_test.go | 25 - pkg/controller/controller.go | 34 -- .../preflight/preflight_controller.go | 96 ---- .../preflight_controller_suite_test.go | 75 --- .../preflight/preflight_controller_test.go | 72 --- pkg/controller/preflightjob/analyzers.go | 64 --- .../preflightjob/cluster_version.go | 11 - pkg/controller/preflightjob/collectors.go | 89 ---- .../preflightjob/preflightjob_controller.go | 178 ------- .../preflightjob_controller_suite_test.go | 75 --- .../preflightjob_controller_test.go | 25 - 30 files changed, 9 insertions(+), 2283 deletions(-) delete mode 100644 pkg/controller/add_analyzer.go delete mode 100644 pkg/controller/add_analyzerjob.go delete mode 100644 pkg/controller/add_collector.go delete mode 100644 pkg/controller/add_collectorjob.go delete mode 100644 pkg/controller/add_preflight.go delete mode 100644 pkg/controller/add_preflightjob.go delete mode 100644 pkg/controller/analyzer/analyzer_controller.go delete mode 100644 pkg/controller/analyzer/analyzer_controller_suite_test.go delete mode 100644 pkg/controller/analyzer/analyzer_controller_test.go delete mode 100644 pkg/controller/analyzerjob/analyzerjob_controller.go delete mode 100644 pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go delete mode 100644 pkg/controller/analyzerjob/analyzerjob_controller_test.go delete mode 100644 pkg/controller/collector/collector_controller.go delete mode 100644 pkg/controller/collector/collector_controller_suite_test.go delete mode 100644 pkg/controller/collector/collector_controller_test.go delete mode 100644 pkg/controller/collectorjob/collector_server.go delete mode 100644 pkg/controller/collectorjob/collectorjob_controller.go delete mode 100644 pkg/controller/collectorjob/collectorjob_controller_suite_test.go delete mode 100644 pkg/controller/collectorjob/collectorjob_controller_test.go delete mode 100644 pkg/controller/controller.go delete mode 100644 pkg/controller/preflight/preflight_controller.go delete mode 100644 pkg/controller/preflight/preflight_controller_suite_test.go delete mode 100644 pkg/controller/preflight/preflight_controller_test.go delete mode 100644 pkg/controller/preflightjob/analyzers.go delete mode 100644 pkg/controller/preflightjob/cluster_version.go delete mode 100644 pkg/controller/preflightjob/collectors.go delete mode 100644 pkg/controller/preflightjob/preflightjob_controller.go delete mode 100644 pkg/controller/preflightjob/preflightjob_controller_suite_test.go delete mode 100644 pkg/controller/preflightjob/preflightjob_controller_test.go diff --git a/pkg/analyze/text_analyze_test.go b/pkg/analyze/text_analyze_test.go index 91f3fe8f..3bdb8f9c 100644 --- a/pkg/analyze/text_analyze_test.go +++ b/pkg/analyze/text_analyze_test.go @@ -39,6 +39,7 @@ func Test_textAnalyze(t *testing.T) { IsPass: true, IsWarn: false, IsFail: false, + Title: "text-collector-1", Message: "pass", }, files: map[string][]byte{ @@ -68,6 +69,7 @@ func Test_textAnalyze(t *testing.T) { IsPass: false, IsWarn: false, IsFail: true, + Title: "text-collector-2", Message: "fail", }, files: map[string][]byte{ @@ -94,10 +96,11 @@ func Test_textAnalyze(t *testing.T) { RegexPattern: "", }, expectResult: AnalyzeResult{ - IsPass: true, + IsPass: false, IsWarn: false, - IsFail: false, - Message: "success", + IsFail: true, + Title: "", + Message: "Invalid analyzer", }, files: map[string][]byte{ "text-collector-3/cfile-3.txt": []byte("Connection to service succeeded"), @@ -126,6 +129,7 @@ func Test_textAnalyze(t *testing.T) { IsPass: true, IsWarn: false, IsFail: false, + Title: "text-collector-5", Message: "success", }, files: map[string][]byte{ @@ -155,6 +159,7 @@ func Test_textAnalyze(t *testing.T) { IsPass: false, IsWarn: false, IsFail: true, + Title: "text-collector-4", Message: "fail", }, files: map[string][]byte{ @@ -184,6 +189,7 @@ func Test_textAnalyze(t *testing.T) { IsPass: false, IsWarn: false, IsFail: true, + Title: "text-collector-6", Message: "fail", }, files: map[string][]byte{ diff --git a/pkg/controller/add_analyzer.go b/pkg/controller/add_analyzer.go deleted file mode 100644 index 1436ac21..00000000 --- a/pkg/controller/add_analyzer.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/analyzer" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, analyzer.Add) -} diff --git a/pkg/controller/add_analyzerjob.go b/pkg/controller/add_analyzerjob.go deleted file mode 100644 index 4477a7cd..00000000 --- a/pkg/controller/add_analyzerjob.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/analyzerjob" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, analyzerjob.Add) -} diff --git a/pkg/controller/add_collector.go b/pkg/controller/add_collector.go deleted file mode 100644 index f959119d..00000000 --- a/pkg/controller/add_collector.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/collector" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, collector.Add) -} diff --git a/pkg/controller/add_collectorjob.go b/pkg/controller/add_collectorjob.go deleted file mode 100644 index f10e583b..00000000 --- a/pkg/controller/add_collectorjob.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/collectorjob" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, collectorjob.Add) -} diff --git a/pkg/controller/add_preflight.go b/pkg/controller/add_preflight.go deleted file mode 100644 index d1f3c5fe..00000000 --- a/pkg/controller/add_preflight.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/preflight" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, preflight.Add) -} diff --git a/pkg/controller/add_preflightjob.go b/pkg/controller/add_preflightjob.go deleted file mode 100644 index 558954d2..00000000 --- a/pkg/controller/add_preflightjob.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "github.com/replicatedhq/troubleshoot/pkg/controller/preflightjob" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, preflightjob.Add) -} diff --git a/pkg/controller/analyzer/analyzer_controller.go b/pkg/controller/analyzer/analyzer_controller.go deleted file mode 100644 index 308686e8..00000000 --- a/pkg/controller/analyzer/analyzer_controller.go +++ /dev/null @@ -1,167 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzer - -import ( - "context" - "reflect" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -/** -* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller -* business logic. Delete these comments after modifying this file.* - */ - -// Add creates a new Analyzer Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcileAnalyzer{Client: mgr.GetClient(), scheme: mgr.GetScheme()} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("analyzer-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to Analyzer - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Analyzer{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - // TODO(user): Modify this to be the types you create - // Uncomment watch a Deployment created by Analyzer - change this for objects you create - err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &troubleshootv1beta1.Analyzer{}, - }) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileAnalyzer{} - -// ReconcileAnalyzer reconciles a Analyzer object -type ReconcileAnalyzer struct { - client.Client - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a Analyzer object and makes changes based on the state read -// and what is in the Analyzer.Spec -// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes -// a Deployment as an example -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzers,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzers/status,verbs=get;update;patch -func (r *ReconcileAnalyzer) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the Analyzer instance - instance := &troubleshootv1beta1.Analyzer{} - err := r.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - // TODO(user): Change this to be the object type created by your controller - // Define the desired Deployment object - deploy := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: instance.Name + "-deployment", - Namespace: instance.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - }, - }, - } - if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { - return reconcile.Result{}, err - } - - // TODO(user): Change this for the object type created by your controller - // Check if the Deployment already exists - found := &appsv1.Deployment{} - err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) - if err != nil && errors.IsNotFound(err) { - log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) - err = r.Create(context.TODO(), deploy) - return reconcile.Result{}, err - } else if err != nil { - return reconcile.Result{}, err - } - - // TODO(user): Change this for the object type created by your controller - // Update the found object and write the result back if there are any changes - if !reflect.DeepEqual(deploy.Spec, found.Spec) { - found.Spec = deploy.Spec - log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) - err = r.Update(context.TODO(), found) - if err != nil { - return reconcile.Result{}, err - } - } - return reconcile.Result{}, nil -} diff --git a/pkg/controller/analyzer/analyzer_controller_suite_test.go b/pkg/controller/analyzer/analyzer_controller_suite_test.go deleted file mode 100644 index 251ba346..00000000 --- a/pkg/controller/analyzer/analyzer_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzer - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/analyzer/analyzer_controller_test.go b/pkg/controller/analyzer/analyzer_controller_test.go deleted file mode 100644 index fc079eb2..00000000 --- a/pkg/controller/analyzer/analyzer_controller_test.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzer - -import ( - "testing" -) - -func TestReconcile(t *testing.T) { - -} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller.go b/pkg/controller/analyzerjob/analyzerjob_controller.go deleted file mode 100644 index 33121b2f..00000000 --- a/pkg/controller/analyzerjob/analyzerjob_controller.go +++ /dev/null @@ -1,167 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzerjob - -import ( - "context" - "reflect" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -/** -* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller -* business logic. Delete these comments after modifying this file.* - */ - -// Add creates a new AnalyzerJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcileAnalyzerJob{Client: mgr.GetClient(), scheme: mgr.GetScheme()} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("analyzerjob-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to AnalyzerJob - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.AnalyzerJob{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - // TODO(user): Modify this to be the types you create - // Uncomment watch a Deployment created by AnalyzerJob - change this for objects you create - err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &troubleshootv1beta1.AnalyzerJob{}, - }) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileAnalyzerJob{} - -// ReconcileAnalyzerJob reconciles a AnalyzerJob object -type ReconcileAnalyzerJob struct { - client.Client - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a AnalyzerJob object and makes changes based on the state read -// and what is in the AnalyzerJob.Spec -// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes -// a Deployment as an example -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzerjobs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=analyzerjobs/status,verbs=get;update;patch -func (r *ReconcileAnalyzerJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the AnalyzerJob instance - instance := &troubleshootv1beta1.AnalyzerJob{} - err := r.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - // TODO(user): Change this to be the object type created by your controller - // Define the desired Deployment object - deploy := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: instance.Name + "-deployment", - Namespace: instance.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"deployment": instance.Name + "-deployment"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": instance.Name + "-deployment"}}, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "nginx", - Image: "nginx", - }, - }, - }, - }, - }, - } - if err := controllerutil.SetControllerReference(instance, deploy, r.scheme); err != nil { - return reconcile.Result{}, err - } - - // TODO(user): Change this for the object type created by your controller - // Check if the Deployment already exists - found := &appsv1.Deployment{} - err = r.Get(context.TODO(), types.NamespacedName{Name: deploy.Name, Namespace: deploy.Namespace}, found) - if err != nil && errors.IsNotFound(err) { - log.Info("Creating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) - err = r.Create(context.TODO(), deploy) - return reconcile.Result{}, err - } else if err != nil { - return reconcile.Result{}, err - } - - // TODO(user): Change this for the object type created by your controller - // Update the found object and write the result back if there are any changes - if !reflect.DeepEqual(deploy.Spec, found.Spec) { - found.Spec = deploy.Spec - log.Info("Updating Deployment", "namespace", deploy.Namespace, "name", deploy.Name) - err = r.Update(context.TODO(), found) - if err != nil { - return reconcile.Result{}, err - } - } - return reconcile.Result{}, nil -} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go b/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go deleted file mode 100644 index 2b921fd4..00000000 --- a/pkg/controller/analyzerjob/analyzerjob_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzerjob - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/analyzerjob/analyzerjob_controller_test.go b/pkg/controller/analyzerjob/analyzerjob_controller_test.go deleted file mode 100644 index ab548afa..00000000 --- a/pkg/controller/analyzerjob/analyzerjob_controller_test.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package analyzerjob - -import ( - "testing" -) - -func TestReconcile(t *testing.T) { - -} diff --git a/pkg/controller/collector/collector_controller.go b/pkg/controller/collector/collector_controller.go deleted file mode 100644 index 3f2cfcfa..00000000 --- a/pkg/controller/collector/collector_controller.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collector - -import ( - "context" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -// Add creates a new Collector Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcileCollector{Client: mgr.GetClient(), scheme: mgr.GetScheme()} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("collector-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to Collector - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Collector{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileCollector{} - -// ReconcileCollector reconciles a Collector object -type ReconcileCollector struct { - client.Client - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a Collector object and makes changes based on the state read -// and what is in the Collector.Spec -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectors,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectors/status,verbs=get;update;patch -func (r *ReconcileCollector) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the Collector instance - instance := &troubleshootv1beta1.Collector{} - err := r.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if errors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - // The troubleshoot spec doesn't really do anything. the work - // is performed in the troubleshootjob crd. this one is really - // primarily used as a packaging format2 - - return reconcile.Result{}, nil -} - -func (r *ReconcileCollector) getCollectorConfigMapSpec(instance *troubleshootv1beta1.Collector) (*v1.ConfigMap, error) { - configMap := v1.ConfigMap{} - - return &configMap, nil -} diff --git a/pkg/controller/collector/collector_controller_suite_test.go b/pkg/controller/collector/collector_controller_suite_test.go deleted file mode 100644 index 57bb98a1..00000000 --- a/pkg/controller/collector/collector_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collector - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/collector/collector_controller_test.go b/pkg/controller/collector/collector_controller_test.go deleted file mode 100644 index d64299ca..00000000 --- a/pkg/controller/collector/collector_controller_test.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collector - -import ( - "testing" -) - -func TestReconcile(t *testing.T) { - -} diff --git a/pkg/controller/collectorjob/collector_server.go b/pkg/controller/collectorjob/collector_server.go deleted file mode 100644 index 0d0fae10..00000000 --- a/pkg/controller/collectorjob/collector_server.go +++ /dev/null @@ -1,127 +0,0 @@ -package collectorjob - -import ( - "context" - "fmt" - "time" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - corev1 "k8s.io/api/core/v1" - kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -func (r *ReconcileCollectorJob) createCollectorServer(instance *troubleshootv1beta1.CollectorJob) error { - name := fmt.Sprintf("%s-%s", instance.Name, "collector") - - namespacedName := types.NamespacedName{ - Name: name, - Namespace: instance.Namespace, - } - - found := &corev1.Pod{} - err := r.Get(context.Background(), namespacedName, found) - if err == nil || !kuberneteserrors.IsNotFound(err) { - return err - } - - imageName := "replicated/troubleshoot:latest" - imagePullPolicy := corev1.PullAlways - - if instance.Spec.Image != "" { - imageName = instance.Spec.Image - } - if instance.Spec.ImagePullPolicy != "" { - imagePullPolicy = corev1.PullPolicy(instance.Spec.ImagePullPolicy) - } - - podLabels := make(map[string]string) - podLabels["collector"] = instance.Name - podLabels["troubleshoot-role"] = "collector" - - pod := corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: instance.Namespace, - Labels: podLabels, - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Pod", - }, - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - Containers: []corev1.Container{ - { - Image: imageName, - ImagePullPolicy: imagePullPolicy, - Name: "collector", - Command: []string{"collector"}, - Args: []string{"server"}, - Ports: []corev1.ContainerPort{ - { - Name: "http", - ContainerPort: 8000, - }, - }, - }, - }, - }, - } - - if err := controllerutil.SetControllerReference(instance, &pod, r.scheme); err != nil { - return err - } - - if err := r.Create(context.Background(), &pod); err != nil { - return err - } - - service := corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: instance.Namespace, - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Service", - }, - Spec: corev1.ServiceSpec{ - Selector: podLabels, - Type: corev1.ServiceTypeClusterIP, - Ports: []corev1.ServicePort{ - { - Name: "http", - Port: 8000, - TargetPort: intstr.FromInt(8000), - }, - }, - }, - } - - if err := controllerutil.SetControllerReference(instance, &service, r.scheme); err != nil { - return err - } - - if err := r.Create(context.Background(), &service); err != nil { - return err - } - - instance.Status.ServerPodName = name - instance.Status.ServerPodNamespace = instance.Namespace - instance.Status.ServerPodPort = 8000 - instance.Status.IsServerReady = true - - // wait for the server to be ready - // TODO - time.Sleep(time.Second * 5) - - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil -} diff --git a/pkg/controller/collectorjob/collectorjob_controller.go b/pkg/controller/collectorjob/collectorjob_controller.go deleted file mode 100644 index 75b4874c..00000000 --- a/pkg/controller/collectorjob/collectorjob_controller.go +++ /dev/null @@ -1,439 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collectorjob - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "math/rand" - "net/http" - "os" - "time" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - troubleshootclientv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" - collectrunner "github.com/replicatedhq/troubleshoot/pkg/collect" - "github.com/replicatedhq/troubleshoot/pkg/k8sutil" - "github.com/replicatedhq/troubleshoot/pkg/logger" - "gopkg.in/yaml.v2" - corev1 "k8s.io/api/core/v1" - kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -// Add creates a new CollectorJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcileCollectorJob{ - Client: mgr.GetClient(), - config: mgr.GetConfig(), - scheme: mgr.GetScheme(), - } -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("collectorjob-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to CollectorJob - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.CollectorJob{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{ - IsController: true, - OwnerType: &troubleshootv1beta1.CollectorJob{}, - }) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcileCollectorJob{} - -// ReconcileCollectorJob reconciles a CollectorJob object -type ReconcileCollectorJob struct { - client.Client - config *rest.Config - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a CollectorJob object and makes changes based on the state read -// and what is in the CollectorJob.Spec -// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes -// a Deployment as an example -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectorjobs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=collectorjobs/status,verbs=get;update;patch -func (r *ReconcileCollectorJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the CollectorJob instance - instance := &troubleshootv1beta1.CollectorJob{} - err := r.Get(context.Background(), request.NamespacedName, instance) - if err != nil { - if kuberneteserrors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - // for a new object, create the http server - if !instance.Status.IsServerReady { - if err := r.createCollectorServer(instance); err != nil { - return reconcile.Result{}, err - } - } - - namespace := instance.Namespace - if instance.Spec.Collector.Namespace != "" { - namespace = instance.Spec.Collector.Namespace - } - - collectorSpec, err := r.getCollectorSpec(namespace, instance.Spec.Collector.Name) - if err != nil { - return reconcile.Result{}, err - } - - for _, collector := range collectorSpec.Spec.Collectors { - if err := r.reconileOneCollectorJob(instance, collector); err != nil { - return reconcile.Result{}, err - } - } - - return reconcile.Result{}, nil -} - -func (r *ReconcileCollectorJob) getCollectorSpec(namespace string, name string) (*troubleshootv1beta1.Collector, error) { - troubleshootClient, err := troubleshootclientv1beta1.NewForConfig(r.config) - if err != nil { - return nil, err - } - - collector, err := troubleshootClient.Collectors(namespace).Get(name, metav1.GetOptions{}) - if err != nil { - if kuberneteserrors.IsNotFound(err) { - return nil, nil - } - - return nil, err - } - - return collector, nil -} - -func (r *ReconcileCollectorJob) reconileOneCollectorJob(instance *troubleshootv1beta1.CollectorJob, collect *troubleshootv1beta1.Collect) error { - if contains(instance.Status.Running, collectrunner.DeterministicIDForCollector(collect)) { - collectorPod, err := r.getCollectorPod(instance, collect) - if err != nil { - return err - } - - if collectorPod.Status.Phase == corev1.PodFailed { - instance.Status.Failed = append(instance.Status.Failed, collectrunner.DeterministicIDForCollector(collect)) - instance.Status.Running = remove(instance.Status.Running, collectrunner.DeterministicIDForCollector(collect)) - - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil - } - if collectorPod.Status.Phase == corev1.PodSucceeded { - // Get the logs - podLogOpts := corev1.PodLogOptions{} - - k8sClient, err := kubernetes.NewForConfig(r.config) - if err != nil { - return err - } - req := k8sClient.CoreV1().Pods(collectorPod.Namespace).GetLogs(collectorPod.Name, &podLogOpts) - podLogs, err := req.Stream() - if err != nil { - return err - } - defer podLogs.Close() - buf := new(bytes.Buffer) - _, err = io.Copy(buf, podLogs) - if err != nil { - return err - } - - client := &http.Client{} - - serviceURI := "" - - // For local dev, it's useful to run the manager out of the cluster - // but this is difficult to connect to the collector service running in-cluster - // so, we can create a local port-foward to get back into the cluster. - stopCh := make(chan struct{}, 1) - if os.Getenv("TROUBLESHOOT_EXTERNAL_MANAGER") != "" { - logger.Printf("setting up port forwarding because the manager is not running in the cluster\n") - - // this isn't likely to be very solid - localPort := 3000 + rand.New(rand.NewSource(time.Now().UnixNano())).Intn(999) - - ch, err := k8sutil.PortForward(r.config, localPort, 8000, instance.Namespace, instance.Name+"-collector") - if err != nil { - return err - } - - stopCh = ch - serviceURI = fmt.Sprintf("http://localhost:%d", localPort) - } else { - serviceURI = fmt.Sprintf("http://%s-collector.%s.svc.cluster.local:8000", instance.Name, instance.Namespace) - } - - request, err := http.NewRequest("PUT", serviceURI, buf) - if err != nil { - return err - } - request.ContentLength = int64(len(buf.String())) - request.Header.Add("collector-id", collectrunner.DeterministicIDForCollector(collect)) - resp, err := client.Do(request) - if err != nil { - return err - } - - if resp.StatusCode != 201 { - return errors.New("failed to send logs to collector") - } - - if os.Getenv("TROUBLESHOOT_EXTERNAL_MANAGER") != "" { - logger.Printf("stopping port forwarding\n") - close(stopCh) - } - - instance.Status.Successful = append(instance.Status.Successful, collectrunner.DeterministicIDForCollector(collect)) - instance.Status.Running = remove(instance.Status.Running, collectrunner.DeterministicIDForCollector(collect)) - - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil - } - return nil - } - - if err := r.createSpecInConfigMap(instance, collect); err != nil { - return err - } - if err := r.createCollectorPod(instance, collect); err != nil { - return err - } - - return nil -} - -func (r *ReconcileCollectorJob) createSpecInConfigMap(instance *troubleshootv1beta1.CollectorJob, collector *troubleshootv1beta1.Collect) error { - name := fmt.Sprintf("%s-%s", instance.Name, collectrunner.DeterministicIDForCollector(collector)) - - namespacedName := types.NamespacedName{ - Name: name, - Namespace: instance.Namespace, - } - - found := &corev1.ConfigMap{} - err := r.Get(context.Background(), namespacedName, found) - if err == nil || !kuberneteserrors.IsNotFound(err) { - return err - } - - specContents, err := yaml.Marshal(collector) - if err != nil { - return err - } - - specData := make(map[string]string) - specData["collector.yaml"] = string(specContents) - - configMap := corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: instance.Namespace, - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "ConfigMap", - }, - Data: specData, - } - - if err := controllerutil.SetControllerReference(instance, &configMap, r.scheme); err != nil { - return err - } - - if err := r.Create(context.Background(), &configMap); err != nil { - return err - } - - return nil -} - -func (r *ReconcileCollectorJob) getCollectorPod(instance *troubleshootv1beta1.CollectorJob, collector *troubleshootv1beta1.Collect) (*corev1.Pod, error) { - name := fmt.Sprintf("%s-%s", instance.Name, collectrunner.DeterministicIDForCollector(collector)) - - namespacedName := types.NamespacedName{ - Name: name, - Namespace: instance.Namespace, - } - - pod := &corev1.Pod{} - err := r.Get(context.Background(), namespacedName, pod) - if err != nil { - return nil, err - } - - return pod, nil -} - -func (r *ReconcileCollectorJob) createCollectorPod(instance *troubleshootv1beta1.CollectorJob, collector *troubleshootv1beta1.Collect) error { - name := fmt.Sprintf("%s-%s", instance.Name, collectrunner.DeterministicIDForCollector(collector)) - - namespacedName := types.NamespacedName{ - Name: name, - Namespace: instance.Namespace, - } - - found := &corev1.Pod{} - err := r.Get(context.Background(), namespacedName, found) - if err == nil || !kuberneteserrors.IsNotFound(err) { - return err - } - - imageName := "replicated/troubleshoot:latest" - imagePullPolicy := corev1.PullAlways - - if instance.Spec.Image != "" { - imageName = instance.Spec.Image - } - if instance.Spec.ImagePullPolicy != "" { - imagePullPolicy = corev1.PullPolicy(instance.Spec.ImagePullPolicy) - } - - pod := corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: instance.Namespace, - }, - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Pod", - }, - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - Containers: []corev1.Container{ - { - Image: imageName, - ImagePullPolicy: imagePullPolicy, - Name: collectrunner.DeterministicIDForCollector(collector), - Command: []string{"collector"}, - Args: []string{ - "run", - fmt.Sprintf("--redact=%t", instance.Spec.Redact), - "--collector", - "/troubleshoot/specs/collector.yaml", - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "collector", - MountPath: "/troubleshoot/specs", - }, - }, - }, - }, - Volumes: []corev1.Volume{ - { - Name: "collector", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, - }, - }, - }, - }, - }, - } - - if err := controllerutil.SetControllerReference(instance, &pod, r.scheme); err != nil { - return err - } - - if err := r.Create(context.Background(), &pod); err != nil { - return err - } - - instance.Status.Running = append(instance.Status.Running, collectrunner.DeterministicIDForCollector(collector)) - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil -} - -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false -} - -func remove(s []string, r string) []string { - for i, v := range s { - if v == r { - return append(s[:i], s[i+1:]...) - } - } - return s -} diff --git a/pkg/controller/collectorjob/collectorjob_controller_suite_test.go b/pkg/controller/collectorjob/collectorjob_controller_suite_test.go deleted file mode 100644 index bce58ed9..00000000 --- a/pkg/controller/collectorjob/collectorjob_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collectorjob - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/collectorjob/collectorjob_controller_test.go b/pkg/controller/collectorjob/collectorjob_controller_test.go deleted file mode 100644 index 54d074ab..00000000 --- a/pkg/controller/collectorjob/collectorjob_controller_test.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package collectorjob - -import ( - "testing" -) - -func TestReconcile(t *testing.T) { - -} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go deleted file mode 100644 index c884eca9..00000000 --- a/pkg/controller/controller.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "sigs.k8s.io/controller-runtime/pkg/manager" -) - -// AddToManagerFuncs is a list of functions to add all Controllers to the Manager -var AddToManagerFuncs []func(manager.Manager) error - -// AddToManager adds all Controllers to the Manager -func AddToManager(m manager.Manager) error { - for _, f := range AddToManagerFuncs { - if err := f(m); err != nil { - return err - } - } - return nil -} diff --git a/pkg/controller/preflight/preflight_controller.go b/pkg/controller/preflight/preflight_controller.go deleted file mode 100644 index 04968d63..00000000 --- a/pkg/controller/preflight/preflight_controller.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflight - -import ( - "context" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -// Add creates a new Preflight Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcilePreflight{Client: mgr.GetClient(), scheme: mgr.GetScheme()} -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("preflight-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to Preflight - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.Preflight{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcilePreflight{} - -// ReconcilePreflight reconciles a Preflight object -type ReconcilePreflight struct { - client.Client - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a Preflight object and makes changes based on the state read -// and what is in the Preflight.Spec -// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes -// a Deployment as an example -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflights,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflights/status,verbs=get;update;patch -func (r *ReconcilePreflight) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the Preflight instance - instance := &troubleshootv1beta1.Preflight{} - err := r.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if kuberneteserrors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - return reconcile.Result{}, nil -} diff --git a/pkg/controller/preflight/preflight_controller_suite_test.go b/pkg/controller/preflight/preflight_controller_suite_test.go deleted file mode 100644 index 7b81e6b5..00000000 --- a/pkg/controller/preflight/preflight_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflight - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/preflight/preflight_controller_test.go b/pkg/controller/preflight/preflight_controller_test.go deleted file mode 100644 index 17439255..00000000 --- a/pkg/controller/preflight/preflight_controller_test.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflight - -import ( - "testing" - "time" - - "github.com/onsi/gomega" - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - "golang.org/x/net/context" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var c client.Client - -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} -var depKey = types.NamespacedName{Name: "foo-deployment", Namespace: "default"} - -const timeout = time.Second * 5 - -func TestReconcile(t *testing.T) { - g := gomega.NewGomegaWithT(t) - instance := &troubleshootv1beta1.Preflight{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "default"}} - - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c = mgr.GetClient() - - recFn, requests := SetupTestReconcile(newReconciler(mgr)) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) - - stopMgr, mgrStopped := StartTestManager(mgr, g) - - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() - - // Create the Preflight object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return - } - g.Expect(err).NotTo(gomega.HaveOccurred()) - defer c.Delete(context.TODO(), instance) - g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) -} diff --git a/pkg/controller/preflightjob/analyzers.go b/pkg/controller/preflightjob/analyzers.go deleted file mode 100644 index 0f9789b4..00000000 --- a/pkg/controller/preflightjob/analyzers.go +++ /dev/null @@ -1,64 +0,0 @@ -package preflightjob - -import ( - "context" - // "fmt" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" -) - -type AnalysisResult struct { - Success bool - TextOutput string -} - -func (r *ReconcilePreflightJob) reconcilePreflightAnalyzers(instance *troubleshootv1beta1.PreflightJob, preflight *troubleshootv1beta1.Preflight) error { - for _, analyzer := range preflight.Spec.Analyzers { - if err := r.reconcileOnePreflightAnalyzer(instance, analyzer); err != nil { - return err - } - } - - return nil -} - -func (r *ReconcilePreflightJob) reconcileOnePreflightAnalyzer(instance *troubleshootv1beta1.PreflightJob, analyze *troubleshootv1beta1.Analyze) error { - if contains(instance.Status.AnalyzersRunning, idForAnalyzer(analyze)) { - // these are the analyzers we want to attempt to run - if analyze.ClusterVersion != nil { - result, err := r.analyzeClusterVersion(instance, analyze.ClusterVersion) - if err != nil { - return err - } - - if result.Success == false { - return nil // collectors are not yet ready - } - - instance.Status.AnalyzersSuccessful = append(instance.Status.AnalyzersSuccessful, idForAnalyzer(analyze)) - instance.Status.AnalyzersRunning = remove(instance.Status.AnalyzersRunning, idForAnalyzer(analyze)) - - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil - } - - return nil - } - - return nil -} - -func idForAnalyzer(analyzer *troubleshootv1beta1.Analyze) string { - if analyzer.ClusterVersion != nil { - return "cluster-version" - } - - if analyzer.StorageClass != nil { - return "storage-classes" - } - - return "" -} diff --git a/pkg/controller/preflightjob/cluster_version.go b/pkg/controller/preflightjob/cluster_version.go deleted file mode 100644 index b6492d07..00000000 --- a/pkg/controller/preflightjob/cluster_version.go +++ /dev/null @@ -1,11 +0,0 @@ -package preflightjob - -import ( - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" -) - -func (r *ReconcilePreflightJob) analyzeClusterVersion(instance *troubleshootv1beta1.PreflightJob, clusterVersion *troubleshootv1beta1.ClusterVersion) (*AnalysisResult, error) { - return &AnalysisResult{ - Success: true, - }, nil -} diff --git a/pkg/controller/preflightjob/collectors.go b/pkg/controller/preflightjob/collectors.go deleted file mode 100644 index 792bcf3c..00000000 --- a/pkg/controller/preflightjob/collectors.go +++ /dev/null @@ -1,89 +0,0 @@ -package preflightjob - -import ( - "context" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - collectrunner "github.com/replicatedhq/troubleshoot/pkg/collect" -) - -func (r *ReconcilePreflightJob) reconcilePreflightCollectors(instance *troubleshootv1beta1.PreflightJob, preflight *troubleshootv1beta1.Preflight) error { - requestedCollectorIDs := make([]string, 0, 0) - for _, collector := range preflight.Spec.Collectors { - requestedCollectorIDs = append(requestedCollectorIDs, collectrunner.DeterministicIDForCollector(collector)) - if err := r.reconcileOnePreflightCollector(instance, collector); err != nil { - return err - } - } - - if !contains(requestedCollectorIDs, "cluster-info") { - clusterInfo := troubleshootv1beta1.Collect{ - ClusterInfo: &troubleshootv1beta1.ClusterInfo{}, - } - if err := r.reconcileOnePreflightCollector(instance, &clusterInfo); err != nil { - return err - } - } - if !contains(requestedCollectorIDs, "cluster-resources") { - clusterResources := troubleshootv1beta1.Collect{ - ClusterResources: &troubleshootv1beta1.ClusterResources{}, - } - if err := r.reconcileOnePreflightCollector(instance, &clusterResources); err != nil { - return err - } - } - - return nil -} - -func (r *ReconcilePreflightJob) reconcileOnePreflightCollector(instance *troubleshootv1beta1.PreflightJob, collect *troubleshootv1beta1.Collect) error { - if contains(instance.Status.CollectorsRunning, collectrunner.DeterministicIDForCollector(collect)) { - // preflight just leaves these stopped containers. - // it's playing with fire a little, but the analyzers can just - // read from the stdout of the stopped container - // - // in the very common use case (what we are building for today) - // there's not too much risk in something destroying and reaping that stopped pod - // immediately. this is a longer term problem to solve, maybe something, - // the mananger? can broker these collector results. but, ya know... - - instance.Status.CollectorsSuccessful = append(instance.Status.CollectorsSuccessful, collectrunner.DeterministicIDForCollector(collect)) - instance.Status.CollectorsRunning = remove(instance.Status.CollectorsRunning, collectrunner.DeterministicIDForCollector(collect)) - - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil - } - - _, _, err := collectrunner.CreateCollector(r.Client, r.scheme, instance, instance.Name, instance.Namespace, "", "preflight", collect, instance.Spec.Image, instance.Spec.ImagePullPolicy) - if err != nil { - return err - } - - instance.Status.CollectorsRunning = append(instance.Status.CollectorsRunning, collectrunner.DeterministicIDForCollector(collect)) - if err := r.Update(context.Background(), instance); err != nil { - return err - } - - return nil -} - -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false -} - -func remove(s []string, r string) []string { - for i, v := range s { - if v == r { - return append(s[:i], s[i+1:]...) - } - } - return s -} diff --git a/pkg/controller/preflightjob/preflightjob_controller.go b/pkg/controller/preflightjob/preflightjob_controller.go deleted file mode 100644 index f07ea2ba..00000000 --- a/pkg/controller/preflightjob/preflightjob_controller.go +++ /dev/null @@ -1,178 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflightjob - -import ( - "context" - - troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" - troubleshootclientv1beta1 "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/typed/troubleshoot/v1beta1" - "github.com/replicatedhq/troubleshoot/pkg/preflight" - kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -var log = logf.Log.WithName("controller") - -// Add creates a new PreflightJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller -// and Start it when the Manager is Started. -func Add(mgr manager.Manager) error { - return add(mgr, newReconciler(mgr)) -} - -// newReconciler returns a new reconcile.Reconciler -func newReconciler(mgr manager.Manager) reconcile.Reconciler { - return &ReconcilePreflightJob{ - Client: mgr.GetClient(), - config: mgr.GetConfig(), - scheme: mgr.GetScheme(), - } -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler -func add(mgr manager.Manager, r reconcile.Reconciler) error { - // Create a new controller - c, err := controller.New("preflightjob-controller", mgr, controller.Options{Reconciler: r}) - if err != nil { - return err - } - - // Watch for changes to PreflightJob - err = c.Watch(&source.Kind{Type: &troubleshootv1beta1.PreflightJob{}}, &handler.EnqueueRequestForObject{}) - if err != nil { - return err - } - - return nil -} - -var _ reconcile.Reconciler = &ReconcilePreflightJob{} - -// ReconcilePreflightJob reconciles a PreflightJob object -type ReconcilePreflightJob struct { - client.Client - config *rest.Config - scheme *runtime.Scheme -} - -// Reconcile reads that state of the cluster for a PreflightJob object and makes changes based on the state read -// and what is in the PreflightJob.Spec -// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes -// a Deployment as an example -// Automatically generate RBAC rules to allow the Controller to read and write Deployments -// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflightjobs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=troubleshoot.replicated.com,resources=preflightjobs/status,verbs=get;update;patch -func (r *ReconcilePreflightJob) Reconcile(request reconcile.Request) (reconcile.Result, error) { - // Fetch the PreflightJob instance - instance := &troubleshootv1beta1.PreflightJob{} - err := r.Get(context.TODO(), request.NamespacedName, instance) - if err != nil { - if kuberneteserrors.IsNotFound(err) { - // Object not found, return. Created objects are automatically garbage collected. - // For additional cleanup logic use finalizers. - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, err - } - - if !instance.Status.IsServerReady { - preflightServerOptions := preflight.PreflightServerOptions{ - ImageName: instance.Spec.Image, - PullPolicy: instance.Spec.ImagePullPolicy, - Name: instance.Name, - Namespace: instance.Namespace, - OwnerReference: instance, - } - pod, _, err := preflight.CreatePreflightServer(r.Client, r.scheme, preflightServerOptions) - if err != nil { - return reconcile.Result{}, err - } - - instance.Status.ServerPodName = pod.Name - instance.Status.ServerPodNamespace = pod.Namespace - instance.Status.ServerPodPort = 8000 - instance.Status.IsServerReady = true - - if err := r.Update(context.Background(), instance); err != nil { - return reconcile.Result{}, err - } - - } - - namespace := instance.Namespace - if instance.Spec.Preflight.Namespace != "" { - namespace = instance.Spec.Preflight.Namespace - } - - preflightSpec, err := r.getPreflightSpec(namespace, instance.Spec.Preflight.Name) - if err != nil { - return reconcile.Result{}, err - } - - if len(instance.Status.AnalyzersRunning) == 0 && len(instance.Status.AnalyzersSuccessful) == 0 && len(instance.Status.AnalyzersFailed) == 0 { - // Add them all! - analyzersRunning := []string{} - for _, analyzer := range preflightSpec.Spec.Analyzers { - analyzersRunning = append(analyzersRunning, idForAnalyzer(analyzer)) - } - - instance.Status.AnalyzersRunning = analyzersRunning - if err := r.Update(context.Background(), instance); err != nil { - return reconcile.Result{}, err - } - } - - if err := r.reconcilePreflightCollectors(instance, preflightSpec); err != nil { - return reconcile.Result{}, err - } - if err := r.reconcilePreflightAnalyzers(instance, preflightSpec); err != nil { - return reconcile.Result{}, err - } - - // just finished, nothing to do - return reconcile.Result{}, nil -} - -func (r *ReconcilePreflightJob) getPreflightSpec(namespace string, name string) (*troubleshootv1beta1.Preflight, error) { - troubleshootClient, err := troubleshootclientv1beta1.NewForConfig(r.config) - if err != nil { - return nil, err - } - - preflight, err := troubleshootClient.Preflights(namespace).Get(name, metav1.GetOptions{}) - if err != nil { - if kuberneteserrors.IsNotFound(err) { - return nil, nil - } - - return nil, err - } - - return preflight, nil -} diff --git a/pkg/controller/preflightjob/preflightjob_controller_suite_test.go b/pkg/controller/preflightjob/preflightjob_controller_suite_test.go deleted file mode 100644 index f86f6179..00000000 --- a/pkg/controller/preflightjob/preflightjob_controller_suite_test.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflightjob - -import ( - stdlog "log" - "os" - "path/filepath" - "sync" - "testing" - - "github.com/onsi/gomega" - "github.com/replicatedhq/troubleshoot/pkg/apis" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/envtest" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -var cfg *rest.Config - -func TestMain(m *testing.M) { - t := &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crds")}, - } - apis.AddToScheme(scheme.Scheme) - - var err error - if cfg, err = t.Start(); err != nil { - stdlog.Fatal(err) - } - - code := m.Run() - t.Stop() - os.Exit(code) -} - -// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and -// writes the request to requests after Reconcile is finished. -func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { - requests := make(chan reconcile.Request) - fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { - result, err := inner.Reconcile(req) - requests <- req - return result, err - }) - return fn, requests -} - -// StartTestManager adds recFn -func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { - stop := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) - }() - return stop, wg -} diff --git a/pkg/controller/preflightjob/preflightjob_controller_test.go b/pkg/controller/preflightjob/preflightjob_controller_test.go deleted file mode 100644 index 4fce2318..00000000 --- a/pkg/controller/preflightjob/preflightjob_controller_test.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2019 Replicated, Inc.. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preflightjob - -import ( - "testing" -) - -func TestReconcile(t *testing.T) { - -}