github.com/deemoprobe/k8s-first-commit@v0.0.0-20230430165612-a541f1982be3/pkg/client/client.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 // A client for the Kubernetes cluster management API 18 // There are three fundamental objects 19 // Task - A single running container 20 // TaskForce - A set of co-scheduled Task(s) 21 // ReplicationController - A manager for replicating TaskForces 22 package client 23 24 import ( 25 "bytes" 26 "crypto/tls" 27 "encoding/json" 28 "fmt" 29 "io" 30 "io/ioutil" 31 "log" 32 "net/http" 33 "net/url" 34 "strings" 35 36 "github.com/GoogleCloudPlatform/kubernetes/pkg/api" 37 ) 38 39 // ClientInterface holds the methods for clients of Kubenetes, an interface to allow mock testing 40 type ClientInterface interface { 41 ListTasks(labelQuery map[string]string) (api.TaskList, error) 42 GetTask(name string) (api.Task, error) 43 DeleteTask(name string) error 44 CreateTask(api.Task) (api.Task, error) 45 UpdateTask(api.Task) (api.Task, error) 46 47 GetReplicationController(name string) (api.ReplicationController, error) 48 CreateReplicationController(api.ReplicationController) (api.ReplicationController, error) 49 UpdateReplicationController(api.ReplicationController) (api.ReplicationController, error) 50 DeleteReplicationController(string) error 51 52 GetService(name string) (api.Service, error) 53 CreateService(api.Service) (api.Service, error) 54 UpdateService(api.Service) (api.Service, error) 55 DeleteService(string) error 56 } 57 58 // AuthInfo is used to store authorization information 59 type AuthInfo struct { 60 User string 61 Password string 62 } 63 64 // Client is the actual implementation of a Kubernetes client. 65 // Host is the http://... base for the URL 66 type Client struct { 67 Host string 68 Auth *AuthInfo 69 httpClient *http.Client 70 } 71 72 // Underlying base implementation of performing a request. 73 // method is the HTTP method (e.g. "GET") 74 // path is the path on the host to hit 75 // requestBody is the body of the request. Can be nil. 76 // target the interface to marshal the JSON response into. Can be nil. 77 func (client Client) rawRequest(method, path string, requestBody io.Reader, target interface{}) ([]byte, error) { 78 request, err := http.NewRequest(method, client.makeURL(path), requestBody) 79 if err != nil { 80 return []byte{}, err 81 } 82 if client.Auth != nil { 83 request.SetBasicAuth(client.Auth.User, client.Auth.Password) 84 } 85 tr := &http.Transport{ 86 TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 87 } 88 var httpClient *http.Client 89 if client.httpClient != nil { 90 httpClient = client.httpClient 91 } else { 92 httpClient = &http.Client{Transport: tr} 93 } 94 response, err := httpClient.Do(request) 95 if err != nil { 96 return nil, err 97 } 98 if response.StatusCode != 200 { 99 return nil, fmt.Errorf("request [%s %s] failed (%d) %s", method, client.makeURL(path), response.StatusCode, response.Status) 100 } 101 defer response.Body.Close() 102 body, err := ioutil.ReadAll(response.Body) 103 if err != nil { 104 return body, err 105 } 106 if target != nil { 107 err = json.Unmarshal(body, target) 108 } 109 if err != nil { 110 log.Printf("Failed to parse: %s\n", string(body)) 111 // FIXME: no need to return err here? 112 } 113 return body, err 114 } 115 116 func (client Client) makeURL(path string) string { 117 return client.Host + "/api/v1beta1/" + path 118 } 119 120 func EncodeLabelQuery(labelQuery map[string]string) string { 121 query := make([]string, 0, len(labelQuery)) 122 for key, value := range labelQuery { 123 query = append(query, key+"="+value) 124 } 125 return url.QueryEscape(strings.Join(query, ",")) 126 } 127 128 func DecodeLabelQuery(labelQuery string) map[string]string { 129 result := map[string]string{} 130 if len(labelQuery) == 0 { 131 return result 132 } 133 parts := strings.Split(labelQuery, ",") 134 for _, part := range parts { 135 pieces := strings.Split(part, "=") 136 if len(pieces) == 2 { 137 result[pieces[0]] = pieces[1] 138 } else { 139 log.Printf("Invalid label query: %s", labelQuery) 140 } 141 } 142 return result 143 } 144 145 // ListTasks takes a label query, and returns the list of tasks that match that query 146 func (client Client) ListTasks(labelQuery map[string]string) (api.TaskList, error) { 147 path := "tasks" 148 if labelQuery != nil && len(labelQuery) > 0 { 149 path += "?labels=" + EncodeLabelQuery(labelQuery) 150 } 151 var result api.TaskList 152 _, err := client.rawRequest("GET", path, nil, &result) 153 return result, err 154 } 155 156 // GetTask takes the name of the task, and returns the corresponding Task object, and an error if it occurs 157 func (client Client) GetTask(name string) (api.Task, error) { 158 var result api.Task 159 _, err := client.rawRequest("GET", "tasks/"+name, nil, &result) 160 return result, err 161 } 162 163 // DeleteTask takes the name of the task, and returns an error if one occurs 164 func (client Client) DeleteTask(name string) error { 165 _, err := client.rawRequest("DELETE", "tasks/"+name, nil, nil) 166 return err 167 } 168 169 // CreateTask takes the representation of a task. Returns the server's representation of the task, and an error, if it occurs 170 func (client Client) CreateTask(task api.Task) (api.Task, error) { 171 var result api.Task 172 body, err := json.Marshal(task) 173 if err == nil { 174 _, err = client.rawRequest("POST", "tasks", bytes.NewBuffer(body), &result) 175 } 176 return result, err 177 } 178 179 // UpdateTask takes the representation of a task to update. Returns the server's representation of the task, and an error, if it occurs 180 func (client Client) UpdateTask(task api.Task) (api.Task, error) { 181 var result api.Task 182 body, err := json.Marshal(task) 183 if err == nil { 184 _, err = client.rawRequest("PUT", "tasks/"+task.ID, bytes.NewBuffer(body), &result) 185 } 186 return result, err 187 } 188 189 // GetReplicationController returns information about a particular replication controller 190 func (client Client) GetReplicationController(name string) (api.ReplicationController, error) { 191 var result api.ReplicationController 192 _, err := client.rawRequest("GET", "replicationControllers/"+name, nil, &result) 193 return result, err 194 } 195 196 // CreateReplicationController creates a new replication controller 197 func (client Client) CreateReplicationController(controller api.ReplicationController) (api.ReplicationController, error) { 198 var result api.ReplicationController 199 body, err := json.Marshal(controller) 200 if err == nil { 201 _, err = client.rawRequest("POST", "replicationControllers", bytes.NewBuffer(body), &result) 202 } 203 return result, err 204 } 205 206 // UpdateReplicationController updates an existing replication controller 207 func (client Client) UpdateReplicationController(controller api.ReplicationController) (api.ReplicationController, error) { 208 var result api.ReplicationController 209 body, err := json.Marshal(controller) 210 if err == nil { 211 _, err = client.rawRequest("PUT", "replicationControllers/"+controller.ID, bytes.NewBuffer(body), &result) 212 } 213 return result, err 214 } 215 216 func (client Client) DeleteReplicationController(name string) error { 217 _, err := client.rawRequest("DELETE", "replicationControllers/"+name, nil, nil) 218 return err 219 } 220 221 // GetReplicationController returns information about a particular replication controller 222 func (client Client) GetService(name string) (api.Service, error) { 223 var result api.Service 224 _, err := client.rawRequest("GET", "services/"+name, nil, &result) 225 return result, err 226 } 227 228 // CreateReplicationController creates a new replication controller 229 func (client Client) CreateService(svc api.Service) (api.Service, error) { 230 var result api.Service 231 body, err := json.Marshal(svc) 232 if err == nil { 233 _, err = client.rawRequest("POST", "services", bytes.NewBuffer(body), &result) 234 } 235 return result, err 236 } 237 238 // UpdateReplicationController updates an existing replication controller 239 func (client Client) UpdateService(svc api.Service) (api.Service, error) { 240 var result api.Service 241 body, err := json.Marshal(svc) 242 if err == nil { 243 _, err = client.rawRequest("PUT", "services/"+svc.ID, bytes.NewBuffer(body), &result) 244 } 245 return result, err 246 } 247 248 func (client Client) DeleteService(name string) error { 249 _, err := client.rawRequest("DELETE", "services/"+name, nil, nil) 250 return err 251 }