kubecfg doesn't allow updates because of path checks

Check for 1 path segment on create/list, 2 on update/delete, and
allow any number of path segments on get (for now).

Also pretty prints the list of actual types that are supported for
create/update, which today corresponds to the list of types that
are supported period.
pull/6/head
Clayton Coleman 2014-07-22 20:25:06 -04:00
parent e7f4460ab8
commit fbd7bc375f
2 changed files with 38 additions and 11 deletions

View File

@ -22,6 +22,7 @@ import (
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"os" "os"
"sort"
"strconv" "strconv"
"strings" "strings"
"text/template" "text/template"
@ -55,10 +56,10 @@ var (
) )
func usage() { func usage() {
fmt.Fprint(os.Stderr, `usage: kubecfg -h [-c config/file.json] [-p :,..., :] <method> fmt.Fprintf(os.Stderr, `usage: kubecfg -h [-c config/file.json] [-p :,..., :] <method>
Kubernetes REST API: Kubernetes REST API:
kubecfg [OPTIONS] get|list|create|delete|update <url> kubecfg [OPTIONS] get|list|create|delete|update <%s>[/<id>]
Manage replication controllers: Manage replication controllers:
kubecfg [OPTIONS] stop|rm|rollingupdate <controller> kubecfg [OPTIONS] stop|rm|rollingupdate <controller>
@ -66,10 +67,16 @@ func usage() {
kubecfg [OPTIONS] resize <controller> <replicas> kubecfg [OPTIONS] resize <controller> <replicas>
Options: Options:
`) `, prettyWireStorage())
flag.PrintDefaults() flag.PrintDefaults()
} }
func prettyWireStorage() string {
types := kubecfg.SupportedWireStorage()
sort.Strings(types)
return strings.Join(types, "|")
}
// readConfig reads and parses pod, replicationController, and service // readConfig reads and parses pod, replicationController, and service
// configuration files. If any errors log and exit non-zero. // configuration files. If any errors log and exit non-zero.
func readConfig(storage string) []byte { func readConfig(storage string) []byte {
@ -150,32 +157,44 @@ func main() {
} }
func executeAPIRequest(method string, s *kube_client.Client) bool { func executeAPIRequest(method string, s *kube_client.Client) bool {
parseStorage := func() string { if len(flag.Args()) != 2 {
if len(flag.Args()) != 2 { glog.Fatalf("usage: kubecfg [OPTIONS] get|list|create|update|delete <%s>[/<id>]", prettyWireStorage())
glog.Fatal("usage: kubecfg [OPTIONS] get|list|create|update|delete <url>")
}
return strings.Trim(flag.Arg(1), "/")
} }
verb := "" verb := ""
segments := strings.SplitN(flag.Arg(1), "/", 2)
storage := segments[0]
path := strings.Trim(flag.Arg(1), "/")
setBody := false
switch method { switch method {
case "get", "list": case "get", "list":
verb = "GET" verb = "GET"
case "delete": case "delete":
verb = "DELETE" verb = "DELETE"
if len(segments) == 1 || segments[1] == "" {
glog.Fatalf("usage: kubecfg [OPTIONS] delete <%s>/<id>", prettyWireStorage())
}
case "create": case "create":
verb = "POST" verb = "POST"
setBody = true
if len(segments) != 1 {
glog.Fatalf("usage: kubecfg [OPTIONS] create <%s>", prettyWireStorage())
}
case "update": case "update":
verb = "PUT" verb = "PUT"
setBody = true
if len(segments) == 1 || segments[1] == "" {
glog.Fatalf("usage: kubecfg [OPTIONS] update <%s>/<id>", prettyWireStorage())
}
default: default:
return false return false
} }
r := s.Verb(verb). r := s.Verb(verb).
Path(parseStorage()). Path(path).
ParseSelector(*selector) ParseSelector(*selector)
if method == "create" || method == "update" { if setBody {
r.Body(readConfig(parseStorage())) r.Body(readConfig(storage))
} }
result := r.Do() result := r.Do()
obj, err := result.Get() obj, err := result.Get()

View File

@ -44,3 +44,11 @@ func ToWireFormat(data []byte, storage string) ([]byte, error) {
} }
return api.Encode(obj) return api.Encode(obj)
} }
func SupportedWireStorage() []string {
types := []string{}
for k, _ := range storageToType {
types = append(types, k)
}
return types
}