mirror of https://github.com/k3s-io/k3s
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
parent
e7f4460ab8
commit
fbd7bc375f
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue