cleanup
This commit is contained in:
parent
f87c7cd9fa
commit
a625328cc7
181
cmd/util/util.go
181
cmd/util/util.go
@ -21,22 +21,6 @@ THE SOFTWARE.
|
||||
*/
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
k3d "github.com/rancher/k3d/pkg/types"
|
||||
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// possible matches
|
||||
// -
|
||||
var filterRegexp = regexp.MustCompile(`^(?P<group>master|worker|all)(?P<subsetSpec>\[(?P<subset>(?P<subsetList>(\d+,?)+)|(?P<subsetRange>\d*:\d*)|(?P<subsetWildcard>\*))\])?$`)
|
||||
|
||||
// mapSubexpNames maps regex capturing group names to corresponding matches
|
||||
func mapSubexpNames(names, matches []string) map[string]string {
|
||||
//names, matches = names[1:], matches[1:]
|
||||
@ -46,168 +30,3 @@ func mapSubexpNames(names, matches []string) map[string]string {
|
||||
}
|
||||
return nameMatchMap
|
||||
}
|
||||
|
||||
// SplitFilterFromFlag separates a flag's value from the node filter, if there is one
|
||||
func SplitFilterFromFlag(flag string) (string, string, error) {
|
||||
|
||||
/* Case 1) no filter specified */
|
||||
|
||||
if !strings.Contains(flag, "@") {
|
||||
return flag, "", nil
|
||||
}
|
||||
|
||||
/* Case 2) filter indicated using '@' in flag */
|
||||
|
||||
split := strings.Split(flag, "@")
|
||||
|
||||
// max number of pieces after split = 2 (only one @ allowed in flag)
|
||||
if len(split) > 2 {
|
||||
return "", "", fmt.Errorf("Invalid flag '%s': only one '@' for node filter allowed", flag)
|
||||
}
|
||||
|
||||
// trailing or leading '@'
|
||||
if len(split) < 2 {
|
||||
return "", "", fmt.Errorf("Invalid flag '%s' includes '@' but is missing either an object or a filter", flag)
|
||||
}
|
||||
|
||||
return split[0], split[1], nil
|
||||
|
||||
}
|
||||
|
||||
// FilterNodes takes a string filter to return a filtered list of nodes
|
||||
func FilterNodes(nodes []*k3d.Node, filterString string) ([]*k3d.Node, error) {
|
||||
|
||||
// filterString is a semicolon-separated list of node filters
|
||||
filters := strings.Split(filterString, ";")
|
||||
|
||||
if len(filters) == 0 {
|
||||
log.Warnln("No filter specified")
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// map roles to subsets
|
||||
masterNodes := []*k3d.Node{}
|
||||
workerNodes := []*k3d.Node{}
|
||||
for _, node := range nodes {
|
||||
if node.Role == k3d.MasterRole {
|
||||
masterNodes = append(masterNodes, node)
|
||||
} else if node.Role == k3d.WorkerRole {
|
||||
workerNodes = append(workerNodes, node)
|
||||
}
|
||||
}
|
||||
|
||||
filteredNodes := []*k3d.Node{}
|
||||
set := make(map[*k3d.Node]struct{})
|
||||
|
||||
// range over all instances of group[subset] specs
|
||||
for _, filter := range filters {
|
||||
|
||||
// match regex with capturing groups
|
||||
match := filterRegexp.FindStringSubmatch(filter)
|
||||
|
||||
if len(match) == 0 {
|
||||
return nil, fmt.Errorf("Failed to parse node filters: invalid format or empty subset in '%s'", filter)
|
||||
}
|
||||
|
||||
// map capturing group names to submatches
|
||||
submatches := mapSubexpNames(filterRegexp.SubexpNames(), match)
|
||||
|
||||
// if one of the filters is 'all', we only return this and drop all others
|
||||
if submatches["group"] == "all" {
|
||||
// TODO: only log if really more than one is specified
|
||||
log.Warnf("Node filter 'all' set, but more were specified in '%s'", filterString)
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// Choose the group of nodes to operate on
|
||||
groupNodes := []*k3d.Node{}
|
||||
if submatches["group"] == string(k3d.MasterRole) {
|
||||
groupNodes = masterNodes
|
||||
} else if submatches["group"] == string(k3d.WorkerRole) {
|
||||
groupNodes = workerNodes
|
||||
}
|
||||
|
||||
/* Option 1) subset defined by list */
|
||||
if submatches["subsetList"] != "" {
|
||||
for _, index := range strings.Split(submatches["subsetList"], ",") {
|
||||
if index != "" {
|
||||
num, err := strconv.Atoi(index)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to convert subset number to integer in '%s'", filter)
|
||||
}
|
||||
if num < 0 || num >= len(groupNodes) {
|
||||
return nil, fmt.Errorf("Index out of range: index '%d' < 0 or > number of available nodes in filter '%s'", num, filter)
|
||||
}
|
||||
if _, exists := set[groupNodes[num]]; !exists {
|
||||
filteredNodes = append(filteredNodes, groupNodes[num])
|
||||
set[groupNodes[num]] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Option 2) subset defined by range */
|
||||
} else if submatches["subsetRange"] != "" {
|
||||
|
||||
/*
|
||||
* subset specified by a range 'START:END', where each side is optional
|
||||
*/
|
||||
|
||||
split := strings.Split(submatches["subsetRange"], ":")
|
||||
if len(split) != 2 {
|
||||
return nil, fmt.Errorf("Failed to parse subset range in '%s'", filter)
|
||||
}
|
||||
|
||||
start := 0
|
||||
end := len(groupNodes) - 1
|
||||
|
||||
var err error
|
||||
|
||||
if split[0] != "" {
|
||||
start, err = strconv.Atoi(split[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to convert subset range start to integer in '%s'", filter)
|
||||
}
|
||||
if start < 0 || start >= len(groupNodes) {
|
||||
return nil, fmt.Errorf("Invalid subset range: start < 0 or > number of available nodes in '%s'", filter)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if split[1] != "" {
|
||||
end, err = strconv.Atoi(split[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to convert subset range start to integer in '%s'", filter)
|
||||
}
|
||||
if end < start || end >= len(groupNodes) {
|
||||
return nil, fmt.Errorf("Invalid subset range: end < start or > number of available nodes in '%s'", filter)
|
||||
}
|
||||
}
|
||||
|
||||
for i := start; i <= end; i++ {
|
||||
if _, exists := set[groupNodes[i]]; !exists {
|
||||
filteredNodes = append(filteredNodes, groupNodes[i])
|
||||
set[groupNodes[i]] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
/* Option 3) subset defined by wildcard */
|
||||
} else if submatches["subsetWildcard"] == "*" {
|
||||
/*
|
||||
* '*' = all nodes
|
||||
*/
|
||||
for _, node := range groupNodes {
|
||||
if _, exists := set[node]; !exists {
|
||||
filteredNodes = append(filteredNodes, node)
|
||||
set[node] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
/* Option X) invalid/unknown subset */
|
||||
} else {
|
||||
return nil, fmt.Errorf("Failed to parse node specifiers: unknown subset in '%s'", filter)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return filteredNodes, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user