filter nodes and validate volume mounts

This commit is contained in:
iwilltry42 2019-11-06 19:34:20 +01:00
parent 62501af7e9
commit c92c9b8e2f
3 changed files with 42 additions and 78 deletions

View File

@ -130,11 +130,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
}
volumeFilterMap := make(map[string]string, 1)
for _, volumeFlag := range volumeFlags {
v, f, err := cliutil.SplitFilterFromFlag(volumeFlag)
volume, filter, err := cliutil.SplitFilterFromFlag(volumeFlag)
if err != nil {
log.Fatalln(err)
}
volumeFilterMap[v] = f
if err := cliutil.ValidateVolumeMount(volume); err != nil {
log.Fatalln(err)
}
volumeFilterMap[volume] = filter
}
/* generate cluster */
@ -178,11 +181,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
// append volumes
// TODO:
for v, f := range volumeFilterMap {
nodes, err := cliutil.FilterNodes(f)
for volume, filter := range volumeFilterMap {
nodes, err := cliutil.FilterNodes(&cluster.Nodes, filter)
if err != nil {
log.Fatalln(err)
}
for _, node := range nodes {
node.Volumes = append(node.Volumes, volume)
}
}
return runtime, cluster

View File

@ -75,7 +75,7 @@ func SplitFilterFromFlag(flag string) (string, string, error) {
}
// FilterNodes takes a string filter to return a filtered list of nodes
func FilterNodes(filterString string, nodes []*k3d.Node) ([]*k3d.Node, error) {
func FilterNodes(nodes *[]k3d.Node, filterString string) ([]*k3d.Node, error) {
// filterString is a semicolon-separated list of node filters
filters := strings.Split(filterString, ";")

View File

@ -25,83 +25,41 @@ import (
"fmt"
"os"
"strings"
log "github.com/sirupsen/logrus"
)
// ValidateVolumeFlag checks, if the source of volume mounts exists and if the destination is an absolute path
// a flag can look like this: --volume SRC:DST@NODES, where...
// ValidateVolumeMount checks, if the source of volume mounts exists and if the destination is an absolute path
// - SRC: source directory/file -> tests: must exist
// - DEST: source directory/file -> tests: must be absolute path
// - NODES: specifies a set of nodes -> tests: fit regex // TODO:
func ValidateVolumeFlag(volumeFlags []string) (string, string, error) {
for _, volume := range volumeFlags {
src := ""
dest := ""
nodes := ""
split := strings.Split(volume, "@")
// max number of pieces after split = 2 (only one @ allowed in flag)
if len(split) > 2 {
return rolesToVolumesMap, fmt.Errorf("Invalid volume flag '%s': only one '@' allowed", volume)
}
// min number of pieces after split = 1 (catch empty flags)
if len(split) > 1 {
nodes = split[1]
}
// catch all other unlikely cases
if len(split) == 0 || split[0] == "" {
return rolesToVolumesMap, fmt.Errorf("Invalid volume flag '%s'", volume)
}
// validate 'SRC[:DEST]' substring
split = strings.Split(split[0], ":")
if len(split) < 1 || len(split) > 2 {
return rolesToVolumesMap, fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volume)
}
// we only have SRC specified -> DEST = SRC
if len(split) == 1 {
src = split[0]
dest = src
} else {
src = split[0]
dest = split[1]
}
// verify that the source exists
if src != "" {
if _, err := os.Stat(src); err != nil {
return rolesToVolumesMap, fmt.Errorf("Failed to stat file/dir that you're trying to mount: '%s' in '%s'", src, volume)
}
}
// verify that the destination is an absolute path
if !strings.HasPrefix(dest, "/") {
return rolesToVolumesMap, fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volume)
}
// put into struct
volumeSpec.Source = src
volumeSpec.Destination = dest
// if no nodes are specified with an @nodeset, attach volume to all nodes and go to next value
if nodes == "" {
rolesToVolumesMap.AllRoles = append(rolesToVolumesMap.AllRoles, volumeSpec)
continue
}
specifiedNodes, err := parseNodeSpecifier(nodes, masterCount, workerCount)
if err != nil {
log.Errorf("Failed to parse node specifier on '--volume %s'", volume)
return rolesToVolumesMap, err
}
log.Debugf("Specified nodes: %+v", specifiedNodes)
func ValidateVolumeMount(volumeMount string) error {
src := ""
dest := ""
// validate 'SRC[:DEST]' substring
split := strings.Split(volumeMount, ":")
if len(split) < 1 || len(split) > 2 {
return fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volumeMount)
}
return rolesToVolumesMap, nil
// we only have SRC specified -> DEST = SRC
if len(split) == 1 {
src = split[0]
dest = src
} else {
src = split[0]
dest = split[1]
}
// verify that the source exists
if src != "" {
if _, err := os.Stat(src); err != nil {
return fmt.Errorf("Failed to stat file/dir that you're trying to mount: '%s' in '%s'", src, volumeMount)
}
}
// verify that the destination is an absolute path
if !strings.HasPrefix(dest, "/") {
return fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volumeMount)
}
return nil
}