mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-08 14:15:25 +08:00
Merge branch 'develop' into gra-1088_dns_updates
This commit is contained in:
commit
bd9cf14c02
57 changed files with 547 additions and 1138 deletions
1
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
|
@ -31,6 +31,7 @@ body:
|
|||
label: Version
|
||||
description: What version are you running?
|
||||
options:
|
||||
- v0.18.0
|
||||
- v0.17.1
|
||||
- v0.17.0
|
||||
- v0.16.3
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
<p align="center">
|
||||
<a href="https://github.com/gravitl/netmaker/releases">
|
||||
<img src="https://img.shields.io/badge/Version-0.17.1-informational?style=flat-square" />
|
||||
<img src="https://img.shields.io/badge/Version-0.18.0-informational?style=flat-square" />
|
||||
</a>
|
||||
<a href="https://hub.docker.com/r/gravitl/netmaker/tags">
|
||||
<img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />
|
||||
|
|
20
cli/cmd/host/add_network.go
Normal file
20
cli/cmd/host/add_network.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package host
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/cli/functions"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var addHostNetworkCmd = &cobra.Command{
|
||||
Use: "add_network HostID Network",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Short: "Add a network to a host",
|
||||
Long: `Add a network to a host`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
functions.PrettyPrint(functions.AddHostToNetwork(args[0], args[1]))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(addHostNetworkCmd)
|
||||
}
|
20
cli/cmd/host/delete_network.go
Normal file
20
cli/cmd/host/delete_network.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package host
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/cli/functions"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var deleteHostNetworkCmd = &cobra.Command{
|
||||
Use: "delete_network HostID Network",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Short: "Delete a network from a host",
|
||||
Long: `Delete a network from a host`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
functions.PrettyPrint(functions.DeleteHostFromNetwork(args[0], args[1]))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(deleteHostNetworkCmd)
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package host
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/gravitl/netmaker/cli/functions"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var hostUpdateNetworksCmd = &cobra.Command{
|
||||
Use: "update_network HostID Networks(comma separated list)",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Short: "Update a host's networks",
|
||||
Long: `Update a host's networks`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
functions.PrettyPrint(functions.UpdateHostNetworks(args[0], strings.Split(args[1], ",")))
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(hostUpdateNetworksCmd)
|
||||
}
|
|
@ -26,11 +26,14 @@ func UpdateHost(hostID string, body *models.ApiHost) *models.ApiHost {
|
|||
return request[models.ApiHost](http.MethodPut, "/api/hosts/"+hostID, body)
|
||||
}
|
||||
|
||||
// UpdateHostNetworks - update a host's networks
|
||||
func UpdateHostNetworks(hostID string, networks []string) *hostNetworksUpdatePayload {
|
||||
return request[hostNetworksUpdatePayload](http.MethodPut, "/api/hosts/"+hostID+"/networks", &hostNetworksUpdatePayload{
|
||||
Networks: networks,
|
||||
})
|
||||
// AddHostToNetwork - add a network to host
|
||||
func AddHostToNetwork(hostID, network string) *hostNetworksUpdatePayload {
|
||||
return request[hostNetworksUpdatePayload](http.MethodPost, "/api/hosts/"+hostID+"/networks/"+network, nil)
|
||||
}
|
||||
|
||||
// DeleteHostFromNetwork - deletes a network from host
|
||||
func DeleteHostFromNetwork(hostID, network string) *hostNetworksUpdatePayload {
|
||||
return request[hostNetworksUpdatePayload](http.MethodDelete, "/api/hosts/"+hostID+"/networks/"+network, nil)
|
||||
}
|
||||
|
||||
// CreateRelay - turn a host into a relay
|
||||
|
|
|
@ -3,14 +3,15 @@ version: "3.4"
|
|||
services:
|
||||
netmaker:
|
||||
container_name: netmaker
|
||||
image: gravitl/netmaker:v0.17.1-ee
|
||||
image: gravitl/netmaker:v0.18.0-ee
|
||||
restart: always
|
||||
volumes:
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
- sqldata:/root/data
|
||||
- mosquitto_data:/etc/netmaker
|
||||
environment:
|
||||
SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN"
|
||||
BROKER_NAME: "broker.NETMAKER_BASE_DOMAIN"
|
||||
SERVER_NAME: "NETMAKER_BASE_DOMAIN"
|
||||
STUN_DOMAIN: "stun.NETMAKER_BASE_DOMAIN"
|
||||
SERVER_HOST: "SERVER_PUBLIC_IP"
|
||||
SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
|
||||
COREDNS_ADDR: "SERVER_PUBLIC_IP"
|
||||
|
@ -25,16 +26,18 @@ services:
|
|||
MQ_HOST: "mq"
|
||||
MQ_PORT: "443"
|
||||
MQ_SERVER_PORT: "1883"
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME"
|
||||
STUN_PORT: "3478"
|
||||
VERBOSITY: "1"
|
||||
METRICS_EXPORTER: "on"
|
||||
LICENSE_KEY: "YOUR_LICENSE_KEY"
|
||||
NETMAKER_ACCOUNT_ID: "YOUR_ACCOUNT_ID"
|
||||
MQ_ADMIN_PASSWORD: "REPLACE_MQ_ADMIN_PASSWORD"
|
||||
ports:
|
||||
- "51821-51830:51821-51830/udp"
|
||||
- "3478:3478/udp"
|
||||
netmaker-ui:
|
||||
container_name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.17.1
|
||||
image: gravitl/netmaker-ui:v0.18.0
|
||||
depends_on:
|
||||
- netmaker
|
||||
links:
|
||||
|
@ -70,11 +73,11 @@ services:
|
|||
restart: unless-stopped
|
||||
command: ["/mosquitto/config/wait.sh"]
|
||||
environment:
|
||||
NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME"
|
||||
volumes:
|
||||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
- /root/wait.sh:/mosquitto/config/wait.sh
|
||||
- mosquitto_data:/mosquitto/data
|
||||
- mosquitto_logs:/mosquitto/log
|
||||
ports:
|
||||
- "1883:1883"
|
||||
|
@ -125,7 +128,6 @@ volumes:
|
|||
caddy_conf: {}
|
||||
sqldata: {}
|
||||
dnsconfig: {}
|
||||
mosquitto_data: {}
|
||||
mosquitto_logs: {}
|
||||
prometheus_data: {}
|
||||
grafana_data: {}
|
||||
|
|
|
@ -3,14 +3,15 @@ version: "3.4"
|
|||
services:
|
||||
netmaker: # The Primary Server for running Netmaker
|
||||
container_name: netmaker
|
||||
image: gravitl/netmaker:v0.17.1
|
||||
image: gravitl/netmaker:v0.18.0
|
||||
restart: always
|
||||
volumes: # Volume mounts necessary for sql, coredns, and mqtt
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
- sqldata:/root/data
|
||||
- shared_certs:/etc/netmaker
|
||||
environment: # Necessary capabilities to set iptables when running in container
|
||||
SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN" # The domain/host IP indicating the mq broker address
|
||||
BROKER_NAME: "broker.NETMAKER_BASE_DOMAIN" # The domain/host IP indicating the mq broker address
|
||||
SERVER_NAME: "NETMAKER_BASE_DOMAIN" # The base domain of netmaker
|
||||
SERVER_HOST: "SERVER_PUBLIC_IP" # Set to public IP of machine.
|
||||
SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN" # Overrides SERVER_HOST if set. Useful for making HTTP available via different interfaces/networks.
|
||||
SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
|
||||
|
@ -26,8 +27,11 @@ services:
|
|||
DATABASE: "sqlite" # Database to use - sqlite, postgres, or rqlite
|
||||
NODE_ID: "netmaker-server-1" # used for HA - identifies this server vs other servers
|
||||
MQ_HOST: "mq" # the address of the mq server. If running from docker compose it will be "mq". Otherwise, need to input address. If using "host networking", it will find and detect the IP of the mq container.
|
||||
MQ_SERVER_PORT: "1883" # the reachable port of MQ by the server - change if internal MQ port changes (or use external port if MQ is not on the same machine)
|
||||
MQ_PORT: "443" # the reachable port of MQ - change if external MQ port changes (port on proxy, not necessarily the one exposed in docker-compose)
|
||||
MQ_SERVER_PORT: "1883" # the reachable port of MQ by the server - change if internal MQ port changes (or use external port if MQ is not on the same machine)
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME" # the username to set for MQ access
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD" # the password to set for MQ access
|
||||
STUN_PORT: "3478" # the reachable port of STUN on the server
|
||||
VERBOSITY: "1" # logging verbosity level - 1, 2, or 3
|
||||
# this section is for OAuth
|
||||
AUTH_PROVIDER: "" # "<azure-ad|github|google|oidc>"
|
||||
|
@ -37,10 +41,10 @@ services:
|
|||
AZURE_TENANT: "" # "<only for azure, you may optionally specify the tenant for the OAuth>"
|
||||
OIDC_ISSUER: "" # https://oidc.yourprovider.com - URL of oidc provider
|
||||
ports:
|
||||
- "51821-51830:51821-51830/udp" # wireguard ports
|
||||
- "3478:3478/udp" # the stun port
|
||||
netmaker-ui: # The Netmaker UI Component
|
||||
container_name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.17.1
|
||||
image: gravitl/netmaker-ui:v0.18.0
|
||||
depends_on:
|
||||
- netmaker
|
||||
links:
|
||||
|
@ -68,17 +72,20 @@ services:
|
|||
restart: always
|
||||
volumes:
|
||||
- dnsconfig:/root/dnsconfig
|
||||
mq: # the MQTT broker for netmaker
|
||||
mq: # the mqtt broker for netmaker
|
||||
container_name: mq
|
||||
image: eclipse-mosquitto:2.0.15-openssl
|
||||
depends_on:
|
||||
- netmaker
|
||||
restart: unless-stopped
|
||||
command: ["/mosquitto/config/wait.sh"]
|
||||
environment:
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD" # must be same value as in netmaker env
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME" # must be same value as in netmaker env
|
||||
volumes:
|
||||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf # need to pull conf file from github before running (under docker/mosquitto.conf)
|
||||
- mosquitto_data:/mosquitto/data
|
||||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
- /root/wait.sh:/mosquitto/config/wait.sh
|
||||
- mosquitto_logs:/mosquitto/log
|
||||
- shared_certs:/mosquitto/certs
|
||||
ports:
|
||||
- "1883:1883"
|
||||
- "8883:8883"
|
||||
|
@ -88,5 +95,4 @@ volumes:
|
|||
shared_certs: {} # netmaker certs generated for MQ comms - used by nodes/servers
|
||||
sqldata: {} # storage for embedded sqlite
|
||||
dnsconfig: {} # storage for coredns
|
||||
mosquitto_data: {} # storage for mqtt data
|
||||
mosquitto_logs: {} # storage for mqtt logs
|
||||
|
|
|
@ -3,12 +3,11 @@ version: "3.4"
|
|||
services:
|
||||
netmaker:
|
||||
container_name: netmaker
|
||||
image: gravitl/netmaker:v0.17.1
|
||||
image: gravitl/netmaker:v0.18.0
|
||||
restart: always
|
||||
volumes:
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
- sqldata:/root/data
|
||||
- mosquitto_data:/etc/netmaker
|
||||
environment:
|
||||
BROKER_NAME: "broker.NETMAKER_BASE_DOMAIN"
|
||||
SERVER_NAME: "NETMAKER_BASE_DOMAIN"
|
||||
|
@ -25,18 +24,17 @@ services:
|
|||
DATABASE: "sqlite"
|
||||
NODE_ID: "netmaker-server-1"
|
||||
MQ_HOST: "mq"
|
||||
MQ_PORT: "443"
|
||||
MQ_PORT: "443"
|
||||
MQ_SERVER_PORT: "1883"
|
||||
STUN_PORT: "3478"
|
||||
VERBOSITY: "1"
|
||||
MQ_ADMIN_PASSWORD: "REPLACE_MQ_ADMIN_PASSWORD"
|
||||
STUN_PORT: "3478"
|
||||
PROXY: "on"
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME"
|
||||
ports:
|
||||
- "51821-51830:51821-51830/udp"
|
||||
- "3478:3478/udp"
|
||||
netmaker-ui:
|
||||
container_name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.17.1
|
||||
image: gravitl/netmaker-ui:v0.18.0
|
||||
depends_on:
|
||||
- netmaker
|
||||
links:
|
||||
|
@ -72,16 +70,15 @@ services:
|
|||
restart: unless-stopped
|
||||
command: ["/mosquitto/config/wait.sh"]
|
||||
environment:
|
||||
NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
|
||||
MQ_PASSWORD: "REPLACE_MQ_PASSWORD"
|
||||
MQ_USERNAME: "REPLACE_MQ_USERNAME"
|
||||
volumes:
|
||||
- /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
|
||||
- /root/wait.sh:/mosquitto/config/wait.sh
|
||||
- mosquitto_data:/mosquitto/data
|
||||
- mosquitto_logs:/mosquitto/log
|
||||
volumes:
|
||||
caddy_data: {}
|
||||
caddy_conf: {}
|
||||
sqldata: {}
|
||||
dnsconfig: {}
|
||||
mosquitto_data: {}
|
||||
mosquitto_logs: {}
|
||||
|
|
|
@ -67,7 +67,8 @@ type ServerConfig struct {
|
|||
Server string `yaml:"server"`
|
||||
Broker string `yam:"broker"`
|
||||
PublicIPService string `yaml:"publicipservice"`
|
||||
MQAdminPassword string `yaml:"mqadminpassword"`
|
||||
MQPassword string `yaml:"mqpassword"`
|
||||
MQUserName string `yaml:"mqusername"`
|
||||
MetricsExporter string `yaml:"metrics_exporter"`
|
||||
BasicAuth string `yaml:"basic_auth"`
|
||||
LicenseValue string `yaml:"license_value"`
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -16,7 +15,6 @@ import (
|
|||
var dnsHost models.Host
|
||||
|
||||
func TestGetAllDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -47,7 +45,6 @@ func TestGetAllDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetNodeDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -94,7 +91,6 @@ func TestGetNodeDNS(t *testing.T) {
|
|||
})
|
||||
}
|
||||
func TestGetCustomDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
t.Run("NoNetworks", func(t *testing.T) {
|
||||
|
@ -133,7 +129,6 @@ func TestGetCustomDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetDNSEntryNum(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -152,7 +147,6 @@ func TestGetDNSEntryNum(t *testing.T) {
|
|||
})
|
||||
}
|
||||
func TestGetDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -196,7 +190,6 @@ func TestGetDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -207,7 +200,6 @@ func TestCreateDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSetDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
t.Run("NoNetworks", func(t *testing.T) {
|
||||
|
@ -255,7 +247,6 @@ func TestSetDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetDNSEntry(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -285,7 +276,6 @@ func TestGetDNSEntry(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteDNS(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -307,7 +297,6 @@ func TestDeleteDNS(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestValidateDNSUpdate(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllDNS(t)
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -369,7 +358,6 @@ func TestValidateDNSUpdate(t *testing.T) {
|
|||
|
||||
}
|
||||
func TestValidateDNSCreate(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
_ = logic.DeleteDNS("mynode", "skynet")
|
||||
t.Run("NoNetwork", func(t *testing.T) {
|
||||
entry := models.DNSEntry{"10.0.0.2", "", "myhost", "badnet"}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
//
|
||||
// Schemes: https
|
||||
// BasePath: /
|
||||
// Version: 0.17.1
|
||||
// Version: 0.18.0
|
||||
// Host: netmaker.io
|
||||
//
|
||||
// Consumes:
|
||||
|
|
|
@ -214,7 +214,7 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
|||
if network.DefaultKeepalive != 0 {
|
||||
keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
|
||||
}
|
||||
gwendpoint := host.EndpointIP.String() + ":" + strconv.Itoa(host.ListenPort)
|
||||
gwendpoint := host.EndpointIP.String() + ":" + strconv.Itoa(logic.GetPeerListenPort(host))
|
||||
newAllowedIPs := network.AddressRange
|
||||
if newAllowedIPs != "" && network.AddressRange6 != "" {
|
||||
newAllowedIPs += ","
|
||||
|
|
|
@ -97,7 +97,6 @@ func updateHost(w http.ResponseWriter, r *http.Request) {
|
|||
if updateRelay {
|
||||
logic.UpdateHostRelay(currHost.ID.String(), currHost.RelayedHosts, newHost.RelayedHosts)
|
||||
}
|
||||
|
||||
// publish host update through MQ
|
||||
if err := mq.HostUpdate(&models.HostUpdate{
|
||||
Action: models.UpdateHost,
|
||||
|
@ -190,10 +189,6 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
|
|||
logger.Log(0, r.Header.Get("user"), "failed to send delete host update: ", currHost.ID.String(), err.Error())
|
||||
}
|
||||
|
||||
if err = mq.DeleteMqClient(currHost.ID.String()); err != nil {
|
||||
logger.Log(0, "error removing DynSec credentials for host:", currHost.Name, err.Error())
|
||||
}
|
||||
|
||||
apiHostData := currHost.ConvertNMHostToAPI()
|
||||
logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
@ -242,6 +237,11 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
}); err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to update host to join network:", hostid, network, err.Error())
|
||||
}
|
||||
go func() { // notify of peer change
|
||||
if err := mq.PublishPeerUpdate(); err != nil {
|
||||
logger.Log(1, "error publishing peer update ", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("added host %s to network %s", currHost.Name, network))
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
|
|
@ -403,13 +403,25 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = logic.AddDefaultHostsToNetwork(network.NetID, servercfg.GetServer()); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to add default hosts to network [%v]: %v",
|
||||
network.NetID, err.Error()))
|
||||
defaultHosts := logic.GetDefaultHosts()
|
||||
for i := range defaultHosts {
|
||||
currHost := &defaultHosts[i]
|
||||
newNode, err := logic.UpdateHostNetwork(currHost, network.NetID, true)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to add host to network:", currHost.ID.String(), network.NetID, err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logger.Log(1, "added new node", newNode.ID.String(), "to host", currHost.Name)
|
||||
if err = mq.HostUpdate(&models.HostUpdate{
|
||||
Action: models.JoinHostToNetwork,
|
||||
Host: *currHost,
|
||||
Node: *newNode,
|
||||
}); err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to add host to network:", currHost.ID.String(), network.NetID, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Send message notifying host of new peers/network conf
|
||||
|
||||
logger.Log(1, r.Header.Get("user"), "created network", network.NetID)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(network)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -20,8 +22,27 @@ type NetworkValidationTestCase struct {
|
|||
|
||||
var netHost models.Host
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
database.InitializeDatabase()
|
||||
defer database.CloseDB()
|
||||
logic.CreateAdmin(&models.User{
|
||||
UserName: "admin",
|
||||
Password: "password",
|
||||
IsAdmin: true,
|
||||
Networks: []string{},
|
||||
Groups: []string{},
|
||||
})
|
||||
peerUpdate := make(chan *models.Node)
|
||||
go logic.ManageZombies(context.Background(), peerUpdate)
|
||||
go func() {
|
||||
for update := range peerUpdate {
|
||||
//do nothing
|
||||
logger.Log(3, "received node update", update.Action)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func TestCreateNetwork(t *testing.T) {
|
||||
initialize()
|
||||
deleteAllNetworks()
|
||||
|
||||
var network models.Network
|
||||
|
@ -34,7 +55,6 @@ func TestCreateNetwork(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
}
|
||||
func TestGetNetwork(t *testing.T) {
|
||||
initialize()
|
||||
createNet()
|
||||
|
||||
t.Run("GetExistingNetwork", func(t *testing.T) {
|
||||
|
@ -50,7 +70,6 @@ func TestGetNetwork(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteNetwork(t *testing.T) {
|
||||
initialize()
|
||||
createNet()
|
||||
//create nodes
|
||||
t.Run("NetworkwithNodes", func(t *testing.T) {
|
||||
|
@ -66,7 +85,6 @@ func TestDeleteNetwork(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateKey(t *testing.T) {
|
||||
initialize()
|
||||
createNet()
|
||||
keys, _ := logic.GetKeys("skynet")
|
||||
for _, key := range keys {
|
||||
|
@ -138,7 +156,6 @@ func TestCreateKey(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetKeys(t *testing.T) {
|
||||
initialize()
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
network, err := logic.GetNetwork("skynet")
|
||||
|
@ -161,7 +178,6 @@ func TestGetKeys(t *testing.T) {
|
|||
})
|
||||
}
|
||||
func TestDeleteKey(t *testing.T) {
|
||||
initialize()
|
||||
createNet()
|
||||
network, err := logic.GetNetwork("skynet")
|
||||
assert.Nil(t, err)
|
||||
|
@ -183,7 +199,6 @@ func TestDeleteKey(t *testing.T) {
|
|||
func TestSecurityCheck(t *testing.T) {
|
||||
//these seem to work but not sure it the tests are really testing the functionality
|
||||
|
||||
initialize()
|
||||
os.Setenv("MASTER_KEY", "secretkey")
|
||||
t.Run("NoNetwork", func(t *testing.T) {
|
||||
networks, username, err := logic.UserPermissions(false, "", "Bearer secretkey")
|
||||
|
@ -214,7 +229,6 @@ func TestValidateNetwork(t *testing.T) {
|
|||
//t.Skip()
|
||||
//This functions is not called by anyone
|
||||
//it panics as validation function 'display_name_valid' is not defined
|
||||
initialize()
|
||||
//yes := true
|
||||
//no := false
|
||||
//deleteNet(t)
|
||||
|
@ -291,7 +305,6 @@ func TestValidateNetwork(t *testing.T) {
|
|||
func TestIpv6Network(t *testing.T) {
|
||||
//these seem to work but not sure it the tests are really testing the functionality
|
||||
|
||||
initialize()
|
||||
os.Setenv("MASTER_KEY", "secretkey")
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
|
@ -318,21 +331,6 @@ func deleteAllNetworks() {
|
|||
}
|
||||
}
|
||||
|
||||
func initialize() {
|
||||
database.InitializeDatabase()
|
||||
createAdminUser()
|
||||
}
|
||||
|
||||
func createAdminUser() {
|
||||
logic.CreateAdmin(&models.User{
|
||||
UserName: "admin",
|
||||
Password: "password",
|
||||
IsAdmin: true,
|
||||
Networks: []string{},
|
||||
Groups: []string{},
|
||||
})
|
||||
}
|
||||
|
||||
func createNet() {
|
||||
var network models.Network
|
||||
network.NetID = "skynet"
|
||||
|
|
|
@ -577,8 +577,6 @@ func createNode(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
server := servercfg.GetServerInfo()
|
||||
server.TrafficKey = key
|
||||
// consume password before hashing for mq client creation
|
||||
hostPassword := data.Host.HostPass
|
||||
data.Node.Server = servercfg.GetServer()
|
||||
if !logic.HostExists(&data.Host) {
|
||||
logic.CheckHostPorts(&data.Host)
|
||||
|
@ -606,18 +604,6 @@ func createNode(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Create client for this host in Mq
|
||||
if err := mq.CreateMqClient(&mq.MqClient{
|
||||
ID: data.Host.ID.String(),
|
||||
Text: data.Host.Name,
|
||||
Password: hostPassword,
|
||||
Networks: []string{networkName},
|
||||
}); err != nil {
|
||||
logger.Log(0, fmt.Sprintf("failed to create DynSec client: %v", err.Error()))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = logic.AssociateNodeToHost(&data.Node, &data.Host)
|
||||
|
|
|
@ -21,7 +21,6 @@ func TestCreateEgressGateway(t *testing.T) {
|
|||
var gateway models.EgressGatewayRequest
|
||||
gateway.Ranges = []string{"10.100.100.0/24"}
|
||||
gateway.NetID = "skynet"
|
||||
database.InitializeDatabase()
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
t.Run("NoNodes", func(t *testing.T) {
|
||||
|
@ -78,7 +77,6 @@ func TestCreateEgressGateway(t *testing.T) {
|
|||
}
|
||||
func TestDeleteEgressGateway(t *testing.T) {
|
||||
var gateway models.EgressGatewayRequest
|
||||
database.InitializeDatabase()
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
testnode := createTestNode()
|
||||
|
@ -110,7 +108,6 @@ func TestDeleteEgressGateway(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetNetworkNodes(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllNetworks()
|
||||
createNet()
|
||||
t.Run("BadNet", func(t *testing.T) {
|
||||
|
|
|
@ -123,12 +123,24 @@ func createHostRelay(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := mq.HostUpdate(&models.HostUpdate{
|
||||
Action: models.UpdateHost,
|
||||
Host: *relayHost,
|
||||
}); err != nil {
|
||||
logger.Log(0, "failed to send host update: ", relayHost.ID.String(), err.Error())
|
||||
}
|
||||
logger.Log(1, r.Header.Get("user"), "created relay on host", relay.HostID)
|
||||
go func(relayHostID string) {
|
||||
relatedhosts := logic.GetRelatedHosts(relayHostID)
|
||||
for _, relatedHost := range relatedhosts {
|
||||
relatedHost.ProxyEnabled = true
|
||||
logic.UpsertHost(&relatedHost)
|
||||
if err := mq.HostUpdate(&models.HostUpdate{
|
||||
Action: models.UpdateHost,
|
||||
Host: relatedHost,
|
||||
}); err != nil {
|
||||
logger.Log(0, "failed to send host update: ", relatedHost.ID.String(), err.Error())
|
||||
}
|
||||
}
|
||||
if err := mq.PublishPeerUpdate(); err != nil {
|
||||
logger.Log(0, "fail to publish peer update: ", err.Error())
|
||||
|
|
|
@ -6,8 +6,10 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
|
@ -19,6 +21,35 @@ func serverHandlers(r *mux.Router) {
|
|||
}))
|
||||
r.HandleFunc("/api/server/getconfig", allowUsers(http.HandlerFunc(getConfig))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/server/getserverinfo", authorize(true, false, "node", http.HandlerFunc(getServerInfo))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/server/status", http.HandlerFunc(getStatus)).Methods(http.MethodGet)
|
||||
}
|
||||
|
||||
// swagger:route GET /api/server/status server getStatus
|
||||
//
|
||||
// Get the server configuration.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: serverConfigResponse
|
||||
func getStatus(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO
|
||||
// - check health of broker
|
||||
type status struct {
|
||||
DB bool `json:"db_connected"`
|
||||
Broker bool `json:"broker_connected"`
|
||||
}
|
||||
|
||||
currentServerStatus := status{
|
||||
DB: database.IsConnected(),
|
||||
Broker: mq.IsConnected(),
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(¤tServerStatus)
|
||||
}
|
||||
|
||||
// allowUsers - allow all authenticated (valid) users - only used by getConfig, may be able to remove during refactor
|
||||
|
|
|
@ -3,7 +3,6 @@ package controller
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -18,7 +17,6 @@ func deleteAllUsers() {
|
|||
|
||||
func TestHasAdmin(t *testing.T) {
|
||||
//delete all current users
|
||||
database.InitializeDatabase()
|
||||
users, _ := logic.GetUsers()
|
||||
for _, user := range users {
|
||||
success, err := logic.DeleteUser(user.UserName)
|
||||
|
@ -48,7 +46,7 @@ func TestHasAdmin(t *testing.T) {
|
|||
})
|
||||
t.Run("multiple admins", func(t *testing.T) {
|
||||
var user = models.User{"admin1", "password", nil, true, nil}
|
||||
err := logic.CreateUser(&user)
|
||||
err := logic.CreateUser(&user)
|
||||
assert.Nil(t, err)
|
||||
found, err := logic.HasAdmin()
|
||||
assert.Nil(t, err)
|
||||
|
@ -57,7 +55,6 @@ func TestHasAdmin(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateUser(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
user := models.User{"admin", "password", nil, true, nil}
|
||||
t.Run("NoUser", func(t *testing.T) {
|
||||
|
@ -72,7 +69,6 @@ func TestCreateUser(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCreateAdmin(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
var user models.User
|
||||
t.Run("NoAdmin", func(t *testing.T) {
|
||||
|
@ -90,7 +86,6 @@ func TestCreateAdmin(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDeleteUser(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
t.Run("NonExistent User", func(t *testing.T) {
|
||||
deleted, err := logic.DeleteUser("admin")
|
||||
|
@ -107,7 +102,6 @@ func TestDeleteUser(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestValidateUser(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
var user models.User
|
||||
t.Run("Valid Create", func(t *testing.T) {
|
||||
user.UserName = "admin"
|
||||
|
@ -155,7 +149,6 @@ func TestValidateUser(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
t.Run("NonExistantUser", func(t *testing.T) {
|
||||
admin, err := logic.GetUser("admin")
|
||||
|
@ -172,7 +165,6 @@ func TestGetUser(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetUsers(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
t.Run("NonExistantUser", func(t *testing.T) {
|
||||
admin, err := logic.GetUsers()
|
||||
|
@ -203,7 +195,6 @@ func TestGetUsers(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateUser(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
user := models.User{"admin", "password", nil, true, nil}
|
||||
newuser := models.User{"hello", "world", []string{"wirecat, netmaker"}, true, []string{}}
|
||||
|
@ -246,7 +237,6 @@ func TestUpdateUser(t *testing.T) {
|
|||
// }
|
||||
|
||||
func TestVerifyAuthRequest(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
deleteAllUsers()
|
||||
var authRequest models.UserAuthParams
|
||||
t.Run("EmptyUserName", func(t *testing.T) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -80,8 +81,12 @@ const (
|
|||
FETCH_ALL = "fetchall"
|
||||
// CLOSE_DB - graceful close of db const
|
||||
CLOSE_DB = "closedb"
|
||||
// isconnected
|
||||
isConnected = "isconnected"
|
||||
)
|
||||
|
||||
var dbMutex sync.RWMutex
|
||||
|
||||
func getCurrentDB() map[string]interface{} {
|
||||
switch servercfg.GetDB() {
|
||||
case "rqlite":
|
||||
|
@ -148,6 +153,8 @@ func IsJSONString(value string) bool {
|
|||
|
||||
// Insert - inserts object into db
|
||||
func Insert(key string, value string, tableName string) error {
|
||||
dbMutex.Lock()
|
||||
defer dbMutex.Unlock()
|
||||
if key != "" && value != "" && IsJSONString(value) {
|
||||
return getCurrentDB()[INSERT].(func(string, string, string) error)(key, value, tableName)
|
||||
} else {
|
||||
|
@ -157,6 +164,8 @@ func Insert(key string, value string, tableName string) error {
|
|||
|
||||
// InsertPeer - inserts peer into db
|
||||
func InsertPeer(key string, value string) error {
|
||||
dbMutex.Lock()
|
||||
defer dbMutex.Unlock()
|
||||
if key != "" && value != "" && IsJSONString(value) {
|
||||
return getCurrentDB()[INSERT_PEER].(func(string, string) error)(key, value)
|
||||
} else {
|
||||
|
@ -166,11 +175,15 @@ func InsertPeer(key string, value string) error {
|
|||
|
||||
// DeleteRecord - deletes a record from db
|
||||
func DeleteRecord(tableName string, key string) error {
|
||||
dbMutex.Lock()
|
||||
defer dbMutex.Unlock()
|
||||
return getCurrentDB()[DELETE].(func(string, string) error)(tableName, key)
|
||||
}
|
||||
|
||||
// DeleteAllRecords - removes a table and remakes
|
||||
func DeleteAllRecords(tableName string) error {
|
||||
dbMutex.Lock()
|
||||
defer dbMutex.Unlock()
|
||||
err := getCurrentDB()[DELETE_ALL].(func(string) error)(tableName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -196,6 +209,8 @@ func FetchRecord(tableName string, key string) (string, error) {
|
|||
|
||||
// FetchRecords - fetches all records in given table
|
||||
func FetchRecords(tableName string) (map[string]string, error) {
|
||||
dbMutex.RLock()
|
||||
defer dbMutex.RUnlock()
|
||||
return getCurrentDB()[FETCH_ALL].(func(string) (map[string]string, error))(tableName)
|
||||
}
|
||||
|
||||
|
@ -241,3 +256,8 @@ func initializeUUID() error {
|
|||
func CloseDB() {
|
||||
getCurrentDB()[CLOSE_DB].(func())()
|
||||
}
|
||||
|
||||
// IsConnected - tell if the database is connected or not
|
||||
func IsConnected() bool {
|
||||
return getCurrentDB()[isConnected].(func() bool)()
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ var PG_FUNCTIONS = map[string]interface{}{
|
|||
DELETE_ALL: pgDeleteAllRecords,
|
||||
FETCH_ALL: pgFetchRecords,
|
||||
CLOSE_DB: pgCloseDB,
|
||||
isConnected: pgIsConnected,
|
||||
}
|
||||
|
||||
func getPGConnString() string {
|
||||
|
@ -135,3 +136,8 @@ func pgFetchRecords(tableName string) (map[string]string, error) {
|
|||
func pgCloseDB() {
|
||||
PGDB.Close()
|
||||
}
|
||||
|
||||
func pgIsConnected() bool {
|
||||
stats := PGDB.Stats()
|
||||
return stats.OpenConnections > 0
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ var RQLITE_FUNCTIONS = map[string]interface{}{
|
|||
DELETE_ALL: rqliteDeleteAllRecords,
|
||||
FETCH_ALL: rqliteFetchRecords,
|
||||
CLOSE_DB: rqliteCloseDB,
|
||||
isConnected: rqliteConnected,
|
||||
}
|
||||
|
||||
func initRqliteDatabase() error {
|
||||
|
@ -104,3 +105,8 @@ func rqliteFetchRecords(tableName string) (map[string]string, error) {
|
|||
func rqliteCloseDB() {
|
||||
RQliteDatabase.Close()
|
||||
}
|
||||
|
||||
func rqliteConnected() bool {
|
||||
leader, err := RQliteDatabase.Leader()
|
||||
return err == nil && len(leader) > 0
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ var SQLITE_FUNCTIONS = map[string]interface{}{
|
|||
DELETE_ALL: sqliteDeleteAllRecords,
|
||||
FETCH_ALL: sqliteFetchRecords,
|
||||
CLOSE_DB: sqliteCloseDB,
|
||||
isConnected: sqliteConnected,
|
||||
}
|
||||
|
||||
func initSqliteDB() error {
|
||||
|
@ -135,3 +136,8 @@ func sqliteFetchRecords(tableName string) (map[string]string, error) {
|
|||
func sqliteCloseDB() {
|
||||
SqliteDB.Close()
|
||||
}
|
||||
|
||||
func sqliteConnected() bool {
|
||||
stats := SqliteDB.Stats()
|
||||
return stats.OpenConnections > 0
|
||||
}
|
||||
|
|
|
@ -7,5 +7,4 @@ listener 1883
|
|||
protocol websockets
|
||||
allow_anonymous false
|
||||
|
||||
plugin /usr/lib/mosquitto_dynamic_security.so
|
||||
plugin_opt_config_file /mosquitto/data/dynamic-security.json
|
||||
password_file /mosquitto/password.txt
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
#!/bin/ash
|
||||
|
||||
wait_for_netmaker() {
|
||||
echo "SERVER: ${NETMAKER_SERVER_HOST}"
|
||||
until curl --output /dev/null --silent --fail --head \
|
||||
--location "${NETMAKER_SERVER_HOST}/api/server/health"; do
|
||||
echo "Waiting for netmaker server to startup"
|
||||
sleep 1
|
||||
done
|
||||
encrypt_password() {
|
||||
echo "${MQ_USERNAME}:${MQ_PASSWORD}" > /mosquitto/password.txt
|
||||
mosquitto_passwd -U /mosquitto/password.txt
|
||||
}
|
||||
|
||||
main(){
|
||||
# wait for netmaker to startup
|
||||
apk add curl
|
||||
wait_for_netmaker
|
||||
|
||||
encrypt_password
|
||||
echo "Starting MQ..."
|
||||
# Run the main container command.
|
||||
/docker-entrypoint.sh
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package functions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
@ -19,11 +21,27 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
database.InitializeDatabase()
|
||||
defer database.CloseDB()
|
||||
logic.CreateAdmin(&models.User{
|
||||
UserName: "admin",
|
||||
Password: "password",
|
||||
IsAdmin: true,
|
||||
Networks: []string{},
|
||||
Groups: []string{},
|
||||
})
|
||||
peerUpdate := make(chan *models.Node)
|
||||
go logic.ManageZombies(context.Background(), peerUpdate)
|
||||
go func() {
|
||||
for update := range peerUpdate {
|
||||
//do nothing
|
||||
logger.Log(3, "received node update", update.Action)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func TestNetworkExists(t *testing.T) {
|
||||
err := database.InitializeDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("error initilizing database: %s", err)
|
||||
}
|
||||
database.DeleteRecord(database.NETWORKS_TABLE_NAME, testNetwork.NetID)
|
||||
defer database.CloseDB()
|
||||
exists, err := logic.NetworkExists(testNetwork.NetID)
|
||||
|
@ -53,10 +71,6 @@ func TestNetworkExists(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetAllExtClients(t *testing.T) {
|
||||
err := database.InitializeDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("error initilizing database: %s", err)
|
||||
}
|
||||
defer database.CloseDB()
|
||||
database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, testExternalClient.ClientID)
|
||||
|
||||
|
|
17
go.mod
17
go.mod
|
@ -4,7 +4,7 @@ go 1.19
|
|||
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.2
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
|
@ -15,11 +15,11 @@ require (
|
|||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/txn2/txeh v1.3.0
|
||||
golang.org/x/crypto v0.3.0
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/oauth2 v0.3.0
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.6.0
|
||||
golang.org/x/net v0.6.0 // indirect
|
||||
golang.org/x/oauth2 v0.4.0
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220324164955-056925b7df31
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
|
@ -29,7 +29,6 @@ require (
|
|||
require (
|
||||
filippo.io/edwards25519 v1.0.0
|
||||
github.com/c-robinson/iplib v1.0.6
|
||||
github.com/go-ping/ping v1.1.0
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0
|
||||
)
|
||||
|
||||
|
@ -60,8 +59,8 @@ require (
|
|||
cloud.google.com/go/compute v1.12.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
|
|
50
go.sum
50
go.sum
|
@ -17,7 +17,6 @@ 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/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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -29,16 +28,13 @@ github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
|
|||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
|
||||
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
||||
github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
|
||||
github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -52,7 +48,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
|
|||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
|
||||
|
@ -73,13 +68,10 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
|
|||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
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.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
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/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.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/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
||||
|
@ -106,7 +98,6 @@ 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/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -116,9 +107,7 @@ 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.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
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/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/go.mod h1:UW/gxgQwSePTvL1KA8QEHsXeYHP4xkoXgbDdN781p34=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
|
@ -160,10 +149,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
|
@ -172,17 +160,18 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
|
||||
golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
|
||||
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -193,10 +182,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -205,8 +192,9 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
|
@ -215,8 +203,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
@ -240,11 +229,8 @@ 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 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/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gortc.io/stun v1.23.0 h1:CpRQFjakCZMwVKTwInKbcCzlBklj62LGzD3NPdFyGrE=
|
||||
|
|
|
@ -16,7 +16,7 @@ spec:
|
|||
hostNetwork: true
|
||||
containers:
|
||||
- name: netclient
|
||||
image: gravitl/netclient:v0.17.1
|
||||
image: gravitl/netclient:v0.18.0
|
||||
env:
|
||||
- name: TOKEN
|
||||
value: "TOKEN_VALUE"
|
||||
|
|
|
@ -28,7 +28,7 @@ spec:
|
|||
# - "<node label value>"
|
||||
containers:
|
||||
- name: netclient
|
||||
image: gravitl/netclient:v0.17.1
|
||||
image: gravitl/netclient:v0.18.0
|
||||
env:
|
||||
- name: TOKEN
|
||||
value: "TOKEN_VALUE"
|
||||
|
|
|
@ -81,7 +81,7 @@ spec:
|
|||
value: "Kubernetes"
|
||||
- name: VERBOSITY
|
||||
value: "3"
|
||||
image: gravitl/netmaker:v0.17.1
|
||||
image: gravitl/netmaker:v0.18.0
|
||||
imagePullPolicy: Always
|
||||
name: netmaker
|
||||
ports:
|
||||
|
|
|
@ -15,7 +15,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: netmaker-ui
|
||||
image: gravitl/netmaker-ui:v0.17.1
|
||||
image: gravitl/netmaker-ui:v0.18.0
|
||||
ports:
|
||||
- containerPort: 443
|
||||
env:
|
||||
|
|
|
@ -1,17 +1,38 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/matryer/is"
|
||||
)
|
||||
|
||||
func TestCheckPorts(t *testing.T) {
|
||||
func TestMain(m *testing.M) {
|
||||
database.InitializeDatabase()
|
||||
defer database.CloseDB()
|
||||
CreateAdmin(&models.User{
|
||||
UserName: "admin",
|
||||
Password: "password",
|
||||
IsAdmin: true,
|
||||
Networks: []string{},
|
||||
Groups: []string{},
|
||||
})
|
||||
peerUpdate := make(chan *models.Node)
|
||||
go ManageZombies(context.Background(), peerUpdate)
|
||||
go func() {
|
||||
for update := range peerUpdate {
|
||||
//do nothing
|
||||
logger.Log(3, "received node update", update.Action)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func TestCheckPorts(t *testing.T) {
|
||||
h := models.Host{
|
||||
ID: uuid.New(),
|
||||
EndpointIP: net.ParseIP("192.168.1.1"),
|
||||
|
|
|
@ -96,6 +96,7 @@ func CreateHost(h *models.Host) error {
|
|||
return err
|
||||
}
|
||||
h.HostPass = string(hash)
|
||||
checkForZombieHosts(h)
|
||||
return UpsertHost(h)
|
||||
}
|
||||
|
||||
|
@ -216,6 +217,7 @@ func UpdateHostNetwork(h *models.Host, network string, add bool) (*models.Node,
|
|||
newNode := models.Node{}
|
||||
newNode.Server = servercfg.GetServer()
|
||||
newNode.Network = network
|
||||
newNode.HostID = h.ID
|
||||
if err := AssociateNodeToHost(&newNode, h); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -308,21 +310,6 @@ func GetDefaultHosts() []models.Host {
|
|||
return defaultHostList[:]
|
||||
}
|
||||
|
||||
// AddDefaultHostsToNetwork - adds a node to network for every default host on Netmaker server
|
||||
func AddDefaultHostsToNetwork(network, server string) error {
|
||||
// add default hosts to network
|
||||
defaultHosts := GetDefaultHosts()
|
||||
for i := range defaultHosts {
|
||||
newNode := models.Node{}
|
||||
newNode.Network = network
|
||||
newNode.Server = server
|
||||
if err := AssociateNodeToHost(&newNode, &defaultHosts[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetHostNetworks - fetches all the networks
|
||||
func GetHostNetworks(hostID string) []string {
|
||||
currHost, err := GetHost(hostID)
|
||||
|
|
|
@ -534,7 +534,7 @@ func createNode(node *models.Node) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
CheckZombies(node, host.MacAddress)
|
||||
CheckZombies(node)
|
||||
|
||||
nodebytes, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
|
|
|
@ -201,7 +201,7 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|||
if host.IsRelayed {
|
||||
relayHost, err := GetHost(host.RelayedBy)
|
||||
if err == nil {
|
||||
relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, getPeerListenPort(relayHost)))
|
||||
relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, GetPeerListenPort(relayHost)))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|||
relayedHost := relayedHost
|
||||
payload, err := GetPeerUpdateForHost(&relayedHost)
|
||||
if err == nil {
|
||||
relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedHost.EndpointIP, getPeerListenPort(&relayedHost)))
|
||||
relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedHost.EndpointIP, GetPeerListenPort(&relayedHost)))
|
||||
if udpErr == nil {
|
||||
relayPeersMap[relayedHost.PublicKey.String()] = models.RelayedConf{
|
||||
RelayedPeerEndpoint: relayedEndpoint,
|
||||
|
@ -259,14 +259,14 @@ func GetProxyUpdateForHost(host *models.Host) (models.ProxyManagerPayload, error
|
|||
if currPeerConf, found = peerConfMap[peerHost.PublicKey.String()]; !found {
|
||||
currPeerConf = models.PeerConf{
|
||||
Proxy: peerHost.ProxyEnabled,
|
||||
PublicListenPort: int32(getPeerListenPort(peerHost)),
|
||||
PublicListenPort: int32(GetPeerListenPort(peerHost)),
|
||||
}
|
||||
}
|
||||
|
||||
if peerHost.IsRelayed && peerHost.RelayedBy != host.ID.String() {
|
||||
relayHost, err := GetHost(peerHost.RelayedBy)
|
||||
if err == nil {
|
||||
relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, getPeerListenPort(peerHost)))
|
||||
relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, GetPeerListenPort(relayHost)))
|
||||
if err == nil {
|
||||
currPeerConf.IsRelayed = true
|
||||
currPeerConf.RelayedTo = relayTo
|
||||
|
@ -370,7 +370,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
|
|||
}
|
||||
peerConfig.Endpoint = &net.UDPAddr{
|
||||
IP: peerHost.EndpointIP,
|
||||
Port: getPeerListenPort(peerHost),
|
||||
Port: GetPeerListenPort(peerHost),
|
||||
}
|
||||
|
||||
if uselocal {
|
||||
|
@ -390,7 +390,21 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
|
|||
}
|
||||
peerConfig.AllowedIPs = allowedips
|
||||
if node.IsIngressGateway || node.IsEgressGateway {
|
||||
|
||||
if peer.IsIngressGateway {
|
||||
_, extPeerIDAndAddrs, err := getExtPeers(&peer)
|
||||
if err == nil {
|
||||
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
||||
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
||||
PeerAddr: net.IPNet{
|
||||
IP: net.ParseIP(extPeerIdAndAddr.Address),
|
||||
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
||||
},
|
||||
PeerKey: extPeerIdAndAddr.ID,
|
||||
Allow: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
|
||||
PeerAddr: net.IPNet{
|
||||
IP: net.ParseIP(peer.PrimaryAddress()),
|
||||
|
@ -429,6 +443,16 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
|
|||
if node.IsIngressGateway {
|
||||
extPeers, extPeerIDAndAddrs, err = getExtPeers(&node)
|
||||
if err == nil {
|
||||
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
||||
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
||||
PeerAddr: net.IPNet{
|
||||
IP: net.ParseIP(extPeerIdAndAddr.Address),
|
||||
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
||||
},
|
||||
PeerKey: extPeerIdAndAddr.ID,
|
||||
Allow: true,
|
||||
}
|
||||
}
|
||||
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
|
||||
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
||||
hostPeerUpdate.PeerIDs[extPeerIdAndAddr.ID] = make(map[string]models.IDandAddr)
|
||||
|
@ -459,19 +483,6 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
|
|||
}
|
||||
}
|
||||
if node.IsEgressGateway {
|
||||
if node.IsIngressGateway {
|
||||
for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
|
||||
nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
|
||||
PeerAddr: net.IPNet{
|
||||
IP: net.ParseIP(extPeerIdAndAddr.Address),
|
||||
Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
|
||||
},
|
||||
PeerKey: extPeerIdAndAddr.ID,
|
||||
Allow: true,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
|
||||
EgressID: node.ID.String(),
|
||||
Network: node.PrimaryNetworkRange(),
|
||||
|
@ -488,7 +499,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
|
|||
return hostPeerUpdate, nil
|
||||
}
|
||||
|
||||
func getPeerListenPort(host *models.Host) int {
|
||||
func GetPeerListenPort(host *models.Host) int {
|
||||
peerPort := host.ListenPort
|
||||
if host.ProxyEnabled {
|
||||
if host.PublicListenPort != 0 {
|
||||
|
@ -557,7 +568,7 @@ func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, err
|
|||
Port: peerHost.ListenPort,
|
||||
}
|
||||
if peerHost.ProxyEnabled {
|
||||
peerConfig.Endpoint.Port = getPeerListenPort(peerHost)
|
||||
peerConfig.Endpoint.Port = GetPeerListenPort(peerHost)
|
||||
}
|
||||
if uselocal {
|
||||
peerConfig.Endpoint.IP = peer.LocalAddress.IP
|
||||
|
@ -690,7 +701,7 @@ func GetPeerUpdateLegacy(node *models.Node) (models.PeerUpdate, error) {
|
|||
if node.LocalAddress.String() != peer.LocalAddress.String() && peer.LocalAddress.IP != nil {
|
||||
peerHost.EndpointIP = peer.LocalAddress.IP
|
||||
if peerHost.ListenPort != 0 {
|
||||
peerHost.ListenPort = getPeerListenPort(peerHost)
|
||||
peerHost.ListenPort = GetPeerListenPort(peerHost)
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
|
@ -723,7 +734,7 @@ func GetPeerUpdateLegacy(node *models.Node) (models.PeerUpdate, error) {
|
|||
// or, if port is for some reason zero use the LocalListenPort
|
||||
// but only do this if LocalListenPort is not zero
|
||||
if ((!setUDPPort) || peerHost.ListenPort == 0) && peerHost.ListenPort != 0 {
|
||||
peerHost.ListenPort = getPeerListenPort(peerHost)
|
||||
peerHost.ListenPort = GetPeerListenPort(peerHost)
|
||||
}
|
||||
|
||||
endpoint := peerHost.EndpointIP.String() + ":" + strconv.FormatInt(int64(peerHost.ListenPort), 10)
|
||||
|
|
|
@ -10,8 +10,12 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNetworkUserLogic(t *testing.T) {
|
||||
func TestMain(m *testing.M) {
|
||||
database.InitializeDatabase()
|
||||
defer database.CloseDB()
|
||||
}
|
||||
|
||||
func TestNetworkUserLogic(t *testing.T) {
|
||||
networkUser := promodels.NetworkUser{
|
||||
ID: "helloworld",
|
||||
}
|
||||
|
|
|
@ -3,13 +3,11 @@ package pro
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/models/promodels"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUserGroupLogic(t *testing.T) {
|
||||
database.InitializeDatabase()
|
||||
|
||||
t.Run("User Groups initialized successfully", func(t *testing.T) {
|
||||
err := InitializeGroups()
|
||||
|
|
|
@ -2,7 +2,6 @@ package logic
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -18,15 +17,16 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
zombies []uuid.UUID
|
||||
removeZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
|
||||
newZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
|
||||
zombies []uuid.UUID
|
||||
hostZombies []uuid.UUID
|
||||
newZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
|
||||
newHostZombie chan uuid.UUID = make(chan (uuid.UUID), 10)
|
||||
)
|
||||
|
||||
// CheckZombies - checks if new node has same macaddress as existing node
|
||||
// CheckZombies - checks if new node has same hostid as existing node
|
||||
// if so, existing node is added to zombie node quarantine list
|
||||
// also cleans up nodes past their expiration date
|
||||
func CheckZombies(newnode *models.Node, mac net.HardwareAddr) {
|
||||
func CheckZombies(newnode *models.Node) {
|
||||
nodes, err := GetNetworkNodes(newnode.Network)
|
||||
if err != nil {
|
||||
logger.Log(1, "Failed to retrieve network nodes", newnode.Network, err.Error())
|
||||
|
@ -44,6 +44,35 @@ func CheckZombies(newnode *models.Node, mac net.HardwareAddr) {
|
|||
}
|
||||
}
|
||||
|
||||
// checkForZombieHosts - checks if new host has the same macAddress as an existing host
|
||||
// if true, existing host is added to host zombie collection
|
||||
func checkForZombieHosts(h *models.Host) {
|
||||
hosts, err := GetAllHosts()
|
||||
if err != nil {
|
||||
logger.Log(3, "errror retrieving all hosts", err.Error())
|
||||
}
|
||||
for _, existing := range hosts {
|
||||
if existing.ID == h.ID {
|
||||
//probably an unnecessary check as new host should not be in database yet, but just in case
|
||||
//skip self
|
||||
continue
|
||||
}
|
||||
if existing.MacAddress.String() == h.MacAddress.String() {
|
||||
//add to hostZombies
|
||||
newHostZombie <- existing.ID
|
||||
//add all nodes belonging to host to zombile list
|
||||
for _, node := range existing.Nodes {
|
||||
id, err := uuid.Parse(node)
|
||||
if err != nil {
|
||||
logger.Log(3, "error parsing uuid from host.Nodes", err.Error())
|
||||
continue
|
||||
}
|
||||
newHostZombie <- id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ManageZombies - goroutine which adds/removes/deletes nodes from the zombie node quarantine list
|
||||
func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
|
||||
logger.Log(2, "Zombie management started")
|
||||
|
@ -51,24 +80,12 @@ func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
|
|||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
close(peerUpdate)
|
||||
return
|
||||
case id := <-newZombie:
|
||||
logger.Log(1, "adding", id.String(), "to zombie quaratine list")
|
||||
zombies = append(zombies, id)
|
||||
case id := <-removeZombie:
|
||||
found := false
|
||||
if len(zombies) > 0 {
|
||||
for i := len(zombies) - 1; i >= 0; i-- {
|
||||
if zombies[i] == id {
|
||||
logger.Log(1, "removing zombie from quaratine list", zombies[i].String())
|
||||
zombies = append(zombies[:i], zombies[i+1:]...)
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
logger.Log(3, "no zombies found")
|
||||
}
|
||||
case id := <-newHostZombie:
|
||||
hostZombies = append(hostZombies, id)
|
||||
case <-time.After(time.Second * ZOMBIE_TIMEOUT):
|
||||
logger.Log(3, "checking for zombie nodes")
|
||||
if len(zombies) > 0 {
|
||||
|
@ -92,6 +109,23 @@ func ManageZombies(ctx context.Context, peerUpdate chan *models.Node) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if len(hostZombies) > 0 {
|
||||
logger.Log(3, "checking host zombies")
|
||||
for i := len(hostZombies) - 1; i >= 0; i-- {
|
||||
host, err := GetHost(hostZombies[i].String())
|
||||
if err != nil {
|
||||
logger.Log(1, "error retrieving zombie host", err.Error())
|
||||
logger.Log(1, "deleting ", host.ID.String(), " from zombie list")
|
||||
zombies = append(zombies[:i], zombies[i+1:]...)
|
||||
continue
|
||||
}
|
||||
if len(host.Nodes) == 0 {
|
||||
if err := RemoveHost(host); err != nil {
|
||||
logger.Log(0, "error deleting zombie host", host.ID.String(), err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,10 +149,10 @@ func InitializeZombies() {
|
|||
}
|
||||
if node.HostID == othernode.HostID {
|
||||
if node.LastCheckIn.After(othernode.LastCheckIn) {
|
||||
zombies = append(zombies, othernode.ID)
|
||||
newZombie <- othernode.ID
|
||||
logger.Log(1, "adding", othernode.ID.String(), "to zombie list")
|
||||
} else {
|
||||
zombies = append(zombies, node.ID)
|
||||
newZombie <- node.ID
|
||||
logger.Log(1, "adding", node.ID.String(), "to zombie list")
|
||||
}
|
||||
}
|
||||
|
|
6
main.go
6
main.go
|
@ -118,11 +118,6 @@ func startControllers() {
|
|||
logger.Log(0, "error occurred initializing DNS: ", err.Error())
|
||||
}
|
||||
}
|
||||
if servercfg.IsMessageQueueBackend() {
|
||||
if err := mq.Configure(); err != nil {
|
||||
logger.FatalLog("failed to configure MQ: ", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
//Run Rest Server
|
||||
if servercfg.IsRestBackend() {
|
||||
|
@ -172,7 +167,6 @@ func runMessageQueue(wg *sync.WaitGroup) {
|
|||
defer wg.Done()
|
||||
brokerHost, secure := servercfg.GetMessageQueueEndpoint()
|
||||
logger.Log(0, "connecting to mq broker at", brokerHost, "with TLS?", fmt.Sprintf("%v", secure))
|
||||
mq.SetUpAdminClient()
|
||||
mq.SetupMQTT()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go mq.Keepalive(ctx)
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-ping/ping"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
||||
|
@ -84,28 +81,3 @@ func ResetMetricForNode(server, peerKey, peerID string) {
|
|||
|
||||
// MetricCollectionInterval - collection interval for metrics
|
||||
const MetricCollectionInterval = time.Second * 25
|
||||
|
||||
// PeerConnectionStatus - get peer connection status by pinging
|
||||
func PeerConnectionStatus(address string) (connected bool) {
|
||||
fmt.Println("PINGER ADDR: ", address)
|
||||
pinger, err := ping.NewPinger(address)
|
||||
if err != nil {
|
||||
logger.Log(0, "could not initiliaze ping peer address", address, err.Error())
|
||||
connected = false
|
||||
} else {
|
||||
pinger.Timeout = time.Second * 2
|
||||
err = pinger.Run()
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to ping on peer address", address, err.Error())
|
||||
return false
|
||||
} else {
|
||||
pingStats := pinger.Statistics()
|
||||
if pingStats.PacketsRecv > 0 {
|
||||
connected = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package models
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ApiHost - the host struct for API usage
|
||||
type ApiHost struct {
|
||||
|
@ -76,7 +79,11 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
|
|||
h.ID = currentHost.ID
|
||||
h.HostPass = currentHost.HostPass
|
||||
h.DaemonInstalled = currentHost.DaemonInstalled
|
||||
h.EndpointIP = net.ParseIP(a.EndpointIP)
|
||||
if len(a.EndpointIP) == 0 || strings.Contains(a.EndpointIP, "nil") {
|
||||
h.EndpointIP = currentHost.EndpointIP
|
||||
} else {
|
||||
h.EndpointIP = net.ParseIP(a.EndpointIP)
|
||||
}
|
||||
h.Debug = a.Debug
|
||||
h.FirewallInUse = a.FirewallInUse
|
||||
h.IPForwarding = currentHost.IPForwarding
|
||||
|
|
|
@ -58,7 +58,8 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
|||
convertedNode.Failover = a.Failover
|
||||
convertedNode.IsEgressGateway = a.IsEgressGateway
|
||||
convertedNode.IsIngressGateway = a.IsIngressGateway
|
||||
convertedNode.EgressGatewayRanges = a.EgressGatewayRanges
|
||||
// prevents user from changing ranges, must delete and recreate
|
||||
convertedNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
|
||||
convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange
|
||||
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
|
||||
convertedNode.DNSOn = a.DNSOn
|
||||
|
|
|
@ -2,7 +2,7 @@ package models
|
|||
|
||||
// moved from controllers need work
|
||||
//func TestUpdateNetwork(t *testing.T) {
|
||||
// database.InitializeDatabase()
|
||||
// initialize()
|
||||
// createNet()
|
||||
// network := getNet()
|
||||
// t.Run("NetID", func(t *testing.T) {
|
||||
|
|
|
@ -229,6 +229,8 @@ type ServerConfig struct {
|
|||
DNSMode string `yaml:"dnsmode"`
|
||||
Version string `yaml:"version"`
|
||||
MQPort string `yaml:"mqport"`
|
||||
MQUserName string `yaml:"mq_username"`
|
||||
MQPassword string `yaml:"mq_password"`
|
||||
Server string `yaml:"server"`
|
||||
Broker string `yaml:"broker"`
|
||||
Is_EE bool `yaml:"isee"`
|
||||
|
|
214
mq/dynsec.go
214
mq/dynsec.go
|
@ -1,214 +0,0 @@
|
|||
package mq
|
||||
|
||||
import (
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
// mq client for admin
|
||||
var mqAdminClient mqtt.Client
|
||||
|
||||
const (
|
||||
// constant for client command
|
||||
CreateClientCmd = "createClient"
|
||||
// constant for disable command
|
||||
DisableClientCmd = "disableClient"
|
||||
// constant for delete client command
|
||||
DeleteClientCmd = "deleteClient"
|
||||
// constant for modify client command
|
||||
ModifyClientCmd = "modifyClient"
|
||||
|
||||
// constant for create role command
|
||||
CreateRoleCmd = "createRole"
|
||||
// constant for delete role command
|
||||
DeleteRoleCmd = "deleteRole"
|
||||
|
||||
// constant for admin user name
|
||||
mqAdminUserName = "Netmaker-Admin"
|
||||
// constant for server user name
|
||||
mqNetmakerServerUserName = "Netmaker-Server"
|
||||
// constant for exporter user name
|
||||
mqExporterUserName = "Netmaker-Exporter"
|
||||
|
||||
// DynamicSecSubTopic - constant for dynamic security subscription topic
|
||||
dynamicSecSubTopic = "$CONTROL/dynamic-security/#"
|
||||
// DynamicSecPubTopic - constant for dynamic security subscription topic
|
||||
dynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
|
||||
)
|
||||
|
||||
// struct for dynamic security file
|
||||
type dynJSON struct {
|
||||
Clients []client `json:"clients"`
|
||||
Roles []role `json:"roles"`
|
||||
DefaultAcl defaultAccessAcl `json:"defaultACLAccess"`
|
||||
}
|
||||
|
||||
// struct for client role
|
||||
type clientRole struct {
|
||||
Rolename string `json:"rolename"`
|
||||
}
|
||||
|
||||
// struct for MQ client
|
||||
type client struct {
|
||||
Username string `json:"username"`
|
||||
TextName string `json:"textName"`
|
||||
Password string `json:"password"`
|
||||
Salt string `json:"salt"`
|
||||
Iterations int `json:"iterations"`
|
||||
Roles []clientRole `json:"roles"`
|
||||
}
|
||||
|
||||
// struct for MQ role
|
||||
type role struct {
|
||||
Rolename string `json:"rolename"`
|
||||
Acls []Acl `json:"acls"`
|
||||
}
|
||||
|
||||
// struct for default acls
|
||||
type defaultAccessAcl struct {
|
||||
PublishClientSend bool `json:"publishClientSend"`
|
||||
PublishClientReceive bool `json:"publishClientReceive"`
|
||||
Subscribe bool `json:"subscribe"`
|
||||
Unsubscribe bool `json:"unsubscribe"`
|
||||
}
|
||||
|
||||
// MqDynSecGroup - struct for MQ client group
|
||||
type MqDynSecGroup struct {
|
||||
Groupname string `json:"groupname"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// MqDynSecRole - struct for MQ client role
|
||||
type MqDynSecRole struct {
|
||||
Rolename string `json:"rolename"`
|
||||
Priority int `json:"priority"`
|
||||
}
|
||||
|
||||
// Acl - struct for MQ acls
|
||||
type Acl struct {
|
||||
AclType string `json:"acltype"`
|
||||
Topic string `json:"topic"`
|
||||
Priority int `json:"priority,omitempty"`
|
||||
Allow bool `json:"allow"`
|
||||
}
|
||||
|
||||
// MqDynSecCmd - struct for MQ dynamic security command
|
||||
type MqDynSecCmd struct {
|
||||
Command string `json:"command"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
RoleName string `json:"rolename,omitempty"`
|
||||
Acls []Acl `json:"acls,omitempty"`
|
||||
Clientid string `json:"clientid"`
|
||||
Textname string `json:"textname"`
|
||||
Textdescription string `json:"textdescription"`
|
||||
Groups []MqDynSecGroup `json:"groups"`
|
||||
Roles []MqDynSecRole `json:"roles"`
|
||||
}
|
||||
|
||||
// MqDynsecPayload - struct for dynamic security command payload
|
||||
type MqDynsecPayload struct {
|
||||
Commands []MqDynSecCmd `json:"commands"`
|
||||
}
|
||||
|
||||
// encodePasswordToPBKDF2 - encodes the given password with PBKDF2 hashing for MQ
|
||||
func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLength int) string {
|
||||
binaryEncoded := pbkdf2.Key([]byte(password), []byte(salt), iterations, keyLength, sha512.New)
|
||||
return base64.StdEncoding.EncodeToString(binaryEncoded)
|
||||
}
|
||||
|
||||
// Configure - configures the dynamic initial configuration for MQ
|
||||
func Configure() error {
|
||||
|
||||
logger.Log(0, "Configuring MQ...")
|
||||
dynConfig := dynConfigInI
|
||||
path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
|
||||
|
||||
password := servercfg.GetMqAdminPassword()
|
||||
if password == "" {
|
||||
return errors.New("MQ admin password not provided")
|
||||
}
|
||||
if logic.CheckIfFileExists(path) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err == nil {
|
||||
var cfg dynJSON
|
||||
err = json.Unmarshal(data, &cfg)
|
||||
if err == nil {
|
||||
logger.Log(0, "MQ config exists already, So Updating Existing Config...")
|
||||
dynConfig = cfg
|
||||
}
|
||||
}
|
||||
}
|
||||
exporter := false
|
||||
for i, cI := range dynConfig.Clients {
|
||||
if cI.Username == mqAdminUserName || cI.Username == mqNetmakerServerUserName {
|
||||
salt := logic.RandomString(12)
|
||||
hashed := encodePasswordToPBKDF2(password, salt, 101, 64)
|
||||
cI.Password = hashed
|
||||
cI.Iterations = 101
|
||||
cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
|
||||
dynConfig.Clients[i] = cI
|
||||
} else if servercfg.Is_EE && cI.Username == mqExporterUserName {
|
||||
exporter = true
|
||||
exporterPassword := servercfg.GetLicenseKey()
|
||||
salt := logic.RandomString(12)
|
||||
hashed := encodePasswordToPBKDF2(exporterPassword, salt, 101, 64)
|
||||
cI.Password = hashed
|
||||
cI.Iterations = 101
|
||||
cI.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
|
||||
dynConfig.Clients[i] = cI
|
||||
}
|
||||
}
|
||||
if servercfg.Is_EE && !exporter {
|
||||
exporterPassword := servercfg.GetLicenseKey()
|
||||
salt := logic.RandomString(12)
|
||||
hashed := encodePasswordToPBKDF2(exporterPassword, salt, 101, 64)
|
||||
exporterMQClient.Password = hashed
|
||||
exporterMQClient.Iterations = 101
|
||||
exporterMQClient.Salt = base64.StdEncoding.EncodeToString([]byte(salt))
|
||||
dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
|
||||
}
|
||||
data, err := json.MarshalIndent(dynConfig, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(path, data, 0755)
|
||||
}
|
||||
|
||||
// publishes the message to dynamic security topic
|
||||
func publishEventToDynSecTopic(payload MqDynsecPayload) error {
|
||||
|
||||
d, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var connecterr error
|
||||
if token := mqAdminClient.Publish(dynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
|
||||
if token.Error() == nil {
|
||||
connecterr = errors.New("connect timeout")
|
||||
} else {
|
||||
connecterr = token.Error()
|
||||
}
|
||||
}
|
||||
return connecterr
|
||||
}
|
||||
|
||||
// watchDynSecTopic - message handler for dynamic security responses
|
||||
func watchDynSecTopic(client mqtt.Client, msg mqtt.Message) {
|
||||
|
||||
logger.Log(1, fmt.Sprintf("----->WatchDynSecTopic Message: %+v", string(msg.Payload())))
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package mq
|
||||
|
||||
// MqClient - type for taking in an MQ client's data
|
||||
type MqClient struct {
|
||||
ID string
|
||||
Text string
|
||||
Password string
|
||||
Networks []string
|
||||
}
|
||||
|
||||
// DeleteMqClient - removes a client from the DynSec system
|
||||
func DeleteMqClient(hostID string) error {
|
||||
|
||||
event := MqDynsecPayload{
|
||||
Commands: []MqDynSecCmd{
|
||||
{
|
||||
Command: DeleteClientCmd,
|
||||
Username: hostID,
|
||||
},
|
||||
},
|
||||
}
|
||||
return publishEventToDynSecTopic(event)
|
||||
}
|
||||
|
||||
// CreateMqClient - creates an MQ DynSec client
|
||||
func CreateMqClient(client *MqClient) error {
|
||||
|
||||
event := MqDynsecPayload{
|
||||
Commands: []MqDynSecCmd{
|
||||
{
|
||||
Command: CreateClientCmd,
|
||||
Username: client.ID,
|
||||
Password: client.Password,
|
||||
Textname: client.Text,
|
||||
Roles: []MqDynSecRole{
|
||||
{
|
||||
Rolename: genericRole,
|
||||
Priority: -1,
|
||||
},
|
||||
},
|
||||
Groups: make([]MqDynSecGroup, 0),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return publishEventToDynSecTopic(event)
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
package mq
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
const (
|
||||
// constant for admin role
|
||||
adminRole = "admin"
|
||||
// constant for generic role
|
||||
genericRole = "generic"
|
||||
|
||||
// const for dynamic security file
|
||||
dynamicSecurityFile = "dynamic-security.json"
|
||||
)
|
||||
|
||||
var (
|
||||
// default configuration of dynamic security
|
||||
dynConfigInI = dynJSON{
|
||||
Clients: []client{
|
||||
{
|
||||
Username: mqAdminUserName,
|
||||
TextName: "netmaker admin user",
|
||||
Password: "",
|
||||
Salt: "",
|
||||
Iterations: 0,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: adminRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Username: mqNetmakerServerUserName,
|
||||
TextName: "netmaker server user",
|
||||
Password: "",
|
||||
Salt: "",
|
||||
Iterations: 0,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: genericRole,
|
||||
},
|
||||
},
|
||||
},
|
||||
exporterMQClient,
|
||||
},
|
||||
Roles: []role{
|
||||
{
|
||||
Rolename: adminRole,
|
||||
Acls: fetchAdminAcls(),
|
||||
},
|
||||
{
|
||||
Rolename: genericRole,
|
||||
Acls: fetchGenericAcls(),
|
||||
},
|
||||
},
|
||||
DefaultAcl: defaultAccessAcl{
|
||||
PublishClientSend: false,
|
||||
PublishClientReceive: true,
|
||||
Subscribe: false,
|
||||
Unsubscribe: true,
|
||||
},
|
||||
}
|
||||
|
||||
exporterMQClient = client{
|
||||
Username: mqExporterUserName,
|
||||
TextName: "netmaker metrics exporter",
|
||||
Password: "",
|
||||
Salt: "",
|
||||
Iterations: 101,
|
||||
Roles: []clientRole{
|
||||
{
|
||||
Rolename: genericRole,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// GetAdminClient - fetches admin client of the MQ
|
||||
func GetAdminClient() (mqtt.Client, error) {
|
||||
opts := mqtt.NewClientOptions()
|
||||
setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
|
||||
mqclient := mqtt.NewClient(opts)
|
||||
var connecterr error
|
||||
if token := mqclient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
|
||||
if token.Error() == nil {
|
||||
connecterr = errors.New("connect timeout")
|
||||
} else {
|
||||
connecterr = token.Error()
|
||||
}
|
||||
}
|
||||
return mqclient, connecterr
|
||||
}
|
||||
|
||||
// genericAcls - fetches generice role related acls
|
||||
func fetchGenericAcls() []Acl {
|
||||
return []Acl{
|
||||
{
|
||||
AclType: "publishClientSend",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "publishClientReceive",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "subscribePattern",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "unsubscribePattern",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// fetchAdminAcls - fetches admin role related acls
|
||||
func fetchAdminAcls() []Acl {
|
||||
return []Acl{
|
||||
{
|
||||
AclType: "publishClientSend",
|
||||
Topic: "$CONTROL/dynamic-security/#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "publishClientReceive",
|
||||
Topic: "$CONTROL/dynamic-security/#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "subscribePattern",
|
||||
Topic: "$CONTROL/dynamic-security/#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "publishClientReceive",
|
||||
Topic: "$SYS/#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "subscribePattern",
|
||||
Topic: "$SYS/#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "publishClientReceive",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "subscribePattern",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "unsubscribePattern",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
{
|
||||
AclType: "publishClientSend",
|
||||
Topic: "#",
|
||||
Priority: -1,
|
||||
Allow: true,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -168,12 +168,6 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
|
|||
logger.Log(0, "failed to pulish peer update: ", err.Error())
|
||||
}
|
||||
}
|
||||
if sendPeerUpdate {
|
||||
err := PublishPeerUpdate()
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to pulish peer update: ", err.Error())
|
||||
}
|
||||
}
|
||||
// if servercfg.Is_EE && ifaceDelta {
|
||||
// if err = logic.EnterpriseResetAllPeersFailovers(currentHost.ID.String(), currentHost.Network); err != nil {
|
||||
// logger.Log(1, "failed to reset failover list during node update", currentHost.ID.String(), currentHost.Network)
|
||||
|
|
41
mq/mq.go
41
mq/mq.go
|
@ -2,7 +2,6 @@ package mq
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
|
@ -23,39 +22,6 @@ var peer_force_send = 0
|
|||
|
||||
var mqclient mqtt.Client
|
||||
|
||||
// SetUpAdminClient - sets up admin client for the MQ
|
||||
func SetUpAdminClient() {
|
||||
opts := mqtt.NewClientOptions()
|
||||
setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
|
||||
mqAdminClient = mqtt.NewClient(opts)
|
||||
opts.SetOnConnectHandler(func(client mqtt.Client) {
|
||||
if token := client.Subscribe(dynamicSecSubTopic, 2, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
client.Disconnect(240)
|
||||
logger.Log(0, fmt.Sprintf("Dynamic security client subscription failed: %v ", token.Error()))
|
||||
}
|
||||
|
||||
opts.SetOrderMatters(true)
|
||||
opts.SetResumeSubs(true)
|
||||
})
|
||||
tperiod := time.Now().Add(10 * time.Second)
|
||||
for {
|
||||
if token := mqAdminClient.Connect(); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
|
||||
logger.Log(2, "Admin: unable to connect to broker, retrying ...")
|
||||
if time.Now().After(tperiod) {
|
||||
if token.Error() == nil {
|
||||
logger.FatalLog("Admin: could not connect to broker, token timeout, exiting ...")
|
||||
} else {
|
||||
logger.FatalLog("Admin: could not connect to broker, exiting ...", token.Error().Error())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func setMqOptions(user, password string, opts *mqtt.ClientOptions) {
|
||||
broker, _ := servercfg.GetMessageQueueEndpoint()
|
||||
opts.AddBroker(broker)
|
||||
|
@ -73,7 +39,7 @@ func setMqOptions(user, password string, opts *mqtt.ClientOptions) {
|
|||
// SetupMQTT creates a connection to broker and return client
|
||||
func SetupMQTT() {
|
||||
opts := mqtt.NewClientOptions()
|
||||
setMqOptions(mqNetmakerServerUserName, servercfg.GetMqAdminPassword(), opts)
|
||||
setMqOptions(servercfg.GetMqUserName(), servercfg.GetMqPassword(), opts)
|
||||
opts.SetOnConnectHandler(func(client mqtt.Client) {
|
||||
if token := client.Subscribe("ping/#", 2, mqtt.MessageHandler(Ping)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
|
||||
client.Disconnect(240)
|
||||
|
@ -129,3 +95,8 @@ func Keepalive(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsConnected - function for determining if the mqclient is connected or not
|
||||
func IsConnected() bool {
|
||||
return mqclient != nil && mqclient.IsConnected()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,51 @@
|
|||
#!/bin/bash
|
||||
|
||||
# setup_netclient - installs netclient locally
|
||||
setup_netclient() {
|
||||
|
||||
# DEV_TEMP - Temporary instructions for testing
|
||||
# wget https://fileserver.netmaker.org/testing/netclient
|
||||
# chmod +x netclient
|
||||
# ./netclient install
|
||||
|
||||
# RELEASE_REPLACE - Use this once release is ready
|
||||
# if [ -f /etc/debian_version ]; then
|
||||
# curl -sL 'https://apt.netmaker.org/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/netclient.asc
|
||||
# curl -sL 'https://apt.netmaker.org/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/netclient.list
|
||||
# sudo apt update
|
||||
# sudo apt install netclient
|
||||
# elif [ -f /etc/centos-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/fedora-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/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
|
||||
}
|
||||
|
||||
|
||||
cat << "EOF"
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -184,13 +230,11 @@ wait_seconds 3
|
|||
|
||||
set -e
|
||||
|
||||
NETMAKER_BASE_DOMAIN=nm.$(curl -s ifconfig.me | tr . -).nip.io
|
||||
NETMAKER_BASE_DOMAIN=nm.$(dig myip.opendns.com @resolver1.opendns.com +short | tr . -).nip.io
|
||||
COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
||||
SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
|
||||
SERVER_PUBLIC_IP=$(dig myip.opendns.com @resolver1.opendns.com +short)
|
||||
MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||
MQ_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||
DOMAIN_TYPE=""
|
||||
|
||||
echo "-----------------------------------------------------"
|
||||
echo "Would you like to use your own domain for netmaker, or an auto-generated domain?"
|
||||
echo "To use your own domain, add a Wildcard DNS record (e.x: *.netmaker.example.com) pointing to $SERVER_PUBLIC_IP"
|
||||
|
@ -267,6 +311,49 @@ else
|
|||
EMAIL="$GET_EMAIL"
|
||||
fi
|
||||
|
||||
wait_seconds 1
|
||||
|
||||
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
|
||||
|
||||
|
||||
wait_seconds 2
|
||||
|
||||
echo "-----------------------------------------------------------------"
|
||||
|
@ -301,8 +388,9 @@ if [ "$INSTALL_TYPE" = "ee" ]; then
|
|||
CADDY_URL="https://raw.githubusercontent.com/gravitl/netmaker/master/docker/Caddyfile-EE"
|
||||
fi
|
||||
|
||||
wget -O /root/docker-compose.yml $COMPOSE_URL && wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf && wget -O /root/Caddyfile $CADDY_URL && wget -q -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh && chmod +x /root/wait.sh
|
||||
|
||||
wget -O /root/docker-compose.yml $COMPOSE_URL && wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf && wget -O /root/Caddyfile $CADDY_URL
|
||||
wget -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
|
||||
chmod +x /root/wait.sh
|
||||
mkdir -p /etc/netmaker
|
||||
|
||||
echo "Setting docker-compose and Caddyfile..."
|
||||
|
@ -312,7 +400,8 @@ sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/Caddyfile
|
|||
sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MASTER_KEY/$MASTER_KEY/g" /root/docker-compose.yml
|
||||
sed -i "s/YOUR_EMAIL/$EMAIL/g" /root/Caddyfile
|
||||
sed -i "s/REPLACE_MQ_ADMIN_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MQ_PASSWORD/$MQ_PASSWORD/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MQ_USERNAME/$MQ_USERNAME/g" /root/docker-compose.yml
|
||||
if [ "$INSTALL_TYPE" = "ee" ]; then
|
||||
sed -i "s~YOUR_LICENSE_KEY~$LICENSE_KEY~g" /root/docker-compose.yml
|
||||
sed -i "s/YOUR_ACCOUNT_ID/$ACCOUNT_ID/g" /root/docker-compose.yml
|
||||
|
@ -366,36 +455,28 @@ ACCESS_TOKEN=$(jq -r '.accessstring' <<< ${curlresponse})
|
|||
|
||||
wait_seconds 3
|
||||
|
||||
echo "Configuring netmaker server as ingress gateway"
|
||||
# echo "Installing Netclient"
|
||||
# setup_netclient
|
||||
|
||||
for i in 1 2 3 4 5 6
|
||||
do
|
||||
echo " waiting for server node to become available"
|
||||
wait_seconds 10
|
||||
curlresponse=$(curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/netmaker)
|
||||
SERVER_ID=$(jq -r '.[0].id' <<< ${curlresponse})
|
||||
echo " Server ID: $SERVER_ID"
|
||||
if [ $SERVER_ID == "null" ]; then
|
||||
SERVER_ID=""
|
||||
fi
|
||||
if [[ "$i" -ge "6" && -z "$SERVER_ID" ]]; then
|
||||
echo " Netmaker is having issues configuring itself, please investigate (docker logs netmaker)"
|
||||
echo " Exiting..."
|
||||
exit 1
|
||||
elif [ -z "$SERVER_ID" ]; then
|
||||
echo " server node not yet configured, retrying..."
|
||||
elif [[ ! -z "$SERVER_ID" ]]; then
|
||||
echo " server node is now availble, continuing"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# echo "Adding Netclient to Network"
|
||||
# netclient join -t $ACCESS_TOKEN
|
||||
|
||||
# # TODO - Get Host ID
|
||||
|
||||
|
||||
if [[ ! -z "$SERVER_ID" ]]; then
|
||||
curl -o /dev/null -s -X POST -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/netmaker/$SERVER_ID/createingress
|
||||
fi
|
||||
# echo "Setting Netclient as Default Host"
|
||||
# HOST_ID=$(grep 'id:' /etc/netclient/netclient.yml | awk '{print $2}')
|
||||
# echo $HOST_ID
|
||||
# # TODO - API call to make host default
|
||||
|
||||
# echo "Setting Netclient as Ingress Gateway"
|
||||
# if [[ ! -z "$SERVER_ID" ]]; then
|
||||
# curl -o /dev/null -s -X POST -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/netmaker/$HOST_ID/createingress
|
||||
# fi
|
||||
)}
|
||||
|
||||
|
||||
|
||||
set +e
|
||||
test_connection
|
||||
|
||||
|
|
|
@ -1,304 +0,0 @@
|
|||
#!/bin/bash
|
||||
echo "checking for root permissions..."
|
||||
|
||||
echo "setting flags..."
|
||||
|
||||
while getopts d:e:m:v:c: flag
|
||||
do
|
||||
case "${flag}" in
|
||||
d) domain=${OPTARG};;
|
||||
e) email=${OPTARG};;
|
||||
m) addmesh=${OPTARG};;
|
||||
v) addvpn=${OPTARG};;
|
||||
c) num_clients=${OPTARG};;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "checking for root permissions..."
|
||||
|
||||
|
||||
if [ $EUID -ne 0 ]; then
|
||||
echo "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
echo "checking dependencies..."
|
||||
|
||||
declare -A osInfo;
|
||||
osInfo[/etc/debian_version]="apt-get install -y"u
|
||||
osInfo[/etc/alpine-release]="apk --update add"
|
||||
osInfo[/etc/centos-release]="yum install -y"
|
||||
osInfo[/etc/fedora-release]="dnf install -y"
|
||||
|
||||
for f in ${!osInfo[@]}
|
||||
do
|
||||
if [[ -f $f ]];then
|
||||
install_cmd=${osInfo[$f]}
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -f /etc/debian_version ]; then
|
||||
apt update
|
||||
elif [ -f /etc/alpine-release ]; then
|
||||
apk update
|
||||
elif [ -f /etc/centos-release ]; then
|
||||
yum update
|
||||
elif [ -f /etc/fedora-release ]; then
|
||||
dnf update
|
||||
fi
|
||||
|
||||
dependencies=( "docker.io" "docker-compose" "wireguard" "jq" )
|
||||
|
||||
for dependency in ${dependencies[@]}; do
|
||||
is_installed=$(dpkg-query -W --showformat='${Status}\n' ${dependency} | grep "install ok installed")
|
||||
|
||||
if [ "${is_installed}" == "install ok installed" ]; then
|
||||
echo " " ${dependency} is installed
|
||||
else
|
||||
echo " " ${dependency} is not installed. Attempting install.
|
||||
${install_cmd} ${dependency}
|
||||
sleep 5
|
||||
is_installed=$(dpkg-query -W --showformat='${Status}\n' ${dependency} | grep "install ok installed")
|
||||
if [ "${is_installed}" == "install ok installed" ]; then
|
||||
echo " " ${dependency} is installed
|
||||
elif [ -x "$(command -v ${dependency})" ]; then
|
||||
echo " " ${dependency} is installed
|
||||
else
|
||||
echo " " failed to install ${dependency}. Exiting.
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
set -e
|
||||
|
||||
NETMAKER_BASE_DOMAIN=nm.$(curl -s ifconfig.me | tr . -).nip.io
|
||||
COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
|
||||
SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
|
||||
MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
|
||||
EMAIL="$(echo $RANDOM | md5sum | head -c 32)@email.com"
|
||||
MQ_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 64 ; echo '')
|
||||
if [ -n "$domain" ]; then
|
||||
NETMAKER_BASE_DOMAIN=$domain
|
||||
fi
|
||||
|
||||
if [ -n "$email" ]; then
|
||||
EMAIL=$email
|
||||
fi
|
||||
|
||||
if [ -n "$addmesh" ]; then
|
||||
MESH_SETUP=$addmesh
|
||||
else
|
||||
MESH_SETUP="true"
|
||||
fi
|
||||
|
||||
if [ -n "$addvpn" ]; then
|
||||
VPN_SETUP=$addvpn
|
||||
else
|
||||
VPN_SETUP="false"
|
||||
fi
|
||||
|
||||
if [ -n "$num_clients" ]; then
|
||||
NUM_CLIENTS=$num_clients
|
||||
else
|
||||
NUM_CLIENTS=5
|
||||
fi
|
||||
|
||||
|
||||
echo " ----------------------------"
|
||||
echo " SETUP ARGUMENTS"
|
||||
echo " ----------------------------"
|
||||
echo " domain: $NETMAKER_BASE_DOMAIN"
|
||||
echo " email: $EMAIL"
|
||||
echo " coredns ip: $COREDNS_IP"
|
||||
echo " public ip: $SERVER_PUBLIC_IP"
|
||||
echo " master key: $MASTER_KEY"
|
||||
echo " setup mesh?: $MESH_SETUP"
|
||||
echo " setup vpn?: $VPN_SETUP"
|
||||
if [ "${VPN_SETUP}" == "true" ]; then
|
||||
echo " # clients: $NUM_CLIENTS"
|
||||
fi
|
||||
echo " ----------------------------"
|
||||
|
||||
sleep 5
|
||||
|
||||
echo "setting mosquitto.conf..."
|
||||
|
||||
wget -q -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
|
||||
wget -q -O /root/Caddyfile https://raw.githubusercontent.com/gravitl/netmaker/master/docker/Caddyfile
|
||||
wget -q -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
|
||||
chmod +x /root/wait.sh
|
||||
echo "setting docker-compose..."
|
||||
|
||||
mkdir -p /etc/netmaker
|
||||
|
||||
wget -q -O /root/docker-compose.yml https://raw.githubusercontent.com/gravitl/netmaker/master/compose/docker-compose.yml
|
||||
sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/docker-compose.yml
|
||||
sed -i "s/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g" /root/Caddyfile
|
||||
sed -i "s/SERVER_PUBLIC_IP/$SERVER_PUBLIC_IP/g" /root/docker-compose.yml
|
||||
sed -i "s/COREDNS_IP/$COREDNS_IP/g" /root/docker-compose.yml
|
||||
sed -i "s/REPLACE_MASTER_KEY/$MASTER_KEY/g" /root/docker-compose.yml
|
||||
sed -i "s/YOUR_EMAIL/$EMAIL/g" /root/Caddyfile
|
||||
sed -i "s/REPLACE_MQ_ADMIN_PASSWORD/$MQ_ADMIN_PASSWORD/g" /root/docker-compose.yml
|
||||
echo "starting containers..."
|
||||
|
||||
docker-compose -f /root/docker-compose.yml up -d
|
||||
|
||||
test_connection() {
|
||||
|
||||
echo "testing Caddy setup (please be patient, this may take 1-2 minutes)"
|
||||
for i in 1 2 3 4 5 6 7 8
|
||||
do
|
||||
curlresponse=$(curl -vIs https://api.${NETMAKER_BASE_DOMAIN} 2>&1)
|
||||
|
||||
if [[ "$i" == 8 ]]; then
|
||||
echo " Caddy is having an issue setting up certificates, please investigate (docker logs caddy)"
|
||||
echo " exiting..."
|
||||
exit 1
|
||||
elif [[ "$curlresponse" == *"failed to verify the legitimacy of the server"* ]]; then
|
||||
echo " certificates not yet configured, retrying..."
|
||||
|
||||
elif [[ "$curlresponse" == *"left intact"* ]]; then
|
||||
echo " certificates ok"
|
||||
break
|
||||
else
|
||||
secs=$(($i*5+10))
|
||||
echo " issue establishing connection...retrying in $secs seconds..."
|
||||
fi
|
||||
sleep $secs
|
||||
done
|
||||
}
|
||||
|
||||
set +e
|
||||
test_connection
|
||||
|
||||
|
||||
cat << "EOF"
|
||||
|
||||
|
||||
__ __ ______ ______ __ __ ______ __ __ ______ ______
|
||||
/\ "-.\ \ /\ ___\ /\__ _\ /\ "-./ \ /\ __ \ /\ \/ / /\ ___\ /\ == \
|
||||
\ \ \-. \ \ \ __\ \/_/\ \/ \ \ \-./\ \ \ \ __ \ \ \ _"-. \ \ __\ \ \ __<
|
||||
\ \_\\"\_\ \ \_____\ \ \_\ \ \_\ \ \_\ \ \_\ \_\ \ \_\ \_\ \ \_____\ \ \_\ \_\
|
||||
\/_/ \/_/ \/_____/ \/_/ \/_/ \/_/ \/_/\/_/ \/_/\/_/ \/_____/ \/_/ /_/
|
||||
|
||||
|
||||
EOF
|
||||
|
||||
|
||||
echo "visit https://dashboard.$NETMAKER_BASE_DOMAIN to log in"
|
||||
echo "visit https://grafana.$NETMAKER_BASE_DOMAIN to view metrics on grafana dashboard"
|
||||
echo "visit https://prometheus.$NETMAKER_BASE_DOMAIN to view metrics on prometheus"
|
||||
sleep 7
|
||||
|
||||
setup_mesh() {( set -e
|
||||
echo "creating netmaker network (10.101.0.0/16)"
|
||||
|
||||
curl -s -o /dev/null -d '{"addressrange":"10.101.0.0/16","netid":"netmaker"}' -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/networks
|
||||
|
||||
sleep 5
|
||||
|
||||
echo "creating netmaker access key"
|
||||
|
||||
curlresponse=$(curl -s -d '{"uses":99999,"name":"netmaker-key"}' -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/networks/netmaker/keys)
|
||||
ACCESS_TOKEN=$(jq -r '.accessstring' <<< ${curlresponse})
|
||||
|
||||
sleep 5
|
||||
|
||||
echo "configuring netmaker server as ingress gateway"
|
||||
|
||||
curlresponse=$(curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/netmaker)
|
||||
SERVER_ID=$(jq -r '.[0].id' <<< ${curlresponse})
|
||||
|
||||
curl -o /dev/null -s -X POST -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/netmaker/$SERVER_ID/createingress
|
||||
|
||||
sleep 5
|
||||
|
||||
echo "finished configuring server and network. You can now add clients."
|
||||
echo ""
|
||||
echo "For Linux, Mac, Windows, and FreeBSD:"
|
||||
echo " 1. Install the netclient: https://docs.netmaker.org/netclient.html#installation"
|
||||
echo " 2. Join the network: netclient join -t $ACCESS_TOKEN"
|
||||
echo ""
|
||||
echo "For Android and iOS clients, perform the following steps:"
|
||||
echo " 1. Log into UI at dashboard.$NETMAKER_BASE_DOMAIN"
|
||||
echo " 2. Navigate to \"EXTERNAL CLIENTS\" tab"
|
||||
echo " 3. Select the gateway and create clients"
|
||||
echo " 4. Scan the QR Code from WireGuard app in iOS or Android"
|
||||
echo ""
|
||||
echo "Netmaker setup is now complete. You are ready to begin using Netmaker."
|
||||
)}
|
||||
|
||||
setup_vpn() {( set -e
|
||||
echo "creating vpn network (10.201.0.0/16)"
|
||||
|
||||
curl -s -o /dev/null -d '{"addressrange":"10.201.0.0/16","netid":"vpn","defaultextclientdns":"10.201.255.254"}' -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/networks
|
||||
|
||||
sleep 5
|
||||
|
||||
echo "configuring netmaker server as vpn inlet..."
|
||||
|
||||
curlresponse=$(curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/vpn)
|
||||
SERVER_ID=$(jq -r '.[0].id' <<< ${curlresponse})
|
||||
|
||||
curl -s -o /dev/null -X POST -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/vpn/$SERVER_ID/createingress
|
||||
|
||||
echo "waiting 5 seconds for server to apply configuration..."
|
||||
|
||||
sleep 5
|
||||
|
||||
|
||||
echo "configuring netmaker server vpn gateway..."
|
||||
|
||||
[ -z "$GATEWAY_IFACE" ] && GATEWAY_IFACE=$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)')
|
||||
|
||||
echo "gateway iface: $GATEWAY_IFACE"
|
||||
|
||||
curlresponse=$(curl -s -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/vpn)
|
||||
SERVER_ID=$(jq -r '.[0].id' <<< ${curlresponse})
|
||||
|
||||
EGRESS_JSON=$( jq -n \
|
||||
--arg gw "$GATEWAY_IFACE" \
|
||||
'{ranges: ["0.0.0.0/0"], interface: $gw}' )
|
||||
|
||||
echo "egress json: $EGRESS_JSON"
|
||||
curl -s -o /dev/null -X POST -d "$EGRESS_JSON" -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/nodes/vpn/$SERVER_ID/creategateway
|
||||
|
||||
sleep 3
|
||||
|
||||
echo "creating client configs..."
|
||||
|
||||
for ((a=1; a <= $NUM_CLIENTS; a++))
|
||||
do
|
||||
CLIENT_JSON=$( jq -n \
|
||||
--arg clientid "vpnclient-$a" \
|
||||
'{clientid: $clientid}' )
|
||||
|
||||
curl -s -o /dev/null -d "$CLIENT_JSON" -H "Authorization: Bearer $MASTER_KEY" -H 'Content-Type: application/json' https://api.${NETMAKER_BASE_DOMAIN}/api/extclients/vpn/$SERVER_ID
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "finished configuring vpn server."
|
||||
echo ""
|
||||
echo "To configure clients, perform the following steps:"
|
||||
echo " 1. log into dashboard.$NETMAKER_BASE_DOMAIN"
|
||||
echo " 2. Navigate to \"EXTERNAL CLIENTS\" tab"
|
||||
echo " 3. Download or scan a client config (vpnclient-x) to the appropriate device"
|
||||
echo " 4. Follow the steps for your system to configure WireGuard on the appropriate device"
|
||||
echo " 5. Create and delete clients as necessary. Changes to netmaker server settings require regenerating ext clients."
|
||||
|
||||
)}
|
||||
|
||||
if [ "${MESH_SETUP}" != "false" ]; then
|
||||
setup_mesh
|
||||
fi
|
||||
|
||||
if [ "${VPN_SETUP}" == "true" ]; then
|
||||
setup_vpn
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Netmaker setup is now complete. You are ready to begin using Netmaker."
|
|
@ -88,6 +88,8 @@ func GetServerInfo() models.ServerConfig {
|
|||
var cfg models.ServerConfig
|
||||
cfg.Server = GetServer()
|
||||
cfg.Broker = GetBroker()
|
||||
cfg.MQUserName = GetMqUserName()
|
||||
cfg.MQPassword = GetMqPassword()
|
||||
cfg.API = GetAPIConnString()
|
||||
cfg.CoreDNSAddr = GetCoreDNSAddr()
|
||||
cfg.APIPort = GetAPIPort()
|
||||
|
@ -589,13 +591,24 @@ func GetMQServerPort() string {
|
|||
return port
|
||||
}
|
||||
|
||||
// GetMqAdminPassword - fetches the MQ Admin password
|
||||
func GetMqAdminPassword() string {
|
||||
// GetMqPassword - fetches the MQ password
|
||||
func GetMqPassword() string {
|
||||
password := ""
|
||||
if os.Getenv("MQ_ADMIN_PASSWORD") != "" {
|
||||
password = os.Getenv("MQ_ADMIN_PASSWORD")
|
||||
} else if config.Config.Server.MQAdminPassword != "" {
|
||||
password = config.Config.Server.MQAdminPassword
|
||||
if os.Getenv("MQ_PASSWORD") != "" {
|
||||
password = os.Getenv("MQ_PASSWORD")
|
||||
} else if config.Config.Server.MQPassword != "" {
|
||||
password = config.Config.Server.MQPassword
|
||||
}
|
||||
return password
|
||||
}
|
||||
|
||||
// GetMqUserName - fetches the MQ username
|
||||
func GetMqUserName() string {
|
||||
password := ""
|
||||
if os.Getenv("MQ_USERNAME") != "" {
|
||||
password = os.Getenv("MQ_USERNAME")
|
||||
} else if config.Config.Server.MQUserName != "" {
|
||||
password = config.Config.Server.MQUserName
|
||||
}
|
||||
return password
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package stunserver
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
@ -71,7 +70,6 @@ func (s *Server) serveConn(c net.PacketConn, res, req *stun.Message) error {
|
|||
logger.Log(1, "ReadFrom: %v", err.Error())
|
||||
return nil
|
||||
}
|
||||
log.Printf("read %d bytes from %s\n", n, addr)
|
||||
if _, err = req.Write(buf[:n]); err != nil {
|
||||
logger.Log(1, "Write: %v", err.Error())
|
||||
return err
|
||||
|
|
|
@ -718,7 +718,7 @@ info:
|
|||
|
||||
API calls must be authenticated via a header of the format -H “Authorization: Bearer <YOUR_SECRET_KEY>” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes/<network>/authenticate endpoint, as documented below.
|
||||
title: Netmaker
|
||||
version: 0.17.1
|
||||
version: 0.18.0
|
||||
paths:
|
||||
/api/dns:
|
||||
get:
|
||||
|
|
Loading…
Add table
Reference in a new issue