github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/common/reconcilechecks/images/images.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 images
    20  
    21  import (
    22  	"encoding/json"
    23  	"fmt"
    24  	"strings"
    25  
    26  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/apis/deployer"
    28  
    29  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    30  )
    31  
    32  var log = logf.Log.WithName("image_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  // Image handles checks and defaults on versions of images
    54  type Image struct {
    55  	Versions           *deployer.Versions
    56  	DefaultRegistryURL string
    57  	DefaultArch        string
    58  }
    59  
    60  // SetDefaults sets defaults on instance based on fabric version
    61  func (i *Image) SetDefaults(instance Instance) error {
    62  	if !strings.Contains(instance.GetFabricVersion(), "-") {
    63  		return fmt.Errorf("fabric version format '%s' is not valid, must pass hyphenated version (e.g. 2.2.1-1)", instance.GetFabricVersion())
    64  	}
    65  
    66  	arch := i.DefaultArch
    67  	if len(instance.GetArch()) > 0 {
    68  		arch = instance.GetArch()[0]
    69  	}
    70  
    71  	registryURL := i.DefaultRegistryURL
    72  	if instance.GetRegistryURL() != "" {
    73  		registryURL = instance.GetRegistryURL()
    74  	}
    75  
    76  	// Add '/' at the end if not present in registry URL
    77  	if registryURL != "" && !strings.HasSuffix(registryURL, "/") {
    78  		registryURL = registryURL + "/"
    79  	}
    80  
    81  	switch instance.(type) {
    82  	case *current.IBPCA:
    83  		return setDefaultCAImages(instance.(*current.IBPCA), arch, registryURL, i.Versions.CA)
    84  	case *current.IBPPeer:
    85  		return setDefaultPeerImages(instance.(*current.IBPPeer), arch, registryURL, i.Versions.Peer)
    86  	case *current.IBPOrderer:
    87  		return setDefaultOrdererImages(instance.(*current.IBPOrderer), arch, registryURL, i.Versions.Orderer)
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  // UpdateRequired process update events to determine if images needed to be updated.
    94  func (i *Image) UpdateRequired(update Update) bool {
    95  	if update.ImagesUpdated() {
    96  		return false
    97  	}
    98  
    99  	// If neither fabric version nor images updated or both fabric version and images updated, return since no changes
   100  	// made or required
   101  	if !update.ImagesUpdated() && !update.FabricVersionUpdated() {
   102  		return false
   103  	}
   104  
   105  	if update.FabricVersionUpdated() {
   106  		return true
   107  	}
   108  
   109  	return false
   110  }
   111  
   112  func normalizeFabricVersion(fabricVersion string, versions interface{}) string {
   113  	switch versions.(type) {
   114  	case map[string]deployer.VersionCA:
   115  		if !strings.Contains(fabricVersion, "-") {
   116  			for version, config := range versions.(map[string]deployer.VersionCA) {
   117  				if strings.HasPrefix(version, fabricVersion) && config.Default {
   118  					return version
   119  				}
   120  			}
   121  		}
   122  	case map[string]deployer.VersionPeer:
   123  		if !strings.Contains(fabricVersion, "-") {
   124  			for version, config := range versions.(map[string]deployer.VersionPeer) {
   125  				if strings.HasPrefix(version, fabricVersion) && config.Default {
   126  					return version
   127  				}
   128  			}
   129  		}
   130  	case map[string]deployer.VersionOrderer:
   131  		if !strings.Contains(fabricVersion, "-") {
   132  			for version, config := range versions.(map[string]deployer.VersionOrderer) {
   133  				if strings.HasPrefix(version, fabricVersion) && config.Default {
   134  					return version
   135  				}
   136  			}
   137  		}
   138  	}
   139  
   140  	return fabricVersion
   141  }
   142  
   143  func setDefaultCAImages(instance *current.IBPCA, arch, registryURL string, versions map[string]deployer.VersionCA) error {
   144  	fabricVersion := instance.Spec.FabricVersion
   145  	log.Info(fmt.Sprintf("Using default images for instance '%s' for fabric version '%s'", instance.GetName(), fabricVersion))
   146  
   147  	version, found := versions[fabricVersion]
   148  	if !found {
   149  		return fmt.Errorf("no default CA images defined for fabric version '%s'", fabricVersion)
   150  	}
   151  
   152  	version.Image.Override(nil, registryURL, arch)
   153  	specVersions := &current.CAImages{}
   154  	versionBytes, err := json.Marshal(version.Image)
   155  	if err != nil {
   156  		return err
   157  	}
   158  	err = json.Unmarshal(versionBytes, specVersions)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	instance.Spec.Images = specVersions
   163  
   164  	return nil
   165  }
   166  
   167  func setDefaultPeerImages(instance *current.IBPPeer, arch, registryURL string, versions map[string]deployer.VersionPeer) error {
   168  	fabricVersion := instance.Spec.FabricVersion
   169  	log.Info(fmt.Sprintf("Using default images for instance '%s' for fabric version '%s'", instance.GetName(), fabricVersion))
   170  
   171  	version, found := versions[fabricVersion]
   172  	if !found {
   173  		return fmt.Errorf("no default Peer images defined for fabric version '%s'", fabricVersion)
   174  	}
   175  
   176  	version.Image.Override(nil, registryURL, arch)
   177  	specVersions := &current.PeerImages{}
   178  	versionBytes, err := json.Marshal(version.Image)
   179  	if err != nil {
   180  		return err
   181  	}
   182  	err = json.Unmarshal(versionBytes, specVersions)
   183  	if err != nil {
   184  		return err
   185  	}
   186  	instance.Spec.Images = specVersions
   187  
   188  	return nil
   189  }
   190  
   191  func setDefaultOrdererImages(instance *current.IBPOrderer, arch, registryURL string, versions map[string]deployer.VersionOrderer) error {
   192  	fabricVersion := instance.Spec.FabricVersion
   193  	log.Info(fmt.Sprintf("Using default images for instance '%s' for fabric version '%s'", instance.GetName(), fabricVersion))
   194  
   195  	version, found := versions[fabricVersion]
   196  	if !found {
   197  		return fmt.Errorf("no default Orderer images defined for fabric version '%s'", fabricVersion)
   198  	}
   199  
   200  	version.Image.Override(nil, registryURL, arch)
   201  
   202  	specVersions := &current.OrdererImages{}
   203  	versionBytes, err := json.Marshal(version.Image)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	err = json.Unmarshal(versionBytes, specVersions)
   208  	if err != nil {
   209  		return err
   210  	}
   211  	instance.Spec.Images = specVersions
   212  
   213  	return nil
   214  }