Migrate from urfave/cli to cobra (#1385)

This commit is contained in:
Ta-Ching Chen
2019-11-08 21:22:00 +08:00
committed by GitHub
parent 4b456db517
commit 1888cd2ac7
66 changed files with 2901 additions and 1130 deletions
+135
View File
@@ -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
}
+58 -66
View File
@@ -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
}
+10 -8
View File
@@ -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))
}
+30 -29
View File
@@ -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,
+9 -10
View File
@@ -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")
}
+10 -10
View File
@@ -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")
}
+6 -5
View File
@@ -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 {
+16 -20
View File
@@ -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
}
+17 -16
View File
@@ -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")
}
+35 -45
View File
@@ -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")