...

Source file src/edge-infra.dev/pkg/edge/webhooks/edge-injector/webhook.go

Documentation: edge-infra.dev/pkg/edge/webhooks/edge-injector

     1  package edgeinjector
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	appsv1 "k8s.io/api/apps/v1"
     8  	corev1 "k8s.io/api/core/v1"
     9  	virtv1 "kubevirt.io/api/core/v1"
    10  	"sigs.k8s.io/controller-runtime/pkg/webhook"
    11  	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
    12  
    13  	dsapi "edge-infra.dev/pkg/edge/datasync/apis/v1alpha1"
    14  	dsv1 "edge-infra.dev/pkg/sds/devices/k8s/apis/v1"
    15  
    16  	"github.com/go-logr/logr"
    17  
    18  	"edge-infra.dev/pkg/k8s/runtime/controller"
    19  	"edge-infra.dev/pkg/lib/fog"
    20  
    21  	"k8s.io/apimachinery/pkg/runtime"
    22  	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    23  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    24  	ctrl "sigs.k8s.io/controller-runtime"
    25  )
    26  
    27  // +kubebuilder:rbac:groups="",resources=pods;nodes,verbs=get;list;watch
    28  // +kubebuilder:rbac:groups="",resources=secrets,verbs=create;get;list;update;patch;watch;delete
    29  // +kubebuilder:rbac:groups="",resources=pods/status;secrets/status;nodes/status,verbs=get;watch
    30  // +kubebuilder:rbac:groups="apps",resources=daemonsets;deployments;replicasets;statefulsets,verbs=get;list;watch
    31  // +kubebuilder:rbac:groups="datasync.edge.ncr.com",resources=couchdbusers,verbs=create;get;list;update;patch;watch
    32  // +kubebuilder:rbac:groups="datasync.edge.ncr.com",resources=couchdbusers/status,verbs=get;watch
    33  // +kubebuilder:rbac:groups="device-system.edge.ncr.com",resources=devicestatuses,verbs=get;watch;list
    34  
    35  func Run(o ...controller.Option) error {
    36  	log := fog.New()
    37  	log.WithName("EdgeInjector")
    38  
    39  	c, err := NewConfig()
    40  	if err != nil {
    41  		log.Error(err, "fail to build configuration")
    42  		os.Exit(1)
    43  	}
    44  
    45  	mgr, err := create(log, c, o...)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	log.Info("starting webhooks")
    51  	if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
    52  		log.Error(err, "problem running manager")
    53  		return err
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  // create a webhook, implementation example can be found here: https://book.kubebuilder.io/cronjob-tutorial/webhook-implementation.html
    60  func create(log logr.Logger, c *Config, o ...controller.Option) (ctrl.Manager, error) {
    61  	ctrl.SetLogger(log)
    62  
    63  	log.Info("setting up manager")
    64  
    65  	if c.EnableWebhook {
    66  		o = append(o,
    67  			controller.WithCertDir(c.CertDir),
    68  			controller.WithPort(c.Port),
    69  		)
    70  	}
    71  
    72  	mgr, err := createManager(o...)
    73  	if err != nil {
    74  		ctrl.Log.Error(err, "unable to create manager")
    75  		return nil, err
    76  	}
    77  
    78  	if c.EnableWebhook {
    79  		webhookServer := mgr.GetWebhookServer()
    80  		webhookServer.Register(Path(CouchDBSecret), &webhook.Admission{Handler: admission.WithCustomDefaulter(createScheme(), &corev1.Pod{}, &CouchUserWebhook{Client: mgr.GetClient()})})
    81  		webhookServer.Register(Path(NodeSecret), &webhook.Admission{Handler: admission.WithCustomDefaulter(createScheme(), &corev1.Pod{}, &NodeWebhook{Client: mgr.GetClient()})})
    82  		webhookServer.Register("/resourcerequest-deployment", &admission.Webhook{Handler: admission.WithCustomDefaulter(createScheme(), &appsv1.Deployment{}, &ResourceRequestWebhook{Client: mgr.GetClient()})})
    83  		webhookServer.Register("/resourcerequest-daemonset", &admission.Webhook{Handler: admission.WithCustomDefaulter(createScheme(), &appsv1.DaemonSet{}, &ResourceRequestWebhook{Client: mgr.GetClient()})})
    84  		webhookServer.Register("/resourcerequest-statefulset", &admission.Webhook{Handler: admission.WithCustomDefaulter(createScheme(), &appsv1.StatefulSet{}, &ResourceRequestWebhook{Client: mgr.GetClient()})})
    85  		webhookServer.Register("/resourcerequest-pods", &admission.Webhook{Handler: admission.WithCustomDefaulter(createScheme(), &corev1.Pod{}, &ResourceRequestWebhook{Client: mgr.GetClient()})})
    86  		webhookServer.Register("/device-class-validation-deviceclasses", &admission.Webhook{Handler: admission.WithCustomValidator(createScheme(), &dsv1.DeviceClass{}, &DeviceClassWebhook{})})
    87  		webhookServer.Register("/device-class-validation-devicesets", &admission.Webhook{Handler: admission.WithCustomValidator(createScheme(), &dsv1.DeviceSet{}, &DeviceClassWebhook{})})
    88  	}
    89  
    90  	if err := (&PodSecretReconciler{
    91  		Client:               mgr.GetClient(),
    92  		Name:                 "podsecretreconciler",
    93  		RequeueTime:          c.RequeueTime,
    94  		PollingInterval:      c.PollingInterval,
    95  		ReconcileConcurrency: c.ReconcileConcurrency,
    96  	}).SetupWithManager(mgr); err != nil {
    97  		log.Error(err, "failed to create PodSecretReconciler and set up with manager")
    98  		return nil, err
    99  	}
   100  
   101  	return mgr, nil
   102  }
   103  
   104  func createManager(o ...controller.Option) (ctrl.Manager, error) {
   105  	cfg, opts := controller.ProcessOptions(o...)
   106  	opts.LeaderElectionID = InjectorLabel
   107  	opts.Scheme = createScheme()
   108  
   109  	return ctrl.NewManager(cfg, opts)
   110  }
   111  
   112  func Path(s SecretType) string {
   113  	return fmt.Sprintf("/mutating-create-update-pod-%s", s)
   114  }
   115  
   116  func createScheme() *runtime.Scheme {
   117  	scheme := runtime.NewScheme()
   118  	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
   119  	utilruntime.Must(dsapi.AddToScheme(scheme))
   120  	utilruntime.Must(dsv1.AddToScheme(scheme))
   121  	utilruntime.Must(virtv1.AddToScheme(scheme))
   122  	return scheme
   123  }
   124  

View as plain text