1
1
/*
2
- Copyright 2018 The Kubernetes Authors.
2
+ Copyright 2019 The Kubernetes Authors.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -14,54 +14,127 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
+ //go:generate go run ./vendor/sigs.k8s.io/controller-tools/cmd/crd generate --domain metamagical.io
17
18
package main
18
19
19
20
import (
20
- "flag"
21
+ "context"
22
+ "math/rand"
21
23
"os"
24
+ "time"
22
25
23
- appsv1 "k8s.io/api/apps/v1"
26
+ corev1 "k8s.io/api/core/v1"
27
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
28
+ "k8s.io/apimachinery/pkg/runtime"
24
29
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
25
- "sigs.k8s.io/controller-runtime/examples/crd/pkg"
26
- "sigs.k8s.io/controller-runtime/pkg/builder"
27
- "sigs.k8s.io/controller-runtime/pkg/client/config"
28
- "sigs.k8s.io/controller-runtime/pkg/manager"
29
- logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
30
- "sigs.k8s.io/controller-runtime/pkg/runtime/signals"
30
+ ctrl "sigs.k8s.io/controller-runtime"
31
+ api "sigs.k8s.io/controller-runtime/examples/crd/pkg"
32
+ "sigs.k8s.io/controller-runtime/pkg/client"
33
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
31
34
)
32
35
33
- var log = logf .Log .WithName ("example-controller" )
36
+ var (
37
+ setupLog = ctrl .Log .WithName ("setup" )
38
+ recLog = ctrl .Log .WithName ("reconciler" )
39
+ )
40
+
41
+ type reconciler struct {
42
+ client.Client
43
+ scheme * runtime.Scheme
44
+ }
45
+
46
+ func (r * reconciler ) Reconcile (req ctrl.Request ) (ctrl.Result , error ) {
47
+ log := recLog .WithValues ("chaospod" , req .NamespacedName )
48
+ log .V (1 ).Info ("reconciling chaos pod" )
49
+ ctx := context .Background ()
50
+
51
+ var chaosctl api.ChaosPod
52
+ if err := r .Get (ctx , req .NamespacedName , & chaosctl ); err != nil {
53
+ log .Error (err , "unable to get chaosctl" )
54
+ return ctrl.Result {}, err
55
+ }
56
+
57
+ var pod corev1.Pod
58
+ podFound := true
59
+ if err := r .Get (ctx , req .NamespacedName , & pod ); err != nil {
60
+ if ! apierrors .IsNotFound (err ) {
61
+ log .Error (err , "unable to get pod" )
62
+ return ctrl.Result {}, err
63
+ }
64
+ podFound = false
65
+ }
66
+
67
+ if podFound {
68
+ shouldStop := chaosctl .Spec .NextStop .Time .Before (time .Now ())
69
+ if ! shouldStop {
70
+ return ctrl.Result {RequeueAfter : chaosctl .Spec .NextStop .Sub (time .Now ()) + 1 * time .Second }, nil
71
+ }
72
+
73
+ if err := r .Delete (ctx , & pod ); err != nil {
74
+ log .Error (err , "unable to delete pod" )
75
+ return ctrl.Result {}, err
76
+ }
77
+
78
+ return ctrl.Result {Requeue : true }, nil
79
+ }
80
+
81
+ templ := chaosctl .Spec .Template .DeepCopy ()
82
+ pod .ObjectMeta = templ .ObjectMeta
83
+ pod .Name = req .Name
84
+ pod .Namespace = req .Namespace
85
+ pod .Spec = templ .Spec
86
+
87
+ if err := ctrl .SetControllerReference (& chaosctl , & pod , r .scheme ); err != nil {
88
+ log .Error (err , "unable to set pod's owner reference" )
89
+ return ctrl.Result {}, err
90
+ }
91
+
92
+ if err := r .Create (ctx , & pod ); err != nil {
93
+ log .Error (err , "unable to create pod" )
94
+ return ctrl.Result {}, err
95
+ }
96
+
97
+ chaosctl .Spec .NextStop .Time = time .Now ().Add (time .Duration (10 * (rand .Int63n (2 )+ 1 )) * time .Second )
98
+ chaosctl .Status .LastRun = pod .CreationTimestamp
99
+ if err := r .Update (ctx , & chaosctl ); err != nil {
100
+ log .Error (err , "unable to update chaosctl status" )
101
+ return ctrl.Result {}, err
102
+ }
103
+ return ctrl.Result {}, nil
104
+ }
34
105
35
106
func main () {
36
- flag .Parse ()
37
- entryLog := log .WithName ("entrypoint" )
107
+ ctrl .SetLogger (zap .Logger (true ))
38
108
39
- entryLog .Info ("setting up manager" )
40
- mgr , err := manager .New (config .GetConfigOrDie (), manager.Options {})
109
+ mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {})
41
110
if err != nil {
42
- entryLog .Error (err , "unable to set up overall controller manager" )
111
+ setupLog .Error (err , "unable to start manager" )
43
112
os .Exit (1 )
44
113
}
45
114
46
- entryLog .Info ("setting up scheme" )
47
- if err := pkg .AddToScheme (mgr .GetScheme ()); err != nil {
48
- entryLog .Error (err , "unable add APIs to scheme" )
115
+ // in a real controller, we'd create a new scheme for this
116
+ err = api .AddToScheme (mgr .GetScheme ())
117
+ if err != nil {
118
+ setupLog .Error (err , "unable to add scheme" )
49
119
os .Exit (1 )
50
120
}
51
121
52
- entryLog .Info ("setting up controllers" )
53
- err = builder .ControllerManagedBy (mgr ).
54
- For (& pkg.FirstMate {}).
55
- Owns (& appsv1.Deployment {}).
56
- Complete (& FirstMateController {})
122
+ err = ctrl .NewControllerManagedBy (mgr ).
123
+ For (& api.ChaosPod {}).
124
+ Owns (& corev1.Pod {}).
125
+ Complete (& reconciler {
126
+ Client : mgr .GetClient (),
127
+ scheme : mgr .GetScheme (),
128
+ })
129
+
57
130
if err != nil {
58
- entryLog .Error (err , "unable to set up controllers " )
131
+ setupLog .Error (err , "unable to create controller " )
59
132
os .Exit (1 )
60
133
}
61
134
62
- entryLog .Info ("starting manager" )
63
- if err := mgr .Start (signals .SetupSignalHandler ()); err != nil {
64
- entryLog .Error (err , "unable to run manager" )
135
+ setupLog .Info ("starting manager" )
136
+ if err := mgr .Start (ctrl .SetupSignalHandler ()); err != nil {
137
+ setupLog .Error (err , "problem running manager" )
65
138
os .Exit (1 )
66
139
}
67
140
}
0 commit comments