From cc3c78663cd7113c3905d43ddac0b0bfc359bf48 Mon Sep 17 00:00:00 2001 From: Josh Curl Date: Mon, 28 Nov 2016 16:36:23 -0800 Subject: [PATCH] CLI validation for services, console, and engines --- cmd/control/console.go | 30 ++++++++++++++++++++------- cmd/control/engine.go | 28 ++++++++++++++++++------- cmd/control/service/service.go | 38 +++++++++++++++++++++++++++++----- tests/consoles_test.go | 4 +++- tests/custom_docker_test.go | 3 +++ 5 files changed, 82 insertions(+), 21 deletions(-) diff --git a/cmd/control/console.go b/cmd/control/console.go index ac18bed5..883c0361 100644 --- a/cmd/control/console.go +++ b/cmd/control/console.go @@ -11,9 +11,11 @@ import ( "github.com/codegangsta/cli" composeConfig "github.com/docker/libcompose/config" "github.com/docker/libcompose/project/options" + "github.com/rancher/os/cmd/control/service" "github.com/rancher/os/compose" "github.com/rancher/os/config" "github.com/rancher/os/log" + "github.com/rancher/os/util" "github.com/rancher/os/util/network" ) @@ -54,6 +56,7 @@ func consoleSwitch(c *cli.Context) error { newConsole := c.Args()[0] cfg := config.LoadConfig() + validateConsole(newConsole, cfg) if newConsole == currentConsole() { log.Warnf("Console is already set to %s", newConsole) } @@ -106,6 +109,7 @@ func consoleEnable(c *cli.Context) error { newConsole := c.Args()[0] cfg := config.LoadConfig() + validateConsole(newConsole, cfg) if newConsole != "default" { if err := compose.StageServices(cfg, newConsole); err != nil { @@ -122,14 +126,7 @@ func consoleEnable(c *cli.Context) error { func consoleList(c *cli.Context) error { cfg := config.LoadConfig() - - consoles, err := network.GetConsoles(cfg.Rancher.Repositories.ToArray()) - if err != nil { - return err - } - consoles = append(consoles, "default") - sort.Strings(consoles) - + consoles := availableConsoles(cfg) currentConsole := currentConsole() for _, console := range consoles { @@ -145,6 +142,23 @@ func consoleList(c *cli.Context) error { return nil } +func validateConsole(console string, cfg *config.CloudConfig) { + consoles := availableConsoles(cfg) + if !service.IsLocalOrURL(console) && !util.Contains(consoles, console) { + log.Fatalf("%s is not a valid console", console) + } +} + +func availableConsoles(cfg *config.CloudConfig) []string { + consoles, err := network.GetConsoles(cfg.Rancher.Repositories.ToArray()) + if err != nil { + log.Fatal(err) + } + consoles = append(consoles, "default") + sort.Strings(consoles) + return consoles +} + func currentConsole() (console string) { consoleBytes, err := ioutil.ReadFile("/run/console-done") if err == nil { diff --git a/cmd/control/engine.go b/cmd/control/engine.go index 5ccdf916..4d161148 100644 --- a/cmd/control/engine.go +++ b/cmd/control/engine.go @@ -10,9 +10,11 @@ import ( "github.com/codegangsta/cli" "github.com/docker/libcompose/project/options" + "github.com/rancher/os/cmd/control/service" "github.com/rancher/os/compose" "github.com/rancher/os/config" "github.com/rancher/os/log" + "github.com/rancher/os/util" "github.com/rancher/os/util/network" ) @@ -53,6 +55,7 @@ func engineSwitch(c *cli.Context) error { newEngine := c.Args()[0] cfg := config.LoadConfig() + validateEngine(newEngine, cfg) project, err := compose.GetProject(cfg, true, false) if err != nil { @@ -85,6 +88,7 @@ func engineEnable(c *cli.Context) error { newEngine := c.Args()[0] cfg := config.LoadConfig() + validateEngine(newEngine, cfg) if err := compose.StageServices(cfg, newEngine); err != nil { return err @@ -99,13 +103,7 @@ func engineEnable(c *cli.Context) error { func engineList(c *cli.Context) error { cfg := config.LoadConfig() - - engines, err := network.GetEngines(cfg.Rancher.Repositories.ToArray()) - if err != nil { - return err - } - sort.Strings(engines) - + engines := availableEngines(cfg) currentEngine := currentEngine() for _, engine := range engines { @@ -121,6 +119,22 @@ func engineList(c *cli.Context) error { return nil } +func validateEngine(engine string, cfg *config.CloudConfig) { + engines := availableEngines(cfg) + if !service.IsLocalOrURL(engine) && !util.Contains(engines, engine) { + log.Fatalf("%s is not a valid engine", engine) + } +} + +func availableEngines(cfg *config.CloudConfig) []string { + engines, err := network.GetEngines(cfg.Rancher.Repositories.ToArray()) + if err != nil { + log.Fatal(err) + } + sort.Strings(engines) + return engines +} + func currentEngine() (engine string) { engineBytes, err := ioutil.ReadFile(dockerDone) if err == nil { diff --git a/cmd/control/service/service.go b/cmd/control/service/service.go index da98e037..3ac20765 100644 --- a/cmd/control/service/service.go +++ b/cmd/control/service/service.go @@ -11,6 +11,7 @@ import ( "github.com/rancher/os/compose" "github.com/rancher/os/config" "github.com/rancher/os/log" + "github.com/rancher/os/util" "github.com/rancher/os/util/network" ) @@ -91,6 +92,8 @@ func disable(c *cli.Context) error { cfg := config.LoadConfig() for _, service := range c.Args() { + validateService(service, cfg) + if _, ok := cfg.Rancher.ServicesInclude[service]; !ok { continue } @@ -113,9 +116,12 @@ func del(c *cli.Context) error { cfg := config.LoadConfig() for _, service := range c.Args() { + validateService(service, cfg) + if _, ok := cfg.Rancher.ServicesInclude[service]; !ok { continue } + delete(cfg.Rancher.ServicesInclude, service) changed = true } @@ -135,8 +141,10 @@ func enable(c *cli.Context) error { var enabledServices []string for _, service := range c.Args() { + validateService(service, cfg) + if val, ok := cfg.Rancher.ServicesInclude[service]; !ok || !val { - if strings.HasPrefix(service, "/") && !strings.HasPrefix(service, "/var/lib/rancher/conf") { + if isLocal(service) && !strings.HasPrefix(service, "/var/lib/rancher/conf") { log.Fatalf("ERROR: Service should be in path /var/lib/rancher/conf") } @@ -166,10 +174,7 @@ func list(c *cli.Context) error { clone[service] = enabled } - services, err := network.GetServices(cfg.Rancher.Repositories.ToArray()) - if err != nil { - log.Fatalf("Failed to get services: %v", err) - } + services := availableService(cfg) for _, service := range services { if enabled, ok := clone[service]; ok { @@ -194,3 +199,26 @@ func list(c *cli.Context) error { return nil } + +func isLocal(service string) bool { + return strings.HasPrefix(service, "/") +} + +func IsLocalOrURL(service string) bool { + return isLocal(service) || strings.HasPrefix(service, "http:/") || strings.HasPrefix(service, "http:/") +} + +func validateService(service string, cfg *config.CloudConfig) { + services := availableService(cfg) + if !IsLocalOrURL(service) && !util.Contains(services, service) { + log.Fatalf("%s is not a valid service", service) + } +} + +func availableService(cfg *config.CloudConfig) []string { + services, err := network.GetServices(cfg.Rancher.Repositories.ToArray()) + if err != nil { + log.Fatalf("Failed to get services: %v", err) + } + return services +} diff --git a/tests/consoles_test.go b/tests/consoles_test.go index 26900e3d..ee98d762 100644 --- a/tests/consoles_test.go +++ b/tests/consoles_test.go @@ -16,7 +16,9 @@ func (s *QemuSuite) TestConsoleCommand(c *C) { s.CheckCall(c, ` sudo ros console list | grep default | grep current -sudo ros console list | grep debian | grep disabled`) +sudo ros console list | grep debian | grep disabled +(sudo ros console switch invalid 2>&1 || true) | grep "invalid is not a valid console" +(sudo ros console enable invalid 2>&1 || true) | grep "invalid is not a valid console"`) s.MakeCall("sudo ros console switch -f debian") c.Assert(s.WaitForSSH(), IsNil) diff --git a/tests/custom_docker_test.go b/tests/custom_docker_test.go index d056794e..9cfdb6c1 100644 --- a/tests/custom_docker_test.go +++ b/tests/custom_docker_test.go @@ -11,6 +11,9 @@ set -ex docker version | grep 1.10.3 sudo ros engine list | grep 1.10.3 | grep current +(sudo ros engine switch invalid 2>&1 || true) | grep "invalid is not a valid engine" +(sudo ros engine enable invalid 2>&1 || true) | grep "invalid is not a valid engine" + docker run -d --restart=always nginx docker ps | grep nginx`)