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 }