github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/k8s/orderer/orderer.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 k8sorderer
    20  
    21  import (
    22  	"fmt"
    23  
    24  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    25  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    26  	k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient"
    27  	baseorderer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/orderer"
    28  	baseordereroverride "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/orderer/override"
    29  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/common"
    30  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/k8s/orderer/override"
    31  	"github.com/IBM-Blockchain/fabric-operator/version"
    32  	"github.com/pkg/errors"
    33  	"k8s.io/apimachinery/pkg/runtime"
    34  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    35  	"sigs.k8s.io/controller-runtime/pkg/reconcile"
    36  )
    37  
    38  var log = logf.Log.WithName("k8s_orderer")
    39  
    40  const (
    41  	defaultOrdererNode = "./definitions/orderer/orderernode.yaml"
    42  )
    43  
    44  type Orderer struct {
    45  	*baseorderer.Orderer
    46  }
    47  
    48  func New(client k8sclient.Client, scheme *runtime.Scheme, config *config.Config) *Orderer {
    49  	o := &override.Override{
    50  		Override: baseordereroverride.Override{
    51  			Client: client,
    52  			Config: config,
    53  		},
    54  	}
    55  
    56  	orderer := &Orderer{
    57  		Orderer: baseorderer.New(client, scheme, config, o),
    58  	}
    59  
    60  	return orderer
    61  }
    62  
    63  func (o *Orderer) Reconcile(instance *current.IBPOrderer, update baseorderer.Update) (common.Result, error) {
    64  	var err error
    65  
    66  	if instance.Spec.NodeNumber == nil {
    67  		log.Info(fmt.Sprintf("Reconciling cluster instance '%s' ... update: %+v", instance.Name, update))
    68  
    69  		versionSet, err := o.SetVersion(instance)
    70  		if err != nil {
    71  			return common.Result{}, errors.Wrap(err, fmt.Sprintf("failed updating CR '%s' to version '%s'", instance.Name, version.Operator))
    72  		}
    73  		if versionSet {
    74  			log.Info("Instance version updated, requeuing request...")
    75  			return common.Result{
    76  				Result: reconcile.Result{
    77  					Requeue: true,
    78  				},
    79  			}, nil
    80  		}
    81  
    82  		if instance.Status.Status == "" || instance.Status.Status == current.False || (instance.Status.Version != "" && version.String(instance.Status.Version).GreaterThan(version.V210)) {
    83  			instanceUpdated, err := o.PreReconcileChecks(instance, update)
    84  			if err != nil {
    85  				return common.Result{}, errors.Wrap(err, "failed pre reconcile checks")
    86  			}
    87  
    88  			if instanceUpdated {
    89  				log.Info("Instance updated, requeuing request...")
    90  				return common.Result{
    91  					Result: reconcile.Result{
    92  						Requeue: true,
    93  					},
    94  					OverrideUpdateStatus: true,
    95  				}, nil
    96  			}
    97  		}
    98  	}
    99  
   100  	// TODO: Major rehaul is needed of versioning and migration strategy. Need a way to
   101  	// migrate as first step to get CR spec in appropriate state to avoid versioning checks
   102  	// like below and above
   103  	if (instance.Status.Version == "" && instance.Status.Status == current.True) || (instance.Status.Version != "" && version.String(instance.Status.Version).Equal(version.V210)) {
   104  		if instance.Spec.NodeNumber == nil {
   105  			number := 1
   106  			instance.Spec.NodeNumber = &number
   107  		}
   108  	}
   109  
   110  	var result common.Result
   111  	if instance.Spec.NodeNumber == nil {
   112  		result, err := o.ReconcileCluster(instance, update, o.AddHostPortToProfile)
   113  		if err != nil {
   114  			return common.Result{}, errors.Wrap(err, "failed to reconcile cluster")
   115  		}
   116  
   117  		return result, nil
   118  	}
   119  
   120  	result, err = o.ReconcileNode(instance, update)
   121  	if err != nil {
   122  		return common.Result{}, errors.Wrap(err, "failed to reconcile node")
   123  	}
   124  
   125  	return result, nil
   126  }
   127  
   128  func (o *Orderer) ReconcileNode(instance *current.IBPOrderer, update baseorderer.Update) (common.Result, error) {
   129  	var err error
   130  
   131  	hostAPI := fmt.Sprintf("%s-%s-orderer.%s", instance.Namespace, instance.Name, instance.Spec.Domain)
   132  	hostOperations := fmt.Sprintf("%s-%s-operations.%s", instance.Namespace, instance.Name, instance.Spec.Domain)
   133  	hostGrpc := fmt.Sprintf("%s-%s-grpcweb.%s", instance.Namespace, instance.Name, instance.Spec.Domain)
   134  	hosts := []string{}
   135  	currentVer := version.String(instance.Spec.FabricVersion)
   136  	if currentVer.EqualWithoutTag(version.V2_4_1) || currentVer.GreaterThan(version.V2_4_1) {
   137  		hostAdmin := fmt.Sprintf("%s-%s-admin.%s", instance.Namespace, instance.Name, instance.Spec.Domain)
   138  		hosts = append(hosts, hostAPI, hostOperations, hostGrpc, hostAdmin, "127.0.0.1")
   139  		//TODO: need to Re-enroll when orderer migrated from 1.4.x/2.2.x to 2.4.1
   140  	} else {
   141  		hosts = append(hosts, hostAPI, hostOperations, hostGrpc, "127.0.0.1")
   142  	}
   143  
   144  	o.CheckCSRHosts(instance, hosts)
   145  
   146  	k8snode := NewNode(baseorderer.NewNode(o.Client, o.Scheme, o.Config, instance.GetName(), o.RenewCertTimers, o.RestartManager))
   147  
   148  	log.Info(fmt.Sprintf("Reconciling Orderer node %s", instance.GetName()))
   149  	if !instance.Spec.IsUsingChannelLess() && instance.Spec.GenesisBlock == "" && !(instance.Spec.IsPrecreateOrderer()) {
   150  		return common.Result{}, fmt.Errorf("Genesis block not provided for orderer node: %s", instance.GetName())
   151  	}
   152  
   153  	result, err := k8snode.Reconcile(instance, update)
   154  	if err != nil {
   155  		return result, err
   156  	}
   157  	return result, nil
   158  }
   159  
   160  func (o *Orderer) GetNodes(instance *current.IBPOrderer) []*Node {
   161  	size := instance.Spec.ClusterSize
   162  	nodes := []*Node{}
   163  	for i := 1; i <= size; i++ {
   164  		node := o.GetNode(i)
   165  		nodes = append(nodes, node)
   166  	}
   167  	return nodes
   168  }
   169  
   170  func (o *Orderer) GetNode(nodeNumber int) *Node {
   171  	basenode := o.NodeManager.GetNode(nodeNumber, o.RenewCertTimers, o.RestartManager)
   172  	return NewNode(basenode)
   173  }