Merge branch 'develop' into story/GRA-1252

This commit is contained in:
Alex Feiszli 2023-03-14 14:45:13 -04:00 committed by GitHub
commit cf6e4d0bde
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 449 additions and 136 deletions

View file

@ -4,10 +4,11 @@ ARG tags
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -w" -tags ${tags} . RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -w " -tags ${tags} .
# RUN go build -tags=ee . -o netmaker main.go # RUN go build -tags=ee . -o netmaker main.go
FROM alpine:3.16.2 FROM alpine:3.16.2
# add a c lib
# set the working directory # set the working directory
WORKDIR /root/ WORKDIR /root/
RUN mkdir -p /etc/netclient/config RUN mkdir -p /etc/netclient/config

View file

@ -27,6 +27,7 @@ services:
VERBOSITY: "1" VERBOSITY: "1"
MQ_PASSWORD: "REPLACE_MQ_PASSWORD" MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
MQ_USERNAME: "REPLACE_MQ_USERNAME" MQ_USERNAME: "REPLACE_MQ_USERNAME"
STUN_PORT: "3478"
ports: ports:
- "3478:3478/udp" - "3478:3478/udp"
netmaker-ui: netmaker-ui:

View file

@ -27,6 +27,7 @@ var HttpHandlers = []interface{}{
loggerHandlers, loggerHandlers,
hostHandlers, hostHandlers,
enrollmentKeyHandlers, enrollmentKeyHandlers,
legacyHandlers,
} }
// HandleRESTRequests - handles the rest requests // HandleRESTRequests - handles the rest requests

View file

@ -200,9 +200,13 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
// ready the response // ready the response
server := servercfg.GetServerInfo() server := servercfg.GetServerInfo()
server.TrafficKey = key server.TrafficKey = key
response := models.RegisterResponse{
ServerConf: server,
RequestedHost: newHost,
}
logger.Log(0, newHost.Name, newHost.ID.String(), "registered with Netmaker") logger.Log(0, newHost.Name, newHost.ID.String(), "registered with Netmaker")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(&server) json.NewEncoder(w).Encode(&response)
// notify host of changes, peer and node updates // notify host of changes, peer and node updates
go checkNetRegAndHostUpdate(enrollmentKey.Networks, &newHost) go checkNetRegAndHostUpdate(enrollmentKey.Networks, &newHost)
} }

View file

