github.com/fabianvf/ocp-release-operator-sdk@v0.0.0-20190426141702-57620ee2f090/pkg/ansible/controller/controller.go (about)

     1  // Copyright 2018 The Operator-SDK Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package controller
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"strings"
    21  	"time"
    22  
    23  	"github.com/operator-framework/operator-sdk/pkg/ansible/events"
    24  	"github.com/operator-framework/operator-sdk/pkg/ansible/runner"
    25  	"github.com/operator-framework/operator-sdk/pkg/predicate"
    26  
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  	"k8s.io/apimachinery/pkg/runtime/schema"
    31  	"sigs.k8s.io/controller-runtime/pkg/client"
    32  	"sigs.k8s.io/controller-runtime/pkg/controller"
    33  	crthandler "sigs.k8s.io/controller-runtime/pkg/handler"
    34  	"sigs.k8s.io/controller-runtime/pkg/manager"
    35  	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
    36  	"sigs.k8s.io/controller-runtime/pkg/source"
    37  )
    38  
    39  var log = logf.Log.WithName("ansible-controller")
    40  
    41  // Options - options for your controller
    42  type Options struct {
    43  	EventHandlers               []events.EventHandler
    44  	LoggingLevel                events.LogLevel
    45  	Runner                      runner.Runner
    46  	GVK                         schema.GroupVersionKind
    47  	ReconcilePeriod             time.Duration
    48  	ManageStatus                bool
    49  	WatchDependentResources     bool
    50  	WatchClusterScopedResources bool
    51  	MaxWorkers                  int
    52  }
    53  
    54  // Add - Creates a new ansible operator controller and adds it to the manager
    55  func Add(mgr manager.Manager, options Options) *controller.Controller {
    56  	log.Info("Watching resource", "Options.Group", options.GVK.Group, "Options.Version", options.GVK.Version, "Options.Kind", options.GVK.Kind)
    57  	if options.EventHandlers == nil {
    58  		options.EventHandlers = []events.EventHandler{}
    59  	}
    60  	eventHandlers := append(options.EventHandlers, events.NewLoggingEventHandler(options.LoggingLevel))
    61  	apiReader, err := client.New(mgr.GetConfig(), client.Options{})
    62  	if err != nil {
    63  		log.Error(err, "Unable to get new api client")
    64  	}
    65  
    66  	aor := &AnsibleOperatorReconciler{
    67  		// The default client will use the DelegatingReader for reads
    68  		// this forces it to use the cache for unstructured types.
    69  		Client: client.DelegatingClient{
    70  			Reader:       mgr.GetCache(),
    71  			Writer:       mgr.GetClient(),
    72  			StatusClient: mgr.GetClient(),
    73  		},
    74  		APIReader:       apiReader,
    75  		GVK:             options.GVK,
    76  		Runner:          options.Runner,
    77  		EventHandlers:   eventHandlers,
    78  		ReconcilePeriod: options.ReconcilePeriod,
    79  		ManageStatus:    options.ManageStatus,
    80  	}
    81  
    82  	scheme := mgr.GetScheme()
    83  	_, err = scheme.New(options.GVK)
    84  	if runtime.IsNotRegisteredError(err) {
    85  		// Register the GVK with the schema
    86  		scheme.AddKnownTypeWithName(options.GVK, &unstructured.Unstructured{})
    87  		metav1.AddToGroupVersion(mgr.GetScheme(), schema.GroupVersion{
    88  			Group:   options.GVK.Group,
    89  			Version: options.GVK.Version,
    90  		})
    91  	} else if err != nil {
    92  		log.Error(err, "")
    93  		os.Exit(1)
    94  	}
    95  
    96  	//Create new controller runtime controller and set the controller to watch GVK.
    97  	c, err := controller.New(fmt.Sprintf("%v-controller", strings.ToLower(options.GVK.Kind)), mgr, controller.Options{
    98  		Reconciler:              aor,
    99  		MaxConcurrentReconciles: options.MaxWorkers,
   100  	})
   101  	if err != nil {
   102  		log.Error(err, "")
   103  		os.Exit(1)
   104  	}
   105  	u := &unstructured.Unstructured{}
   106  	u.SetGroupVersionKind(options.GVK)
   107  	if err := c.Watch(&source.Kind{Type: u}, &crthandler.EnqueueRequestForObject{}, predicate.GenerationChangedPredicate{}); err != nil {
   108  		log.Error(err, "")
   109  		os.Exit(1)
   110  	}
   111  	return &c
   112  }