From c92c9b8e2fa9bf428e40cfd849cedf56fb7ed78e Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Wed, 6 Nov 2019 19:34:20 +0100 Subject: [PATCH] filter nodes and validate volume mounts --- cmd/create/createCluster.go | 14 +++-- cmd/util/util.go | 2 +- cmd/util/volumes.go | 104 +++++++++++------------------------- 3 files changed, 42 insertions(+), 78 deletions(-) diff --git a/cmd/create/createCluster.go b/cmd/create/createCluster.go index 1115726c..4cab5fb6 100644 --- a/cmd/create/createCluster.go +++ b/cmd/create/createCluster.go @@ -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 diff --git a/cmd/util/util.go b/cmd/util/util.go index 8b675c6e..c889a9c2 100644 --- a/cmd/util/util.go +++ b/cmd/util/util.go @@ -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, ";") diff --git a/cmd/util/volumes.go b/cmd/util/volumes.go index 8eb4d5c1..582d9488 100644 --- a/cmd/util/volumes.go +++ b/cmd/util/volumes.go @@ -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 }