github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/common/reconcilechecks/fabricversion.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 reconcilechecks
    20  
    21  import (
    22  	"errors"
    23  	"fmt"
    24  
    25  	"github.com/IBM-Blockchain/fabric-operator/pkg/apis/deployer"
    26  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/common/reconcilechecks/images"
    27  	"github.com/IBM-Blockchain/fabric-operator/version"
    28  
    29  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    30  )
    31  
    32  var log = logf.Log.WithName("reconcile_checks")
    33  
    34  //go:generate counterfeiter -o mocks/instance.go -fake-name Instance . Instance
    35  
    36  // Instance is an instance of an IBP custom resource
    37  type Instance interface {
    38  	GetArch() []string
    39  	GetRegistryURL() string
    40  	GetFabricVersion() string
    41  	SetFabricVersion(string)
    42  	ImagesSet() bool
    43  }
    44  
    45  //go:generate counterfeiter -o mocks/update.go -fake-name Update . Update
    46  
    47  // Update defines update events we are interested in
    48  type Update interface {
    49  	ImagesUpdated() bool
    50  	FabricVersionUpdated() bool
    51  }
    52  
    53  // FabricVersionHelper is a helper function meant to be consumed by the different controllers to handle
    54  // events on fabric version and images in specs
    55  func FabricVersionHelper(instance Instance, versions *deployer.Versions, update Update) (bool, error) {
    56  	image := &images.Image{
    57  		Versions: versions,
    58  		// DefaultRegistryURL: "hyperledger", // changing default for OSS
    59  		DefaultArch: "amd64",
    60  	}
    61  
    62  	fv := &images.FabricVersion{
    63  		Versions: versions,
    64  	}
    65  
    66  	return FabricVersion(instance, update, image, fv)
    67  }
    68  
    69  //go:generate counterfeiter -o mocks/image.go -fake-name Image . Image
    70  // Image defines the contract with the image checks
    71  type Image interface {
    72  	UpdateRequired(images.Update) bool
    73  	SetDefaults(images.Instance) error
    74  }
    75  
    76  //go:generate counterfeiter -o mocks/version.go -fake-name Version . Version
    77  // Version defines the contract with the version checks
    78  type Version interface {
    79  	Normalize(images.FabricVersionInstance) string
    80  	Validate(images.FabricVersionInstance) error
    81  }
    82  
    83  // FabricVersion is a lower-level call that requires all dependencies to be injected to handle
    84  // events on fabric version and images in specs. It returns back two values, the first return
    85  // value indicates if a spec change has been made. The second return value returns an error.
    86  func FabricVersion(instance Instance, update Update, image Image, fv Version) (bool, error) {
    87  	var requeue bool
    88  
    89  	fabricVersion := instance.GetFabricVersion()
    90  	if fabricVersion == "" {
    91  		return false, errors.New("fabric version is not set")
    92  	}
    93  
    94  	// If fabric version is changed EXCEPT during migration, or images section is blank, then
    95  	// lookup default images associated with fabric version and update images in instance's spec
    96  	if update.FabricVersionUpdated() {
    97  
    98  		// If fabric version update is triggered by migration of operator, then no changes required
    99  		if version.IsMigratedFabricVersion(instance.GetFabricVersion()) {
   100  			return false, nil
   101  		}
   102  
   103  		log.Info(fmt.Sprintf("Images to be updated, fabric version changed, new fabric version is '%s'", fabricVersion))
   104  	}
   105  
   106  	if !instance.ImagesSet() {
   107  		log.Info(fmt.Sprintf("Images missing, setting to default images based on fabric version '%s'", fabricVersion))
   108  	}
   109  
   110  	// If images set, need to do further processing to determine if images need to be updated (overriden) based on events
   111  	// detected on fabric version
   112  	if instance.ImagesSet() {
   113  		required := image.UpdateRequired(update)
   114  
   115  		if !required {
   116  			return false, nil
   117  		}
   118  	}
   119  
   120  	// Normalize version to x.x.x-x
   121  	normalizedVersion := fv.Normalize(instance)
   122  	if instance.GetFabricVersion() != normalizedVersion {
   123  		instance.SetFabricVersion(normalizedVersion)
   124  		requeue = true
   125  	}
   126  
   127  	if err := fv.Validate(instance); err != nil {
   128  		return false, err
   129  	}
   130  
   131  	if err := image.SetDefaults(instance); err != nil {
   132  		return false, err
   133  	}
   134  	requeue = true
   135  
   136  	return requeue, nil
   137  }