From 7a3edd9d7e3cd53ea6957d0b7a71cd645baa1e2a Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Tue, 19 Jan 2021 18:03:57 +0100 Subject: [PATCH] NodeSpec: transform network string to list of strings to allow checking out node networks --- CHANGELOG.md | 1 + pkg/client/cluster.go | 10 ++++---- pkg/client/node.go | 2 +- pkg/client/registry.go | 10 ++++---- pkg/runtimes/docker/translate.go | 33 +++++++++++++++++---------- pkg/runtimes/docker/translate_test.go | 7 +++--- pkg/tools/tools.go | 16 ++++++------- pkg/types/types.go | 2 +- 8 files changed, 46 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2bfbb7c..074757f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - `ClusterCreate` and `NodeCreate` don't start the entities (containers) anymore - `ClusterRun` and `NodeRun` orchestrate the new Create and Start functionality - `NodeDelete` now takes an additional `NodeDeleteOpts` struct to toggle specific steps +- NodeSpec now features a list of networks (required for registries) - New config flow: CLIConfig (SimpleConfig) -> ClusterConfig -> Cluster + Opts #### CLI diff --git a/pkg/client/cluster.go b/pkg/client/cluster.go index 9aae94ce..277e7adb 100644 --- a/pkg/client/cluster.go +++ b/pkg/client/cluster.go @@ -399,7 +399,7 @@ ClusterCreatOpts: } node.Name = generateNodeName(cluster.Name, node.Role, suffix) - node.Network = cluster.Network.Name + node.Networks = []string{cluster.Network.Name} node.Restart = true node.GPURequest = clusterCreateOpts.GPURequest @@ -507,10 +507,10 @@ ClusterCreatOpts: fmt.Sprintf("PORTS=%s", ports), fmt.Sprintf("WORKER_PROCESSES=%d", len(strings.Split(ports, ","))), }, - Role: k3d.LoadBalancerRole, - Labels: clusterCreateOpts.GlobalLabels, // TODO: createLoadBalancer: add more expressive labels - Network: cluster.Network.Name, - Restart: true, + Role: k3d.LoadBalancerRole, + Labels: clusterCreateOpts.GlobalLabels, // TODO: createLoadBalancer: add more expressive labels + Networks: []string{cluster.Network.Name}, + Restart: true, } cluster.Nodes = append(cluster.Nodes, lbNode) // append lbNode to list of cluster nodes, so it will be considered during rollback log.Infof("Creating LoadBalancer '%s'", lbNode.Name) diff --git a/pkg/client/node.go b/pkg/client/node.go index 58f35b54..49140f5c 100644 --- a/pkg/client/node.go +++ b/pkg/client/node.go @@ -47,7 +47,7 @@ func NodeAddToCluster(ctx context.Context, runtime runtimes.Runtime, node *k3d.N } // network - node.Network = cluster.Network.Name + node.Networks = []string{cluster.Network.Name} // skeleton if node.Labels == nil { diff --git a/pkg/client/registry.go b/pkg/client/registry.go index 3f69195a..1a0afbef 100644 --- a/pkg/client/registry.go +++ b/pkg/client/registry.go @@ -63,11 +63,11 @@ func RegistryCreate(ctx context.Context, runtime runtimes.Runtime, reg *k3d.Regi // } registryNode := &k3d.Node{ - Name: reg.Host, - Image: reg.Image, - Role: k3d.RegistryRole, - Network: "bridge", // Default network: TODO: change to const from types - Restart: true, + Name: reg.Host, + Image: reg.Image, + Role: k3d.RegistryRole, + Networks: []string{"bridge"}, // Default network: TODO: change to const from types + Restart: true, } // error out if that registry exists already diff --git a/pkg/runtimes/docker/translate.go b/pkg/runtimes/docker/translate.go index 135f0f7c..cb693298 100644 --- a/pkg/runtimes/docker/translate.go +++ b/pkg/runtimes/docker/translate.go @@ -103,15 +103,21 @@ func TranslateNodeToContainer(node *k3d.Node) (*NodeInDocker, error) { containerConfig.ExposedPorts = exposedPorts hostConfig.PortBindings = node.Ports /* Network */ - networkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ - node.Network: {}, + endpointsConfig := map[string]*network.EndpointSettings{} + for _, net := range node.Networks { + endpointsConfig[net] = &network.EndpointSettings{} } - netInfo, err := GetNetwork(context.Background(), node.Network) - if err != nil { - log.Warnln("Failed to get network information") - log.Warnln(err) - } else if netInfo.Driver == "host" { - hostConfig.NetworkMode = "host" + + networkingConfig.EndpointsConfig = endpointsConfig + + if len(node.Networks) > 0 { + netInfo, err := GetNetwork(context.Background(), node.Networks[0]) // FIXME: only considering first network here, as that's the one k3d creates for a cluster + if err != nil { + log.Warnln("Failed to get network information") + log.Warnln(err) + } else if netInfo.Driver == "host" { + hostConfig.NetworkMode = "host" + } } return &NodeInDocker{ @@ -158,13 +164,16 @@ func TranslateContainerDetailsToNode(containerDetails types.ContainerJSON) (*k3d restart = true } - // get the clusterNetwork - clusterNetwork := "" + // get networks and ensure that the cluster network is first in list + orderedNetworks := []string{} + otherNetworks := []string{} for networkName := range containerDetails.NetworkSettings.Networks { if strings.HasPrefix(networkName, fmt.Sprintf("%s-%s", k3d.DefaultObjectNamePrefix, containerDetails.Config.Labels[k3d.LabelClusterName])) { // FIXME: catch error if label 'k3d.cluster' does not exist, but this should also never be the case - clusterNetwork = networkName + orderedNetworks = append(orderedNetworks, networkName) } + otherNetworks = append(otherNetworks, networkName) } + orderedNetworks = append(orderedNetworks, otherNetworks...) // serverOpts serverOpts := k3d.ServerOpts{IsInit: false} @@ -213,7 +222,7 @@ func TranslateContainerDetailsToNode(containerDetails types.ContainerJSON) (*k3d Restart: restart, Created: containerDetails.Created, Labels: labels, - Network: clusterNetwork, + Networks: orderedNetworks, ServerOpts: serverOpts, AgentOpts: k3d.AgentOpts{}, State: nodeState, diff --git a/pkg/runtimes/docker/translate_test.go b/pkg/runtimes/docker/translate_test.go index 67794992..a64c53b9 100644 --- a/pkg/runtimes/docker/translate_test.go +++ b/pkg/runtimes/docker/translate_test.go @@ -51,8 +51,9 @@ func TestTranslateNodeToContainer(t *testing.T) { }, }, }, - Restart: true, - Labels: map[string]string{k3d.LabelRole: string(k3d.ServerRole), "test_key_1": "test_val_1"}, + Restart: true, + Labels: map[string]string{k3d.LabelRole: string(k3d.ServerRole), "test_key_1": "test_val_1"}, + Networks: []string{"mynet"}, } init := true @@ -87,7 +88,7 @@ func TestTranslateNodeToContainer(t *testing.T) { }, NetworkingConfig: network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ - "": {}, + "mynet": {}, }, }, } diff --git a/pkg/tools/tools.go b/pkg/tools/tools.go index 8a9b01b1..7b64f716 100644 --- a/pkg/tools/tools.go +++ b/pkg/tools/tools.go @@ -202,14 +202,14 @@ func ImageImportIntoClusterMulti(ctx context.Context, runtime runtimes.Runtime, // startToolsNode will start a new k3d tools container and connect it to the network of the chosen cluster func startToolsNode(ctx context.Context, runtime runtimes.Runtime, cluster *k3d.Cluster, network string, volumes []string) (*k3d.Node, error) { node := &k3d.Node{ - Name: fmt.Sprintf("%s-%s-tools", k3d.DefaultObjectNamePrefix, cluster.Name), - Image: fmt.Sprintf("%s:%s", k3d.DefaultToolsImageRepo, version.GetHelperImageVersion()), - Role: k3d.NoRole, - Volumes: volumes, - Network: network, - Cmd: []string{}, - Args: []string{"noop"}, - Labels: k3d.DefaultObjectLabels, + Name: fmt.Sprintf("%s-%s-tools", k3d.DefaultObjectNamePrefix, cluster.Name), + Image: fmt.Sprintf("%s:%s", k3d.DefaultToolsImageRepo, version.GetHelperImageVersion()), + Role: k3d.NoRole, + Volumes: volumes, + Networks: []string{network}, + Cmd: []string{}, + Args: []string{"noop"}, + Labels: k3d.DefaultObjectLabels, } node.Labels[k3d.LabelClusterName] = cluster.Name if err := k3dc.NodeRun(ctx, runtime, node, k3d.NodeCreateOpts{}); err != nil { diff --git a/pkg/types/types.go b/pkg/types/types.go index 71591a95..ed5109ec 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -310,7 +310,7 @@ type Node struct { Restart bool `yaml:"restart" json:"restart,omitempty"` Created string `yaml:"created" json:"created,omitempty"` Labels map[string]string // filled automatically - Network string // filled automatically + Networks []string // filled automatically ExtraHosts []string // filled automatically ServerOpts ServerOpts `yaml:"serverOpts" json:"serverOpts,omitempty"` AgentOpts AgentOpts `yaml:"agentOpts" json:"agentOpts,omitempty"`