add node management

This commit is contained in:
Anish Mukherjee 2022-11-22 18:57:17 +05:30
parent 6a403d1974
commit d9c9d29d33
15 changed files with 469 additions and 0 deletions

View file

@ -0,0 +1,39 @@
package node
import (
"strings"
"github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models"
"github.com/spf13/cobra"
)
var (
networkInterface string
natEnabled bool
)
var nodeCreateEgressCmd = &cobra.Command{
Use: "create_egress [NETWORK NAME] [NODE ID] [EGRESS GATEWAY ADDRESSES (comma separated)]",
Args: cobra.ExactArgs(3),
Short: "Turn a Node into a Egress",
Long: `Turn a Node into a Egress`,
Run: func(cmd *cobra.Command, args []string) {
egress := &models.EgressGatewayRequest{
NetID: args[0],
NodeID: args[1],
Interface: networkInterface,
Ranges: strings.Split(args[2], ","),
}
if natEnabled {
egress.NatEnabled = "yes"
}
functions.PrettyPrint(functions.CreateEgress(args[0], args[1], egress))
},
}
func init() {
nodeCreateEgressCmd.Flags().StringVar(&networkInterface, "interface", "", "Network interface name (ex:- eth0)")
nodeCreateEgressCmd.Flags().BoolVar(&natEnabled, "nat", false, "Enable NAT for Egress Traffic ?")
rootCmd.AddCommand(nodeCreateEgressCmd)
}

View file

@ -0,0 +1,23 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var failover bool
var nodeCreateIngressCmd = &cobra.Command{
Use: "create_ingress [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Turn a Node into a Ingress",
Long: `Turn a Node into a Ingress`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.CreateIngress(args[0], args[1], failover))
},
}
func init() {
nodeCreateIngressCmd.Flags().BoolVar(&failover, "failover", false, "Enable FailOver ?")
rootCmd.AddCommand(nodeCreateIngressCmd)
}

View file

@ -0,0 +1,22 @@
package node
import (
"strings"
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeCreateRelayCmd = &cobra.Command{
Use: "create_relay [NETWORK NAME] [NODE ID] [RELAY ADDRESSES (comma separated)]",
Args: cobra.ExactArgs(3),
Short: "Turn a Node into a Relay",
Long: `Turn a Node into a Relay`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.CreateRelay(args[0], args[1], strings.Split(args[2], ",")))
},
}
func init() {
rootCmd.AddCommand(nodeCreateRelayCmd)
}

20
cli/cmd/node/delete.go Normal file
View file

@ -0,0 +1,20 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeDeleteCmd = &cobra.Command{
Use: "delete [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Delete a Node",
Long: `Delete a Node`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.DeleteNode(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeDeleteCmd)
}

View file

@ -0,0 +1,20 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeDeleteEgressCmd = &cobra.Command{
Use: "delete_egress [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Delete Egress role from a Node",
Long: `Delete Egress role from a Node`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.DeleteEgress(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeDeleteEgressCmd)
}

View file

@ -0,0 +1,20 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeDeleteIngressCmd = &cobra.Command{
Use: "delete_ingress [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Delete Ingress role from a Node",
Long: `Delete Ingress role from a Node`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.DeleteIngress(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeDeleteIngressCmd)
}

View file

@ -0,0 +1,20 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeDeleteRelayCmd = &cobra.Command{
Use: "delete_relay [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Delete Relay role from a Node",
Long: `Delete Relay role from a Node`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.DeleteRelay(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeDeleteRelayCmd)
}

20
cli/cmd/node/get.go Normal file
View file

@ -0,0 +1,20 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeGetCmd = &cobra.Command{
Use: "get [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Get a node by ID",
Long: `Get a node by ID`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.GetNodeByID(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeGetCmd)
}

28
cli/cmd/node/list.go Normal file
View file

@ -0,0 +1,28 @@
package node
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var networkName string
// nodeListCmd lists all nodes
var nodeListCmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
Short: "List all nodes",
Long: `List all nodes`,
Run: func(cmd *cobra.Command, args []string) {
if networkName != "" {
functions.PrettyPrint(functions.GetNodes(networkName))
} else {
functions.PrettyPrint(functions.GetNodes())
}
},
}
func init() {
nodeListCmd.Flags().StringVar(&networkName, "network", "", "Network name specifier")
rootCmd.AddCommand(nodeListCmd)
}