@ -17,6 +17,7 @@ import (
"github.com/gravitl/netmaker/models/promodels" "github.com/gravitl/netmaker/models/promodels"
"github.com/gravitl/netmaker/mq" "github.com/gravitl/netmaker/mq"
"github.com/skip2/go-qrcode" "github.com/skip2/go-qrcode"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
func extClientHandlers(r *mux.Router) { func extClientHandlers(r *mux.Router) {
@ -317,16 +318,22 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
} }
var extclient models.ExtClient var extclient models.ExtClient
var CustomExtClient models.CustomExtClient var customExtClient models.CustomExtClient
err := json.NewDecoder(r.Body).Decode(&CustomExtClient)
err := json.NewDecoder(r.Body).Decode(&customExtClient)
if err == nil { if err == nil {
if CustomExtClient.ClientID != "" && !validName(CustomExtClient.ClientID) { if customExtClient.ClientID != "" && !validName(customExtClient.ClientID) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest")) logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientID, "badrequest"))
return return
} }
extclient.ClientID = CustomExtClient.ClientID extclient.ClientID = customExtClient.ClientID
if len(customExtClient.PublicKey) > 0 {
if _, err := wgtypes.ParseKey(customExtClient.PublicKey); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(errInvalidExtClientPubKey, "badrequest"))
return
}
extclient.PublicKey = customExtClient.PublicKey
}
} }
extclient.Network = networkName extclient.Network = networkName
@ -350,16 +357,13 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
listenPort = host.ProxyListenPort listenPort = host.ProxyListenPort
} }
extclient.IngressGatewayEndpoint = host.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10) extclient.IngressGatewayEndpoint = host.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
extclient.Enabled = true extclient.Enabled = true
parentNetwork, err := logic.GetNetwork(networkName) parentNetwork, err := logic.GetNetwork(networkName)
if err == nil { // check if parent network default ACL is enabled (yes) or not (no) if err == nil { // check if parent network default ACL is enabled (yes) or not (no)
extclient.Enabled = parentNetwork.DefaultACL == "yes" extclient.Enabled = parentNetwork.DefaultACL == "yes"
} }
// check pro settings
err = logic.CreateExtClient(&extclient) if err = logic.CreateExtClient(&extclient); err != nil {
if err != nil {
logger.Log(0, r.Header.Get("user"), logger.Log(0, r.Header.Get("user"),
fmt.Sprintf("failed to create new ext client on network [%s]: %v", networkName, err)) fmt.Sprintf("failed to create new ext client on network [%s]: %v", networkName, err))
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
@ -389,8 +393,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
logger.Log(0, r.Header.Get("user"), "created new ext client on network", networkName) logger.Log(0, r.Header.Get("user"), "created new ext client on network", networkName)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
go func() { go func() {
err = mq.PublishPeerUpdate() if err := mq.PublishPeerUpdate(); err != nil {
if err != nil {
logger.Log(1, "error setting ext peers on "+nodeid+": "+err.Error()) logger.Log(1, "error setting ext peers on "+nodeid+": "+err.Error())
} }
if err := mq.PublishExtCLientDNS(&extclient); err != nil { if err := mq.PublishExtCLientDNS(&extclient); err != nil {

35
controllers/legacy.go Normal file
View file

@ -0,0 +1,35 @@
package controller
import (
"net/http"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
)
func legacyHandlers(r *mux.Router) {
r.HandleFunc("/api/v1/legacy/nodes", logic.SecurityCheck(true, http.HandlerFunc(wipeLegacyNodes))).Methods(http.MethodDelete)
}
// swagger:route DELETE /api/v1/legacy/nodes nodes wipeLegacyNodes
//
// Delete all legacy nodes from DB.
//
// Schemes: https
//
// Security:
// oauth
//
// Responses:
// 200: wipeLegacyNodesResponse
func wipeLegacyNodes(w http.ResponseWriter, r *http.Request) {
// Set header
w.Header().Set("Content-Type", "application/json")
if err := logic.RemoveAllLegacyNodes(); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
logger.Log(0, "error occurred when removing legacy nodes", err.Error())
}
logger.Log(0, r.Header.Get("user"), "wiped legacy nodes")
logic.ReturnSuccessResponse(w, r, "wiped all legacy nodes")
}

View file

@ -74,5 +74,30 @@ func migrate(w http.ResponseWriter, r *http.Request) {
} }
r.Body = io.NopCloser(strings.NewReader(string(payload))) r.Body = io.NopCloser(strings.NewReader(string(payload)))
r.ContentLength = int64(len(string(payload))) r.ContentLength = int64(len(string(payload)))
logger.Log(3, "deleteing legacy node", data.LegacyNodeID, legacyNode.ID, legacyNode.Name)
if err := database.DeleteRecord(database.NODES_TABLE_NAME, data.LegacyNodeID); err != nil {
logger.Log(0, "error deleting legacy node", legacyNode.Name, err.Error())
}
createNode(w, r) createNode(w, r)
//newly created node has same node id as legacy node allowing using legacyNode.ID in gateway creation
logger.Log(3, "re-creating legacy gateways")
if legacyNode.IsIngressGateway == "yes" {
if _, err := logic.CreateIngressGateway(legacyNode.Network, legacyNode.ID, false); err != nil {
logger.Log(0, "error creating ingress gateway during migration", err.Error())
}
}
if legacyNode.IsEgressGateway == "yes" {
if _, err := logic.CreateEgressGateway(legacyNode.EgressGatewayRequest); err != nil {
logger.Log(0, "error creating egress gateway during migration", err.Error())
}
}
if legacyNode.IsRelay == "yes" {
if _, _, err := logic.CreateRelay(models.RelayRequest{
NodeID: legacyNode.ID,
NetID: legacyNode.Network,
RelayAddrs: legacyNode.RelayAddrs,
}); err != nil {
logger.Log(0, "error creating relay during migration", err.Error())
}
}
} }

View file

@ -638,7 +638,7 @@ func createNode(w http.ResponseWriter, r *http.Request) {
Host: data.Host, Host: data.Host,
Peers: hostPeerUpdate.Peers, Peers: hostPeerUpdate.Peers,
} }
logger.Log(1, r.Header.Get("user"), "created new node", data.Host.Name, "on network", networkName) logger.Log(1, r.Header.Get("user"), "created new node", data.Host.Name, data.Node.ID.String(), "on network", networkName)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response) json.NewEncoder(w).Encode(response)
@ -976,8 +976,13 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
fromNode := r.Header.Get("requestfrom") == "node" fromNode := r.Header.Get("requestfrom") == "node"
node, err := logic.GetNodeByID(nodeid) node, err := logic.GetNodeByID(nodeid)
if err != nil { if err != nil {
logger.Log(0, "error retrieving node to delete", err.Error()) if logic.CheckAndRemoveLegacyNode(nodeid) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) logger.Log(0, "removed legacy node", nodeid)
logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
} else {
logger.Log(0, "error retrieving node to delete", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
}
return return
} }
if r.Header.Get("ismaster") != "yes" { if r.Header.Get("ismaster") != "yes" {

View file

@ -5,7 +5,10 @@ import (
"regexp" "regexp"
) )
var errInvalidExtClientID = errors.New("ext client ID must be alphanumderic and/or dashes") var (
errInvalidExtClientPubKey = errors.New("incorrect ext client public key")
errInvalidExtClientID = errors.New("ext client ID must be alphanumderic and/or dashes")
)
// allow only dashes and alphaneumeric for ext client and node names // allow only dashes and alphaneumeric for ext client and node names
func validName(name string) bool { func validName(name string) bool {

5
go.mod
View file

@ -42,7 +42,8 @@ require (
require ( require (
github.com/guumaster/tablewriter v0.0.10 github.com/guumaster/tablewriter v0.0.10
github.com/matryer/is v1.4.1 github.com/kr/pretty v0.3.0
github.com/matryer/is v1.4.0
github.com/olekukonko/tablewriter v0.0.5 github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.6.1 github.com/spf13/cobra v1.6.1
) )
@ -51,7 +52,9 @@ require (
cloud.google.com/go/compute/metadata v0.2.1 // indirect cloud.google.com/go/compute/metadata v0.2.1 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
) )

13
go.sum
View file

@ -17,6 +17,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -69,16 +70,18 @@ github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTx
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 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/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/matryer/is v1.4.0/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.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.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
@ -98,6 +101,7 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -107,7 +111,9 @@ github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sA
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f h1:BSnJgAfHzEp7o8PYJ7YfwAVHhqu7BYUTggcn/LGlUWY= github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f h1:BSnJgAfHzEp7o8PYJ7YfwAVHhqu7BYUTggcn/LGlUWY=
github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f/go.mod h1:UW/gxgQwSePTvL1KA8QEHsXeYHP4xkoXgbDdN781p34= github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f/go.mod h1:UW/gxgQwSePTvL1KA8QEHsXeYHP4xkoXgbDdN781p34=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@ -229,6 +235,7 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -117,14 +117,15 @@ func GetExtClient(clientid string, network string) (models.ExtClient, error) {
// CreateExtClient - creates an extclient // CreateExtClient - creates an extclient
func CreateExtClient(extclient *models.ExtClient) error { func CreateExtClient(extclient *models.ExtClient) error {
if extclient.PrivateKey == "" { if len(extclient.PublicKey) == 0 {
privateKey, err := wgtypes.GeneratePrivateKey() privateKey, err := wgtypes.GeneratePrivateKey()
if err != nil { if err != nil {
return err return err
} }
extclient.PrivateKey = privateKey.String() extclient.PrivateKey = privateKey.String()
extclient.PublicKey = privateKey.PublicKey().String() extclient.PublicKey = privateKey.PublicKey().String()
} else {
extclient.PrivateKey = "[ENTER PRIVATE KEY]"
} }
parentNetwork, err := GetNetwork(extclient.Network) parentNetwork, err := GetNetwork(extclient.Network)
@ -156,7 +157,6 @@ func CreateExtClient(extclient *models.ExtClient) error {
} }
extclient.LastModified = time.Now().Unix() extclient.LastModified = time.Now().Unix()
key, err := GetRecordKey(extclient.ClientID, extclient.Network) key, err := GetRecordKey(extclient.ClientID, extclient.Network)
if err != nil { if err != nil {
return err return err

View file

@ -208,7 +208,6 @@ func UpdateHostNetwork(h *models.Host, network string, add bool) (*models.Node,
} else { } else {
return nil, errors.New("host already part of network " + network) return nil, errors.New("host already part of network " + network)
} }
} }
} }
if !add { if !add {
@ -362,13 +361,13 @@ func GetRelatedHosts(hostID string) []models.Host {
// with the same endpoint have different listen ports // with the same endpoint have different listen ports
// in the case of 64535 hosts or more with same endpoint, ports will not be changed // in the case of 64535 hosts or more with same endpoint, ports will not be changed
func CheckHostPorts(h *models.Host) { func CheckHostPorts(h *models.Host) {
portsInUse := make(map[int]bool) portsInUse := make(map[int]bool, 0)
hosts, err := GetAllHosts() hosts, err := GetAllHosts()
if err != nil { if err != nil {
return return
} }
for _, host := range hosts { for _, host := range hosts {
if host.ID == h.ID { if host.ID.String() == h.ID.String() {
//skip self //skip self
continue continue
} }
@ -380,12 +379,18 @@ func CheckHostPorts(h *models.Host) {
} }
// iterate until port is not found or max iteration is reached // iterate until port is not found or max iteration is reached
for i := 0; portsInUse[h.ListenPort] && i < maxPort-minPort+1; i++ { for i := 0; portsInUse[h.ListenPort] && i < maxPort-minPort+1; i++ {
updatePort(&h.ListenPort) h.ListenPort++
if h.ListenPort > maxPort {
h.ListenPort = minPort
}
} }
// allocate h.ListenPort so it is unavailable to h.ProxyListenPort // allocate h.ListenPort so it is unavailable to h.ProxyListenPort
portsInUse[h.ListenPort] = true portsInUse[h.ListenPort] = true
for i := 0; portsInUse[h.ProxyListenPort] && i < maxPort-minPort+1; i++ { for i := 0; portsInUse[h.ProxyListenPort] && i < maxPort-minPort+1; i++ {
updatePort(&h.ProxyListenPort) h.ProxyListenPort++
if h.ProxyListenPort > maxPort {
h.ProxyListenPort = minPort
}
} }
} }
@ -409,10 +414,3 @@ func GetHostByNodeID(id string) *models.Host {
} }
return nil return nil
} }
func updatePort(p *int) {
*p++
if *p > maxPort {
*p = minPort
}
}

46
logic/legacy.go Normal file
View file

@ -0,0 +1,46 @@
package logic
import (
"encoding/json"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
)
// IsLegacyNode - checks if a node is legacy or not
func IsLegacyNode(nodeID string) bool {
record, err := database.FetchRecord(database.NODES_TABLE_NAME, nodeID)
if err != nil {
return false
}
var currentNode models.Node
var legacyNode models.LegacyNode
currentNodeErr := json.Unmarshal([]byte(record), &currentNode)
legacyNodeErr := json.Unmarshal([]byte(record), &legacyNode)
return currentNodeErr != nil && legacyNodeErr == nil
}
// CheckAndRemoveLegacyNode - checks for legacy node and removes
func CheckAndRemoveLegacyNode(nodeID string) bool {
if IsLegacyNode(nodeID) {
if err := database.DeleteRecord(database.NODES_TABLE_NAME, nodeID); err == nil {
return true
}
}
return false
}
// RemoveAllLegacyNodes - fetches all legacy nodes from DB and removes
func RemoveAllLegacyNodes() error {
records, err := database.FetchRecords(database.NODES_TABLE_NAME)
if err != nil {
return err
}
for k := range records {
if CheckAndRemoveLegacyNode(k) {
logger.Log(0, "removed legacy node", k)
}
}
return nil
}

View file

@ -198,7 +198,7 @@ func GetPeerUpdateForHost(ctx context.Context, network string, host *models.Host
peerConfig.ReplaceAllowedIPs = true peerConfig.ReplaceAllowedIPs = true
uselocal := false uselocal := false
if host.EndpointIP.String() == peerHost.EndpointIP.String() { if host.EndpointIP.String() == peerHost.EndpointIP.String() {
//peer is on same network // peer is on same network
// set to localaddress // set to localaddress
uselocal = true uselocal = true
if node.LocalAddress.IP == nil { if node.LocalAddress.IP == nil {
@ -295,10 +295,12 @@ func GetPeerUpdateForHost(ctx context.Context, network string, host *models.Host
if node.Network == network { // add to peers map for metrics if node.Network == network { // add to peers map for metrics
hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{ hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = models.IDandAddr{
ID: peer.ID.String(), ID: peer.ID.String(),
Address: peer.PrimaryAddress(), Address: peer.PrimaryAddress(),
Name: peerHost.Name, Name: peerHost.Name,
Network: peer.Network, Network: peer.Network,
Interfaces: peerHost.Interfaces,
ProxyListenPort: peerHost.ProxyListenPort,
} }
hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, nodePeer) hostPeerUpdate.NodePeers = append(hostPeerUpdate.NodePeers, nodePeer)
} }

View file

@ -34,6 +34,12 @@ type APIEnrollmentKey struct {
Tags []string `json:"tags"` Tags []string `json:"tags"`
} }
// RegisterResponse - the response to a successful enrollment register
type RegisterResponse struct {
ServerConf ServerConfig `json:"server_config"`
RequestedHost Host `json:"requested_host"`
}
// EnrollmentKey.IsValid - checks if the key is still valid to use // EnrollmentKey.IsValid - checks if the key is still valid to use
func (k *EnrollmentKey) IsValid() bool { func (k *EnrollmentKey) IsValid() bool {
if k == nil { if k == nil {

View file

@ -7,6 +7,21 @@ import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
// OS_Types - list of OS types Netmaker cares about
var OS_Types = struct {
Linux string
Windows string
Mac string
FreeBSD string
IoT string
}{
Linux: "linux",
Windows: "windows",
Mac: "darwin",
FreeBSD: "freebsd",
IoT: "iot",
}
// WIREGUARD_INTERFACE name of wireguard interface // WIREGUARD_INTERFACE name of wireguard interface
const WIREGUARD_INTERFACE = "netmaker" const WIREGUARD_INTERFACE = "netmaker"

View file

@ -28,11 +28,13 @@ type Metric struct {
// IDandAddr - struct to hold ID and primary Address // IDandAddr - struct to hold ID and primary Address
type IDandAddr struct { type IDandAddr struct {
ID string `json:"id" bson:"id" yaml:"id"` ID string `json:"id" bson:"id" yaml:"id"`
Address string `json:"address" bson:"address" yaml:"address"` Address string `json:"address" bson:"address" yaml:"address"`
Name string `json:"name" bson:"name" yaml:"name"` Name string `json:"name" bson:"name" yaml:"name"`
IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"` IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
Network string `json:"network" bson:"network" yaml:"network" validate:"network"` Network string `json:"network" bson:"network" yaml:"network" validate:"network"`
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
ProxyListenPort int `json:"proxy_listen_port" yaml:"proxy_listen_port"`
} }
// PeerMap - peer map for ids and addresses in metrics // PeerMap - peer map for ids and addresses in metrics

View file

@ -8,12 +8,17 @@ import (
"golang.zx2c4.com/wireguard/wgctrl/wgtypes" "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
) )
const PLACEHOLDER_KEY_TEXT = "ACCESS_KEY" const (
const PLACEHOLDER_TOKEN_TEXT = "ACCESS_TOKEN" // PLACEHOLDER_KEY_TEXT - access key placeholder text if option turned off
PLACEHOLDER_KEY_TEXT = "ACCESS_KEY"
// PLACEHOLDER_TOKEN_TEXT - access key token placeholder text if option turned off
PLACEHOLDER_TOKEN_TEXT = "ACCESS_TOKEN"
)
// CustomExtClient - struct for CustomExtClient params // CustomExtClient - struct for CustomExtClient params
type CustomExtClient struct { type CustomExtClient struct {
ClientID string `json:"clientid"` ClientID string `json:"clientid"`
PublicKey string `json:"publickey,omitempty"`
} }
// AuthParams - struct for auth params // AuthParams - struct for auth params

View file

@ -12,6 +12,10 @@ import (
) )
func decryptMsgWithHost(host *models.Host, msg []byte) ([]byte, error) { func decryptMsgWithHost(host *models.Host, msg []byte) ([]byte, error) {
if host.OS == models.OS_Types.IoT { // just pass along IoT messages
return msg, nil
}
trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() // get server private key trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() // get server private key
if trafficErr != nil { if trafficErr != nil {
return nil, trafficErr return nil, trafficErr
@ -41,6 +45,10 @@ func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
} }
func encryptMsg(host *models.Host, msg []byte) ([]byte, error) { func encryptMsg(host *models.Host, msg []byte) ([]byte, error) {
if host.OS == models.OS_Types.IoT {
return msg, nil
}
// fetch server public key to be certain hasn't changed in transit // fetch server public key to be certain hasn't changed in transit
trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() trafficKey, trafficErr := logic.RetrievePrivateTrafficKey()
if trafficErr != nil { if trafficErr != nil {

View file

@ -1,27 +1,38 @@
# Netmaker v0.18.3 # Netmaker v0.18.3
## **Do not attempt upgrade from 0.17.x quite yet** ## **Wait till out of pre-release to fully upgrade**
## whats new ## whats new
- Enrollment Keys, give the ability for an admin to enroll clients into multiple networks, can be unlimited, time, or usage based - Forced node deletions, if a host doesn't not receive message to delete a node, you can forcefully remove it by deleting it twice from UI/CLI
- EMQX broker support and better MQTT support in general - Allows user to remove orpahned Nodes + Hosts easier
- Now you must specify BROKER_ENDPOINT - EMQX ACLs, if using EMQX as broker, ACLs per host will be created, enhancing security around messages
- Also specify SERVER_BROKER_ENDPOINT, if not provided server will connect to broker over BROKER_ENDPOINT - You can now create ext clients with your own public key, but this feature will not be represented on current UI (new UI on the horizon)
- Thsi gives ability for user to specify any broker endpoint and use any protocal on clients desired, such as, `mqtts://mybroker.com:8083` - STUN is now represented as a list including your NM server + 2 we are hosting + 2 of googles (clients will only use 2) for better NAT detection
(we will still default to wss) - you specify which STUN servers to use with STUN_LIST env variable
## whats fixed ## whats fixed
- Fixed default ACL behavior, should work as expected - More Peer calculation improvements
- Peer calculations enhancement - JSON output on list commands for `nmctl`
- main routines share a context and docker stop/ctrl+c give expected results now - Upgrade script
- Github workflow edits - Ports set from server for Hosts on register/join are actually used
- Removed Deprecated Local Network Range from client + server - **CLients**
- More efficient Windows daemon handling
- Better peer route setting on clients
- Some commands involving the message queue on client have been fixed
- NFTables masquerading issue
- Some logging has been adjusted
- Migrations on Linux work for 0.17.x - 0.18.3
- EnrollmentKEys in an HA setup should function fine now
- Registration by enrollment key on client GUI
## known issues ## 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 - 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 - Caddy does not handle netmaker exporter well for EE
- Incorrect latency on metrics (EE) - Incorrect latency on metrics (EE)
- Swagger docs not up to date - Swagger docs not up to date
- Lengthy delay when you create an ext client
- issues connecting over IPv6 on Macs
- Nodes on same local network may not always connect
- Netclient GUI shows egress range(s) twice
- DNS entries are not sent after registration with EnrollmentKeys
- If you do NOT set STUN_LIST on server, it could lead to strange behavior on client

View file

@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
LATEST="testing"
# check_version - make sure current version is 0.17.1 before continuing # check_version - make sure current version is 0.17.1 before continuing
check_version() { check_version() {
IMG_TAG=$(yq -r '.services.netmaker.image' docker-compose.yml) IMG_TAG=$(yq -r '.services.netmaker.image' docker-compose.yml)
@ -200,9 +202,9 @@ collect_server_settings() {
esac esac
done done
STUN_NAME="stun.$SERVER_NAME" STUN_DOMAIN="stun.$SERVER_NAME"
echo "-----------------------------------------------------" echo "-----------------------------------------------------"
echo "Netmaker v0.18.3 requires a new DNS entry for $STUN_NAME." echo "Netmaker v0.18 requires a new DNS entry for $STUN_DOMAIN."
echo "Please confirm this is added to your DNS provider before continuing" echo "Please confirm this is added to your DNS provider before continuing"
echo "(note: this is not required if using an nip.io address)" echo "(note: this is not required if using an nip.io address)"
echo "-----------------------------------------------------" echo "-----------------------------------------------------"
@ -214,6 +216,7 @@ collect_node_settings() {
curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://$SERVER_HTTP_HOST/api/nodes | jq -c '[ .[] | select(.isserver=="yes") ]' > nodejson.tmp curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://$SERVER_HTTP_HOST/api/nodes | jq -c '[ .[] | select(.isserver=="yes") ]' > nodejson.tmp
NODE_LEN=$(jq length nodejson.tmp) NODE_LEN=$(jq length nodejson.tmp)
HAS_INGRESS="no" HAS_INGRESS="no"
HAS_RELAY="no"
if [ "$NODE_LEN" -gt 0 ]; then if [ "$NODE_LEN" -gt 0 ]; then
echo "===SERVER NODES===" echo "===SERVER NODES==="
for i in $(seq 1 $NODE_LEN); do for i in $(seq 1 $NODE_LEN); do
@ -251,21 +254,144 @@ collect_node_settings() {
echo "WARNING: Your server contains an Ingress Gateway. After upgrading, existing Ext Clients will be lost and must be recreated. Please confirm that you would like to continue." echo "WARNING: Your server contains an Ingress Gateway. After upgrading, existing Ext Clients will be lost and must be recreated. Please confirm that you would like to continue."
confirm confirm
fi fi
if [[ $HAS_RELAY == "yes" ]]; then
echo "WARNING: Your server contains a Relay. After upgrading, relay will be unset. Relay functionality has been moved to the 'host' level, and must be reconfigured once all machines are upgraded."
confirm
fi
}
# setup_caddy - updates Caddy with new info
setup_caddy() {
echo "backing up Caddyfile to /root/Caddyfile.backup"
cp /root/Caddyfile /root/Caddyfile.backup
if grep -wq "acme.zerossl.com/v2/DV90" Caddyfile; then
echo "zerossl already set, continuing"
else
echo "editing Caddyfile"
sed -i '0,/email/{s~email~acme_ca https://acme.zerossl.com/v2/DV90\n\t&~}' /root/Caddyfile
fi
cat <<EOT >> /root/Caddyfile
# STUN
https://$STUN_DOMAIN {
reverse_proxy netmaker:3478
}
EOT
}
# set_mq_credentials - sets mq credentials
set_mq_credentials() {
unset GET_MQ_USERNAME
unset GET_MQ_PASSWORD
unset CONFIRM_MQ_PASSWORD
echo "Enter Credentials For MQ..."
read -p "MQ Username (click 'enter' to use 'netmaker'): " GET_MQ_USERNAME
if [ -z "$GET_MQ_USERNAME" ]; then
echo "using default username for mq"
MQ_USERNAME="netmaker"
else
MQ_USERNAME="$GET_MQ_USERNAME"
fi
select domain_option in "Auto Generated Password" "Input Your Own Password"; do
case $REPLY in
1)
echo "generating random password for mq"
MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
break
;;
2)
while true
do
echo "Enter your Password For MQ: "
read -s GET_MQ_PASSWORD
echo "Enter your password again to confirm: "
read -s CONFIRM_MQ_PASSWORD
if [ ${GET_MQ_PASSWORD} != ${CONFIRM_MQ_PASSWORD} ]; then
echo "wrong password entered, try again..."
continue
fi
MQ_PASSWORD="$GET_MQ_PASSWORD"
echo "MQ Password Saved Successfully!!"
break
done
break
;;
*) echo "invalid option $REPLY";;
esac
done
} }
# set_compose - set compose file with proper values # set_compose - set compose file with proper values
set_compose() { set_compose() {
# DEV_TEMP - Temporary instructions for testing set_mq_credentials
sed -i "s/v0.17.1/testing/g" /root/docker-compose.yml
echo "retrieving updated wait script and mosquitto conf"
rm /root/wait.sh
rm /root/mosquitto.conf
# DEV_TEMP
wget -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/develop/docker/wait.sh
# RELEASE_REPLACE - Use this once release is ready
# wget -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
chmod +x /root/wait.sh
# DEV_TEMP
wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/develop/docker/mosquitto.conf
# RELEASE_REPLACE - Use this once release is ready
# wget -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
chmod +x /root/mosquitto.conf
# DEV_TEMP
sed -i "s/v0.17.1/$LATEST/g" /root/docker-compose.yml
STUN_PORT=3478
# RELEASE_REPLACE - Use this once release is ready # RELEASE_REPLACE - Use this once release is ready
#sed -i "s/v0.17.1/v0.18.3/g" /root/docker-compose.yml #sed -i "s/v0.17.1/v0.18.3/g" /root/docker-compose.yml
yq ".services.netmaker.environment.SERVER_NAME = \"$SERVER_NAME\"" -i /root/docker-compose.yml yq ".services.netmaker.environment.SERVER_NAME = \"$SERVER_NAME\"" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"BROKER_NAME\": \"$BROKER_NAME\"}" -i /root/docker-compose.yml yq ".services.netmaker.environment += {\"BROKER_ENDPOINT\": \"wss://$BROKER_NAME\"}" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"STUN_NAME\": \"$STUN_NAME\"}" -i /root/docker-compose.yml yq ".services.netmaker.environment += {\"SERVER_BROKER_ENDPOINT\": \"ws://mq:1883\"}" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"STUN_PORT\": \"3478\"}" -i /root/docker-compose.yml yq ".services.netmaker.environment += {\"STUN_LIST\": \"$STUN_DOMAIN:$STUN_PORT,stun1.netmaker.io:3478,stun2.netmaker.io:3478,stun1.l.google.com:19302,stun2.l.google.com:19302\"}" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i /root/docker-compose.yml
yq ".services.netmaker.environment += {\"STUN_PORT\": \"$STUN_PORT\"}" -i /root/docker-compose.yml
yq ".services.netmaker.ports += \"3478:3478/udp\"" -i /root/docker-compose.yml yq ".services.netmaker.ports += \"3478:3478/udp\"" -i /root/docker-compose.yml
yq ".services.mq.environment += {\"MQ_PASSWORD\": \"$MQ_PASSWORD\"}" -i /root/docker-compose.yml
yq ".services.mq.environment += {\"MQ_USERNAME\": \"$MQ_USERNAME\"}" -i /root/docker-compose.yml
#remove unnecessary ports
yq eval 'del( .services.netmaker.ports[] | select(. == "51821*") )' -i /root/docker-compose.yml
yq eval 'del( .services.mq.ports[] | select(. == "8883*") )' -i /root/docker-compose.yml
yq eval 'del( .services.mq.ports[] | select(. == "1883*") )' -i /root/docker-compose.yml
yq eval 'del( .services.mq.expose[] | select(. == "8883*") )' -i /root/docker-compose.yml
yq eval 'del( .services.mq.expose[] | select(. == "1883*") )' -i /root/docker-compose.yml
# delete unnecessary compose sections
yq eval 'del(.services.netmaker.cap_add)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.sysctls)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.MQ_ADMIN_PASSWORD)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.MQ_HOST)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.MQ_PORT)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.MQ_SERVER_PORT)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.PORT_FORWARD_SERVICES)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.CLIENT_MODE)' -i /root/docker-compose.yml
yq eval 'del(.services.netmaker.environment.HOST_NETWORK)' -i /root/docker-compose.yml
yq eval 'del(.services.mq.environment.NETMAKER_SERVER_HOST)' -i /root/docker-compose.yml
yq eval 'del( .services.netmaker.volumes[] | select(. == "mosquitto_data*") )' -i /root/docker-compose.yml
yq eval 'del( .services.mq.volumes[] | select(. == "mosquitto_data*") )' -i /root/docker-compose.yml
yq eval 'del( .volumes.mosquitto_data )' -i /root/docker-compose.yml
} }
# start_containers - run docker-compose up -d # start_containers - run docker-compose up -d
@ -298,49 +424,36 @@ test_caddy() {
done done
} }
# setup_netclient - installs netclient locally # setup_netclient - adds netclient to docker-compose
setup_netclient() { setup_netclient() {
# DEV_TEMP - Temporary instructions for testing # yq ".services.netclient += {\"container_name\": \"netclient\"}" -i /root/docker-compose.yml
wget https://fileserver.netmaker.org/testing/netclient # yq ".services.netclient += {\"image\": \"gravitl/netclient:testing\"}" -i /root/docker-compose.yml
chmod +x netclient # yq ".services.netclient += {\"hostname\": \"netmaker-1\"}" -i /root/docker-compose.yml
./netclient install # yq ".services.netclient += {\"network_mode\": \"host\"}" -i /root/docker-compose.yml
# yq ".services.netclient.depends_on += [\"netmaker\"]" -i /root/docker-compose.yml
# yq ".services.netclient += {\"restart\": \"always\"}" -i /root/docker-compose.yml
# yq ".services.netclient.environment += {\"TOKEN\": \"$KEY\"}" -i /root/docker-compose.yml
# yq ".services.netclient.volumes += [\"/etc/netclient:/etc/netclient\"]" -i /root/docker-compose.yml
# yq ".services.netclient.cap_add += [\"NET_ADMIN\"]" -i /root/docker-compose.yml
# yq ".services.netclient.cap_add += [\"NET_RAW\"]" -i /root/docker-compose.yml
# yq ".services.netclient.cap_add += [\"SYS_MODULE\"]" -i /root/docker-compose.yml
# RELEASE_REPLACE - Use this once release is ready # docker-compose up -d
# if [ -f /etc/debian_version ]; then
# curl -sL 'https://apt.netmaker.org/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/netclient.asc set +e
# curl -sL 'https://apt.netmaker.org/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/netclient.list netclient uninstall
# sudo apt update set -e
# sudo apt install netclient
# elif [ -f /etc/centos-release ]; then wget -O /tmp/netclient https://fileserver.netmaker.org/$LATEST/netclient
# curl -sL 'https://rpm.netmaker.org/gpg.key' | sudo tee /tmp/gpg.key
# curl -sL 'https://rpm.netmaker.org/netclient-repo' | sudo tee /etc/yum.repos.d/netclient.repo chmod +x /tmp/netclient
# sudo rpm --import /tmp/gpg.key /tmp/netclient install
# sudo dnf check-update netclient join -t $KEY
# sudo dnf install netclient
# elif [ -f /etc/fedora-release ]; then echo "waiting for client to become available"
# curl -sL 'https://rpm.netmaker.org/gpg.key' | sudo tee /tmp/gpg.key wait_seconds 10
# curl -sL 'https://rpm.netmaker.org/netclient-repo' | sudo tee /etc/yum.repos.d/netclient.repo
# sudo rpm --import /tmp/gpg.key
# sudo dnf check-update
# sudo dnf install netclient
# elif [ -f /etc/redhat-release ]; then
# curl -sL 'https://rpm.netmaker.org/gpg.key' | sudo tee /tmp/gpg.key
# curl -sL 'https://rpm.netmaker.org/netclient-repo' | sudo tee /etc/yum.repos.d/netclient.repo
# sudo rpm --import /tmp/gpg.key
# sudo dnf check-update(
# sudo dnf install netclient
# elif [ -f /etc/arch-release ]; then
# yay -S netclient
# else
# echo "OS not supported for automatic install"
# exit 1
# fi
# if [ -z "${install_cmd}" ]; then
# echo "OS unsupported for automatic dependency install"
# exit 1
# fi
} }
# setup_nmctl - pulls nmctl and makes it executable # setup_nmctl - pulls nmctl and makes it executable
@ -365,10 +478,16 @@ setup_nmctl() {
# join_networks - joins netclient into the networks using old settings # join_networks - joins netclient into the networks using old settings
join_networks() { join_networks() {
NODE_LEN=$(jq length nodejson.tmp) NODE_LEN=$(jq length nodejson.tmp)
HAS_INGRESS="no"
if [ "$NODE_LEN" -gt 0 ]; then if [ "$NODE_LEN" -gt 0 ]; then
for i in $(seq 1 $NODE_LEN); do for i in $(seq 1 $NODE_LEN); do
HAS_INGRESS="no"
HAS_EGRESS="no"
EGRESS_RANGES=""
HAS_RELAY="no"
RELAY_ADDRS=""
HAS_FAILOVER="no"
NUM=$(($i-1)) NUM=$(($i-1))
NETWORK=$(jq -r ".[$NUM].network" ./nodejson.tmp) NETWORK=$(jq -r ".[$NUM].network" ./nodejson.tmp)
echo " joining network $NETWORK with following settings. Please confirm:" echo " joining network $NETWORK with following settings. Please confirm:"
@ -379,7 +498,9 @@ join_networks() {
echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)" echo " is egress: $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp)"
if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then if [[ $(jq -r ".[$NUM].isegressgateway" ./nodejson.tmp) == "yes" ]]; then
HAS_EGRESS="yes" HAS_EGRESS="yes"
echo " egress range: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp)" echo " egress ranges: $(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')"
EGRESS_RANGES=$(jq -r ".[$NUM].egressgatewayranges" ./nodejson.tmp | tr -d '[]\n"[:space:]')
fi fi
echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)" echo " is ingress: $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp)"
if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then if [[ $(jq -r ".[$NUM].isingressgateway" ./nodejson.tmp) == "yes" ]]; then
@ -397,27 +518,26 @@ join_networks() {
echo " ------------" echo " ------------"
confirm confirm
echo "running command: ./nmctl keys create $NETWORK 1"
KEY_JSON=$(./nmctl keys create $NETWORK 1)
KEY=$(echo $KEY_JSON | jq -r .accessstring)
echo "join key created: $KEY" if [[ $NUM -eq 0 ]]; then
echo "running command: ./nmctl keys create $NETWORK 1"
KEY_JSON=$(./nmctl keys create $NETWORK 1)
KEY=$(echo $KEY_JSON | jq -r .accessstring)
echo "join key created: $KEY"
setup_netclient
else
HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id)
./nmctl host add_network $HOST_ID $NETWORK
fi
NAME=$(jq -r ".[$NUM].name" ./nodejson.tmp) NAME=$(jq -r ".[$NUM].name" ./nodejson.tmp)
ADDRESS=$(jq -r ".[$NUM].address" ./nodejson.tmp) ADDRESS=$(jq -r ".[$NUM].address" ./nodejson.tmp)
ADDRESS6=$(jq -r ".[$NUM].address6" ./nodejson.tmp) ADDRESS6=$(jq -r ".[$NUM].address6" ./nodejson.tmp)
if [[ ! -z "$ADDRESS6" ]]; then echo "wait 10 seconds for netclient to be ready"
echo "joining with command: netclient join -t $KEY --name=$NAME --address=$ADDRESS --address6=$ADDRESS6 sleep 10
"
confirm
netclient join -t $KEY --name=$NAME --address=$ADDRESS --address6=$ADDRESS6
else
echo "joining with command: netclient join -t $KEY --name=$NAME --address=$ADDRESS"
confirm
netclient join -t $KEY --name=$NAME --address=$ADDRESS
fi
NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .$NETWORK.commonnode.id) NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .$NETWORK.commonnode.id)
echo "join complete. New node ID: $NODE_ID" echo "join complete. New node ID: $NODE_ID"
if [[ $NUM -eq 0 ]]; then if [[ $NUM -eq 0 ]]; then
@ -425,13 +545,17 @@ join_networks() {
echo "For first join, making host a default" echo "For first join, making host a default"
echo "Host ID: $HOST_ID" echo "Host ID: $HOST_ID"
# set as a default host # set as a default host
# TODO - this command is not working set +e
./nmctl host update $HOST_ID --default ./nmctl host update $HOST_ID --default
sleep 2
set -e
fi fi
# create an egress if necessary # create an egress if necessary
if [[ $HAS_EGRESS == "yes" ]]; then if [[ $HAS_EGRESS == "yes" ]]; then
echo "Egress is currently unimplemented. Wait for 0.18.3" echo "creating egress"
./nmctl node create_egress $NETWORK $NODE_ID $EGRESS_RANGES
sleep 2
fi fi
echo "HAS INGRESS: $HAS_INGRESS" echo "HAS INGRESS: $HAS_INGRESS"
@ -440,16 +564,19 @@ join_networks() {
if [[ $HAS_FAILOVER == "yes" ]]; then if [[ $HAS_FAILOVER == "yes" ]]; then
echo "creating ingress and failover..." echo "creating ingress and failover..."
./nmctl node create_ingress $NETWORK $NODE_ID --failover ./nmctl node create_ingress $NETWORK $NODE_ID --failover
sleep 2
else else
echo "creating ingress..." echo "creating ingress..."
./nmctl node create_ingress $NETWORK $NODE_ID ./nmctl node create_ingress $NETWORK $NODE_ID
sleep 2
fi fi
fi fi
# relay # relay
if [[ $HAS_RELAY == "yes" ]]; then if [[ $HAS_RELAY == "yes" ]]; then
echo "creating relay..." echo "cannot recreate relay; relay functionality moved to host"
./nmctl node create_relay $NETWORK $NODE_ID $RELAY_ADDRS # ./nmctl node create_relay $NETWORK $NODE_ID $RELAY_ADDRS
# sleep 2
fi fi
done done
@ -462,7 +589,7 @@ join_networks() {
cat << "EOF" cat << "EOF"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The Netmaker Upgrade Script: Upgrading to v0.18.3 so you don't have to! The Netmaker Upgrade Script: Upgrading to v0.18 so you don't have to!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EOF EOF
@ -499,12 +626,19 @@ collect_node_settings
echo "...backing up docker compose to docker-compose.yml.backup" echo "...backing up docker compose to docker-compose.yml.backup"
cp /root/docker-compose.yml /root/docker-compose.yml.backup cp /root/docker-compose.yml /root/docker-compose.yml.backup
echo "...setting Caddyfile values"
setup_caddy
echo "...setting docker-compose values" echo "...setting docker-compose values"
set_compose set_compose
echo "...starting containers" echo "...starting containers"
start_containers start_containers
echo "...remove old mosquitto data"
# TODO - yq is not removing volume from docker compose
# docker volume rm root_mosquitto_data
wait_seconds 3 wait_seconds 3
echo "..testing Caddy proxy" echo "..testing Caddy proxy"
@ -515,11 +649,9 @@ echo "..testing Netmaker health"
# netmaker_health_check # netmaker_health_check
# wait_seconds 2 # wait_seconds 2
echo "...setting up netclient (this may take a minute, be patient)"
setup_netclient
wait_seconds 2 wait_seconds 2
echo "...join networks" echo "...setup netclient"
join_networks join_networks
echo "-----------------------------------------------------------------" echo "-----------------------------------------------------------------"