From 45e4e373030e9fb08767da0a21d0ff408aed27b5 Mon Sep 17 00:00:00 2001
From: kaiyou <dev@kaiyou.fr>
Date: Mon, 5 Sep 2022 22:58:34 +0200
Subject: [PATCH] Use a pflag type for node role

---
 cmd/hepto/config.go    |  2 +-
 pkg/cluster/cluster.go | 22 +++++++++++++++++++---
 pkg/cluster/config.go  | 29 +++++++++++++++++++++++++++--
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/cmd/hepto/config.go b/cmd/hepto/config.go
index 93e7747..f04329d 100644
--- a/cmd/hepto/config.go
+++ b/cmd/hepto/config.go
@@ -64,5 +64,5 @@ func init() {
 	rootCmd.Flags().IntVar(&config.Node.Port, "discovery-port", 7123, "TCP port used for discovering the cluster")
 	rootCmd.Flags().StringVar(&config.Node.Name, "name", "", "Hepto node name")
 	rootCmd.Flags().StringSliceVar(&config.Node.Anchors, "anchors", []string{}, "List of cluster anchors")
-	rootCmd.Flags().StringVar(&config.Node.Role, "role", "node", "Node role inside the cluster")
+	rootCmd.Flags().Var(&config.Node.Role, "role", "Node role inside the cluster")
 }
diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go
index 4370b0a..53d5add 100644
--- a/pkg/cluster/cluster.go
+++ b/pkg/cluster/cluster.go
@@ -3,11 +3,14 @@
 package cluster
 
 import (
+	"context"
 	"net"
 
 	"forge.tedomum.net/acides/hepto/hepto/pkg/sml"
 	"forge.tedomum.net/acides/hepto/hepto/pkg/wg"
+	"forge.tedomum.net/acides/hepto/hepto/pkg/wrappers"
 	"github.com/sirupsen/logrus"
+	"go.etcd.io/etcd/server/v3/embed"
 )
 
 type Cluster struct {
@@ -35,7 +38,7 @@ func New(settings *ClusterSettings, node *NodeSettings) (*Cluster, error) {
 	}
 	c.vpn = vpn
 	// Initialize cluster PKI and local keys
-	if node.Role == "master" {
+	if node.Role == Master {
 		pki, err := NewClusterPKI("pki")
 		if err != nil {
 			return nil, err
@@ -51,7 +54,7 @@ func New(settings *ClusterSettings, node *NodeSettings) (*Cluster, error) {
 	c.certs = certs
 	// Initialize node meta
 	c.ml.Meta.VpnKey = vpn.PubKey.String()
-	c.ml.Meta.Role = node.Role
+	c.ml.Meta.Role = string(node.Role)
 	// Initialize cluster state
 	c.ml.State.PKI = c.pki
 	c.ml.State.Certificates = make(map[string]*NodeCerts)
@@ -71,10 +74,11 @@ func (c *Cluster) Run() error {
 	for {
 		select {
 		case <-events:
-			if c.node.Role == "master" {
+			if c.node.Role == Master {
 				c.handlePKI()
 			}
 			c.updateVPN()
+			c.updateServices()
 		case <-instrUpdates:
 			c.networking.MTU = instr.MinMTU()
 			c.updateVPN()
@@ -107,3 +111,15 @@ func (c *Cluster) updateVPN() {
 	logrus.Debugf("updating VPN mesh, %d peers, MTU %d", len(peers), c.networking.MTU)
 	c.vpn.Update(peers, c.networking.MTU)
 }
+
+func (c *Cluster) updateServices() {
+	ctx := context.Background()
+	if c.node.Role == Master {
+		etcdConfig := embed.NewConfig()
+		etcdConfig.Dir = "/etcd"
+		_, err := wrappers.ETCd(ctx, etcdConfig)
+		if err != nil {
+			logrus.Fatal(err)
+		}
+	}
+}
diff --git a/pkg/cluster/config.go b/pkg/cluster/config.go
index a7e5332..e78cb6b 100644
--- a/pkg/cluster/config.go
+++ b/pkg/cluster/config.go
@@ -1,6 +1,7 @@
 package cluster
 
 import (
+	"errors"
 	"net"
 
 	"forge.tedomum.net/acides/hepto/hepto/pkg/types"
@@ -16,8 +17,8 @@ type ClusterSettings struct {
 type NodeSettings struct {
 	// Node name, must be unique inside a cluster
 	Name string
-	// Node role, TODO: switch to proper types
-	Role string
+	// Node role
+	Role NodeRole
 	// Port for initial memberlist negotiations
 	Port int
 	// Public IPv6 address for the node
@@ -26,6 +27,30 @@ type NodeSettings struct {
 	Anchors []string
 }
 
+type NodeRole string
+
+const (
+	Master NodeRole = "master"
+	Node            = "node"
+)
+
+func (r *NodeRole) String() string {
+	return string(*r)
+}
+
+func (r *NodeRole) Type() string {
+	return "NodeRole"
+}
+
+func (r *NodeRole) Set(v string) error {
+	cast := (NodeRole)(v)
+	if cast == Master || cast == Node {
+		*r = (NodeRole)(cast)
+		return nil
+	}
+	return errors.New("wrong node type")
+}
+
 type ClusterNetworking struct {
 	NodeNet     types.Address
 	NodeAddress types.Address
-- 
GitLab