github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/integration/helpers/version.go (about) 1 package helpers 2 3 import ( 4 "crypto/tls" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os" 10 "strconv" 11 "strings" 12 "sync" 13 14 "code.cloudfoundry.org/cli/actor/versioncheck" 15 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/gexec" 19 ) 20 21 func IsVersionMet(minVersion string) bool { 22 version := matchMajorAPIVersion(minVersion) 23 ok, err := versioncheck.IsMinimumAPIVersionMet(version, minVersion) 24 Expect(err).ToNot(HaveOccurred()) 25 26 return ok 27 } 28 29 type UAAVersion struct { 30 App struct { 31 Version string `json:"version"` 32 } `json:"app"` 33 } 34 35 func (v UAAVersion) Version() string { 36 return v.App.Version 37 } 38 39 func IsUAAVersionAtLeast(minVersion string) bool { 40 info := fetchAPIVersion() 41 uaaUrl := fmt.Sprintf("%s/info", info.Links.UAA.Href) 42 tr := &http.Transport{ 43 TLSClientConfig: &tls.Config{InsecureSkipVerify: skipSSLValidation()}, 44 } 45 req, err := http.NewRequest("GET", uaaUrl, nil) 46 Expect(err).ToNot(HaveOccurred()) 47 req.Header.Add("Accept", "application/json") 48 client := &http.Client{Transport: tr} 49 resp, err := client.Do(req) 50 Expect(err).ToNot(HaveOccurred()) 51 52 defer resp.Body.Close() 53 54 if resp.StatusCode == http.StatusOK { 55 bodyBytes, err2 := ioutil.ReadAll(resp.Body) 56 Expect(err2).ToNot(HaveOccurred()) 57 58 version := &UAAVersion{} 59 60 err3 := json.Unmarshal(bodyBytes, &version) 61 Expect(err3).ToNot(HaveOccurred()) 62 currentUaaVersion := version.Version() 63 ok, err := versioncheck.IsMinimumAPIVersionMet(currentUaaVersion, minVersion) 64 Expect(err).ToNot(HaveOccurred()) 65 return ok 66 } 67 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 68 return false 69 } 70 71 func SkipIfUAAVersionLessThan(version string) { 72 if !IsUAAVersionAtLeast(version) { 73 Skip(fmt.Sprintf("Test requires UAA version at least %s", version)) 74 } 75 } 76 77 func SkipIfUAAVersionAtLeast(version string) { 78 if IsUAAVersionAtLeast(version) { 79 Skip(fmt.Sprintf("Test requires UAA version less than %s", version)) 80 } 81 } 82 83 func matchMajorAPIVersion(minVersion string) string { 84 version := GetAPIVersionV2() 85 if strings.HasPrefix(minVersion, "3") { 86 version = getAPIVersionV3() 87 } 88 return version 89 } 90 91 func GetAPIVersionV2() string { 92 return fetchAPIVersion().Links.CloudContollerV2.Meta.Version 93 } 94 95 func SkipIfVersionLessThan(minVersion string) { 96 if ignoreAPIVersion() { 97 return 98 } 99 100 version := matchMajorAPIVersion(minVersion) 101 if !IsVersionMet(minVersion) { 102 Skip(fmt.Sprintf("minimum version %s not met by API version %s", minVersion, version)) 103 } 104 } 105 106 func SkipIfVersionAtLeast(maxVersion string) { 107 version := matchMajorAPIVersion(maxVersion) 108 109 if IsVersionMet(maxVersion) { 110 Skip(fmt.Sprintf("maximum version %s exceeded by API version %s", maxVersion, version)) 111 } 112 } 113 114 func ignoreAPIVersion() bool { 115 ignoreEnv := os.Getenv("CF_INT_IGNORE_API_VERSION_CHECK") 116 if ignoreEnv == "" { 117 return false 118 } 119 120 ignoreBool, err := strconv.ParseBool(ignoreEnv) 121 return ignoreBool || err != nil 122 } 123 124 type ccRoot struct { 125 Links struct { 126 CloudContollerV2 struct { 127 Meta struct { 128 Version string 129 } 130 } `json:"cloud_controller_v2"` 131 132 CloudContollerV3 struct { 133 Meta struct { 134 Version string 135 } 136 } `json:"cloud_controller_v3"` 137 138 UAA struct { 139 Href string `json:"href"` 140 } `json:"uaa"` 141 } `json:"links"` 142 } 143 144 var cacheLock sync.Mutex 145 var CcRootCache *ccRoot 146 147 func fetchAPIVersion() ccRoot { 148 cacheLock.Lock() 149 defer cacheLock.Unlock() 150 if CcRootCache == nil { 151 session := CF("curl", "/") 152 Eventually(session).Should(Exit(0)) 153 var result ccRoot 154 err := json.Unmarshal(session.Out.Contents(), &result) 155 Expect(err).ToNot(HaveOccurred()) 156 CcRootCache = &result 157 } 158 return *CcRootCache 159 } 160 161 func getAPIVersionV3() string { 162 return fetchAPIVersion().Links.CloudContollerV3.Meta.Version 163 } 164 165 func SkipIfNoRoutingAPI() { 166 // TODO: #161159794 remove this function and check a nicer error message when available 167 var response struct { 168 RoutingEndpoint string `json:"routing_endpoint"` 169 } 170 Curl(&response, "/v2/info") 171 172 if response.RoutingEndpoint == "" { 173 Skip("Test requires routing endpoint on /v2/info") 174 } 175 }