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  }