From b36bfa02a6bb6bd8f9620759524cfb08a8f523c7 Mon Sep 17 00:00:00 2001 From: lllwan <32893806+lllwan@users.noreply.github.com> Date: Sat, 5 Dec 2020 08:06:25 +0800 Subject: [PATCH] Add JSON format appfile support (#691) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add JSON format appfile support Co-authored-by: 摩羯 Co-authored-by: wangxun --- e2e/application/application_test.go | 2 ++ e2e/commonContext.go | 12 ++++++++ go.mod | 2 +- go.sum | 5 ++++ pkg/appfile/appfile.go | 44 +++++++++++++++++++++++++++-- pkg/commands/up.go | 11 ++++++-- 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/e2e/application/application_test.go b/e2e/application/application_test.go index 788a284c2..1ecfab0b6 100644 --- a/e2e/application/application_test.go +++ b/e2e/application/application_test.go @@ -14,9 +14,11 @@ var ( applicationName = "app-basic" traitAlias = "scaler" appNameForInit = "initmyapp" + jsonAppFile = `{"name":"nginx-vela","services":{"nginx":{"type":"webservice","image":"nginx:1.9.4","port":80}}}` ) var _ = ginkgo.Describe("Application", func() { + e2e.JsonAppFileContext("json appfile apply", jsonAppFile) e2e.EnvSetContext("env set", "default") e2e.DeleteEnvFunc("env delete", envName) e2e.EnvInitContext("env init", envName) diff --git a/e2e/commonContext.go b/e2e/commonContext.go index 67f4d46c9..34c4a0893 100644 --- a/e2e/commonContext.go +++ b/e2e/commonContext.go @@ -49,6 +49,18 @@ var ( }) } + JsonAppFileContext = func(context, jsonAppFile string) bool { + return ginkgo.Context(context, func() { + ginkgo.It("Start the application through the app file in JSON format.", func() { + writeStatus := ioutil.WriteFile("vela.json", []byte(jsonAppFile), 0644) + gomega.Expect(writeStatus).NotTo(gomega.HaveOccurred()) + output, err := Exec("vela up -f vela.json") + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + gomega.Expect(output).NotTo(gomega.ContainSubstring("Error:")) + }) + }) + } + DeleteEnvFunc = func(context string, envName string) bool { return ginkgo.Context(context, func() { ginkgo.It("should print env does not exist message", func() { diff --git a/go.mod b/go.mod index 964acbb59..df342dd3a 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/mholt/archiver/v3 v3.3.0 github.com/oam-dev/trait-injector v0.0.0-20200331033130-0a27b176ffc4 github.com/onsi/ginkgo v1.13.0 - github.com/onsi/gomega v1.10.1 + github.com/onsi/gomega v1.10.3 github.com/openservicemesh/osm v0.3.0 github.com/pkg/errors v0.9.1 github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b diff --git a/go.sum b/go.sum index 55aac73c6..c49cfe2c5 100644 --- a/go.sum +++ b/go.sum @@ -767,6 +767,7 @@ github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7 h1:2hRPrmiwPrp3fQX967rNJIhQPtiGXdlQWAxKbKw3VHA= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -1420,6 +1421,8 @@ github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -2037,6 +2040,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/pkg/appfile/appfile.go b/pkg/appfile/appfile.go index 7353b635c..994a33669 100644 --- a/pkg/appfile/appfile.go +++ b/pkg/appfile/appfile.go @@ -1,8 +1,10 @@ package appfile import ( + "encoding/json" "errors" "io/ioutil" + "os" "path/filepath" "time" @@ -25,7 +27,11 @@ var ( ) // DefaultAppfilePath defines the default file path that used by `vela up` command -const DefaultAppfilePath = "./vela.yaml" +const ( + DefaultJSONAppfilePath = "./vela.json" + DefaultAppfilePath = "./vela.yaml" + DefaultUnknowFormatAppfilePath = "./Appfile" +) // AppFile defines the spec of KubeVela Appfile type AppFile struct { @@ -49,7 +55,26 @@ func NewAppFile() *AppFile { // Load will load appfile from default path func Load() (*AppFile, error) { - return LoadFromFile(DefaultAppfilePath) + if _, err := os.Stat(DefaultAppfilePath); err != nil { + return LoadFromFile(DefaultAppfilePath) + } + if _, err := os.Stat(DefaultJSONAppfilePath); err != nil { + return LoadFromFile(DefaultJSONAppfilePath) + } + return LoadFromFile(DefaultUnknowFormatAppfilePath) +} + +// JSONToYaml will convert JSON format appfile to yaml and load the AppFile struct +func JSONToYaml(data []byte, appFile *AppFile) (*AppFile, error) { + j, e := yaml.JSONToYAML(data) + if e != nil { + return nil, e + } + err := yaml.Unmarshal(j, appFile) + if err != nil { + return nil, err + } + return appFile, nil } // LoadFromFile will read the file and load the AppFile struct @@ -59,7 +84,20 @@ func LoadFromFile(filename string) (*AppFile, error) { return nil, err } af := NewAppFile() - err = yaml.Unmarshal(b, af) + // Add JSON format appfile support + ext := filepath.Ext(filename) + switch ext { + case ".yaml", ".yml": + err = yaml.Unmarshal(b, af) + case ".json": + af, err = JSONToYaml(b, af) + default: + if json.Valid(b) { + af, err = JSONToYaml(b, af) + } else { + err = yaml.Unmarshal(b, af) + } + } if err != nil { return nil, err } diff --git a/pkg/commands/up.go b/pkg/commands/up.go index f63e7d5e6..3a15ac827 100644 --- a/pkg/commands/up.go +++ b/pkg/commands/up.go @@ -84,7 +84,13 @@ func saveRemoteAppfile(url string) (string, error) { if err != nil { return "", err } - dest := "vela.yaml" + ext := filepath.Ext(url) + dest := "Appfile" + if ext == ".json" { + dest = "vela.json" + } else if ext == ".yaml" || ext == ".yml" { + dest = "vela.yaml" + } //nolint:gosec return dest, ioutil.WriteFile(dest, body, 0644) } @@ -99,9 +105,8 @@ type buildResult struct { func (o *AppfileOptions) export(filePath string, quiet bool) (*buildResult, []byte, error) { var app *appfile.AppFile var err error - if !quiet { - o.IO.Info("Parsing vela.yaml ...") + o.IO.Info("Parsing vela appfile ...") } if filePath != "" { if strings.HasPrefix(filePath, "https://") || strings.HasPrefix(filePath, "http://") {