github.com/deemoprobe/k8s-first-commit@v0.0.0-20230430165612-a541f1982be3/pkg/cloudcfg/cloudcfg.go (about) 1 /* 2 Copyright 2014 Google Inc. All rights reserved. 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 cloudcfg is ... 18 package cloudcfg 19 20 import ( 21 "bytes" 22 "crypto/tls" 23 "encoding/json" 24 "fmt" 25 "io/ioutil" 26 "log" 27 "net/http" 28 "os" 29 "strconv" 30 "strings" 31 "time" 32 33 "github.com/GoogleCloudPlatform/kubernetes/pkg/api" 34 "github.com/GoogleCloudPlatform/kubernetes/pkg/client" 35 "gopkg.in/v1/yaml" 36 ) 37 38 func promptForString(field string) string { 39 fmt.Printf("Please enter %s: ", field) 40 var result string 41 fmt.Scan(&result) 42 return result 43 } 44 45 // Parse an AuthInfo object from a file path 46 func LoadAuthInfo(path string) (client.AuthInfo, error) { 47 var auth client.AuthInfo 48 if _, err := os.Stat(path); os.IsNotExist(err) { 49 auth.User = promptForString("Username") 50 auth.Password = promptForString("Password") 51 data, err := json.Marshal(auth) 52 if err != nil { 53 return auth, err 54 } 55 err = ioutil.WriteFile(path, data, 0600) 56 return auth, err 57 } 58 data, err := ioutil.ReadFile(path) 59 if err != nil { 60 return auth, err 61 } 62 err = json.Unmarshal(data, &auth) 63 return auth, err 64 } 65 66 // Perform a rolling update of a collection of tasks. 67 // 'name' points to a replication controller. 68 // 'client' is used for updating tasks. 69 // 'updatePeriod' is the time between task updates. 70 func Update(name string, client client.ClientInterface, updatePeriod time.Duration) error { 71 controller, err := client.GetReplicationController(name) 72 if err != nil { 73 return err 74 } 75 labels := controller.DesiredState.ReplicasInSet 76 77 taskList, err := client.ListTasks(labels) 78 if err != nil { 79 return err 80 } 81 for _, task := range taskList.Items { 82 _, err = client.UpdateTask(task) 83 if err != nil { 84 return err 85 } 86 time.Sleep(updatePeriod) 87 } 88 return nil 89 } 90 91 // RequestWithBody is a helper method that creates an HTTP request with the specified url, method 92 // and a body read from 'configFile' 93 // FIXME: need to be public API? 94 func RequestWithBody(configFile, url, method string) (*http.Request, error) { 95 if len(configFile) == 0 { 96 return nil, fmt.Errorf("empty config file.") 97 } 98 data, err := ioutil.ReadFile(configFile) 99 if err != nil { 100 return nil, err 101 } 102 return RequestWithBodyData(data, url, method) 103 } 104 105 // RequestWithBodyData is a helper method that creates an HTTP request with the specified url, method 106 // and body data 107 // FIXME: need to be public API? 108 func RequestWithBodyData(data []byte, url, method string) (*http.Request, error) { 109 request, err := http.NewRequest(method, url, bytes.NewBuffer(data)) 110 request.ContentLength = int64(len(data)) 111 return request, err 112 } 113 114 // Execute a request, adds authentication, and HTTPS cert ignoring. 115 // TODO: Make this stuff optional 116 // FIXME: need to be public API? 117 func DoRequest(request *http.Request, user, password string) (string, error) { 118 request.SetBasicAuth(user, password) 119 tr := &http.Transport{ 120 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 121 } 122 client := &http.Client{Transport: tr} 123 response, err := client.Do(request) 124 if err != nil { 125 return "", err 126 } 127 defer response.Body.Close() 128 body, err := ioutil.ReadAll(response.Body) 129 return string(body), err 130 } 131 132 // StopController stops a controller named 'name' by setting replicas to zero 133 func StopController(name string, client client.ClientInterface) error { 134 controller, err := client.GetReplicationController(name) 135 if err != nil { 136 return err 137 } 138 controller.DesiredState.Replicas = 0 139 controllerOut, err := client.UpdateReplicationController(controller) 140 if err != nil { 141 return err 142 } 143 data, err := yaml.Marshal(controllerOut) 144 if err != nil { 145 return err 146 } 147 fmt.Print(string(data)) 148 return nil 149 } 150 151 func makePorts(spec string) []api.Port { 152 parts := strings.Split(spec, ",") 153 var result []api.Port 154 for _, part := range parts { 155 pieces := strings.Split(part, ":") 156 if len(pieces) != 2 { 157 log.Printf("Bad port spec: %s", part) 158 continue 159 } 160 host, err := strconv.Atoi(pieces[0]) 161 if err != nil { 162 log.Printf("Host part is not integer: %s %v", pieces[0], err) 163 continue 164 } 165 container, err := strconv.Atoi(pieces[1]) 166 if err != nil { 167 log.Printf("Container part is not integer: %s %v", pieces[1], err) 168 continue 169 } 170 result = append(result, api.Port{ContainerPort: container, HostPort: host}) 171 } 172 return result 173 } 174 175 // RunController creates a new replication controller named 'name' which creates 'replicas' tasks running 'image' 176 func RunController(image, name string, replicas int, client client.ClientInterface, portSpec string, servicePort int) error { 177 controller := api.ReplicationController{ 178 JSONBase: api.JSONBase{ 179 ID: name, 180 }, 181 DesiredState: api.ReplicationControllerState{ 182 Replicas: replicas, 183 ReplicasInSet: map[string]string{ 184 "name": name, 185 }, 186 TaskTemplate: api.TaskTemplate{ 187 DesiredState: api.TaskState{ 188 Manifest: api.ContainerManifest{ 189 Containers: []api.Container{ 190 api.Container{ 191 Image: image, 192 Ports: makePorts(portSpec), 193 }, 194 }, 195 }, 196 }, 197 Labels: map[string]string{ 198 "name": name, 199 }, 200 }, 201 }, 202 Labels: map[string]string{ 203 "name": name, 204 }, 205 } 206 207 controllerOut, err := client.CreateReplicationController(controller) 208 if err != nil { 209 return err 210 } 211 data, err := yaml.Marshal(controllerOut) 212 if err != nil { 213 return err 214 } 215 fmt.Print(string(data)) 216 217 if servicePort > 0 { 218 svc, err := createService(name, servicePort, client) 219 if err != nil { 220 return err 221 } 222 data, err = yaml.Marshal(svc) 223 if err != nil { 224 return err 225 } 226 fmt.Printf(string(data)) 227 } 228 return nil 229 } 230 231 func createService(name string, port int, client client.ClientInterface) (api.Service, error) { 232 svc := api.Service{ 233 JSONBase: api.JSONBase{ID: name}, 234 Port: port, 235 Labels: map[string]string{ 236 "name": name, 237 }, 238 } 239 svc, err := client.CreateService(svc) 240 return svc, err 241 } 242 243 // DeleteController deletes a replication controller named 'name', requires that the controller 244 // already be stopped 245 func DeleteController(name string, client client.ClientInterface) error { 246 controller, err := client.GetReplicationController(name) 247 if err != nil { 248 return err 249 } 250 if controller.DesiredState.Replicas != 0 { 251 return fmt.Errorf("controller has non-zero replicas (%d)", controller.DesiredState.Replicas) 252 } 253 return client.DeleteReplicationController(name) 254 }