From f775806405918f2ae9338b80729a7c5fac3e74a0 Mon Sep 17 00:00:00 2001 From: Soam Vasani Date: Fri, 4 Nov 2016 22:56:44 -0700 Subject: [PATCH 1/3] Add HTTP method to HTTPTrigger --- types.go | 1 + 1 file changed, 1 insertion(+) diff --git a/types.go b/types.go index 9515478c..f8325b4d 100644 --- a/types.go +++ b/types.go @@ -49,6 +49,7 @@ type ( HTTPTrigger struct { Metadata `json:"metadata"` UrlPattern string `json:"urlpattern"` + Method string `json:"method"` Function Metadata `json:"function"` } From a5ae7688cefa819e144bd31c318c34cc97421c42 Mon Sep 17 00:00:00 2001 From: Soam Vasani Date: Fri, 4 Nov 2016 22:57:11 -0700 Subject: [PATCH 2/3] Make *Update functions consistently return fission.Metadata --- controller/api_test.go | 32 +++++++------------------ controller/client/client.go | 48 ++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/controller/api_test.go b/controller/api_test.go index 961343cf..8b218c26 100644 --- a/controller/api_test.go +++ b/controller/api_test.go @@ -119,12 +119,8 @@ func TestHTTPTriggerApi(t *testing.T) { Uid: "", }, } - uid, err := g.client.HTTPTriggerCreate(testTrigger) + m, err := g.client.HTTPTriggerCreate(testTrigger) panicIf(err) - m := &fission.Metadata{ - Name: testTrigger.Metadata.Name, - Uid: uid, - } defer g.client.HTTPTriggerDelete(m) tr, err := g.client.HTTPTriggerGet(m) @@ -133,22 +129,18 @@ func TestHTTPTriggerApi(t *testing.T) { assert(*testTrigger == *tr, "trigger should match after reading") testTrigger.UrlPattern = "/hi" - uid2, err := g.client.HTTPTriggerUpdate(testTrigger) + m2, err := g.client.HTTPTriggerUpdate(testTrigger) panicIf(err) - m.Uid = uid2 + m.Uid = m2.Uid tr, err = g.client.HTTPTriggerGet(m) panicIf(err) testTrigger.Metadata.Uid = m.Uid assert(*testTrigger == *tr, "trigger should match after reading") testTrigger.Metadata.Name = "yyy" - uid, err = g.client.HTTPTriggerCreate(testTrigger) + m, err = g.client.HTTPTriggerCreate(testTrigger) panicIf(err) - m = &fission.Metadata{ - Name: testTrigger.Metadata.Name, - Uid: uid, - } defer g.client.HTTPTriggerDelete(m) ts, err := g.client.HTTPTriggerList() @@ -164,12 +156,8 @@ func TestEnvironmentApi(t *testing.T) { }, RunContainerImageUrl: "gcr.io/xyz", } - uid, err := g.client.EnvironmentCreate(testEnv) + m, err := g.client.EnvironmentCreate(testEnv) panicIf(err) - m := &fission.Metadata{ - Name: testEnv.Metadata.Name, - Uid: uid, - } defer g.client.EnvironmentDelete(m) tr, err := g.client.EnvironmentGet(m) @@ -178,22 +166,18 @@ func TestEnvironmentApi(t *testing.T) { assert(*testEnv == *tr, "env should match after reading") testEnv.RunContainerImageUrl = "/hi" - uid2, err := g.client.EnvironmentUpdate(testEnv) + m2, err := g.client.EnvironmentUpdate(testEnv) panicIf(err) - m.Uid = uid2 + m.Uid = m2.Uid tr, err = g.client.EnvironmentGet(m) panicIf(err) testEnv.Metadata.Uid = m.Uid assert(*testEnv == *tr, "env should match after reading") testEnv.Metadata.Name = "yyy" - uid, err = g.client.EnvironmentCreate(testEnv) + m, err = g.client.EnvironmentCreate(testEnv) panicIf(err) - m = &fission.Metadata{ - Name: testEnv.Metadata.Name, - Uid: uid, - } defer g.client.EnvironmentDelete(m) ts, err := g.client.EnvironmentList() diff --git a/controller/client/client.go b/controller/client/client.go index e14c6886..82bd7906 100644 --- a/controller/client/client.go +++ b/controller/client/client.go @@ -238,15 +238,15 @@ func (c *Client) FunctionList() ([]fission.Function, error) { return funcs, nil } -func (c *Client) HTTPTriggerCreate(t *fission.HTTPTrigger) (string, error) { +func (c *Client) HTTPTriggerCreate(t *fission.HTTPTrigger) (*fission.Metadata, error) { reqbody, err := json.Marshal(t) if err != nil { - return "", err + return nil, err } resp, err := http.Post(c.url("triggers/http"), "application/json", bytes.NewReader(reqbody)) if err != nil { - return "", err + return nil, err } defer resp.Body.Close() @@ -256,16 +256,16 @@ func (c *Client) HTTPTriggerCreate(t *fission.HTTPTrigger) (string, error) { "name": t.Metadata.Name, "err": err, }).Error("Failed to create http trigger") - return "", err + return nil, err } var m fission.Metadata err = json.Unmarshal(body, &m) if err != nil { - return "", err + return nil, err } - return m.Uid, nil + return &m, nil } func (c *Client) HTTPTriggerGet(m *fission.Metadata) (*fission.HTTPTrigger, error) { @@ -294,30 +294,30 @@ func (c *Client) HTTPTriggerGet(m *fission.Metadata) (*fission.HTTPTrigger, erro return &t, nil } -func (c *Client) HTTPTriggerUpdate(t *fission.HTTPTrigger) (string, error) { +func (c *Client) HTTPTriggerUpdate(t *fission.HTTPTrigger) (*fission.Metadata, error) { reqbody, err := json.Marshal(t) if err != nil { - return "", err + return nil, err } relativeUrl := fmt.Sprintf("triggers/http/%v", t.Metadata.Name) resp, err := c.put(relativeUrl, "application/json", reqbody) if err != nil { - return "", err + return nil, err } defer resp.Body.Close() body, err := c.handleResponse(resp) if err != nil { - return "", err + return nil, err } var m fission.Metadata err = json.Unmarshal(body, &m) if err != nil { - return "", err + return nil, err } - return m.Uid, nil + return &m, nil } func (c *Client) HTTPTriggerDelete(m *fission.Metadata) error { @@ -349,15 +349,15 @@ func (c *Client) HTTPTriggerList() ([]fission.HTTPTrigger, error) { return triggers, nil } -func (c *Client) EnvironmentCreate(env *fission.Environment) (string, error) { +func (c *Client) EnvironmentCreate(env *fission.Environment) (*fission.Metadata, error) { reqbody, err := json.Marshal(env) if err != nil { - return "", err + return nil, err } resp, err := http.Post(c.url("environments"), "application/json", bytes.NewReader(reqbody)) if err != nil { - return "", err + return nil, err } defer resp.Body.Close() @@ -367,16 +367,16 @@ func (c *Client) EnvironmentCreate(env *fission.Environment) (string, error) { "name": env.Metadata.Name, "err": err, }).Error("Failed to create environment") - return "", err + return nil, err } var m fission.Metadata err = json.Unmarshal(body, &m) if err != nil { - return "", err + return nil, err } - return m.Uid, nil + return &m, nil } func (c *Client) EnvironmentGet(m *fission.Metadata) (*fission.Environment, error) { @@ -405,30 +405,30 @@ func (c *Client) EnvironmentGet(m *fission.Metadata) (*fission.Environment, erro return &env, nil } -func (c *Client) EnvironmentUpdate(env *fission.Environment) (string, error) { +func (c *Client) EnvironmentUpdate(env *fission.Environment) (*fission.Metadata, error) { reqbody, err := json.Marshal(env) if err != nil { - return "", err + return nil, err } relativeUrl := fmt.Sprintf("environments/%v", env.Metadata.Name) resp, err := c.put(relativeUrl, "application/json", reqbody) if err != nil { - return "", err + return nil, err } defer resp.Body.Close() body, err := c.handleResponse(resp) if err != nil { - return "", err + return nil, err } var m fission.Metadata err = json.Unmarshal(body, &m) if err != nil { - return "", err + return nil, err } - return m.Uid, nil + return &m, nil } func (c *Client) EnvironmentDelete(m *fission.Metadata) error { From 96616507fd45bfd9686768113cfc61ba7c07ed2e Mon Sep 17 00:00:00 2001 From: Soam Vasani Date: Fri, 4 Nov 2016 22:59:52 -0700 Subject: [PATCH 3/3] Fission CLI fission (function|httptrigger|environment) (create|get|update|delete|list) TODO: Commands for getting status, logs, perf stats. Commands for changing configuration. Add examples. --- fission/common.go | 44 ++++++++++ fission/deployment.go | 181 +++++++++++++++++++++++++++++++++++++++++ fission/environment.go | 111 +++++++++++++++++++++++++ fission/function.go | 143 ++++++++++++++++++++++++++++++++ fission/httptrigger.go | 135 ++++++++++++++++++++++++++++++ fission/main.go | 87 ++++++++++++++++++++ 6 files changed, 701 insertions(+) create mode 100644 fission/common.go create mode 100644 fission/deployment.go create mode 100644 fission/environment.go create mode 100644 fission/function.go create mode 100644 fission/httptrigger.go create mode 100644 fission/main.go diff --git a/fission/common.go b/fission/common.go new file mode 100644 index 00000000..e2bbfec2 --- /dev/null +++ b/fission/common.go @@ -0,0 +1,44 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import ( + "fmt" + "os" + + "github.com/platform9/fission/controller/client" +) + +func fatal(msg string) { + os.Stderr.WriteString(msg + "\n") + os.Exit(1) +} + +func getClient(serverUrl string) *client.Client { + + if len(serverUrl) == 0 { + fatal("Need --server or FISSION_URL set to your fission server.") + } + + return client.MakeClient(serverUrl) +} + +func checkErr(err error, msg string) { + if err != nil { + fatal(fmt.Sprintf("Failed to %v: %v", msg, err)) + } +} diff --git a/fission/deployment.go b/fission/deployment.go new file mode 100644 index 00000000..a98319ba --- /dev/null +++ b/fission/deployment.go @@ -0,0 +1,181 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import "fmt" + +func getDeploymentYaml() { + fmt.Printf(` +apiVersion: v1 +kind: Namespace +metadata: + name: fission + labels: + name: fission + +--- +apiVersion: v1 +kind: Namespace +metadata: + name: fission-function + labels: + name: fission-function + +--- +apiVersion: v1 +kind: Service +metadata: + name: controller + namespace: fission + labels: + svc: controller +spec: + type: NodePort + ports: + - port: 80 + targetPort: 8888 + nodePort: 31313 + selector: + svc: controller + +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: controller + namespace: fission +spec: + replicas: 1 + template: + metadata: + labels: + svc: controller + spec: + containers: + - name: controller + image: fission/fission-bundle + command: ["/fission-bundle"] + args: ["--controllerPort", "8888", "--filepath", "/tmp"] + +--- +apiVersion: v1 +kind: Service +metadata: + name: router + namespace: fission + labels: + svc: router +spec: + type: NodePort + ports: + - port: 80 + targetPort: 8888 + nodePort: 31314 + selector: + svc: router + +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: router + namespace: fission +spec: + replicas: 1 + template: + metadata: + labels: + svc: router + spec: + containers: + - name: router + image: fission/fission-bundle + command: ["/fission-bundle"] + args: ["--routerPort", "8888"] + +--- +apiVersion: v1 +kind: Service +metadata: + name: poolmgr + namespace: fission + labels: + svc: poolmgr +spec: + ports: + - port: 80 + targetPort: 8888 + selector: + svc: poolmgr + +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: poolmgr + namespace: fission +spec: + replicas: 1 + template: + metadata: + labels: + svc: poolmgr + spec: + containers: + - name: poolmgr + image: fission/fission-bundle + command: ["/fission-bundle"] + args: ["--poolmgrPort", "8888"] + +--- +apiVersion: v1 +kind: Service +metadata: + name: etcd + namespace: fission + labels: + svc: etcd +spec: + ports: + - port: 2379 + targetPort: 2379 + selector: + svc: etcd + +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: etcd + namespace: fission +spec: + replicas: 1 + template: + metadata: + labels: + svc: etcd + spec: + containers: + - name: etcd + image: quay.io/coreos/etcd + env: + - name: ETCD_LISTEN_CLIENT_URLS + value: http://0.0.0.0:2379 + - name: ETCD_ADVERTISE_CLIENT_URLS + value: http://etcd:2379 +`) +} diff --git a/fission/environment.go b/fission/environment.go new file mode 100644 index 00000000..24186908 --- /dev/null +++ b/fission/environment.go @@ -0,0 +1,111 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import ( + "fmt" + "text/tabwriter" + + "github.com/urfave/cli" + + "github.com/platform9/fission" + "os" +) + +func envCreate(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + envName := c.String("name") + envImg := c.String("image") + + env := &fission.Environment{ + Metadata: fission.Metadata{ + Name: envName, + }, + RunContainerImageUrl: envImg, + } + + _, err := client.EnvironmentCreate(env) + checkErr(err, "create environment") + + fmt.Printf("environment '%v' created\n", envName) + return err +} + +func envGet(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + envName := c.String("name") + m := &fission.Metadata{Name: envName} + env, err := client.EnvironmentGet(m) + checkErr(err, "get environment") + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "IMAGE") + fmt.Fprintf(w, "%v\t%v\t%v\n", + env.Metadata.Name, env.Metadata.Uid, env.RunContainerImageUrl) + w.Flush() + return nil +} + +func envUpdate(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + envName := c.String("name") + image := c.String("image") + env := &fission.Environment{ + Metadata: fission.Metadata{ + Name: envName, + }, + RunContainerImageUrl: image, + } + + _, err := client.EnvironmentUpdate(env) + checkErr(err, "update environment") + + fmt.Printf("environment '%v' updated\n", envName) + return nil +} + +func envDelete(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + envName := c.String("name") + m := &fission.Metadata{Name: envName} + err := client.EnvironmentDelete(m) + checkErr(err, "delete environment") + + fmt.Printf("environment '%v' deleted\n", envName) + return nil +} + +func envList(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + envs, err := client.EnvironmentList() + checkErr(err, "list environments") + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "IMAGE") + for _, env := range envs { + fmt.Fprintf(w, "%v\t%v\t%v\n", + env.Metadata.Name, env.Metadata.Uid, env.RunContainerImageUrl) + } + w.Flush() + + return nil +} diff --git a/fission/function.go b/fission/function.go new file mode 100644 index 00000000..e54e0a00 --- /dev/null +++ b/fission/function.go @@ -0,0 +1,143 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import ( + "fmt" + "io/ioutil" + "os" + "text/tabwriter" + + "github.com/urfave/cli" + + "github.com/platform9/fission" +) + +func fnCreate(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("name") + envName := c.String("env") + + fileName := c.String("code") + code, err := ioutil.ReadFile(fileName) + checkErr(err, fmt.Sprintf("read %v", fileName)) + + function := &fission.Function{ + Metadata: fission.Metadata{Name: fnName}, + Environment: fission.Metadata{Name: envName}, + Code: string(code), + } + + _, err = client.FunctionCreate(function) + checkErr(err, "create function") + + fmt.Printf("function '%v' created\n", fnName) + return err +} + +func fnGet(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("name") + fnUid := c.String("uid") + m := &fission.Metadata{Name: fnName, Uid: fnUid} + + code, err := client.FunctionGetRaw(m) + checkErr(err, "get function") + + fmt.Println(string(code)) + return err +} + +func fnGetMeta(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("name") + fnUid := c.String("uid") + m := &fission.Metadata{Name: fnName, Uid: fnUid} + + f, err := client.FunctionGet(m) + checkErr(err, "get function") + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV") + fmt.Fprintf(w, "%v\t%v\t%v\n", + f.Metadata.Name, f.Metadata.Uid, f.Environment.Name) + w.Flush() + return err +} + +func fnUpdate(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("name") + + function, err := client.FunctionGet(&fission.Metadata{Name: fnName}) + checkErr(err, fmt.Sprintf("read function '%v'", fnName)) + + envName := c.String("env") + if len(envName) > 0 { + function.Environment.Name = envName + } + + fileName := c.String("code") + if len(fileName) > 0 { + code, err := ioutil.ReadFile(fileName) + checkErr(err, fmt.Sprintf("read %v", fileName)) + + function.Code = string(code) + } + + _, err = client.FunctionCreate(function) + checkErr(err, "update function") + + fmt.Printf("function '%v' created\n", fnName) + return err +} + +func fnDelete(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("name") + fnUid := c.String("uid") + m := &fission.Metadata{Name: fnName, Uid: fnUid} + + err := client.FunctionDelete(m) + checkErr(err, fmt.Sprintf("delete function '%v'", fnName)) + + fmt.Printf("function '%v' deleted\n", fnName) + return err +} + +func fnList(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fns, err := client.FunctionList() + checkErr(err, "list functions") + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + + fmt.Fprintf(w, "%v\t%v\t%v\n", "NAME", "UID", "ENV") + for _, f := range fns { + fmt.Fprintf(w, "%v\t%v\t%v\n", + f.Metadata.Name, f.Metadata.Uid, f.Environment.Name) + } + w.Flush() + + return err +} diff --git a/fission/httptrigger.go b/fission/httptrigger.go new file mode 100644 index 00000000..2ff30599 --- /dev/null +++ b/fission/httptrigger.go @@ -0,0 +1,135 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import ( + "fmt" + "net/http" + "os" + "strings" + "text/tabwriter" + + "github.com/satori/go.uuid" + "github.com/urfave/cli" + + "github.com/platform9/fission" +) + +// returns one of http.Method* +func getMethod(method string) string { + switch strings.ToUpper(method) { + case "GET": + return http.MethodGet + case "HEAD": + return http.MethodHead + case "POST": + return http.MethodPost + case "PUT": + return http.MethodPut + case "PATCH": + return http.MethodPatch + case "DELETE": + return http.MethodDelete + case "CONNECT": + return http.MethodConnect + case "OPTIONS": + return http.MethodOptions + case "TRACE": + return http.MethodTrace + } + fatal(fmt.Sprintf("Invalid HTTP Method %v", method)) + return "" +} + +func htCreate(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + fnName := c.String("function") + if len(fnName) == 0 { + fatal("Need a function name to create a trigger, use --function") + } + fnUid := c.String("uid") + triggerUrl := c.String("url") + if len(triggerUrl) == 0 { + fatal("Need a trigger URL, use --url") + } + method := c.String("method") + if len(method) == 0 { + method = "GET" + } + + // just name triggers by uuid. + triggerName := uuid.NewV4().String() + + ht := &fission.HTTPTrigger{ + Metadata: fission.Metadata{ + Name: triggerName, + }, + UrlPattern: triggerUrl, + Method: getMethod(method), + Function: fission.Metadata{ + Name: fnName, + Uid: fnUid, + }, + } + + _, err := client.HTTPTriggerCreate(ht) + checkErr(err, "create HTTP trigger") + + fmt.Printf("trigger '%v' created\n", triggerName) + return err +} + +func htGet(c *cli.Context) error { + return nil +} + +func htUpdate(c *cli.Context) error { + return nil +} + +func htDelete(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + htName := c.String("name") + if len(htName) == 0 { + fatal("Need name of trigger to delete, use --name") + } + + err := client.HTTPTriggerDelete(&fission.Metadata{Name: htName}) + checkErr(err, "delete trigger") + + fmt.Printf("trigger '%v' deleted\n", htName) + return nil +} + +func htList(c *cli.Context) error { + client := getClient(c.GlobalString("server")) + + hts, err := client.HTTPTriggerList() + checkErr(err, "list HTTP triggers") + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0) + + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", "NAME", "METHOD", "URL", "FUNCTION_NAME", "FUNCTION_UID") + for _, ht := range hts { + fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\n", + ht.Metadata.Name, ht.Method, ht.UrlPattern, ht.Function.Name, ht.Function.Uid) + } + w.Flush() + + return nil +} diff --git a/fission/main.go b/fission/main.go new file mode 100644 index 00000000..414ff909 --- /dev/null +++ b/fission/main.go @@ -0,0 +1,87 @@ +/* +Copyright 2016 The Fission Authors. + +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. +*/ + +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + app.Flags = []cli.Flag{ + cli.StringFlag{Name: "server", Usage: "Fission server URL", EnvVar: "FISSION_URL"}, + } + + // functions + fnNameFlag := cli.StringFlag{Name: "name", Usage: "function name"} + fnEnvNameFlag := cli.StringFlag{Name: "env", Usage: "environment name for function"} + fnCodeFlag := cli.StringFlag{Name: "code", Usage: "file containing source code, or - for stdin"} + fnUidFlag := cli.StringFlag{Name: "uid", Usage: "function uid, optional (use latest if unspecified)"} + fnSubcommands := []cli.Command{ + {Name: "create", Usage: "Create new function", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag}, Action: fnCreate}, + {Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag, fnUidFlag}, Action: fnGet}, + {Name: "getmeta", Usage: "Get function metadata", Flags: []cli.Flag{fnNameFlag, fnUidFlag}, Action: fnGetMeta}, + {Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnEnvNameFlag, fnCodeFlag}, Action: fnUpdate}, + {Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag, fnUidFlag}, Action: fnDelete}, + {Name: "list", Usage: "List all functions", Flags: []cli.Flag{}, Action: fnList}, + } + + // httptriggers + htNameFlag := cli.StringFlag{Name: "name", Usage: "HTTP Trigger name"} + htMethodFlag := cli.StringFlag{Name: "method", Usage: "HTTP Method: GET|POST|PUT|DELETE|HEAD; defaults to GET"} + htUrlFlag := cli.StringFlag{Name: "url", Usage: "URL pattern (see TODO for supported patterns)"} + htFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"} + htFnUidFlag := cli.StringFlag{Name: "uid", Usage: "Function UID (optional; uses latest if unspecified)"} + htSubcommands := []cli.Command{ + {Name: "create", Usage: "Create HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag, htFnNameFlag, htFnUidFlag}, Action: htCreate}, + {Name: "get", Usage: "Get HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag}, Action: htGet}, + {Name: "update", Usage: "Update HTTP trigger", Flags: []cli.Flag{htMethodFlag, htUrlFlag, htFnNameFlag, htFnUidFlag}, Action: htUpdate}, + {Name: "delete", Usage: "Delete HTTP trigger", Flags: []cli.Flag{htNameFlag}, Action: htDelete}, + {Name: "list", Usage: "List HTTP triggers", Flags: []cli.Flag{}, Action: htList}, + } + + // environments + envNameFlag := cli.StringFlag{Name: "name", Usage: "Environment name"} + envImageFlag := cli.StringFlag{Name: "image", Usage: "Environment image URL"} + envSubcommands := []cli.Command{ + {Name: "create", Aliases: []string{"add"}, Usage: "Add an environment", Flags: []cli.Flag{envNameFlag, envImageFlag}, Action: envCreate}, + {Name: "get", Usage: "Get environment details", Flags: []cli.Flag{envNameFlag}, Action: envGet}, + {Name: "update", Usage: "Update environment", Flags: []cli.Flag{envNameFlag, envImageFlag}, Action: envUpdate}, + {Name: "delete", Usage: "Delete environment", Flags: []cli.Flag{envNameFlag}, Action: envDelete}, + {Name: "list", Usage: "List all environments", Flags: []cli.Flag{}, Action: envList}, + } + + app.Commands = []cli.Command{ + {Name: "function", Aliases: []string{"fn"}, Usage: "Create, update and manage functions", Subcommands: fnSubcommands}, + {Name: "httptrigger", Aliases: []string{"ht", "route"}, Usage: "Manage HTTP triggers (routes) for functions", Subcommands: htSubcommands}, + {Name: "environemnt", Aliases: []string{"env"}, Usage: "Manage environments", Subcommands: envSubcommands}, + + // Misc commands + { + Name: "get-deployment-yaml", + Usage: "Get deployment yaml. Use it as 'fission get-deployment-yaml | kubectl create -f -'", + Action: func(c *cli.Context) error { + getDeploymentYaml() + return nil + }, + }, + } + + app.Run(os.Args) +}