1 package pxe
2
3 import (
4 "context"
5
6 "github.com/go-logr/logr"
7 v1dnsmasq "github.com/kvaps/dnsmasq-controller/api/v1beta1"
8 appsv1 "k8s.io/api/apps/v1"
9 corev1 "k8s.io/api/core/v1"
10 "k8s.io/apimachinery/pkg/fields"
11 "k8s.io/apimachinery/pkg/runtime"
12 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
13 clientgoscheme "k8s.io/client-go/kubernetes/scheme"
14 "k8s.io/client-go/rest"
15 ctrl "sigs.k8s.io/controller-runtime"
16 "sigs.k8s.io/controller-runtime/pkg/cache"
17 "sigs.k8s.io/controller-runtime/pkg/client"
18 "sigs.k8s.io/controller-runtime/pkg/manager"
19
20 "edge-infra.dev/pkg/k8s/runtime/controller"
21 edgereconcile "edge-infra.dev/pkg/k8s/runtime/controller/reconcile"
22 "edge-infra.dev/pkg/k8s/runtime/patch"
23 "edge-infra.dev/pkg/k8s/runtime/sap"
24 v1ienode "edge-infra.dev/pkg/sds/ien/k8s/apis/v1"
25 v1pxe "edge-infra.dev/pkg/sds/ien/k8s/controllers/pxe/apis/v1"
26 "edge-infra.dev/pkg/sds/ien/k8s/controllers/pxe/common"
27 )
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 var (
57 metricsBindAddress = ":9000"
58 healthBindAddress = ":9001"
59 )
60
61 type Reconciler struct {
62 name string
63 client client.Client
64 manager *sap.ResourceManager
65 }
66
67
68 func Run(log logr.Logger, opts ...controller.Option) error {
69 ctrl.SetLogger(log)
70 opts = append(opts, controller.WithMetricsAddress(metricsBindAddress))
71 mgr, err := createManager(opts...)
72 if err != nil {
73 return err
74 }
75
76 if err := registerControllers(mgr); err != nil {
77 return err
78 }
79
80
81 ctx := ctrl.LoggerInto(context.Background(), log)
82
83 key := client.ObjectKey{
84 Namespace: common.PXENamespace,
85 Name: "static-file-server-deployment",
86 }
87
88 deploy := &appsv1.Deployment{}
89 err = mgr.GetAPIReader().Get(ctx, key, deploy)
90 if client.IgnoreNotFound(err) != nil {
91 return err
92 }
93 if err == nil {
94 if err := mgr.GetClient().Delete(ctx, deploy); err != nil {
95 return err
96 }
97 }
98
99 key = client.ObjectKey{
100 Namespace: common.PXENamespace,
101 Name: "static-file-server-configmap",
102 }
103
104 cm := &corev1.ConfigMap{}
105 err = mgr.GetAPIReader().Get(ctx, key, cm)
106 if client.IgnoreNotFound(err) != nil {
107 return err
108 }
109 if err == nil {
110 if err := mgr.GetClient().Delete(ctx, cm); err != nil {
111 return err
112 }
113 }
114
115
116 return mgr.Start(ctrl.SetupSignalHandler())
117 }
118
119
120 func createManager(ctrlOpts ...controller.Option) (ctrl.Manager, error) {
121 cfg, opts := managerOptions(ctrlOpts...)
122
123 return ctrl.NewManager(cfg, opts)
124 }
125
126
127
128 func managerOptions(ctrlOpts ...controller.Option) (*rest.Config, manager.Options) {
129 cfg, opts := controller.ProcessOptions(ctrlOpts...)
130 opts.Scheme = scheme()
131 opts.HealthProbeBindAddress = healthBindAddress
132 opts.Cache = cacheOptions()
133
134 return cfg, opts
135 }
136
137
138
139 func cacheOptions() cache.Options {
140 return cache.Options{
141 ByObject: map[client.Object]cache.ByObject{
142 &v1pxe.PXE{}: {
143 Field: fields.Everything(),
144 },
145 &v1ienode.IENode{}: {
146 Field: fields.Everything(),
147 },
148 &corev1.Node{}: {
149 Field: fields.Everything(),
150 },
151 &corev1.ConfigMap{}: {
152 Field: fields.SelectorFromSet(fields.Set{
153 "metadata.namespace": common.PXENamespace,
154 }),
155 },
156 &corev1.Secret{}: {
157 Field: fields.SelectorFromSet(fields.Set{
158 "metadata.namespace": common.PXENamespace,
159 }),
160 },
161 &appsv1.Deployment{}: {
162 Field: fields.SelectorFromSet(fields.Set{
163 "metadata.namespace": common.PXENamespace,
164 }),
165 },
166 &v1dnsmasq.DnsmasqOptions{}: {
167 Field: fields.SelectorFromSet(fields.Set{
168 "metadata.namespace": common.PXENamespace,
169 }),
170 },
171 &v1dnsmasq.DhcpHosts{}: {
172 Field: fields.SelectorFromSet(fields.Set{
173 "metadata.namespace": common.PXENamespace,
174 }),
175 },
176 &v1dnsmasq.DhcpOptions{}: {
177 Field: fields.SelectorFromSet(fields.Set{
178 "metadata.namespace": common.PXENamespace,
179 }),
180 },
181 },
182 }
183 }
184
185
186 func registerControllers(mgr ctrl.Manager) error {
187 client := mgr.GetClient()
188
189 scaler, err := NewScaler(mgr, client)
190 if err != nil {
191 return err
192 }
193 if err := scaler.SetupWithManager(mgr); err != nil {
194 return err
195 }
196
197 provisioner, err := NewProvisioner(mgr, client)
198 if err != nil {
199 return err
200 }
201 return provisioner.SetupWithManager(mgr)
202 }
203
204
205
206 func scheme() *runtime.Scheme {
207 scheme := runtime.NewScheme()
208 utilruntime.Must(clientgoscheme.AddToScheme(scheme))
209 utilruntime.Must(v1ienode.AddToScheme(scheme))
210 utilruntime.Must(v1pxe.AddToScheme(scheme))
211 utilruntime.Must(v1dnsmasq.AddToScheme(scheme))
212
213 return scheme
214 }
215
216
217 func (r *Reconciler) summarize(ctx context.Context, patcher *patch.SerialPatcher, pxe *v1pxe.PXE, recErr error) (ctrl.Result, error) {
218 s := edgereconcile.NewSummarizer(patcher)
219 return s.SummarizeAndPatch(ctx, pxe,
220 edgereconcile.WithResult(edgereconcile.ResultEmpty),
221 edgereconcile.WithError(recErr),
222 edgereconcile.WithProcessors(
223 edgereconcile.RecordReconcileReq,
224 edgereconcile.RecordResult,
225 ),
226 edgereconcile.WithFieldOwner(r.name),
227 )
228 }
229
View as plain text