37
cli/cmd/node/root.go Normal file
View file

@ -0,0 +1,37 @@
package node
import (
"os"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "node",
Short: "Manage nodes associated with a network",
Long: `Manage nodes associated with a network`,
// Run: func(cmd *cobra.Command, args []string) { },
}
func GetRoot() *cobra.Command {
return rootCmd
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}
func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
// Cobra also supports local flags, which will only run
// when this action is called directly.
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

22
cli/cmd/node/uncordon.go Normal file
View file

@ -0,0 +1,22 @@
package node
import (
"fmt"
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var nodeUncordonCmd = &cobra.Command{
Use: "uncordon [NETWORK NAME] [NODE ID]",
Args: cobra.ExactArgs(2),
Short: "Get a node by ID",
Long: `Get a node by ID`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(*functions.UncordonNode(args[0], args[1]))
},
}
func init() {
rootCmd.AddCommand(nodeUncordonCmd)
}

33
cli/cmd/node/update.go Normal file
View file

@ -0,0 +1,33 @@
package node
import (
"encoding/json"
"log"
"os"
"github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models"
"github.com/spf13/cobra"
)
var nodeUpdateCmd = &cobra.Command{
Use: "update [NETWORK NAME] [NODE ID] [/path/to/node_definition.json]",
Args: cobra.ExactArgs(3),
Short: "Update a Node",
Long: `Update a Node`,
Run: func(cmd *cobra.Command, args []string) {
content, err := os.ReadFile(args[2])
if err != nil {
log.Fatal("Error when opening file: ", err)
}
node := &models.Node{}
if err := json.Unmarshal(content, node); err != nil {
log.Fatal(err)
}
functions.PrettyPrint(functions.UpdateNode(args[0], args[1], node))
},
}
func init() {
rootCmd.AddCommand(nodeUpdateCmd)
}

View file

@ -7,6 +7,7 @@ import (
"github.com/gravitl/netmaker/cli/cmd/context"
"github.com/gravitl/netmaker/cli/cmd/keys"
"github.com/gravitl/netmaker/cli/cmd/network"
"github.com/gravitl/netmaker/cli/cmd/node"
"github.com/spf13/cobra"
)
@ -49,4 +50,5 @@ func init() {
rootCmd.AddCommand(context.GetRoot())
rootCmd.AddCommand(keys.GetRoot())
rootCmd.AddCommand(acl.GetRoot())
rootCmd.AddCommand(node.GetRoot())
}

62
cli/functions/node.go Normal file
View file

@ -0,0 +1,62 @@
package functions
import (
"fmt"
"net/http"
"github.com/gravitl/netmaker/models"
)
func GetNodes(networkName ...string) *[]models.Node {
if len(networkName) == 1 {
return request[[]models.Node](http.MethodGet, "/api/nodes/"+networkName[0], nil)
} else {
return request[[]models.Node](http.MethodGet, "/api/nodes", nil)
}
}
func GetNodeByID(networkName, nodeID string) *models.NodeGet {
return request[models.NodeGet](http.MethodGet, fmt.Sprintf("/api/nodes/%s/%s", networkName, nodeID), nil)
}
func UpdateNode(networkName, nodeID string, node *models.Node) *models.Node {
return request[models.Node](http.MethodPut, fmt.Sprintf("/api/nodes/%s/%s", networkName, nodeID), node)
}
func DeleteNode(networkName, nodeID string) *models.SuccessResponse {
return request[models.SuccessResponse](http.MethodDelete, fmt.Sprintf("/api/nodes/%s/%s", networkName, nodeID), nil)
}
func CreateRelay(networkName, nodeID string, relayAddresses []string) *models.Node {
return request[models.Node](http.MethodPost, fmt.Sprintf("/api/nodes/%s/%s/createrelay", networkName, nodeID), &models.RelayRequest{
NetID: networkName,
NodeID: nodeID,
RelayAddrs: relayAddresses,
})
}
func DeleteRelay(networkName, nodeID string) *models.Node {
return request[models.Node](http.MethodDelete, fmt.Sprintf("/api/nodes/%s/%s/deleterelay", networkName, nodeID), nil)
}
func CreateEgress(networkName, nodeID string, payload *models.EgressGatewayRequest) *models.Node {
return request[models.Node](http.MethodPost, fmt.Sprintf("/api/nodes/%s/%s/creategateway", networkName, nodeID), payload)
}
func DeleteEgress(networkName, nodeID string) *models.Node {
return request[models.Node](http.MethodDelete, fmt.Sprintf("/api/nodes/%s/%s/deletegateway", networkName, nodeID), nil)
}
func CreateIngress(networkName, nodeID string, failover bool) *models.Node {
return request[models.Node](http.MethodPost, fmt.Sprintf("/api/nodes/%s/%s/createingress", networkName, nodeID), &struct {
Failover bool `json:"failover"`
}{Failover: failover})
}
func DeleteIngress(networkName, nodeID string) *models.Node {
return request[models.Node](http.MethodDelete, fmt.Sprintf("/api/nodes/%s/%s/deleteingress", networkName, nodeID), nil)
}
func UncordonNode(networkName, nodeID string) *string {
return request[string](http.MethodPost, fmt.Sprintf("/api/nodes/%s/%s/approve", networkName, nodeID), nil)
}

