github.com/cactusblossom/fabric-ca@v0.0.0-20200611062428-0082fc643826/lib/metadata/version.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package metadata
     8  
     9  import (
    10  	"fmt"
    11  	"runtime"
    12  	"strconv"
    13  	"strings"
    14  
    15  	db "github.com/hyperledger/fabric-ca/lib/server/db/util"
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  // Current levels which are incremented each time there is a change which
    20  // requires database migration
    21  const (
    22  	// IdentityLevel is the current level of identities
    23  	IdentityLevel = 2
    24  	// AffiliationLevel is the current level of affiliations
    25  	AffiliationLevel = 1
    26  	// CertificateLevel is the current level of certificates
    27  	CertificateLevel = 1
    28  )
    29  
    30  // Version specifies fabric-ca-client/fabric-ca-server version
    31  // It is defined by the Makefile and passed in with ldflags
    32  var Version = "1.4.7"
    33  
    34  // GetVersionInfo returns version information for the fabric-ca-client/fabric-ca-server
    35  func GetVersionInfo(prgName string) string {
    36  	if Version == "" {
    37  		Version = "development build"
    38  	}
    39  
    40  	return fmt.Sprintf("%s:\n Version: %s\n Go version: %s\n OS/Arch: %s\n",
    41  		prgName, Version, runtime.Version(),
    42  		fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH))
    43  }
    44  
    45  // GetVersion returns the version
    46  func GetVersion() string {
    47  	if Version == "" {
    48  		panic("Version is not set for fabric-ca library")
    49  	}
    50  	return Version
    51  }
    52  
    53  // Mapping of versions to levels.
    54  // NOTE: Append new versions to this array if migration is
    55  // required for identity, affiliation, or certificate information.
    56  var versionToLevelsMapping = []versionLevels{
    57  	{
    58  		version: "0",
    59  		levels:  &db.Levels{Identity: 0, Affiliation: 0, Certificate: 0},
    60  	},
    61  	{
    62  		version: "1.1.0",
    63  		levels:  &db.Levels{Identity: 1, Affiliation: 1, Certificate: 1},
    64  	},
    65  	{
    66  		version: "1.2.0",
    67  		levels:  &db.Levels{Identity: 1, Affiliation: 1, Certificate: 1, Credential: 1, RAInfo: 1, Nonce: 1},
    68  	},
    69  	{
    70  		version: "1.3.0",
    71  		levels:  &db.Levels{Identity: 1, Affiliation: 1, Certificate: 1, Credential: 1, RAInfo: 1, Nonce: 1},
    72  	},
    73  	{
    74  		version: "1.3.1",
    75  		levels:  &db.Levels{Identity: 2, Affiliation: 1, Certificate: 1, Credential: 1, RAInfo: 1, Nonce: 1},
    76  	},
    77  	{
    78  		version: "1.4.0",
    79  		levels:  &db.Levels{Identity: 2, Affiliation: 1, Certificate: 1, Credential: 1, RAInfo: 1, Nonce: 1},
    80  	},
    81  }
    82  
    83  type versionLevels struct {
    84  	version string
    85  	levels  *db.Levels
    86  }
    87  
    88  // GetLevels returns the levels for a particular version
    89  func GetLevels(version string) (*db.Levels, error) {
    90  	for i := len(versionToLevelsMapping) - 1; i >= 0; i-- {
    91  		vl := versionToLevelsMapping[i]
    92  		cmp, err := CmpVersion(vl.version, version)
    93  		if err != nil {
    94  			return nil, err
    95  		}
    96  		if cmp >= 0 {
    97  			return vl.levels, nil
    98  		}
    99  	}
   100  	return nil, nil
   101  }
   102  
   103  // CmpVersion compares version v1 to v2.
   104  // Return 0 if equal, 1 if v2 > v1, or -1 if v2 < v1.
   105  func CmpVersion(v1, v2 string) (int, error) {
   106  	v1strs := strs(v1)
   107  	v2strs := strs(v2)
   108  	m := max(len(v1strs), len(v2strs))
   109  	for i := 0; i < m; i++ {
   110  		v1val, err := val(v1strs, i)
   111  		if err != nil {
   112  			return 0, errors.WithMessage(err, fmt.Sprintf("Invalid version: '%s'", v1))
   113  		}
   114  		v2val, err := val(v2strs, i)
   115  		if err != nil {
   116  			return 0, errors.WithMessage(err, fmt.Sprintf("Invalid version: '%s'", v2))
   117  		}
   118  		if v1val < v2val {
   119  			return 1, nil
   120  		} else if v1val > v2val {
   121  			return -1, nil
   122  		}
   123  	}
   124  	return 0, nil
   125  }
   126  
   127  func strs(version string) []string {
   128  	return strings.Split(strings.Split(version, "-")[0], ".")
   129  }
   130  
   131  func max(a, b int) int {
   132  	if a > b {
   133  		return a
   134  	}
   135  	return b
   136  }
   137  
   138  func val(strs []string, i int) (int, error) {
   139  	if i >= len(strs) {
   140  		return 0, nil
   141  	}
   142  	str := strs[i]
   143  	v, err := strconv.Atoi(str)
   144  	if err != nil {
   145  		return 0, errors.WithMessage(err, fmt.Sprintf("Invalid version format at '%s'", str))
   146  	}
   147  	return v, nil
   148  }