This repository has been archived by the owner on Feb 5, 2021. It is now read-only.
/
route_traffic.go
140 lines (131 loc) · 5.13 KB
/
route_traffic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package main
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/spf13/cobra"
"cellery.io/cellery/components/cli/cli"
"cellery.io/cellery/components/cli/pkg/commands/instance"
"cellery.io/cellery/components/cli/pkg/constants"
"cellery.io/cellery/components/cli/pkg/util"
)
func newRouteTrafficCommand(cli cli.Cli) *cobra.Command {
var sourceInstance string
var dependencyInstance string
var targetPercentage string
var targetInstance string
var percentage int
var srcInstances []string
var enableSessionAwareness bool
var assumeYes bool
cmd := &cobra.Command{
Use: "route-traffic [--source|-s=<list_of_source_cell_instances>] --dependency|-d <dependency_instance_name> --target|-t <target instance name> [--percentage|-p <x>]",
Short: "route a percentage of the traffic to a cell instance",
Example: "cellery route-traffic --source hr-client-inst1 --dependency hr-inst-1 --target hr-inst-2 --percentage 20 \n" +
"cellery route-traffic --dependency hr-inst-1 --target hr-inst-2 --percentage 20 \n" +
"cellery route-traffic --dependency hr-inst-1 --target hr-inst-2 \n" +
"cellery route-traffic --dependency hr-inst-1 --target hr-inst-2 --percentage 25 --enable-session-awareness",
Args: func(cmd *cobra.Command, args []string) error {
// validate
err := validateArguments(dependencyInstance, targetInstance)
if err != nil {
return err
}
// get source cell instances as an array
srcInstances = getSourceCellInstanceArr(sourceInstance)
// validate source cell instance name(s)
for _, srcInstance := range srcInstances {
err := validateInstanceName(srcInstance)
if err != nil {
util.ExitWithErrorMessage("Error in running route traffic command", err)
}
}
// validate target instance name
err = validateInstanceName(targetInstance)
if err != nil {
util.ExitWithErrorMessage("Error in running route traffic command", err)
}
// calculate target percentage value
percentage, err = getTargetInstancePercentage(targetPercentage)
if err != nil {
util.ExitWithErrorMessage("Error in running route traffic command", err)
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
err := instance.RunRouteTrafficCommand(cli, srcInstances, dependencyInstance, targetInstance, percentage, enableSessionAwareness, assumeYes)
if err != nil {
util.ExitWithErrorMessage(fmt.Sprintf("Unable to route traffic to the target instance: %s, percentage: %d", targetInstance, percentage), err)
}
},
}
cmd.Flags().StringVarP(&sourceInstance, "source", "s", "", "comma separated source instance list")
cmd.Flags().StringVarP(&dependencyInstance, "dependency", "d", "", "existing dependency instance name")
cmd.Flags().StringVarP(&targetInstance, "target", "t", "", "target instance to which the traffic should be re-routed")
cmd.Flags().StringVarP(&targetPercentage, "percentage", "p", "", "percentage to be switched to the target instance")
cmd.Flags().BoolVarP(&enableSessionAwareness, "enable-session-awareness", "a", false, "flag to enable session awareness based on user name")
cmd.Flags().BoolVarP(&assumeYes, "assume-yes", "y", false, "flag to assume yes for user confirmations")
return cmd
}
func getSourceCellInstanceArr(sourceCellInstances string) []string {
var trimmedInstances []string
if len(sourceCellInstances) == 0 {
return trimmedInstances
}
instances := strings.Split(sourceCellInstances, ",")
for _, instance := range instances {
trimmedInstances = append(trimmedInstances, strings.TrimSpace(instance))
}
return trimmedInstances
}
func getTargetInstancePercentage(percentage string) (int, error) {
// if the percentage is not given, assume its 100 (full traffic switch - canary)
if percentage == "" {
return 100, nil
}
intPercentage, err := strconv.Atoi(percentage)
if err != nil {
return -1, err
}
if intPercentage > 100 {
return -1, fmt.Errorf("invalid target percentage value %d", intPercentage)
}
return intPercentage, nil
}
func validateInstanceName(instanceName string) error {
isCellInstValid, err := regexp.MatchString(fmt.Sprintf("^%s$", constants.CelleryIdPattern), instanceName)
if err != nil {
return err
}
if !isCellInstValid {
return fmt.Errorf("expects a valid cell instance name, received '%s'", instanceName)
}
return nil
}
func validateArguments(dependency string, target string) error {
if dependency == "" {
return fmt.Errorf("mandatory flag dependency/d not provided")
}
if target == "" {
return fmt.Errorf("mandatory flag target/t not provided")
}
return nil
}