sigs.k8s.io/kubebuilder/v3@v3.14.0/pkg/plugins/golang/declarative/v1/scaffolds/internal/templates/controller.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package templates
    18  
    19  import (
    20  	"path/filepath"
    21  
    22  	log "github.com/sirupsen/logrus"
    23  
    24  	"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
    25  )
    26  
    27  var _ machinery.Template = &Controller{}
    28  
    29  // Controller scaffolds the file that defines the controller for a CRD or a builtin resource
    30  // nolint:maligned
    31  type Controller struct {
    32  	machinery.TemplateMixin
    33  	machinery.MultiGroupMixin
    34  	machinery.BoilerplateMixin
    35  	machinery.ResourceMixin
    36  
    37  	IsLegacyLayout bool
    38  	PackageName    string
    39  }
    40  
    41  // SetTemplateDefaults implements file.Template
    42  func (f *Controller) SetTemplateDefaults() error {
    43  	if f.Path == "" {
    44  		if f.IsLegacyLayout {
    45  			if f.MultiGroup {
    46  				f.Path = filepath.Join("controllers", "%[group]", "%[kind]_controller.go")
    47  			} else {
    48  				f.Path = filepath.Join("controllers", "%[kind]_controller.go")
    49  			}
    50  		} else {
    51  			if f.MultiGroup {
    52  				f.Path = filepath.Join("internal", "controller", "%[group]", "%[kind]_controller.go")
    53  			} else {
    54  				f.Path = filepath.Join("internal", "controller", "%[kind]_controller.go")
    55  			}
    56  		}
    57  
    58  	}
    59  	f.Path = f.Resource.Replacer().Replace(f.Path)
    60  	log.Println(f.Path)
    61  
    62  	f.PackageName = "controller"
    63  	if f.IsLegacyLayout {
    64  		f.PackageName = "controllers"
    65  	}
    66  
    67  	f.TemplateBody = controllerTemplate
    68  
    69  	f.IfExistsAction = machinery.OverwriteFile
    70  
    71  	return nil
    72  }
    73  
    74  //nolint:lll
    75  const controllerTemplate = `{{ .Boilerplate }}
    76  
    77  package {{ .PackageName }}
    78  
    79  import (
    80  	"github.com/go-logr/logr"
    81  	"k8s.io/apimachinery/pkg/runtime"
    82  	ctrl "sigs.k8s.io/controller-runtime"
    83  	"sigs.k8s.io/controller-runtime/pkg/client"
    84  	"sigs.k8s.io/controller-runtime/pkg/controller"
    85  	"sigs.k8s.io/controller-runtime/pkg/handler"
    86  	"sigs.k8s.io/controller-runtime/pkg/reconcile"
    87  	"sigs.k8s.io/controller-runtime/pkg/source"
    88  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon"
    89  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/status"
    90  	"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
    91  
    92  	{{ .Resource.ImportAlias }} "{{ .Resource.Path }}"
    93  )
    94  
    95  var _ reconcile.Reconciler = &{{ .Resource.Kind }}Reconciler{}
    96  
    97  // {{ .Resource.Kind }}Reconciler reconciles a {{ .Resource.Kind }} object
    98  type {{ .Resource.Kind }}Reconciler struct {
    99  	client.Client
   100  	Log    logr.Logger
   101  	Scheme *runtime.Scheme
   102  
   103  	declarative.Reconciler
   104  }
   105  
   106  //+kubebuilder:rbac:groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }},verbs=get;list;watch;create;update;patch;delete
   107  //+kubebuilder:rbac:groups={{ .Resource.QualifiedGroup }},resources={{ .Resource.Plural }}/status,verbs=get;update;patch
   108  
   109  // SetupWithManager sets up the controller with the Manager.
   110  func (r *{{ .Resource.Kind }}Reconciler) SetupWithManager(mgr ctrl.Manager) error {
   111  	addon.Init()
   112  
   113  	labels := map[string]string{
   114  		"k8s-app": "{{ lower .Resource.Kind }}",
   115  	}
   116  
   117  	watchLabels := declarative.SourceLabel(mgr.GetScheme())
   118  
   119  	if err := r.Reconciler.Init(mgr, &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{},
   120  		declarative.WithObjectTransform(declarative.AddLabels(labels)),
   121  		declarative.WithOwner(declarative.SourceAsOwner),
   122  		declarative.WithLabels(watchLabels),
   123  		declarative.WithStatus(status.NewBasic(mgr.GetClient())),
   124  		// TODO: add an application to your manifest:  declarative.WithObjectTransform(addon.TransformApplicationFromStatus),
   125  		// TODO: add an application to your manifest:  declarative.WithManagedApplication(watchLabels),
   126  		declarative.WithObjectTransform(addon.ApplyPatches),
   127  	); err != nil {
   128  		return err
   129  	}
   130  
   131  	c, err := controller.New("{{ lower .Resource.Kind }}-controller", mgr, controller.Options{Reconciler: r})
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	// Watch for changes to {{ .Resource.Kind }}
   137  	err = c.Watch(source.Kind(mgr.GetCache(), &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{}), &handler.EnqueueRequestForObject{})
   138  	if err != nil {
   139  		return err
   140  	}
   141  
   142  	// Watch for changes to deployed objects
   143  	err = declarative.WatchAll(mgr.GetConfig(), c, r, watchLabels)
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	return nil
   149  }
   150  `