sigs.k8s.io/controller-runtime@v0.18.2/examples/crd/main.go (about) 1 /* 2 Copyright 2019 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 main 18 19 import ( 20 "context" 21 "math/rand" 22 "os" 23 "time" 24 25 corev1 "k8s.io/api/core/v1" 26 apierrors "k8s.io/apimachinery/pkg/api/errors" 27 "k8s.io/apimachinery/pkg/runtime" 28 _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" 29 ctrl "sigs.k8s.io/controller-runtime" 30 api "sigs.k8s.io/controller-runtime/examples/crd/pkg" 31 "sigs.k8s.io/controller-runtime/pkg/client" 32 "sigs.k8s.io/controller-runtime/pkg/log" 33 "sigs.k8s.io/controller-runtime/pkg/log/zap" 34 ) 35 36 var ( 37 setupLog = ctrl.Log.WithName("setup") 38 ) 39 40 type reconciler struct { 41 client.Client 42 scheme *runtime.Scheme 43 } 44 45 func (r *reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 46 log := log.FromContext(ctx).WithValues("chaospod", req.NamespacedName) 47 log.V(1).Info("reconciling chaos pod") 48 49 var chaospod api.ChaosPod 50 if err := r.Get(ctx, req.NamespacedName, &chaospod); err != nil { 51 log.Error(err, "unable to get chaosctl") 52 return ctrl.Result{}, err 53 } 54 55 var pod corev1.Pod 56 podFound := true 57 if err := r.Get(ctx, req.NamespacedName, &pod); err != nil { 58 if !apierrors.IsNotFound(err) { 59 log.Error(err, "unable to get pod") 60 return ctrl.Result{}, err 61 } 62 podFound = false 63 } 64 65 if podFound { 66 shouldStop := chaospod.Spec.NextStop.Time.Before(time.Now()) 67 if !shouldStop { 68 return ctrl.Result{RequeueAfter: chaospod.Spec.NextStop.Sub(time.Now()) + 1*time.Second}, nil 69 } 70 71 if err := r.Delete(ctx, &pod); err != nil { 72 log.Error(err, "unable to delete pod") 73 return ctrl.Result{}, err 74 } 75 76 return ctrl.Result{Requeue: true}, nil 77 } 78 79 templ := chaospod.Spec.Template.DeepCopy() 80 pod.ObjectMeta = templ.ObjectMeta 81 pod.Name = req.Name 82 pod.Namespace = req.Namespace 83 pod.Spec = templ.Spec 84 85 if err := ctrl.SetControllerReference(&chaospod, &pod, r.scheme); err != nil { 86 log.Error(err, "unable to set pod's owner reference") 87 return ctrl.Result{}, err 88 } 89 90 if err := r.Create(ctx, &pod); err != nil { 91 log.Error(err, "unable to create pod") 92 return ctrl.Result{}, err 93 } 94 95 chaospod.Spec.NextStop.Time = time.Now().Add(time.Duration(10*(rand.Int63n(2)+1)) * time.Second) 96 chaospod.Status.LastRun = pod.CreationTimestamp 97 if err := r.Update(ctx, &chaospod); err != nil { 98 log.Error(err, "unable to update chaosctl status") 99 return ctrl.Result{}, err 100 } 101 return ctrl.Result{}, nil 102 } 103 104 func main() { 105 ctrl.SetLogger(zap.New()) 106 107 mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{}) 108 if err != nil { 109 setupLog.Error(err, "unable to start manager") 110 os.Exit(1) 111 } 112 113 // in a real controller, we'd create a new scheme for this 114 err = api.AddToScheme(mgr.GetScheme()) 115 if err != nil { 116 setupLog.Error(err, "unable to add scheme") 117 os.Exit(1) 118 } 119 120 err = ctrl.NewControllerManagedBy(mgr). 121 For(&api.ChaosPod{}). 122 Owns(&corev1.Pod{}). 123 Complete(&reconciler{ 124 Client: mgr.GetClient(), 125 scheme: mgr.GetScheme(), 126 }) 127 if err != nil { 128 setupLog.Error(err, "unable to create controller") 129 os.Exit(1) 130 } 131 132 err = ctrl.NewWebhookManagedBy(mgr). 133 For(&api.ChaosPod{}). 134 Complete() 135 if err != nil { 136 setupLog.Error(err, "unable to create webhook") 137 os.Exit(1) 138 } 139 140 setupLog.Info("starting manager") 141 if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { 142 setupLog.Error(err, "problem running manager") 143 os.Exit(1) 144 } 145 }