| // Licensed to Apache Software Foundation (ASF) under one or more contributor |
| // license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright |
| // ownership. Apache Software Foundation (ASF) licenses this file to you under |
| // the Apache License, Version 2.0 (the "License"); you may |
| // not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package controllers |
| |
| import ( |
| "context" |
| "fmt" |
| |
| "github.com/go-logr/logr" |
| core "k8s.io/api/core/v1" |
| apierrors "k8s.io/apimachinery/pkg/api/errors" |
| "k8s.io/apimachinery/pkg/runtime" |
| ctrl "sigs.k8s.io/controller-runtime" |
| "sigs.k8s.io/controller-runtime/pkg/client" |
| "sigs.k8s.io/controller-runtime/pkg/event" |
| "sigs.k8s.io/controller-runtime/pkg/predicate" |
| |
| "github.com/apache/skywalking-swck/pkg/kubernetes" |
| "github.com/apache/skywalking-swck/pkg/operator/injector" |
| ) |
| |
| // ConfigMapReconciler reconciles a ConfigMap object |
| type ConfigMapReconciler struct { |
| client.Client |
| Log logr.Logger |
| Scheme *runtime.Scheme |
| FileRepo kubernetes.Repo |
| } |
| |
| // +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete |
| // +kubebuilder:rbac:groups="",resources=configmaps/status,verbs=get;update;patch |
| |
| func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { |
| log := r.Log.WithValues("configmap", req.NamespacedName) |
| log.Info("=====================reconcile started================================") |
| errCol := new(kubernetes.ErrorCollector) |
| |
| configmap := &core.ConfigMap{} |
| err := r.Client.Get(ctx, client.ObjectKey{Namespace: injector.DefaultConfigmapNamespace, Name: injector.DefaultConfigmapName}, configmap) |
| if err != nil && !apierrors.IsNotFound(err) { |
| errCol.Collect(fmt.Errorf("failed to get configmap: %w", err)) |
| } |
| // if change the default configmap, we need to validate the value |
| // if validate false , we will delete the configmap and recreate a default configmap |
| if !apierrors.IsNotFound(err) { |
| ok, errinfo := injector.ValidateConfigmap(configmap) |
| if !ok { |
| log.Error(errinfo, "the default configmap validate false") |
| if deleteErr := r.Client.Delete(ctx, configmap); deleteErr != nil { |
| log.Error(deleteErr, "failed to delete the configmap that validate false") |
| } |
| } |
| log.Info("delete the configmap that validate false") |
| } |
| app := kubernetes.Application{ |
| Client: r.Client, |
| FileRepo: r.FileRepo, |
| CR: configmap, |
| GVK: core.SchemeGroupVersion.WithKind("ConfigMap"), |
| TmplFunc: injector.GetTmplFunc(), |
| } |
| |
| // adding false means the configmap don't need to compose , such as ownerReferences |
| ap, err := app.Apply(ctx, "injector/templates/configmap.yaml", log, false) |
| if err != nil { |
| log.Error(err, "failed to apply default configmap") |
| return ctrl.Result{}, err |
| } |
| if ap { |
| log.Info("create default configmap") |
| } |
| |
| return ctrl.Result{}, nil |
| } |
| |
| func (r *ConfigMapReconciler) SetupWithManager(mgr ctrl.Manager) error { |
| // Only monitor the default configmap template |
| return ctrl.NewControllerManagedBy(mgr). |
| For(&core.ConfigMap{}). |
| WithEventFilter( |
| predicate.Funcs{ |
| CreateFunc: func(e event.CreateEvent) bool { |
| if e.Object.GetNamespace() == injector.DefaultConfigmapNamespace && |
| e.Object.GetName() == injector.DefaultConfigmapName { |
| return true |
| } |
| return false |
| }, |
| UpdateFunc: func(e event.UpdateEvent) bool { |
| if (e.ObjectNew.GetName() == injector.DefaultConfigmapName && |
| e.ObjectNew.GetNamespace() == injector.DefaultConfigmapNamespace) || |
| (e.ObjectOld.GetName() == injector.DefaultConfigmapName && |
| e.ObjectOld.GetNamespace() == injector.DefaultConfigmapNamespace) { |
| return true |
| } |
| return false |
| }, |
| DeleteFunc: func(e event.DeleteEvent) bool { |
| if e.Object.GetNamespace() == injector.DefaultConfigmapNamespace && |
| e.Object.GetName() == injector.DefaultConfigmapName { |
| return true |
| } |
| return false |
| }, |
| }). |
| Complete(r) |
| } |