merge develop

This commit is contained in:
0xdcarns 2023-03-06 10:28:54 -05:00
commit 48aad9780c
12 changed files with 235 additions and 11 deletions

View file

@ -0,0 +1,47 @@
package enrollment_key
import (
"strings"
"github.com/gravitl/netmaker/cli/functions"
"github.com/gravitl/netmaker/models"
"github.com/spf13/cobra"
)
var (
expiration int
usesRemaining int
networks string
unlimited bool
tags string
)
var enrollmentKeyCreateCmd = &cobra.Command{
Use: "create",
Args: cobra.NoArgs,
Short: "Create an enrollment key",
Long: `Create an enrollment key`,
Run: func(cmd *cobra.Command, args []string) {
enrollKey := &models.APIEnrollmentKey{
Expiration: int64(expiration),
UsesRemaining: usesRemaining,
Unlimited: unlimited,
}
if networks != "" {
enrollKey.Networks = strings.Split(networks, ",")
}
if tags != "" {
enrollKey.Tags = strings.Split(tags, ",")
}
functions.PrettyPrint(functions.CreateEnrollmentKey(enrollKey))
},
}
func init() {
enrollmentKeyCreateCmd.Flags().IntVar(&expiration, "expiration", 0, "Expiration time of the key in UNIX timestamp format")
enrollmentKeyCreateCmd.Flags().IntVar(&usesRemaining, "uses", 0, "Number of times this key can be used")
enrollmentKeyCreateCmd.Flags().StringVar(&networks, "networks", "", "Comma-separated list of networks which the enrollment key can access")
enrollmentKeyCreateCmd.Flags().BoolVar(&unlimited, "unlimited", false, "Should the key have unlimited uses ?")
enrollmentKeyCreateCmd.Flags().StringVar(&tags, "tags", "", "Comma-separated list of any additional tags")
rootCmd.AddCommand(enrollmentKeyCreateCmd)
}

View file

@ -0,0 +1,23 @@
package enrollment_key
import (
"fmt"
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var enrollmentKeyDeleteCmd = &cobra.Command{
Use: "delete keyID",
Args: cobra.ExactArgs(1),
Short: "Delete an enrollment key",
Long: `Delete an enrollment key`,
Run: func(cmd *cobra.Command, args []string) {
functions.DeleteEnrollmentKey(args[0])
fmt.Println("Enrollment key ", args[0], " deleted")
},
}
func init() {
rootCmd.AddCommand(enrollmentKeyDeleteCmd)
}

View file

@ -0,0 +1,20 @@
package enrollment_key
import (
"github.com/gravitl/netmaker/cli/functions"
"github.com/spf13/cobra"
)
var enrollmentKeyListCmd = &cobra.Command{
Use: "list",
Args: cobra.NoArgs,
Short: "List enrollment keys",
Long: `List enrollment keys`,
Run: func(cmd *cobra.Command, args []string) {
functions.PrettyPrint(functions.GetEnrollmentKeys())
},
}
func init() {
rootCmd.AddCommand(enrollmentKeyListCmd)
}

View file

@ -0,0 +1,28 @@
package enrollment_key
import (
"os"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "enrollment_key",
Short: "Manage Enrollment Keys",
Long: `Manage Enrollment Keys`,
}
// GetRoot returns the root subcommand
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)
}
}

View file

