github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/base/orderer/node.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 baseorderer
    20  
    21  import (
    22  	"context"
    23  	"encoding/json"
    24  	"fmt"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  	"time"
    29  
    30  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    31  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    32  	"github.com/IBM-Blockchain/fabric-operator/pkg/action"
    33  	commonapi "github.com/IBM-Blockchain/fabric-operator/pkg/apis/common"
    34  	"github.com/IBM-Blockchain/fabric-operator/pkg/certificate"
    35  	commoninit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common"
    36  	commonconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/config"
    37  	initializer "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer"
    38  	ordererconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer/config/v1"
    39  	v2ordererconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer/config/v2"
    40  	v24ordererconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer/config/v24"
    41  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/validator"
    42  	controllerclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient"
    43  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources"
    44  	resourcemanager "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/manager"
    45  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/orderer/override"
    46  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/common"
    47  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/common/reconcilechecks"
    48  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    49  	"github.com/IBM-Blockchain/fabric-operator/pkg/restart"
    50  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    51  	"github.com/IBM-Blockchain/fabric-operator/version"
    52  	"github.com/pkg/errors"
    53  	appsv1 "k8s.io/api/apps/v1"
    54  	corev1 "k8s.io/api/core/v1"
    55  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    56  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    57  	"k8s.io/apimachinery/pkg/labels"
    58  	"k8s.io/apimachinery/pkg/runtime"
    59  	"k8s.io/apimachinery/pkg/types"
    60  	"sigs.k8s.io/controller-runtime/pkg/client"
    61  	k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
    62  	"sigs.k8s.io/controller-runtime/pkg/reconcile"
    63  	"sigs.k8s.io/yaml"
    64  )
    65  
    66  const (
    67  	NODE = "node"
    68  )
    69  
    70  type Override interface {
    71  	Deployment(v1.Object, *appsv1.Deployment, resources.Action) error
    72  	Service(v1.Object, *corev1.Service, resources.Action) error
    73  	PVC(v1.Object, *corev1.PersistentVolumeClaim, resources.Action) error
    74  	EnvCM(v1.Object, *corev1.ConfigMap, resources.Action, map[string]interface{}) error
    75  	OrdererNode(v1.Object, *current.IBPOrderer, resources.Action) error
    76  }
    77  
    78  //go:generate counterfeiter -o mocks/deployment_manager.go -fake-name DeploymentManager . DeploymentManager
    79  
    80  type DeploymentManager interface {
    81  	resources.Manager
    82  	CheckForSecretChange(v1.Object, string, func(string, *appsv1.Deployment) bool) error
    83  }
    84  
    85  //go:generate counterfeiter -o mocks/initializeibporderer.go -fake-name InitializeIBPOrderer . InitializeIBPOrderer
    86  
    87  type InitializeIBPOrderer interface {
    88  	GenerateSecrets(commoninit.SecretType, *current.IBPOrderer, *commonconfig.Response) error
    89  	Create(initializer.OrdererConfig, initializer.IBPOrderer, string) (*initializer.Response, error)
    90  	Update(initializer.OrdererConfig, initializer.IBPOrderer) (*initializer.Response, error)
    91  	CreateOrUpdateConfigMap(*current.IBPOrderer, initializer.OrdererConfig) error
    92  	GetConfigFromConfigMap(instance *current.IBPOrderer) (*corev1.ConfigMap, error)
    93  	MissingCrypto(*current.IBPOrderer) bool
    94  	Delete(*current.IBPOrderer) error
    95  	CheckIfAdminCertsUpdated(*current.IBPOrderer) (bool, error)
    96  	UpdateAdminSecret(*current.IBPOrderer) error
    97  	GetInitOrderer(instance *current.IBPOrderer, storagePath string) (*initializer.Orderer, error)
    98  	GetUpdatedOrderer(instance *current.IBPOrderer) (*initializer.Orderer, error)
    99  	UpdateSecrets(prefix commoninit.SecretType, instance *current.IBPOrderer, crypto *commonconfig.Response) error
   100  	GenerateSecretsFromResponse(instance *current.IBPOrderer, cryptoResponse *commonconfig.CryptoResponse) error
   101  	UpdateSecretsFromResponse(instance *current.IBPOrderer, cryptoResponse *commonconfig.CryptoResponse) error
   102  	GetCrypto(instance *current.IBPOrderer) (*commonconfig.CryptoResponse, error)
   103  	GetCoreConfigFromFile(instance *current.IBPOrderer, file string) (initializer.OrdererConfig, error)
   104  	GetCoreConfigFromBytes(instance *current.IBPOrderer, bytes []byte) (initializer.OrdererConfig, error)
   105  }
   106  
   107  //go:generate counterfeiter -o mocks/update.go -fake-name Update . Update
   108  
   109  type Update interface {
   110  	SpecUpdated() bool
   111  	ConfigOverridesUpdated() bool
   112  	TLSCertUpdated() bool
   113  	EcertUpdated() bool
   114  	OrdererTagUpdated() bool
   115  	CertificateUpdated() bool
   116  	RestartNeeded() bool
   117  	EcertReenrollNeeded() bool
   118  	TLScertReenrollNeeded() bool
   119  	EcertNewKeyReenroll() bool
   120  	TLScertNewKeyReenroll() bool
   121  	DeploymentUpdated() bool
   122  	MSPUpdated() bool
   123  	EcertEnroll() bool
   124  	TLScertEnroll() bool
   125  	CertificateCreated() bool
   126  	GetCreatedCertType() commoninit.SecretType
   127  	CryptoBackupNeeded() bool
   128  	MigrateToV2() bool
   129  	MigrateToV24() bool
   130  	NodeOUUpdated() bool
   131  	ImagesUpdated() bool
   132  	FabricVersionUpdated() bool
   133  }
   134  
   135  type IBPOrderer interface {
   136  	Initialize(instance *current.IBPOrderer, update Update) error
   137  	PreReconcileChecks(instance *current.IBPOrderer, update Update) (bool, error)
   138  	ReconcileManagers(instance *current.IBPOrderer, update Update, genesisBlock []byte) error
   139  	Reconcile(instance *current.IBPOrderer, update Update) (common.Result, error)
   140  }
   141  
   142  //go:generate counterfeiter -o mocks/certificate_manager.go -fake-name CertificateManager . CertificateManager
   143  
   144  type CertificateManager interface {
   145  	CheckCertificatesForExpire(instance v1.Object, numSecondsBeforeExpire int64) (current.IBPCRStatusType, string, error)
   146  	GetSignCert(string, string) ([]byte, error)
   147  	GetDurationToNextRenewal(commoninit.SecretType, v1.Object, int64) (time.Duration, error)
   148  	RenewCert(commoninit.SecretType, certificate.Instance, *current.EnrollmentSpec, *commonapi.BCCSP, string, bool, bool) error
   149  }
   150  
   151  //go:generate counterfeiter -o mocks/restart_manager.go -fake-name RestartManager . RestartManager
   152  
   153  type RestartManager interface {
   154  	ForAdminCertUpdate(instance v1.Object) error
   155  	ForCertUpdate(certType commoninit.SecretType, instance v1.Object) error
   156  	ForConfigOverride(instance v1.Object) error
   157  	ForNodeOU(instance v1.Object) error
   158  	TriggerIfNeeded(instance restart.Instance) error
   159  	ForRestartAction(instance v1.Object) error
   160  }
   161  
   162  type OrdererConfig interface {
   163  	MergeWith(interface{}, bool) error
   164  	ToBytes() ([]byte, error)
   165  	UsingPKCS11() bool
   166  	SetPKCS11Defaults(bool)
   167  	GetBCCSPSection() *commonapi.BCCSP
   168  	SetDefaultKeyStore()
   169  	SetBCCSPLibrary(string)
   170  }
   171  
   172  type Manager struct {
   173  	Client controllerclient.Client
   174  	Scheme *runtime.Scheme
   175  	Config *config.Config
   176  }
   177  
   178  func (m *Manager) GetNode(nodeNumber int, renewCertTimers map[string]*time.Timer, restartManager RestartManager) *Node {
   179  	return NewNode(m.Client, m.Scheme, m.Config, fmt.Sprintf("%s%d", NODE, nodeNumber), renewCertTimers, restartManager)
   180  }
   181  
   182  var _ IBPOrderer = &Node{}
   183  
   184  type Node struct {
   185  	Client controllerclient.Client
   186  	Scheme *runtime.Scheme
   187  	Config *config.Config
   188  
   189  	DeploymentManager     DeploymentManager
   190  	ServiceManager        resources.Manager
   191  	PVCManager            resources.Manager
   192  	EnvConfigMapManager   resources.Manager
   193  	RoleManager           resources.Manager
   194  	RoleBindingManager    resources.Manager
   195  	ServiceAccountManager resources.Manager
   196  
   197  	Override    Override
   198  	Initializer InitializeIBPOrderer
   199  	Name        string
   200  
   201  	CertificateManager CertificateManager
   202  	RenewCertTimers    map[string]*time.Timer
   203  
   204  	Restart RestartManager
   205  }
   206  
   207  func NewNode(client controllerclient.Client, scheme *runtime.Scheme, config *config.Config, name string, renewCertTimers map[string]*time.Timer, restartManager RestartManager) *Node {
   208  	n := &Node{
   209  		Client: client,
   210  		Scheme: scheme,
   211  		Config: config,
   212  		Override: &override.Override{
   213  			Name:   name,
   214  			Client: client,
   215  			Config: config,
   216  		},
   217  		Name:            name,
   218  		RenewCertTimers: renewCertTimers,
   219  		Restart:         restartManager,
   220  	}
   221  	n.CreateManagers()
   222  
   223  	validator := &validator.Validator{
   224  		Client: client,
   225  	}
   226  
   227  	n.Initializer = initializer.New(client, scheme, config.OrdererInitConfig, name, validator)
   228  	n.CertificateManager = certificate.New(client, scheme)
   229  
   230  	return n
   231  }
   232  
   233  func NewNodeWithOverrides(client controllerclient.Client, scheme *runtime.Scheme, config *config.Config, name string, o Override, renewCertTimers map[string]*time.Timer, restartManager RestartManager) *Node {
   234  	n := &Node{
   235  		Client:          client,
   236  		Scheme:          scheme,
   237  		Config:          config,
   238  		Override:        o,
   239  		Name:            name,
   240  		RenewCertTimers: renewCertTimers,
   241  		Restart:         restartManager,
   242  	}
   243  	n.CreateManagers()
   244  
   245  	validator := &validator.Validator{
   246  		Client: client,
   247  	}
   248  
   249  	n.Initializer = initializer.New(client, scheme, config.OrdererInitConfig, name, validator)
   250  	n.CertificateManager = certificate.New(client, scheme)
   251  
   252  	return n
   253  }
   254  
   255  func (n *Node) CreateManagers() {
   256  	override := n.Override
   257  	resourceManager := resourcemanager.New(n.Client, n.Scheme)
   258  	n.DeploymentManager = resourceManager.CreateDeploymentManager("", override.Deployment, n.GetLabels, n.Config.OrdererInitConfig.DeploymentFile)
   259  	n.ServiceManager = resourceManager.CreateServiceManager("", override.Service, n.GetLabels, n.Config.OrdererInitConfig.ServiceFile)
   260  	n.PVCManager = resourceManager.CreatePVCManager("", override.PVC, n.GetLabels, n.Config.OrdererInitConfig.PVCFile)
   261  	n.EnvConfigMapManager = resourceManager.CreateConfigMapManager("env", override.EnvCM, n.GetLabels, n.Config.OrdererInitConfig.CMFile, nil)
   262  	n.RoleManager = resourceManager.CreateRoleManager("", nil, n.GetLabels, n.Config.OrdererInitConfig.RoleFile)
   263  	n.RoleBindingManager = resourceManager.CreateRoleBindingManager("", nil, n.GetLabels, n.Config.OrdererInitConfig.RoleBindingFile)
   264  	n.ServiceAccountManager = resourceManager.CreateServiceAccountManager("", nil, n.GetLabels, n.Config.OrdererInitConfig.ServiceAccountFile)
   265  }
   266  
   267  func (n *Node) Reconcile(instance *current.IBPOrderer, update Update) (common.Result, error) {
   268  	log.Info(fmt.Sprintf("Reconciling node instance '%s' ... update: %+v", instance.Name, update))
   269  	var err error
   270  	var status *current.CRStatus
   271  
   272  	versionSet, err := n.SetVersion(instance)
   273  	if err != nil {
   274  		return common.Result{}, errors.Wrap(err, fmt.Sprintf("failed updating CR '%s' to version '%s'", instance.Name, version.Operator))
   275  	}
   276  	if versionSet {
   277  		log.Info("Instance version updated, requeuing request...")
   278  		return common.Result{
   279  			Result: reconcile.Result{
   280  				Requeue: true,
   281  			},
   282  		}, nil
   283  	}
   284  
   285  	instanceUpdated, err := n.PreReconcileChecks(instance, update)
   286  	if err != nil {
   287  		return common.Result{}, errors.Wrap(err, "failed pre reconcile checks")
   288  	}
   289  	externalEndpointUpdated := n.UpdateExternalEndpoint(instance)
   290  
   291  	if instanceUpdated || externalEndpointUpdated {
   292  		log.Info(fmt.Sprintf("Updating instance after pre reconcile checks: %t, updating external endpoint: %t",
   293  			instanceUpdated, externalEndpointUpdated))
   294  
   295  		err = n.Client.Patch(context.TODO(), instance, nil, controllerclient.PatchOption{
   296  			Resilient: &controllerclient.ResilientPatch{
   297  				Retry:    3,
   298  				Into:     &current.IBPOrderer{},
   299  				Strategy: k8sclient.MergeFrom,
   300  			},
   301  		})
   302  		if err != nil {
   303  			return common.Result{}, errors.Wrap(err, "failed to update instance")
   304  		}
   305  
   306  		log.Info("Instance updated, requeuing request...")
   307  		return common.Result{
   308  			Result: reconcile.Result{
   309  				Requeue: true,
   310  			},
   311  			Status: &current.CRStatus{
   312  				Type:    current.Initializing,
   313  				Reason:  "Setting default values for either zone, region, and/or external endpoint",
   314  				Message: "Operator has updated spec with defaults as part of initialization",
   315  			},
   316  		}, nil
   317  	}
   318  
   319  	err = n.Initialize(instance, update)
   320  	if err != nil {
   321  		return common.Result{}, operatorerrors.Wrap(err, operatorerrors.OrdererInitilizationFailed, "failed to initialize orderer node")
   322  	}
   323  
   324  	err = n.ReconcileManagers(instance, update, nil)
   325  	if err != nil {
   326  		return common.Result{}, errors.Wrap(err, "failed to reconcile managers")
   327  	}
   328  
   329  	err = n.UpdateConnectionProfile(instance)
   330  	if err != nil {
   331  		return common.Result{}, errors.Wrap(err, "failed to create connection profile")
   332  	}
   333  
   334  	err = n.CheckStates(instance)
   335  	if err != nil {
   336  		return common.Result{}, errors.Wrap(err, "failed to check and restore state")
   337  	}
   338  
   339  	// custom product logic can be implemented here
   340  	// No-Op atm
   341  	status, result, err := n.CustomLogic(instance, update)
   342  
   343  	if err != nil {
   344  		return common.Result{}, errors.Wrap(err, "failed to run custom offering logic")
   345  	}
   346  
   347  	if result != nil {
   348  		return *result, nil
   349  	}
   350  
   351  	if update.MSPUpdated() {
   352  		err = n.UpdateMSPCertificates(instance)
   353  		if err != nil {
   354  			if err != nil {
   355  				return common.Result{}, errors.Wrap(err, "failed to update certificates passed in MSP spec")
   356  			}
   357  		}
   358  	}
   359  
   360  	if update.EcertUpdated() {
   361  		log.Info("Ecert was updated")
   362  		// Request deployment restart for tls cert update
   363  		err = n.Restart.ForCertUpdate(commoninit.ECERT, instance)
   364  		if err != nil {
   365  			return common.Result{}, errors.Wrap(err, "failed to update restart config")
   366  		}
   367  	}
   368  
   369  	if update.TLSCertUpdated() {
   370  		log.Info("TLS cert was updated")
   371  		// Request deployment restart for ecert update
   372  		err = n.Restart.ForCertUpdate(commoninit.TLS, instance)
   373  		if err != nil {
   374  			return common.Result{}, errors.Wrap(err, "failed to update restart config")
   375  		}
   376  	}
   377  
   378  	if err := n.HandleActions(instance, update); err != nil {
   379  		return common.Result{}, errors.Wrap(err, "failed to handle actions")
   380  	}
   381  
   382  	if err := n.HandleRestart(instance, update); err != nil {
   383  		return common.Result{}, err
   384  	}
   385  
   386  	return common.Result{
   387  		Status: status,
   388  	}, nil
   389  }
   390  
   391  // PreReconcileChecks validate CR request before starting reconcile flow
   392  func (n *Node) PreReconcileChecks(instance *current.IBPOrderer, update Update) (bool, error) {
   393  	var err error
   394  
   395  	imagesUpdated, err := reconcilechecks.FabricVersionHelper(instance, n.Config.Operator.Versions, update)
   396  	if err != nil {
   397  		return false, errors.Wrap(err, "failed during version and image checks")
   398  	}
   399  
   400  	if instance.Spec.HSMSet() {
   401  		err = util.ValidateHSMProxyURL(instance.Spec.HSM.PKCS11Endpoint)
   402  		if err != nil {
   403  			return false, errors.Wrapf(err, "invalid HSM endpoint for orderer instance '%s'", instance.GetName())
   404  		}
   405  	}
   406  
   407  	if !instance.Spec.DomainSet() {
   408  		return false, fmt.Errorf("domain not set for orderer instance '%s'", instance.GetName())
   409  	}
   410  
   411  	if instance.Spec.Action.Enroll.Ecert && instance.Spec.Action.Reenroll.Ecert {
   412  		return false, errors.New("both enroll and renenroll action requested for ecert, must only select one")
   413  	}
   414  
   415  	if instance.Spec.Action.Enroll.TLSCert && instance.Spec.Action.Reenroll.TLSCert {
   416  		return false, errors.New("both enroll and renenroll action requested for TLS cert, must only select one")
   417  	}
   418  
   419  	if instance.Spec.Action.Enroll.Ecert && instance.Spec.Action.Reenroll.EcertNewKey {
   420  		return false, errors.New("both enroll and renenroll with new key action requested for ecert, must only select one")
   421  	}
   422  
   423  	if instance.Spec.Action.Enroll.TLSCert && instance.Spec.Action.Reenroll.TLSCertNewKey {
   424  		return false, errors.New("both enroll and renenroll with new key action requested for TLS cert, must only select one")
   425  	}
   426  
   427  	if instance.Spec.Action.Reenroll.Ecert && instance.Spec.Action.Reenroll.EcertNewKey {
   428  		return false, errors.New("both reenroll and renenroll with new key action requested for ecert, must only select one")
   429  	}
   430  
   431  	if instance.Spec.Action.Reenroll.TLSCert && instance.Spec.Action.Reenroll.TLSCertNewKey {
   432  		return false, errors.New("both reenroll and renenroll with new key action requested for TLS cert, must only select one")
   433  	}
   434  
   435  	zoneUpdated, err := n.SelectZone(instance)
   436  	if err != nil {
   437  		return false, err
   438  	}
   439  
   440  	regionUpdated, err := n.SelectRegion(instance)
   441  	if err != nil {
   442  		return false, err
   443  	}
   444  
   445  	hsmImageUpdated := n.ReconcileHSMImages(instance)
   446  
   447  	var replicasUpdated bool
   448  	if instance.Spec.Replicas == nil {
   449  		replicas := int32(1)
   450  		instance.Spec.Replicas = &replicas
   451  		replicasUpdated = true
   452  	}
   453  
   454  	updated := zoneUpdated || regionUpdated || hsmImageUpdated || replicasUpdated || imagesUpdated
   455  
   456  	if updated {
   457  		log.Info(fmt.Sprintf("zoneUpdated %t, regionUpdated %t, hsmImageUpdated %t, replicasUpdated %t, imagesUpdated %t",
   458  			zoneUpdated, regionUpdated, hsmImageUpdated, replicasUpdated, imagesUpdated))
   459  	}
   460  
   461  	return updated, nil
   462  }
   463  
   464  func (n *Node) Initialize(instance *current.IBPOrderer, update Update) error {
   465  	var err error
   466  
   467  	log.Info(fmt.Sprintf("Checking if initialization needed for node: %s", instance.GetName()))
   468  
   469  	// TODO: Add checks to determine if initialization is neeeded. Split this method into
   470  	// two, one should handle initialization during the create event of a CR and the other
   471  	// should update events
   472  
   473  	// Service account is required by HSM init job
   474  	err = n.ReconcileRBAC(instance)
   475  	if err != nil {
   476  		return errors.Wrap(err, "failed RBAC reconciliation")
   477  	}
   478  
   479  	if instance.IsHSMEnabled() {
   480  		// If HSM config not found, HSM proxy is being used
   481  		if instance.UsingHSMProxy() {
   482  			err = os.Setenv("PKCS11_PROXY_SOCKET", instance.Spec.HSM.PKCS11Endpoint)
   483  			if err != nil {
   484  				return err
   485  			}
   486  		} else {
   487  
   488  			hsmConfig, err := commonconfig.ReadHSMConfig(n.Client, instance)
   489  			if err != nil {
   490  				return errors.New("using non-proxy HSM, but no HSM config defined as config map 'ibp-hsm-config'")
   491  			}
   492  
   493  			if hsmConfig.Daemon != nil {
   494  				log.Info("Using daemon based HSM, creating pvc...")
   495  				n.PVCManager.SetCustomName(instance.Spec.CustomNames.PVC.Orderer)
   496  				err = n.PVCManager.Reconcile(instance, update.SpecUpdated())
   497  				if err != nil {
   498  					return errors.Wrap(err, "failed PVC reconciliation")
   499  				}
   500  			}
   501  		}
   502  	}
   503  
   504  	initOrderer, err := n.Initializer.GetInitOrderer(instance, n.GetInitStoragePath(instance))
   505  	if err != nil {
   506  		return err
   507  	}
   508  	initOrderer.UsingHSMProxy = instance.UsingHSMProxy()
   509  
   510  	ordererConfig := n.Config.OrdererInitConfig.OrdererFile
   511  	if version.GetMajorReleaseVersion(instance.Spec.FabricVersion) == version.V2 {
   512  		currentVer := version.String(instance.Spec.FabricVersion)
   513  		if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
   514  			ordererConfig = n.Config.OrdererInitConfig.OrdererV24File
   515  		} else if currentVer.LessThan(version.V2_4_1) {
   516  			ordererConfig = n.Config.OrdererInitConfig.OrdererV2File
   517  		}
   518  	}
   519  
   520  	initOrderer.Config, err = n.Initializer.GetCoreConfigFromFile(instance, ordererConfig)
   521  	if err != nil {
   522  		return err
   523  	}
   524  
   525  	updated := update.ConfigOverridesUpdated() || update.NodeOUUpdated()
   526  	if update.ConfigOverridesUpdated() {
   527  		err = n.InitializeUpdateConfigOverride(instance, initOrderer)
   528  		if err != nil {
   529  			return err
   530  		}
   531  		// Request deployment restart for config override update
   532  		if err := n.Restart.ForConfigOverride(instance); err != nil {
   533  			return err
   534  		}
   535  	}
   536  	if update.NodeOUUpdated() {
   537  		err = n.InitializeUpdateNodeOU(instance)
   538  		if err != nil {
   539  			return err
   540  		}
   541  		// Request deloyment restart for node OU update
   542  		if err = n.Restart.ForNodeOU(instance); err != nil {
   543  			return err
   544  		}
   545  	}
   546  	if !updated {
   547  		err = n.InitializeCreate(instance, initOrderer)
   548  		if err != nil {
   549  			return err
   550  		}
   551  	}
   552  
   553  	updateNeeded, err := n.Initializer.CheckIfAdminCertsUpdated(instance)
   554  	if err != nil {
   555  		return err
   556  	}
   557  
   558  	if updateNeeded {
   559  		err = n.Initializer.UpdateAdminSecret(instance)
   560  		if err != nil {
   561  			return err
   562  		}
   563  		// Request deployment restart for admin cert updates
   564  		if err = n.Restart.ForAdminCertUpdate(instance); err != nil {
   565  			return err
   566  		}
   567  	}
   568  
   569  	return nil
   570  }
   571  
   572  func (n *Node) InitializeCreate(instance *current.IBPOrderer, initOrderer *initializer.Orderer) error {
   573  	// TODO: Should also check for secrets not just config map
   574  	if n.ConfigExists(instance) {
   575  		log.Info(fmt.Sprintf("Config '%s-config' exists, not reinitializing node", instance.GetName()))
   576  		return nil
   577  	}
   578  
   579  	log.Info(fmt.Sprintf("Running initialization for create event on node '%s', since config '%s-config' does not exists", instance.GetName(), instance.GetName()))
   580  	configOverride, err := instance.GetConfigOverride()
   581  	if err != nil {
   582  		return err
   583  	}
   584  	resp, err := n.Initializer.Create(configOverride.(OrdererConfig), initOrderer, n.GetInitStoragePath(instance))
   585  	if err != nil {
   586  		return err
   587  	}
   588  
   589  	if resp != nil {
   590  		if resp.Crypto != nil {
   591  			if !instance.Spec.NodeOUDisabled() {
   592  				if err := resp.Crypto.VerifyCertOU("orderer"); err != nil {
   593  					return err
   594  				}
   595  			}
   596  
   597  			err = n.Initializer.GenerateSecretsFromResponse(instance, resp.Crypto)
   598  			if err != nil {
   599  				return err
   600  			}
   601  		}
   602  
   603  		if resp.Config != nil {
   604  			log.Info(fmt.Sprintf("Create config map for '%s'...", instance.GetName()))
   605  			if instance.IsHSMEnabled() && !instance.UsingHSMProxy() {
   606  				hsmConfig, err := commonconfig.ReadHSMConfig(n.Client, instance)
   607  				if err != nil {
   608  					return err
   609  				}
   610  				resp.Config.SetBCCSPLibrary(filepath.Join("/hsm/lib", filepath.Base(hsmConfig.Library.FilePath)))
   611  			}
   612  
   613  			err = n.Initializer.CreateOrUpdateConfigMap(instance, resp.Config)
   614  			if err != nil {
   615  				return err
   616  			}
   617  		}
   618  	}
   619  
   620  	return nil
   621  }
   622  
   623  func (n *Node) ConfigExists(instance *current.IBPOrderer) bool {
   624  	name := fmt.Sprintf("%s-config", instance.GetName())
   625  	namespacedName := types.NamespacedName{
   626  		Name:      name,
   627  		Namespace: instance.Namespace,
   628  	}
   629  
   630  	cm := &corev1.ConfigMap{}
   631  	err := n.Client.Get(context.TODO(), namespacedName, cm)
   632  	if err != nil {
   633  		return false
   634  	}
   635  
   636  	return true
   637  }
   638  
   639  func (n *Node) InitializeUpdateConfigOverride(instance *current.IBPOrderer, initOrderer *initializer.Orderer) error {
   640  	log.Info(fmt.Sprintf("Running initialization update config override for node: %s", instance.GetName()))
   641  
   642  	if n.Initializer.MissingCrypto(instance) {
   643  		log.Info("Missing crypto for node")
   644  		// If crypto is missing, we should run the create logic
   645  		err := n.InitializeCreate(instance, initOrderer)
   646  		if err != nil {
   647  			return err
   648  		}
   649  
   650  		return nil
   651  	}
   652  
   653  	cm, err := n.Initializer.GetConfigFromConfigMap(instance)
   654  	if err != nil {
   655  		return err
   656  	}
   657  
   658  	initOrderer.Config, err = n.Initializer.GetCoreConfigFromBytes(instance, cm.BinaryData["orderer.yaml"])
   659  	if err != nil {
   660  		return err
   661  	}
   662  
   663  	configOverride, err := instance.GetConfigOverride()
   664  	if err != nil {
   665  		return err
   666  	}
   667  
   668  	resp, err := n.Initializer.Update(configOverride.(OrdererConfig), initOrderer)
   669  	if err != nil {
   670  		return err
   671  	}
   672  
   673  	if resp != nil && resp.Config != nil {
   674  		log.Info(fmt.Sprintf("Update config map for '%s'...", instance.GetName()))
   675  		err = n.Initializer.CreateOrUpdateConfigMap(instance, resp.Config)
   676  		if err != nil {
   677  			return err
   678  		}
   679  	}
   680  
   681  	return nil
   682  }
   683  
   684  func (n *Node) InitializeUpdateNodeOU(instance *current.IBPOrderer) error {
   685  	log.Info(fmt.Sprintf("Running initialize update node OU enabled: %t for orderer '%s", !instance.Spec.NodeOUDisabled(), instance.GetName()))
   686  
   687  	crypto, err := n.Initializer.GetCrypto(instance)
   688  	if err != nil {
   689  		return err
   690  	}
   691  
   692  	if !instance.Spec.NodeOUDisabled() {
   693  		if err := crypto.VerifyCertOU("orderer"); err != nil {
   694  			return err
   695  
   696  		}
   697  	} else {
   698  		// If nodeOUDisabled, admin certs are required
   699  		if crypto.Enrollment.AdminCerts == nil {
   700  			return errors.New("node OU disabled, admin certs are required but missing")
   701  		}
   702  	}
   703  
   704  	// Update config.yaml in config map
   705  	err = n.Initializer.CreateOrUpdateConfigMap(instance, nil)
   706  	if err != nil {
   707  		return err
   708  	}
   709  
   710  	return nil
   711  }
   712  
   713  func (n *Node) ReconcileManagers(instance *current.IBPOrderer, updated Update, genesisBlock []byte) error {
   714  	var err error
   715  
   716  	update := updated.SpecUpdated()
   717  
   718  	n.PVCManager.SetCustomName(instance.Spec.CustomNames.PVC.Orderer)
   719  	err = n.PVCManager.Reconcile(instance, update)
   720  	if err != nil {
   721  		return errors.Wrapf(err, "failed PVC reconciliation")
   722  	}
   723  
   724  	err = n.ServiceManager.Reconcile(instance, update)
   725  	if err != nil {
   726  		return errors.Wrap(err, "failed Service reconciliation")
   727  	}
   728  
   729  	err = n.ReconcileRBAC(instance)
   730  	if err != nil {
   731  		return errors.Wrap(err, "failed RBAC reconciliation")
   732  	}
   733  
   734  	err = n.EnvConfigMapManager.Reconcile(instance, update)
   735  	if err != nil {
   736  		return errors.Wrap(err, "failed Env ConfigMap reconciliation")
   737  	}
   738  
   739  	if instance.Spec.IsUsingChannelLess() {
   740  		log.Info("Node is in channel less mode - ending reconcile")
   741  	} else if !instance.Spec.IsPrecreateOrderer() {
   742  		log.Info("Node is not precreate - reconciling genesis secret")
   743  		err = n.ReconcileGenesisSecret(instance)
   744  		if err != nil {
   745  			return errors.Wrap(err, "failed Genesis Secret reconciliation")
   746  		}
   747  	}
   748  
   749  	err = n.DeploymentManager.Reconcile(instance, updated.DeploymentUpdated())
   750  	if err != nil {
   751  		return errors.Wrap(err, "failed Deployment reconciliation")
   752  	}
   753  
   754  	return nil
   755  }
   756  
   757  func (n *Node) CheckStates(instance *current.IBPOrderer) error {
   758  	// Don't need to check state if the state is being updated via CR. State needs
   759  	// to be checked if operator detects changes to a resources that was not triggered
   760  	// via CR.
   761  	if n.DeploymentManager.Exists(instance) {
   762  		err := n.DeploymentManager.CheckState(instance)
   763  		if err != nil {
   764  			log.Error(err, "unexpected state")
   765  			err = n.DeploymentManager.RestoreState(instance)
   766  			if err != nil {
   767  				return err
   768  			}
   769  		}
   770  	}
   771  
   772  	return nil
   773  }
   774  
   775  func (n *Node) SetVersion(instance *current.IBPOrderer) (bool, error) {
   776  	if instance.Status.Version == "" || !version.String(instance.Status.Version).Equal(version.Operator) {
   777  		log.Info("Version of Operator: ", "version", version.Operator)
   778  		log.Info(fmt.Sprintf("Version of CR '%s': %s", instance.GetName(), instance.Status.Version))
   779  		log.Info(fmt.Sprintf("Setting '%s' to version '%s'", instance.Name, version.Operator))
   780  
   781  		instance.Status.Version = version.Operator
   782  		err := n.Client.PatchStatus(context.TODO(), instance, nil, controllerclient.PatchOption{
   783  			Resilient: &controllerclient.ResilientPatch{
   784  				Retry:    3,
   785  				Into:     &current.IBPOrderer{},
   786  				Strategy: k8sclient.MergeFrom,
   787  			},
   788  		})
   789  		if err != nil {
   790  			return false, err
   791  		}
   792  		return true, nil
   793  	}
   794  	return false, nil
   795  }
   796  
   797  func (n *Node) GetLabels(instance v1.Object) map[string]string {
   798  	parts := strings.Split(instance.GetName(), "node")
   799  	label := os.Getenv("OPERATOR_LABEL_PREFIX")
   800  	if label == "" {
   801  		label = "fabric"
   802  	}
   803  
   804  	if len(parts) > 1 {
   805  		ordererclustername := strings.Join(parts[:len(parts)-1], "node")
   806  		orderingnode := "node" + parts[len(parts)-1]
   807  		return map[string]string{
   808  			"app":                          instance.GetName(),
   809  			"creator":                      label,
   810  			"orderingservice":              ordererclustername,
   811  			"orderingnode":                 orderingnode,
   812  			"parent":                       ordererclustername,
   813  			"app.kubernetes.io/name":       label,
   814  			"app.kubernetes.io/instance":   label + "orderer",
   815  			"app.kubernetes.io/managed-by": label + "-operator",
   816  		}
   817  	}
   818  
   819  	return map[string]string{
   820  		"app":                          instance.GetName(),
   821  		"creator":                      label,
   822  		"orderingservice":              fmt.Sprintf("%s", instance.GetName()),
   823  		"app.kubernetes.io/name":       label,
   824  		"app.kubernetes.io/instance":   label + "orderer",
   825  		"app.kubernetes.io/managed-by": label + "-operator",
   826  	}
   827  }
   828  
   829  func (n *Node) Delete(instance *current.IBPOrderer) error {
   830  	log.Info(fmt.Sprintf("Deleting node '%s'", n.Name))
   831  	err := n.ServiceManager.Delete(instance)
   832  	if err != nil {
   833  		return errors.Wrapf(err, "failed to delete service '%s'", n.ServiceManager.GetName(instance))
   834  	}
   835  
   836  	err = n.PVCManager.Delete(instance)
   837  	if err != nil {
   838  		return errors.Wrapf(err, "failed to delete pvc '%s'", n.ServiceManager.GetName(instance))
   839  	}
   840  
   841  	err = n.EnvConfigMapManager.Delete(instance)
   842  	if err != nil {
   843  		return errors.Wrapf(err, "failed to delete config map '%s'", n.ServiceManager.GetName(instance))
   844  	}
   845  
   846  	err = n.Initializer.Delete(instance)
   847  	if err != nil {
   848  		return errors.Wrapf(err, "failed to delete secrets")
   849  	}
   850  
   851  	// Important: This must always be the last resource to be deleted
   852  	err = n.DeploymentManager.Delete(instance)
   853  	if err != nil {
   854  		return errors.Wrapf(err, "failed to delete deployment '%s'", n.DeploymentManager.GetName(instance))
   855  	}
   856  
   857  	return nil
   858  }
   859  
   860  func (n *Node) ReconcileGenesisSecret(instance *current.IBPOrderer) error {
   861  	namespacedName := types.NamespacedName{
   862  		Name:      instance.Name + "-genesis",
   863  		Namespace: instance.Namespace,
   864  	}
   865  
   866  	secret := &corev1.Secret{}
   867  	err := n.Client.Get(context.TODO(), namespacedName, secret)
   868  	if err != nil {
   869  		if k8serrors.IsNotFound(err) {
   870  			// Request object not found, could have been deleted after reconcile request.
   871  			// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
   872  			// Return and don't requeue
   873  			return n.CreateGenesisSecret(instance)
   874  		}
   875  		// Error reading the object - requeue the request.
   876  		return err
   877  	}
   878  	return nil
   879  }
   880  
   881  func (n *Node) CreateGenesisSecret(instance *current.IBPOrderer) error {
   882  	data := map[string][]byte{}
   883  
   884  	genesisBlock, err := util.Base64ToBytes(instance.Spec.GenesisBlock)
   885  	if err != nil {
   886  		return errors.Wrap(err, "failed to decode genesis block")
   887  	}
   888  
   889  	data["orderer.block"] = genesisBlock
   890  	s := &corev1.Secret{
   891  		Data: data,
   892  	}
   893  	s.Name = instance.Name + "-genesis"
   894  	s.Namespace = instance.Namespace
   895  	s.Labels = n.GetLabels(instance)
   896  
   897  	err = n.Client.CreateOrUpdate(context.TODO(), s, controllerclient.CreateOrUpdateOption{
   898  		Owner:  instance,
   899  		Scheme: n.Scheme,
   900  	})
   901  	if err != nil {
   902  		return errors.Wrap(err, "failed to create genesis secret")
   903  	}
   904  
   905  	return nil
   906  }
   907  
   908  func (n *Node) ReconcileRBAC(instance *current.IBPOrderer) error {
   909  	var err error
   910  
   911  	err = n.RoleManager.Reconcile(instance, false)
   912  	if err != nil {
   913  		return err
   914  	}
   915  
   916  	err = n.RoleBindingManager.Reconcile(instance, false)
   917  	if err != nil {
   918  		return err
   919  	}
   920  
   921  	err = n.ServiceAccountManager.Reconcile(instance, false)
   922  	if err != nil {
   923  		return err
   924  	}
   925  
   926  	return nil
   927  }
   928  
   929  func (n *Node) SelectZone(instance *current.IBPOrderer) (bool, error) {
   930  	if instance.Spec.Zone == "select" {
   931  		log.Info("Selecting zone...")
   932  		zone := util.GetZone(n.Client)
   933  		log.Info(fmt.Sprintf("Zone set to: '%s'", zone))
   934  		instance.Spec.Zone = zone
   935  		return true, nil
   936  	}
   937  	if instance.Spec.Zone != "" {
   938  		err := util.ValidateZone(n.Client, instance.Spec.Zone)
   939  		if err != nil {
   940  			return false, err
   941  		}
   942  	}
   943  	return false, nil
   944  }
   945  
   946  func (n *Node) SelectRegion(instance *current.IBPOrderer) (bool, error) {
   947  	if instance.Spec.Region == "select" {
   948  		log.Info("Selecting region...")
   949  		region := util.GetRegion(n.Client)
   950  		log.Info(fmt.Sprintf("Region set to: '%s'", region))
   951  		instance.Spec.Region = region
   952  		return true, nil
   953  	}
   954  	if instance.Spec.Region != "" {
   955  		err := util.ValidateRegion(n.Client, instance.Spec.Region)
   956  		if err != nil {
   957  			return false, err
   958  		}
   959  	}
   960  	return false, nil
   961  }
   962  
   963  func (n *Node) UpdateExternalEndpoint(instance *current.IBPOrderer) bool {
   964  	if instance.Spec.ExternalAddress == "" {
   965  		instance.Spec.ExternalAddress = instance.Namespace + "-" + instance.Name + "-orderer" + "." + instance.Spec.Domain + ":443"
   966  		return true
   967  	}
   968  	return false
   969  }
   970  
   971  func (n *Node) UpdateConnectionProfile(instance *current.IBPOrderer) error {
   972  	var err error
   973  
   974  	endpoints := n.GetEndpoints(instance)
   975  
   976  	tlscert, err := common.GetTLSSignCertEncoded(n.Client, instance)
   977  	if err != nil {
   978  		return err
   979  	}
   980  
   981  	tlscacerts, err := common.GetTLSCACertEncoded(n.Client, instance)
   982  	if err != nil {
   983  		return err
   984  	}
   985  
   986  	tlsintercerts, err := common.GetTLSIntercertEncoded(n.Client, instance)
   987  	if err != nil {
   988  		return err
   989  	}
   990  
   991  	ecert, err := common.GetEcertSignCertEncoded(n.Client, instance)
   992  	if err != nil {
   993  		return err
   994  	}
   995  
   996  	cacert, err := common.GetEcertCACertEncoded(n.Client, instance)
   997  	if err != nil {
   998  		return err
   999  	}
  1000  
  1001  	admincerts, err := common.GetEcertAdmincertEncoded(n.Client, instance)
  1002  	if err != nil {
  1003  		return err
  1004  	}
  1005  
  1006  	if len(tlsintercerts) > 0 {
  1007  		tlscacerts = tlsintercerts
  1008  	}
  1009  
  1010  	err = n.UpdateConnectionProfileConfigmap(instance, *endpoints, tlscert, tlscacerts, ecert, cacert, admincerts)
  1011  	if err != nil {
  1012  		return err
  1013  	}
  1014  
  1015  	return nil
  1016  }
  1017  
  1018  func (n *Node) UpdateConnectionProfileConfigmap(instance *current.IBPOrderer, endpoints current.OrdererEndpoints, tlscert string, tlscacerts []string, ecert string, cacert []string, admincerts []string) error {
  1019  
  1020  	// TODO add ecert.intermediatecerts and ecert.admincerts
  1021  	// TODO add tls.cacerts
  1022  	// TODO get the whole PeerConnectionProfile object from caller??
  1023  	name := instance.Name + "-connection-profile"
  1024  	connectionProfile := &current.OrdererConnectionProfile{
  1025  		Endpoints: endpoints,
  1026  		TLS: &current.MSP{
  1027  			SignCerts: tlscert,
  1028  			CACerts:   tlscacerts,
  1029  		},
  1030  		Component: &current.MSP{
  1031  			SignCerts:  ecert,
  1032  			CACerts:    cacert,
  1033  			AdminCerts: admincerts,
  1034  		},
  1035  	}
  1036  
  1037  	bytes, err := json.Marshal(connectionProfile)
  1038  	if err != nil {
  1039  		return errors.Wrap(err, "failed to marshal connection profile")
  1040  	}
  1041  	cm := &corev1.ConfigMap{
  1042  		BinaryData: map[string][]byte{"profile.json": bytes},
  1043  	}
  1044  	cm.Name = name
  1045  	cm.Namespace = instance.Namespace
  1046  	cm.Labels = n.GetLabels(instance)
  1047  
  1048  	nn := types.NamespacedName{
  1049  		Name:      name,
  1050  		Namespace: instance.GetNamespace(),
  1051  	}
  1052  
  1053  	err = n.Client.Get(context.TODO(), nn, &corev1.ConfigMap{})
  1054  	if err == nil {
  1055  		log.Info(fmt.Sprintf("Update connection profile configmap '%s' for %s", nn.Name, instance.Name))
  1056  		err = n.Client.Update(context.TODO(), cm, controllerclient.UpdateOption{Owner: instance, Scheme: n.Scheme})
  1057  		if err != nil {
  1058  			return errors.Wrap(err, "failed to update connection profile configmap")
  1059  		}
  1060  	} else {
  1061  		log.Info(fmt.Sprintf("Create connection profile configmap '%s' for %s", nn.Name, instance.Name))
  1062  		err = n.Client.Create(context.TODO(), cm, controllerclient.CreateOption{Owner: instance, Scheme: n.Scheme})
  1063  		if err != nil {
  1064  			return errors.Wrap(err, "failed to create connection profile configmap")
  1065  		}
  1066  	}
  1067  
  1068  	return nil
  1069  }
  1070  
  1071  func (n *Node) GetEndpoints(instance *current.IBPOrderer) *current.OrdererEndpoints {
  1072  	endpoints := &current.OrdererEndpoints{
  1073  		API:        "grpcs://" + instance.Namespace + "-" + instance.Name + "-orderer." + instance.Spec.Domain + ":443",
  1074  		Operations: "https://" + instance.Namespace + "-" + instance.Name + "-operations." + instance.Spec.Domain + ":443",
  1075  		Grpcweb:    "https://" + instance.Namespace + "-" + instance.Name + "-grpcweb." + instance.Spec.Domain + ":443",
  1076  	}
  1077  	currentVer := version.String(instance.Spec.FabricVersion)
  1078  	if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
  1079  		endpoints.Admin = "https://" + instance.Namespace + "-" + instance.Name + "-admin." + instance.Spec.Domain + ":443"
  1080  	}
  1081  	return endpoints
  1082  }
  1083  
  1084  func (n *Node) UpdateParentStatus(instance *current.IBPOrderer) error {
  1085  	parentName := instance.Labels["parent"]
  1086  
  1087  	nn := types.NamespacedName{
  1088  		Name:      parentName,
  1089  		Namespace: instance.GetNamespace(),
  1090  	}
  1091  
  1092  	log.Info(fmt.Sprintf("Node '%s' is setting parent '%s' status", instance.GetName(), parentName))
  1093  
  1094  	parentInstance := &current.IBPOrderer{}
  1095  	err := n.Client.Get(context.TODO(), nn, parentInstance)
  1096  	if err != nil {
  1097  		if k8serrors.IsNotFound(err) {
  1098  			log.Info(fmt.Sprintf("Parent '%s' for node '%s' not found, skipping setting parent status", parentName, instance.GetName()))
  1099  			return nil
  1100  		}
  1101  		return err
  1102  	}
  1103  
  1104  	// If parent is deployed and child was not updated to warning state, no longer update the parent
  1105  	if parentInstance.Status.Type == current.Deployed && instance.Status.Type != current.Warning {
  1106  		log.Info(fmt.Sprintf("Parent '%s' is in 'Deployed' state, can't update status", parentName))
  1107  		return nil
  1108  	}
  1109  
  1110  	labelSelector, err := labels.Parse(fmt.Sprintf("parent=%s", parentName))
  1111  	if err != nil {
  1112  		return errors.Wrap(err, "failed to parse selector for parent name")
  1113  	}
  1114  
  1115  	listOptions := &client.ListOptions{
  1116  		LabelSelector: labelSelector,
  1117  		Namespace:     instance.GetNamespace(),
  1118  	}
  1119  
  1120  	ordererList := &current.IBPOrdererList{}
  1121  	err = n.Client.List(context.TODO(), ordererList, listOptions)
  1122  	if err != nil {
  1123  		return err
  1124  	}
  1125  
  1126  	clustersize := parentInstance.Spec.ClusterSize
  1127  
  1128  	var returnStatus current.IBPCRStatusType
  1129  	reason := "No reason"
  1130  
  1131  	log.Info(fmt.Sprintf("Found %d nodes, original cluster size %d", len(ordererList.Items), clustersize))
  1132  
  1133  	updateStatus := false
  1134  	errorstateNodes := []string{}
  1135  	deployingstateNodes := []string{}
  1136  	precreatedNodes := []string{}
  1137  	deployedNodes := []string{}
  1138  	warningNodes := []string{}
  1139  
  1140  	for _, node := range ordererList.Items {
  1141  		if node.Status.Type == current.Error {
  1142  			log.Info(fmt.Sprintf("Node %s is in Error state", node.GetName()))
  1143  			errorstateNodes = append(errorstateNodes, node.GetName())
  1144  		} else if node.Status.Type == current.Deploying {
  1145  			log.Info(fmt.Sprintf("Node %s is in Deploying state", node.GetName()))
  1146  			deployingstateNodes = append(deployingstateNodes, node.GetName())
  1147  		} else if node.Status.Type == current.Precreated {
  1148  			log.Info(fmt.Sprintf("Node %s is in Precreating state", node.GetName()))
  1149  			precreatedNodes = append(precreatedNodes, node.GetName())
  1150  		} else if node.Status.Type == current.Warning {
  1151  			log.Info(fmt.Sprintf("Node %s is in Warning state", node.GetName()))
  1152  			warningNodes = append(warningNodes, node.GetName())
  1153  		} else if node.Status.Type == current.Deployed {
  1154  			log.Info(fmt.Sprintf("Node %s is in Deployed state", node.GetName()))
  1155  			deployedNodes = append(deployedNodes, node.GetName())
  1156  		}
  1157  	}
  1158  
  1159  	if len(deployingstateNodes) != 0 {
  1160  		log.Info("Nodes are in deploying state currently, not updating parent status")
  1161  		updateStatus = false
  1162  	} else if len(errorstateNodes) != 0 {
  1163  		updateStatus = true
  1164  		reason = "The orderer nodes " + strings.Join(errorstateNodes[:], ",") + " are in Error state"
  1165  		returnStatus = current.Error
  1166  	} else if len(precreatedNodes) != 0 {
  1167  		updateStatus = true
  1168  		reason = "The orderer nodes " + strings.Join(precreatedNodes[:], ",") + " are in Precreated state"
  1169  		returnStatus = current.Precreated
  1170  	} else if len(warningNodes) != 0 {
  1171  		updateStatus = true
  1172  		reason = "The orderer nodes " + strings.Join(warningNodes[:], ",") + " are in Warning state"
  1173  		returnStatus = current.Warning
  1174  	} else if len(deployedNodes) != 0 {
  1175  		updateStatus = true
  1176  		returnStatus = current.Deployed
  1177  		reason = "All nodes are deployed"
  1178  	}
  1179  
  1180  	if updateStatus {
  1181  		parentInstance.Status.Type = returnStatus
  1182  		parentInstance.Status.Status = current.True
  1183  		parentInstance.Status.Reason = reason
  1184  		parentInstance.Status.LastHeartbeatTime = time.Now().String()
  1185  
  1186  		log.Info(fmt.Sprintf("Setting parent status to: %+v", parentInstance.Status))
  1187  		err = n.Client.UpdateStatus(context.TODO(), parentInstance)
  1188  		if err != nil {
  1189  			return err
  1190  		}
  1191  	}
  1192  
  1193  	return nil
  1194  }
  1195  
  1196  func (n *Node) GetInitStoragePath(instance *current.IBPOrderer) string {
  1197  	if n.Config != nil && n.Config.OrdererInitConfig != nil && n.Config.OrdererInitConfig.StoragePath != "" {
  1198  		return filepath.Join(n.Config.OrdererInitConfig.StoragePath, instance.GetName())
  1199  	}
  1200  
  1201  	return filepath.Join("/", "ordererinit", instance.GetName())
  1202  }
  1203  
  1204  func (n *Node) GetBCCSPSectionForInstance(instance *current.IBPOrderer) (*commonapi.BCCSP, error) {
  1205  	var bccsp *commonapi.BCCSP
  1206  	if instance.IsHSMEnabled() {
  1207  		co, err := instance.GetConfigOverride()
  1208  		if err != nil {
  1209  			return nil, errors.Wrap(err, "failed to get configoverride")
  1210  		}
  1211  
  1212  		configOverride := co.(OrdererConfig)
  1213  		configOverride.SetPKCS11Defaults(instance.UsingHSMProxy())
  1214  		bccsp = configOverride.GetBCCSPSection()
  1215  	}
  1216  
  1217  	return bccsp, nil
  1218  }
  1219  
  1220  func (n *Node) ReconcileFabricOrdererMigration(instance *current.IBPOrderer) error {
  1221  	ordererConfig, err := n.FabricOrdererMigration(instance)
  1222  	if err != nil {
  1223  		return errors.Wrap(err, "failed to migrate orderer between fabric versions")
  1224  	}
  1225  
  1226  	if ordererConfig != nil {
  1227  		log.Info("Orderer config updated during fabric orderer migration, updating config map...")
  1228  		if err := n.Initializer.CreateOrUpdateConfigMap(instance, ordererConfig); err != nil {
  1229  			return errors.Wrapf(err, "failed to create/update '%s' orderer's config map", instance.GetName())
  1230  		}
  1231  	}
  1232  
  1233  	return nil
  1234  }
  1235  
  1236  // Moving to fabric version above 1.4.6 require that the `msp/keystore` value be removed
  1237  // from BCCSP section if configured to use PKCS11 (HSM). NOTE: This does not support
  1238  // migration across major release, will not cover migration orderer from 1.4.x to 2.x
  1239  func (n *Node) FabricOrdererMigration(instance *current.IBPOrderer) (*ordererconfig.Orderer, error) {
  1240  	if !instance.IsHSMEnabled() {
  1241  		return nil, nil
  1242  	}
  1243  
  1244  	ordererTag := instance.Spec.Images.OrdererTag
  1245  	if !strings.Contains(ordererTag, "sha") {
  1246  		tag := strings.Split(ordererTag, "-")[0]
  1247  
  1248  		ordererVersion := version.String(tag)
  1249  		if !ordererVersion.GreaterThan(version.V1_4_6) {
  1250  			return nil, nil
  1251  		}
  1252  
  1253  		log.Info(fmt.Sprintf("Orderer moving to fabric version %s", ordererVersion))
  1254  	} else {
  1255  		if instance.Spec.FabricVersion == version.V2 {
  1256  			return nil, nil
  1257  		}
  1258  		log.Info(fmt.Sprintf("Orderer moving to digest %s", ordererTag))
  1259  	}
  1260  
  1261  	// Read orderer config map and remove keystore value from BCCSP section
  1262  	cm, err := n.Initializer.GetConfigFromConfigMap(instance)
  1263  	if err != nil {
  1264  		return nil, errors.Wrapf(err, "failed to get '%s' orderer's config map", instance.GetName())
  1265  	}
  1266  
  1267  	ordererConfig := &ordererconfig.Orderer{}
  1268  	if err := yaml.Unmarshal(cm.BinaryData["orderer.yaml"], ordererConfig); err != nil {
  1269  		return nil, errors.Wrap(err, "invalid orderer config")
  1270  	}
  1271  
  1272  	// If already nil, don't need to proceed further as config updates are not required
  1273  	if ordererConfig.General.BCCSP.PKCS11.FileKeyStore == nil {
  1274  		return nil, nil
  1275  	}
  1276  
  1277  	ordererConfig.General.BCCSP.PKCS11.FileKeyStore = nil
  1278  
  1279  	return ordererConfig, nil
  1280  }
  1281  
  1282  func (n *Node) UpdateMSPCertificates(instance *current.IBPOrderer) error {
  1283  	log.Info("Updating certificates passed in MSP spec")
  1284  	updatedOrderer, err := n.Initializer.GetUpdatedOrderer(instance)
  1285  	if err != nil {
  1286  		return err
  1287  	}
  1288  
  1289  	crypto, err := updatedOrderer.GenerateCrypto()
  1290  	if err != nil {
  1291  		return err
  1292  	}
  1293  
  1294  	if crypto != nil {
  1295  		err = n.Initializer.UpdateSecrets("ecert", instance, crypto.Enrollment)
  1296  		if err != nil {
  1297  			return errors.Wrap(err, "failed to update ecert secrets")
  1298  		}
  1299  
  1300  		err = n.Initializer.UpdateSecrets("tls", instance, crypto.TLS)
  1301  		if err != nil {
  1302  			return errors.Wrap(err, "failed to update tls secrets")
  1303  		}
  1304  
  1305  		err = n.Initializer.UpdateSecrets("clientauth", instance, crypto.ClientAuth)
  1306  		if err != nil {
  1307  			return errors.Wrap(err, "failed to update client auth secrets")
  1308  		}
  1309  	}
  1310  
  1311  	return nil
  1312  }
  1313  
  1314  func (n *Node) RenewCert(certType commoninit.SecretType, obj runtime.Object, newKey bool) error {
  1315  	instance := obj.(*current.IBPOrderer)
  1316  	if instance.Spec.Secret == nil {
  1317  		return errors.New(fmt.Sprintf("missing secret spec for instance '%s'", instance.GetName()))
  1318  	}
  1319  
  1320  	if instance.Spec.Secret.Enrollment != nil {
  1321  		log.Info(fmt.Sprintf("Renewing %s certificate for instance '%s'", string(certType), instance.Name))
  1322  
  1323  		hsmEnabled := instance.IsHSMEnabled()
  1324  		spec := instance.Spec.Secret.Enrollment
  1325  		storagePath := n.GetInitStoragePath(instance)
  1326  		bccsp, err := n.GetBCCSPSectionForInstance(instance)
  1327  		if err != nil {
  1328  			return err
  1329  		}
  1330  
  1331  		err = n.CertificateManager.RenewCert(certType, instance, spec, bccsp, storagePath, hsmEnabled, newKey)
  1332  		if err != nil {
  1333  			return err
  1334  		}
  1335  	} else {
  1336  		return errors.New("cannot auto-renew certificate created by MSP, force renewal required")
  1337  	}
  1338  
  1339  	return nil
  1340  }
  1341  
  1342  func (n *Node) EnrollForEcert(instance *current.IBPOrderer) error {
  1343  	log.Info(fmt.Sprintf("Ecert enroll triggered via action parameter for '%s'", instance.GetName()))
  1344  
  1345  	secret := instance.Spec.Secret
  1346  	if secret == nil || secret.Enrollment == nil || secret.Enrollment.Component == nil {
  1347  		return errors.New("unable to enroll, no ecert enrollment information provided")
  1348  	}
  1349  	ecertSpec := secret.Enrollment.Component
  1350  
  1351  	storagePath := filepath.Join(n.GetInitStoragePath(instance), "ecert")
  1352  	crypto, err := action.Enroll(instance, ecertSpec, storagePath, n.Client, n.Scheme, true, n.Config.Operator.Orderer.Timeouts.EnrollJob)
  1353  	if err != nil {
  1354  		return errors.Wrap(err, "failed to enroll for ecert")
  1355  	}
  1356  
  1357  	err = n.Initializer.GenerateSecrets("ecert", instance, crypto)
  1358  	if err != nil {
  1359  		return errors.Wrap(err, "failed to generate ecert secrets")
  1360  	}
  1361  
  1362  	return nil
  1363  }
  1364  
  1365  func (n *Node) EnrollForTLSCert(instance *current.IBPOrderer) error {
  1366  	log.Info(fmt.Sprintf("TLS cert enroll triggered via action parameter for '%s'", instance.GetName()))
  1367  
  1368  	secret := instance.Spec.Secret
  1369  	if secret == nil || secret.Enrollment == nil || secret.Enrollment.TLS == nil {
  1370  		return errors.New("unable to enroll, no TLS enrollment information provided")
  1371  	}
  1372  	tlscertSpec := secret.Enrollment.TLS
  1373  
  1374  	storagePath := filepath.Join(n.GetInitStoragePath(instance), "tls")
  1375  	crypto, err := action.Enroll(instance, tlscertSpec, storagePath, n.Client, n.Scheme, false, n.Config.Operator.Orderer.Timeouts.EnrollJob)
  1376  	if err != nil {
  1377  		return errors.Wrap(err, "failed to enroll for TLS cert")
  1378  	}
  1379  
  1380  	err = n.Initializer.GenerateSecrets("tls", instance, crypto)
  1381  	if err != nil {
  1382  		return errors.Wrap(err, "failed to generate ecert secrets")
  1383  	}
  1384  
  1385  	return nil
  1386  }
  1387  
  1388  func (n *Node) FabricOrdererMigrationV2_0(instance *current.IBPOrderer) error {
  1389  	log.Info(fmt.Sprintf("Orderer instance '%s' migrating to v2", instance.GetName()))
  1390  
  1391  	initOrderer, err := n.Initializer.GetInitOrderer(instance, n.GetInitStoragePath(instance))
  1392  	if err != nil {
  1393  		return err
  1394  	}
  1395  	initOrderer.UsingHSMProxy = instance.UsingHSMProxy()
  1396  
  1397  	ordererConfig := n.Config.OrdererInitConfig.OrdererFile
  1398  	if version.GetMajorReleaseVersion(instance.Spec.FabricVersion) == version.V2 {
  1399  		currentVer := version.String(instance.Spec.FabricVersion)
  1400  		if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
  1401  			ordererConfig = n.Config.OrdererInitConfig.OrdererV24File
  1402  		} else {
  1403  			ordererConfig = n.Config.OrdererInitConfig.OrdererV2File
  1404  		}
  1405  	}
  1406  
  1407  	switch version.GetMajorReleaseVersion(instance.Spec.FabricVersion) {
  1408  	case version.V2:
  1409  		currentVer := version.String(instance.Spec.FabricVersion)
  1410  		if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
  1411  			log.Info("v2.4.x Fabric Orderer requested")
  1412  			v24config, err := v24ordererconfig.ReadOrdererFile(ordererConfig)
  1413  			if err != nil {
  1414  				return errors.Wrap(err, "failed to read v2.4.x default config file")
  1415  			}
  1416  			initOrderer.Config = v24config
  1417  		} else if currentVer.LessThan(version.V2_4_1) {
  1418  			log.Info("v2.2.x Fabric Orderer requested")
  1419  			v2config, err := v2ordererconfig.ReadOrdererFile(ordererConfig)
  1420  			if err != nil {
  1421  				return errors.Wrap(err, "failed to read v2.2.x default config file")
  1422  			}
  1423  			initOrderer.Config = v2config
  1424  		}
  1425  	case version.V1:
  1426  		fallthrough
  1427  	default:
  1428  		// Choosing to default to v1.4 to not break backwards comptability, if coming
  1429  		// from a previous version of operator the 'FabricVersion' field would not be set and would
  1430  		// result in an error. // TODO: Determine if we want to throw error or handle setting
  1431  		// FabricVersion as part of migration logic.
  1432  		oconfig, err := ordererconfig.ReadOrdererFile(ordererConfig)
  1433  		if err != nil {
  1434  			return errors.Wrap(err, "failed to read v1.4 default config file")
  1435  		}
  1436  		initOrderer.Config = oconfig
  1437  	}
  1438  
  1439  	configOverride, err := instance.GetConfigOverride()
  1440  	if err != nil {
  1441  		return err
  1442  	}
  1443  
  1444  	err = initOrderer.OverrideConfig(configOverride.(OrdererConfig))
  1445  	if err != nil {
  1446  		return err
  1447  	}
  1448  
  1449  	if instance.IsHSMEnabled() && !instance.UsingHSMProxy() {
  1450  		log.Info(fmt.Sprintf("During orderer '%s' migration, detected using HSM sidecar, setting library path", instance.GetName()))
  1451  		hsmConfig, err := commonconfig.ReadHSMConfig(n.Client, instance)
  1452  		if err != nil {
  1453  			return err
  1454  		}
  1455  		initOrderer.Config.SetBCCSPLibrary(filepath.Join("/hsm/lib", filepath.Base(hsmConfig.Library.FilePath)))
  1456  	}
  1457  
  1458  	err = n.Initializer.CreateOrUpdateConfigMap(instance, initOrderer.GetConfig())
  1459  	if err != nil {
  1460  		return err
  1461  	}
  1462  
  1463  	return nil
  1464  }
  1465  
  1466  func (n *Node) FabricOrdererMigrationV2_4(instance *current.IBPOrderer) error {
  1467  	log.Info(fmt.Sprintf("Orderer instance '%s' migrating to v2.4.x", instance.GetName()))
  1468  
  1469  	initOrderer, err := n.Initializer.GetInitOrderer(instance, n.GetInitStoragePath(instance))
  1470  	if err != nil {
  1471  		return err
  1472  	}
  1473  
  1474  	ordererConfig, err := v24ordererconfig.ReadOrdererFile(n.Config.OrdererInitConfig.OrdererV24File)
  1475  	if err != nil {
  1476  		return errors.Wrap(err, "failed to read v2.4.x default config file")
  1477  	}
  1478  
  1479  	// removed the field from the struct
  1480  	// ordererConfig.FileLedger.Prefix = ""
  1481  
  1482  	name := fmt.Sprintf("%s-env", instance.GetName())
  1483  	namespacedName := types.NamespacedName{
  1484  		Name:      name,
  1485  		Namespace: instance.Namespace,
  1486  	}
  1487  
  1488  	cm := &corev1.ConfigMap{}
  1489  	err = n.Client.Get(context.TODO(), namespacedName, cm)
  1490  	if err != nil {
  1491  		return errors.Wrap(err, "failed to get env configmap")
  1492  	}
  1493  
  1494  	// Add configs for 2.4.x
  1495  	trueVal := true
  1496  	ordererConfig.Admin.TLs.Enabled = &trueVal
  1497  	ordererConfig.Admin.TLs.ClientAuthRequired = &trueVal
  1498  
  1499  	intermediateExists := util.IntermediateSecretExists(n.Client, instance.Namespace, fmt.Sprintf("ecert-%s-intercerts", instance.Name)) &&
  1500  		util.IntermediateSecretExists(n.Client, instance.Namespace, fmt.Sprintf("tls-%s-intercerts", instance.Name))
  1501  	intercertPath := "/certs/msp/tlsintermediatecerts/intercert-0.pem"
  1502  	currentVer := version.String(instance.Spec.FabricVersion)
  1503  	if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
  1504  		// Enable Channel participation for 2.4.x orderers
  1505  		cm.Data["ORDERER_CHANNELPARTICIPATION_ENABLED"] = "true"
  1506  
  1507  		cm.Data["ORDERER_ADMIN_TLS_ENABLED"] = "true"
  1508  		cm.Data["ORDERER_ADMIN_TLS_CERTIFICATE"] = "/certs/tls/signcerts/cert.pem"
  1509  		cm.Data["ORDERER_ADMIN_TLS_PRIVATEKEY"] = "/certs/tls/keystore/key.pem"
  1510  		cm.Data["ORDERER_ADMIN_TLS_CLIENTAUTHREQUIRED"] = "true"
  1511  		if intermediateExists {
  1512  			// override intermediate cert paths for root and clientroot cas
  1513  			cm.Data["ORDERER_ADMIN_TLS_ROOTCAS"] = intercertPath
  1514  			cm.Data["ORDERER_ADMIN_TLS_CLIENTROOTCAS"] = intercertPath
  1515  		} else {
  1516  			cm.Data["ORDERER_ADMIN_TLS_ROOTCAS"] = "/certs/msp/tlscacerts/cacert-0.pem"
  1517  			cm.Data["ORDERER_ADMIN_TLS_CLIENTROOTCAS"] = "/certs/msp/tlscacerts/cacert-0.pem"
  1518  		}
  1519  	}
  1520  
  1521  	err = n.Client.Update(context.TODO(), cm, controllerclient.UpdateOption{Owner: instance, Scheme: n.Scheme})
  1522  	if err != nil {
  1523  		return errors.Wrap(err, "failed to update env configmap")
  1524  	}
  1525  
  1526  	initOrderer.Config = ordererConfig
  1527  	configOverride, err := instance.GetConfigOverride()
  1528  	if err != nil {
  1529  		return err
  1530  	}
  1531  
  1532  	err = initOrderer.OverrideConfig(configOverride.(OrdererConfig))
  1533  	if err != nil {
  1534  		return err
  1535  	}
  1536  
  1537  	if instance.IsHSMEnabled() && !instance.UsingHSMProxy() {
  1538  		log.Info(fmt.Sprintf("During orderer '%s' migration, detected using HSM sidecar, setting library path", instance.GetName()))
  1539  		hsmConfig, err := commonconfig.ReadHSMConfig(n.Client, instance)
  1540  		if err != nil {
  1541  			return err
  1542  		}
  1543  		initOrderer.Config.SetBCCSPLibrary(filepath.Join("/hsm/lib", filepath.Base(hsmConfig.Library.FilePath)))
  1544  	}
  1545  
  1546  	err = n.Initializer.CreateOrUpdateConfigMap(instance, initOrderer.GetConfig())
  1547  	if err != nil {
  1548  		return err
  1549  	}
  1550  	return nil
  1551  }
  1552  
  1553  func (n *Node) ReconcileHSMImages(instance *current.IBPOrderer) bool {
  1554  	hsmConfig, err := commonconfig.ReadHSMConfig(n.Client, instance)
  1555  	if err != nil {
  1556  		return false
  1557  	}
  1558  
  1559  	if hsmConfig.Library.AutoUpdateDisabled {
  1560  		return false
  1561  	}
  1562  
  1563  	updated := false
  1564  	if hsmConfig.Library.Image != "" {
  1565  		hsmImage := hsmConfig.Library.Image
  1566  		lastIndex := strings.LastIndex(hsmImage, ":")
  1567  		image := hsmImage[:lastIndex]
  1568  		tag := hsmImage[lastIndex+1:]
  1569  
  1570  		if instance.Spec.Images.HSMImage != image {
  1571  			instance.Spec.Images.HSMImage = image
  1572  			updated = true
  1573  		}
  1574  
  1575  		if instance.Spec.Images.HSMTag != tag {
  1576  			instance.Spec.Images.HSMTag = tag
  1577  			updated = true
  1578  		}
  1579  	}
  1580  
  1581  	return updated
  1582  }
  1583  
  1584  func (n *Node) HandleActions(instance *current.IBPOrderer, update Update) error {
  1585  	orig := instance.DeepCopy()
  1586  
  1587  	if update.EcertReenrollNeeded() {
  1588  		if err := n.ReenrollEcert(instance); err != nil {
  1589  			log.Error(err, "Resetting action flag on failure")
  1590  			instance.ResetEcertReenroll()
  1591  			return err
  1592  		}
  1593  		instance.ResetEcertReenroll()
  1594  	}
  1595  
  1596  	if update.TLScertReenrollNeeded() {
  1597  		if err := n.ReenrollTLSCert(instance); err != nil {
  1598  			log.Error(err, "Resetting action flag on failure")
  1599  			instance.ResetTLSReenroll()
  1600  			return err
  1601  		}
  1602  		instance.ResetTLSReenroll()
  1603  	}
  1604  
  1605  	if update.EcertNewKeyReenroll() {
  1606  		if err := n.ReenrollEcertNewKey(instance); err != nil {
  1607  			log.Error(err, "Resetting action flag on failure")
  1608  			instance.ResetEcertReenroll()
  1609  			return err
  1610  		}
  1611  		instance.ResetEcertReenroll()
  1612  	}
  1613  
  1614  	if update.TLScertNewKeyReenroll() {
  1615  		if err := n.ReenrollTLSCertNewKey(instance); err != nil {
  1616  			log.Error(err, "Resetting action flag on failure")
  1617  			instance.ResetTLSReenroll()
  1618  			return err
  1619  		}
  1620  		instance.ResetTLSReenroll()
  1621  	}
  1622  
  1623  	if update.EcertEnroll() {
  1624  		if err := n.EnrollForEcert(instance); err != nil {
  1625  			log.Error(err, "Resetting action flag on failure")
  1626  			instance.ResetEcertEnroll()
  1627  			return err
  1628  		}
  1629  		instance.ResetEcertEnroll()
  1630  	}
  1631  
  1632  	if update.TLScertEnroll() {
  1633  		if err := n.EnrollForTLSCert(instance); err != nil {
  1634  			log.Error(err, "Resetting action flag on failure")
  1635  			instance.ResetTLSEnroll()
  1636  			return err
  1637  		}
  1638  		instance.ResetTLSEnroll()
  1639  	}
  1640  
  1641  	// This should be the last action checked
  1642  	if update.RestartNeeded() {
  1643  		if err := n.RestartAction(instance); err != nil {
  1644  			log.Error(err, "Resetting action flag on failure")
  1645  			instance.ResetRestart()
  1646  			return err
  1647  		}
  1648  		instance.ResetRestart()
  1649  	}
  1650  
  1651  	if err := n.Client.Patch(context.TODO(), instance, k8sclient.MergeFrom(orig)); err != nil {
  1652  		return errors.Wrap(err, "failed to reset action flags")
  1653  	}
  1654  
  1655  	return nil
  1656  }
  1657  
  1658  func (n *Node) ReenrollEcert(instance *current.IBPOrderer) error {
  1659  	log.Info("Ecert reenroll triggered via action parameter")
  1660  	if err := n.reenrollCert(instance, commoninit.ECERT, false); err != nil {
  1661  		return errors.Wrap(err, "ecert reenroll reusing existing private key action failed")
  1662  	}
  1663  	return nil
  1664  }
  1665  
  1666  func (n *Node) ReenrollEcertNewKey(instance *current.IBPOrderer) error {
  1667  	log.Info("Ecert with new key reenroll triggered via action parameter")
  1668  	if err := n.reenrollCert(instance, commoninit.ECERT, true); err != nil {
  1669  		return errors.Wrap(err, "ecert reenroll with new key action failed")
  1670  	}
  1671  	return nil
  1672  }
  1673  
  1674  func (n *Node) ReenrollTLSCert(instance *current.IBPOrderer) error {
  1675  	log.Info("TLS reenroll triggered via action parameter")
  1676  	if err := n.reenrollCert(instance, commoninit.TLS, false); err != nil {
  1677  		return errors.Wrap(err, "tls reenroll reusing existing private key action failed")
  1678  	}
  1679  	return nil
  1680  }
  1681  
  1682  func (n *Node) ReenrollTLSCertNewKey(instance *current.IBPOrderer) error {
  1683  	log.Info("TLS with new key reenroll triggered via action parameter")
  1684  	if err := n.reenrollCert(instance, commoninit.TLS, true); err != nil {
  1685  		return errors.Wrap(err, "tls reenroll with new key action failed")
  1686  	}
  1687  	return nil
  1688  }
  1689  
  1690  func (n *Node) reenrollCert(instance *current.IBPOrderer, certType commoninit.SecretType, newKey bool) error {
  1691  	return action.Reenroll(n, n.Client, certType, instance, newKey)
  1692  }
  1693  
  1694  func (n *Node) RestartAction(instance *current.IBPOrderer) error {
  1695  	log.Info("Restart triggered via action parameter")
  1696  	if err := n.Restart.ForRestartAction(instance); err != nil {
  1697  		return errors.Wrap(err, "failed to restart orderer node pods")
  1698  	}
  1699  	return nil
  1700  }
  1701  
  1702  func (n *Node) HandleRestart(instance *current.IBPOrderer, update Update) error {
  1703  	// If restart is disabled for components, can return immediately
  1704  	if n.Config.Operator.Restart.Disable.Components {
  1705  		return nil
  1706  	}
  1707  
  1708  	err := n.Restart.TriggerIfNeeded(instance)
  1709  	if err != nil {
  1710  		return errors.Wrap(err, "failed to restart deployment")
  1711  	}
  1712  
  1713  	return nil
  1714  }
  1715  
  1716  func (n *Node) CustomLogic(instance *current.IBPOrderer, update Update) (*current.CRStatus, *common.Result, error) {
  1717  	var status *current.CRStatus
  1718  	var err error
  1719  	return status, nil, err
  1720  }