mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 15:26:04 +08:00
merge develop
This commit is contained in:
commit
48aad9780c
47
cli/cmd/enrollment_key/create.go
Normal file
47
cli/cmd/enrollment_key/create.go
Normal 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)
|
||||
}
|
23
cli/cmd/enrollment_key/delete.go
Normal file
23
cli/cmd/enrollment_key/delete.go
Normal 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)
|
||||
}
|
20
cli/cmd/enrollment_key/list.go
Normal file
20
cli/cmd/enrollment_key/list.go
Normal 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)
|
||||
}
|
28
cli/cmd/enrollment_key/root.go
Normal file
28
cli/cmd/enrollment_key/root.go
Normal 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)
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
|
|
22
cli/functions/enrollment_keys.go
Normal file
22
cli/functions/enrollment_keys.go
Normal 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
4
go.mod
|
@ -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
8
go.sum
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
24
release.md
24
release.md
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue