github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/pv/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 pv
    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  	corev1 "k8s.io/api/core/v1"
    29  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    30  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	"k8s.io/apimachinery/pkg/runtime"
    32  	"k8s.io/apimachinery/pkg/types"
    33  	"sigs.k8s.io/controller-runtime/pkg/client"
    34  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    35  )
    36  
    37  var log = logf.Log.WithName("pv_manager")
    38  
    39  type Manager struct {
    40  	Client k8sclient.Client
    41  	Scheme *runtime.Scheme
    42  	Name   string
    43  
    44  	LabelsFunc   func(v1.Object) map[string]string
    45  	OverrideFunc func(v1.Object, *corev1.PersistentVolume, resources.Action) error
    46  }
    47  
    48  func (m *Manager) GetName(instance v1.Object) string {
    49  	return fmt.Sprintf("%s-%s", instance.GetNamespace(), instance.GetName())
    50  }
    51  
    52  func (m *Manager) Reconcile(instance v1.Object, update bool) error {
    53  	name := m.GetName(instance)
    54  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, &corev1.PersistentVolume{})
    55  	if err != nil {
    56  		if k8serrors.IsNotFound(err) {
    57  			log.Info(fmt.Sprintf("Creating pv '%s'", name))
    58  			pv, err := m.GetPVFromTemplate(instance)
    59  			if err != nil {
    60  				return err
    61  			}
    62  
    63  			err = m.Client.Create(context.TODO(), pv, k8sclient.CreateOption{Owner: instance, Scheme: m.Scheme})
    64  			if err != nil {
    65  				return err
    66  			}
    67  			return nil
    68  		}
    69  		return err
    70  	}
    71  
    72  	// TODO: If needed, update logic for servie goes here
    73  
    74  	return nil
    75  }
    76  
    77  func (m *Manager) GetPVFromTemplate(instance v1.Object) (*corev1.PersistentVolume, error) {
    78  	pvc := &corev1.PersistentVolume{
    79  		ObjectMeta: v1.ObjectMeta{
    80  			Name:      m.GetName(instance),
    81  			Namespace: instance.GetNamespace(),
    82  			Labels:    m.LabelsFunc(instance),
    83  		},
    84  	}
    85  
    86  	return m.BasedOnCR(instance, pvc)
    87  }
    88  
    89  func (m *Manager) BasedOnCR(instance v1.Object, pvc *corev1.PersistentVolume) (*corev1.PersistentVolume, error) {
    90  	if m.OverrideFunc != nil {
    91  		err := m.OverrideFunc(instance, pvc, resources.Create)
    92  		if err != nil {
    93  			return nil, operatorerrors.New(operatorerrors.InvalidPVCCreateRequest, err.Error())
    94  		}
    95  	}
    96  
    97  	return pvc, nil
    98  }
    99  
   100  func (m *Manager) Get(instance v1.Object) (client.Object, error) {
   101  	if instance == nil {
   102  		return nil, nil // Instance has not been reconciled yet
   103  	}
   104  
   105  	name := m.GetName(instance)
   106  	pvc := &corev1.PersistentVolume{}
   107  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, pvc)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	return pvc, nil
   113  }
   114  
   115  func (m *Manager) Exists(instance v1.Object) bool {
   116  	_, err := m.Get(instance)
   117  	if err != nil {
   118  		return false
   119  	}
   120  
   121  	return true
   122  }
   123  
   124  func (m *Manager) Delete(instance v1.Object) error {
   125  	pvc, err := m.Get(instance)
   126  	if err != nil {
   127  		if !k8serrors.IsNotFound(err) {
   128  			return err
   129  		}
   130  	}
   131  
   132  	if pvc == nil {
   133  		return nil
   134  	}
   135  
   136  	err = m.Client.Delete(context.TODO(), pvc)
   137  	if err != nil {
   138  		if !k8serrors.IsNotFound(err) {
   139  			return err
   140  		}
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  func (m *Manager) CheckState(instance v1.Object) error {
   147  	// NO-OP
   148  	return nil
   149  }
   150  
   151  func (m *Manager) RestoreState(instance v1.Object) error {
   152  	// NO-OP
   153  	return nil
   154  }
   155  
   156  func (m *Manager) SetCustomName(name string) {
   157  	// NO-OP
   158  }