2014-06-06 23:40:48 +00:00
/ *
Copyright 2014 Google Inc . All rights reserved .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2014-06-23 18:32:11 +00:00
2014-06-06 23:40:48 +00:00
package main
import (
"flag"
"fmt"
2014-06-12 20:41:48 +00:00
"io/ioutil"
2014-09-08 18:25:49 +00:00
"net/http"
2014-06-06 23:40:48 +00:00
"os"
2014-07-25 19:28:20 +00:00
"reflect"
2014-07-23 00:25:06 +00:00
"sort"
2014-06-06 23:40:48 +00:00
"strconv"
2014-06-12 21:13:02 +00:00
"strings"
2014-07-15 04:13:06 +00:00
"text/template"
2014-06-06 23:40:48 +00:00
"time"
2014-08-01 21:14:33 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
2014-09-11 17:02:53 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
2014-08-28 13:56:38 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
2014-06-26 00:55:43 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg"
2014-09-02 17:55:27 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
2014-06-25 03:51:57 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
2014-07-25 19:28:20 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/version"
2014-08-30 06:19:32 +00:00
"github.com/GoogleCloudPlatform/kubernetes/pkg/version/verflag"
2014-06-25 03:51:57 +00:00
"github.com/golang/glog"
2014-06-06 23:40:48 +00:00
)
2014-06-07 21:06:28 +00:00
var (
Uniformize handling of -server_version flag of kubecfg to match -version.
In particular, add support for -server_version=raw and use matching
format for the output of -version and -server_version.
The "normal" format is essentially defined by (version.Info) String()
method, so future updates to that method will be reflected on both.
Full version information is still available by using the "raw" flag.
Tested:
- Used cluster/kubecfg.sh to query local build and the server.
$ cluster/kubecfg.sh -version
Kubernetes version 0.2+, build 9316edfc0d2b28923fbb6eafa38458350859f926
$ cluster/kubecfg.sh -server_version
Server: Kubernetes version 0.2, build a0abb3815755d6a77eed2d07bb0aa7d255e4e769
$ cluster/kubecfg.sh -version=raw
version.Info{Major:"0", Minor:"2+", GitVersion:"v0.2-25-g9316edfc0d2b28", GitCommit:"9316edfc0d2b28923fbb6eafa38458350859f926", GitTreeState:"clean"}
$ cluster/kubecfg.sh -server_version=raw
version.Info{Major:"0", Minor:"2", GitVersion:"v0.2", GitCommit:"a0abb3815755d6a77eed2d07bb0aa7d255e4e769", GitTreeState:"clean"}
Fixes: #1092
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
2014-09-09 21:28:43 +00:00
serverVersion = verflag . Version ( "server_version" , verflag . VersionFalse , "Print the server's version information and quit" )
2014-07-25 19:28:20 +00:00
preventSkew = flag . Bool ( "expect_version_match" , false , "Fail if server's version doesn't match own version." )
2014-09-20 14:54:42 +00:00
config = flag . String ( "c" , "" , "Path or URL to the config file, or '-' to read from STDIN" )
2014-07-25 19:28:20 +00:00
selector = flag . String ( "l" , "" , "Selector (label query) to use for listing" )
updatePeriod = flag . Duration ( "u" , 60 * time . Second , "Update interval period" )
portSpec = flag . String ( "p" , "" , "The port spec, comma-separated list of <external>:<internal>,..." )
servicePort = flag . Int ( "s" , - 1 , "If positive, create and run a corresponding service on this port, only used with 'run'" )
authConfig = flag . String ( "auth" , os . Getenv ( "HOME" ) + "/.kubernetes_auth" , "Path to the auth info file. If missing, prompt the user. Only used if doing https." )
json = flag . Bool ( "json" , false , "If true, print raw JSON for responses" )
yaml = flag . Bool ( "yaml" , false , "If true, print raw YAML for responses" )
verbose = flag . Bool ( "verbose" , false , "If true, print extra information" )
proxy = flag . Bool ( "proxy" , false , "If true, run a proxy to the api server" )
www = flag . String ( "www" , "" , "If -proxy is true, use this directory to serve static files" )
templateFile = flag . String ( "template_file" , "" , "If present, load this file as a golang template and use it for output printing" )
templateStr = flag . String ( "template" , "" , "If present, parse this string as a golang template and use it for output printing" )
2014-08-20 05:16:53 +00:00
imageName = flag . String ( "image" , "" , "Image used when updating a replicationController. Will apply to the first container in the pod template." )
2014-09-30 00:15:00 +00:00
clientConfig = & client . Config { }
2014-06-07 21:06:28 +00:00
)
2014-06-06 23:40:48 +00:00
2014-09-30 00:15:00 +00:00
func init ( ) {
flag . StringVar ( & clientConfig . Host , "h" , "" , "The host to connect to." )
flag . StringVar ( & clientConfig . Version , "api_version" , latest . Version , "The version of the API to use against this server." )
flag . StringVar ( & clientConfig . CAFile , "certificate_authority" , "" , "Path to a cert. file for the certificate authority" )
flag . StringVar ( & clientConfig . CertFile , "client_certificate" , "" , "Path to a client certificate for TLS." )
flag . StringVar ( & clientConfig . KeyFile , "client_key" , "" , "Path to a client key file for TLS." )
2014-10-02 14:25:09 +00:00
flag . BoolVar ( & clientConfig . Insecure , "insecure_skip_tls_verify" , clientConfig . Insecure , "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure." )
2014-09-30 00:15:00 +00:00
}
2014-09-08 04:14:18 +00:00
var parser = kubecfg . NewParser ( map [ string ] runtime . Object {
"pods" : & api . Pod { } ,
"services" : & api . Service { } ,
"replicationControllers" : & api . ReplicationController { } ,
"minions" : & api . Minion { } ,
2014-08-13 22:10:02 +00:00
} )
2014-06-06 23:40:48 +00:00
func usage ( ) {
2014-09-20 14:54:42 +00:00
fmt . Fprintf ( os . Stderr , ` Usage : kubecfg - h [ - c config / file . json | url | - ] < method >
2014-09-03 03:47:15 +00:00
Kubernetes REST API :
2014-06-11 22:08:23 +00:00
2014-07-23 00:25:06 +00:00
kubecfg [ OPTIONS ] get | list | create | delete | update < % s > [ / < id > ]
2014-06-11 22:08:23 +00:00
2014-09-03 03:47:15 +00:00
Manage replication controllers :
2014-08-20 05:16:53 +00:00
kubecfg [ OPTIONS ] stop | rm < controller >
2014-09-03 03:47:15 +00:00
kubecfg [ OPTIONS ] [ - u < time > ] [ - image < image > ] rollingupdate < controller >
2014-06-26 00:55:43 +00:00
kubecfg [ OPTIONS ] resize < controller > < replicas >
2014-06-11 22:08:23 +00:00
2014-09-03 03:47:15 +00:00
Launch a simple ReplicationController with a single container based
on the given image :
2014-08-20 05:16:53 +00:00
kubecfg [ OPTIONS ] [ - p < port spec > ] run < image > < replicas > < controller >
2014-09-03 03:47:15 +00:00
Options :
2014-07-23 00:25:06 +00:00
` , prettyWireStorage ( ) )
2014-06-11 22:08:23 +00:00
flag . PrintDefaults ( )
2014-08-13 22:10:02 +00:00
2014-06-06 23:40:48 +00:00
}
2014-07-23 00:25:06 +00:00
func prettyWireStorage ( ) string {
2014-08-13 22:10:02 +00:00
types := parser . SupportedWireStorage ( )
2014-07-23 00:25:06 +00:00
sort . Strings ( types )
return strings . Join ( types , "|" )
}
2014-09-08 18:25:49 +00:00
// readConfigData reads the bytes from the specified filesytem or network location associated with the *config flag
func readConfigData ( ) [ ] byte {
2014-09-20 14:54:42 +00:00
// read from STDIN
if * config == "-" {
data , err := ioutil . ReadAll ( os . Stdin )
if err != nil {
glog . Fatalf ( "Unable to read from STDIN: %v\n" , err )
}
return data
}
2014-09-08 18:25:49 +00:00
// we look for http:// or https:// to determine if valid URL, otherwise do normal file IO
if strings . Index ( * config , "http://" ) == 0 || strings . Index ( * config , "https://" ) == 0 {
resp , err := http . Get ( * config )
if err != nil {
glog . Fatalf ( "Unable to access URL %v: %v\n" , * config , err )
}
defer resp . Body . Close ( )
if resp . StatusCode != 200 {
glog . Fatalf ( "Unable to read URL, server reported %d %s" , resp . StatusCode , resp . Status )
}
data , err := ioutil . ReadAll ( resp . Body )
if err != nil {
glog . Fatalf ( "Unable to read URL %v: %v\n" , * config , err )
}
return data
}
2014-09-20 14:54:42 +00:00
data , err := ioutil . ReadFile ( * config )
if err != nil {
glog . Fatalf ( "Unable to read %v: %v\n" , * config , err )
}
return data
2014-09-08 18:25:49 +00:00
}
2014-07-20 15:36:20 +00:00
// readConfig reads and parses pod, replicationController, and service
// configuration files. If any errors log and exit non-zero.
2014-09-11 23:01:29 +00:00
func readConfig ( storage string , serverCodec runtime . Codec ) [ ] byte {
2014-06-12 20:41:48 +00:00
if len ( * config ) == 0 {
2014-06-25 03:51:57 +00:00
glog . Fatal ( "Need config file (-c)" )
2014-06-12 20:41:48 +00:00
}
2014-09-08 18:25:49 +00:00
2014-09-11 23:01:29 +00:00
data , err := parser . ToWireFormat ( readConfigData ( ) , storage , latest . Codec , serverCodec )
2014-09-08 18:25:49 +00:00
2014-06-12 20:41:48 +00:00
if err != nil {
2014-07-01 02:45:00 +00:00
glog . Fatalf ( "Error parsing %v as an object for %v: %v\n" , * config , storage , err )
2014-06-12 20:41:48 +00:00
}
2014-06-16 03:53:21 +00:00
if * verbose {
2014-06-25 03:51:57 +00:00
glog . Infof ( "Parsed config file successfully; sending:\n%v\n" , string ( data ) )
2014-06-16 03:53:21 +00:00
}
2014-06-12 20:41:48 +00:00
return data
}
2014-06-06 23:40:48 +00:00
func main ( ) {
2014-06-11 22:08:23 +00:00
flag . Usage = func ( ) {
usage ( )
}
2014-07-20 15:36:20 +00:00
flag . Parse ( )
2014-06-25 03:51:57 +00:00
util . InitLogs ( )
defer util . FlushLogs ( )
2014-06-06 23:40:48 +00:00
2014-08-01 05:55:44 +00:00
verflag . PrintAndExitIfRequested ( )
2014-06-06 23:40:48 +00:00
2014-09-30 00:15:00 +00:00
// Initialize the client
if clientConfig . Host == "" {
clientConfig . Host = os . Getenv ( "KUBERNETES_MASTER" )
2014-06-28 05:48:32 +00:00
}
2014-09-30 18:27:19 +00:00
// TODO: get the namespace context when kubecfg ns is completed
2014-10-02 16:51:36 +00:00
ctx := api . NewContext ( )
2014-09-30 18:27:19 +00:00
2014-09-30 00:15:00 +00:00
if clientConfig . Host == "" {
// TODO: eventually apiserver should start on 443 and be secure by default
clientConfig . Host = "http://localhost:8080"
2014-06-12 01:13:25 +00:00
}
2014-09-30 00:15:00 +00:00
if client . IsConfigTransportSecure ( clientConfig ) {
2014-08-28 13:56:38 +00:00
auth , err := kubecfg . LoadAuthInfo ( * authConfig , os . Stdin )
2014-06-12 01:13:25 +00:00
if err != nil {
2014-07-01 02:45:00 +00:00
glog . Fatalf ( "Error loading auth: %v" , err )
2014-06-12 01:13:25 +00:00
}
2014-09-30 00:15:00 +00:00
clientConfig . Username = auth . User
clientConfig . Password = auth . Password
2014-10-02 00:10:07 +00:00
if auth . CAFile != "" {
clientConfig . CAFile = auth . CAFile
}
if auth . CertFile != "" {
clientConfig . CertFile = auth . CertFile
}
if auth . KeyFile != "" {
clientConfig . KeyFile = auth . KeyFile
}
2014-10-02 14:25:09 +00:00
if auth . Insecure != nil {
clientConfig . Insecure = * auth . Insecure
}
2014-09-30 00:15:00 +00:00
}
kubeClient , err := client . New ( clientConfig )
if err != nil {
glog . Fatalf ( "Can't configure client: %v" , err )
2014-06-06 23:40:48 +00:00
}
Uniformize handling of -server_version flag of kubecfg to match -version.
In particular, add support for -server_version=raw and use matching
format for the output of -version and -server_version.
The "normal" format is essentially defined by (version.Info) String()
method, so future updates to that method will be reflected on both.
Full version information is still available by using the "raw" flag.
Tested:
- Used cluster/kubecfg.sh to query local build and the server.
$ cluster/kubecfg.sh -version
Kubernetes version 0.2+, build 9316edfc0d2b28923fbb6eafa38458350859f926
$ cluster/kubecfg.sh -server_version
Server: Kubernetes version 0.2, build a0abb3815755d6a77eed2d07bb0aa7d255e4e769
$ cluster/kubecfg.sh -version=raw
version.Info{Major:"0", Minor:"2+", GitVersion:"v0.2-25-g9316edfc0d2b28", GitCommit:"9316edfc0d2b28923fbb6eafa38458350859f926", GitTreeState:"clean"}
$ cluster/kubecfg.sh -server_version=raw
version.Info{Major:"0", Minor:"2", GitVersion:"v0.2", GitCommit:"a0abb3815755d6a77eed2d07bb0aa7d255e4e769", GitTreeState:"clean"}
Fixes: #1092
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
2014-09-09 21:28:43 +00:00
if * serverVersion != verflag . VersionFalse {
2014-08-28 13:56:38 +00:00
got , err := kubeClient . ServerVersion ( )
2014-07-25 19:28:20 +00:00
if err != nil {
fmt . Printf ( "Couldn't read version from server: %v\n" , err )
os . Exit ( 1 )
}
Uniformize handling of -server_version flag of kubecfg to match -version.
In particular, add support for -server_version=raw and use matching
format for the output of -version and -server_version.
The "normal" format is essentially defined by (version.Info) String()
method, so future updates to that method will be reflected on both.
Full version information is still available by using the "raw" flag.
Tested:
- Used cluster/kubecfg.sh to query local build and the server.
$ cluster/kubecfg.sh -version
Kubernetes version 0.2+, build 9316edfc0d2b28923fbb6eafa38458350859f926
$ cluster/kubecfg.sh -server_version
Server: Kubernetes version 0.2, build a0abb3815755d6a77eed2d07bb0aa7d255e4e769
$ cluster/kubecfg.sh -version=raw
version.Info{Major:"0", Minor:"2+", GitVersion:"v0.2-25-g9316edfc0d2b28", GitCommit:"9316edfc0d2b28923fbb6eafa38458350859f926", GitTreeState:"clean"}
$ cluster/kubecfg.sh -server_version=raw
version.Info{Major:"0", Minor:"2", GitVersion:"v0.2", GitCommit:"a0abb3815755d6a77eed2d07bb0aa7d255e4e769", GitTreeState:"clean"}
Fixes: #1092
Signed-off-by: Filipe Brandenburger <filbranden@google.com>
2014-09-09 21:28:43 +00:00
if * serverVersion == verflag . VersionRaw {
fmt . Printf ( "%#v\n" , * got )
os . Exit ( 0 )
} else {
fmt . Printf ( "Server: Kubernetes %s\n" , got )
os . Exit ( 0 )
}
2014-07-25 19:28:20 +00:00
}
if * preventSkew {
2014-08-28 13:56:38 +00:00
got , err := kubeClient . ServerVersion ( )
2014-07-25 19:28:20 +00:00
if err != nil {
fmt . Printf ( "Couldn't read version from server: %v\n" , err )
os . Exit ( 1 )
}
if c , s := version . Get ( ) , * got ; ! reflect . DeepEqual ( c , s ) {
fmt . Printf ( "Server version (%#v) differs from client version (%#v)!\n" , s , c )
os . Exit ( 1 )
}
}
2014-06-24 02:57:54 +00:00
if * proxy {
2014-06-25 03:51:57 +00:00
glog . Info ( "Starting to serve on localhost:8001" )
2014-08-28 13:56:38 +00:00
server := kubecfg . NewProxyServer ( * www , kubeClient )
2014-06-25 03:51:57 +00:00
glog . Fatal ( server . Serve ( ) )
2014-06-24 02:57:54 +00:00
}
2014-06-24 05:18:14 +00:00
if len ( flag . Args ( ) ) < 1 {
usage ( )
os . Exit ( 1 )
}
method := flag . Arg ( 0 )
2014-10-02 16:51:36 +00:00
matchFound := executeAPIRequest ( ctx , method , kubeClient ) || executeControllerRequest ( ctx , method , kubeClient )
2014-06-11 22:08:23 +00:00
if matchFound == false {
2014-06-25 03:51:57 +00:00
glog . Fatalf ( "Unknown command %s" , method )
2014-06-11 22:08:23 +00:00
}
}
2014-07-23 15:16:41 +00:00
// storagePathFromArg normalizes a path and breaks out the first segment if available
func storagePathFromArg ( arg string ) ( storage , path string , hasSuffix bool ) {
path = strings . Trim ( arg , "/" )
segments := strings . SplitN ( path , "/" , 2 )
storage = segments [ 0 ]
if len ( segments ) > 1 && segments [ 1 ] != "" {
hasSuffix = true
}
return storage , path , hasSuffix
}
//checkStorage returns true if the provided storage is valid
func checkStorage ( storage string ) bool {
2014-08-13 22:10:02 +00:00
for _ , allowed := range parser . SupportedWireStorage ( ) {
2014-07-23 15:16:41 +00:00
if allowed == storage {
return true
}
2014-06-11 22:08:23 +00:00
}
2014-07-23 15:16:41 +00:00
return false
}
2014-06-11 22:08:23 +00:00
2014-09-27 03:35:12 +00:00
func getPrinter ( ) kubecfg . ResourcePrinter {
var printer kubecfg . ResourcePrinter
switch {
case * json :
printer = & kubecfg . IdentityPrinter { }
case * yaml :
printer = & kubecfg . YAMLPrinter { }
case len ( * templateFile ) > 0 || len ( * templateStr ) > 0 :
var data [ ] byte
if len ( * templateFile ) > 0 {
var err error
data , err = ioutil . ReadFile ( * templateFile )
if err != nil {
glog . Fatalf ( "Error reading template %s, %v\n" , * templateFile , err )
return nil
}
} else {
data = [ ] byte ( * templateStr )
}
tmpl , err := template . New ( "output" ) . Parse ( string ( data ) )
if err != nil {
glog . Fatalf ( "Error parsing template %s, %v\n" , string ( data ) , err )
return nil
}
printer = & kubecfg . TemplatePrinter {
Template : tmpl ,
}
default :
printer = humanReadablePrinter ( )
}
return printer
}
2014-10-02 16:51:36 +00:00
func executeAPIRequest ( ctx api . Context , method string , c * client . Client ) bool {
2014-07-23 15:16:41 +00:00
storage , path , hasSuffix := storagePathFromArg ( flag . Arg ( 1 ) )
validStorage := checkStorage ( storage )
2014-06-21 21:23:14 +00:00
verb := ""
2014-07-23 00:25:06 +00:00
setBody := false
2014-08-01 21:14:33 +00:00
var version uint64
2014-09-27 03:35:12 +00:00
printer := getPrinter ( )
2014-06-10 21:42:59 +00:00
switch method {
2014-07-23 15:16:41 +00:00
case "get" :
verb = "GET"
if ! validStorage || ! hasSuffix {
glog . Fatalf ( "usage: kubecfg [OPTIONS] %s <%s>[/<id>]" , method , prettyWireStorage ( ) )
}
case "list" :
2014-06-21 21:23:14 +00:00
verb = "GET"
2014-07-23 15:16:41 +00:00
if ! validStorage || hasSuffix {
glog . Fatalf ( "usage: kubecfg [OPTIONS] %s <%s>" , method , prettyWireStorage ( ) )
}
2014-06-10 21:42:59 +00:00
case "delete" :
2014-06-21 21:23:14 +00:00
verb = "DELETE"
2014-07-23 15:16:41 +00:00
if ! validStorage || ! hasSuffix {
glog . Fatalf ( "usage: kubecfg [OPTIONS] %s <%s>/<id>" , method , prettyWireStorage ( ) )
2014-07-23 00:25:06 +00:00
}
2014-06-10 21:42:59 +00:00
case "create" :
2014-06-21 21:23:14 +00:00
verb = "POST"
2014-07-23 00:25:06 +00:00
setBody = true
2014-07-23 15:16:41 +00:00
if ! validStorage || hasSuffix {
glog . Fatalf ( "usage: kubecfg [OPTIONS] %s <%s>" , method , prettyWireStorage ( ) )
2014-07-23 00:25:06 +00:00
}
2014-06-10 21:42:59 +00:00
case "update" :
2014-08-28 13:56:38 +00:00
obj , err := c . Verb ( "GET" ) . Path ( path ) . Do ( ) . Get ( )
2014-08-01 21:14:33 +00:00
if err != nil {
glog . Fatalf ( "error obtaining resource version for update: %v" , err )
}
2014-10-07 15:12:16 +00:00
jsonBase , err := runtime . FindTypeMeta ( obj )
2014-08-01 21:14:33 +00:00
if err != nil {
glog . Fatalf ( "error finding json base for update: %v" , err )
}
version = jsonBase . ResourceVersion ( )
2014-06-21 21:23:14 +00:00
verb = "PUT"
2014-07-23 00:25:06 +00:00
setBody = true
2014-07-23 15:16:41 +00:00
if ! validStorage || ! hasSuffix {
glog . Fatalf ( "usage: kubecfg [OPTIONS] %s <%s>/<id>" , method , prettyWireStorage ( ) )
2014-07-23 00:25:06 +00:00
}
2014-09-27 03:35:12 +00:00
case "print" :
data := readConfig ( storage , c . RESTClient . Codec )
obj , err := latest . Codec . Decode ( data )
if err != nil {
glog . Fatalf ( "error setting resource version: %v" , err )
}
printer . PrintObj ( obj , os . Stdout )
return true
2014-06-11 22:08:23 +00:00
default :
return false
}
2014-09-19 23:04:55 +00:00
r := c . Verb ( verb ) . Path ( path )
if len ( * selector ) > 0 {
r . ParseSelectorParam ( "labels" , * selector )
}
2014-07-23 00:25:06 +00:00
if setBody {
2014-08-01 21:14:33 +00:00
if version != 0 {
2014-09-11 23:01:29 +00:00
data := readConfig ( storage , c . RESTClient . Codec )
2014-09-16 19:56:26 +00:00
obj , err := latest . Codec . Decode ( data )
2014-08-01 21:14:33 +00:00
if err != nil {
glog . Fatalf ( "error setting resource version: %v" , err )
}
2014-10-07 15:12:16 +00:00
jsonBase , err := runtime . FindTypeMeta ( obj )
2014-08-01 21:14:33 +00:00
if err != nil {
glog . Fatalf ( "error setting resource version: %v" , err )
}
jsonBase . SetResourceVersion ( version )
2014-09-11 23:01:29 +00:00
data , err = c . RESTClient . Codec . Encode ( obj )
2014-08-01 21:14:33 +00:00
if err != nil {
glog . Fatalf ( "error setting resource version: %v" , err )
}
r . Body ( data )
} else {
2014-09-11 23:01:29 +00:00
r . Body ( readConfig ( storage , c . RESTClient . Codec ) )
2014-08-01 21:14:33 +00:00
}
2014-06-21 21:23:14 +00:00
}
2014-07-01 02:45:00 +00:00
result := r . Do ( )
obj , err := result . Get ( )
2014-06-21 21:23:14 +00:00
if err != nil {
2014-06-25 03:51:57 +00:00
glog . Fatalf ( "Got request error: %v\n" , err )
2014-06-21 21:23:14 +00:00
return false
}
if err = printer . PrintObj ( obj , os . Stdout ) ; err != nil {
2014-07-01 02:45:00 +00:00
body , _ := result . Raw ( )
glog . Fatalf ( "Failed to print: %v\nRaw received object:\n%#v\n\nBody received: %v" , err , obj , string ( body ) )
2014-06-11 22:08:23 +00:00
}
2014-06-21 21:23:14 +00:00
fmt . Print ( "\n" )
2014-06-11 22:08:23 +00:00
return true
}
2014-10-02 16:51:36 +00:00
func executeControllerRequest ( ctx api . Context , method string , c * client . Client ) bool {
2014-06-11 22:08:23 +00:00
parseController := func ( ) string {
if len ( flag . Args ( ) ) != 2 {
2014-06-26 00:55:43 +00:00
glog . Fatal ( "usage: kubecfg [OPTIONS] stop|rm|rollingupdate <controller>" )
2014-06-11 22:08:23 +00:00
}
return flag . Arg ( 1 )
}
var err error
switch method {
case "stop" :
2014-10-02 16:51:36 +00:00
err = kubecfg . StopController ( ctx , parseController ( ) , c )
2014-06-11 22:08:23 +00:00
case "rm" :
2014-10-02 16:51:36 +00:00
err = kubecfg . DeleteController ( ctx , parseController ( ) , c )
2014-06-10 21:42:59 +00:00
case "rollingupdate" :
2014-10-02 16:51:36 +00:00
err = kubecfg . Update ( ctx , parseController ( ) , c , * updatePeriod , * imageName )
2014-06-10 21:42:59 +00:00
case "run" :
2014-06-11 22:08:23 +00:00
if len ( flag . Args ( ) ) != 4 {
2014-06-26 00:55:43 +00:00
glog . Fatal ( "usage: kubecfg [OPTIONS] run <image> <replicas> <controller>" )
2014-06-06 23:40:48 +00:00
}
2014-06-11 22:08:23 +00:00
image := flag . Arg ( 1 )
2014-08-22 00:55:48 +00:00
replicas , err2 := strconv . Atoi ( flag . Arg ( 2 ) )
if err2 != nil {
glog . Fatalf ( "Error parsing replicas: %v" , err2 )
2014-06-06 23:40:48 +00:00
}
2014-08-22 00:55:48 +00:00
name := flag . Arg ( 3 )
2014-10-02 16:51:36 +00:00
err = kubecfg . RunController ( ctx , image , name , replicas , c , * portSpec , * servicePort )
2014-06-12 17:03:17 +00:00
case "resize" :
args := flag . Args ( )
if len ( args ) < 3 {
2014-06-26 00:55:43 +00:00
glog . Fatal ( "usage: kubecfg resize <controller> <replicas>" )
2014-06-12 17:03:17 +00:00
}
name := args [ 1 ]
2014-08-22 00:55:48 +00:00
replicas , err2 := strconv . Atoi ( args [ 2 ] )
if err2 != nil {
glog . Fatalf ( "Error parsing replicas: %v" , err2 )
2014-06-12 17:03:17 +00:00
}
2014-10-02 16:51:36 +00:00
err = kubecfg . ResizeController ( ctx , name , replicas , c )
2014-06-10 21:42:59 +00:00
default :
2014-06-11 22:08:23 +00:00
return false
2014-06-06 23:40:48 +00:00
}
if err != nil {
2014-07-01 02:45:00 +00:00
glog . Fatalf ( "Error: %v" , err )
2014-06-06 23:40:48 +00:00
}
2014-06-11 22:08:23 +00:00
return true
2014-06-06 23:40:48 +00:00
}
2014-08-13 23:41:58 +00:00
func humanReadablePrinter ( ) * kubecfg . HumanReadablePrinter {
printer := kubecfg . NewHumanReadablePrinter ( )
// Add Handler calls here to support additional types
return printer
}