@@ -9,34 +9,36 @@ import (
9
9
"flag"
10
10
"fmt"
11
11
"os"
12
+ "path/filepath"
13
+ "strconv"
14
+ "net/http"
12
15
13
16
"github.com/pkg/errors"
14
17
"github.com/spf13/pflag"
15
18
admissionv1 "k8s.io/api/admissionregistration/v1"
16
19
corev1 "k8s.io/api/core/v1"
20
+ apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
17
21
clientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
18
22
apiclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
19
23
apierrors "k8s.io/apimachinery/pkg/api/errors"
20
24
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21
25
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22
26
"k8s.io/apimachinery/pkg/runtime"
27
+ "k8s.io/apimachinery/pkg/runtime/serializer"
23
28
"k8s.io/client-go/kubernetes"
24
29
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
25
30
"k8s.io/client-go/tools/clientcmd"
26
31
"k8s.io/kubectl/pkg/util"
27
32
28
33
configv1alpha2 "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2"
34
+ configClientset "github.com/openservicemesh/osm/pkg/gen/client/config/clientset/versioned"
29
35
30
36
"github.com/openservicemesh/osm/pkg/certificate/providers"
31
- "github.com/openservicemesh/osm/pkg/configurator"
32
37
"github.com/openservicemesh/osm/pkg/constants"
33
- "github.com/openservicemesh/osm/pkg/crdconversion"
34
- configClientset "github.com/openservicemesh/osm/pkg/gen/client/config/clientset/versioned"
35
38
"github.com/openservicemesh/osm/pkg/httpserver"
36
39
httpserverconstants "github.com/openservicemesh/osm/pkg/httpserver/constants"
37
40
"github.com/openservicemesh/osm/pkg/k8s/events"
38
41
"github.com/openservicemesh/osm/pkg/logger"
39
- "github.com/openservicemesh/osm/pkg/messaging"
40
42
"github.com/openservicemesh/osm/pkg/metricsstore"
41
43
"github.com/openservicemesh/osm/pkg/reconciler"
42
44
"github.com/openservicemesh/osm/pkg/signals"
@@ -47,6 +49,8 @@ const (
47
49
meshConfigName = "osm-mesh-config"
48
50
presetMeshConfigName = "preset-mesh-config"
49
51
presetMeshConfigJSONKey = "preset-mesh-config.json"
52
+ webhookHealthPath = "/healthz"
53
+ healthPort = 9095
50
54
)
51
55
52
56
var (
57
61
meshName string
58
62
osmVersion string
59
63
60
- crdConverterConfig crdconversion.Config
61
-
62
64
certProviderKind string
63
65
64
- tresorOptions providers.TresorOptions
65
66
vaultOptions providers.VaultOptions
66
67
certManagerOptions providers.CertManagerOptions
67
68
@@ -147,6 +148,8 @@ func main() {
147
148
namespace : osmNamespace ,
148
149
}
149
150
151
+ applyOrUpdateCRDs (crdClient )
152
+
150
153
err = bootstrap .ensureMeshConfig ()
151
154
if err != nil {
152
155
log .Fatal ().Err (err ).Msgf ("Error setting up default MeshConfig %s from ConfigMap %s" , meshConfigName , presetMeshConfigName )
@@ -158,37 +161,27 @@ func main() {
158
161
log .Fatal ().Err (err ).Msg ("Error initializing Kubernetes events recorder" )
159
162
}
160
163
161
- stop := signals .RegisterExitHandlers ()
162
164
_ , cancel := context .WithCancel (context .Background ())
163
165
defer cancel ()
166
+ stop := signals .RegisterExitHandlers ()
164
167
165
168
// Start the default metrics store
166
169
metricsstore .DefaultMetricsStore .Start (
167
170
metricsstore .DefaultMetricsStore .ErrCodeCounter ,
168
171
metricsstore .DefaultMetricsStore .HTTPResponseTotal ,
169
172
metricsstore .DefaultMetricsStore .HTTPResponseDuration ,
170
- metricsstore .DefaultMetricsStore .ConversionWebhookResourceTotal ,
171
173
)
172
174
173
- msgBroker := messaging .NewBroker (stop )
174
-
175
- // Initialize Configurator to retrieve mesh specific config
176
- cfg := configurator .NewConfigurator (configClient , stop , osmNamespace , osmMeshConfigName , msgBroker )
177
-
178
- // Intitialize certificate manager/provider
179
- certProviderConfig := providers .NewCertificateProviderConfig (kubeClient , kubeConfig , cfg , providers .Kind (certProviderKind ), osmNamespace ,
180
- caBundleSecretName , tresorOptions , vaultOptions , certManagerOptions , msgBroker )
181
-
182
- certManager , _ , err := certProviderConfig .GetCertificateManager ()
183
- if err != nil {
184
- events .GenericEventRecorder ().FatalEvent (err , events .InvalidCertificateManager ,
185
- "Error initializing certificate manager of kind %s" , certProviderKind )
186
- }
187
-
188
- // Initialize the crd conversion webhook server to support the conversion of OSM's CRDs
189
- crdConverterConfig .ListenPort = constants .CRDConversionWebhookPort
190
- if err := crdconversion .NewConversionWebhook (crdConverterConfig , kubeClient , crdClient , certManager , osmNamespace , enableReconciler , stop ); err != nil {
191
- events .GenericEventRecorder ().FatalEvent (err , events .InitializationError , "Error creating crd conversion webhook" )
175
+ /*
176
+ * Initialize osm-bootstrap's HTTP server
177
+ */
178
+ if enableReconciler {
179
+ log .Info ().Msgf ("OSM reconciler enabled for custom resource definitions" )
180
+ err = reconciler .NewReconcilerClient (kubeClient , apiServerClient , meshName , osmVersion , stop , reconciler .CrdInformerKey )
181
+ if err != nil {
182
+ events .GenericEventRecorder ().FatalEvent (err , events .InitializationError , "Error creating reconciler client for custom resource definitions" )
183
+ log .Fatal ().Err (err ).Msgf ("Failed to create reconcile client for custom resource definitions" )
184
+ }
192
185
}
193
186
194
187
/*
@@ -199,22 +192,79 @@ func main() {
199
192
httpServer .AddHandler (httpserverconstants .MetricsPath , metricsstore .DefaultMetricsStore .Handler ())
200
193
// Version
201
194
httpServer .AddHandler (httpserverconstants .VersionPath , version .GetVersionHandler ())
202
- // Start HTTP server
195
+ // Webhook
196
+ httpServer .AddHandler (webhookHealthPath , metricsstore .AddHTTPMetrics (http .HandlerFunc (healthHandler )))
197
+
203
198
err = httpServer .Start ()
204
199
if err != nil {
205
200
log .Fatal ().Err (err ).Msgf ("Failed to start OSM metrics/probes HTTP server" )
206
201
}
207
202
208
- if enableReconciler {
209
- log .Info ().Msgf ("OSM reconciler enabled for custom resource definitions" )
210
- err = reconciler .NewReconcilerClient (kubeClient , apiServerClient , meshName , osmVersion , stop , reconciler .CrdInformerKey )
203
+ <- stop
204
+ cancel ()
205
+ log .Info ().Msgf ("Stopping osm-bootstrap %s; %s; %s" , version .Version , version .GitCommit , version .BuildDate )
206
+ }
207
+
208
+ func healthHandler (w http.ResponseWriter , _ * http.Request ) {
209
+ w .WriteHeader (http .StatusOK )
210
+ if _ , err := w .Write ([]byte ("Health OK" )); err != nil {
211
+ log .Error ().Err (err ).Msg ("Error writing bytes for webhook health check handler" )
212
+ }
213
+ }
214
+
215
+ func applyOrUpdateCRDs (crdClient * apiclient.ApiextensionsV1Client ) {
216
+ crdFiles , err := filepath .Glob ("/osm-crds/*.yaml" )
217
+
218
+ if err != nil {
219
+ log .Fatal ().Err (err ).Msgf ("error reading files from /osm-crds" )
220
+ }
221
+
222
+ scheme = runtime .NewScheme ()
223
+ codecs := serializer .NewCodecFactory (scheme )
224
+ decode := codecs .UniversalDeserializer ().Decode
225
+
226
+ for _ , file := range crdFiles {
227
+ yaml , err := os .ReadFile (filepath .Clean (file ))
211
228
if err != nil {
212
- events . GenericEventRecorder ().FatalEvent (err , events . InitializationError , "Error creating reconciler client for custom resource definitions" )
229
+ log . Fatal ().Err (err ). Msgf ( "Error reading CRD file %s" , file )
213
230
}
214
- }
215
231
216
- <- stop
217
- log .Info ().Msgf ("Stopping osm-bootstrap %s; %s; %s" , version .Version , version .GitCommit , version .BuildDate )
232
+ crd := & apiv1.CustomResourceDefinition {}
233
+ _ , _ , err = decode (yaml , nil , crd )
234
+ if err != nil {
235
+ log .Fatal ().Err (err ).Msgf ("Error decoding CRD file %s" , file )
236
+ }
237
+
238
+ crd .Labels [constants .ReconcileLabel ] = strconv .FormatBool (enableReconciler )
239
+
240
+ crdExisting , err := crdClient .CustomResourceDefinitions ().Get (context .Background (), crd .Name , metav1.GetOptions {})
241
+ if err != nil && ! apierrors .IsNotFound (err ) {
242
+ log .Fatal ().Err (err ).Msgf ("error getting CRD %s" , crd .Name )
243
+ }
244
+
245
+ if apierrors .IsNotFound (err ) {
246
+ log .Info ().Msgf ("crds %s not found, creating CRD" , crd .Name )
247
+ if err := util .CreateApplyAnnotation (crd , unstructured .UnstructuredJSONScheme ); err != nil {
248
+ log .Fatal ().Err (err ).Msgf ("Error applying annotation to CRD %s" , crd .Name )
249
+ }
250
+ if _ , err = crdClient .CustomResourceDefinitions ().Create (context .Background (), crd , metav1.CreateOptions {}); err != nil {
251
+ log .Fatal ().Err (err ).Msgf ("Error creating crd : %s" , crd .Name )
252
+ }
253
+ log .Info ().Msgf ("Successfully created crd: %s" , crd .Name )
254
+ } else {
255
+ log .Info ().Msgf ("Patching conversion webhook configuration for crd: %s, setting to \" None\" " , crd .Name )
256
+
257
+ crdExisting .Labels [constants .ReconcileLabel ] = strconv .FormatBool (enableReconciler )
258
+ crdExisting .Spec = crd .Spec
259
+ crdExisting .Spec .Conversion = & apiv1.CustomResourceConversion {
260
+ Strategy : apiv1 .NoneConverter ,
261
+ }
262
+ if _ , err = crdClient .CustomResourceDefinitions ().Update (context .Background (), crdExisting , metav1.UpdateOptions {}); err != nil {
263
+ log .Fatal ().Err (err ).Msgf ("Error updating conversion webhook configuration for crd : %s" , crd .Name )
264
+ }
265
+ log .Info ().Msgf ("successfully set conversion webhook configuration for crd : %s to \" None\" " , crd .Name )
266
+ }
267
+ }
218
268
}
219
269
220
270
func (b * bootstrap ) createDefaultMeshConfig () error {
0 commit comments