github.com/jenkins-x/test-infra@v0.0.7/kubetest/util.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "io" 23 "io/ioutil" 24 "log" 25 "net/http" 26 "os" 27 "os/exec" 28 "strings" 29 "time" 30 ) 31 32 var httpTransport *http.Transport 33 34 func init() { 35 httpTransport = new(http.Transport) 36 httpTransport.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) 37 } 38 39 // Essentially curl url | writer 40 func httpRead(url string, writer io.Writer) error { 41 log.Printf("curl %s", url) 42 c := &http.Client{Transport: httpTransport} 43 r, err := c.Get(url) 44 if err != nil { 45 return err 46 } 47 defer r.Body.Close() 48 if r.StatusCode >= 400 { 49 return fmt.Errorf("%v returned %d", url, r.StatusCode) 50 } 51 _, err = io.Copy(writer, r.Body) 52 if err != nil { 53 return err 54 } 55 return nil 56 } 57 58 type instanceGroup struct { 59 Name string `json:"name"` 60 CreationTimestamp string `json:"creationTimestamp"` 61 } 62 63 // getLatestClusterUpTime returns latest created instanceGroup timestamp from gcloud parsing results 64 func getLatestClusterUpTime(gcloudJSON string) (time.Time, error) { 65 igs := []instanceGroup{} 66 if err := json.Unmarshal([]byte(gcloudJSON), &igs); err != nil { 67 return time.Time{}, fmt.Errorf("error when unmarshal json: %v", err) 68 } 69 70 latest := time.Time{} 71 72 for _, ig := range igs { 73 created, err := time.Parse(time.RFC3339, ig.CreationTimestamp) 74 if err != nil { 75 return time.Time{}, fmt.Errorf("error when parse time from %s: %v", ig.CreationTimestamp, err) 76 } 77 78 if created.After(latest) { 79 latest = created 80 } 81 } 82 83 // this returns time.Time{} if no ig exists, which will always force a new cluster 84 return latest, nil 85 } 86 87 // (only works on gke) 88 // getLatestGKEVersion will return newest validMasterVersions. 89 // Pass in releasePrefix to get latest valid version of a specific release. 90 // Empty releasePrefix means use latest across all available releases. 91 func getLatestGKEVersion(project, zone, region, releasePrefix string) (string, error) { 92 cmd := []string{ 93 "container", 94 "get-server-config", 95 fmt.Sprintf("--project=%v", project), 96 "--format=value(validMasterVersions)", 97 } 98 99 // --gkeCommandGroup is from gke.go 100 if *gkeCommandGroup != "" { 101 cmd = append([]string{*gkeCommandGroup}, cmd...) 102 } 103 104 // zone can be empty for regional cluster 105 if zone != "" { 106 cmd = append(cmd, fmt.Sprintf("--zone=%v", zone)) 107 } else if region != "" { 108 cmd = append(cmd, fmt.Sprintf("--region=%v", region)) 109 } 110 111 res, err := control.Output(exec.Command("gcloud", cmd...)) 112 if err != nil { 113 return "", err 114 } 115 versions := strings.Split(strings.TrimSpace(string(res)), ";") 116 latestValid := "" 117 for _, version := range versions { 118 if strings.HasPrefix(version, releasePrefix) { 119 latestValid = version 120 break 121 } 122 } 123 if latestValid == "" { 124 return "", fmt.Errorf("cannot find valid gke release %s version from: %s", releasePrefix, string(res)) 125 } 126 return "v" + latestValid, nil 127 } 128 129 // gcsWrite uploads contents to the dest location in GCS. 130 // It currently shells out to gsutil, but this could change in future. 131 func gcsWrite(dest string, contents []byte) error { 132 f, err := ioutil.TempFile("", "") 133 if err != nil { 134 return fmt.Errorf("error creating temp file: %v", err) 135 } 136 137 defer func() { 138 if err := os.Remove(f.Name()); err != nil { 139 log.Printf("error removing temp file: %v", err) 140 } 141 }() 142 143 if _, err := f.Write(contents); err != nil { 144 return fmt.Errorf("error writing temp file: %v", err) 145 } 146 147 if err := f.Close(); err != nil { 148 return fmt.Errorf("error closing temp file: %v", err) 149 } 150 151 return control.FinishRunning(exec.Command("gsutil", "cp", f.Name(), dest)) 152 }