github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controllerutil/resource_wrapper.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package controllerutil
    21  
    22  import (
    23  	"context"
    24  
    25  	corev1 "k8s.io/api/core/v1"
    26  	"sigs.k8s.io/controller-runtime/pkg/client"
    27  
    28  	appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1"
    29  	cfgcore "github.com/1aal/kubeblocks/pkg/configuration/core"
    30  )
    31  
    32  type ResourceCtx struct {
    33  	context.Context
    34  
    35  	Err    error
    36  	Client client.Client
    37  
    38  	Namespace     string
    39  	ClusterName   string
    40  	ComponentName string
    41  }
    42  
    43  type ResourceFetcher[T any] struct {
    44  	obj *T
    45  	*ResourceCtx
    46  
    47  	ClusterObj    *appsv1alpha1.Cluster
    48  	ClusterDefObj *appsv1alpha1.ClusterDefinition
    49  	ClusterVerObj *appsv1alpha1.ClusterVersion
    50  
    51  	ConfigMapObj        *corev1.ConfigMap
    52  	ConfigurationObj    *appsv1alpha1.Configuration
    53  	ConfigConstraintObj *appsv1alpha1.ConfigConstraint
    54  
    55  	ClusterComObj    *appsv1alpha1.ClusterComponentSpec
    56  	ClusterDefComObj *appsv1alpha1.ClusterComponentDefinition
    57  	ClusterVerComObj *appsv1alpha1.ClusterComponentVersion
    58  }
    59  
    60  func (r *ResourceFetcher[T]) Init(ctx *ResourceCtx, object *T) *T {
    61  	r.obj = object
    62  	r.ResourceCtx = ctx
    63  	return r.obj
    64  }
    65  
    66  func (r *ResourceFetcher[T]) Wrap(fn func() error) (ret *T) {
    67  	ret = r.obj
    68  	if r.Err != nil {
    69  		return
    70  	}
    71  	r.Err = fn()
    72  	return
    73  }
    74  
    75  func (r *ResourceFetcher[T]) Cluster() *T {
    76  	clusterKey := client.ObjectKey{
    77  		Namespace: r.Namespace,
    78  		Name:      r.ClusterName,
    79  	}
    80  	return r.Wrap(func() error {
    81  		r.ClusterObj = &appsv1alpha1.Cluster{}
    82  		return r.Client.Get(r.Context, clusterKey, r.ClusterObj)
    83  	})
    84  }
    85  
    86  func (r *ResourceFetcher[T]) ClusterDef() *T {
    87  	clusterDefKey := client.ObjectKey{
    88  		Namespace: "",
    89  		Name:      r.ClusterObj.Spec.ClusterDefRef,
    90  	}
    91  	return r.Wrap(func() error {
    92  		r.ClusterDefObj = &appsv1alpha1.ClusterDefinition{}
    93  		return r.Client.Get(r.Context, clusterDefKey, r.ClusterDefObj)
    94  	})
    95  }
    96  
    97  func (r *ResourceFetcher[T]) ClusterVer() *T {
    98  	clusterVerKey := client.ObjectKey{
    99  		Namespace: "",
   100  		Name:      r.ClusterObj.Spec.ClusterVersionRef,
   101  	}
   102  	return r.Wrap(func() error {
   103  		if clusterVerKey.Name == "" {
   104  			return nil
   105  		}
   106  		r.ClusterVerObj = &appsv1alpha1.ClusterVersion{}
   107  		return r.Client.Get(r.Context, clusterVerKey, r.ClusterVerObj)
   108  	})
   109  }
   110  func (r *ResourceFetcher[T]) ClusterDefComponent() *T {
   111  	foundFn := func() (err error) {
   112  		if r.ClusterComObj == nil {
   113  			return
   114  		}
   115  		r.ClusterDefComObj = r.ClusterDefObj.GetComponentDefByName(r.ClusterComObj.ComponentDefRef)
   116  		return
   117  	}
   118  	return r.Wrap(foundFn)
   119  }
   120  
   121  func (r *ResourceFetcher[T]) ClusterVerComponent() *T {
   122  	foundFn := func() (err error) {
   123  		if r.ClusterComObj == nil || r.ClusterVerObj == nil {
   124  			return
   125  		}
   126  		components := r.ClusterVerObj.Spec.GetDefNameMappingComponents()
   127  		r.ClusterVerComObj = components[r.ClusterComObj.ComponentDefRef]
   128  		return
   129  	}
   130  	return r.Wrap(foundFn)
   131  }
   132  
   133  func (r *ResourceFetcher[T]) ClusterComponent() *T {
   134  	return r.Wrap(func() (err error) {
   135  		r.ClusterComObj = r.ClusterObj.Spec.GetComponentByName(r.ComponentName)
   136  		return
   137  	})
   138  }
   139  
   140  func (r *ResourceFetcher[T]) Configuration() *T {
   141  	configKey := client.ObjectKey{
   142  		Name:      cfgcore.GenerateComponentConfigurationName(r.ClusterName, r.ComponentName),
   143  		Namespace: r.Namespace,
   144  	}
   145  	return r.Wrap(func() (err error) {
   146  		configuration := appsv1alpha1.Configuration{}
   147  		err = r.Client.Get(r.Context, configKey, &configuration)
   148  		if err != nil {
   149  			return client.IgnoreNotFound(err)
   150  		}
   151  		r.ConfigurationObj = &configuration
   152  		return
   153  	})
   154  }
   155  
   156  func (r *ResourceFetcher[T]) ConfigMap(configSpec string) *T {
   157  	cmKey := client.ObjectKey{
   158  		Name:      cfgcore.GetComponentCfgName(r.ClusterName, r.ComponentName, configSpec),
   159  		Namespace: r.Namespace,
   160  	}
   161  
   162  	return r.Wrap(func() error {
   163  		r.ConfigMapObj = &corev1.ConfigMap{}
   164  		return r.Client.Get(r.Context, cmKey, r.ConfigMapObj)
   165  	})
   166  }
   167  
   168  func (r *ResourceFetcher[T]) ConfigConstraints(ccName string) *T {
   169  	return r.Wrap(func() error {
   170  		if ccName != "" {
   171  			r.ConfigConstraintObj = &appsv1alpha1.ConfigConstraint{}
   172  			return r.Client.Get(r.Context, client.ObjectKey{Name: ccName}, r.ConfigConstraintObj)
   173  		}
   174  		return nil
   175  	})
   176  }
   177  
   178  func (r *ResourceFetcher[T]) Complete() error {
   179  	return r.Err
   180  }
   181  
   182  type Fetcher struct {
   183  	ResourceFetcher[Fetcher]
   184  }
   185  
   186  func NewResourceFetcher(resourceCtx *ResourceCtx) *Fetcher {
   187  	f := &Fetcher{}
   188  	return f.Init(resourceCtx, f)
   189  }