@ -6,6 +6,7 @@ import (
"github.com/gravitl/netmaker/cli/cmd/acl"
"github.com/gravitl/netmaker/cli/cmd/context"
"github.com/gravitl/netmaker/cli/cmd/dns"
"github.com/gravitl/netmaker/cli/cmd/enrollment_key"
"github.com/gravitl/netmaker/cli/cmd/ext_client"
"github.com/gravitl/netmaker/cli/cmd/host"
"github.com/gravitl/netmaker/cli/cmd/keys"
@ -55,4 +56,5 @@ func init() {
rootCmd.AddCommand(metrics.GetRoot())
rootCmd.AddCommand(network_user.GetRoot())
rootCmd.AddCommand(host.GetRoot())
rootCmd.AddCommand(enrollment_key.GetRoot())
}

View file

@ -0,0 +1,22 @@
package functions
import (
"net/http"
"github.com/gravitl/netmaker/models"
)
// CreateEnrollmentKey - create an enrollment key
func CreateEnrollmentKey(key *models.APIEnrollmentKey) *models.EnrollmentKey {
return request[models.EnrollmentKey](http.MethodPost, "/api/v1/enrollment-keys", key)
}
// GetEnrollmentKeys - gets all enrollment keys
func GetEnrollmentKeys() *[]models.EnrollmentKey {
return request[[]models.EnrollmentKey](http.MethodGet, "/api/v1/enrollment-keys", nil)
}
// DeleteEnrollmentKey - delete an enrollment key
func DeleteEnrollmentKey(keyID string) {
request[any](http.MethodDelete, "/api/v1/enrollment-keys/"+keyID, nil)
}

4
go.mod
View file

@ -13,7 +13,7 @@ require (
github.com/mattn/go-sqlite3 v1.14.16
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.2
github.com/txn2/txeh v1.3.0
golang.org/x/crypto v0.6.0
golang.org/x/net v0.6.0 // indirect
@ -42,7 +42,7 @@ require (
require (
github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.0
github.com/matryer/is v1.4.1
github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.6.1
)

8
go.sum
View file

@ -77,8 +77,8 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
@ -134,8 +134,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/txn2/txeh v1.3.0 h1:vnbv63htVMZCaQgLqVBxKvj2+HHHFUzNW7I183zjg3E=
github.com/txn2/txeh v1.3.0/go.mod h1:O7M6gUTPeMF+vsa4c4Ipx3JDkOYrruB1Wry8QRsMcw8=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=

View file

@ -395,6 +395,21 @@ func HostExists(h *models.Host) bool {
return (err != nil && !database.IsEmptyRecord(err)) || (err == nil)
}
// GetHostByNodeID - returns a host if found to have a node's ID, else nil
func GetHostByNodeID(id string) *models.Host {
hosts, err := GetAllHosts()
if err != nil {
return nil
}
for i := range hosts {
h := hosts[i]
if StringSliceContains(h.Nodes, id) {
return &h
}
}
return nil
}
func updatePort(p *int) {
*p++
if *p > maxPort {

View file

@ -83,8 +83,9 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
// DeleteNode - marks node for deletion (and adds to zombie list) if called by UI or deletes node if called by node
func DeleteNode(node *models.Node, purge bool) error {
alreadyDeleted := node.PendingDelete || node.Action == models.NODE_DELETE
node.Action = models.NODE_DELETE
if !purge {
if !purge && !alreadyDeleted {
newnode := *node
newnode.PendingDelete = true
if err := UpdateNode(node, &newnode); err != nil {
@ -93,8 +94,15 @@ func DeleteNode(node *models.Node, purge bool) error {
newZombie <- node.ID
return nil
}
if alreadyDeleted {
logger.Log(1, "forcibly deleting node", node.ID.String())
}
host, err := GetHost(node.HostID.String())
if err != nil {
logger.Log(1, "no host found for node", node.ID.String(), "deleting..")
if delErr := deleteNodeByID(node); delErr != nil {
logger.Log(0, "failed to delete node", node.ID.String(), delErr.Error())
}
return err
}
if err := DissasociateNodeFromHost(node, host); err != nil {

View file

@ -6,6 +6,7 @@ import (
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
@ -30,9 +31,47 @@ func Ping(client mqtt.Client, msg mqtt.Message) {
node, err := logic.GetNodeByID(id)
if err != nil {
logger.Log(3, "mq-ping error getting node: ", err.Error())
_, err := database.FetchRecord(database.NODES_TABLE_NAME, id)
node, err := logic.GetNodeByID(id)
if err != nil {
logger.Log(3, "error reading database", err.Error())
logger.Log(3, "mq-ping error getting node: ", err.Error())
if database.IsEmptyRecord(err) {
h := logic.GetHostByNodeID(id) // check if a host is still associated
if h != nil { // inform host that node should be removed
fakeNode := models.Node{}
fakeNode.ID, _ = uuid.Parse(id)
fakeNode.Action = models.NODE_DELETE
fakeNode.PendingDelete = true
if err := NodeUpdate(&fakeNode); err != nil {
logger.Log(0, "failed to inform host", h.Name, h.ID.String(), "to remove node", id, err.Error())
}
}
}
return
}
decrypted, decryptErr := decryptMsg(&node, msg.Payload())
if decryptErr != nil {
logger.Log(0, "error decrypting when updating node ", node.ID.String(), decryptErr.Error())
return
}
var checkin models.NodeCheckin
if err := json.Unmarshal(decrypted, &checkin); err != nil {
logger.Log(1, "error unmarshaling payload ", err.Error())
return
}
host, err := logic.GetHost(node.HostID.String())
if err != nil {
logger.Log(0, "error retrieving host for node ", node.ID.String(), err.Error())
return
}
node.SetLastCheckIn()
host.Version = checkin.Version
node.Connected = checkin.Connected
host.Interfaces = checkin.Ifaces
for i := range host.Interfaces {
host.Interfaces[i].AddressString = host.Interfaces[i].Address.String()
}
if err := logic.UpdateNode(&node, &node); err != nil {
logger.Log(0, "error updating node", node.ID.String(), " on checkin", err.Error())
return
}

View file

@ -1,7 +1,27 @@
# Netmaker v0.18.1
# Netmaker v0.18.2
## **Do not attempt upgrade from 0.17.x quite yet**
## whats new
- Enrollment Keys, give the ability for an admin to enroll clients into multiple networks, can be unlimited, time, or usage based
- EMQX broker support and better MQTT support in general
- Now you must specify BROKER_ENDPOINT
- Also specify SERVER_BROKER_ENDPOINT, if not provided server will connect to broker over BROKER_ENDPOINT
- Thsi gives ability for user to specify any broker endpoint and use any protocal on clients desired, such as, `mqtts://mybroker.com:8083`
(we will still default to wss)
## whats fixed
- Fixed default ACL behavior, should work as expected
- Peer calculations enhancement
- main routines share a context and docker stop/ctrl+c give expected results now
- Github workflow edits
- Removed Deprecated Local Network Range from client + server
## known issues
- EnrollmentKeys may not function as intended in an HA setup
- If a host does not receive a message to delete a node, it could become orphaned and un-deletable
- Network interface routes may be removed after sometime/unintended network update
- Upgrade script does not handle clients
- Caddy does not handle netmaker exporter well for EE
- Incorrect latency on metrics (EE)
- Swagger docs not up to date