Migrate from urfave/cli to cobra (#1385)
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra/helptemplate"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/canaryconfig"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/environment"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/function"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/kubewatch"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/mqtrigger"
|
||||
_package "github.com/fission/fission/pkg/fission-cli/cmd/package"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/support"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/timetrigger"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/version"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
)
|
||||
|
||||
const (
|
||||
usage = `Fission: Fast and Simple Serverless Functions for Kubernetes
|
||||
|
||||
* Github: https://github.com/fission/fission
|
||||
* Documentation: https://docs.fission.io/docs
|
||||
`
|
||||
)
|
||||
|
||||
func App() *cobra.Command {
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "fission",
|
||||
Long: usage,
|
||||
//SilenceUsage: true,
|
||||
PreRunE: wrapper.Wrapper(
|
||||
func(flags cli.Input) error {
|
||||
console.Verbosity = flags.Int(flagkey.Verbosity)
|
||||
return nil
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
// Workaround fix for not to show help command
|
||||
// https://github.com/spf13/cobra/issues/587
|
||||
rootCmd.SetHelpCommand(&cobra.Command{
|
||||
Use: "no-help",
|
||||
Hidden: true,
|
||||
})
|
||||
|
||||
wrapper.SetFlags(rootCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.GlobalServerFlag, flag.GlobalVerbosityFlag},
|
||||
})
|
||||
|
||||
groups := helptemplate.CommandGroups{}
|
||||
groups = append(groups, helptemplate.CreateCmdGroup("Basic Commands", environment.Commands(), _package.Commands(), function.Commands()))
|
||||
groups = append(groups, helptemplate.CreateCmdGroup("Trigger Commands", httptrigger.Commands(), mqtrigger.Commands(), timetrigger.Commands(), kubewatch.Commands()))
|
||||
groups = append(groups, helptemplate.CreateCmdGroup("Deploy Strategies Commands", canaryconfig.Commands()))
|
||||
groups = append(groups, helptemplate.CreateCmdGroup("Declarative Application Commands", spec.Commands()))
|
||||
groups = append(groups, helptemplate.CreateCmdGroup("Other Commands", support.Commands(), version.Commands()))
|
||||
groups.Add(rootCmd)
|
||||
|
||||
helptemplate.ActsAsRootCommand(rootCmd, nil, groups...)
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
@@ -17,16 +17,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
fcli "github.com/fission/fission/pkg/fission-cli"
|
||||
"github.com/fission/fission/cmd/fission-cli/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fcli.NewCliApp().Run(os.Args)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
app.App().Execute()
|
||||
}
|
||||
|
||||
@@ -40,7 +40,10 @@ require (
|
||||
github.com/imdario/mergo v0.3.5
|
||||
github.com/influxdata/influxdb v1.2.0
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/life1347/color v1.7.0
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c // indirect
|
||||
github.com/mattn/go-colorable v0.1.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
||||
github.com/mholt/archiver v0.0.0-20180417220235-e4ef56d48eb0
|
||||
github.com/nats-io/gnatsd v1.4.1 // indirect
|
||||
github.com/nats-io/go-nats v1.6.0 // indirect
|
||||
@@ -56,7 +59,8 @@ require (
|
||||
github.com/prometheus/common v0.4.1
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670 // indirect
|
||||
github.com/urfave/cli v1.20.0
|
||||
@@ -69,7 +73,6 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443 // indirect
|
||||
golang.org/x/image v0.0.0-20190618124811-92942e4437e2 // indirect
|
||||
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b
|
||||
golang.org/x/sys v0.0.0-20190619183051-17bc6164aac4 // indirect
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||
google.golang.org/appengine v1.6.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
|
||||
@@ -31,6 +31,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
@@ -46,11 +47,15 @@ github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyV
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-oidc v0.0.0-20180117170138-065b426bd416/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
||||
github.com/coreos/go-semver v0.0.0-20180108230905-e214231b295a/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -188,12 +193,14 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
|
||||
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb v1.2.0 h1:ZSB1cdZP9/8yyFzZhyaHimPL55Qo2kRDv2VhgnCePJ4=
|
||||
github.com/influxdata/influxdb v1.2.0/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||
@@ -214,15 +221,24 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/life1347/color v1.7.0 h1:Csr56ts64td/iG9T9o4p9cXNK46YB1/ZSq3V+qDwD4Y=
|
||||
github.com/life1347/color v1.7.0/go.mod h1:yXW8vSPZhOJLmveaa6cN+24V2xrX2Cuf3X7nVpiRidw=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20180323154445-8b799c424f57/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c h1:N7uWGS2fTwH/4BwxbHiJZNAFTSJ5yPU0emHsQWvkxEY=
|
||||
github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mholt/archiver v0.0.0-20180417220235-e4ef56d48eb0 h1:581DnhoG2Q33rqM3X6Is+8agf17B2vlzV/H52/Xvcd0=
|
||||
github.com/mholt/archiver v0.0.0-20180417220235-e4ef56d48eb0/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -257,6 +273,7 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
@@ -288,14 +305,24 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967 h1:x7xEyJDP7Hv3LVgvWhzioQqbC/KtuUhTigKlH/8ehhE=
|
||||
github.com/robfig/cron v0.0.0-20180505203441-b41be1df6967/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937 h1:+ryWjMVzFAkEz5zT+Ms49aROZwxlJce3x3zLTFpkz3Y=
|
||||
github.com/spf13/cobra v0.0.0-20180319062004-c439c4fa0937/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -303,6 +330,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670 h1:HQWT4ta3wW5GZ790GaqLCS+w1dvuA3rMfEQxLi+UOYU=
|
||||
github.com/ulikunitz/xz v0.0.0-20180703112113-636d36a76670/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
@@ -310,6 +338,7 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible h1:0pz39ZAycJFF7ju/1mepnk26RLVLBCWz1STcD3doU0A=
|
||||
github.com/wcharczuk/go-chart v2.0.1+incompatible/go.mod h1:PF5tmL4EIx/7Wf+hEkpCqYi5He4u90sw+0+6FhrryuE=
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@@ -327,6 +356,7 @@ go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -379,15 +409,17 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190619183051-17bc6164aac4 h1:FFQWNXvutleFrNfNdz+TAJiRUdRxjFpjBtDMQ2y3psA=
|
||||
golang.org/x/sys v0.0.0-20190619183051-17bc6164aac4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
||||
@@ -421,7 +421,11 @@ func (spec EnvironmentSpec) Validate() error {
|
||||
}
|
||||
|
||||
if spec.Poolsize < 0 {
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "EnvironmentSpec.Poolsize", spec.Poolsize, "Poolsize must be greater or equal to 0"))
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "EnvironmentSpec.Poolsize", spec.Poolsize, "must be greater or equal to 0"))
|
||||
}
|
||||
|
||||
if spec.TerminationGracePeriod < 0 {
|
||||
result = multierror.Append(result, MakeValidationErr(ErrorInvalidValue, "EnvironmentSpec.TerminationGracePeriod", spec.TerminationGracePeriod, "must be greater or equal to 0"))
|
||||
}
|
||||
|
||||
return result.ErrorOrNil()
|
||||
|
||||
@@ -1,464 +0,0 @@
|
||||
/*
|
||||
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 fission_cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/urfave/cli"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/urfavecli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/canaryconfig"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/environment"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/function"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/kubewatch"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/mqtrigger"
|
||||
_package "github.com/fission/fission/pkg/fission-cli/cmd/package"
|
||||
plugincmd "github.com/fission/fission/pkg/fission-cli/cmd/plugin"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/recorder"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/records"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/replay"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/support"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/timetrigger"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/version"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
"github.com/fission/fission/pkg/info"
|
||||
"github.com/fission/fission/pkg/plugin"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
|
||||
func cliHook(c *cli.Context) error {
|
||||
consolemsg.Verbosity = c.Int("verbosity")
|
||||
consolemsg.Verbose(2, "Verbosity = 2")
|
||||
return flagValueParser(c.Args())
|
||||
}
|
||||
|
||||
func NewCliApp() *cli.App {
|
||||
app := cli.NewApp()
|
||||
app.Name = "fission"
|
||||
app.Usage = "Serverless functions for Kubernetes"
|
||||
app.HideVersion = true
|
||||
app.CustomAppHelpTemplate = helpTemplate
|
||||
app.ExtraInfo = func() map[string]string {
|
||||
pluginInfo := map[string]string{}
|
||||
for _, pmd := range plugin.FindAll() {
|
||||
names := strings.Join(append([]string{pmd.Name}, pmd.Aliases...), ", ")
|
||||
pluginInfo[names] = pmd.Usage
|
||||
}
|
||||
return pluginInfo
|
||||
}
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{Name: flag.FISSION_SERVER, Value: "", Usage: "Fission server URL"},
|
||||
cli.IntFlag{Name: flag.GLOBAL_VERBOSITY, Value: 1, Usage: "CLI verbosity (0 is quiet, 1 is the default, 2 is verbose.)"},
|
||||
cli.BoolFlag{Name: flag.GLOBAL_PLUGIN, Hidden: true},
|
||||
}
|
||||
|
||||
// all resource create commands accept --spec
|
||||
specSaveFlag := cli.BoolFlag{Name: "spec", Usage: "Save to the spec directory instead of creating on cluster"}
|
||||
|
||||
// namespace reference for all objects
|
||||
fnNamespaceFlag := cli.StringFlag{Name: "fnNamespace, fns", Value: metav1.NamespaceDefault, Usage: "Namespace for function object"}
|
||||
envNamespaceFlag := cli.StringFlag{Name: flag.GetCliFlagName(flag.ENVIRONMENT_NAMESPACE, flag.ENVIRONMENT_NAMESPACE_ALIAS), Value: metav1.NamespaceDefault, Usage: "Namespace for environment object"}
|
||||
pkgNamespaceFlag := cli.StringFlag{Name: "pkgNamespace, pkgns", Value: metav1.NamespaceDefault, Usage: "Namespace for package object"}
|
||||
triggerNamespaceFlag := cli.StringFlag{Name: "triggerNamespace, triggerns", Value: metav1.NamespaceDefault, Usage: "Namespace for trigger object"}
|
||||
recorderNamespaceFlag := cli.StringFlag{Name: "recorderNamespace, recorderns", Value: metav1.NamespaceDefault, Usage: "Namespace for recorder object"}
|
||||
canaryNamespaceFlag := cli.StringFlag{Name: "canaryNamespace, canaryns", Value: metav1.NamespaceDefault, Usage: "Namespace for canary config object"}
|
||||
|
||||
// trigger method and url flags (used in function and route CLIs)
|
||||
htMethodFlag := cli.StringFlag{Name: "method", Value: http.MethodGet, Usage: "HTTP Method: GET|POST|PUT|DELETE|HEAD"}
|
||||
htUrlFlag := cli.StringFlag{Name: "url", Usage: "URL pattern (See gorilla/mux supported patterns)"}
|
||||
|
||||
// Resource & scale related flags (Used in env and function)
|
||||
minCpu := cli.IntFlag{Name: flag.RUNTIME_MINCPU, Usage: "Minimum CPU to be assigned to pod (In millicore, minimum 1)"}
|
||||
maxCpu := cli.IntFlag{Name: flag.RUNTIME_MAXCPU, Usage: "Maximum CPU to be assigned to pod (In millicore, minimum 1)"}
|
||||
minMem := cli.IntFlag{Name: flag.RUNTIME_MINMEMORY, Usage: "Minimum memory to be assigned to pod (In megabyte)"}
|
||||
maxMem := cli.IntFlag{Name: flag.RUNTIME_MAXMEMORY, Usage: "Maximum memory to be assigned to pod (In megabyte)"}
|
||||
minScale := cli.IntFlag{Name: flag.RUNTIME_MINSCALE, Usage: "Minimum number of pods (Uses resource inputs to configure HPA)"}
|
||||
maxScale := cli.IntFlag{Name: flag.RUNTIME_MAXSCALE, Usage: "Maximum number of pods (Uses resource inputs to configure HPA)"}
|
||||
targetcpu := cli.IntFlag{Name: flag.RUNTIME_TARGETCPU, Usage: "Target average CPU usage percentage across pods for scaling"}
|
||||
specializationTimeoutFlag := cli.IntFlag{Name: "specializationtimeout, st", Value: 120, Usage: "Timeout for newdeploy to wait for function pod creation"}
|
||||
|
||||
// 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: "local path or URL for single file source code"}
|
||||
fnDeployArchiveFlag := cli.StringSliceFlag{Name: "deployarchive, deploy", Usage: "local path or URL for deployment archive"}
|
||||
fnSrcArchiveFlag := cli.StringSliceFlag{Name: "sourcearchive, src, source", Usage: "local path or URL for source archive"}
|
||||
fnKeepURLFlag := cli.BoolFlag{Name: "keeparchiveurl, keepurl", Usage: "Keep the providing URL in archive instead of downloading file from it. (If set, no checksum will be generated for file integrity check. You must ensure the file won't be changed.)"}
|
||||
fnPkgNameFlag := cli.StringFlag{Name: "pkgname, pkg", Usage: "Name of the existing package (--deploy and --src and --env will be ignored), should be in the same namespace as the function"}
|
||||
fnPodFlag := cli.StringFlag{Name: "pod", Usage: "function pod name, optional (use latest if unspecified)"}
|
||||
fnFollowFlag := cli.BoolFlag{Name: "follow, f", Usage: "specify if the logs should be streamed"}
|
||||
fnDetailFlag := cli.BoolFlag{Name: "detail, d", Usage: "display detailed information"}
|
||||
fnLogDBTypeFlag := cli.StringFlag{Name: "dbtype", Usage: "log database type, e.g. influxdb (currently only influxdb is supported)"}
|
||||
fnBodyFlag := cli.StringFlag{Name: "body, b", Usage: "request body"}
|
||||
fnHeaderFlag := cli.StringSliceFlag{Name: "header, H", Usage: "request headers"}
|
||||
fnQueryFlag := cli.StringSliceFlag{Name: "query, q", Usage: "request query parameters: -q key1=value1 -q key2=value2"}
|
||||
fnEntryPointFlag := cli.StringFlag{Name: "entrypoint", Usage: "entry point for environment v2 to load with"}
|
||||
fnBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "build command for builder to run with"}
|
||||
fnSecretFlag := cli.StringSliceFlag{Name: "secret", Usage: "function access to secret, should be present in the same namespace as the function. You can provide multiple secrets using multiple --secrets flags. In the case of fn update the the secrets will be replaced by the provided list of secrets."}
|
||||
fnCfgMapFlag := cli.StringSliceFlag{Name: "configmap", Usage: "function access to configmap, should be present in the same namespace as the function. You can provide multiple configmaps using multiple --configmap flags. In case of fn update the configmaps will be replaced by the provided list of configmaps."}
|
||||
fnLogReverseQueryFlag := cli.BoolFlag{Name: "reverse, r", Usage: "specify the log reverse query base on time, it will be invalid if the 'follow' flag is specified"}
|
||||
fnLogCountFlag := cli.StringFlag{Name: "recordcount", Usage: "the n most recent log records"}
|
||||
fnForceFlag := cli.BoolFlag{Name: "force", Usage: "Force update a package even if it is used by one or more functions"}
|
||||
fnExecutorTypeFlag := cli.StringFlag{Name: "executortype", Value: types.ExecutorTypePoolmgr, Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy' defaults to 'poolmgr'"}
|
||||
fnExecutionTimeoutFlag := cli.IntFlag{Name: "fntimeout, ft", Value: 60, Usage: "Time duration to wait for the response while executing the function. If the flag is not provided, by default it will wait of 60s for the response."}
|
||||
fnTimeoutFlag := cli.DurationFlag{Name: "timeout, t", Value: 30 * time.Second, Usage: "The length of time to wait for the response. If set to zero or negative number, no timeout is set."}
|
||||
|
||||
fnSubcommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create new function (and optionally, an HTTP route to it)", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, specSaveFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnKeepURLFlag, fnEntryPointFlag, fnBuildCmdFlag, fnPkgNameFlag, htUrlFlag, htMethodFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, fnCfgMapFlag, fnSecretFlag, specializationTimeoutFlag, fnExecutionTimeoutFlag}, Action: urfavecli.Wrapper(function.Create)},
|
||||
{Name: "get", Usage: "Get function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: urfavecli.Wrapper(function.Get)},
|
||||
{Name: "getmeta", Usage: "Get function metadata", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: urfavecli.Wrapper(function.GetMeta)},
|
||||
{Name: "update", Usage: "Update function source code", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag, envNamespaceFlag, fnCodeFlag, fnSrcArchiveFlag, fnDeployArchiveFlag, fnKeepURLFlag, fnEntryPointFlag, fnPkgNameFlag, pkgNamespaceFlag, fnBuildCmdFlag, fnForceFlag, minCpu, maxCpu, minMem, maxMem, minScale, maxScale, fnExecutorTypeFlag, targetcpu, specializationTimeoutFlag, fnExecutionTimeoutFlag, fnSecretFlag, fnCfgMapFlag}, Action: urfavecli.Wrapper(function.Update)},
|
||||
{Name: "delete", Usage: "Delete function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag}, Action: urfavecli.Wrapper(function.Delete)},
|
||||
// TODO : for fnList, i feel like it's nice to allow --fns all, to list functions across all namespaces for cluster admins, although, this is against ns isolation.
|
||||
// so, in the future, if we end up using kubeconfig in fission cli and enforcing rolebindings to be created for users by admins etc, we can add this option at the time.
|
||||
{Name: "list", Usage: "List all functions in a namespace if specified, else, list functions across all namespaces", Flags: []cli.Flag{fnNamespaceFlag}, Action: urfavecli.Wrapper(function.List)},
|
||||
{Name: "logs", Usage: "Display function logs", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnPodFlag, fnFollowFlag, fnDetailFlag, fnLogDBTypeFlag, fnLogReverseQueryFlag, fnLogCountFlag}, Action: urfavecli.Wrapper(function.Log)},
|
||||
{Name: "test", Usage: "Test a function", Flags: []cli.Flag{fnNameFlag, fnNamespaceFlag, fnEnvNameFlag,
|
||||
fnCodeFlag, fnSrcArchiveFlag, htMethodFlag, fnBodyFlag, fnHeaderFlag, fnQueryFlag, fnTimeoutFlag},
|
||||
Action: urfavecli.Wrapper(function.Test)},
|
||||
}
|
||||
|
||||
// httptriggers
|
||||
htNameFlag := cli.StringFlag{Name: "name", Usage: "HTTP Trigger name"}
|
||||
htHostFlag := cli.StringFlag{Name: "host", Usage: "(DEPRECATED) Use --ingressrule instead"}
|
||||
htIngressFlag := cli.BoolFlag{Name: "createingress", Usage: "Creates ingress with same URL, defaults to false"}
|
||||
htIngressRuleFlag := cli.StringFlag{Name: "ingressrule", Usage: "Host for Ingress rule: --ingressrule host=path (the format of host/path depends on what ingress controller you used)"}
|
||||
htIngressAnnotationFlag := cli.StringSliceFlag{Name: "ingressannotation", Usage: "Annotation for Ingress: --ingressannotation key=value (the format of annotation depends on what ingress controller you used)"}
|
||||
htIngressTLSFlag := cli.StringFlag{Name: "ingresstls", Usage: "Name of the Secret contains TLS key and crt for Ingress (the usability of TLS features depends on what ingress controller you used)"}
|
||||
htFnNameFlag := cli.StringSliceFlag{Name: "function", Usage: "Name(s) of the function for this trigger. (If 2 functions are supplied with this flag, traffic gets routed to them based on weights supplied with --weight flag.)"}
|
||||
htFnWeightFlag := cli.IntSliceFlag{Name: "weight", Usage: "Weight for each function supplied with --function flag, in the same order. Used for canary deployment"}
|
||||
htFnFilterFlag := cli.StringFlag{Name: "function", Usage: "Name of the function for trigger(s)"}
|
||||
htSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create HTTP trigger", Flags: []cli.Flag{htNameFlag, htMethodFlag, htUrlFlag, htFnNameFlag, htIngressRuleFlag, htIngressAnnotationFlag, htIngressTLSFlag, htIngressFlag, fnNamespaceFlag, specSaveFlag, htFnWeightFlag, htHostFlag}, Action: urfavecli.Wrapper(httptrigger.Create)},
|
||||
{Name: "get", Usage: "Get HTTP trigger", Flags: []cli.Flag{htNameFlag}, Action: urfavecli.Wrapper(httptrigger.Get)},
|
||||
{Name: "update", Usage: "Update HTTP trigger", Flags: []cli.Flag{htNameFlag, triggerNamespaceFlag, htFnNameFlag, htIngressRuleFlag, htIngressAnnotationFlag, htIngressTLSFlag, htIngressFlag, htFnWeightFlag, htHostFlag}, Action: urfavecli.Wrapper(httptrigger.Update)},
|
||||
{Name: "delete", Usage: "Delete HTTP trigger", Flags: []cli.Flag{htNameFlag, triggerNamespaceFlag, htFnFilterFlag}, Action: urfavecli.Wrapper(httptrigger.Delete)},
|
||||
{Name: "list", Usage: "List HTTP triggers", Flags: []cli.Flag{triggerNamespaceFlag, htFnFilterFlag}, Action: urfavecli.Wrapper(httptrigger.List)},
|
||||
}
|
||||
|
||||
// timetriggers
|
||||
ttNameFlag := cli.StringFlag{Name: "name", Usage: "Time Trigger name"}
|
||||
ttCronFlag := cli.StringFlag{Name: "cron", Usage: "Time trigger cron spec with each asterisk representing respectively second, minute, hour, the day of the month, month and day of the week. Also supports readable formats like '@every 5m', '@hourly'"}
|
||||
ttFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"}
|
||||
ttRoundFlag := cli.IntFlag{Name: "round", Value: 1, Usage: "Get next N rounds of invocation time"}
|
||||
ttSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create time trigger", Flags: []cli.Flag{ttNameFlag, ttFnNameFlag, fnNamespaceFlag, ttCronFlag, specSaveFlag}, Action: urfavecli.Wrapper(timetrigger.Create)},
|
||||
{Name: "update", Usage: "Update time trigger", Flags: []cli.Flag{ttNameFlag, triggerNamespaceFlag, ttCronFlag, ttFnNameFlag}, Action: urfavecli.Wrapper(timetrigger.Update)},
|
||||
{Name: "delete", Usage: "Delete time trigger", Flags: []cli.Flag{ttNameFlag, triggerNamespaceFlag}, Action: urfavecli.Wrapper(timetrigger.Delete)},
|
||||
{Name: "list", Usage: "List time triggers", Flags: []cli.Flag{triggerNamespaceFlag}, Action: urfavecli.Wrapper(timetrigger.List)},
|
||||
{Name: "showschedule", Aliases: []string{"show"}, Usage: "Show schedule for cron spec", Flags: []cli.Flag{ttCronFlag, ttRoundFlag}, Action: urfavecli.Wrapper(timetrigger.Show)},
|
||||
}
|
||||
|
||||
// Message queue trigger
|
||||
mqtNameFlag := cli.StringFlag{Name: "name", Usage: "Message queue Trigger name"}
|
||||
mqtFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"}
|
||||
mqtMQTypeFlag := cli.StringFlag{Name: "mqtype", Value: "nats-streaming", Usage: "Message queue type, e.g. nats-streaming, azure-storage-queue (optional)"}
|
||||
mqtTopicFlag := cli.StringFlag{Name: "topic", Usage: "Message queue Topic the trigger listens on"}
|
||||
mqtRespTopicFlag := cli.StringFlag{Name: "resptopic", Usage: "Topic that the function response is sent on (optional; response discarded if unspecified)"}
|
||||
mqtErrorTopicFlag := cli.StringFlag{Name: "errortopic", Usage: "Topic that the function error messages are sent to (optional; errors discarded if unspecified"}
|
||||
mqtMaxRetries := cli.IntFlag{Name: "maxretries", Value: 0, Usage: "Maximum number of times the function will be retried upon failure (optional; default is 0)"}
|
||||
mqtMsgContentType := cli.StringFlag{Name: "contenttype, c", Value: "application/json", Usage: "Content type of messages that publish to the topic (optional)"}
|
||||
mqtSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create Message queue trigger", Flags: []cli.Flag{mqtNameFlag, mqtFnNameFlag, fnNamespaceFlag, mqtMQTypeFlag, mqtTopicFlag, mqtRespTopicFlag, mqtErrorTopicFlag, mqtMaxRetries, mqtMsgContentType, specSaveFlag}, Action: urfavecli.Wrapper(mqtrigger.Create)},
|
||||
{Name: "update", Usage: "Update message queue trigger", Flags: []cli.Flag{mqtNameFlag, triggerNamespaceFlag, mqtTopicFlag, mqtRespTopicFlag, mqtErrorTopicFlag, mqtMaxRetries, mqtFnNameFlag, mqtMsgContentType}, Action: urfavecli.Wrapper(mqtrigger.Update)},
|
||||
{Name: "delete", Usage: "Delete message queue trigger", Flags: []cli.Flag{mqtNameFlag, triggerNamespaceFlag}, Action: urfavecli.Wrapper(mqtrigger.Delete)},
|
||||
{Name: "list", Usage: "List message queue triggers", Flags: []cli.Flag{mqtMQTypeFlag, triggerNamespaceFlag}, Action: urfavecli.Wrapper(mqtrigger.List)},
|
||||
}
|
||||
|
||||
// Recorders
|
||||
recNameFlag := cli.StringFlag{Name: "name", Usage: "Recorder name"}
|
||||
recFnFlag := cli.StringFlag{Name: "function", Usage: "Record Function name(s): --function=fnA"}
|
||||
recTriggersFlag := cli.StringSliceFlag{Name: "trigger", Usage: "Record Trigger name(s): --trigger=trigger1,trigger2,trigger3"}
|
||||
//recRetentionPolFlag := cli.StringFlag{Name: "retention", Usage: "Retention policy (number of days)"}
|
||||
//recEvictionPolFlag := cli.StringFlag{Name: "eviction", Usage: "Eviction policy (default LRU)"}
|
||||
recEnabled := cli.BoolFlag{Name: "enable", Usage: "Enable recorder"}
|
||||
recDisabled := cli.BoolFlag{Name: "disable", Usage: "Disable recorder"}
|
||||
recSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create recorder", Flags: []cli.Flag{recNameFlag, recFnFlag, recTriggersFlag, specSaveFlag}, Action: urfavecli.Wrapper(recorder.Create)},
|
||||
{Name: "get", Usage: "Get recorder", Flags: []cli.Flag{recNameFlag}, Action: urfavecli.Wrapper(recorder.Get)},
|
||||
{Name: "update", Usage: "Update recorder", Flags: []cli.Flag{recNameFlag, recFnFlag, recTriggersFlag, recEnabled, recDisabled}, Action: urfavecli.Wrapper(recorder.Update)},
|
||||
{Name: "delete", Usage: "Delete recorder", Flags: []cli.Flag{recNameFlag, recorderNamespaceFlag}, Action: urfavecli.Wrapper(recorder.Delete)},
|
||||
{Name: "list", Usage: "List recorders", Flags: []cli.Flag{}, Action: urfavecli.Wrapper(recorder.List)},
|
||||
}
|
||||
|
||||
// View records
|
||||
filterTimeFrom := cli.StringFlag{Name: "from", Usage: "Filter records by time interval; specify start of interval"}
|
||||
filterTimeTo := cli.StringFlag{Name: "to", Usage: "Filter records by time interval; specify end of interval"}
|
||||
filterFunction := cli.StringFlag{Name: "function", Usage: "Filter records by function"}
|
||||
filterTrigger := cli.StringFlag{Name: "trigger", Usage: "Filter records by trigger"}
|
||||
verbosityFlag := cli.BoolFlag{Name: "v", Usage: "Toggle verbosity -- view more detailed requests/responses"}
|
||||
vvFlag := cli.BoolFlag{Name: "vv", Usage: "Toggle verbosity -- view raw requests/responses"}
|
||||
recViewSubcommands := []cli.Command{
|
||||
{Name: "view", Usage: "View existing records", Flags: []cli.Flag{filterTimeTo, filterTimeFrom, filterFunction, filterTrigger, verbosityFlag, vvFlag}, Action: urfavecli.Wrapper(records.View)},
|
||||
}
|
||||
|
||||
// Replay records
|
||||
reqIDFlag := cli.StringFlag{Name: "reqUID", Usage: "Replay a particular request by providing the reqUID (to view reqUIDs, do 'fission records view')"}
|
||||
|
||||
// environments
|
||||
envNameFlag := cli.StringFlag{Name: flag.RESOURCE_NAME, Usage: "Environment name"}
|
||||
envPoolsizeFlag := cli.IntFlag{Name: flag.ENVIRONMENT_POOLSIZE, Value: 3, Usage: "Size of the pool"}
|
||||
envImageFlag := cli.StringFlag{Name: flag.ENVIRONMENT_IMAGE, Usage: "Environment image URL"}
|
||||
envBuilderImageFlag := cli.StringFlag{Name: flag.ENVIRONMENT_BUILDER, Usage: "Environment builder image URL (optional)"}
|
||||
envBuildCmdFlag := cli.StringFlag{Name: flag.ENVIRONMENT_BUILDCOMMAND, Usage: "Build command for environment builder to build source package (optional)"}
|
||||
envKeepArchiveFlag := cli.BoolFlag{Name: flag.ENVIRONMENT_KEEPARCHIVE, Usage: "Keep the archive instead of extracting it into a directory (optional, defaults to false)"}
|
||||
envExternalNetworkFlag := cli.BoolFlag{Name: flag.ENVIRONMENT_EXTERNAL_NETWORK, Usage: "Allow environment access external network when istio feature enabled (optional, defaults to false)"}
|
||||
envTerminationGracePeriodFlag := cli.Int64Flag{Name: flag.GetCliFlagName(flag.ENVIRONMENT_GRACE_PERIOD, flag.ENVIRONMENT_GRACE_PERIOD_ALIAS), Value: 360, Usage: "The grace time (in seconds) for pod to perform connection draining before termination (optional)"}
|
||||
envVersionFlag := cli.IntFlag{Name: flag.ENVIRONMENT_VERSION, Value: 1, Usage: "Environment API version (1 means v1 interface)"}
|
||||
envSubcommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Add an environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, envKeepArchiveFlag, minCpu, maxCpu, minMem, maxMem, envVersionFlag, envExternalNetworkFlag, envTerminationGracePeriodFlag, specSaveFlag}, Action: urfavecli.Wrapper(environment.Create)},
|
||||
{Name: "get", Usage: "Get environment details", Flags: []cli.Flag{envNameFlag, envNamespaceFlag}, Action: urfavecli.Wrapper(environment.Get)},
|
||||
{Name: "update", Usage: "Update environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag, envPoolsizeFlag, envImageFlag, envBuilderImageFlag, envBuildCmdFlag, envKeepArchiveFlag, minCpu, maxCpu, minMem, maxMem, envExternalNetworkFlag, envTerminationGracePeriodFlag}, Action: urfavecli.Wrapper(environment.Update)},
|
||||
{Name: "delete", Usage: "Delete environment", Flags: []cli.Flag{envNameFlag, envNamespaceFlag}, Action: urfavecli.Wrapper(environment.Delete)},
|
||||
{Name: "list", Usage: "List all environments", Flags: []cli.Flag{envNamespaceFlag}, Action: urfavecli.Wrapper(environment.List)},
|
||||
}
|
||||
|
||||
// watches
|
||||
wNameFlag := cli.StringFlag{Name: "name", Usage: "Watch name"}
|
||||
wFnNameFlag := cli.StringFlag{Name: "function", Usage: "Function name"}
|
||||
wNamespaceFlag := cli.StringFlag{Name: "ns", Usage: "Namespace of resource to watch"}
|
||||
wObjTypeFlag := cli.StringFlag{Name: "type", Usage: "Type of resource to watch (Pod, Service, etc.)"}
|
||||
wLabelsFlag := cli.StringFlag{Name: "labels", Usage: "Label selector of the form a=b,c=d"}
|
||||
wSubCommands := []cli.Command{
|
||||
{Name: "create", Aliases: []string{"add"}, Usage: "Create a watch", Flags: []cli.Flag{wFnNameFlag, fnNamespaceFlag, wNamespaceFlag, wObjTypeFlag, wLabelsFlag, specSaveFlag}, Action: urfavecli.Wrapper(kubewatch.Create)},
|
||||
// TODO add update flag when supported
|
||||
{Name: "delete", Usage: "Delete watch", Flags: []cli.Flag{wNameFlag, triggerNamespaceFlag}, Action: urfavecli.Wrapper(kubewatch.Delete)},
|
||||
{Name: "list", Usage: "List all watches", Flags: []cli.Flag{triggerNamespaceFlag}, Action: urfavecli.Wrapper(kubewatch.List)},
|
||||
}
|
||||
|
||||
// packages
|
||||
pkgNameFlag := cli.StringFlag{Name: "name", Usage: "Package name"}
|
||||
pkgForceFlag := cli.BoolFlag{Name: "force, f", Usage: "Force update a package even if it is used by one or more functions"}
|
||||
pkgEnvironmentFlag := cli.StringFlag{Name: "env", Usage: "Environment name"}
|
||||
pkgSrcArchiveFlag := cli.StringSliceFlag{Name: "sourcearchive, src", Usage: "Local path or URL for source archive"}
|
||||
pkgDeployArchiveFlag := cli.StringSliceFlag{Name: "deployarchive, deploy", Usage: "Local path or URL for binary archive"}
|
||||
pkgKeepURLFlag := cli.BoolFlag{Name: "keeparchiveurl, keepurl", Usage: "Keep the providing URL in archive instead of downloading file from it. (If set, no checksum will be generated for file integrity check. You must ensure the file won't be changed.)"}
|
||||
pkgBuildCmdFlag := cli.StringFlag{Name: "buildcmd", Usage: "Build command for builder to run with"}
|
||||
pkgOutputFlag := cli.StringFlag{Name: "output, o", Usage: "Output filename to save archive content"}
|
||||
pkgStatusFlag := cli.StringFlag{Name: "status", Usage: `Filter packages by status`}
|
||||
pkgOrphanFlag := cli.BoolFlag{Name: "orphan", Usage: "Orphan packages that are not referenced by any function"}
|
||||
pkgSubCommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create new package", Flags: []cli.Flag{pkgNamespaceFlag, pkgEnvironmentFlag, envNamespaceFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgKeepURLFlag, pkgBuildCmdFlag}, Action: urfavecli.Wrapper(_package.Create)},
|
||||
{Name: "update", Usage: "Update package", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgEnvironmentFlag, envNamespaceFlag, pkgSrcArchiveFlag, pkgDeployArchiveFlag, pkgKeepURLFlag, pkgBuildCmdFlag, pkgForceFlag}, Action: urfavecli.Wrapper(_package.Update)},
|
||||
{Name: "rebuild", Usage: "Rebuild a failed package", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag}, Action: urfavecli.Wrapper(_package.Rebuild)},
|
||||
{Name: "getsrc", Usage: "Get source archive content", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgOutputFlag}, Action: urfavecli.Wrapper(_package.GetSrc)},
|
||||
{Name: "getdeploy", Usage: "Get deployment archive content", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgOutputFlag}, Action: urfavecli.Wrapper(_package.GetDeploy)},
|
||||
{Name: "info", Usage: "Show package information", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag}, Action: urfavecli.Wrapper(_package.Info)},
|
||||
{Name: "list", Usage: "List all packages", Flags: []cli.Flag{pkgOrphanFlag, pkgStatusFlag, pkgNamespaceFlag}, Action: urfavecli.Wrapper(_package.List)},
|
||||
{Name: "delete", Usage: "Delete package", Flags: []cli.Flag{pkgNameFlag, pkgNamespaceFlag, pkgForceFlag, pkgOrphanFlag}, Action: urfavecli.Wrapper(_package.Delete)},
|
||||
}
|
||||
|
||||
// specs
|
||||
specDirFlag := cli.StringFlag{Name: "specdir", Usage: "Directory to store specs, defaults to ./specs"}
|
||||
specNameFlag := cli.StringFlag{Name: "name", Usage: "(optional) Name for the app, applied to resources as a Kubernetes annotation"}
|
||||
specDeployIDFlag := cli.StringFlag{Name: "deployid, id", Usage: "(optional) Deployment ID for the spec deployment config"}
|
||||
specWaitFlag := cli.BoolFlag{Name: "wait", Usage: "Wait for package builds"}
|
||||
specWatchFlag := cli.BoolFlag{Name: "watch", Usage: "Watch local files for change, and re-apply specs as necessary"}
|
||||
specDeleteFlag := cli.BoolFlag{Name: "delete", Usage: "Allow apply to delete resources that no longer exist in the specification"}
|
||||
specSubCommands := []cli.Command{
|
||||
{Name: "init", Usage: "Create an initial declarative app specification", Flags: []cli.Flag{specDirFlag, specNameFlag, specDeployIDFlag}, Action: urfavecli.Wrapper(spec.Init)},
|
||||
{Name: "validate", Usage: "Validate Fission app specification", Flags: []cli.Flag{specDirFlag}, Action: urfavecli.Wrapper(spec.Validate)},
|
||||
{Name: "apply", Usage: "Create, update, or delete Fission resources from app specification", Flags: []cli.Flag{specDirFlag, specDeleteFlag, specWaitFlag, specWatchFlag}, Action: urfavecli.Wrapper(spec.Apply)},
|
||||
{Name: "destroy", Usage: "Delete all Fission resources in the app specification", Flags: []cli.Flag{specDirFlag}, Action: urfavecli.Wrapper(spec.Destroy)},
|
||||
}
|
||||
|
||||
// support
|
||||
supportOutputFlag := cli.StringFlag{Name: "output, o", Value: support.DEFAULT_OUTPUT_DIR, Usage: "Output directory to save dump archive/files"}
|
||||
supportNoZipFlag := cli.BoolFlag{Name: "nozip", Usage: "Save dump information into multiple files instead of single zip file"}
|
||||
supportSubCommands := []cli.Command{
|
||||
{Name: "dump", Usage: "Collect & dump all necessary for troubleshooting", Flags: []cli.Flag{supportOutputFlag, supportNoZipFlag}, Action: urfavecli.Wrapper(support.Dump)},
|
||||
}
|
||||
|
||||
// canary configs
|
||||
canaryConfigNameFlag := cli.StringFlag{Name: "name", Usage: "Name for the canary config"}
|
||||
triggerNameFlag := cli.StringFlag{Name: "httptrigger", Usage: "Http trigger that this config references"}
|
||||
newFunc := cli.StringFlag{Name: "newfunction", Usage: "New version of the function"}
|
||||
oldFunc := cli.StringFlag{Name: "oldfunction", Usage: "Old stable version of the function"}
|
||||
weightIncrementFlag := cli.IntFlag{Name: "increment-step", Value: 20, Usage: "Weight increment step for function"}
|
||||
incrementIntervalFlag := cli.StringFlag{Name: "increment-interval", Value: "2m", Usage: "Weight increment interval, string representation of time.Duration, ex : 1m, 2h, 2d"}
|
||||
failureThresholdFlag := cli.IntFlag{Name: "failure-threshold", Value: 10, Usage: "Threshold in percentage beyond which the new version of the function is considered unstable"}
|
||||
canarySubCommands := []cli.Command{
|
||||
{Name: "create", Usage: "Create a canary config", Flags: []cli.Flag{canaryConfigNameFlag, triggerNameFlag, newFunc, oldFunc, fnNamespaceFlag, weightIncrementFlag, incrementIntervalFlag, failureThresholdFlag}, Action: urfavecli.Wrapper(canaryconfig.Create)},
|
||||
{Name: "get", Usage: "View parameters in a canary config", Flags: []cli.Flag{canaryConfigNameFlag, canaryNamespaceFlag}, Action: urfavecli.Wrapper(canaryconfig.Get)},
|
||||
{Name: "update", Usage: "Update parameters of a canary config", Flags: []cli.Flag{canaryConfigNameFlag, canaryNamespaceFlag, incrementIntervalFlag, weightIncrementFlag, failureThresholdFlag}, Action: urfavecli.Wrapper(canaryconfig.Update)},
|
||||
{Name: "delete", Usage: "Delete a canary config", Flags: []cli.Flag{canaryConfigNameFlag, canaryNamespaceFlag}, Action: urfavecli.Wrapper(canaryconfig.Delete)},
|
||||
{Name: "list", Usage: "List all canary configs in a namespace", Flags: []cli.Flag{canaryNamespaceFlag}, Action: urfavecli.Wrapper(canaryconfig.List)},
|
||||
}
|
||||
|
||||
pluginSubCommands := []cli.Command{
|
||||
{Name: "list", Usage: "List installed client plugins", Action: urfavecli.Wrapper(plugincmd.List)},
|
||||
}
|
||||
|
||||
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: "timetrigger", Aliases: []string{"tt", "timer"}, Usage: "Manage Time triggers (timers) for functions", Subcommands: ttSubcommands},
|
||||
{Name: "mqtrigger", Aliases: []string{"mqt", "messagequeue"}, Usage: "Manage message queue triggers for functions", Subcommands: mqtSubcommands},
|
||||
{Name: "recorder", Usage: "Manage recorders for functions", Subcommands: recSubcommands, Hidden: true},
|
||||
{Name: "records", Usage: "View records with optional filters", Subcommands: recViewSubcommands, Hidden: true},
|
||||
{Name: "replay", Usage: "Replay records", Flags: []cli.Flag{reqIDFlag}, Action: urfavecli.Wrapper(replay.Replay)},
|
||||
{Name: "environment", Aliases: []string{"env"}, Usage: "Manage environments", Subcommands: envSubcommands},
|
||||
{Name: "watch", Aliases: []string{"w"}, Usage: "Manage watches", Subcommands: wSubCommands},
|
||||
{Name: "package", Aliases: []string{"pkg"}, Usage: "Manage packages", Subcommands: pkgSubCommands},
|
||||
{Name: "spec", Aliases: []string{"specs"}, Usage: "Manage a declarative app specification", Subcommands: specSubCommands},
|
||||
{Name: "support", Usage: "Collect an archive of diagnostic information for support", Subcommands: supportSubCommands},
|
||||
{Name: "canary-config", Aliases: []string{}, Usage: "Create, Update and manage Canary Configs", Subcommands: canarySubCommands},
|
||||
{Name: "plugin", Aliases: []string{"plugins"}, Usage: "Manage Fission CLI plugins", Subcommands: pluginSubCommands},
|
||||
{Name: "version", Usage: "Version information", Action: urfavecli.Wrapper(version.Version)},
|
||||
}
|
||||
|
||||
app.Before = cliHook
|
||||
app.Action = handleNoCommand
|
||||
return app
|
||||
}
|
||||
|
||||
func handleNoCommand(ctx *cli.Context) error {
|
||||
if ctx.GlobalBool("plugin") {
|
||||
bs, err := json.Marshal(plugin.Metadata{
|
||||
Version: info.Version,
|
||||
Usage: ctx.App.Usage,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Errorf("Failed to marshal plugin metadata to JSON: %v", err)
|
||||
}
|
||||
fmt.Println(string(bs))
|
||||
return nil
|
||||
}
|
||||
if len(ctx.Args()) > 0 {
|
||||
return handleCommandNotFound(ctx, ctx.Args().First())
|
||||
}
|
||||
|
||||
return cli.ShowAppHelp(ctx)
|
||||
}
|
||||
|
||||
func handleCommandNotFound(ctx *cli.Context, subCommand string) error {
|
||||
pmd, err := plugin.Find(subCommand)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case plugin.ErrPluginNotFound:
|
||||
url, ok := plugin.SearchRegistries(subCommand)
|
||||
if !ok {
|
||||
return errors.New("No help topic for '" + subCommand + "'")
|
||||
}
|
||||
return errors.Errorf(`Command '%v' is not installed.
|
||||
It is available to download at '%v'.
|
||||
|
||||
To install it for your local Fission CLI:
|
||||
1. Download the plugin binary for your OS from the URL
|
||||
2. Ensure that the plugin binary is executable: chmod +x <binary>
|
||||
2. Add the plugin binary to your $PATH: mv <binary> /usr/local/bin/fission-%v`, subCommand, url, subCommand)
|
||||
default:
|
||||
return errors.Wrap(err, "Error occurred when invoking "+subCommand)
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild global arguments string (urfave/cli does not have an option to get the raw input of the global flags)
|
||||
var globalArgs []string
|
||||
for _, globalFlagName := range ctx.GlobalFlagNames() {
|
||||
if globalFlagName == "plugin" {
|
||||
continue
|
||||
}
|
||||
val := fmt.Sprintf("%v", ctx.GlobalGeneric(globalFlagName))
|
||||
if len(val) > 0 {
|
||||
globalArgs = append(globalArgs, fmt.Sprintf("--%v", globalFlagName), val)
|
||||
}
|
||||
}
|
||||
args := append(globalArgs, ctx.Args().Tail()...)
|
||||
|
||||
err = plugin.Exec(pmd, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func flagValueParser(args []string) error {
|
||||
// all input value for flags are properly set
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var flagIndexes []int
|
||||
var errorFlags []string
|
||||
|
||||
// find out all flag indexes
|
||||
for i, v := range args {
|
||||
// support both flags with "--" and "-"
|
||||
if strings.HasPrefix(v, "-") {
|
||||
flagIndexes = append(flagIndexes, i)
|
||||
}
|
||||
}
|
||||
|
||||
// add total length of args to indicate the end of args
|
||||
flagIndexes = append(flagIndexes, len(args))
|
||||
|
||||
for i := 0; i < len(flagIndexes)-1; i++ {
|
||||
// if the difference between the flag index i and i+1
|
||||
// is bigger then 2 means that CLI receives extra arguments
|
||||
// for one flag. For example,
|
||||
// 1. fission fn create --name e1 --code examples/nodejs/* --env nodejs ...
|
||||
// The wildcard will be extracted to multiple files and cause the difference between `--code` and `--env` large than 2.
|
||||
// 2. fission fn create --spec --name e1 ...
|
||||
// The difference between --spec and --name is 1.
|
||||
if flagIndexes[i+1]-flagIndexes[i] > 2 {
|
||||
index := flagIndexes[i]
|
||||
errorFlags = append(errorFlags, args[index])
|
||||
}
|
||||
}
|
||||
|
||||
if len(errorFlags) > 0 {
|
||||
return errors.Errorf("Unable to parse flags: %v\nThe argument should have only one input value. Please quote the input value if it contains wildcard characters(*).", strings.Join(errorFlags[:], ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var helpTemplate = `NAME:
|
||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||
{{.Name}}:{{end}}{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||
|
||||
PLUGIN COMMANDS:{{ range $name, $usage := ExtraInfo }}
|
||||
{{$name}}{{"\t"}}{{$usage}}{{end}}
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
||||
{{end}}{{$option}}{{end}}{{end}}
|
||||
`
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
Copyright 2019 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 cobra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
wCli "github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra/helptemplate"
|
||||
cmd "github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
var _ wCli.Input = &Cli{}
|
||||
|
||||
type (
|
||||
Cli struct {
|
||||
c *cobra.Command
|
||||
args []string
|
||||
}
|
||||
)
|
||||
|
||||
// Parse is only for converting urfave *cli.Context to Input and will be removed in future.
|
||||
func Parse(cmd *cobra.Command, args []string) wCli.Input {
|
||||
return Cli{c: cmd, args: args}
|
||||
}
|
||||
|
||||
func Wrapper(action cmd.CommandAction) func(*cobra.Command, []string) error {
|
||||
return func(c *cobra.Command, args []string) error {
|
||||
return action(Cli{c: c, args: args})
|
||||
}
|
||||
}
|
||||
|
||||
func SetFlags(cmd *cobra.Command, flagSet flag.FlagSet) {
|
||||
aliases := make(map[string]string)
|
||||
|
||||
// set required flags
|
||||
for _, f := range flagSet.Required {
|
||||
requiredFlags(cmd, f)
|
||||
for _, alias := range f.Aliases {
|
||||
aliases[alias] = f.Name
|
||||
}
|
||||
}
|
||||
|
||||
// set optional flags
|
||||
for _, f := range flagSet.Optional {
|
||||
optionalFlags(cmd, f)
|
||||
for _, alias := range f.Aliases {
|
||||
aliases[alias] = f.Name
|
||||
}
|
||||
}
|
||||
|
||||
// set flag alias normalize function
|
||||
cmd.Flags().SetNormalizeFunc(
|
||||
func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
n, ok := aliases[name]
|
||||
if ok {
|
||||
name = n
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
},
|
||||
)
|
||||
cmd.Flags().SortFlags = false
|
||||
}
|
||||
|
||||
func optionalFlags(cmd *cobra.Command, flags ...flag.Flag) {
|
||||
for _, f := range flags {
|
||||
toCobraFlag(cmd, f)
|
||||
if f.Deprecated {
|
||||
usage := fmt.Sprintf("Use --%v instead. The flag still works for now and will be removed in future", f.Substitute)
|
||||
cmd.Flags().MarkDeprecated(f.Name, usage)
|
||||
} else if f.Hidden {
|
||||
cmd.Flags().MarkHidden(f.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func requiredFlags(cmd *cobra.Command, flags ...flag.Flag) {
|
||||
for _, f := range flags {
|
||||
toCobraFlag(cmd, f)
|
||||
cmd.MarkFlagRequired(f.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func toCobraFlag(cmd *cobra.Command, f flag.Flag) {
|
||||
// Workaround to pass aliases to templater for generating flag aliases.
|
||||
if len(f.Aliases) > 0 {
|
||||
var aliases []string
|
||||
for _, alias := range f.Aliases {
|
||||
dash := "--"
|
||||
if len(alias) == 1 {
|
||||
dash = "-"
|
||||
f.Short = alias
|
||||
}
|
||||
aliases = append(aliases, dash+alias)
|
||||
}
|
||||
// Use separator to separator aliases and usage text.
|
||||
f.Usage = fmt.Sprintf("%s%s%s",
|
||||
strings.Join(aliases, helptemplate.AliasSeparator),
|
||||
helptemplate.AliasSeparator, f.Usage)
|
||||
}
|
||||
|
||||
switch f.Type {
|
||||
case flag.Bool:
|
||||
val, ok := f.DefaultValue.(bool)
|
||||
if !ok {
|
||||
val = false
|
||||
}
|
||||
cmd.Flags().BoolP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.String:
|
||||
val, ok := f.DefaultValue.(string)
|
||||
if !ok {
|
||||
val = ""
|
||||
}
|
||||
cmd.Flags().StringP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.StringSlice:
|
||||
val, ok := f.DefaultValue.([]string)
|
||||
if !ok {
|
||||
val = []string{}
|
||||
}
|
||||
cmd.Flags().StringArrayP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Int:
|
||||
val, ok := f.DefaultValue.(int)
|
||||
if !ok {
|
||||
val = 0
|
||||
}
|
||||
cmd.Flags().IntP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.IntSlice:
|
||||
val, ok := f.DefaultValue.([]int)
|
||||
if !ok {
|
||||
val = []int{}
|
||||
}
|
||||
cmd.Flags().IntSliceP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Int64:
|
||||
val, ok := f.DefaultValue.(int64)
|
||||
if !ok {
|
||||
val = 0
|
||||
}
|
||||
cmd.Flags().Int64P(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Int64Slice:
|
||||
val, ok := f.DefaultValue.([]int64)
|
||||
if !ok {
|
||||
val = []int64{}
|
||||
}
|
||||
cmd.Flags().Int64SliceP(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Float32:
|
||||
val, ok := f.DefaultValue.(float32)
|
||||
if !ok {
|
||||
val = 0
|
||||
}
|
||||
cmd.Flags().Float32P(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Float64:
|
||||
val, ok := f.DefaultValue.(float64)
|
||||
if !ok {
|
||||
val = 0
|
||||
}
|
||||
cmd.Flags().Float64P(f.Name, f.Short, val, f.Usage)
|
||||
case flag.Duration:
|
||||
val, ok := f.DefaultValue.(time.Duration)
|
||||
if !ok {
|
||||
val = 0
|
||||
}
|
||||
cmd.Flags().DurationP(f.Name, f.Short, val, f.Usage)
|
||||
}
|
||||
}
|
||||
|
||||
func WrapperChain(actions ...cmd.CommandAction) func(*cobra.Command, []string) error {
|
||||
return func(c *cobra.Command, args []string) error {
|
||||
for _, action := range actions {
|
||||
err := action(Cli{c: c, args: args})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (u Cli) IsSet(key string) bool {
|
||||
return u.c.Flags().Changed(key)
|
||||
}
|
||||
|
||||
func (u Cli) Bool(key string) bool {
|
||||
// TODO: ignore the error here, but we should handle it properly in some ways.
|
||||
v, _ := u.c.Flags().GetBool(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) String(key string) string {
|
||||
v, _ := u.c.Flags().GetString(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) StringSlice(key string) []string {
|
||||
// difference between StringSlice and StringArray
|
||||
// --ss="one" --ss="two,three"
|
||||
// StringSlice* - will result in []string{"one", "two", "three"}
|
||||
// StringArray* - will result in []s
|
||||
// https://github.com/spf13/cobra/issues/661#issuecomment-377684634
|
||||
// Use StringArray here to fit our use case.
|
||||
v, _ := u.c.Flags().GetStringArray(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) Int(key string) int {
|
||||
v, _ := u.c.Flags().GetInt(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) IntSlice(key string) []int {
|
||||
v, _ := u.c.Flags().GetIntSlice(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) Int64(key string) int64 {
|
||||
v, _ := u.c.Flags().GetInt64(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) Int64Slice(key string) []int64 {
|
||||
v, _ := u.c.Flags().GetIntSlice(key)
|
||||
vals := make([]int64, len(v))
|
||||
for _, i := range v {
|
||||
vals = append(vals, int64(i))
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
func (u Cli) GlobalBool(key string) bool {
|
||||
v, _ := u.c.Flags().GetBool(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalString(key string) string {
|
||||
v, _ := u.c.Flags().GetString(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalStringSlice(key string) []string {
|
||||
v, _ := u.c.Flags().GetStringArray(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt(key string) int {
|
||||
v, _ := u.c.Flags().GetInt(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalIntSlice(key string) []int {
|
||||
v, _ := u.c.Flags().GetIntSlice(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt64(key string) int64 {
|
||||
v, _ := u.c.Flags().GetInt64(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt64Slice(key string) []int64 {
|
||||
v, _ := u.c.Flags().GetInt64Slice(key)
|
||||
return v
|
||||
}
|
||||
|
||||
func (u Cli) Duration(key string) time.Duration {
|
||||
v, _ := u.c.Flags().GetDuration(key)
|
||||
return v
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Original file location: https://github.com/kubernetes/kubectl/tree/master/pkg/util/templates
|
||||
|
||||
package helptemplate
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type CommandGroup struct {
|
||||
Message string
|
||||
Commands []*cobra.Command
|
||||
}
|
||||
|
||||
type CommandGroups []CommandGroup
|
||||
|
||||
func (g CommandGroups) Add(c *cobra.Command) {
|
||||
for _, group := range g {
|
||||
c.AddCommand(group.Commands...)
|
||||
}
|
||||
}
|
||||
|
||||
func (g CommandGroups) Has(c *cobra.Command) bool {
|
||||
for _, group := range g {
|
||||
for _, command := range group.Commands {
|
||||
if command == c {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AddAdditionalCommands(g CommandGroups, message string, cmds []*cobra.Command) CommandGroups {
|
||||
group := CommandGroup{Message: message}
|
||||
for _, c := range cmds {
|
||||
// Don't show commands that have no short description
|
||||
if !g.Has(c) && len(c.Short) != 0 {
|
||||
group.Commands = append(group.Commands, c)
|
||||
}
|
||||
}
|
||||
if len(group.Commands) == 0 {
|
||||
return g
|
||||
}
|
||||
return append(g, group)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2019 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 helptemplate
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func CreateCmdGroup(msg string, cmds ...*cobra.Command) CommandGroup {
|
||||
return CommandGroup{
|
||||
Message: msg,
|
||||
Commands: cmds,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Original file location: https://github.com/kubernetes/kubectl/tree/master/pkg/util/templates
|
||||
|
||||
package helptemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const AliasSeparator = " |:|: "
|
||||
|
||||
type FlagExposer interface {
|
||||
ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer
|
||||
}
|
||||
|
||||
func ActsAsRootCommand(cmd *cobra.Command, filters []string, groups ...CommandGroup) FlagExposer {
|
||||
if cmd == nil {
|
||||
panic("nil root command")
|
||||
}
|
||||
templater := &templater{
|
||||
RootCmd: cmd,
|
||||
UsageTemplate: MainUsageTemplate(),
|
||||
HelpTemplate: MainHelpTemplate(),
|
||||
CommandGroups: groups,
|
||||
Filtered: filters,
|
||||
}
|
||||
cmd.SetFlagErrorFunc(templater.FlagErrorFunc())
|
||||
cmd.SetUsageFunc(templater.UsageFunc())
|
||||
cmd.SetHelpFunc(templater.HelpFunc())
|
||||
return templater
|
||||
}
|
||||
|
||||
func UseOptionsTemplates(cmd *cobra.Command) {
|
||||
templater := &templater{
|
||||
UsageTemplate: OptionsUsageTemplate(),
|
||||
HelpTemplate: OptionsHelpTemplate(),
|
||||
}
|
||||
cmd.SetUsageFunc(templater.UsageFunc())
|
||||
cmd.SetHelpFunc(templater.HelpFunc())
|
||||
}
|
||||
|
||||
type templater struct {
|
||||
UsageTemplate string
|
||||
HelpTemplate string
|
||||
RootCmd *cobra.Command
|
||||
CommandGroups
|
||||
Filtered []string
|
||||
}
|
||||
|
||||
func (templater *templater) FlagErrorFunc(exposedFlags ...string) func(*cobra.Command, error) error {
|
||||
return func(c *cobra.Command, err error) error {
|
||||
c.SilenceUsage = true
|
||||
switch c.CalledAs() {
|
||||
case "options":
|
||||
return fmt.Errorf("%s\nRun '%s' without flags", err, c.CommandPath())
|
||||
default:
|
||||
return fmt.Errorf("%s\nSee '%s --help' for usage", err, c.CommandPath())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (templater *templater) ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer {
|
||||
cmd.SetUsageFunc(templater.UsageFunc(flags...))
|
||||
return templater
|
||||
}
|
||||
|
||||
func (templater *templater) HelpFunc() func(*cobra.Command, []string) {
|
||||
return func(c *cobra.Command, s []string) {
|
||||
t := template.New("help")
|
||||
t.Funcs(templater.templateFuncs())
|
||||
template.Must(t.Parse(templater.HelpTemplate))
|
||||
err := t.Execute(os.Stdout, c)
|
||||
if err != nil {
|
||||
c.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Command) error {
|
||||
return func(c *cobra.Command) error {
|
||||
t := template.New("usage")
|
||||
t.Funcs(templater.templateFuncs(exposedFlags...))
|
||||
template.Must(t.Parse(templater.UsageTemplate))
|
||||
return t.Execute(os.Stdout, c)
|
||||
}
|
||||
}
|
||||
|
||||
func (templater *templater) templateFuncs(exposedFlags ...string) template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"trim": strings.TrimSpace,
|
||||
"trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) },
|
||||
"trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) },
|
||||
"gt": cobra.Gt,
|
||||
"eq": cobra.Eq,
|
||||
"rpad": rpad,
|
||||
"appendIfNotPresent": appendIfNotPresent,
|
||||
"flagsNotIntersected": flagsNotIntersected,
|
||||
"visibleFlags": visibleFlags,
|
||||
"flagsUsages": flagsUsages,
|
||||
"cmdGroups": templater.cmdGroups,
|
||||
"cmdGroupsString": templater.cmdGroupsString,
|
||||
"rootCmd": templater.rootCmdName,
|
||||
"isRootCmd": templater.isRootCmd,
|
||||
"optionsCmdFor": templater.optionsCmdFor,
|
||||
"usageLine": templater.usageLine,
|
||||
"exposed": func(c *cobra.Command) *flag.FlagSet {
|
||||
exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
|
||||
exposed.SortFlags = false
|
||||
if len(exposedFlags) > 0 {
|
||||
for _, name := range exposedFlags {
|
||||
if flag := c.Flags().Lookup(name); flag != nil {
|
||||
exposed.AddFlag(flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
return exposed
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (templater *templater) cmdGroups(c *cobra.Command, all []*cobra.Command) []CommandGroup {
|
||||
if len(templater.CommandGroups) > 0 && c == templater.RootCmd {
|
||||
all = filter(all, templater.Filtered...)
|
||||
return AddAdditionalCommands(templater.CommandGroups, "Other Commands:", all)
|
||||
}
|
||||
all = filter(all, "options")
|
||||
return []CommandGroup{
|
||||
{
|
||||
Message: "Available Commands:",
|
||||
Commands: all,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (t *templater) cmdGroupsString(c *cobra.Command) string {
|
||||
groups := []string{}
|
||||
for _, cmdGroup := range t.cmdGroups(c, c.Commands()) {
|
||||
cmds := []string{cmdGroup.Message}
|
||||
for _, cmd := range cmdGroup.Commands {
|
||||
if cmd.IsAvailableCommand() {
|
||||
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||
}
|
||||
}
|
||||
groups = append(groups, strings.Join(cmds, "\n"))
|
||||
}
|
||||
return strings.Join(groups, "\n\n")
|
||||
}
|
||||
|
||||
func (t *templater) rootCmdName(c *cobra.Command) string {
|
||||
return t.rootCmd(c).CommandPath()
|
||||
}
|
||||
|
||||
func (t *templater) isRootCmd(c *cobra.Command) bool {
|
||||
return t.rootCmd(c) == c
|
||||
}
|
||||
|
||||
func (t *templater) parents(c *cobra.Command) []*cobra.Command {
|
||||
parents := []*cobra.Command{c}
|
||||
for current := c; !t.isRootCmd(current) && current.HasParent(); {
|
||||
current = current.Parent()
|
||||
parents = append(parents, current)
|
||||
}
|
||||
return parents
|
||||
}
|
||||
|
||||
func (t *templater) rootCmd(c *cobra.Command) *cobra.Command {
|
||||
if c != nil && !c.HasParent() {
|
||||
return c
|
||||
}
|
||||
if t.RootCmd == nil {
|
||||
panic("nil root cmd")
|
||||
}
|
||||
return t.RootCmd
|
||||
}
|
||||
|
||||
func (t *templater) optionsCmdFor(c *cobra.Command) string {
|
||||
if !c.Runnable() {
|
||||
return ""
|
||||
}
|
||||
rootCmdStructure := t.parents(c)
|
||||
for i := len(rootCmdStructure) - 1; i >= 0; i-- {
|
||||
cmd := rootCmdStructure[i]
|
||||
if _, _, err := cmd.Find([]string{"options"}); err == nil {
|
||||
return cmd.CommandPath() + " options"
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t *templater) usageLine(c *cobra.Command) string {
|
||||
usage := c.UseLine()
|
||||
suffix := "[options]"
|
||||
if c.HasFlags() && !strings.Contains(usage, suffix) {
|
||||
usage += " " + suffix
|
||||
}
|
||||
return usage
|
||||
}
|
||||
|
||||
func flagsUsages(f *flag.FlagSet) string {
|
||||
x := new(bytes.Buffer)
|
||||
|
||||
var flags [][]string
|
||||
var maxPadLength int
|
||||
|
||||
f.VisitAll(func(flag *flag.Flag) {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
|
||||
format := "--%s=%s"
|
||||
if flag.Value.Type() == "string" {
|
||||
format = "--%s='%s'"
|
||||
}
|
||||
|
||||
var usage string
|
||||
var aliases []string
|
||||
|
||||
// extract aliases from usage text
|
||||
u := strings.Split(flag.Usage, AliasSeparator)
|
||||
|
||||
if len(u) == 1 {
|
||||
// means the flag has no aliases
|
||||
usage = u[0]
|
||||
format = format + " %s"
|
||||
} else {
|
||||
usage = u[len(u)-1]
|
||||
aliases = u[0 : len(u)-1]
|
||||
format = format + " (%s)"
|
||||
}
|
||||
|
||||
aliasesStr := strings.Join(aliases, ", ")
|
||||
flagName := fmt.Sprintf(format, flag.Name, flag.DefValue, aliasesStr)
|
||||
flags = append(flags, []string{flagName, usage})
|
||||
|
||||
if len(flagName) > maxPadLength {
|
||||
maxPadLength = len(flagName)
|
||||
}
|
||||
})
|
||||
|
||||
for _, v := range flags {
|
||||
name := rpad(v[0], maxPadLength)
|
||||
fmt.Fprintf(x, " %s %s\n", name, toFitUsagePadding(v[1], maxPadLength))
|
||||
}
|
||||
|
||||
return x.String()
|
||||
}
|
||||
|
||||
func toFitUsagePadding(u string, pad int) (usage string) {
|
||||
us := strings.Split(u, " ")
|
||||
length := pad
|
||||
|
||||
for _, chunk := range us {
|
||||
if length+len(chunk) > 100 {
|
||||
usage = usage + "\n" + lpad(chunk, pad+len(chunk)+4) // 4 for whitespace in format
|
||||
length = pad
|
||||
continue
|
||||
}
|
||||
usage = usage + " " + chunk
|
||||
length += len(chunk) + 1 // 1 is for whitespace
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
|
||||
func rpad(s string, padding int) string {
|
||||
template := fmt.Sprintf("%%-%ds", padding)
|
||||
return fmt.Sprintf(template, s)
|
||||
}
|
||||
|
||||
func lpad(s string, padding int) string {
|
||||
template := fmt.Sprintf("%%%ds", padding)
|
||||
return fmt.Sprintf(template, s)
|
||||
}
|
||||
|
||||
func appendIfNotPresent(s, stringToAppend string) string {
|
||||
if strings.Contains(s, stringToAppend) {
|
||||
return s
|
||||
}
|
||||
return s + " " + stringToAppend
|
||||
}
|
||||
|
||||
func flagsNotIntersected(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
|
||||
f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
|
||||
f.SortFlags = false // disable sorting flags
|
||||
l.VisitAll(func(flag *flag.Flag) {
|
||||
if r.Lookup(flag.Name) == nil {
|
||||
f.AddFlag(flag)
|
||||
}
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
func visibleFlags(l *flag.FlagSet) *flag.FlagSet {
|
||||
hidden := "help"
|
||||
f := flag.NewFlagSet("visible", flag.ContinueOnError)
|
||||
f.SortFlags = false // disable sorting flags
|
||||
l.VisitAll(func(flag *flag.Flag) {
|
||||
if flag.Name != hidden {
|
||||
f.AddFlag(flag)
|
||||
}
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
func filter(cmds []*cobra.Command, names ...string) []*cobra.Command {
|
||||
out := []*cobra.Command{}
|
||||
for _, c := range cmds {
|
||||
if c.Hidden {
|
||||
continue
|
||||
}
|
||||
skip := false
|
||||
for _, name := range names {
|
||||
if name == c.Name() {
|
||||
skip = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
out = append(out, c)
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes 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.
|
||||
*/
|
||||
|
||||
// Original file location: https://github.com/kubernetes/kubectl/tree/master/pkg/util/templates
|
||||
|
||||
package helptemplate
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
// SectionVars is the help template section that declares variables to be used in the template.
|
||||
SectionVars = `{{$isRootCmd := isRootCmd .}}` +
|
||||
`{{$rootCmd := rootCmd .}}` +
|
||||
`{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` +
|
||||
`{{$explicitlyExposedFlags := exposed .}}` +
|
||||
`{{$optionsCmdFor := optionsCmdFor .}}` +
|
||||
`{{$usageLine := usageLine .}}`
|
||||
|
||||
// SectionAliases is the help template section that displays command aliases.
|
||||
SectionAliases = `{{if gt .Aliases 0}}Aliases:
|
||||
{{.NameAndAliases}}
|
||||
|
||||
{{end}}`
|
||||
|
||||
// SectionExamples is the help template section that displays command examples.
|
||||
SectionExamples = `{{if .HasExample}}Examples:
|
||||
{{trimRight .Example}}
|
||||
|
||||
{{end}}`
|
||||
|
||||
// SectionSubcommands is the help template section that displays the command's subcommands.
|
||||
SectionSubcommands = `{{if .HasAvailableSubCommands}}{{cmdGroupsString .}}
|
||||
|
||||
{{end}}`
|
||||
|
||||
// SectionFlags is the help template section that displays the command's flags.
|
||||
SectionFlags = `{{ if or $visibleFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
|
||||
{{ if $visibleFlags.HasFlags}}{{trimRight (flagsUsages $visibleFlags)}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{ if $visibleFlags.HasFlags}}
|
||||
{{end}}{{trimRight (flagsUsages $explicitlyExposedFlags)}}{{end}}
|
||||
|
||||
{{end}}`
|
||||
|
||||
// SectionUsage is the help template section that displays the command's usage.
|
||||
SectionUsage = `{{if and .Runnable (ne .UseLine "") (ne .UseLine $rootCmd)}}Usage:
|
||||
{{$usageLine}}
|
||||
|
||||
{{end}}`
|
||||
|
||||
// SectionTipsHelp is the help template section that displays the '--help' hint.
|
||||
SectionTipsHelp = `{{if .HasSubCommands}}Use "{{$rootCmd}} <command> --help" for more information about a given command.{{end}}`
|
||||
|
||||
// SectionTipsGlobalOptions is the help template section that displays the 'options' hint for displaying global flags.
|
||||
SectionTipsGlobalOptions = `{{if $optionsCmdFor}}Use "{{$optionsCmdFor}}" for a list of global command-line options (applies to all commands).{{end}}`
|
||||
)
|
||||
|
||||
// MainHelpTemplate if the template for 'help' used by most commands.
|
||||
func MainHelpTemplate() string {
|
||||
return `{{with or .Long .Short }}{{. | trimRight}}
|
||||
{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
||||
}
|
||||
|
||||
// MainUsageTemplate if the template for 'usage' used by most commands.
|
||||
func MainUsageTemplate() string {
|
||||
sections := []string{
|
||||
"\n",
|
||||
SectionVars,
|
||||
SectionAliases,
|
||||
SectionExamples,
|
||||
SectionSubcommands,
|
||||
SectionFlags,
|
||||
SectionUsage,
|
||||
SectionTipsHelp,
|
||||
SectionTipsGlobalOptions,
|
||||
}
|
||||
return strings.TrimRightFunc(strings.Join(sections, ""), unicode.IsSpace)
|
||||
}
|
||||
|
||||
// OptionsHelpTemplate if the template for 'help' used by the 'options' command.
|
||||
func OptionsHelpTemplate() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// OptionsUsageTemplate if the template for 'usage' used by the 'options' command.
|
||||
func OptionsUsageTemplate() string {
|
||||
return `{{ if .HasInheritedFlags}}The following options can be passed to any command:
|
||||
|
||||
{{flagsUsages .InheritedFlags}}{{end}}`
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 urfavecli
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
|
||||
fCli "github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||
)
|
||||
|
||||
var _ fCli.Input = &Cli{}
|
||||
|
||||
type Cli struct {
|
||||
c *cli.Context
|
||||
}
|
||||
|
||||
// Parse is only for converting urfave *cli.Context to Input and will be removed in future.
|
||||
func Parse(c *cli.Context) fCli.Input {
|
||||
return Cli{c: c}
|
||||
}
|
||||
|
||||
func Wrapper(action cmd.CommandAction) func(*cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
return action(Cli{c: c})
|
||||
}
|
||||
}
|
||||
|
||||
func (u Cli) IsSet(key string) bool {
|
||||
return u.c.IsSet(key)
|
||||
}
|
||||
|
||||
func (u Cli) Bool(key string) bool {
|
||||
return u.c.Bool(key)
|
||||
}
|
||||
|
||||
func (u Cli) String(key string) string {
|
||||
return u.c.String(key)
|
||||
}
|
||||
|
||||
func (u Cli) StringSlice(key string) []string {
|
||||
return u.c.StringSlice(key)
|
||||
}
|
||||
|
||||
func (u Cli) Int(key string) int {
|
||||
return u.c.Int(key)
|
||||
}
|
||||
|
||||
func (u Cli) IntSlice(key string) []int {
|
||||
return u.c.IntSlice(key)
|
||||
}
|
||||
|
||||
func (u Cli) Int64(key string) int64 {
|
||||
return u.c.Int64(key)
|
||||
}
|
||||
|
||||
func (u Cli) Int64Slice(key string) []int64 {
|
||||
return u.c.Int64Slice(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalBool(key string) bool {
|
||||
return u.c.GlobalBool(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalString(key string) string {
|
||||
return u.c.GlobalString(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalStringSlice(key string) []string {
|
||||
return u.c.GlobalStringSlice(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt(key string) int {
|
||||
return u.c.GlobalInt(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalIntSlice(key string) []int {
|
||||
return u.c.GlobalIntSlice(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt64(key string) int64 {
|
||||
return u.c.GlobalInt64(key)
|
||||
}
|
||||
|
||||
func (u Cli) GlobalInt64Slice(key string) []int64 {
|
||||
return u.c.GlobalInt64Slice(key)
|
||||
}
|
||||
|
||||
func (u Cli) Duration(key string) time.Duration {
|
||||
return u.c.Duration(key)
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2019 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 canaryconfig
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a canary config",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.CanaryNameFlag, flag.CanaryTriggerNameFlag, flag.CanaryNewFuncFlag, flag.CanaryOldFuncFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.CanaryWeightIncrementFlag, flag.CanaryIncrementIntervalFlag, flag.CanaryFailureThresholdFlag},
|
||||
})
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Aliases: []string{},
|
||||
Short: "View parameters in a canary config",
|
||||
RunE: wrapper.Wrapper(Get),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.CanaryNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceCanaryFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{},
|
||||
Short: "Update parameters of a canary config",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.CanaryNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceCanaryFlag, flag.CanaryWeightIncrementFlag, flag.CanaryIncrementIntervalFlag, flag.CanaryFailureThresholdFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete a canary config",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.CanaryNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceCanaryFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List canary configs",
|
||||
Long: "List all canary configs in a namespace if specified, else, list canary configs across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceCanaryFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "canary",
|
||||
Aliases: []string{"canary-config"},
|
||||
Short: "Create, Update and manage canary configs",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getCmd, updateCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -21,10 +21,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
@@ -56,13 +58,14 @@ func (opts *CreateSubCommand) do(flags cli.Input) error {
|
||||
func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
// canary configs can be created for functions in the same namespace
|
||||
|
||||
trigger := flags.String("httptrigger")
|
||||
newFunc := flags.String("newfunction")
|
||||
oldFunc := flags.String("oldfunction")
|
||||
ns := flags.String("fnNamespace")
|
||||
incrementStep := flags.Int("increment-step")
|
||||
failureThreshold := flags.Int("failure-threshold")
|
||||
incrementInterval := flags.String("increment-interval")
|
||||
name := flags.String(flagkey.CanaryName)
|
||||
ht := flags.String(flagkey.CanaryHTTPTriggerName)
|
||||
newFunc := flags.String(flagkey.CanaryNewFunc)
|
||||
oldFunc := flags.String(flagkey.CanaryOldFunc)
|
||||
fnNs := flags.String(flagkey.NamespaceFunction)
|
||||
incrementStep := flags.Int(flagkey.CanaryWeightIncrement)
|
||||
failureThreshold := flags.Int(flagkey.CanaryFailureThreshold)
|
||||
incrementInterval := flags.String(flagkey.CanaryIncrementInterval)
|
||||
|
||||
// check for time parsing
|
||||
_, err := time.ParseDuration(incrementInterval)
|
||||
@@ -71,14 +74,12 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
}
|
||||
|
||||
// check that the trigger exists in the same namespace.
|
||||
m, err := util.GetMetadata("httptrigger", "fnNamespace", flags)
|
||||
htTrigger, err := opts.client.HTTPTriggerGet(&metav1.ObjectMeta{
|
||||
Name: ht,
|
||||
Namespace: fnNs,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error finding http trigger in given namespace")
|
||||
}
|
||||
|
||||
htTrigger, err := opts.client.HTTPTriggerGet(m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error finding trigger referenced in the canary config")
|
||||
return errors.Wrap(err, "error finding http trigger referenced in the canary config")
|
||||
}
|
||||
|
||||
// check that the trigger has function reference type function weights
|
||||
@@ -99,21 +100,19 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
|
||||
// check that the functions exist in the same namespace
|
||||
fnList := []string{newFunc, oldFunc}
|
||||
err = util.CheckFunctionExistence(opts.client, fnList, ns)
|
||||
err = util.CheckFunctionExistence(opts.client, fnList, fnNs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error checking functions existence")
|
||||
}
|
||||
|
||||
canaryMetadata, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// finally create canaryCfg in the same namespace as the functions referenced
|
||||
opts.canary = &fv1.CanaryConfig{
|
||||
Metadata: *canaryMetadata,
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: fnNs,
|
||||
},
|
||||
Spec: fv1.CanaryConfigSpec{
|
||||
Trigger: trigger,
|
||||
Trigger: ht,
|
||||
NewFunction: newFunc,
|
||||
OldFunction: oldFunc,
|
||||
WeightIncrement: incrementStep,
|
||||
|
||||
@@ -20,9 +20,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -30,27 +32,28 @@ type DeleteSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Delete(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Delete(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := DeleteSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *DeleteSubCommand) run(flags cli.Input) error {
|
||||
metadata, err := util.GetMetadata("name", "canaryNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
func (opts *DeleteSubCommand) run(input cli.Input) error {
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.CanaryName),
|
||||
Namespace: input.String(flagkey.NamespaceCanary),
|
||||
}
|
||||
err = opts.client.CanaryConfigDelete(metadata)
|
||||
|
||||
err := opts.client.CanaryConfigDelete(m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error deleting canary config")
|
||||
}
|
||||
|
||||
fmt.Printf("canaryconfig '%v.%v' deleted\n", metadata.Name, metadata.Namespace)
|
||||
fmt.Printf("canaryconfig '%v.%v' deleted\n", m.Name, m.Namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -32,24 +34,22 @@ type GetSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Get(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Get(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := GetSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *GetSubCommand) run(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "canaryNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
canaryCfg, err := opts.client.CanaryConfigGet(m)
|
||||
func (opts *GetSubCommand) run(input cli.Input) error {
|
||||
canaryCfg, err := opts.client.CanaryConfigGet(&metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.CanaryName),
|
||||
Namespace: input.String(flagkey.NamespaceCanary),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting canary config")
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -33,27 +34,27 @@ type ListSubCommand struct {
|
||||
namespace string
|
||||
}
|
||||
|
||||
func List(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func List(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := ListSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *ListSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *ListSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *ListSubCommand) complete(flags cli.Input) error {
|
||||
opts.namespace = flags.String("canaryNamespace")
|
||||
opts.namespace = flags.String(flagkey.NamespaceCanary)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -33,43 +35,43 @@ type UpdateSubCommand struct {
|
||||
canary *fv1.CanaryConfig
|
||||
}
|
||||
|
||||
func Update(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Update(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := UpdateSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *UpdateSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
// get the current config
|
||||
m, err := util.GetMetadata("name", "canaryNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
incrementStep := flags.Int("increment-step")
|
||||
failureThreshold := flags.Int("failure-threshold")
|
||||
incrementInterval := flags.String("increment-interval")
|
||||
name := input.String(flagkey.CanaryName)
|
||||
ns := input.String(flagkey.NamespaceCanary)
|
||||
incrementStep := input.Int(flagkey.CanaryWeightIncrement)
|
||||
failureThreshold := input.Int(flagkey.CanaryFailureThreshold)
|
||||
incrementInterval := input.String(flagkey.CanaryIncrementInterval)
|
||||
|
||||
// check for time parsing
|
||||
_, err = time.ParseDuration(incrementInterval)
|
||||
_, err := time.ParseDuration(incrementInterval)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error parsing time duration")
|
||||
}
|
||||
|
||||
canaryCfg, err := opts.client.CanaryConfigGet(m)
|
||||
canaryCfg, err := opts.client.CanaryConfigGet(&metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: ns,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting canary config")
|
||||
}
|
||||
@@ -97,7 +99,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(flags cli.Input) error {
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
_, err := opts.client.CanaryConfigUpdate(opts.canary)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating canary config")
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
Copyright 2019 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 environment
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create an environment",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.EnvNameFlag, flag.EnvImageFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceEnvironmentFlag, flag.EnvPoolsizeFlag,
|
||||
flag.EnvBuilderImageFlag, flag.EnvBuildCmdFlag, flag.EnvKeepArchiveFlag,
|
||||
flag.RunTimeMinCPUFlag, flag.RunTimeMaxCPUFlag, flag.RunTimeMinMemoryFlag, flag.RunTimeMaxMemoryFlag,
|
||||
flag.EnvVersionFlag, flag.EnvExternalNetworkFlag, flag.EnvTerminationGracePeriodFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get environment details",
|
||||
RunE: wrapper.Wrapper(Get),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.EnvNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceEnvironmentFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update an environment",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.EnvNameFlag},
|
||||
Optional: []flag.Flag{flag.EnvImageFlag, flag.NamespaceEnvironmentFlag, flag.EnvPoolsizeFlag,
|
||||
flag.EnvBuilderImageFlag, flag.EnvBuildCmdFlag, flag.EnvKeepArchiveFlag,
|
||||
flag.EnvExternalNetworkFlag, flag.EnvTerminationGracePeriodFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete an environment",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.EnvNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceEnvironmentFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List environments",
|
||||
Long: "List all environments in a namespace if specified, else, list environments across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceEnvironmentFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "environment",
|
||||
Aliases: []string{"env"},
|
||||
Short: "Create, update and manage environments",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getCmd, updateCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -27,9 +27,10 @@ import (
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
type CreateSubCommand struct {
|
||||
@@ -37,28 +38,28 @@ type CreateSubCommand struct {
|
||||
env *fv1.Environment
|
||||
}
|
||||
|
||||
func Create(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Create(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := CreateSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *CreateSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *CreateSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
// complete creates a environment objects and populates it with default value and CLI inputs.
|
||||
func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
env, err := createEnvironmentFromCmd(flags)
|
||||
func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
env, err := createEnvironmentFromCmd(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -68,23 +69,21 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
|
||||
// run write the resource to a spec file or create a fission CRD with remote fission server.
|
||||
// It also prints warning/error if necessary.
|
||||
func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||
m, err := util.GetMetadata(flag.RESOURCE_NAME, flag.ENVIRONMENT_NAMESPACE, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
m := opts.env.Metadata
|
||||
|
||||
envList, err := opts.client.EnvironmentList(m.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(envList) > 0 {
|
||||
consolemsg.Verbose(2, "%d environment(s) are present in the %s namespace. "+
|
||||
console.Verbose(2, "%d environment(s) are present in the %s namespace. "+
|
||||
"These environments are not isolated from each other; use separate namespaces if you need isolation.",
|
||||
len(envList), m.Namespace)
|
||||
}
|
||||
|
||||
// if we're writing a spec, don't call the API
|
||||
// save to spec file
|
||||
if flags.Bool(flag.SPEC_SPEC) {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specFile := fmt.Sprintf("env-%v.yaml", m.Name)
|
||||
err = spec.SpecSave(*opts.env, specFile)
|
||||
if err != nil {
|
||||
@@ -103,39 +102,33 @@ func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||
}
|
||||
|
||||
// createEnvironmentFromCmd creates environment initialized with CLI input.
|
||||
func createEnvironmentFromCmd(flags cli.Input) (*fv1.Environment, error) {
|
||||
e := &multierror.Error{}
|
||||
func createEnvironmentFromCmd(input cli.Input) (*fv1.Environment, error) {
|
||||
e := utils.MultiErrorWithFormat()
|
||||
|
||||
envNamespace := flags.String(flag.ENVIRONMENT_NAMESPACE)
|
||||
envBuildCmd := flags.String(flag.ENVIRONMENT_BUILDCOMMAND)
|
||||
envExternalNetwork := flags.Bool(flag.ENVIRONMENT_EXTERNAL_NETWORK)
|
||||
keepArchive := flags.Bool(flag.ENVIRONMENT_KEEPARCHIVE)
|
||||
envName := input.String(flagkey.EnvName)
|
||||
envImg := input.String(flagkey.EnvImage)
|
||||
envNamespace := input.String(flagkey.NamespaceEnvironment)
|
||||
envBuildCmd := input.String(flagkey.EnvBuildcommand)
|
||||
envExternalNetwork := input.Bool(flagkey.EnvExternalNetwork)
|
||||
keepArchive := input.Bool(flagkey.EnvKeeparchive)
|
||||
envGracePeriod := input.Int64(flagkey.EnvGracePeriod)
|
||||
|
||||
envName := flags.String(flag.RESOURCE_NAME)
|
||||
if len(envName) == 0 {
|
||||
e = multierror.Append(e, errors.New("Need a name, use --name."))
|
||||
}
|
||||
|
||||
envImg := flags.String(flag.ENVIRONMENT_IMAGE)
|
||||
if len(envImg) == 0 {
|
||||
e = multierror.Append(e, errors.New("Need an image, use --image."))
|
||||
}
|
||||
|
||||
envGracePeriod := flags.Int64(flag.ENVIRONMENT_GRACE_PERIOD)
|
||||
if envGracePeriod <= 0 {
|
||||
envGracePeriod = 360
|
||||
}
|
||||
|
||||
envVersion := flags.Int(flag.ENVIRONMENT_VERSION)
|
||||
envVersion := input.Int(flagkey.EnvVersion)
|
||||
// Environment API interface version is not specified and
|
||||
// builder image is empty, set default interface version
|
||||
if envVersion == 0 {
|
||||
envVersion = 1
|
||||
}
|
||||
|
||||
envBuilderImg := flags.String(flag.ENVIRONMENT_BUILDER)
|
||||
poolsize := input.Int(flagkey.EnvPoolsize)
|
||||
if input.IsSet(flagkey.EnvPoolsize) {
|
||||
// TODO: remove silently version 3 assignment, we need to warn user to set it explicitly.
|
||||
envVersion = 3
|
||||
}
|
||||
|
||||
envBuilderImg := input.String(flagkey.EnvBuilderImage)
|
||||
if len(envBuilderImg) > 0 {
|
||||
if !flags.IsSet(flag.ENVIRONMENT_VERSION) {
|
||||
if !input.IsSet(flagkey.EnvVersion) {
|
||||
// TODO: remove set env version to 2 silently, we need to warn user to set it explicitly.
|
||||
envVersion = 2
|
||||
}
|
||||
@@ -144,14 +137,7 @@ func createEnvironmentFromCmd(flags cli.Input) (*fv1.Environment, error) {
|
||||
}
|
||||
}
|
||||
|
||||
poolsize := 3
|
||||
if flags.IsSet(flag.ENVIRONMENT_POOLSIZE) {
|
||||
poolsize = flags.Int(flag.ENVIRONMENT_POOLSIZE)
|
||||
// TODO: remove silently version 3 assignment, we need to warn user to set it explicitly.
|
||||
envVersion = 3
|
||||
}
|
||||
|
||||
resourceReq, err := util.GetResourceReqs(flags, nil)
|
||||
resourceReq, err := util.GetResourceReqs(input, nil)
|
||||
if err != nil {
|
||||
e = multierror.Append(e, err)
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -31,24 +32,24 @@ type DeleteSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Delete(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Delete(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := DeleteSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *DeleteSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata(flag.RESOURCE_NAME, flag.ENVIRONMENT_NAMESPACE, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
func (opts *DeleteSubCommand) do(input cli.Input) error {
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.EnvName),
|
||||
Namespace: input.String(flagkey.NamespaceEnvironment),
|
||||
}
|
||||
|
||||
err = opts.client.EnvironmentDelete(m)
|
||||
err := opts.client.EnvironmentDelete(m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error deleting environment")
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -33,21 +34,21 @@ type GetSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Get(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Get(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := GetSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *GetSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata(flag.RESOURCE_NAME, flag.ENVIRONMENT_NAMESPACE, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
func (opts *GetSubCommand) do(input cli.Input) error {
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.EnvName),
|
||||
Namespace: input.String(flagkey.NamespaceEnvironment),
|
||||
}
|
||||
|
||||
env, err := opts.client.EnvironmentGet(m)
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -33,21 +33,19 @@ type ListSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func List(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func List(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := ListSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *ListSubCommand) do(flags cli.Input) error {
|
||||
envNamespace := flags.String(flag.ENVIRONMENT_NAMESPACE)
|
||||
|
||||
envs, err := opts.client.EnvironmentList(envNamespace)
|
||||
func (opts *ListSubCommand) do(input cli.Input) error {
|
||||
envs, err := opts.client.EnvironmentList(input.String(flagkey.NamespaceEnvironment))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error listing environments")
|
||||
}
|
||||
|
||||
@@ -21,12 +21,14 @@ import (
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
type UpdateSubCommand struct {
|
||||
@@ -34,37 +36,35 @@ type UpdateSubCommand struct {
|
||||
env *fv1.Environment
|
||||
}
|
||||
|
||||
func Update(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Update(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := UpdateSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *UpdateSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
m, err := util.GetMetadata(flag.RESOURCE_NAME, flag.ENVIRONMENT_NAMESPACE, flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
env, err := opts.client.EnvironmentGet(m)
|
||||
func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
env, err := opts.client.EnvironmentGet(&metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.EnvName),
|
||||
Namespace: input.String(flagkey.NamespaceEnvironment),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error finding environment")
|
||||
}
|
||||
|
||||
env, err = updateExistingEnvironmentWithCmd(env, flags)
|
||||
env, err = updateExistingEnvironmentWithCmd(env, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(flags cli.Input) error {
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
_, err := opts.client.EnvironmentUpdate(opts.env)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating environment")
|
||||
@@ -84,13 +84,13 @@ func (opts *UpdateSubCommand) run(flags cli.Input) error {
|
||||
}
|
||||
|
||||
// updateExistingEnvironmentWithCmd updates a existing environment's value based on CLI input.
|
||||
func updateExistingEnvironmentWithCmd(env *fv1.Environment, flags cli.Input) (*fv1.Environment, error) {
|
||||
e := &multierror.Error{}
|
||||
func updateExistingEnvironmentWithCmd(env *fv1.Environment, input cli.Input) (*fv1.Environment, error) {
|
||||
e := utils.MultiErrorWithFormat()
|
||||
|
||||
envImg := flags.String(flag.ENVIRONMENT_IMAGE)
|
||||
envBuilderImg := flags.String(flag.ENVIRONMENT_BUILDER)
|
||||
envBuildCmd := flags.String(flag.ENVIRONMENT_BUILDCOMMAND)
|
||||
envExternalNetwork := flags.Bool(flag.ENVIRONMENT_EXTERNAL_NETWORK)
|
||||
envImg := input.String(flagkey.EnvImage)
|
||||
envBuilderImg := input.String(flagkey.EnvBuilderImage)
|
||||
envBuildCmd := input.String(flagkey.EnvBuildcommand)
|
||||
envExternalNetwork := input.Bool(flagkey.EnvExternalNetwork)
|
||||
|
||||
if len(envImg) == 0 && len(envBuilderImg) == 0 && len(envBuildCmd) == 0 {
|
||||
e = multierror.Append(e, errors.New("need --image to specify env image, or use --builder to specify env builder, or use --buildcmd to specify new build command"))
|
||||
@@ -111,25 +111,26 @@ func updateExistingEnvironmentWithCmd(env *fv1.Environment, flags cli.Input) (*f
|
||||
env.Spec.Builder.Command = envBuildCmd
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.ENVIRONMENT_POOLSIZE) {
|
||||
env.Spec.Poolsize = flags.Int(flag.ENVIRONMENT_POOLSIZE)
|
||||
if input.IsSet(flagkey.EnvPoolsize) {
|
||||
env.Spec.Poolsize = input.Int(flagkey.EnvPoolsize)
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.ENVIRONMENT_GRACE_PERIOD) {
|
||||
env.Spec.TerminationGracePeriod = flags.Int64(flag.ENVIRONMENT_GRACE_PERIOD)
|
||||
if input.IsSet(flagkey.EnvGracePeriod) {
|
||||
env.Spec.TerminationGracePeriod = input.Int64(flagkey.EnvGracePeriod)
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.ENVIRONMENT_KEEPARCHIVE) {
|
||||
env.Spec.KeepArchive = flags.Bool(flag.ENVIRONMENT_KEEPARCHIVE)
|
||||
if input.IsSet(flagkey.EnvKeeparchive) {
|
||||
env.Spec.KeepArchive = input.Bool(flagkey.EnvKeeparchive)
|
||||
}
|
||||
|
||||
env.Spec.AllowAccessToExternalNetwork = envExternalNetwork
|
||||
|
||||
if flags.IsSet(flag.RUNTIME_MINCPU) || flags.IsSet(flag.RUNTIME_MAXCPU) ||
|
||||
flags.IsSet(flag.RUNTIME_MINMEMORY) || flags.IsSet(flag.RUNTIME_MAXMEMORY) ||
|
||||
flags.IsSet(flag.RUNTIME_MINSCALE) || flags.IsSet(flag.RUNTIME_MAXSCALE) {
|
||||
e = multierror.Append(e, errors.New("updating resource limits/requests for existing environments is currently unsupported; re-create the environment instead"))
|
||||
}
|
||||
// TODO: allow to update resource.
|
||||
//if input.IsSet(flagkey.RuntimeMincpu) || input.IsSet(flagkey.RuntimeMaxcpu) ||
|
||||
// input.IsSet(flagkey.RuntimeMinmemory) || input.IsSet(flagkey.RuntimeMaxmemory) ||
|
||||
// input.IsSet(flagkey.ReplicasMinscale) || input.IsSet(flagkey.ReplicasMaxscale) {
|
||||
// e = multierror.Append(e, errors.New("updating resource limits/requests for existing environments is currently unsupported; re-create the environment instead"))
|
||||
//}
|
||||
|
||||
if e.ErrorOrNil() != nil {
|
||||
return nil, e.ErrorOrNil()
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Copyright 2019 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 function
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a function (and optionally, an HTTP route to it)",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.NamespaceEnvironmentFlag, flag.SpecSaveFlag,
|
||||
flag.FnEnvNameFlag, flag.FnCodeFlag, flag.PkgSrcArchiveFlag, flag.PkgDeployArchiveFlag, flag.FnKeepURLFlag,
|
||||
flag.FnEntryPointFlag, flag.FnBuildCmdFlag, flag.FnPkgNameFlag, flag.HtUrlFlag, flag.HtMethodFlag,
|
||||
flag.RunTimeMinCPUFlag, flag.RunTimeMaxCPUFlag, flag.RunTimeMinMemoryFlag, flag.RunTimeMaxMemoryFlag,
|
||||
flag.ReplicasMinFlag, flag.ReplicasMaxFlag, flag.FnExecutorTypeFlag, flag.RunTimeTargetCPUFlag,
|
||||
flag.FnCfgMapFlag, flag.FnSecretFlag, flag.FnSpecializationTimeoutFlag, flag.FnExecutionTimeoutFlag},
|
||||
})
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Aliases: []string{},
|
||||
Short: "Get function source code",
|
||||
RunE: wrapper.Wrapper(Get),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag},
|
||||
})
|
||||
|
||||
getmetaCmd := &cobra.Command{
|
||||
Use: "getmeta",
|
||||
Aliases: []string{},
|
||||
Short: "Get function metadata",
|
||||
RunE: wrapper.Wrapper(GetMeta),
|
||||
}
|
||||
wrapper.SetFlags(getmetaCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{},
|
||||
Short: "Update a function",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.NamespaceEnvironmentFlag, flag.SpecSaveFlag,
|
||||
flag.FnCodeFlag, flag.PkgSrcArchiveFlag, flag.PkgDeployArchiveFlag,
|
||||
flag.FnKeepURLFlag, flag.FnEntryPointFlag, flag.FnBuildCmdFlag, flag.FnPkgNameFlag, flag.HtUrlFlag,
|
||||
flag.HtMethodFlag, flag.RunTimeMinCPUFlag, flag.RunTimeMaxCPUFlag, flag.RunTimeMinMemoryFlag,
|
||||
flag.RunTimeMaxMemoryFlag, flag.ReplicasMinFlag, flag.ReplicasMaxFlag, flag.FnExecutorTypeFlag,
|
||||
flag.RunTimeTargetCPUFlag, flag.FnCfgMapFlag, flag.FnSecretFlag, flag.FnSpecializationTimeoutFlag,
|
||||
flag.FnExecutionTimeoutFlag, flag.PkgForceFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete a function",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List all functions in a namespace if specified, else, list functions across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag},
|
||||
})
|
||||
|
||||
logsCmd := &cobra.Command{
|
||||
Use: "log",
|
||||
Aliases: []string{"logs"},
|
||||
Short: "Display function logs",
|
||||
RunE: wrapper.Wrapper(Log),
|
||||
}
|
||||
wrapper.SetFlags(logsCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.FnLogPodFlag, flag.FnLogFollowFlag,
|
||||
flag.FnLogDetailFlag, flag.FnLogDBTypeFlag, flag.FnLogReverseQueryFlag, flag.FnLogCountFlag},
|
||||
})
|
||||
|
||||
testCmd := &cobra.Command{
|
||||
Use: "test",
|
||||
Aliases: []string{},
|
||||
Short: "Test a function",
|
||||
RunE: wrapper.Wrapper(Test),
|
||||
}
|
||||
wrapper.SetFlags(testCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.FnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.HtMethodFlag, flag.FnTestBodyFlag,
|
||||
flag.FnTestHeaderFlag, flag.FnTestQueryFlag, flag.FnTestTimeoutFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "function",
|
||||
Aliases: []string{"fn"},
|
||||
Short: "Create, update and manage functions",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getCmd, getmetaCmd, updateCmd, deleteCmd, listCmd, logsCmd, testCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -33,7 +33,8 @@ import (
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
|
||||
_package "github.com/fission/fission/pkg/fission-cli/cmd/package"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
@@ -49,44 +50,40 @@ type CreateSubCommand struct {
|
||||
specFile string
|
||||
}
|
||||
|
||||
func Create(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Create(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := CreateSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *CreateSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *CreateSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
fnNamespace := flags.String("fnNamespace")
|
||||
envNamespace := flags.String("envNamespace")
|
||||
|
||||
fnName := flags.String("name")
|
||||
if len(fnName) == 0 {
|
||||
return errors.New("need --name argument")
|
||||
}
|
||||
func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
fnName := input.String(flagkey.FnName)
|
||||
fnNamespace := input.String(flagkey.NamespaceFunction)
|
||||
envNamespace := input.String(flagkey.NamespaceEnvironment)
|
||||
|
||||
// user wants a spec, create a yaml file with package and function
|
||||
toSpec := false
|
||||
if flags.Bool("spec") {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
toSpec = true
|
||||
opts.specFile = fmt.Sprintf("function-%v.yaml", fnName)
|
||||
}
|
||||
specDir := util.GetSpecDir(flags)
|
||||
specDir := util.GetSpecDir(input)
|
||||
|
||||
// check for unique function names within a namespace
|
||||
metadata, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
metadata, err := util.GetMetadata(flagkey.FnName, flagkey.NamespaceFunction, input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -98,23 +95,23 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
return errors.New("a function with the same name already exists")
|
||||
}
|
||||
|
||||
entrypoint := flags.String("entrypoint")
|
||||
entrypoint := input.String(flagkey.FnEntrypoint)
|
||||
|
||||
fnTimeout := flags.Int("fntimeout")
|
||||
fnTimeout := input.Int(flagkey.FnExecutionTimeout)
|
||||
if fnTimeout <= 0 {
|
||||
return errors.New("fntimeout must be greater than 0")
|
||||
}
|
||||
|
||||
pkgName := flags.String("pkg")
|
||||
pkgName := input.String(flagkey.FnPackageName)
|
||||
|
||||
secretNames := flags.StringSlice("secret")
|
||||
cfgMapNames := flags.StringSlice("configmap")
|
||||
secretNames := input.StringSlice(flagkey.FnSecret)
|
||||
cfgMapNames := input.StringSlice(flagkey.FnCfgMap)
|
||||
|
||||
invokeStrategy, err := getInvokeStrategy(flags, nil)
|
||||
invokeStrategy, err := getInvokeStrategy(input, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resourceReq, err := util.GetResourceReqs(flags, &apiv1.ResourceRequirements{})
|
||||
resourceReq, err := util.GetResourceReqs(input, &apiv1.ResourceRequirements{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -132,13 +129,13 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
}
|
||||
pkgMetadata = &pkg.Metadata
|
||||
envName = pkg.Spec.Environment.Name
|
||||
if envName != flags.String("env") {
|
||||
consolemsg.Warn("Function's environment is different than package's environment, package's environment will be used for creating function")
|
||||
if envName != input.String(flagkey.FnEnvironmentName) {
|
||||
console.Warn("Function's environment is different than package's environment, package's environment will be used for creating function")
|
||||
}
|
||||
envNamespace = pkg.Spec.Environment.Namespace
|
||||
} else {
|
||||
// need to specify environment for creating new package
|
||||
envName = flags.String("env")
|
||||
envName = input.String(flagkey.FnEnvironmentName)
|
||||
if len(envName) == 0 {
|
||||
return errors.New("need --env argument")
|
||||
}
|
||||
@@ -151,21 +148,21 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
})
|
||||
if err != nil {
|
||||
if e, ok := err.(ferror.Error); ok && e.Code == ferror.ErrorNotFound {
|
||||
consolemsg.Warn(fmt.Sprintf("Environment \"%v\" does not exist. Please create the environment before executing the function. \nFor example: `fission env create --name %v --envns %v --image <image>`\n", envName, envName, envNamespace))
|
||||
console.Warn(fmt.Sprintf("Environment \"%v\" does not exist. Please create the environment before executing the function. \nFor example: `fission env create --name %v --envns %v --image <image>`\n", envName, envName, envNamespace))
|
||||
} else {
|
||||
return errors.Wrap(err, "error retrieving environment information")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srcArchiveFiles := flags.StringSlice("src")
|
||||
srcArchiveFiles := input.StringSlice(flagkey.PkgSrcArchive)
|
||||
var deployArchiveFiles []string
|
||||
noZip := false
|
||||
code := flags.String("code")
|
||||
code := input.String(flagkey.FnCode)
|
||||
if len(code) == 0 {
|
||||
deployArchiveFiles = flags.StringSlice("deploy")
|
||||
deployArchiveFiles = input.StringSlice(flagkey.PkgDeployArchive)
|
||||
} else {
|
||||
deployArchiveFiles = append(deployArchiveFiles, flags.String("code"))
|
||||
deployArchiveFiles = append(deployArchiveFiles, input.String(flagkey.FnCode))
|
||||
noZip = true
|
||||
}
|
||||
// return error when both src & deploy archive are empty
|
||||
@@ -173,11 +170,11 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
return errors.New("need --code or --deploy or --src argument")
|
||||
}
|
||||
|
||||
buildcmd := flags.String("buildcmd")
|
||||
keepURL := flags.Bool("keepurl")
|
||||
buildcmd := input.String(flagkey.PkgBuildCmd)
|
||||
keepURL := input.Bool(flagkey.PkgKeepURL)
|
||||
|
||||
// create new package in the same namespace as the function.
|
||||
pkgMetadata, err = _package.CreatePackage(flags, opts.client, fnNamespace, envName, envNamespace,
|
||||
pkgMetadata, err = _package.CreatePackage(input, opts.client, fnNamespace, envName, envNamespace,
|
||||
srcArchiveFiles, deployArchiveFiles, buildcmd, specDir, opts.specFile, noZip, keepURL)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating package")
|
||||
@@ -196,7 +193,7 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
})
|
||||
if err != nil {
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("Secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
console.Warn(fmt.Sprintf("Secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
} else {
|
||||
return errors.Wrap(err, "error checking secret")
|
||||
}
|
||||
@@ -220,7 +217,7 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
})
|
||||
if err != nil {
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as function", cfgMapName, fnNamespace))
|
||||
console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as function", cfgMapName, fnNamespace))
|
||||
} else {
|
||||
return errors.Wrap(err, "error checking configmap")
|
||||
}
|
||||
@@ -268,7 +265,7 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
// It also prints warning/error if necessary.
|
||||
func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||
// if we're writing a spec, don't create the function
|
||||
if flags.Bool("spec") {
|
||||
if flags.Bool(flagkey.SpecSave) {
|
||||
err := spec.SpecSave(*opts.function, opts.specFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating function spec")
|
||||
@@ -284,7 +281,7 @@ func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||
fmt.Printf("function '%v' created\n", opts.function.Metadata.Name)
|
||||
|
||||
// Allow the user to specify an HTTP trigger while creating a function.
|
||||
triggerUrl := flags.String("url")
|
||||
triggerUrl := flags.String(flagkey.HtUrl)
|
||||
if len(triggerUrl) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -292,7 +289,7 @@ func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||
triggerUrl = fmt.Sprintf("/%s", triggerUrl)
|
||||
}
|
||||
|
||||
method, err := httptrigger.GetMethod(flags.String("method"))
|
||||
method, err := httptrigger.GetMethod(flags.String(flagkey.HtMethod))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting HTTP trigger method")
|
||||
}
|
||||
@@ -325,7 +322,7 @@ func getInvokeStrategy(flags cli.Input, existingInvokeStrategy *fv1.InvokeStrate
|
||||
|
||||
var fnExecutor, newFnExecutor fv1.ExecutorType
|
||||
|
||||
switch flags.String("executortype") {
|
||||
switch flags.String(flagkey.FnExecutorType) {
|
||||
case "":
|
||||
fallthrough
|
||||
case types.ExecutorTypePoolmgr:
|
||||
@@ -340,24 +337,24 @@ func getInvokeStrategy(flags cli.Input, existingInvokeStrategy *fv1.InvokeStrate
|
||||
fnExecutor = existingInvokeStrategy.ExecutionStrategy.ExecutorType
|
||||
|
||||
// override the executor type if user specified a new executor type
|
||||
if flags.IsSet("executortype") {
|
||||
if flags.IsSet(flagkey.FnExecutorType) {
|
||||
fnExecutor = newFnExecutor
|
||||
}
|
||||
} else {
|
||||
fnExecutor = newFnExecutor
|
||||
}
|
||||
|
||||
if flags.IsSet("specializationtimeout") && fnExecutor != types.ExecutorTypeNewdeploy {
|
||||
return nil, errors.New("specializationtimeout flag is only applicable for newdeploy type of executor")
|
||||
if flags.IsSet(flagkey.FnSpecializationTimeout) && fnExecutor != types.ExecutorTypeNewdeploy {
|
||||
return nil, errors.Errorf("%v flag is only applicable for newdeploy type of executor", flagkey.FnSpecializationTimeout)
|
||||
}
|
||||
|
||||
if fnExecutor == types.ExecutorTypePoolmgr {
|
||||
if flags.IsSet("targetcpu") || flags.IsSet("minscale") || flags.IsSet("maxscale") {
|
||||
if flags.IsSet(flagkey.RuntimeTargetcpu) || flags.IsSet(flagkey.ReplicasMinscale) || flags.IsSet(flagkey.ReplicasMaxscale) {
|
||||
return nil, errors.New("to set target CPU or min/max scale for function, please specify \"--executortype newdeploy\"")
|
||||
}
|
||||
|
||||
if flags.IsSet("mincpu") || flags.IsSet("maxcpu") || flags.IsSet("minmemory") || flags.IsSet("maxmemory") {
|
||||
consolemsg.Warn("To limit CPU/Memory for function with executor type \"poolmgr\", please specify resources limits when creating environment")
|
||||
if flags.IsSet(flagkey.RuntimeMincpu) || flags.IsSet(flagkey.RuntimeMaxcpu) || flags.IsSet(flagkey.RuntimeMinmemory) || flags.IsSet(flagkey.RuntimeMaxmemory) {
|
||||
console.Warn("To limit CPU/Memory for function with executor type \"poolmgr\", please specify resources limits when creating environment")
|
||||
}
|
||||
strategy = &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -379,33 +376,33 @@ func getInvokeStrategy(flags cli.Input, existingInvokeStrategy *fv1.InvokeStrate
|
||||
specializationTimeout = existingInvokeStrategy.ExecutionStrategy.SpecializationTimeout
|
||||
}
|
||||
|
||||
if flags.IsSet("targetcpu") {
|
||||
if flags.IsSet(flagkey.RuntimeTargetcpu) {
|
||||
targetCPU, err = getTargetCPU(flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if flags.IsSet("minscale") {
|
||||
minScale = flags.Int("minscale")
|
||||
if flags.IsSet(flagkey.ReplicasMinscale) {
|
||||
minScale = flags.Int(flagkey.ReplicasMinscale)
|
||||
}
|
||||
|
||||
if flags.IsSet("maxscale") {
|
||||
maxScale = flags.Int("maxscale")
|
||||
if flags.IsSet(flagkey.ReplicasMaxscale) {
|
||||
maxScale = flags.Int(flagkey.ReplicasMaxscale)
|
||||
if maxScale <= 0 {
|
||||
return nil, errors.New("maxscale must be greater than 0")
|
||||
return nil, errors.Errorf("%v must be greater than 0", flagkey.ReplicasMaxscale)
|
||||
}
|
||||
}
|
||||
|
||||
if flags.IsSet("specializationtimeout") {
|
||||
specializationTimeout = flags.Int("specializationtimeout")
|
||||
if flags.IsSet(flagkey.FnSpecializationTimeout) {
|
||||
specializationTimeout = flags.Int(flagkey.FnSpecializationTimeout)
|
||||
if specializationTimeout < fv1.DefaultSpecializationTimeOut {
|
||||
return nil, errors.New("specializationtimeout must be greater than or equal to 120 seconds")
|
||||
return nil, errors.Errorf("%v must be greater than or equal to 120 seconds", flagkey.FnSpecializationTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
if minScale > maxScale {
|
||||
return nil, fmt.Errorf("minscale provided: %v can not be greater than maxscale value %v", minScale, maxScale)
|
||||
return nil, fmt.Errorf("minscale (%v) can not be greater than maxscale (%v)", minScale, maxScale)
|
||||
}
|
||||
|
||||
// Right now a simple single case strategy implementation
|
||||
@@ -426,14 +423,9 @@ func getInvokeStrategy(flags cli.Input, existingInvokeStrategy *fv1.InvokeStrate
|
||||
}
|
||||
|
||||
func getTargetCPU(flags cli.Input) (int, error) {
|
||||
var targetCPU int
|
||||
if flags.IsSet("targetcpu") {
|
||||
targetCPU = flags.Int("targetcpu")
|
||||
if targetCPU <= 0 || targetCPU > 100 {
|
||||
return 0, errors.New("TargetCPU must be a value between 1 - 100")
|
||||
}
|
||||
} else {
|
||||
targetCPU = DEFAULT_TARGET_CPU_PERCENTAGE
|
||||
targetCPU := flags.Int(flagkey.RuntimeTargetcpu)
|
||||
if targetCPU <= 0 || targetCPU > 100 {
|
||||
return 0, errors.Errorf("%v must be a value between 1 - 100", flagkey.RuntimeTargetcpu)
|
||||
}
|
||||
return targetCPU, nil
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -30,24 +32,24 @@ type DeleteSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Delete(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Delete(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := DeleteSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *DeleteSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
func (opts *DeleteSubCommand) do(input cli.Input) error {
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.FnName),
|
||||
Namespace: input.String(flagkey.NamespaceFunction),
|
||||
}
|
||||
|
||||
err = opts.client.FunctionDelete(m)
|
||||
err := opts.client.FunctionDelete(m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("delete function '%v'", m.Name))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package function
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -47,7 +48,7 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// case: executor type set to poolmgr
|
||||
testArgs: map[string]interface{}{"executortype": fv1.ExecutorTypePoolmgr},
|
||||
testArgs: map[string]interface{}{flagkey.FnExecutorType: fv1.ExecutorTypePoolmgr},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -59,7 +60,7 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// case: executor type set to newdeploy
|
||||
testArgs: map[string]interface{}{"executortype": fv1.ExecutorTypeNewdeploy},
|
||||
testArgs: map[string]interface{}{flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -75,7 +76,7 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// case: executor type change from poolmgr to newdeploy
|
||||
testArgs: map[string]interface{}{"executortype": fv1.ExecutorTypeNewdeploy},
|
||||
testArgs: map[string]interface{}{flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
@@ -96,7 +97,7 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
},
|
||||
{
|
||||
// case: executor type change from newdeploy to poolmgr
|
||||
testArgs: map[string]interface{}{"executortype": fv1.ExecutorTypePoolmgr},
|
||||
testArgs: map[string]interface{}{flagkey.FnExecutorType: fv1.ExecutorTypePoolmgr},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
ExecutionStrategy: fv1.ExecutionStrategy{
|
||||
@@ -118,9 +119,9 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: minscale < maxscale
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"minscale": 2,
|
||||
"maxscale": 3,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMinscale: 2,
|
||||
flagkey.ReplicasMaxscale: 3,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
@@ -138,9 +139,9 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: minscale > maxscale
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"minscale": 5,
|
||||
"maxscale": 3,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMinscale: 5,
|
||||
flagkey.ReplicasMaxscale: 3,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
@@ -149,8 +150,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: maxscale not specified
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"minscale": 5,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMinscale: 5,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
@@ -159,8 +160,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: minscale not specified
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"maxscale": 3,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMaxscale: 3,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
@@ -178,8 +179,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: maxscale set to 0
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"maxscale": 0,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMaxscale: 0,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
@@ -188,8 +189,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: maxscale set to 9 when existing is 5
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"maxscale": 9,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.ReplicasMaxscale: 9,
|
||||
},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -216,7 +217,7 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: change nothing for existing strategy
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -243,8 +244,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: set target cpu percentage
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"targetcpu": 50,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.RuntimeTargetcpu: 50,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: &fv1.InvokeStrategy{
|
||||
@@ -262,8 +263,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: change target cpu percentage
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"targetcpu": 20,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.RuntimeTargetcpu: 20,
|
||||
},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -290,8 +291,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: change specializationtimeout
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"specializationtimeout": 200,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.FnSpecializationTimeout: 200,
|
||||
},
|
||||
existingInvokeStrategy: &fv1.InvokeStrategy{
|
||||
StrategyType: fv1.StrategyTypeExecution,
|
||||
@@ -317,8 +318,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: specializationtimeout should not work for poolmgr
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypePoolmgr,
|
||||
"specializationtimeout": 10,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypePoolmgr,
|
||||
flagkey.FnSpecializationTimeout: 10,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
@@ -327,8 +328,8 @@ func TestGetInvokeStrategy(t *testing.T) {
|
||||
{
|
||||
// case: specializationtimeout should not be less than 120
|
||||
testArgs: map[string]interface{}{
|
||||
"executortype": fv1.ExecutorTypeNewdeploy,
|
||||
"specializationtimeout": 90,
|
||||
flagkey.FnExecutorType: fv1.ExecutorTypeNewdeploy,
|
||||
flagkey.FnSpecializationTimeout: 90,
|
||||
},
|
||||
existingInvokeStrategy: nil,
|
||||
expectedResult: nil,
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -31,24 +32,22 @@ type GetSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Get(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Get(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := GetSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *GetSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fn, err := opts.client.FunctionGet(m)
|
||||
func (opts *GetSubCommand) do(input cli.Input) error {
|
||||
fn, err := opts.client.FunctionGet(&metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.FnName),
|
||||
Namespace: input.String(flagkey.NamespaceFunction),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting function")
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -32,24 +34,22 @@ type GetMetaSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func GetMeta(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func GetMeta(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := GetMetaSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *GetMetaSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fn, err := opts.client.FunctionGet(m)
|
||||
func (opts *GetMetaSubCommand) do(input cli.Input) error {
|
||||
fn, err := opts.client.FunctionGet(&metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.FnName),
|
||||
Namespace: input.String(flagkey.NamespaceFunction),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting function")
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -33,19 +34,19 @@ type ListSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func List(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func List(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := ListSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *ListSubCommand) do(flags cli.Input) error {
|
||||
ns := flags.String("fnNamespace")
|
||||
func (opts *ListSubCommand) do(input cli.Input) error {
|
||||
ns := input.String(flagkey.NamespaceFunction)
|
||||
|
||||
fns, err := opts.client.FunctionList(ns)
|
||||
if err != nil {
|
||||
|
||||
@@ -22,9 +22,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/logdb"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
@@ -33,38 +35,32 @@ type LogSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Log(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Log(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := LogSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *LogSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (opts *LogSubCommand) do(input cli.Input) error {
|
||||
dbType := input.String(flagkey.FnLogDBType)
|
||||
fnPod := input.String(flagkey.FnLogPod)
|
||||
|
||||
dbType := flags.String("dbtype")
|
||||
if len(dbType) == 0 {
|
||||
dbType = logdb.INFLUXDB
|
||||
}
|
||||
logReverseQuery := !input.Bool(flagkey.FnLogFollow) && input.Bool(flagkey.FnLogReverseQuery)
|
||||
|
||||
fnPod := flags.String("pod")
|
||||
|
||||
logReverseQuery := !flags.Bool("f") && flags.Bool("r")
|
||||
|
||||
recordLimit := flags.Int("recordcount")
|
||||
recordLimit := input.Int(flagkey.FnLogCount)
|
||||
if recordLimit <= 0 {
|
||||
recordLimit = 1000
|
||||
}
|
||||
|
||||
f, err := opts.client.FunctionGet(m)
|
||||
f, err := opts.client.FunctionGet(&metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.FnName),
|
||||
Namespace: input.String(flagkey.NamespaceFunction),
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error getting function")
|
||||
}
|
||||
@@ -104,7 +100,7 @@ func (opts *LogSubCommand) do(flags cli.Input) error {
|
||||
return
|
||||
}
|
||||
for _, logEntry := range logEntries {
|
||||
if flags.Bool("d") {
|
||||
if input.Bool(flagkey.FnLogDetail) {
|
||||
fmt.Printf("Timestamp: %s\nNamespace: %s\nFunction Name: %s\nFunction ID: %s\nPod: %s\nContainer: %s\nStream: %s\nLog: %s\n---\n",
|
||||
logEntry.Timestamp, logEntry.Namespace, logEntry.FuncName, logEntry.FuncUid, logEntry.Pod, logEntry.Container, logEntry.Stream, logEntry.Message)
|
||||
} else {
|
||||
@@ -124,7 +120,7 @@ func (opts *LogSubCommand) do(flags cli.Input) error {
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
<-responseChan
|
||||
if !flags.Bool("f") {
|
||||
if !input.Bool(flagkey.FnLogFollow) {
|
||||
ctx.Done()
|
||||
break
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -38,21 +39,21 @@ type TestSubCommand struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func Test(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Test(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := TestSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *TestSubCommand) do(flags cli.Input) error {
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
if err != nil {
|
||||
return err
|
||||
func (opts *TestSubCommand) do(input cli.Input) error {
|
||||
m := &metav1.ObjectMeta{
|
||||
Name: input.String(flagkey.FnName),
|
||||
Namespace: input.String(flagkey.NamespaceFunction),
|
||||
}
|
||||
|
||||
routerURL := os.Getenv("FISSION_ROUTER")
|
||||
@@ -76,7 +77,7 @@ func (opts *TestSubCommand) do(flags cli.Input) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryParams := flags.StringSlice("query")
|
||||
queryParams := input.StringSlice(flagkey.FnTestQuery)
|
||||
if len(queryParams) > 0 {
|
||||
query := url.Values{}
|
||||
for _, q := range queryParams {
|
||||
@@ -97,15 +98,15 @@ func (opts *TestSubCommand) do(flags cli.Input) error {
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if deadline := flags.Duration("timeout"); deadline > 0 {
|
||||
if deadline := input.Duration(flagkey.FnTestTimeout); deadline > 0 {
|
||||
var closeCtx func()
|
||||
ctx, closeCtx = context.WithTimeout(ctx, deadline)
|
||||
defer closeCtx()
|
||||
}
|
||||
|
||||
headers := flags.StringSlice("header")
|
||||
headers := input.StringSlice(flagkey.FnTestHeader)
|
||||
|
||||
resp, err := doHTTPRequest(ctx, flags.String("method"), functionUrl.String(), flags.String("body"), headers)
|
||||
resp, err := doHTTPRequest(ctx, input.String(flagkey.HtMethod), functionUrl.String(), input.String(flagkey.FnTestBody), headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -123,9 +124,9 @@ func (opts *TestSubCommand) do(flags cli.Input) error {
|
||||
}
|
||||
|
||||
fmt.Printf("Error calling function %s: %d; Please try again or fix the error: %s", m.Name, resp.StatusCode, string(body))
|
||||
err = printPodLogs(flags)
|
||||
err = printPodLogs(input)
|
||||
if err != nil {
|
||||
return Log(flags)
|
||||
return Log(input)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -157,8 +158,8 @@ func doHTTPRequest(ctx context.Context, method, url, body string, headers []stri
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func printPodLogs(flags cli.Input) error {
|
||||
fnName := flags.String("name")
|
||||
func printPodLogs(input cli.Input) error {
|
||||
fnName := input.String(flagkey.FnName)
|
||||
if len(fnName) == 0 {
|
||||
return errors.New("need --name argument.")
|
||||
}
|
||||
@@ -174,7 +175,7 @@ func printPodLogs(flags cli.Input) error {
|
||||
}
|
||||
queryURL.Path = fmt.Sprintf("/proxy/logs/%s", fnName)
|
||||
|
||||
req, err := http.NewRequest("POST", queryURL.String(), nil)
|
||||
req, err := http.NewRequest(http.MethodPost, queryURL.String(), nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error creating logs request")
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package function
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -27,7 +28,7 @@ import (
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
_package "github.com/fission/fission/pkg/fission-cli/cmd/package"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
@@ -37,41 +38,30 @@ type UpdateSubCommand struct {
|
||||
function *fv1.Function
|
||||
}
|
||||
|
||||
func Update(flags cli.Input) error {
|
||||
c, err := util.GetServer(flags)
|
||||
func Update(input cli.Input) error {
|
||||
c, err := util.GetServer(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts := UpdateSubCommand{
|
||||
client: c,
|
||||
}
|
||||
return opts.do(flags)
|
||||
return opts.do(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) do(flags cli.Input) error {
|
||||
err := opts.complete(flags)
|
||||
func (opts *UpdateSubCommand) do(input cli.Input) error {
|
||||
err := opts.complete(input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return opts.run(flags)
|
||||
return opts.run(input)
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
if len(flags.String("package")) > 0 {
|
||||
return errors.New("--package is deprecated, please use --deploy instead")
|
||||
}
|
||||
func (opts *UpdateSubCommand) complete(input cli.Input) error {
|
||||
fnName := input.String(flagkey.FnName)
|
||||
fnNamespace := input.String(flagkey.NamespaceFunction)
|
||||
|
||||
if len(flags.String("srcpkg")) > 0 {
|
||||
return errors.New("--srcpkg is deprecated, please use --src instead.")
|
||||
}
|
||||
|
||||
fnName := flags.String("name")
|
||||
if len(fnName) == 0 {
|
||||
return errors.New("Need name of function, use --name")
|
||||
}
|
||||
fnNamespace := flags.String("fnNamespace")
|
||||
|
||||
m, err := util.GetMetadata("name", "fnNamespace", flags)
|
||||
m, err := util.GetMetadata("name", "fnNamespace", input)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -81,8 +71,8 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("read function '%v'", fnName))
|
||||
}
|
||||
|
||||
envName := flags.String("env")
|
||||
envNamespace := flags.String("envNamespace")
|
||||
envName := input.String("env")
|
||||
envNamespace := input.String("envNamespace")
|
||||
// if the new env specified is the same as the old one, no need to update package
|
||||
// same is true for all update parameters, but, for now, we dont check all of them - because, its ok to
|
||||
// re-write the object with same old values, we just end up getting a new resource version for the object.
|
||||
@@ -96,24 +86,24 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
|
||||
var deployArchiveFiles []string
|
||||
codeFlag := false
|
||||
code := flags.String("code")
|
||||
code := input.String("code")
|
||||
if len(code) == 0 {
|
||||
deployArchiveFiles = flags.StringSlice("deploy")
|
||||
deployArchiveFiles = input.StringSlice("deploy")
|
||||
} else {
|
||||
deployArchiveFiles = append(deployArchiveFiles, flags.String("code"))
|
||||
deployArchiveFiles = append(deployArchiveFiles, input.String("code"))
|
||||
codeFlag = true
|
||||
}
|
||||
|
||||
srcArchiveFiles := flags.StringSlice("src")
|
||||
pkgName := flags.String("pkg")
|
||||
entrypoint := flags.String("entrypoint")
|
||||
buildcmd := flags.String("buildcmd")
|
||||
force := flags.Bool("force")
|
||||
srcArchiveFiles := input.StringSlice("src")
|
||||
pkgName := input.String("pkg")
|
||||
entrypoint := input.String("entrypoint")
|
||||
buildcmd := input.String("buildcmd")
|
||||
force := input.Bool("force")
|
||||
|
||||
secretNames := flags.StringSlice("secret")
|
||||
cfgMapNames := flags.StringSlice("configmap")
|
||||
secretNames := input.StringSlice("secret")
|
||||
cfgMapNames := input.StringSlice("configmap")
|
||||
|
||||
specializationTimeout := flags.Int("specializationtimeout")
|
||||
specializationTimeout := input.Int("specializationtimeout")
|
||||
|
||||
if len(srcArchiveFiles) > 0 && len(deployArchiveFiles) > 0 {
|
||||
return errors.New("Need either of --src or --deploy and not both arguments.")
|
||||
@@ -131,7 +121,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
Name: secretName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
console.Warn(fmt.Sprintf("secret %s not found in Namespace: %s. Secret needs to be present in the same namespace as function", secretName, fnNamespace))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +145,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
Name: cfgMapName,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as the function", cfgMapName, fnNamespace))
|
||||
console.Warn(fmt.Sprintf("ConfigMap %s not found in Namespace: %s. ConfigMap needs to be present in the same namespace as the function", cfgMapName, fnNamespace))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,8 +171,8 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
function.Spec.Package.FunctionName = entrypoint
|
||||
}
|
||||
|
||||
if flags.IsSet("fntimeout") {
|
||||
fnTimeout := flags.Int("fntimeout")
|
||||
if input.IsSet("fntimeout") {
|
||||
fnTimeout := input.Int("fntimeout")
|
||||
if fnTimeout <= 0 {
|
||||
return errors.New("fntimeout must be greater than 0")
|
||||
}
|
||||
@@ -193,13 +183,13 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
pkgName = function.Spec.Package.PackageRef.Name
|
||||
}
|
||||
|
||||
strategy, err := getInvokeStrategy(flags, &function.Spec.InvokeStrategy)
|
||||
strategy, err := getInvokeStrategy(input, &function.Spec.InvokeStrategy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
function.Spec.InvokeStrategy = *strategy
|
||||
|
||||
if flags.IsSet("specializationtimeout") {
|
||||
if input.IsSet("specializationtimeout") {
|
||||
if strategy.ExecutionStrategy.ExecutorType != types.ExecutorTypeNewdeploy {
|
||||
return errors.New("specializationtimeout flag is only applicable for newdeploy type of executor")
|
||||
}
|
||||
@@ -211,7 +201,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
}
|
||||
}
|
||||
|
||||
resReqs, err := util.GetResourceReqs(flags, &function.Spec.Resources)
|
||||
resReqs, err := util.GetResourceReqs(input, &function.Spec.Resources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -238,7 +228,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
return errors.New("package is used by multiple functions, use --force to force update")
|
||||
}
|
||||
|
||||
keepURL := flags.Bool("keepurl")
|
||||
keepURL := input.Bool("keepurl")
|
||||
|
||||
pkgMetadata, err = _package.UpdatePackage(opts.client, pkg, envName, envNamespace, srcArchiveFiles, deployArchiveFiles, buildcmd, false, codeFlag, keepURL)
|
||||
if err != nil {
|
||||
@@ -271,7 +261,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
}
|
||||
|
||||
if function.Spec.Environment.Name != pkg.Spec.Environment.Name {
|
||||
consolemsg.Warn("Function's environment is different than package's environment, package's environment will be used for updating function")
|
||||
console.Warn("Function's environment is different than package's environment, package's environment will be used for updating function")
|
||||
function.Spec.Environment.Name = pkg.Spec.Environment.Name
|
||||
function.Spec.Environment.Namespace = pkg.Spec.Environment.Namespace
|
||||
}
|
||||
@@ -281,7 +271,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (opts *UpdateSubCommand) run(flags cli.Input) error {
|
||||
func (opts *UpdateSubCommand) run(input cli.Input) error {
|
||||
_, err := opts.client.FunctionUpdate(opts.function)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error updating function")
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Copyright 2019 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 httptrigger
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create an HTTP trigger",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.HtUrlFlag, flag.HtFnNameFlag},
|
||||
Optional: []flag.Flag{flag.HtNameFlag, flag.HtMethodFlag, flag.HtIngressRuleFlag,
|
||||
flag.HtIngressAnnotationFlag, flag.HtIngressTLSFlag, flag.HtIngressFlag,
|
||||
flag.HtFnWeightFlag, flag.HtHostFlag, flag.NamespaceFunctionFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Aliases: []string{},
|
||||
Short: "Get HTTP trigger details",
|
||||
RunE: wrapper.Wrapper(Get),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.HtNameFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{},
|
||||
Short: "Update an HTTP trigger",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.HtNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag, flag.HtFnNameFlag, flag.HtUrlFlag,
|
||||
flag.HtMethodFlag, flag.HtIngressRuleFlag, flag.HtIngressAnnotationFlag,
|
||||
flag.HtIngressTLSFlag, flag.HtIngressFlag, flag.HtFnWeightFlag, flag.HtHostFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete an HTTP trigger",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.HtNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag, flag.HtFnFilterFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List all HTTP triggers in a namespace if specified, else, list HTTP triggers across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag, flag.HtFnFilterFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "httptrigger",
|
||||
Aliases: []string{"ht", "route"},
|
||||
Short: "Create, update and manage HTTP triggers",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getCmd, updateCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
ferror "github.com/fission/fission/pkg/error"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -104,7 +104,7 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
if !flags.Bool("spec") {
|
||||
err = util.CheckFunctionExistence(opts.client, functionList, fnNamespace)
|
||||
if err != nil {
|
||||
consolemsg.Warn(err.Error())
|
||||
console.Warn(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func (opts *CreateSubCommand) complete(flags cli.Input) error {
|
||||
|
||||
host := flags.String("host")
|
||||
if flags.IsSet("host") {
|
||||
consolemsg.Warn(fmt.Sprintf("--host is now marked as deprecated, see 'help' for details"))
|
||||
console.Warn(fmt.Sprintf("--host is now marked as deprecated, see 'help' for details"))
|
||||
}
|
||||
|
||||
// just name triggers by uuid.
|
||||
|
||||
@@ -19,12 +19,14 @@ package httptrigger
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
type DeleteSubCommand struct {
|
||||
@@ -84,7 +86,7 @@ func (opts *DeleteSubCommand) run(flags cli.Input) error {
|
||||
triggersToDelete = []string{opts.triggerName}
|
||||
}
|
||||
|
||||
errs := &multierror.Error{}
|
||||
errs := utils.MultiErrorWithFormat()
|
||||
|
||||
for _, name := range triggersToDelete {
|
||||
err := opts.client.HTTPTriggerDelete(&metav1.ObjectMeta{
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
)
|
||||
|
||||
@@ -73,7 +73,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
functionList := flags.StringSlice("function")
|
||||
err := util.CheckFunctionExistence(opts.client, functionList, triggerNamespace)
|
||||
if err != nil {
|
||||
consolemsg.Warn(err.Error())
|
||||
console.Warn(err.Error())
|
||||
}
|
||||
|
||||
var functionWeightsList []int
|
||||
@@ -96,7 +96,7 @@ func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||
|
||||
if flags.IsSet("host") {
|
||||
ht.Spec.Host = flags.String("host")
|
||||
consolemsg.Warn(fmt.Sprintf("--host is now marked as deprecated, see 'help' for details"))
|
||||
console.Warn(fmt.Sprintf("--host is now marked as deprecated, see 'help' for details"))
|
||||
}
|
||||
|
||||
if flags.IsSet("ingressrule") || flags.IsSet("ingressannotation") || flags.IsSet("ingresstls") {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2019 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 kubewatch
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a kube watcher",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.KwFnNameFlag, flag.KwObjTypeFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceFunctionFlag, flag.KwLabelsFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete a kube watcher",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.KwFnNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List all kube watchers in a namespace if specified, else, list kube watchers across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "watch",
|
||||
Aliases: []string{"w"},
|
||||
Short: "Create, update and manage kube watcher",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2019 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 mqtrigger
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a message queue trigger",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.MqtFnNameFlag, flag.MqtTopicFlag},
|
||||
Optional: []flag.Flag{flag.MqtNameFlag, flag.NamespaceFunctionFlag, flag.MqtMQTypeFlag,
|
||||
flag.MqtRespTopicFlag, flag.MqtErrorTopicFlag, flag.MqtMaxRetriesFlag, flag.MqtMsgContentTypeFlag,
|
||||
flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{},
|
||||
Short: "Update a message queue trigger",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.MqtNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag, flag.MqtTopicFlag, flag.MqtRespTopicFlag,
|
||||
flag.MqtErrorTopicFlag, flag.MqtMaxRetriesFlag, flag.MqtFnNameFlag, flag.MqtMsgContentTypeFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete a message queue trigger",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.MqtNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List all message queue triggers in a namespace if specified, else, list message queue triggers across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "mqtrigger",
|
||||
Aliases: []string{"mqt"},
|
||||
Short: "Create, update and manage message queue triggers",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, updateCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2019 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 _package
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a package",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.PkgEnvironmentFlag},
|
||||
Optional: []flag.Flag{flag.NamespacePackageFlag, flag.NamespaceEnvironmentFlag,
|
||||
flag.PkgSrcArchiveFlag, flag.PkgDeployArchiveFlag, flag.PkgKeepURLFlag, flag.PkgBuildCmdFlag},
|
||||
})
|
||||
|
||||
getSrcCmd := &cobra.Command{
|
||||
Use: "getsrc",
|
||||
Short: "Get package details",
|
||||
RunE: wrapper.Wrapper(GetSrc),
|
||||
}
|
||||
wrapper.SetFlags(getSrcCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.PkgNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespacePackageFlag, flag.PkgOutputFlag},
|
||||
})
|
||||
|
||||
getDeployCmd := &cobra.Command{
|
||||
Use: "getdeploy",
|
||||
Short: "Get package details",
|
||||
RunE: wrapper.Wrapper(GetDeploy),
|
||||
}
|
||||
wrapper.SetFlags(getDeployCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.PkgNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespacePackageFlag, flag.PkgOutputFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update a package",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.PkgNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespacePackageFlag, flag.PkgEnvironmentFlag, flag.NamespaceEnvironmentFlag,
|
||||
flag.PkgSrcArchiveFlag, flag.PkgDeployArchiveFlag, flag.PkgKeepURLFlag,
|
||||
flag.PkgBuildCmdFlag, flag.PkgForceFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete a package",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.PkgNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespacePackageFlag, flag.PkgForceFlag, flag.PkgOrphanFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all packages in a namespace if specified, else, list packages across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.PkgOrphanFlag, flag.PkgStatusFlag, flag.NamespacePackageFlag},
|
||||
})
|
||||
|
||||
infoCmd := &cobra.Command{
|
||||
Use: "info",
|
||||
Short: "Show package information",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(infoCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.PkgNameFlag, flag.NamespacePackageFlag},
|
||||
})
|
||||
|
||||
rebuildCmd := &cobra.Command{
|
||||
Use: "rebuild",
|
||||
Short: "Rebuild a failed package",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(rebuildCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.PkgNameFlag, flag.NamespacePackageFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "package",
|
||||
Aliases: []string{"pkg"},
|
||||
Short: "Create, update and manage packages",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getSrcCmd, getDeployCmd, updateCmd, deleteCmd, listCmd, infoCmd, rebuildCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -41,8 +41,7 @@ import (
|
||||
// upload the archive using client. noZip avoids zipping the
|
||||
// includeFiles, but is ignored if there's more than one includeFile.
|
||||
func CreateArchive(client *client.Client, includeFiles []string, noZip bool, keepURL bool, specDir string, specFile string) (*fv1.Archive, error) {
|
||||
|
||||
errs := &multierror.Error{}
|
||||
errs := utils.MultiErrorWithFormat()
|
||||
fileURL := ""
|
||||
|
||||
// check files existence
|
||||
@@ -65,7 +64,7 @@ func CreateArchive(client *client.Client, includeFiles []string, noZip bool, kee
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
errs = multierror.Append(errs, errors.New(fmt.Sprintf("Error finding any files with path \"%v\"", path)))
|
||||
errs = multierror.Append(errs, errors.Errorf("Error finding any files with path \"%v\"", path))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2019 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 plugin
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List installed client plugins",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "plugin",
|
||||
Aliases: []string{"plugins"},
|
||||
Short: "Manage CLI plugins",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
command.AddCommand(listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright 2019 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 recorder
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a recorder",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.RecorderNameFlag, flag.RecorderFnFlag, flag.RecorderTriggersFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get recorder details",
|
||||
RunE: wrapper.Wrapper(Get),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.RecorderNameFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Short: "Update a recorder",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(getCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.RecorderNameFlag},
|
||||
Optional: []flag.Flag{flag.RecorderFnFlag, flag.RecorderTriggersFlag, flag.RecorderEnabledFlag, flag.RecorderDisabledFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Short: "Delete a recorder",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.RecorderNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceRecorderFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List all recorders in a namespace if specified, else, list recorders across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceRecorderFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "recorder",
|
||||
Short: "Create, update and manage recorders",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, getCmd, updateCmd, deleteCmd, listCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2019 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 records
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
viewCmd := &cobra.Command{
|
||||
Use: "view",
|
||||
Short: "View existing records",
|
||||
RunE: wrapper.Wrapper(View),
|
||||
}
|
||||
wrapper.SetFlags(viewCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.RecordsFilterTimeToFlag, flag.RecordsFilterTimeFromFlag,
|
||||
flag.RecordsFilterFunctionFlag, flag.RecordsFilterTriggerFlag, flag.RecordsVerbosityFlag,
|
||||
flag.RecordsVvFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "records",
|
||||
Short: "View records with optional filters",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
command.AddCommand(viewCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2019 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 replay
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
replayCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a recorder",
|
||||
RunE: wrapper.Wrapper(Replay),
|
||||
}
|
||||
wrapper.SetFlags(replayCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.RecordsReqIDFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "replay",
|
||||
Short: "Replay records",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
command.AddCommand(replayCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -37,7 +37,7 @@ import (
|
||||
|
||||
pkgutil "github.com/fission/fission/pkg/fission-cli/cmd/package/util"
|
||||
spectypes "github.com/fission/fission/pkg/fission-cli/cmd/spec/types"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
@@ -430,7 +430,7 @@ func localArchiveFromSpec(specDir string, aus *spectypes.ArchiveUploadSpec) (*fv
|
||||
absGlob := rootDir + "/" + relativeGlob
|
||||
f, err := filepath.Glob(absGlob)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Invalid glob in archive %v: %v", aus.Name, relativeGlob))
|
||||
console.Info(fmt.Sprintf("Invalid glob in archive %v: %v", aus.Name, relativeGlob))
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, f...)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright 2019 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 spec
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
initCmd := &cobra.Command{
|
||||
Use: "init",
|
||||
Short: "Create an initial declarative application specification",
|
||||
RunE: wrapper.Wrapper(Init),
|
||||
}
|
||||
wrapper.SetFlags(initCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SpecDirFlag, flag.SpecNameFlag, flag.SpecDeployIDFlag},
|
||||
})
|
||||
|
||||
validateCmd := &cobra.Command{
|
||||
Use: "validate",
|
||||
Short: "Validate declarative application specification",
|
||||
RunE: wrapper.Wrapper(Validate),
|
||||
}
|
||||
wrapper.SetFlags(validateCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SpecDirFlag},
|
||||
})
|
||||
|
||||
applyCmd := &cobra.Command{
|
||||
Use: "apply",
|
||||
Short: "Create, update, or delete resources from application specification",
|
||||
RunE: wrapper.Wrapper(Apply),
|
||||
}
|
||||
wrapper.SetFlags(applyCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SpecDirFlag, flag.SpecDeployIDFlag, flag.SpecWaitFlag},
|
||||
})
|
||||
|
||||
destroyCmd := &cobra.Command{
|
||||
Use: "destroy",
|
||||
Short: "Delete an environment",
|
||||
RunE: wrapper.Wrapper(Destroy),
|
||||
}
|
||||
wrapper.SetFlags(destroyCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SpecDirFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "spec",
|
||||
Aliases: []string{"specs"},
|
||||
Short: "Manage a declarative application specification",
|
||||
}
|
||||
|
||||
command.AddCommand(initCmd, validateCmd, applyCmd, destroyCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -32,10 +32,11 @@ import (
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/cmd/spec/types"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/generator/encoder"
|
||||
v1generator "github.com/fission/fission/pkg/generator/v1"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
var specDefaultEncoder = encoder.DefaultYAMLEncoder()
|
||||
@@ -246,7 +247,7 @@ func (fr *FissionResources) validateFunctionReference(functions map[string]bool,
|
||||
}
|
||||
|
||||
func (fr *FissionResources) Validate(flags cli.Input) error {
|
||||
result := &multierror.Error{}
|
||||
result := utils.MultiErrorWithFormat()
|
||||
|
||||
// check references: both dangling refs + garbage
|
||||
// packages -> archives
|
||||
@@ -357,7 +358,7 @@ func (fr *FissionResources) Validate(flags cli.Input) error {
|
||||
Namespace: cm.Namespace,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("Configmap %s is referred in the spec but not present in the cluster", cm.Name))
|
||||
console.Warn(fmt.Sprintf("Configmap %s is referred in the spec but not present in the cluster", cm.Name))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +368,7 @@ func (fr *FissionResources) Validate(flags cli.Input) error {
|
||||
Namespace: s.Namespace,
|
||||
})
|
||||
if k8serrors.IsNotFound(err) {
|
||||
consolemsg.Warn(fmt.Sprintf("Secret %s is referred in the spec but not present in the cluster", s.Name))
|
||||
console.Warn(fmt.Sprintf("Secret %s is referred in the spec but not present in the cluster", s.Name))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -395,7 +396,7 @@ func (fr *FissionResources) Validate(flags cli.Input) error {
|
||||
}
|
||||
|
||||
if len(t.Spec.Host) > 0 {
|
||||
consolemsg.Warn(fmt.Sprintf("Host in HTTPTrigger spec.Host is now marked as deprecated, see 'help' for details"))
|
||||
console.Warn(fmt.Sprintf("Host in HTTPTrigger spec.Host is now marked as deprecated, see 'help' for details"))
|
||||
}
|
||||
|
||||
result = multierror.Append(result, t.Validate())
|
||||
@@ -430,25 +431,25 @@ func (fr *FissionResources) Validate(flags cli.Input) error {
|
||||
for _, e := range fr.Environments {
|
||||
environments[fmt.Sprintf("%s:%s", e.Metadata.Name, e.Metadata.Namespace)] = struct{}{}
|
||||
if ((e.Spec.Runtime.Container != nil) && (e.Spec.Runtime.PodSpec != nil)) || ((e.Spec.Builder.Container != nil) && (e.Spec.Builder.PodSpec != nil)) {
|
||||
consolemsg.Warn("You have provided both - container spec and pod spec and while merging the pod spec will take precedence.")
|
||||
console.Warn("You have provided both - container spec and pod spec and while merging the pod spec will take precedence.")
|
||||
}
|
||||
// Unlike CLI can change the environment version silently,
|
||||
// we have to warn the user to modify spec file when this takes place.
|
||||
if e.Spec.Version < 3 && e.Spec.Poolsize != 0 {
|
||||
consolemsg.Warn("Poolsize can only be configured when environment version equals to 3, default poolsize 3 will be used for creating environment pool.")
|
||||
console.Warn("Poolsize can only be configured when environment version equals to 3, default poolsize 3 will be used for creating environment pool.")
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range fr.Functions {
|
||||
if _, ok := environments[fmt.Sprintf("%s:%s", f.Spec.Environment.Name, f.Spec.Environment.Namespace)]; !ok {
|
||||
consolemsg.Warn(fmt.Sprintf("Environment %s is referenced in function %s but not declared in specs", f.Spec.Environment.Name, f.Metadata.Name))
|
||||
console.Warn(fmt.Sprintf("Environment %s is referenced in function %s but not declared in specs", f.Spec.Environment.Name, f.Metadata.Name))
|
||||
}
|
||||
strategy := f.Spec.InvokeStrategy.ExecutionStrategy
|
||||
if strategy.ExecutorType == fv1.ExecutorTypeNewdeploy && strategy.SpecializationTimeout < fv1.DefaultSpecializationTimeOut {
|
||||
consolemsg.Warn(fmt.Sprintf("SpecializationTimeout in function spec.InvokeStrategy.ExecutionStrategy should be a value equal to or greater than %v", fv1.DefaultSpecializationTimeOut))
|
||||
console.Warn(fmt.Sprintf("SpecializationTimeout in function spec.InvokeStrategy.ExecutionStrategy should be a value equal to or greater than %v", fv1.DefaultSpecializationTimeOut))
|
||||
}
|
||||
if f.Spec.FunctionTimeout <= 0 {
|
||||
consolemsg.Warn(fmt.Sprintf("FunctionTimeout in function spec should be a field which should have a value greater than 0"))
|
||||
console.Warn(fmt.Sprintf("FunctionTimeout in function spec should be a field which should have a value greater than 0"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +578,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
default:
|
||||
// no need to error out just because there's some extra files around;
|
||||
// also good for compatibility.
|
||||
consolemsg.Warn(fmt.Sprintf("Ignoring unknown type %v in %v", tm.Kind, loc))
|
||||
console.Warn(fmt.Sprintf("Ignoring unknown type %v in %v", tm.Kind, loc))
|
||||
}
|
||||
|
||||
// add to source map, check for duplicates
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright 2019 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 support
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
dumpCmd := &cobra.Command{
|
||||
Use: "dump",
|
||||
Short: "Collect & dump all necessary information for troubleshooting",
|
||||
RunE: wrapper.Wrapper(Dump),
|
||||
}
|
||||
wrapper.SetFlags(dumpCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SupportNoZipFlag, flag.SupportOutputFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "support",
|
||||
Short: "Collect diagnostic information for support",
|
||||
}
|
||||
|
||||
command.AddCommand(dumpCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdEnvironment:
|
||||
items, err := res.client.EnvironmentList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdFunction:
|
||||
items, err := res.client.FunctionList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdPackage:
|
||||
items, err := res.client.PackageList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdHttpTrigger:
|
||||
items, err := res.client.HTTPTriggerList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdKubeWatcher:
|
||||
items, err := res.client.WatchList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
for _, mqType := range []string{types.MessageQueueTypeNats, types.MessageQueueTypeASQ} {
|
||||
l, err := res.client.MessageQueueTriggerList(mqType, metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
break
|
||||
}
|
||||
triggers = append(triggers, l...)
|
||||
@@ -131,7 +131,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
case CrdTimeTrigger:
|
||||
items, err := res.client.TimeTriggerList(metav1.NamespaceAll)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list: %v", res.crdType, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func (res CrdDumper) Dump(dumpDir string) {
|
||||
}
|
||||
|
||||
default:
|
||||
consolemsg.Info(fmt.Sprintf("Unknown type: %v", res.crdType))
|
||||
console.Info(fmt.Sprintf("Unknown type: %v", res.crdType))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -52,7 +52,7 @@ func NewKubernetesVersion(clientset *kubernetes.Clientset) Resource {
|
||||
func (res KubernetesVersion) Dump(dumpDir string) {
|
||||
serverVer, err := res.client.ServerVersion()
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error setting up kubernetes client: %v", err))
|
||||
console.Info(fmt.Sprintf("Error setting up kubernetes client: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesService:
|
||||
objs, err := res.client.CoreV1().Services(metav1.NamespaceAll).List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesDeployment:
|
||||
objs, err := res.client.AppsV1().Deployments(metav1.NamespaceAll).List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesPod:
|
||||
objs, err := res.client.CoreV1().Pods(metav1.NamespaceAll).List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesHPA:
|
||||
objs, err := res.client.AutoscalingV2beta1().HorizontalPodAutoscalers(metav1.NamespaceAll).List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesDaemonSet:
|
||||
objs, err := res.client.AppsV1().DaemonSets(metav1.NamespaceAll).List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
case KubernetesNode:
|
||||
objs, err := res.client.CoreV1().Nodes().List(metav1.ListOptions{LabelSelector: res.selector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
console.Info(fmt.Sprintf("Error getting %v list with selector %v: %v", res.objType, res.selector, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ func (res KubernetesObjectDumper) Dump(dumpDir string) {
|
||||
}
|
||||
|
||||
default:
|
||||
consolemsg.Info(fmt.Sprintf("Unknown type: %v", res.objType))
|
||||
console.Info(fmt.Sprintf("Unknown type: %v", res.objType))
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func (res KubernetesPodLogDumper) Dump(dumpDir string) {
|
||||
Pods(metav1.NamespaceAll).
|
||||
List(metav1.ListOptions{LabelSelector: res.labelSelector})
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error getting controller list: %v", err))
|
||||
console.Info(fmt.Sprintf("Error getting controller list: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ func (res KubernetesPodLogDumper) Dump(dumpDir string) {
|
||||
|
||||
stream, err := req.Stream()
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error streaming logs for pod %v: %v", pod.Name, err))
|
||||
console.Info(fmt.Sprintf("Error streaming logs for pod %v: %v", pod.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -232,13 +232,13 @@ func (res KubernetesPodLogDumper) Dump(dumpDir string) {
|
||||
stream.Close()
|
||||
break
|
||||
}
|
||||
consolemsg.Info(fmt.Sprintf("Error reading logs from buffer: %v", err))
|
||||
console.Info(fmt.Sprintf("Error reading logs from buffer: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
_, err = buffer.WriteString(string(line) + "\n")
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error writing bytes to buffer: %v", err))
|
||||
console.Info(fmt.Sprintf("Error writing bytes to buffer: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"github.com/ghodss/yaml"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ func getPodFileName(dumpdir string, pod metav1.ObjectMeta, containerName string)
|
||||
func writeToFile(file string, obj interface{}) {
|
||||
bs, err := yaml.Marshal(obj)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error encoding object: %v", err))
|
||||
console.Info(fmt.Sprintf("Error encoding object: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -57,6 +57,6 @@ func writeToFile(file string, obj interface{}) {
|
||||
|
||||
err = ioutil.WriteFile(file, bs, 0644)
|
||||
if err != nil {
|
||||
consolemsg.Info(fmt.Sprintf("Error writing file %v: %v", file, err))
|
||||
console.Info(fmt.Sprintf("Error writing file %v: %v", file, err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright 2019 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 timetrigger
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
createCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
Short: "Create a time trigger",
|
||||
RunE: wrapper.Wrapper(Create),
|
||||
}
|
||||
wrapper.SetFlags(createCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.TtNameFlag, flag.TtFnNameFlag, flag.NamespaceFunctionFlag, flag.TtCronFlag, flag.SpecSaveFlag},
|
||||
})
|
||||
|
||||
updateCmd := &cobra.Command{
|
||||
Use: "update",
|
||||
Aliases: []string{},
|
||||
Short: "Update a time trigger",
|
||||
RunE: wrapper.Wrapper(Update),
|
||||
}
|
||||
wrapper.SetFlags(updateCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.TtNameFlag},
|
||||
Optional: []flag.Flag{flag.TtFnNameFlag, flag.NamespaceFunctionFlag, flag.TtCronFlag},
|
||||
})
|
||||
|
||||
deleteCmd := &cobra.Command{
|
||||
Use: "delete",
|
||||
Aliases: []string{},
|
||||
Short: "Delete a time trigger",
|
||||
RunE: wrapper.Wrapper(Delete),
|
||||
}
|
||||
wrapper.SetFlags(deleteCmd, flag.FlagSet{
|
||||
Required: []flag.Flag{flag.TtNameFlag},
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
listCmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{},
|
||||
Short: "List all time triggers in a namespace if specified, else, list time triggers across all namespaces",
|
||||
RunE: wrapper.Wrapper(List),
|
||||
}
|
||||
wrapper.SetFlags(listCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.NamespaceTriggerFlag},
|
||||
})
|
||||
|
||||
showCmd := &cobra.Command{
|
||||
Use: "showschedule",
|
||||
Aliases: []string{"show"},
|
||||
Short: "Show schedule for cron spec",
|
||||
RunE: wrapper.Wrapper(Show),
|
||||
}
|
||||
wrapper.SetFlags(showCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.TtCronFlag, flag.TtRoundFlag},
|
||||
})
|
||||
|
||||
command := &cobra.Command{
|
||||
Use: "timetrigger",
|
||||
Aliases: []string{"tt", "timer"},
|
||||
Short: "Create, update and manage time triggers",
|
||||
}
|
||||
|
||||
command.AddCommand(createCmd, updateCmd, deleteCmd, listCmd, showCmd)
|
||||
|
||||
return command
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2019 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 version
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
wrapper "github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/cobra"
|
||||
)
|
||||
|
||||
func Commands() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Version information",
|
||||
RunE: wrapper.Wrapper(Version),
|
||||
}
|
||||
return command
|
||||
}
|
||||
@@ -14,11 +14,13 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package consolemsg
|
||||
package console
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/life1347/color"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,13 +28,8 @@ var (
|
||||
Verbosity int
|
||||
)
|
||||
|
||||
func Fatal(msg interface{}) {
|
||||
//os.Stderr.WriteString(fmt.Sprintf("Fatal error: %v\n", msg))
|
||||
//os.Exit(1)
|
||||
}
|
||||
|
||||
func Warn(msg interface{}) {
|
||||
os.Stderr.WriteString(fmt.Sprintf("Warning: %v\n", msg))
|
||||
os.Stdout.WriteString(fmt.Sprintf("%v: %v\n", color.YellowString("Warning"), msg))
|
||||
}
|
||||
|
||||
func Info(msg interface{}) {
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Copyright 2019 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 flag
|
||||
|
||||
import "strings"
|
||||
|
||||
const (
|
||||
GLOBAL_VERBOSITY = "verbosity"
|
||||
GLOBAL_PLUGIN = "plugin"
|
||||
|
||||
FISSION_SERVER = "server"
|
||||
|
||||
RESOURCE_NAME = "name"
|
||||
|
||||
ENVIRONMENT_NAMESPACE = "envNamespace"
|
||||
ENVIRONMENT_NAMESPACE_ALIAS = "envns"
|
||||
ENVIRONMENT_POOLSIZE = "poolsize"
|
||||
ENVIRONMENT_IMAGE = "image"
|
||||
ENVIRONMENT_BUILDER = "builder"
|
||||
ENVIRONMENT_BUILDCOMMAND = "buildcmd"
|
||||
ENVIRONMENT_KEEPARCHIVE = "keeparchive"
|
||||
ENVIRONMENT_EXTERNAL_NETWORK = "externalnetwork"
|
||||
ENVIRONMENT_GRACE_PERIOD = "graceperiod"
|
||||
ENVIRONMENT_GRACE_PERIOD_ALIAS = "period"
|
||||
ENVIRONMENT_VERSION = "version"
|
||||
|
||||
SPEC_SPEC = "spec"
|
||||
SPEC_SPECDIR = "specdir"
|
||||
|
||||
RUNTIME_MINCPU = "mincpu"
|
||||
RUNTIME_MAXCPU = "maxcpu"
|
||||
RUNTIME_MINMEMORY = "minmemory"
|
||||
RUNTIME_MAXMEMORY = "maxmemory"
|
||||
RUNTIME_MINSCALE = "minscale"
|
||||
RUNTIME_MAXSCALE = "maxscale"
|
||||
RUNTIME_TARGETCPU = "targetcpu"
|
||||
)
|
||||
|
||||
// GetCliFlagName concatenates flag and its alias into a command flag name.
|
||||
func GetCliFlagName(flags ...string) string {
|
||||
return strings.Join(flags, ", ")
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
Copyright 2019 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 flag
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/types"
|
||||
)
|
||||
|
||||
type (
|
||||
FlagType = int
|
||||
|
||||
FlagSet struct {
|
||||
Required []Flag
|
||||
Optional []Flag
|
||||
}
|
||||
|
||||
Flag struct {
|
||||
Name string
|
||||
Type FlagType
|
||||
Short string // one-letter abbreviated flag
|
||||
Aliases []string
|
||||
Usage string
|
||||
DefaultValue interface{}
|
||||
|
||||
// If a flag is marked as deprecated, it will hided from
|
||||
// the help message automatically. Hence, a flag cannot be
|
||||
// marked as hidden and deprecated at the same time.
|
||||
Hidden bool
|
||||
Deprecated bool
|
||||
// flag name to replace the deprecated flag
|
||||
Substitute string
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
Bool FlagType = iota + 1
|
||||
String
|
||||
StringSlice
|
||||
Int
|
||||
IntSlice
|
||||
Int64
|
||||
Int64Slice
|
||||
Float32
|
||||
Float64
|
||||
Duration
|
||||
)
|
||||
|
||||
var (
|
||||
GlobalVerbosityFlag = Flag{Type: Int, Name: flagkey.Verbosity, Short: "v", Usage: "CLI verbosity (0 is quiet, 1 is the default, 2 is verbose)", DefaultValue: 1}
|
||||
GlobalServerFlag = Flag{Type: String, Name: flagkey.Server, Usage: "Server URL"}
|
||||
|
||||
NamespaceFunctionFlag = Flag{Type: String, Name: flagkey.NamespaceFunction, Aliases: []string{"fns"}, Usage: "Namespace for function object", DefaultValue: metav1.NamespaceDefault}
|
||||
NamespaceEnvironmentFlag = Flag{Type: String, Name: flagkey.NamespaceEnvironment, Aliases: []string{"envns"}, Usage: "Namespace for environment object", DefaultValue: metav1.NamespaceDefault}
|
||||
NamespacePackageFlag = Flag{Type: String, Name: flagkey.NamespacePackage, Aliases: []string{"pkgns"}, Usage: "Namespace for package object", DefaultValue: metav1.NamespaceDefault}
|
||||
NamespaceTriggerFlag = Flag{Type: String, Name: flagkey.NamespaceTrigger, Aliases: []string{"triggerns"}, Usage: "Namespace for trigger object", DefaultValue: metav1.NamespaceDefault}
|
||||
NamespaceRecorderFlag = Flag{Type: String, Name: flagkey.NamespaceRecorder, Aliases: []string{"recorderns"}, Usage: "Namespace for recorder object", DefaultValue: metav1.NamespaceDefault}
|
||||
NamespaceCanaryFlag = Flag{Type: String, Name: flagkey.NamespaceCanary, Aliases: []string{"canaryns"}, Usage: "Namespace for canary config object", DefaultValue: metav1.NamespaceDefault}
|
||||
|
||||
RunTimeMinCPUFlag = Flag{Type: Int, Name: flagkey.RuntimeMincpu, Usage: "Minimum CPU to be assigned to pod (In millicore, minimum 1)"}
|
||||
RunTimeMaxCPUFlag = Flag{Type: Int, Name: flagkey.RuntimeMaxcpu, Usage: "Maximum CPU to be assigned to pod (In millicore, minimum 1)"}
|
||||
RunTimeTargetCPUFlag = Flag{Type: Int, Name: flagkey.RuntimeTargetcpu, Usage: "Target average CPU usage percentage across pods for scaling", DefaultValue: 80}
|
||||
RunTimeMinMemoryFlag = Flag{Type: Int, Name: flagkey.RuntimeMinmemory, Usage: "Minimum memory to be assigned to pod (In megabyte)"}
|
||||
RunTimeMaxMemoryFlag = Flag{Type: Int, Name: flagkey.RuntimeMaxmemory, Usage: "Maximum memory to be assigned to pod (In megabyte)"}
|
||||
|
||||
ReplicasMinFlag = Flag{Type: Int, Name: flagkey.ReplicasMinscale, Usage: "Minimum number of pods (Uses resource inputs to configure HPA)", DefaultValue: 1}
|
||||
ReplicasMaxFlag = Flag{Type: Int, Name: flagkey.ReplicasMaxscale, Usage: "Maximum number of pods (Uses resource inputs to configure HPA)", DefaultValue: 1}
|
||||
|
||||
FnNameFlag = Flag{Type: String, Name: flagkey.FnName, Usage: "Function name"}
|
||||
FnSpecializationTimeoutFlag = Flag{Type: Int, Name: flagkey.FnSpecializationTimeout, Aliases: []string{"st"}, Usage: "Timeout for newdeploy to wait for function pod creation", DefaultValue: fv1.DefaultSpecializationTimeOut}
|
||||
FnEnvNameFlag = Flag{Type: String, Name: flagkey.FnEnvironmentName, Usage: "Environment name for function"}
|
||||
FnCodeFlag = Flag{Type: String, Name: flagkey.FnCode, Usage: "Local path or URL for single file source code"}
|
||||
FnKeepURLFlag = Flag{Type: Bool, Name: flagkey.PkgKeepURL, Aliases: []string{"keepurl"}, Usage: "Keep the providing URL in archive instead of downloading file from it. (If set, no checksum will be generated for file integrity check. You must ensure the file won't be changed.)"}
|
||||
FnPkgNameFlag = Flag{Type: String, Name: flagkey.FnPackageName, Aliases: []string{"pkg"}, Usage: "Name of the existing package (--deploy and --src and --env will be ignored), should be in the same namespace as the function"}
|
||||
FnEntryPointFlag = Flag{Type: String, Name: flagkey.FnEntrypoint, Aliases: []string{"entry"}, Usage: "Entry point for environment v2 to load with"}
|
||||
FnBuildCmdFlag = Flag{Type: String, Name: flagkey.FnBuildCmd, Usage: "Package build command for builder to run with"}
|
||||
FnSecretFlag = Flag{Type: StringSlice, Name: flagkey.FnSecret, Usage: "Function access to secret, should be present in the same namespace as the function. You can provide multiple secrets using multiple --secrets flags. In the case of fn update the the secrets will be replaced by the provided list of secrets."}
|
||||
FnCfgMapFlag = Flag{Type: StringSlice, Name: flagkey.FnCfgMap, Usage: "Function access to configmap, should be present in the same namespace as the function. You can provide multiple configmaps using multiple --configmap flags. In case of fn update the configmaps will be replaced by the provided list of configmaps."}
|
||||
FnExecutorTypeFlag = Flag{Type: String, Name: flagkey.FnExecutorType, Usage: "Executor type for execution; one of 'poolmgr', 'newdeploy'", DefaultValue: types.ExecutorTypePoolmgr}
|
||||
FnExecutionTimeoutFlag = Flag{Type: Int, Name: flagkey.FnExecutionTimeout, Aliases: []string{"ft"}, Usage: "Time duration to wait for the response while executing the function", DefaultValue: 60}
|
||||
FnLogPodFlag = Flag{Type: String, Name: flagkey.FnLogPod, Usage: "Function pod name (use the latest pod name if unspecified)"}
|
||||
FnLogFollowFlag = Flag{Type: Bool, Name: flagkey.FnLogFollow, Short: "f", Usage: "Specify if the logs should be streamed"}
|
||||
FnLogDetailFlag = Flag{Type: Bool, Name: flagkey.FnLogDetail, Short: "d", Usage: "Display detailed information"}
|
||||
FnLogDBTypeFlag = Flag{Type: String, Name: flagkey.FnLogDBType, Usage: "Log database type, e.g. influxdb (currently only influxdb is supported)", DefaultValue: "influxdb"}
|
||||
FnLogReverseQueryFlag = Flag{Type: Bool, Name: flagkey.FnLogReverseQuery, Short: "r", Usage: "Specify the log reverse query base on time, it will be invalid if the 'follow' flag is specified"}
|
||||
FnLogCountFlag = Flag{Type: Int, Name: flagkey.FnLogCount, Usage: "Get N most recent log records", DefaultValue: 20}
|
||||
FnTestBodyFlag = Flag{Type: String, Name: flagkey.FnTestBody, Short: "b", Usage: "Request body"}
|
||||
FnTestTimeoutFlag = Flag{Type: Duration, Name: flagkey.FnTestTimeout, Short: "t", Usage: "Length of time to wait for the response. If set to zero or negative number, no timeout is set", DefaultValue: 30 * time.Second}
|
||||
FnTestHeaderFlag = Flag{Type: StringSlice, Name: flagkey.FnTestHeader, Short: "H", Usage: "Request headers"}
|
||||
FnTestQueryFlag = Flag{Type: StringSlice, Name: flagkey.FnTestQuery, Short: "q", Usage: "Request query parameters: -q key1=value1 -q key2=value2"}
|
||||
|
||||
HtNameFlag = Flag{Type: String, Name: flagkey.HtName, Usage: "HTTP trigger name"}
|
||||
HtMethodFlag = Flag{Type: String, Name: flagkey.HtMethod, Usage: "HTTP Method: GET|POST|PUT|DELETE|HEAD", DefaultValue: http.MethodGet}
|
||||
HtUrlFlag = Flag{Type: String, Name: flagkey.HtUrl, Usage: "URL pattern (See gorilla/mux supported patterns)"}
|
||||
HtHostFlag = Flag{Type: String, Name: flagkey.HtHost, Usage: "Use --ingressrule instead", Deprecated: true, Substitute: flagkey.HtIngressRule}
|
||||
HtIngressFlag = Flag{Type: Bool, Name: flagkey.HtIngress, Usage: "Creates ingress with same URL"}
|
||||
HtIngressRuleFlag = Flag{Type: String, Name: flagkey.HtIngressRule, Usage: "Host for Ingress rule: --ingressrule host=path (the format of host/path depends on what ingress controller you used)"}
|
||||
HtIngressAnnotationFlag = Flag{Type: StringSlice, Name: flagkey.HtIngressAnnotation, Usage: "Annotation for Ingress: --ingressannotation key=value (the format of annotation depends on what ingress controller you used)"}
|
||||
HtIngressTLSFlag = Flag{Type: String, Name: flagkey.HtIngressTLS, Usage: "Name of the Secret contains TLS key and crt for Ingress (the usability of TLS features depends on what ingress controller you used)"}
|
||||
HtFnNameFlag = Flag{Type: StringSlice, Name: flagkey.HtFnName, Usage: "Name(s) of the function for this trigger. (If 2 functions are supplied with this flag, traffic gets routed to them based on weights supplied with --weight flag.)"}
|
||||
HtFnWeightFlag = Flag{Type: IntSlice, Name: flagkey.HtFnWeight, Usage: "Weight for each function supplied with --function flag, in the same order. Used for canary deployment"}
|
||||
HtFnFilterFlag = Flag{Type: String, Name: flagkey.HtFilter, Usage: "Name of the function for trigger(s)"}
|
||||
|
||||
TtNameFlag = Flag{Type: String, Name: flagkey.TtName, Usage: "Time Trigger name"}
|
||||
TtCronFlag = Flag{Type: String, Name: flagkey.TtCron, Usage: "Time trigger cron spec with each asterisk representing respectively second, minute, hour, the day of the month, month and day of the week. Also supports readable formats like '@every 5m', '@hourly'"}
|
||||
TtFnNameFlag = Flag{Type: String, Name: flagkey.TtFnName, Usage: "Function name"}
|
||||
TtRoundFlag = Flag{Type: Int, Name: flagkey.TtRound, Usage: "Get next N rounds of invocation time", DefaultValue: 1}
|
||||
|
||||
MqtNameFlag = Flag{Type: String, Name: flagkey.MqtName, Usage: "Message queue trigger name"}
|
||||
MqtFnNameFlag = Flag{Type: String, Name: flagkey.MqtFnName, Usage: "Function name"}
|
||||
MqtMQTypeFlag = Flag{Type: String, Name: flagkey.MqtMQType, Usage: "Message queue type, e.g. nats-streaming, azure-storage-queue", DefaultValue: "nats-streaming"}
|
||||
MqtTopicFlag = Flag{Type: String, Name: flagkey.MqtTopic, Usage: "Message queue Topic the trigger listens on"}
|
||||
MqtRespTopicFlag = Flag{Type: String, Name: flagkey.MqtRespTopic, Usage: "Topic that the function response is sent on (response discarded if unspecified)"}
|
||||
MqtErrorTopicFlag = Flag{Type: String, Name: flagkey.MqtErrorTopic, Usage: "Topic that the function error messages are sent to (errors discarded if unspecified"}
|
||||
MqtMaxRetriesFlag = Flag{Type: Int, Name: flagkey.MqtMaxRetries, Usage: "Maximum number of times the function will be retried upon failure", DefaultValue: 0}
|
||||
MqtMsgContentTypeFlag = Flag{Type: String, Name: flagkey.MqtMsgContentType, Short: "c", Usage: "Content type of messages that publish to the topic", DefaultValue: "application/json"}
|
||||
|
||||
RecorderNameFlag = Flag{Type: String, Name: flagkey.RecorderName, Usage: "Recorder name"}
|
||||
RecorderFnFlag = Flag{Type: String, Name: flagkey.RecorderFn, Usage: "Record Function name(s): --function=fnA"}
|
||||
RecorderTriggersFlag = Flag{Type: StringSlice, Name: flagkey.RecorderTriggers, Usage: "Record Trigger name(s): --trigger=trigger1,trigger2,trigger3"}
|
||||
RecorderRetentionPolicyFlag = Flag{Type: String, Name: flagkey.RecorderRetentionPolicy, Usage: "Retention policy (number of days)"}
|
||||
RecorderEvictionPolicyFlag = Flag{Type: String, Name: flagkey.RecorderEvictionPolcy, Usage: "Eviction policy (default LRU)"}
|
||||
RecorderEnabledFlag = Flag{Type: Bool, Name: flagkey.RecorderEnabled, Usage: "Enable recorder"}
|
||||
RecorderDisabledFlag = Flag{Type: Bool, Name: flagkey.RecorderDisabled, Usage: "Disable recorder"}
|
||||
|
||||
RecordsFilterTimeFromFlag = Flag{Type: String, Name: flagkey.RecordsFilterTimeFrom, Usage: "Filter records by time interval; specify start of interval"}
|
||||
RecordsFilterTimeToFlag = Flag{Type: String, Name: flagkey.RecordsFilterTimeTo, Usage: "Filter records by time interval; specify end of interval"}
|
||||
RecordsFilterFunctionFlag = Flag{Type: String, Name: flagkey.RecordsFilterFunction, Usage: "Filter records by function"}
|
||||
RecordsFilterTriggerFlag = Flag{Type: String, Name: flagkey.RecordsFilterTrigger, Usage: "Filter records by trigger"}
|
||||
RecordsVerbosityFlag = Flag{Type: Bool, Name: flagkey.RecordsVerbosity, Usage: "Toggle verbosity -- view more detailed requests/responses"}
|
||||
RecordsVvFlag = Flag{Type: Bool, Name: flagkey.RecordsVv, Usage: "Toggle verbosity -- view raw requests/responses"}
|
||||
RecordsReqIDFlag = Flag{Type: String, Name: flagkey.RecordsReqID, Usage: "Replay a particular request by providing the reqUID (to view reqUIDs, do 'fission records view')"}
|
||||
|
||||
EnvNameFlag = Flag{Type: String, Name: flagkey.EnvName, Usage: "Environment name"}
|
||||
EnvPoolsizeFlag = Flag{Type: Int, Name: flagkey.EnvPoolsize, Usage: "Size of the pool", DefaultValue: 3}
|
||||
EnvImageFlag = Flag{Type: String, Name: flagkey.EnvImage, Usage: "Environment image URL"}
|
||||
EnvBuilderImageFlag = Flag{Type: String, Name: flagkey.EnvBuilderImage, Usage: "Environment builder image URL"}
|
||||
EnvBuildCmdFlag = Flag{Type: String, Name: flagkey.EnvBuildcommand, Usage: "Build command for environment builder to build source package"}
|
||||
EnvKeepArchiveFlag = Flag{Type: Bool, Name: flagkey.EnvKeeparchive, Usage: "Keep the archive instead of extracting it into a directory"}
|
||||
EnvExternalNetworkFlag = Flag{Type: Bool, Name: flagkey.EnvExternalNetwork, Usage: "Allow environment access external network when istio feature enabled"}
|
||||
EnvTerminationGracePeriodFlag = Flag{Type: Int, Name: flagkey.EnvGracePeriod, Aliases: []string{"period"}, Usage: "Grace time (in seconds) for pod to perform connection draining before termination", DefaultValue: 360}
|
||||
EnvVersionFlag = Flag{Type: Int, Name: flagkey.EnvVersion, Usage: "Environment API version (1 means v1 interface)", DefaultValue: 1}
|
||||
|
||||
KwNameFlag = Flag{Type: String, Name: flagkey.KwName, Usage: "Watch name"}
|
||||
KwFnNameFlag = Flag{Type: String, Name: flagkey.KwFnName, Usage: "Function name"}
|
||||
KwNamespaceFlag = Flag{Type: String, Name: flagkey.KwNamespace, Usage: "Namespace of resource to watch"}
|
||||
KwObjTypeFlag = Flag{Type: String, Name: flagkey.KwObjType, Usage: "Type of resource to watch (Pod, Service, etc.)"}
|
||||
KwLabelsFlag = Flag{Type: String, Name: flagkey.KwLabels, Usage: "Label selector of the form a=b,c=d"}
|
||||
|
||||
PkgNameFlag = Flag{Type: String, Name: flagkey.PkgName, Usage: "Package name"}
|
||||
PkgForceFlag = Flag{Type: Bool, Name: flagkey.PkgForce, Short: "f", Usage: "Force update a package even if it is used by one or more functions"}
|
||||
PkgEnvironmentFlag = Flag{Type: String, Name: flagkey.PkgEnvironment, Usage: "Environment name"}
|
||||
PkgKeepURLFlag = Flag{Type: Bool, Name: flagkey.PkgKeepURL, Aliases: []string{"keepurl"}, Usage: "Keep the providing URL in archive instead of downloading file from it. (If set, no checksum will be generated for file integrity check. You must ensure the file won't be changed.)"}
|
||||
PkgBuildCmdFlag = Flag{Type: String, Name: flagkey.PkgBuildCmd, Usage: "Build command for builder to run with"}
|
||||
PkgOutputFlag = Flag{Type: String, Name: flagkey.PkgOutput, Short: "o", Usage: "Output filename to save archive content"}
|
||||
PkgStatusFlag = Flag{Type: String, Name: flagkey.PkgStatus, Usage: `Filter packages by status`}
|
||||
PkgOrphanFlag = Flag{Type: Bool, Name: flagkey.PkgOrphan, Usage: "Orphan packages that are not referenced by any function"}
|
||||
PkgDeployArchiveFlag = Flag{Type: StringSlice, Name: flagkey.PkgDeployArchive, Aliases: []string{"deploy"}, Usage: "Local path or URL for binary archive"}
|
||||
PkgSrcArchiveFlag = Flag{Type: StringSlice, Name: flagkey.PkgSrcArchive, Aliases: []string{"source", "src"}, Usage: "Local path or URL for source archive"}
|
||||
|
||||
SpecSaveFlag = Flag{Type: Bool, Name: flagkey.SpecSave, Usage: "Save to the spec directory instead of creating on cluster"}
|
||||
SpecDirFlag = Flag{Type: String, Name: flagkey.SpecDir, Usage: "Directory to store specs, defaults to ./specs"}
|
||||
SpecNameFlag = Flag{Type: String, Name: flagkey.SpecName, Usage: "Name for the app, applied to resources as a Kubernetes annotation"}
|
||||
SpecDeployIDFlag = Flag{Type: String, Name: flagkey.SpecDeployID, Aliases: []string{"id"}, Usage: "Deployment ID for the spec deployment config"}
|
||||
SpecWaitFlag = Flag{Type: Bool, Name: flagkey.SpecWait, Usage: "Wait for package builds"}
|
||||
SpecWatchFlag = Flag{Type: Bool, Name: flagkey.SpecWatch, Usage: "Watch local files for change, and re-apply specs as necessary"}
|
||||
SpecDeleteFlag = Flag{Type: Bool, Name: flagkey.SpecDelete, Usage: "Allow apply to delete resources that no longer exist in the specification"}
|
||||
|
||||
SupportOutputFlag = Flag{Type: String, Name: flagkey.SupportOutput, Short: "o", Usage: "Output directory to save dump archive/files", DefaultValue: flagkey.DefaultSpecOutputDir}
|
||||
SupportNoZipFlag = Flag{Type: Bool, Name: flagkey.SupportNoZip, Usage: "Save dump information into multiple files instead of single zip file"}
|
||||
|
||||
CanaryNameFlag = Flag{Type: String, Name: flagkey.CanaryName, Usage: "Name for the canary config"}
|
||||
CanaryTriggerNameFlag = Flag{Type: String, Name: flagkey.CanaryHTTPTriggerName, Usage: "Http trigger that this config references"}
|
||||
CanaryNewFuncFlag = Flag{Type: String, Name: flagkey.CanaryNewFunc, Aliases: []string{"newfn"}, Usage: "New version of the function"}
|
||||
CanaryOldFuncFlag = Flag{Type: String, Name: flagkey.CanaryOldFunc, Aliases: []string{"oldfn"}, Usage: "Old stable version of the function"}
|
||||
CanaryWeightIncrementFlag = Flag{Type: Int, Name: flagkey.CanaryWeightIncrement, Aliases: []string{"step"}, Usage: "Weight increment step for function", DefaultValue: 20}
|
||||
CanaryIncrementIntervalFlag = Flag{Type: String, Name: flagkey.CanaryIncrementInterval, Aliases: []string{"internal"}, Usage: "Weight increment interval, string representation of time.Duration, ex : 1m, 2h, 2d", DefaultValue: "2m"}
|
||||
CanaryFailureThresholdFlag = Flag{Type: Int, Name: flagkey.CanaryFailureThreshold, Aliases: []string{"threshold"}, Usage: "Threshold in percentage beyond which the new version of the function is considered unstable", DefaultValue: 10}
|
||||
)
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright 2019 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 flagkey
|
||||
|
||||
const (
|
||||
Verbosity = "verbosity"
|
||||
Server = "server"
|
||||
|
||||
resourceName = "name"
|
||||
force = "force"
|
||||
Output = "output"
|
||||
|
||||
NamespaceFunction = "fnNamespace"
|
||||
NamespaceEnvironment = "envNamespace"
|
||||
NamespacePackage = "pkgNamespace"
|
||||
NamespaceTrigger = "triggerNamespace"
|
||||
NamespaceRecorder = "recorderNamespace"
|
||||
NamespaceCanary = "canaryNamespace"
|
||||
|
||||
RuntimeMincpu = "mincpu"
|
||||
RuntimeMaxcpu = "maxcpu"
|
||||
RuntimeMinmemory = "minmemory"
|
||||
RuntimeMaxmemory = "maxmemory"
|
||||
RuntimeTargetcpu = "targetcpu"
|
||||
|
||||
ReplicasMinscale = "minscale"
|
||||
ReplicasMaxscale = "maxscale"
|
||||
|
||||
FnName = resourceName
|
||||
FnSpecializationTimeout = "specializationtimeout"
|
||||
FnEnvironmentName = "env"
|
||||
FnCode = "code"
|
||||
FnPackageName = "pkgname"
|
||||
FnEntrypoint = "entrypoint"
|
||||
FnBuildCmd = "buildcmd"
|
||||
FnSecret = "secret"
|
||||
FnForce = force
|
||||
FnCfgMap = "configmap"
|
||||
FnExecutorType = "executortype"
|
||||
FnExecutionTimeout = "fntimeout"
|
||||
FnTestTimeout = "timeout"
|
||||
FnLogPod = "pod"
|
||||
FnLogFollow = "follow"
|
||||
FnLogDetail = "detail"
|
||||
FnLogDBType = "dbtype"
|
||||
FnLogReverseQuery = "reverse"
|
||||
FnLogCount = "recordcount"
|
||||
FnTestBody = "body"
|
||||
FnTestHeader = "header"
|
||||
FnTestQuery = "query"
|
||||
|
||||
HtName = resourceName
|
||||
HtMethod = "method"
|
||||
HtUrl = "url"
|
||||
HtHost = "host"
|
||||
HtIngress = "createingress"
|
||||
HtIngressRule = "ingressrule"
|
||||
HtIngressAnnotation = "ingressannotation"
|
||||
HtIngressTLS = "ingresstls"
|
||||
HtFnName = "function"
|
||||
HtFnWeight = "weight"
|
||||
HtFilter = HtFnName
|
||||
|
||||
TtName = resourceName
|
||||
TtCron = "cron"
|
||||
TtFnName = "function"
|
||||
TtRound = "round"
|
||||
|
||||
MqtName = resourceName
|
||||
MqtFnName = "function"
|
||||
MqtMQType = "mqtype"
|
||||
MqtTopic = "topic"
|
||||
MqtRespTopic = "resptopic"
|
||||
MqtErrorTopic = "errortopic"
|
||||
MqtMaxRetries = "maxretries"
|
||||
MqtMsgContentType = "contenttype"
|
||||
|
||||
RecorderName = resourceName
|
||||
RecorderFn = "function"
|
||||
RecorderTriggers = "trigger"
|
||||
RecorderRetentionPolicy = "retention"
|
||||
RecorderEvictionPolcy = "eviction"
|
||||
RecorderEnabled = "enable"
|
||||
RecorderDisabled = "disable"
|
||||
RecordsFilterTimeFrom = "from"
|
||||
RecordsFilterTimeTo = "to"
|
||||
RecordsFilterFunction = "function"
|
||||
RecordsFilterTrigger = "trigger"
|
||||
RecordsVerbosity = "v"
|
||||
RecordsVv = "vv"
|
||||
RecordsReqID = "reqUID"
|
||||
|
||||
EnvName = resourceName
|
||||
EnvPoolsize = "poolsize"
|
||||
EnvImage = "image"
|
||||
EnvBuilderImage = "builder"
|
||||
EnvBuildcommand = "buildcmd"
|
||||
EnvKeeparchive = "keeparchive"
|
||||
EnvExternalNetwork = "externalnetwork"
|
||||
EnvGracePeriod = "graceperiod"
|
||||
EnvVersion = "version"
|
||||
|
||||
KwName = resourceName
|
||||
KwFnName = "function"
|
||||
KwNamespace = "ns"
|
||||
KwObjType = "type"
|
||||
KwLabels = "labels"
|
||||
|
||||
PkgName = resourceName
|
||||
PkgForce = force
|
||||
PkgEnvironment = "env"
|
||||
PkgSrcArchive = "sourcearchive"
|
||||
PkgDeployArchive = "deployarchive"
|
||||
PkgKeepURL = "keeparchiveurl"
|
||||
PkgBuildCmd = "buildcmd"
|
||||
PkgOutput = Output
|
||||
PkgStatus = "status"
|
||||
PkgOrphan = "orphan"
|
||||
|
||||
SpecSave = "spec"
|
||||
SpecDir = "specdir"
|
||||
SpecName = resourceName
|
||||
SpecDeployID = "deployid"
|
||||
SpecWait = "wait"
|
||||
SpecWatch = "watch"
|
||||
SpecDelete = "delete"
|
||||
|
||||
SupportOutput = Output
|
||||
SupportNoZip = "nozip"
|
||||
|
||||
CanaryName = resourceName
|
||||
CanaryHTTPTriggerName = "httptrigger"
|
||||
CanaryNewFunc = "newfunction"
|
||||
CanaryOldFunc = "oldfunction"
|
||||
CanaryWeightIncrement = "increment-step"
|
||||
CanaryIncrementInterval = "increment-interval"
|
||||
CanaryFailureThreshold = "failure-threshold"
|
||||
|
||||
DefaultSpecOutputDir = "fission-dump"
|
||||
)
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"k8s.io/client-go/tools/portforward"
|
||||
"k8s.io/client-go/transport/spdy"
|
||||
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ import (
|
||||
// its targetPort. Once the port forward is started, wait for it to
|
||||
// start accepting connections before returning.
|
||||
func SetupPortForward(namespace, labelSelector string) (string, error) {
|
||||
consolemsg.Verbose(2, "Setting up port forward to %s in namespace %s",
|
||||
console.Verbose(2, "Setting up port forward to %s in namespace %s",
|
||||
labelSelector, namespace)
|
||||
|
||||
localPort, err := findFreePort()
|
||||
@@ -49,7 +49,7 @@ func SetupPortForward(namespace, labelSelector string) (string, error) {
|
||||
return "", errors.Wrap(err, "error finding unused port")
|
||||
}
|
||||
|
||||
consolemsg.Verbose(2, "Waiting for local port %v", localPort)
|
||||
console.Verbose(2, "Waiting for local port %v", localPort)
|
||||
for {
|
||||
conn, _ := net.DialTimeout("tcp",
|
||||
net.JoinHostPort("", localPort), time.Millisecond)
|
||||
@@ -61,7 +61,7 @@ func SetupPortForward(namespace, labelSelector string) (string, error) {
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
}
|
||||
|
||||
consolemsg.Verbose(2, "Starting port forward from local port %v", localPort)
|
||||
console.Verbose(2, "Starting port forward from local port %v", localPort)
|
||||
go func() {
|
||||
err := runPortForward(labelSelector, localPort, namespace)
|
||||
if err != nil {
|
||||
@@ -70,7 +70,7 @@ func SetupPortForward(namespace, labelSelector string) (string, error) {
|
||||
}
|
||||
}()
|
||||
|
||||
consolemsg.Verbose(2, "Waiting for port forward %v to start...", localPort)
|
||||
console.Verbose(2, "Waiting for port forward %v to start...", localPort)
|
||||
for {
|
||||
conn, _ := net.DialTimeout("tcp",
|
||||
net.JoinHostPort("", localPort), time.Millisecond)
|
||||
@@ -81,7 +81,7 @@ func SetupPortForward(namespace, labelSelector string) (string, error) {
|
||||
time.Sleep(time.Millisecond * 50)
|
||||
}
|
||||
|
||||
consolemsg.Verbose(2, "Port forward from local port %v started", localPort)
|
||||
console.Verbose(2, "Port forward from local port %v started", localPort)
|
||||
|
||||
return localPort, nil
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func runPortForward(labelSelector string, localPort string, ns string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
consolemsg.Verbose(2, "Connected to Kubernetes API")
|
||||
console.Verbose(2, "Connected to Kubernetes API")
|
||||
|
||||
// if namespace is unset, try to find a pod in any namespace
|
||||
if len(ns) == 0 {
|
||||
@@ -177,7 +177,7 @@ func runPortForward(labelSelector string, localPort string, ns string) error {
|
||||
for _, servicePort := range service.Spec.Ports {
|
||||
targetPort = servicePort.TargetPort.String()
|
||||
}
|
||||
consolemsg.Verbose(2, "Connecting to port %v on pod %v/%v", targetPort, podNameSpace, podNameSpace)
|
||||
console.Verbose(2, "Connecting to port %v on pod %v/%v", targetPort, podNameSpace, podNameSpace)
|
||||
|
||||
stopChannel := make(chan struct{}, 1)
|
||||
readyChannel := make(chan struct{})
|
||||
@@ -199,7 +199,7 @@ func runPortForward(labelSelector string, localPort string, ns string) error {
|
||||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", url)
|
||||
|
||||
outStream := os.Stdout
|
||||
if consolemsg.Verbosity < 2 {
|
||||
if console.Verbosity < 2 {
|
||||
outStream = nil
|
||||
}
|
||||
fw, err := portforward.New(dialer, ports, stopChannel, readyChannel, outStream, os.Stderr)
|
||||
@@ -207,6 +207,6 @@ func runPortForward(labelSelector string, localPort string, ns string) error {
|
||||
return errors.Wrap(err, "error creating port forwarder")
|
||||
}
|
||||
|
||||
consolemsg.Verbose(2, "Starting port forwarder")
|
||||
console.Verbose(2, "Starting port forwarder")
|
||||
return fw.ForwardPorts()
|
||||
}
|
||||
|
||||
@@ -36,10 +36,11 @@ import (
|
||||
|
||||
"github.com/fission/fission/pkg/controller/client"
|
||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||
"github.com/fission/fission/pkg/fission-cli/consolemsg"
|
||||
"github.com/fission/fission/pkg/fission-cli/flag"
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
flagkey "github.com/fission/fission/pkg/fission-cli/flag/key"
|
||||
"github.com/fission/fission/pkg/info"
|
||||
"github.com/fission/fission/pkg/plugin"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
)
|
||||
|
||||
func GetFissionNamespace() string {
|
||||
@@ -111,7 +112,7 @@ func GetKubernetesClient() (*restclient.Config, *kubernetes.Clientset, error) {
|
||||
// In case that user.Current() may be unable to work under some circumstances and return errors like
|
||||
// "user: Current not implemented on darwin/amd64" due to cross-compilation problem. (https://github.com/golang/go/issues/6376).
|
||||
// Instead of doing fatal here, we fallback to get home directory from the environment $HOME.
|
||||
consolemsg.Warn(fmt.Sprintf("Could not get the current user's directory (%s), fallback to get it from env $HOME", err))
|
||||
console.Warn(fmt.Sprintf("Could not get the current user's directory (%s), fallback to get it from env $HOME", err))
|
||||
homeDir = os.Getenv("HOME")
|
||||
} else {
|
||||
homeDir = usr.HomeDir
|
||||
@@ -123,9 +124,9 @@ func GetKubernetesClient() (*restclient.Config, *kubernetes.Clientset, error) {
|
||||
"Set the KUBECONFIG environment variable to your kubeconfig's path.")
|
||||
}
|
||||
loadingRules.ExplicitPath = kubeConfigPath
|
||||
consolemsg.Verbose(2, "Using kubeconfig from %q", kubeConfigPath)
|
||||
console.Verbose(2, "Using kubeconfig from %q", kubeConfigPath)
|
||||
} else {
|
||||
consolemsg.Verbose(2, "Using kubeconfig from environment %q", kubeConfigPath)
|
||||
console.Verbose(2, "Using kubeconfig from environment %q", kubeConfigPath)
|
||||
}
|
||||
|
||||
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
@@ -180,7 +181,7 @@ func GetVersion(client *client.Client) info.Versions {
|
||||
|
||||
serverInfo, err := client.ServerInfo()
|
||||
if err != nil {
|
||||
consolemsg.Warn(fmt.Sprintf("Error getting Fission API version: %v", err))
|
||||
console.Warn(fmt.Sprintf("Error getting Fission API version: %v", err))
|
||||
serverInfo = &info.ServerInfo{}
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ func GetVersion(client *client.Client) info.Versions {
|
||||
}
|
||||
|
||||
func GetServer(flags cli.Input) (c *client.Client, err error) {
|
||||
serverUrl := flags.GlobalString(flag.FISSION_SERVER)
|
||||
serverUrl := flags.GlobalString(flagkey.Server)
|
||||
if len(serverUrl) == 0 {
|
||||
// starts local portforwarder etc.
|
||||
serverUrl, err = GetApplicationUrl("application=fission-api")
|
||||
@@ -230,10 +231,10 @@ func GetResourceReqs(flags cli.Input, resReqs *v1.ResourceRequirements) (*v1.Res
|
||||
r.Limits = make(map[v1.ResourceName]resource.Quantity)
|
||||
}
|
||||
|
||||
e := &multierror.Error{}
|
||||
e := utils.MultiErrorWithFormat()
|
||||
|
||||
if flags.IsSet(flag.RUNTIME_MINCPU) {
|
||||
mincpu := flags.Int(flag.RUNTIME_MINCPU)
|
||||
if flags.IsSet(flagkey.RuntimeMincpu) {
|
||||
mincpu := flags.Int(flagkey.RuntimeMincpu)
|
||||
cpuRequest, err := resource.ParseQuantity(strconv.Itoa(mincpu) + "m")
|
||||
if err != nil {
|
||||
e = multierror.Append(e, errors.Wrap(err, "Failed to parse mincpu"))
|
||||
@@ -241,8 +242,8 @@ func GetResourceReqs(flags cli.Input, resReqs *v1.ResourceRequirements) (*v1.Res
|
||||
r.Requests[v1.ResourceCPU] = cpuRequest
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.RUNTIME_MINMEMORY) {
|
||||
minmem := flags.Int(flag.RUNTIME_MINMEMORY)
|
||||
if flags.IsSet(flagkey.RuntimeMinmemory) {
|
||||
minmem := flags.Int(flagkey.RuntimeMinmemory)
|
||||
memRequest, err := resource.ParseQuantity(strconv.Itoa(minmem) + "Mi")
|
||||
if err != nil {
|
||||
e = multierror.Append(e, errors.Wrap(err, "Failed to parse minmemory"))
|
||||
@@ -250,8 +251,8 @@ func GetResourceReqs(flags cli.Input, resReqs *v1.ResourceRequirements) (*v1.Res
|
||||
r.Requests[v1.ResourceMemory] = memRequest
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.RUNTIME_MAXCPU) {
|
||||
maxcpu := flags.Int(flag.RUNTIME_MAXCPU)
|
||||
if flags.IsSet(flagkey.RuntimeMaxcpu) {
|
||||
maxcpu := flags.Int(flagkey.RuntimeMaxcpu)
|
||||
cpuLimit, err := resource.ParseQuantity(strconv.Itoa(maxcpu) + "m")
|
||||
if err != nil {
|
||||
e = multierror.Append(e, errors.Wrap(err, "Failed to parse maxcpu"))
|
||||
@@ -259,8 +260,8 @@ func GetResourceReqs(flags cli.Input, resReqs *v1.ResourceRequirements) (*v1.Res
|
||||
r.Limits[v1.ResourceCPU] = cpuLimit
|
||||
}
|
||||
|
||||
if flags.IsSet(flag.RUNTIME_MAXMEMORY) {
|
||||
maxmem := flags.Int(flag.RUNTIME_MAXMEMORY)
|
||||
if flags.IsSet(flagkey.RuntimeMaxmemory) {
|
||||
maxmem := flags.Int(flagkey.RuntimeMaxmemory)
|
||||
memLimit, err := resource.ParseQuantity(strconv.Itoa(maxmem) + "Mi")
|
||||
if err != nil {
|
||||
e = multierror.Append(e, errors.Wrap(err, "Failed to parse maxmemory"))
|
||||
@@ -297,7 +298,7 @@ func GetResourceReqs(flags cli.Input, resReqs *v1.ResourceRequirements) (*v1.Res
|
||||
}
|
||||
|
||||
func GetSpecDir(flags cli.Input) string {
|
||||
specDir := flags.String(flag.SPEC_SPECDIR)
|
||||
specDir := flags.String(flagkey.SpecDir)
|
||||
if len(specDir) == 0 {
|
||||
specDir = "specs"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2019 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 utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
func MultiErrorWithFormat() *multierror.Error {
|
||||
return &multierror.Error{
|
||||
ErrorFormat: DefaultErrorFormat,
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultErrorFormat(es []error) string {
|
||||
points := make([]string, len(es))
|
||||
for i, err := range es {
|
||||
points[i] = fmt.Sprintf("* %s", err)
|
||||
}
|
||||
return fmt.Sprintf(
|
||||
"%d errors occurred:\n\t%s\n",
|
||||
len(es), strings.Join(points, "\n\t"))
|
||||
}
|
||||
@@ -98,25 +98,3 @@ type (
|
||||
|
||||
errorCode int
|
||||
)
|
||||
|
||||
//const (
|
||||
// ErrorInternal = iota
|
||||
//
|
||||
// ErrorNotAuthorized
|
||||
// ErrorNotFound
|
||||
// ErrorNameExists
|
||||
// ErrorInvalidArgument
|
||||
// ErrorNoSpace
|
||||
// ErrorNotImplmented
|
||||
//)
|
||||
//
|
||||
//// must match order and len of the above const
|
||||
//var errorDescriptions = []string{
|
||||
// "Internal error",
|
||||
// "Not authorized",
|
||||
// "Resource not found",
|
||||
// "Resource exists",
|
||||
// "Invalid argument",
|
||||
// "No space",
|
||||
// "Not implemented",
|
||||
//}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
#test:disabled
|
||||
|
||||
#
|
||||
# Simple end-to-end test of record with POST
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
#test:disabled
|
||||
|
||||
#
|
||||
# Simple end-to-end test of record with GET
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
#test:disabled
|
||||
|
||||
#
|
||||
# Simple test of recorder updates
|
||||
|
||||
Reference in New Issue
Block a user