Refactor canary config command (#1370)
This commit is contained in:
@@ -1,235 +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 (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"text/tabwriter"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
|
|
||||||
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
|
|
||||||
"github.com/fission/fission/pkg/fission-cli/log"
|
|
||||||
"github.com/fission/fission/pkg/fission-cli/util"
|
|
||||||
"github.com/fission/fission/pkg/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func canaryConfigCreate(c *cli.Context) error {
|
|
||||||
client := util.GetApiClient(c.GlobalString("server"))
|
|
||||||
|
|
||||||
canaryConfigName := c.String("name")
|
|
||||||
// canary configs can be created for functions in the same namespace
|
|
||||||
if len(canaryConfigName) == 0 {
|
|
||||||
log.Fatal("Need a name, use --name.")
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger := c.String("httptrigger")
|
|
||||||
newFunc := c.String("newfunction")
|
|
||||||
oldFunc := c.String("oldfunction")
|
|
||||||
ns := c.String("fnNamespace")
|
|
||||||
incrementStep := c.Int("increment-step")
|
|
||||||
failureThreshold := c.Int("failure-threshold")
|
|
||||||
incrementInterval := c.String("increment-interval")
|
|
||||||
|
|
||||||
// check for time parsing
|
|
||||||
_, err := time.ParseDuration(incrementInterval)
|
|
||||||
util.CheckErr(err, "parsing time duration.")
|
|
||||||
|
|
||||||
// check that the trigger exists in the same namespace.
|
|
||||||
m := &metav1.ObjectMeta{
|
|
||||||
Name: trigger,
|
|
||||||
Namespace: ns,
|
|
||||||
}
|
|
||||||
|
|
||||||
htTrigger, err := client.HTTPTriggerGet(m)
|
|
||||||
if err != nil {
|
|
||||||
util.CheckErr(err, "find trigger referenced in the canary config")
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the trigger has function reference type function weights
|
|
||||||
if htTrigger.Spec.FunctionReference.Type != types.FunctionReferenceTypeFunctionWeights {
|
|
||||||
log.Fatal("Canary config cannot be created for http triggers that do not reference functions by weights")
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the trigger references same functions in the function weights
|
|
||||||
_, ok := htTrigger.Spec.FunctionReference.FunctionWeights[newFunc]
|
|
||||||
if !ok {
|
|
||||||
log.Fatal(fmt.Sprintf("HTTP Trigger doesn't reference the function %s in Canary Config", newFunc))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, ok = htTrigger.Spec.FunctionReference.FunctionWeights[oldFunc]
|
|
||||||
if !ok {
|
|
||||||
log.Fatal(fmt.Sprintf("HTTP Trigger doesn't reference the function %s in Canary Config", oldFunc))
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the functions exist in the same namespace
|
|
||||||
fnList := []string{newFunc, oldFunc}
|
|
||||||
err = util.CheckFunctionExistence(client, fnList, ns)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(fmt.Sprintf("checkFunctionExistence err : %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally create canaryCfg in the same namespace as the functions referenced
|
|
||||||
canaryCfg := &fv1.CanaryConfig{
|
|
||||||
Metadata: metav1.ObjectMeta{
|
|
||||||
Name: canaryConfigName,
|
|
||||||
Namespace: ns,
|
|
||||||
},
|
|
||||||
Spec: fv1.CanaryConfigSpec{
|
|
||||||
Trigger: trigger,
|
|
||||||
NewFunction: newFunc,
|
|
||||||
OldFunction: oldFunc,
|
|
||||||
WeightIncrement: incrementStep,
|
|
||||||
WeightIncrementDuration: incrementInterval,
|
|
||||||
FailureThreshold: failureThreshold,
|
|
||||||
FailureType: fv1.FailureTypeStatusCode,
|
|
||||||
},
|
|
||||||
Status: fv1.CanaryConfigStatus{
|
|
||||||
Status: fv1.CanaryConfigStatusPending,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = client.CanaryConfigCreate(canaryCfg)
|
|
||||||
util.CheckErr(err, "create canary config")
|
|
||||||
|
|
||||||
fmt.Printf("canary config '%v' created\n", canaryConfigName)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func canaryConfigGet(c *cli.Context) error {
|
|
||||||
client := util.GetApiClient(c.GlobalString("server"))
|
|
||||||
|
|
||||||
name := c.String("name")
|
|
||||||
if len(name) == 0 {
|
|
||||||
log.Fatal("Need a name, use --name.")
|
|
||||||
}
|
|
||||||
ns := c.String("canaryNamespace")
|
|
||||||
|
|
||||||
m := &metav1.ObjectMeta{
|
|
||||||
Name: name,
|
|
||||||
Namespace: ns,
|
|
||||||
}
|
|
||||||
|
|
||||||
canaryCfg, err := client.CanaryConfigGet(m)
|
|
||||||
util.CheckErr(err, "get canary config")
|
|
||||||
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
|
||||||
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "TRIGGER", "FUNCTION-N", "FUNCTION-N-1", "WEIGHT-INCREMENT", "INTERVAL", "FAILURE-THRESHOLD", "FAILURE-TYPE", "STATUS")
|
|
||||||
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
|
|
||||||
canaryCfg.Metadata.Name, canaryCfg.Spec.Trigger, canaryCfg.Spec.NewFunction, canaryCfg.Spec.OldFunction, canaryCfg.Spec.WeightIncrement, canaryCfg.Spec.WeightIncrementDuration,
|
|
||||||
canaryCfg.Spec.FailureThreshold, canaryCfg.Spec.FailureType, canaryCfg.Status.Status)
|
|
||||||
|
|
||||||
w.Flush()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func canaryConfigUpdate(c *cli.Context) error {
|
|
||||||
client := util.GetApiClient(c.GlobalString("server"))
|
|
||||||
|
|
||||||
canaryConfigName := c.String("name")
|
|
||||||
ns := c.String("canaryNamespace")
|
|
||||||
if len(canaryConfigName) == 0 {
|
|
||||||
log.Fatal("Need a name, use --name.")
|
|
||||||
}
|
|
||||||
|
|
||||||
incrementStep := c.Int("increment-step")
|
|
||||||
failureThreshold := c.Int("failure-threshold")
|
|
||||||
incrementInterval := c.String("increment-interval")
|
|
||||||
|
|
||||||
// check for time parsing
|
|
||||||
_, err := time.ParseDuration(incrementInterval)
|
|
||||||
util.CheckErr(err, "parsing time duration.")
|
|
||||||
|
|
||||||
// get the current config
|
|
||||||
m := &metav1.ObjectMeta{
|
|
||||||
Name: canaryConfigName,
|
|
||||||
Namespace: ns,
|
|
||||||
}
|
|
||||||
|
|
||||||
var updateNeeded bool
|
|
||||||
canaryCfg, err := client.CanaryConfigGet(m)
|
|
||||||
util.CheckErr(err, "get canary config")
|
|
||||||
|
|
||||||
if incrementStep != canaryCfg.Spec.WeightIncrement {
|
|
||||||
canaryCfg.Spec.WeightIncrement = incrementStep
|
|
||||||
updateNeeded = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if failureThreshold != canaryCfg.Spec.FailureThreshold {
|
|
||||||
canaryCfg.Spec.FailureThreshold = failureThreshold
|
|
||||||
updateNeeded = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if incrementInterval != canaryCfg.Spec.WeightIncrementDuration {
|
|
||||||
canaryCfg.Spec.WeightIncrementDuration = incrementInterval
|
|
||||||
updateNeeded = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if updateNeeded {
|
|
||||||
canaryCfg.Status.Status = fv1.CanaryConfigStatusPending
|
|
||||||
|
|
||||||
_, err = client.CanaryConfigUpdate(canaryCfg)
|
|
||||||
util.CheckErr(err, "update canary config")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func canaryConfigDelete(c *cli.Context) error {
|
|
||||||
client := util.GetApiClient(c.GlobalString("server"))
|
|
||||||
|
|
||||||
canaryConfigName := c.String("name")
|
|
||||||
ns := c.String("canaryNamespace")
|
|
||||||
if len(canaryConfigName) == 0 {
|
|
||||||
log.Fatal("Need a name, use --name.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the current config
|
|
||||||
m := &metav1.ObjectMeta{
|
|
||||||
Name: canaryConfigName,
|
|
||||||
Namespace: ns,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.CanaryConfigDelete(m)
|
|
||||||
util.CheckErr(err, fmt.Sprintf("delete function '%v.%v'", canaryConfigName, ns))
|
|
||||||
|
|
||||||
fmt.Printf("canaryconfig '%v.%v' deleted\n", canaryConfigName, ns)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func canaryConfigList(c *cli.Context) error {
|
|
||||||
client := util.GetApiClient(c.GlobalString("server"))
|
|
||||||
|
|
||||||
ns := c.String("canaryNamespace")
|
|
||||||
|
|
||||||
canaryCfgs, err := client.CanaryConfigList(ns)
|
|
||||||
util.CheckErr(err, "list canary config")
|
|
||||||
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
|
||||||
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "TRIGGER", "FUNCTION-N", "FUNCTION-N-1", "WEIGHT-INCREMENT", "INTERVAL", "FAILURE-THRESHOLD", "FAILURE-TYPE", "STATUS")
|
|
||||||
for _, canaryCfg := range canaryCfgs {
|
|
||||||
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
|
|
||||||
canaryCfg.Metadata.Name, canaryCfg.Spec.Trigger, canaryCfg.Spec.NewFunction, canaryCfg.Spec.OldFunction, canaryCfg.Spec.WeightIncrement, canaryCfg.Spec.WeightIncrementDuration,
|
|
||||||
canaryCfg.Spec.FailureThreshold, canaryCfg.Spec.FailureType, canaryCfg.Status.Status)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Flush()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
|
|
||||||
"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/urfavecli"
|
"github.com/fission/fission/pkg/fission-cli/cliwrapper/driver/urfavecli"
|
||||||
"github.com/fission/fission/pkg/fission-cli/cmd"
|
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||||
|
"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/environment"
|
||||||
"github.com/fission/fission/pkg/fission-cli/cmd/httptrigger"
|
"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/kubewatch"
|
||||||
@@ -306,11 +307,11 @@ func NewCliApp() *cli.App {
|
|||||||
incrementIntervalFlag := cli.StringFlag{Name: "increment-interval", Value: "2m", Usage: "Weight increment interval, string representation of time.Duration, ex : 1m, 2h, 2d"}
|
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"}
|
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{
|
canarySubCommands := []cli.Command{
|
||||||
{Name: "create", Usage: "Create a canary config", Flags: []cli.Flag{canaryConfigNameFlag, triggerNameFlag, newFunc, oldFunc, fnNamespaceFlag, weightIncrementFlag, incrementIntervalFlag, failureThresholdFlag}, Action: canaryConfigCreate},
|
{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: canaryConfigGet},
|
{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: canaryConfigUpdate},
|
{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: canaryConfigDelete},
|
{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: canaryConfigList},
|
{Name: "list", Usage: "List all canary configs in a namespace", Flags: []cli.Flag{canaryNamespaceFlag}, Action: urfavecli.Wrapper(canaryconfig.List)},
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginSubCommands := []cli.Command{
|
pluginSubCommands := []cli.Command{
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
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/cmd"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/util"
|
||||||
|
"github.com/fission/fission/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateSubCommand struct {
|
||||||
|
client *client.Client
|
||||||
|
canary *fv1.CanaryConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func Create(flags cli.Input) error {
|
||||||
|
opts := CreateSubCommand{
|
||||||
|
client: cmd.GetServer(flags),
|
||||||
|
}
|
||||||
|
return opts.do(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *CreateSubCommand) do(flags cli.Input) error {
|
||||||
|
err := opts.complete(flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return opts.run(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
// check for time parsing
|
||||||
|
_, err := time.ParseDuration(incrementInterval)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error parsing time duration")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the trigger exists in the same namespace.
|
||||||
|
m, err := cmd.GetMetadata("httptrigger", "fnNamespace", flags)
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the trigger has function reference type function weights
|
||||||
|
if htTrigger.Spec.FunctionReference.Type != types.FunctionReferenceTypeFunctionWeights {
|
||||||
|
return errors.New("canary config cannot be created for http triggers that do not reference functions by weights")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the trigger references same functions in the function weights
|
||||||
|
_, ok := htTrigger.Spec.FunctionReference.FunctionWeights[newFunc]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("HTTP Trigger doesn't reference the function %s in Canary Config", newFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, ok = htTrigger.Spec.FunctionReference.FunctionWeights[oldFunc]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("HTTP Trigger doesn't reference the function %s in Canary Config", oldFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the functions exist in the same namespace
|
||||||
|
fnList := []string{newFunc, oldFunc}
|
||||||
|
err = util.CheckFunctionExistence(opts.client, fnList, ns)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error checking functions existence")
|
||||||
|
}
|
||||||
|
|
||||||
|
canaryMetadata, err := cmd.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,
|
||||||
|
Spec: fv1.CanaryConfigSpec{
|
||||||
|
Trigger: trigger,
|
||||||
|
NewFunction: newFunc,
|
||||||
|
OldFunction: oldFunc,
|
||||||
|
WeightIncrement: incrementStep,
|
||||||
|
WeightIncrementDuration: incrementInterval,
|
||||||
|
FailureThreshold: failureThreshold,
|
||||||
|
FailureType: fv1.FailureTypeStatusCode,
|
||||||
|
},
|
||||||
|
Status: fv1.CanaryConfigStatus{
|
||||||
|
Status: fv1.CanaryConfigStatusPending,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *CreateSubCommand) run(flags cli.Input) error {
|
||||||
|
_, err := opts.client.CanaryConfigCreate(opts.canary)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error creating canary config")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("canary config '%v' created\n", opts.canary.Metadata.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/fission/fission/pkg/controller/client"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteSubCommand struct {
|
||||||
|
client *client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func Delete(flags cli.Input) error {
|
||||||
|
opts := DeleteSubCommand{
|
||||||
|
client: cmd.GetServer(flags),
|
||||||
|
}
|
||||||
|
return opts.run(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *DeleteSubCommand) run(flags cli.Input) error {
|
||||||
|
metadata, err := cmd.GetMetadata("name", "canaryNamespace", flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = opts.client.CanaryConfigDelete(metadata)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error deleting canary config")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("canaryconfig '%v.%v' deleted\n", metadata.Name, metadata.Namespace)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/fission/fission/pkg/controller/client"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetSubCommand struct {
|
||||||
|
client *client.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get(flags cli.Input) error {
|
||||||
|
opts := GetSubCommand{
|
||||||
|
client: cmd.GetServer(flags),
|
||||||
|
}
|
||||||
|
return opts.run(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *GetSubCommand) run(flags cli.Input) error {
|
||||||
|
m, err := cmd.GetMetadata("name", "canaryNamespace", flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
canaryCfg, err := opts.client.CanaryConfigGet(m)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error getting canary config")
|
||||||
|
}
|
||||||
|
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||||
|
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "TRIGGER", "FUNCTION-N", "FUNCTION-N-1", "WEIGHT-INCREMENT", "INTERVAL", "FAILURE-THRESHOLD", "FAILURE-TYPE", "STATUS")
|
||||||
|
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
|
||||||
|
canaryCfg.Metadata.Name, canaryCfg.Spec.Trigger, canaryCfg.Spec.NewFunction, canaryCfg.Spec.OldFunction, canaryCfg.Spec.WeightIncrement, canaryCfg.Spec.WeightIncrementDuration,
|
||||||
|
canaryCfg.Spec.FailureThreshold, canaryCfg.Spec.FailureType, canaryCfg.Status.Status)
|
||||||
|
|
||||||
|
w.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -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 canaryconfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/fission/fission/pkg/controller/client"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cliwrapper/cli"
|
||||||
|
"github.com/fission/fission/pkg/fission-cli/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListSubCommand struct {
|
||||||
|
client *client.Client
|
||||||
|
namespace string
|
||||||
|
}
|
||||||
|
|
||||||
|
func List(flags cli.Input) error {
|
||||||
|
opts := ListSubCommand{
|
||||||
|
client: cmd.GetServer(flags),
|
||||||
|
}
|
||||||
|
return opts.do(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *ListSubCommand) do(flags cli.Input) error {
|
||||||
|
err := opts.complete(flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return opts.run(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *ListSubCommand) complete(flags cli.Input) error {
|
||||||
|
opts.namespace = flags.String("canaryNamespace")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *ListSubCommand) run(flags cli.Input) error {
|
||||||
|
canaryCfgs, err := opts.client.CanaryConfigList(opts.namespace)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error listing canary config")
|
||||||
|
}
|
||||||
|
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||||
|
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n", "NAME", "TRIGGER", "FUNCTION-N", "FUNCTION-N-1", "WEIGHT-INCREMENT", "INTERVAL", "FAILURE-THRESHOLD", "FAILURE-TYPE", "STATUS")
|
||||||
|
for _, canaryCfg := range canaryCfgs {
|
||||||
|
fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
|
||||||
|
canaryCfg.Metadata.Name, canaryCfg.Spec.Trigger, canaryCfg.Spec.NewFunction, canaryCfg.Spec.OldFunction, canaryCfg.Spec.WeightIncrement, canaryCfg.Spec.WeightIncrementDuration,
|
||||||
|
canaryCfg.Spec.FailureThreshold, canaryCfg.Spec.FailureType, canaryCfg.Status.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
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 (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
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/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateSubCommand struct {
|
||||||
|
client *client.Client
|
||||||
|
canary *fv1.CanaryConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update(flags cli.Input) error {
|
||||||
|
opts := UpdateSubCommand{
|
||||||
|
client: cmd.GetServer(flags),
|
||||||
|
}
|
||||||
|
return opts.do(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *UpdateSubCommand) do(flags cli.Input) error {
|
||||||
|
err := opts.complete(flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return opts.run(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *UpdateSubCommand) complete(flags cli.Input) error {
|
||||||
|
// get the current config
|
||||||
|
m, err := cmd.GetMetadata("name", "canaryNamespace", flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementStep := flags.Int("increment-step")
|
||||||
|
failureThreshold := flags.Int("failure-threshold")
|
||||||
|
incrementInterval := flags.String("increment-interval")
|
||||||
|
|
||||||
|
// check for time parsing
|
||||||
|
_, err = time.ParseDuration(incrementInterval)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error parsing time duration")
|
||||||
|
}
|
||||||
|
|
||||||
|
canaryCfg, err := opts.client.CanaryConfigGet(m)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error getting canary config")
|
||||||
|
}
|
||||||
|
|
||||||
|
var updateNeeded bool
|
||||||
|
|
||||||
|
if incrementStep != canaryCfg.Spec.WeightIncrement {
|
||||||
|
canaryCfg.Spec.WeightIncrement = incrementStep
|
||||||
|
}
|
||||||
|
|
||||||
|
if failureThreshold != canaryCfg.Spec.FailureThreshold {
|
||||||
|
canaryCfg.Spec.FailureThreshold = failureThreshold
|
||||||
|
}
|
||||||
|
|
||||||
|
if incrementInterval != canaryCfg.Spec.WeightIncrementDuration {
|
||||||
|
canaryCfg.Spec.WeightIncrementDuration = incrementInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
if updateNeeded {
|
||||||
|
canaryCfg.Status.Status = fv1.CanaryConfigStatusPending
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.canary = canaryCfg
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (opts *UpdateSubCommand) run(flags cli.Input) error {
|
||||||
|
_, err := opts.client.CanaryConfigUpdate(opts.canary)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "error updating canary config")
|
||||||
|
}
|
||||||
|
fmt.Printf("canary config '%v' updated\n", opts.canary.Metadata.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user