diff --git a/CHANGELOG.md b/CHANGELOG.md index 473948f2..96806758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - port-mapping now go via the loadbalancer (serverlb) by default - the `--port` flag has the `proxy` opt (see new nodefilter syntax above) set by default - to leverage the old behavior of direct port-mappings, use the `direct` opt on the port flag + - the nodefilter `loadbalancer` will now do the same as `servers:*;agents:*` (proxied via the loadbalancer) ### Fixes diff --git a/pkg/client/loadbalancer.go b/pkg/client/loadbalancer.go index fe1989b4..c6bec707 100644 --- a/pkg/client/loadbalancer.go +++ b/pkg/client/loadbalancer.go @@ -139,7 +139,7 @@ func GetLoadbalancerConfig(ctx context.Context, runtime runtimes.Runtime, cluste file = bytes.Trim(file[512:], "\x00") // trim control characters, etc. if err := yaml.Unmarshal(file, &cfg); err != nil { - return cfg, err + return cfg, fmt.Errorf("error unmarshalling loadbalancer config: %w", err) } return cfg, nil diff --git a/pkg/config/transform.go b/pkg/config/transform.go index cc812374..b1850d14 100644 --- a/pkg/config/transform.go +++ b/pkg/config/transform.go @@ -44,6 +44,10 @@ import ( log "github.com/sirupsen/logrus" ) +var ( + DefaultTargetsNodefiltersPortMappings = []string{"servers:*:proxy", "agents:*:proxy"} +) + // TransformSimpleToClusterConfig transforms a simple configuration to a full-fledged cluster configuration func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtime, simpleConfig conf.SimpleConfig) (*conf.ClusterConfig, error) { @@ -171,8 +175,18 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim // -> PORTS for _, portWithNodeFilters := range simpleConfig.Ports { + log.Tracef("inspecting port mapping for %s with nodefilters %s", portWithNodeFilters.Port, portWithNodeFilters.NodeFilters) if len(portWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 { - return nil, fmt.Errorf("Portmapping '%s' lacks a node filter, but there's more than one node", portWithNodeFilters.Port) + log.Infof("portmapping '%s' lacks a nodefilter, but there's more than one node: defaulting to %s", portWithNodeFilters.Port, DefaultTargetsNodefiltersPortMappings) + portWithNodeFilters.NodeFilters = DefaultTargetsNodefiltersPortMappings + } + + for _, f := range portWithNodeFilters.NodeFilters { + if strings.HasPrefix(f, "loadbalancer") { + log.Infof("portmapping '%s' targets the loadbalancer: defaulting to %s", portWithNodeFilters.Port, DefaultTargetsNodefiltersPortMappings) + portWithNodeFilters.NodeFilters = DefaultTargetsNodefiltersPortMappings + break + } } filteredNodes, err := util.FilterNodesWithSuffix(nodeList, portWithNodeFilters.NodeFilters) @@ -180,23 +194,18 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim return nil, err } + nn := "" + for _, n := range filteredNodes["proxy"] { + nn = strings.Join([]string{nn, n.Name}, ",") + } + log.Debugf("Filtered nodes: %#v", nn) + for suffix, nodes := range filteredNodes { portmappings, err := nat.ParsePortSpec(portWithNodeFilters.Port) if err != nil { return nil, fmt.Errorf("error parsing port spec '%s': %+v", portWithNodeFilters.Port, err) } - for _, n := range nodes { - if n.Role == k3d.LoadBalancerRole && n.Name == newCluster.ServerLoadBalancer.Node.Name { - log.Infoln("loadbalancer in filtered list for port mappings: defaulting to all servers and agents as upstream targets") - var err error - nodes, err = util.FilterNodes(newCluster.Nodes, []string{"agents:*", "servers:*"}) - if err != nil { - return nil, err - } - } - } - if suffix == "proxy" || suffix == util.NodeFilterSuffixNone { // proxy is the default suffix for port mappings if newCluster.ServerLoadBalancer == nil { return nil, fmt.Errorf("port-mapping of type 'proxy' specified, but loadbalancer is disabled") @@ -222,6 +231,16 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim } + // print generated loadbalancer config + if log.GetLevel() >= log.DebugLevel { + yamlized, err := yaml.Marshal(newCluster.ServerLoadBalancer.Config) + if err != nil { + log.Errorf("error printing loadbalancer config: %v", err) + } else { + log.Debugf("generated loadbalancer config:\n%s", string(yamlized)) + } + } + // -> K3S NODE LABELS for _, k3sNodeLabelWithNodeFilters := range simpleConfig.Options.K3sOptions.NodeLabels { if len(k3sNodeLabelWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 { diff --git a/pkg/util/filter.go b/pkg/util/filter.go index 7ddb04ba..1f9e5d70 100644 --- a/pkg/util/filter.go +++ b/pkg/util/filter.go @@ -77,7 +77,9 @@ func FilterNodesWithSuffix(nodes []*k3d.Node, nodefilters []string) (map[string] suffix = sf } - result[suffix] = make([]*k3d.Node, 0) // init map for this suffix + if _, ok := result[suffix]; !ok { + result[suffix] = make([]*k3d.Node, 0) // init map for this suffix, if not exists + } filteredNodes, err := FilterNodes(nodes, []string{nf}) if err != nil { @@ -86,7 +88,7 @@ func FilterNodesWithSuffix(nodes []*k3d.Node, nodefilters []string) (map[string] log.Tracef("Filtered %d nodes for suffix '%s' (filter: %s)", len(filteredNodes), suffix, nf) - result[suffix] = filteredNodes + result[suffix] = append(result[suffix], filteredNodes...) } return result, nil