101
cli/samples/node.json Normal file
View file

@ -0,0 +1,101 @@
{
"id": "eda7720b-830c-4e9c-8716-9773e15da160",
"address": "",
"address6": "fd00::ffff:ffff:ffff:ffff",
"localaddress": "",
"name": "netmaker-1",
"networksettings": {
"addressrange": "",
"addressrange6": "fd00::/64",
"netid": "onaw",
"nodeslastmodified": 1668594644,
"networklastmodified": 1668594644,
"defaultinterface": "nm-onaw",
"defaultlistenport": 51821,
"nodelimit": 999999999,
"defaultpostup": "",
"defaultpostdown": "",
"defaultkeepalive": 20,
"accesskeys": [],
"allowmanualsignup": "no",
"islocal": "no",
"isipv4": "no",
"isipv6": "yes",
"ispointtosite": "no",
"localrange": "",
"defaultudpholepunch": "yes",
"defaultextclientdns": "",
"defaultmtu": 1280,
"defaultacl": "yes",
"prosettings": {
"defaultaccesslevel": 3,
"defaultusernodelimit": 0,
"defaultuserclientlimit": 0,
"allowedusers": [],
"allowedgroups": [
"*"
]
}
},
"listenport": 51823,
"locallistenport": 0,
"publickey": "xuLSz/ady+E6hK36cJiCzFp5tByBjnoZid54kHp9MVY=",
"endpoint": "134.209.145.214",
"postup": "",
"postdown": "",
"allowedips": null,
"persistentkeepalive": 20,
"ishub": "no",
"accesskey": "",
"interface": "nm-onaw",
"lastmodified": 1669114997,
"expdatetime": 1968594644,
"lastpeerupdate": 1668594644,
"lastcheckin": 1669114997,
"macaddress": "netmaker-server-1",
"password": "$2a$05$CrRlIbQkuQFQBs1A4wdhX.ar90lTRV9x.4IapTZV.FBaDmVyMukIG",
"network": "onaw",
"isrelayed": "no",
"ispending": "no",
"isrelay": "no",
"isdocker": "no",
"isk8s": "no",
"isegressgateway": "no",
"isingressgateway": "no",
"egressgatewayranges": null,
"egressgatewaynatenabled": "",
"egressgatewayrequest": {
"nodeid": "",
"netid": "",
"natenabled": "",
"ranges": null,
"interface": "",
"postup": "",
"postdown": ""
},
"relayaddrs": null,
"failovernode": "",
"ingressgatewayrange": "",
"ingressgatewayrange6": "",
"isstatic": "yes",
"udpholepunch": "no",
"dnson": "no",
"isserver": "yes",
"action": "noop",
"islocal": "no",
"localrange": "",
"ipforwarding": "yes",
"os": "linux",
"mtu": 1280,
"version": "v0.16.1",
"server": "",
"traffickeys": {
"mine": null,
"server": null
},
"firewallinuse": "iptables",
"internetgateway": "",
"connected": "yes",
"defaultacl": "yes",
"failover": "no"
}