github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/configmap/manager.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package configmap
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  
    25  	k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient"
    26  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    28  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    29  	corev1 "k8s.io/api/core/v1"
    30  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    31  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    32  	"k8s.io/apimachinery/pkg/runtime"
    33  	"k8s.io/apimachinery/pkg/types"
    34  	"sigs.k8s.io/controller-runtime/pkg/client"
    35  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    36  )
    37  
    38  var log = logf.Log.WithName("configmap_manager")
    39  
    40  type Manager struct {
    41  	Client        k8sclient.Client
    42  	Scheme        *runtime.Scheme
    43  	ConfigMapFile string
    44  	Name          string
    45  	Options       map[string]interface{}
    46  
    47  	LabelsFunc   func(v1.Object) map[string]string
    48  	OverrideFunc func(v1.Object, *corev1.ConfigMap, resources.Action, map[string]interface{}) error
    49  }
    50  
    51  func (m *Manager) GetName(instance v1.Object) string {
    52  	if m.Name != "" {
    53  		return fmt.Sprintf("%s-%s", instance.GetName(), m.Name)
    54  	}
    55  	return fmt.Sprintf("%s", instance.GetName())
    56  }
    57  
    58  func (m *Manager) Reconcile(instance v1.Object, update bool) error {
    59  	name := m.GetName(instance)
    60  	configMap := &corev1.ConfigMap{}
    61  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, configMap)
    62  	if err != nil {
    63  		if k8serrors.IsNotFound(err) {
    64  			log.Info(fmt.Sprintf("Creating configmap '%s'", name))
    65  			configMap, err := m.GetConfigMapBasedOnCRFromFile(instance)
    66  			if err != nil {
    67  				return err
    68  			}
    69  
    70  			err = m.Client.Create(context.TODO(), configMap, k8sclient.CreateOption{
    71  				Owner:  instance,
    72  				Scheme: m.Scheme,
    73  			})
    74  			if err != nil {
    75  				return err
    76  			}
    77  			return nil
    78  		}
    79  		return err
    80  	}
    81  
    82  	if update {
    83  		if m.OverrideFunc != nil {
    84  			log.Info(fmt.Sprintf("Updating configmap '%s'", name))
    85  			err := m.OverrideFunc(instance, configMap, resources.Update, m.Options)
    86  			if err != nil {
    87  				return err
    88  			}
    89  
    90  			err = m.Client.Update(context.TODO(), configMap, k8sclient.UpdateOption{
    91  				Owner:  instance,
    92  				Scheme: m.Scheme,
    93  			})
    94  			if err != nil {
    95  				return err
    96  			}
    97  			return nil
    98  		}
    99  	}
   100  
   101  	// TODO: If needed, update logic for servie goes here
   102  
   103  	return nil
   104  }
   105  
   106  func (m *Manager) GetConfigMapBasedOnCRFromFile(instance v1.Object) (*corev1.ConfigMap, error) {
   107  	configMap, err := util.GetConfigMapFromFile(m.ConfigMapFile)
   108  	if err != nil {
   109  		log.Error(err, fmt.Sprintf("Error reading configmap configuration file: %s", m.ConfigMapFile))
   110  		return nil, err
   111  	}
   112  
   113  	configMap.Name = m.GetName(instance)
   114  	configMap.Namespace = instance.GetNamespace()
   115  	configMap.Labels = m.LabelsFunc(instance)
   116  
   117  	return m.BasedOnCR(instance, configMap)
   118  }
   119  
   120  func (m *Manager) BasedOnCR(instance v1.Object, configMap *corev1.ConfigMap) (*corev1.ConfigMap, error) {
   121  	if m.OverrideFunc != nil {
   122  		err := m.OverrideFunc(instance, configMap, resources.Create, m.Options)
   123  		if err != nil {
   124  			return nil, operatorerrors.New(operatorerrors.InvalidConfigMapCreateRequest, err.Error())
   125  		}
   126  	}
   127  
   128  	return configMap, nil
   129  }
   130  
   131  func (m *Manager) Get(instance v1.Object) (client.Object, error) {
   132  	if instance == nil {
   133  		return nil, nil // Instance has not been reconciled yet
   134  	}
   135  
   136  	name := m.GetName(instance)
   137  	cm := &corev1.ConfigMap{}
   138  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, cm)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	return cm, nil
   144  }
   145  
   146  func (m *Manager) Exists(instance v1.Object) bool {
   147  	_, err := m.Get(instance)
   148  	if err != nil {
   149  		return false
   150  	}
   151  
   152  	return true
   153  }
   154  
   155  func (m *Manager) Delete(instance v1.Object) error {
   156  	cm, err := m.Get(instance)
   157  	if err != nil {
   158  		if !k8serrors.IsNotFound(err) {
   159  			return err
   160  		}
   161  	}
   162  
   163  	if cm == nil {
   164  		return nil
   165  	}
   166  
   167  	err = m.Client.Delete(context.TODO(), cm)
   168  	if err != nil {
   169  		if !k8serrors.IsNotFound(err) {
   170  			return err
   171  		}
   172  	}
   173  
   174  	return nil
   175  }
   176  
   177  func (m *Manager) CheckState(instance v1.Object) error {
   178  	// NO-OP
   179  	return nil
   180  }
   181  
   182  func (m *Manager) RestoreState(instance v1.Object) error {
   183  	// NO-OP
   184  	return nil
   185  }
   186  
   187  func (m *Manager) SetCustomName(name string) {
   188  	// NO-OP
   189  }