From fd4b80368126c7d7c9976d492b51b1af064c7090 Mon Sep 17 00:00:00 2001 From: iwilltry42 Date: Thu, 12 Dec 2019 19:14:26 +0100 Subject: [PATCH] start fixing createNode --- cmd/create/createNode.go | 26 +++++++++++++---- pkg/cluster/cluster.go | 5 +++- pkg/cluster/node.go | 62 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/cmd/create/createNode.go b/cmd/create/createNode.go index 212b6cad..dcd8f989 100644 --- a/cmd/create/createNode.go +++ b/cmd/create/createNode.go @@ -26,9 +26,10 @@ import ( "github.com/spf13/cobra" - "github.com/rancher/k3d/pkg/cluster" + k3dc "github.com/rancher/k3d/pkg/cluster" "github.com/rancher/k3d/pkg/runtimes" k3d "github.com/rancher/k3d/pkg/types" + "github.com/rancher/k3d/version" log "github.com/sirupsen/logrus" ) @@ -42,7 +43,13 @@ func NewCmdCreateNode() *cobra.Command { Long: `Create a new containerized k3s node (k3s in docker).`, Args: cobra.ExactArgs(1), // exactly one name accepted // TODO: if not specified, inherit from cluster that the node shall belong to, if that is specified Run: func(cmd *cobra.Command, args []string) { - cluster.CreateNodes(parseCreateNodeCmd(cmd, args)) + nodes, cluster, runtime := parseCreateNodeCmd(cmd, args) + for _, node := range nodes { + if err := k3dc.AddNodeToCluster(runtime, node, cluster); err != nil { + log.Errorf("Failed to add node '%s' to cluster '%s'", node.Name, cluster.Name) + log.Errorln(err) + } + } }, } @@ -50,14 +57,14 @@ func NewCmdCreateNode() *cobra.Command { cmd.Flags().Int("replicas", 1, "Number of replicas of this node specification.") cmd.Flags().String("role", string(k3d.WorkerRole), "Specify node role [master, worker]") cmd.Flags().StringP("cluster", "c", "", "Select the cluster that the node shall connect to.") - cmd.Flags().String("image", k3d.DefaultK3sImageRepo, "Specify k3s image used for the node(s)") // TODO: get image version tag + cmd.Flags().String("image", fmt.Sprintf("%s:%s", k3d.DefaultK3sImageRepo, version.K3sVersion), "Specify k3s image used for the node(s)") // TODO: get image version tag // done return cmd } // parseCreateNodeCmd parses the command input into variables required to create a cluster -func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, runtimes.Runtime) { +func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, *k3d.Cluster, runtimes.Runtime) { // --runtime rt, err := cmd.Flags().GetString("runtime") @@ -94,6 +101,15 @@ func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, runtime log.Fatalln(err) } + // --cluster + clusterName, err := cmd.Flags().GetString("cluster") + if err != nil { + log.Fatalln(err) + } + cluster := &k3d.Cluster{ + Name: clusterName, + } + // generate list of nodes nodes := []*k3d.Node{} for i := 0; i < replicas; i++ { @@ -105,5 +121,5 @@ func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, runtime nodes = append(nodes, node) } - return nodes, runtime + return nodes, cluster, runtime } diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index bc4c3e25..ce833e52 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -106,6 +106,7 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { } node.Labels["k3d.cluster"] = cluster.Name node.Env = append(node.Env, fmt.Sprintf("K3S_CLUSTER_SECRET=%s", cluster.Secret)) + node.Labels["k3d.cluster.secret"] = cluster.Secret // append extra labels for k, v := range extraLabels { @@ -122,7 +123,9 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error { } else if node.Role == k3d.WorkerRole { // connection url - node.Env = append(node.Env, fmt.Sprintf("K3S_URL=https://%s:%d", generateNodeName(cluster.Name, k3d.MasterRole, 0), 6443)) + connectionURL := fmt.Sprintf("https://%s:%d", generateNodeName(cluster.Name, k3d.MasterRole, 0), 6443) + node.Env = append(node.Env, fmt.Sprintf("K3S_URL=%s", connectionURL)) + node.Labels["k3d.cluster.url"] = connectionURL } node.Name = generateNodeName(cluster.Name, node.Role, suffix) diff --git a/pkg/cluster/node.go b/pkg/cluster/node.go index 709a2e00..661c5e3f 100644 --- a/pkg/cluster/node.go +++ b/pkg/cluster/node.go @@ -24,14 +24,64 @@ package cluster import ( "fmt" + "strings" - k3drt "github.com/rancher/k3d/pkg/runtimes" + "github.com/rancher/k3d/pkg/runtimes" k3d "github.com/rancher/k3d/pkg/types" log "github.com/sirupsen/logrus" ) +// AddNodeToCluster adds a node to an existing cluster +func AddNodeToCluster(runtime runtimes.Runtime, node *k3d.Node, cluster *k3d.Cluster) error { + cluster, err := GetCluster(cluster, runtime) + if err != nil { + log.Errorf("Failed to find specified cluster '%s'", cluster.Name) + return err + } + + log.Debugf("Adding node to cluster %+v", cluster) + + // network + node.Network = cluster.Network.Name + + // skeleton + node.Labels = map[string]string{} + node.Env = []string{} + + // copy labels and env vars from a similar node in the selected cluster + for _, existingNode := range cluster.Nodes { + if existingNode.Role == node.Role { + + log.Debugf("Copying configuration from existing node %+v", existingNode) + + for k, v := range existingNode.Labels { + if strings.HasPrefix(k, "k3d") { + node.Labels[k] = v + } + if k == "k3d.cluster.url" { + node.Env = append(node.Env, fmt.Sprintf("K3S_URL=%s", v)) + } + if k == "k3d.cluster.secret" { + node.Env = append(node.Env, fmt.Sprintf("K3S_CLUSTER_SECRET=%s", v)) + } + } + + for _, env := range existingNode.Env { + if strings.HasPrefix(env, "K3S_") { + node.Env = append(node.Env, env) + } + } + break + } + } + + log.Debugf("Resulting node %+v", node) + + return CreateNode(node, runtime) +} + // CreateNodes creates a list of nodes -func CreateNodes(nodes []*k3d.Node, runtime k3drt.Runtime) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? +func CreateNodes(nodes []*k3d.Node, runtime runtimes.Runtime) { // TODO: pass `--atomic` flag, so we stop and return an error if any node creation fails? for _, node := range nodes { if err := CreateNode(node, runtime); err != nil { log.Error(err) @@ -40,7 +90,7 @@ func CreateNodes(nodes []*k3d.Node, runtime k3drt.Runtime) { // TODO: pass `--at } // CreateNode creates a new containerized k3s node -func CreateNode(node *k3d.Node, runtime k3drt.Runtime) error { +func CreateNode(node *k3d.Node, runtime runtimes.Runtime) error { log.Debugf("Creating node from spec\n%+v", node) /* @@ -87,7 +137,7 @@ func CreateNode(node *k3d.Node, runtime k3drt.Runtime) error { } // DeleteNode deletes an existing node -func DeleteNode(runtime k3drt.Runtime, node *k3d.Node) error { +func DeleteNode(runtime runtimes.Runtime, node *k3d.Node) error { if err := runtime.DeleteNode(node); err != nil { log.Error(err) @@ -128,7 +178,7 @@ func patchMasterSpec(node *k3d.Node) error { } // GetNodes returns a list of all existing clusters -func GetNodes(runtime k3drt.Runtime) ([]*k3d.Node, error) { +func GetNodes(runtime runtimes.Runtime) ([]*k3d.Node, error) { nodes, err := runtime.GetNodesByLabel(k3d.DefaultObjectLabels) if err != nil { log.Errorln("Failed to get nodes") @@ -139,7 +189,7 @@ func GetNodes(runtime k3drt.Runtime) ([]*k3d.Node, error) { } // GetNode returns an existing cluster -func GetNode(node *k3d.Node, runtime k3drt.Runtime) (*k3d.Node, error) { +func GetNode(node *k3d.Node, runtime runtimes.Runtime) (*k3d.Node, error) { // get node node, err := runtime.GetNode(node) if err != nil {