mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-02 18:04:23 +08:00
Merge branch 'develop' into refactor-controllers
This commit is contained in:
commit
073be947c6
37 changed files with 2517 additions and 1283 deletions
16
Dockerfile
16
Dockerfile
|
@ -1,6 +1,6 @@
|
|||
#first stage - builder
|
||||
|
||||
FROM golang:1.14-stretch as builder
|
||||
FROM golang:latest as builder
|
||||
|
||||
COPY . /app
|
||||
|
||||
|
@ -10,22 +10,28 @@ ENV GO111MODULE=auto
|
|||
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o app main.go
|
||||
|
||||
WORKDIR /app/netclient
|
||||
|
||||
ENV GO111MODULE=auto
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o netclient main.go
|
||||
|
||||
#second stage
|
||||
|
||||
FROM alpine:latest
|
||||
FROM debian:latest
|
||||
|
||||
RUN apt-get update && apt-get -y install systemd procps
|
||||
|
||||
WORKDIR /root/
|
||||
|
||||
RUN apk add --no-cache tzdata
|
||||
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
|
||||
COPY --from=builder /app .
|
||||
COPY --from=builder /app/config config
|
||||
COPY --from=builder /app/netclient netclient
|
||||
|
||||
EXPOSE 8081
|
||||
EXPOSE 50051
|
||||
|
||||
CMD ["./app", "--clientmode=off"]
|
||||
CMD ["./app"]
|
||||
|
||||
|
|
105
README.md
105
README.md
|
@ -1,3 +1,4 @@
|
|||
|
||||
<p align="center">
|
||||
<img src="netmaker.png"><break/>
|
||||
</p>
|
||||
|
@ -6,7 +7,11 @@
|
|||
</p>
|
||||
|
||||
## What is Netmaker?
|
||||
Netmaker is a tool for creating and managing virtual networks. The goal is to provide functionality similar to Tailscale, ZeroTier, and Nebula, but faster, easier, and more dynamic. It should be like clicking a button. Netmaker consists of a server, an agent, and a UI. You spin up the Netmaker server and then install netclient (the agent) on your computers. Netmaker will do the rest. It will tell all of your computers how to reach each other and will keep them informed of any changes to the network.
|
||||
Netmaker is a tool for creating and managing virtual networks. If you have servers spread across multiple locations, data centers, or clouds, they all live on separate networks. This can make life very difficult. Netmaker takes all those machines and puts them on a single, flat network so that they can talk to each other easily and securely.
|
||||
|
||||
Think of it like Tailscale, ZeroTier, or Nebula, but faster, easier, and more dynamic.
|
||||
|
||||
You spin up the Netmaker server and UI, and then install the Netclient (agent) on your computers. Netmaker will do the rest. It will tell all of your computers how to reach each other and will keep them informed of any changes to the network.
|
||||
|
||||
Netmaker's handy dandy UI can be found [here](https://github.com/gravitl/netmaker-ui).
|
||||
|
||||
|
@ -28,7 +33,9 @@ Under the hood, Netmaker uses WireGuard to create encrypted tunnels between ever
|
|||
|
||||
## Compatible Systems
|
||||
|
||||
Netmaker works on most linux systems that have systemd. It works with Fedora, Ubuntu, and Raspian. Just make sure you have WireGuard installed. Having a problem? Open an issue or Contact us.
|
||||
Netmaker is primarily designed for **linux**, specifically **systemd-based linux.** This includes Fedora, Ubuntu, and Raspian. Just make sure you have WireGuard installed. Having a problem? Open an issue or Contact us.
|
||||
|
||||
In version 0.3 we have released Private DNS. Nameservers can be configured manually on any system, but to have the Netclient add dns automatically, it requires **resolvectl.**
|
||||
|
||||
In future releases, we have plans to support other platforms such as Windows and MacOS.
|
||||
|
||||
|
@ -47,33 +54,91 @@ In future releases, we have plans to support other platforms such as Windows and
|
|||
|
||||
[Intro/Overview Video Tutorial](https://youtu.be/PWLPT320Ybo)
|
||||
[Site-to-Site Video Tutorial](https://youtu.be/krCKBJhwwDk)
|
||||
|
||||
#### Prereqs:
|
||||
1. A server with an IP reachable by your computers (a small ec2 instance or droplet would do just fine).
|
||||
2. Linux installed on the above server (we use Ubuntu, but anything that runs Docker should work).
|
||||
3. Install Docker if running in Docker Mode (see below).
|
||||
|
||||
### Note about permissions
|
||||
The default installation requires special privileges on the server side, because Netmaker will control the local kernel Wireguard. This can be turned off and run in non-privileged mode if necessary (but disables some features). For more details, see the **Usage** docs.
|
||||
|
||||
### Prereqs
|
||||
1. A running linux server to host Netmaker, with an IP reachable by your computers (Debian-based preferred but not required).
|
||||
2. Linux installed on the above server (Debian-based preferred but not required).
|
||||
3. Install Docker and Docker Compose if running in Docker Mode (see below).
|
||||
4. System dependencies installed:
|
||||
- Docker (if running in default Docker mode. DO NOT use snap install for docker.)
|
||||
- Docker Compose
|
||||
- Wireguard + Resolvectl (if running in default Client mode)
|
||||
|
||||
#### CoreDNS Preparation
|
||||
v0.3 introduces CoreDNS as a private nameserver. To run CoreDNS on your server host, you must disable systemd-resolved to open port 53:
|
||||
1. systemctl stop systemd-resolved
|
||||
2. systemctl disable systemd-resolved
|
||||
3. vim /etc/systemd/resolved.conf
|
||||
- uncomment **DNS=** and add 8.8.8.8 or whatever is your preference
|
||||
- uncomment **DNSStubListener=** and set to **"no"**
|
||||
4. sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||
|
||||
|
||||
#### Launch Netmaker:
|
||||
|
||||
Netmaker v0.2 introduces the server as a 'client'. This means the server can add itself into networks if you would like. To do so, Netmaker requires privileged access where it is running, and needs to modify the host filesystem. To run in this mode, we are not currently using Docker.
|
||||
|
||||
**If you would like to run with "client mode", you can use the following script to deploy:**
|
||||
`sudo curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/v0.2/netmaker-install-clientmode.sh | sudo SERVER_DOMAIN=< your server IP > sh -`
|
||||
|
||||
**If you would like to run without "client mode", and manually add/remove the server from networks:**
|
||||
### Launch Netmaker
|
||||
Note, this installs Netmaker with CoreDNS and a Netclient (privileged). If you want to run the server non-privileged or without CoreDNS, see the advanced usage docs.
|
||||
|
||||
1. Clone this repo or just copy contents of "docker-compose.yml" to your Netmaker server (from prereqs).
|
||||
2. In docker-compose.yml, change BACKEND_URL to the public IP of your server.
|
||||
3. Run `sudo docker-compose up`
|
||||
4. Navigate to your server's IP in the browser and you should see the Netmaker UI asking to create a new admin user.
|
||||
5. Create a new admin user
|
||||
6. You are now ready to begin using Netmaker. There should be a default network you can use or you can create your own. Then, Create a key or enable manual node sign up so that your nodes can connect.
|
||||
6. You are now ready to begin using Netmaker.
|
||||
|
||||
#### On your machines :
|
||||
A command will be displayed when you generate a token for signing up nodes. Run it on each machine you would like to connect.
|
||||
`curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/v0.2/netclient-install.sh | KEY=<your access key> sh -`
|
||||
(Note: Key can be left out if manual node signup is enabled)
|
||||
### Create a Network
|
||||
You can also just use the "default" network.
|
||||
1. Click "CREATE NETWORK" in the upper left of your console
|
||||
2. Enter a valid address range, e.g. 10.11.12.0/24
|
||||
3. Enter a name such as "homenet"
|
||||
4. Additional options:
|
||||
- **Dual Stack**: Machines will recieve a private IPv6 address in addition to their IPv4 address.
|
||||
- **Local:** Will use local address range for endpoints instead of public. Use Case: Home or Office network where most devices do not have public IP's. In this case you can create a gateway into the network after creating the Local Network.
|
||||
|
||||
After Network creation, you can edit the network in the NETWORK DETAILS pane, modifying the address range and default options. You can also toggle on **Allow Node Signup Without Keys**, which makes the next step unnecessary, but allows anyone to create a node in your network, which will be cordoned in pending state.
|
||||
|
||||
### Create Keys
|
||||
1. Click the "ACCESS KEYS" tab
|
||||
2. Click "ADD NEW ACCESSS KEY"
|
||||
3. Give your key a name and number of uses
|
||||
4. Several values will be displayed. Save these somewhere, as they will only be displayed once:
|
||||
- **Access Key:** Use only in special edge cases where server connection string must be modified
|
||||
- **Access Token:** Use on machines that already have the netclient utility
|
||||
- **Install Command:** Use on machines that do not have the netclient utility
|
||||
|
||||
### Install Agent:
|
||||
For machines **without** netclient, run the install command (from above): `curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/v0.2/netclient-install.sh | KEY=<your access key> sh -`
|
||||
For machines **with** netclient run the following (with access token from above): `sudo netclient -c install -t <access token>`
|
||||
For networks with **manual signup** enabled (see above), install using the network name: `sudo netclient -c install -n <network name>`
|
||||
|
||||
### Manage Nodes
|
||||
Your machines should now be visible in the control pane.
|
||||
**Modify nodes:** Click the pencil icon in the NODES pane to modify details like WireGuard port, address, and node name. You can also **DELETE** nodes here and they will lose network access.
|
||||
**Approve nodes:** If a node is in pending state (signed up without key), you can approve it. An icon will appear for pending nodes that need approval.
|
||||
|
||||
**Gateway Mode:** Click the Gateway icon to enable gateway mode on a given node. A popup will allow you to choose an existing network, or enter a custom address range.
|
||||
*Example: You create a network in netmaker called Homenet. It has several machines on your home server. You create another network called Cloudnet. It has several machines in AWS. You have one server (server X) which is added to both networks. On Cloudnet, you make Server X a gateway to Homenet. Now, the cloudnet machines have access to your homenet machines. via Server X.*
|
||||
|
||||
*On Homenet, you add Server Y, a machine in AWS, and make it a gateway to a custom address range 172.16.0.0/16. The machines on your home network now have access to any AWS machines in that address range via Server Y*
|
||||
|
||||
### Manage DNS
|
||||
On the DNS tab you can create custom DNS entries for a given network.
|
||||
|
||||
1. All dns entries will be *postfixed* with a private TLD of the network name, for example, ".mynet"
|
||||
2. Default DNS is created for node name + TLD, for instance, node-c42wt.mynet. This is not editable.
|
||||
3. Click ADD ENTRY to add custom DNS
|
||||
- You can click CHOOSE NODE to direct DNS to a specific node in the network
|
||||
- You can also specify any custom address you would like, which can be outside the network (for instance, the IP for google.com)
|
||||
- Add a dns entry name, which will be postfixed with the network TLD. E.g. if you enter "privateapi.com", it will become "privateapi.com.networkname"
|
||||
|
||||
### Uninstalling Client
|
||||
To uninstall the client from a network: `sudo netclient -c remove -n < networkname >`
|
||||
To uninstall entirely, run the above for each network, and then run `sudo rm -rf /etc/netclient`
|
||||
|
||||
### Uninstralling Netmaker
|
||||
To uninstall the netmaker server, simply run `docker-compose down`
|
||||
|
||||
#### LICENSE
|
||||
|
||||
|
@ -81,5 +146,5 @@ Netmaker's source code and all artifacts in this repository are freely available
|
|||
|
||||
#### CONTACT
|
||||
|
||||
Email: info@gravitl.com
|
||||
Email: alex@gravitl.com
|
||||
Discord: https://discord.gg/zRb9Vfhk8A
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
//setting dev by default
|
||||
func getEnv() string {
|
||||
|
||||
env := os.Getenv("APP_ENV")
|
||||
env := os.Getenv("NETMAKER_ENV")
|
||||
|
||||
if len(env) == 0 {
|
||||
return "dev"
|
||||
|
@ -35,16 +35,17 @@ type EnvironmentConfig struct {
|
|||
|
||||
// ServerConfig :
|
||||
type ServerConfig struct {
|
||||
Host string `yaml:"host"`
|
||||
ApiPort string `yaml:"apiport"`
|
||||
GrpcPort string `yaml:"grpcport"`
|
||||
APIHost string `yaml:"apihost"`
|
||||
APIPort string `yaml:"apiport"`
|
||||
GRPCHost string `yaml:"grpchost"`
|
||||
GRPCPort string `yaml:"grpcport"`
|
||||
MasterKey string `yaml:"masterkey"`
|
||||
AllowedOrigin string `yaml:"allowedorigin"`
|
||||
RestBackend bool `yaml:"restbackend"`
|
||||
AgentBackend bool `yaml:"agentbackend"`
|
||||
DefaultNetName string `yaml:"defaultnetname"`
|
||||
DefaultNetRange string `yaml:"defaultnetrange"`
|
||||
CreateDefault bool `yaml:"createdefault"`
|
||||
RestBackend string `yaml:"restbackend"`
|
||||
AgentBackend string `yaml:"agentbackend"`
|
||||
ClientMode string `yaml:"clientmode"`
|
||||
DNSMode string `yaml:"dnsmode"`
|
||||
DisableRemoteIPCheck string `yaml:"disableremoteipcheck"`
|
||||
}
|
||||
|
||||
type MongoConnConfig struct {
|
||||
|
@ -60,13 +61,16 @@ type MongoConnConfig struct {
|
|||
func readConfig() *EnvironmentConfig {
|
||||
file := fmt.Sprintf("config/environments/%s.yaml", getEnv())
|
||||
f, err := os.Open(file)
|
||||
var cfg EnvironmentConfig
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
os.Exit(2)
|
||||
//log.Fatal(err)
|
||||
//os.Exit(2)
|
||||
log.Println("Unable to open config file at config/environments/" + getEnv())
|
||||
log.Println("Will proceed with defaults or enironment variables (no config file).")
|
||||
return &cfg
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var cfg EnvironmentConfig
|
||||
decoder := yaml.NewDecoder(f)
|
||||
err = decoder.Decode(&cfg)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
server:
|
||||
host: "localhost"
|
||||
apiport: "8081"
|
||||
grpcport: "50051"
|
||||
masterkey: "secretkey"
|
||||
allowedorigin: "*"
|
||||
restbackend: true
|
||||
agentbackend: true
|
||||
defaultnetname: "default"
|
||||
defaultnetrange: "10.10.10.0/24"
|
||||
createdefault: true
|
||||
apihost: "" # defaults to 127.0.0.1 or remote ip (SERVER_HOST) if DisableRemoteIPCheck is not set to true. SERVER_API_HOST if set
|
||||
apiport: "" # defaults to 8081 or HTTP_PORT (if set)
|
||||
grpchost: "" # defaults to 127.0.0.1 or remote ip (SERVER_HOST) if DisableRemoteIPCheck is not set to true. SERVER_GRPC_HOST if set.
|
||||
grpcport: "" # defaults to 50051 or GRPC_PORT (if set)
|
||||
masterkey: "" # defaults to 'secretkey' or MASTER_KEY (if set)
|
||||
allowedorigin: "" # defaults to '*' or CORS_ALLOWED_ORIGIN (if set)
|
||||
restbackend: "" # defaults to "on" or REST_BACKEND (if set)
|
||||
agentbackend: "" # defaults to "on" or AGENT_BACKEND (if set)
|
||||
clientmode: "" # defaults to "on" or CLIENT_MODE (if set)
|
||||
dnsmode: "" # defaults to "on" or DNS_MODE (if set)
|
||||
disableremoteipcheck: "" # defaults to "false" or DISABLE_REMOTE_IP_CHECK (if set)
|
||||
mongoconn:
|
||||
user: "mongoadmin"
|
||||
pass: "mongopass"
|
||||
host: "localhost"
|
||||
port: "27017"
|
||||
opts: '/?authSource=admin'
|
||||
user: "" # defaults to "mongoadmin" or MONGO_ADMIN (if set)
|
||||
pass: "" # defaults to "mongopass" or MONGO_PASS (if set)
|
||||
host: "" # defaults to 127.0.0.1 or MONGO_HOST (if set)
|
||||
port: "" # defaults to 27017 or MONGO_PORT (if set)
|
||||
opts: '' # defaults to '/?authSource=admin' or MONGO_OPTS (if set)
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
@ -210,6 +211,9 @@ func UpdateNode(nodechange models.NodeUpdate, node models.Node) (models.Node, er
|
|||
if notifynetwork {
|
||||
errN = SetNetworkNodesLastModified(queryNetwork)
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
errN = SetDNS()
|
||||
}
|
||||
|
||||
return returnnode, errN
|
||||
}
|
||||
|
@ -236,6 +240,9 @@ func DeleteNode(macaddress string, network string) (bool, error) {
|
|||
|
||||
err = SetNetworkNodesLastModified(network)
|
||||
fmt.Println("Deleted node " + macaddress + " from network " + network)
|
||||
if servercfg.IsDNSMode() {
|
||||
err = SetDNS()
|
||||
}
|
||||
|
||||
return deleted, err
|
||||
}
|
||||
|
@ -279,16 +286,12 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
|
|||
//Anyways, this scrolls through all the IP Addresses in the network range and checks against nodes
|
||||
//until one is open and then returns it
|
||||
node.Address, err = functions.UniqueAddress(networkName)
|
||||
fmt.Println("Setting node address: " + node.Address)
|
||||
if err != nil {
|
||||
return node, err
|
||||
}
|
||||
fmt.Println("Setting node address: " + node.Address)
|
||||
|
||||
node.Address6, err = functions.UniqueAddress6(networkName)
|
||||
if node.Address6 != "" {
|
||||
fmt.Println("Setting node ipv6 address: " + node.Address6)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return node, err
|
||||
}
|
||||
|
@ -330,7 +333,9 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
|
|||
}
|
||||
|
||||
SetNetworkNodesLastModified(node.Network)
|
||||
|
||||
if servercfg.IsDNSMode() {
|
||||
err = SetDNS()
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package controller
|
|||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"os/signal"
|
||||
"os"
|
||||
"fmt"
|
||||
|
@ -10,7 +11,6 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
"github.com/gorilla/handlers"
|
||||
"sync"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
)
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ func HandleRESTRequests(wg *sync.WaitGroup) {
|
|||
// Currently allowed dev origin is all. Should change in prod
|
||||
// should consider analyzing the allowed methods further
|
||||
headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization"})
|
||||
originsOk := handlers.AllowedOrigins([]string{config.Config.Server.AllowedOrigin})
|
||||
originsOk := handlers.AllowedOrigins([]string{servercfg.GetAllowedOrigin()})
|
||||
methodsOk := handlers.AllowedMethods([]string{"GET", "PUT", "POST", "DELETE"})
|
||||
|
||||
nodeHandlers(r)
|
||||
|
@ -32,10 +32,7 @@ func HandleRESTRequests(wg *sync.WaitGroup) {
|
|||
fileHandlers(r)
|
||||
serverHandlers(r)
|
||||
|
||||
port := config.Config.Server.ApiPort
|
||||
if os.Getenv("API_PORT") != "" {
|
||||
port = os.Getenv("API_PORT")
|
||||
}
|
||||
port := servercfg.GetAPIPort()
|
||||
|
||||
srv := &http.Server{Addr: ":" + port, Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r)}
|
||||
go func(){
|
||||
|
|
|
@ -175,6 +175,40 @@ func GetCustomDNS(network string) ([]models.DNSEntry, error) {
|
|||
return dns, err
|
||||
}
|
||||
|
||||
func SetDNS() error {
|
||||
hostfile := txeh.Hosts{}
|
||||
var corefilestring string
|
||||
networks, err := functions.ListNetworks()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, net := range networks {
|
||||
corefilestring = corefilestring + net.NetID + " "
|
||||
dns, err := GetDNS(net.NetID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range dns {
|
||||
hostfile.AddHost(entry.Address, entry.Name+"."+entry.Network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if corefilestring == "" {
|
||||
corefilestring = "example.com"
|
||||
}
|
||||
|
||||
err = hostfile.SaveAs("./config/dnsconfig/netmaker.hosts")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = functions.SetCorefile(corefilestring)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetDNSEntryNum(domain string, network string) (int, error) {
|
||||
|
||||
num := 0
|
||||
|
@ -418,7 +452,7 @@ func pushDNS(w http.ResponseWriter, r *http.Request) {
|
|||
// Set header
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
err := WriteHosts()
|
||||
err := SetDNS()
|
||||
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
|
@ -427,35 +461,6 @@ func pushDNS(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode("DNS Pushed to CoreDNS")
|
||||
}
|
||||
|
||||
func WriteHosts() error {
|
||||
//hostfile, err := txeh.NewHostsDefault()
|
||||
hostfile := txeh.Hosts{}
|
||||
/*
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*/
|
||||
networks, err := functions.ListNetworks()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, net := range networks {
|
||||
dns, err := GetDNS(net.NetID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range dns {
|
||||
hostfile.AddHost(entry.Address, entry.Name+"."+entry.Network)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err = hostfile.SaveAs("./config/netmaker.hosts")
|
||||
return err
|
||||
}
|
||||
|
||||
func ValidateDNSCreate(entry models.DNSEntry) error {
|
||||
|
||||
v := validator.New()
|
||||
|
|
|
@ -7,16 +7,15 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
|
@ -91,7 +90,7 @@ func SecurityCheck(netname, token string) error {
|
|||
|
||||
//Consider a more secure way of setting master key
|
||||
func authenticateMaster(tokenString string) bool {
|
||||
if tokenString == config.Config.Server.MasterKey || (tokenString == os.Getenv("MASTER_KEY") && tokenString != "") {
|
||||
if tokenString == servercfg.GetMasterKey() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -598,12 +597,6 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
|
|||
return models.AccessKey{}, errors.New("Duplicate AccessKey Name")
|
||||
}
|
||||
}
|
||||
|
||||
_, gconf, err := functions.GetGlobalConfig()
|
||||
if err != nil {
|
||||
//returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return models.AccessKey{}, err
|
||||
}
|
||||
privAddr := ""
|
||||
if network.IsLocal != nil {
|
||||
if *network.IsLocal {
|
||||
|
@ -611,9 +604,10 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
|
|||
}
|
||||
}
|
||||
|
||||
//netID := params["networkname"]
|
||||
address := gconf.ServerGRPC + gconf.PortGRPC
|
||||
accessstringdec := address + "|" + network.NetID + "|" + accesskey.Value + "|" + privAddr
|
||||
netID := params["networkname"]
|
||||
address := servercfg.GetGRPCHost() + ":" + servercfg.GetGRPCPort()
|
||||
|
||||
accessstringdec := address + "|" + netID + "|" + accesskey.Value + "|" + privAddr
|
||||
accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
|
||||
//validate accesskey
|
||||
v := validator.New()
|
||||
|
|
|
@ -3,11 +3,11 @@ package controller
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
@ -36,11 +36,21 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe
|
|||
}
|
||||
*/
|
||||
// Cast to ReadNodeRes type
|
||||
dualvar := false
|
||||
if network.IsDualStack != nil {
|
||||
dualvar = *network.IsDualStack
|
||||
}
|
||||
localvar := false
|
||||
if network.IsLocal != nil {
|
||||
localvar = *network.IsLocal
|
||||
}
|
||||
|
||||
response := &nodepb.ReadNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
Macaddress: node.MacAddress,
|
||||
Name: node.Name,
|
||||
Address: node.Address,
|
||||
Address6: node.Address6,
|
||||
Endpoint: node.Endpoint,
|
||||
Password: node.Password,
|
||||
Nodenetwork: node.Network,
|
||||
|
@ -49,11 +59,13 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe
|
|||
Postdown: node.PostDown,
|
||||
Postup: node.PostUp,
|
||||
Checkininterval: node.CheckInInterval,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Ispending: node.IsPending,
|
||||
Publickey: node.PublicKey,
|
||||
Listenport: node.ListenPort,
|
||||
Keepalive: node.PersistentKeepalive,
|
||||
Islocal: *network.IsLocal,
|
||||
Islocal: localvar,
|
||||
Isdualstack: dualvar,
|
||||
Localrange: network.LocalRange,
|
||||
},
|
||||
}
|
||||
|
@ -71,6 +83,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
|||
LocalAddress: data.GetLocaladdress(),
|
||||
Name: data.GetName(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
AccessKey: data.GetAccesskey(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
PersistentKeepalive: data.GetKeepalive(),
|
||||
|
@ -97,8 +110,6 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
|||
return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find network: %v", err))
|
||||
} else {
|
||||
fmt.Println("Creating node in network " + network.NetID)
|
||||
fmt.Println("Network is local? " + strconv.FormatBool(*network.IsLocal))
|
||||
fmt.Println("Range if local: " + network.LocalRange)
|
||||
}
|
||||
|
||||
if !validKey {
|
||||
|
@ -123,6 +134,15 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
|||
fmt.Sprintf("Internal error: %v", err),
|
||||
)
|
||||
}
|
||||
dualvar := false
|
||||
if network.IsDualStack != nil {
|
||||
dualvar = *network.IsDualStack
|
||||
}
|
||||
localvar := false
|
||||
if network.IsLocal != nil {
|
||||
localvar = *network.IsLocal
|
||||
}
|
||||
|
||||
// return the node in a CreateNodeRes type
|
||||
response := &nodepb.CreateNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
|
@ -130,15 +150,18 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNo
|
|||
Localaddress: node.LocalAddress,
|
||||
Name: node.Name,
|
||||
Address: node.Address,
|
||||
Address6: node.Address6,
|
||||
Endpoint: node.Endpoint,
|
||||
Password: node.Password,
|
||||
Interface: node.Interface,
|
||||
Nodenetwork: node.Network,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Ispending: node.IsPending,
|
||||
Publickey: node.PublicKey,
|
||||
Listenport: node.ListenPort,
|
||||
Keepalive: node.PersistentKeepalive,
|
||||
Islocal: *network.IsLocal,
|
||||
Islocal: localvar,
|
||||
Isdualstack: dualvar,
|
||||
Localrange: network.LocalRange,
|
||||
},
|
||||
}
|
||||
|
@ -160,6 +183,7 @@ func (s *NodeServiceServer) CheckIn(ctx context.Context, req *nodepb.CheckInReq)
|
|||
// ID: primitive.NilObjectID,
|
||||
MacAddress: data.GetMacaddress(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
Network: data.GetNodenetwork(),
|
||||
Password: data.GetPassword(),
|
||||
|
@ -199,11 +223,12 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNo
|
|||
// Get the node data from the request
|
||||
data := req.GetNode()
|
||||
// Now we have to convert this into a NodeItem type to convert into BSON
|
||||
nodechange := models.NodeUpdate{
|
||||
nodechange := models.Node{
|
||||
// ID: primitive.NilObjectID,
|
||||
MacAddress: data.GetMacaddress(),
|
||||
Name: data.GetName(),
|
||||
Address: data.GetAddress(),
|
||||
Address6: data.GetAddress6(),
|
||||
LocalAddress: data.GetLocaladdress(),
|
||||
Endpoint: data.GetEndpoint(),
|
||||
Password: data.GetPassword(),
|
||||
|
@ -243,12 +268,22 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNo
|
|||
fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),
|
||||
)
|
||||
}
|
||||
dualvar := false
|
||||
if network.IsDualStack != nil {
|
||||
dualvar = *network.IsDualStack
|
||||
}
|
||||
localvar := false
|
||||
if network.IsLocal != nil {
|
||||
localvar = *network.IsLocal
|
||||
}
|
||||
|
||||
return &nodepb.UpdateNodeRes{
|
||||
Node: &nodepb.Node{
|
||||
Macaddress: newnode.MacAddress,
|
||||
Localaddress: newnode.LocalAddress,
|
||||
Name: newnode.Name,
|
||||
Address: newnode.Address,
|
||||
Address6: newnode.Address6,
|
||||
Endpoint: newnode.Endpoint,
|
||||
Password: newnode.Password,
|
||||
Interface: newnode.Interface,
|
||||
|
@ -257,9 +292,11 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNo
|
|||
Nodenetwork: newnode.Network,
|
||||
Ispending: newnode.IsPending,
|
||||
Publickey: newnode.PublicKey,
|
||||
Dnsoff: !servercfg.IsDNSMode(),
|
||||
Listenport: newnode.ListenPort,
|
||||
Keepalive: newnode.PersistentKeepalive,
|
||||
Islocal: *network.IsLocal,
|
||||
Islocal: localvar,
|
||||
Isdualstack: dualvar,
|
||||
Localrange: network.LocalRange,
|
||||
},
|
||||
}, nil
|
||||
|
@ -308,6 +345,7 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
|
|||
stream.Send(&nodepb.GetPeersRes{
|
||||
Peers: &nodepb.PeersResponse{
|
||||
Address: peers[i].Address,
|
||||
Address6: peers[i].Address6,
|
||||
Endpoint: peers[i].Endpoint,
|
||||
Gatewayrange: peers[i].GatewayRange,
|
||||
Isgateway: peers[i].IsGateway,
|
||||
|
|
|
@ -3,7 +3,7 @@ package controller
|
|||
import (
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/serverctl"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"net/http"
|
||||
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
func serverHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/server/addnetwork/{network}", securityCheckServer(http.HandlerFunc(addNetwork))).Methods("POST")
|
||||
r.HandleFunc("/api/server/getconfig", securityCheckServer(http.HandlerFunc(getConfig))).Methods("GET")
|
||||
r.HandleFunc("/api/server/removenetwork/{network}", securityCheckServer(http.HandlerFunc(removeNetwork))).Methods("DELETE")
|
||||
}
|
||||
|
||||
|
@ -49,7 +50,7 @@ func securityCheckServer(next http.Handler) http.HandlerFunc {
|
|||
}
|
||||
//Consider a more secure way of setting master key
|
||||
func authenticateMasterServer(tokenString string) bool {
|
||||
if tokenString == config.Config.Server.MasterKey {
|
||||
if tokenString == servercfg.GetMasterKey() {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -72,6 +73,18 @@ func removeNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode("Server removed from network " + params["network"])
|
||||
}
|
||||
|
||||
func getConfig(w http.ResponseWriter, r *http.Request) {
|
||||
// Set header
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
// get params
|
||||
|
||||
scfg := servercfg.GetConfig()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(scfg)
|
||||
}
|
||||
|
||||
func addNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
// Set header
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
|
|
@ -228,7 +228,7 @@ func getUser(w http.ResponseWriter, r *http.Request) {
|
|||
user, err := GetUser(params["username"])
|
||||
|
||||
if err != nil {
|
||||
mongoconn.GetError(err, w)
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -349,34 +349,26 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
|
|||
|
||||
func updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params = mux.Vars(r)
|
||||
|
||||
var user models.User
|
||||
|
||||
//start here
|
||||
user, err := GetUser(params["username"])
|
||||
if err != nil {
|
||||
json.NewEncoder(w).Encode(err)
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
var userchange models.User
|
||||
|
||||
// we decode our body request params
|
||||
err = json.NewDecoder(r.Body).Decode(&userchange)
|
||||
if err != nil {
|
||||
json.NewEncoder(w).Encode(err)
|
||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
user, err = UpdateUser(userchange, user)
|
||||
|
||||
if err != nil {
|
||||
returnErrorResponse(w, r, formatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
|
|
66
docker-compose.nodns.yml
Normal file
66
docker-compose.nodns.yml
Normal file
|
@ -0,0 +1,66 @@
|
|||
version: "3.4"
|
||||
|
||||
volumes:
|
||||
dnsconfig:
|
||||
driver: local
|
||||
services:
|
||||
mongodb:
|
||||
image: mongo:4.2
|
||||
ports:
|
||||
- "27017:27017"
|
||||
container_name: mongodb
|
||||
volumes:
|
||||
- mongovol:/data/db
|
||||
restart: always
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: mongoadmin
|
||||
MONGO_INITDB_ROOT_PASSWORD: mongopass
|
||||
netmaker:
|
||||
privileged: true
|
||||
container_name: netmaker
|
||||
build: netmaker
|
||||
depends_on:
|
||||
- mongodb
|
||||
image: gravitl/netmaker:v0.3
|
||||
ports:
|
||||
- "8081:8081"
|
||||
- "50051:50051"
|
||||
volumes:
|
||||
- ./:/local
|
||||
- /etc/netclient:/etc/netclient
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
- /usr/bin/wg:/usr/bin/wg:ro
|
||||
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
|
||||
- /run/systemd/system:/run/systemd/system
|
||||
- /etc/systemd/system:/etc/systemd/system
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
restart: always
|
||||
network_mode: host
|
||||
netmaker-ui:
|
||||
container_name: netmaker-ui
|
||||
depends_on:
|
||||
- netmaker
|
||||
image: gravitl/netmaker-ui:v0.3
|
||||
links:
|
||||
- "netmaker:api"
|
||||
ports:
|
||||
- "80:80"
|
||||
environment:
|
||||
BACKEND_URL: "http://3.236.149.180:8081"
|
||||
coredns:
|
||||
depends_on:
|
||||
- netmaker
|
||||
image: coredns/coredns
|
||||
command: -conf /root/dnsconfig/Corefile
|
||||
container_name: coredns
|
||||
restart: always
|
||||
ports:
|
||||
- "53:53/udp"
|
||||
volumes:
|
||||
- dnsconfig:/root/dnsconfig
|
||||
volumes:
|
||||
mongovol: {}
|
||||
dnsconfig: {}
|
|
@ -1,5 +1,8 @@
|
|||
version: "3.3"
|
||||
version: "3.4"
|
||||
|
||||
volumes:
|
||||
dnsconfig:
|
||||
driver: local
|
||||
services:
|
||||
mongodb:
|
||||
image: mongo:4.2
|
||||
|
@ -13,24 +16,51 @@ services:
|
|||
MONGO_INITDB_ROOT_USERNAME: mongoadmin
|
||||
MONGO_INITDB_ROOT_PASSWORD: mongopass
|
||||
netmaker:
|
||||
privileged: true
|
||||
container_name: netmaker
|
||||
build: netmaker
|
||||
depends_on:
|
||||
- mongodb
|
||||
image: gravitl/netmaker:v0.2
|
||||
image: gravitl/netmaker:v0.3
|
||||
ports:
|
||||
- "8081:8081"
|
||||
- "50051:50051"
|
||||
environment:
|
||||
MONGO_HOST: mongodb
|
||||
volumes:
|
||||
- ./:/local
|
||||
- /etc/netclient:/etc/netclient
|
||||
- dnsconfig:/root/config/dnsconfig
|
||||
- /usr/bin/wg:/usr/bin/wg:ro
|
||||
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
|
||||
- /run/systemd/system:/run/systemd/system
|
||||
- /etc/systemd/system:/etc/systemd/system
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- SYS_MODULE
|
||||
restart: always
|
||||
network_mode: host
|
||||
netmaker-ui:
|
||||
container_name: netmaker-ui
|
||||
depends_on:
|
||||
- netmaker
|
||||
image: gravitl/netmaker-ui:v0.2
|
||||
image: gravitl/netmaker-ui:v0.3
|
||||
links:
|
||||
- "netmaker:api"
|
||||
ports:
|
||||
- "80:80"
|
||||
environment:
|
||||
BACKEND_URL: "http://localhost:8081"
|
||||
BACKEND_URL: "http://3.236.149.180:8081"
|
||||
coredns:
|
||||
depends_on:
|
||||
- netmaker
|
||||
image: coredns/coredns
|
||||
command: -conf /root/dnsconfig/Corefile
|
||||
container_name: coredns
|
||||
restart: always
|
||||
ports:
|
||||
- "53:53/udp"
|
||||
volumes:
|
||||
- dnsconfig:/root/dnsconfig
|
||||
volumes:
|
||||
mongovol: {}
|
||||
dnsconfig: {}
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
@ -38,22 +39,13 @@ func CreateServerToken(netID string) (string, error) {
|
|||
accesskey.Name = GenKeyName()
|
||||
accesskey.Value = GenKey()
|
||||
accesskey.Uses = 1
|
||||
_, gconf, errG := GetGlobalConfig()
|
||||
if errG != nil {
|
||||
return "", errG
|
||||
}
|
||||
address := "localhost" + gconf.PortGRPC
|
||||
address := "127.0.0.1:" + servercfg.GetGRPCPort()
|
||||
|
||||
privAddr := ""
|
||||
if *network.IsLocal {
|
||||
privAddr = network.LocalRange
|
||||
}
|
||||
|
||||
fmt.Println("Token details:")
|
||||
fmt.Println(" grpc address + port: " + address)
|
||||
fmt.Println(" network: " + netID)
|
||||
fmt.Println(" private range: " + privAddr)
|
||||
|
||||
accessstringdec := address + "|" + netID + "|" + accesskey.Value + "|" + privAddr
|
||||
|
||||
accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
|
||||
|
@ -131,8 +123,6 @@ func NetworkExists(name string) (bool, error) {
|
|||
if err == mongo.ErrNoDocuments {
|
||||
return false, nil
|
||||
}
|
||||
fmt.Println("ERROR RETRIEVING GROUP!")
|
||||
fmt.Println(err)
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
|
@ -529,13 +519,12 @@ func UniqueAddress6(networkName string) (string, error) {
|
|||
|
||||
var network models.Network
|
||||
network, err := GetParentNetwork(networkName)
|
||||
if !*network.IsDualStack {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("UniqueAddress6 encountered an error")
|
||||
return "666", err
|
||||
fmt.Println("Network Not Found")
|
||||
return "", err
|
||||
}
|
||||
if network.IsDualStack == nil || *network.IsDualStack == false {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
offset := true
|
||||
|
@ -549,7 +538,7 @@ func UniqueAddress6(networkName string) (string, error) {
|
|||
offset = false
|
||||
continue
|
||||
}
|
||||
if IsIPUnique(networkName, ip.String()) {
|
||||
if IsIP6Unique(networkName, ip.String()) {
|
||||
return ip.String(), err
|
||||
}
|
||||
}
|
||||
|
@ -558,35 +547,6 @@ func UniqueAddress6(networkName string) (string, error) {
|
|||
return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
|
||||
}
|
||||
|
||||
//pretty simple get
|
||||
func GetGlobalConfig() (bool, models.GlobalConfig, error) {
|
||||
|
||||
create := false
|
||||
|
||||
filter := bson.M{}
|
||||
|
||||
var globalconf models.GlobalConfig
|
||||
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("config")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
||||
err := collection.FindOne(ctx, filter).Decode(&globalconf)
|
||||
|
||||
defer cancel()
|
||||
|
||||
if err == mongo.ErrNoDocuments {
|
||||
fmt.Println("Global config does not exist. Need to create.")
|
||||
create = true
|
||||
return create, globalconf, err
|
||||
} else if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("Could not get global config")
|
||||
return create, globalconf, err
|
||||
}
|
||||
return create, globalconf, err
|
||||
}
|
||||
|
||||
//generate an access key value
|
||||
func GenKey() string {
|
||||
|
||||
|
@ -650,6 +610,34 @@ func IsIPUnique(network string, ip string) bool {
|
|||
return isunique
|
||||
}
|
||||
|
||||
//checks if IP is unique in the address range
|
||||
//used by UniqueAddress
|
||||
func IsIP6Unique(network string, ip string) bool {
|
||||
|
||||
var node models.Node
|
||||
|
||||
isunique := true
|
||||
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("nodes")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
||||
filter := bson.M{"address6": ip, "network": network}
|
||||
|
||||
err := collection.FindOne(ctx, filter).Decode(&node)
|
||||
|
||||
defer cancel()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return isunique
|
||||
}
|
||||
|
||||
if node.Address6 == ip {
|
||||
isunique = false
|
||||
}
|
||||
return isunique
|
||||
}
|
||||
|
||||
//called once key has been used by createNode
|
||||
//reduces value by one and deletes if necessary
|
||||
func DecrimentKey(networkName string, keyvalue string) {
|
||||
|
|
|
@ -2,9 +2,8 @@ package functions
|
|||
|
||||
import (
|
||||
"time"
|
||||
"os"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
|
@ -51,7 +50,7 @@ func CreateUserJWT(username string, isadmin bool) (response string, err error) {
|
|||
func VerifyUserToken(tokenString string) (username string, isadmin bool, err error) {
|
||||
claims := &models.UserClaims{}
|
||||
|
||||
if tokenString == config.Config.Server.MasterKey || (tokenString == os.Getenv("MASTER_KEY") && tokenString != "") {
|
||||
if tokenString == servercfg.GetMasterKey() {
|
||||
return "masteradministrator", true, nil
|
||||
}
|
||||
|
||||
|
@ -71,7 +70,7 @@ func VerifyToken(tokenString string) (macaddress string, network string, err err
|
|||
|
||||
//this may be a stupid way of serving up a master key
|
||||
//TODO: look into a different method. Encryption?
|
||||
if tokenString == config.Config.Server.MasterKey || (tokenString == os.Getenv("MASTER_KEY") && tokenString != "") {
|
||||
if tokenString == servercfg.GetMasterKey() {
|
||||
return "mastermac", "", nil
|
||||
}
|
||||
|
||||
|
|
51
functions/local.go
Normal file
51
functions/local.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package functions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"log"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func SetCorefile(domains string) error {
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = os.Stat(dir + "/config/dnsconfig")
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir(dir +"/config/dnsconfig", 744)
|
||||
} else if err != nil {
|
||||
fmt.Println("couldnt find or create /config/dnsconfig")
|
||||
return err
|
||||
}
|
||||
|
||||
corefile := domains + ` {
|
||||
reload 15s
|
||||
hosts /root/dnsconfig/netmaker.hosts {
|
||||
fallthrough
|
||||
}
|
||||
forward . 8.8.8.8 8.8.4.4
|
||||
log
|
||||
}
|
||||
`
|
||||
corebytes := []byte(corefile)
|
||||
|
||||
err = ioutil.WriteFile(dir + "/config/dnsconfig/Corefile", corebytes, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
log.Println("")
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
3
go.mod
3
go.mod
|
@ -5,7 +5,7 @@ go 1.15
|
|||
require (
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/go-playground/validator/v10 v10.5.0
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/golang/protobuf v1.4.3 // indirect
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
|
@ -20,5 +20,6 @@ require (
|
|||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20200609130330-bd2cb7843e1b
|
||||
google.golang.org/genproto v0.0.0-20210201151548-94839c025ad4 // indirect
|
||||
google.golang.org/grpc v1.35.0
|
||||
google.golang.org/protobuf v1.25.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
)
|
||||
|
|
2048
grpc/node.pb.go
2048
grpc/node.pb.go
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,7 @@ message Node {
|
|||
string id = 1;
|
||||
string name = 2;
|
||||
string address = 3;
|
||||
string address6 = 26;
|
||||
int32 listenport = 4;
|
||||
string publickey = 5;
|
||||
string endpoint = 6;
|
||||
|
@ -44,7 +45,9 @@ message Node {
|
|||
string postchanges = 21;
|
||||
string allowedips = 22;
|
||||
bool islocal = 23;
|
||||
string localrange = 24;
|
||||
bool isdualstack = 27;
|
||||
bool dnsoff = 24;
|
||||
string localrange = 25;
|
||||
}
|
||||
|
||||
message CheckInResponse {
|
||||
|
@ -63,6 +66,7 @@ message PeersResponse {
|
|||
string publickey = 5;
|
||||
string endpoint = 6;
|
||||
string address = 3;
|
||||
string address6 = 8;
|
||||
int32 listenport = 4;
|
||||
string localaddress = 7;
|
||||
int32 keepalive = 13;
|
||||
|
|
248
main.go
248
main.go
|
@ -5,20 +5,11 @@ package main
|
|||
|
||||
import (
|
||||
"log"
|
||||
"flag"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/controllers"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"github.com/gravitl/netmaker/serverctl"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"fmt"
|
||||
"time"
|
||||
"net/http"
|
||||
"strings"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"net"
|
||||
|
@ -26,70 +17,82 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
"os/signal"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
service "github.com/gravitl/netmaker/controllers"
|
||||
nodepb "github.com/gravitl/netmaker/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var ServerGRPC string
|
||||
var PortGRPC string
|
||||
|
||||
//Start MongoDB Connection and start API Request Handler
|
||||
func main() {
|
||||
|
||||
//Client Mode Prereq Check
|
||||
if servercfg.IsClientMode() {
|
||||
cmd := exec.Command("id", "-u")
|
||||
output, err := cmd.Output()
|
||||
|
||||
var clientmode string
|
||||
var defaultnet string
|
||||
flag.StringVar(&clientmode, "clientmode", "on", "Have a client on the server")
|
||||
flag.StringVar(&defaultnet, "defaultnet", "on", "Create a default network")
|
||||
flag.Parse()
|
||||
if clientmode == "on" {
|
||||
|
||||
cmd := exec.Command("id", "-u")
|
||||
output, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
i, err := strconv.Atoi(string(output[:len(output)-1]))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
log.Fatal("To run in client mode requires root privileges. Either turn off client mode with the --clientmode=off flag, or run with sudo.")
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
i, err := strconv.Atoi(string(output[:len(output)-1]))
|
||||
if err != nil {
|
||||
fmt.Println("Error retrieving uid from 'id -u' for prereq check. Please investigate or disable client mode.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
if i != 0 {
|
||||
log.Fatal("To run in client mode requires root privileges. Either disable client mode or run with sudo.")
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Server starting...")
|
||||
//Start Mongodb
|
||||
mongoconn.ConnectDatabase()
|
||||
|
||||
installserver := false
|
||||
if !(defaultnet == "off") {
|
||||
if config.Config.Server.CreateDefault {
|
||||
created, err := createDefaultNetwork()
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating default network: %v", err)
|
||||
}
|
||||
if created && clientmode != "off" {
|
||||
installserver = true
|
||||
}
|
||||
|
||||
//Create the default network (default: 10.10.10.0/24)
|
||||
created, err := serverctl.CreateDefaultNetwork()
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating default network: %v", err)
|
||||
}
|
||||
|
||||
if created && servercfg.IsClientMode() {
|
||||
installserver = true
|
||||
}
|
||||
|
||||
//NOTE: Removed Check and Logic for DNS Mode
|
||||
//Reasoning. DNS Logic is very small on server. Can run with little/no impact. Just sets a tiny config file.
|
||||
//Real work is done by CoreDNS
|
||||
//We can just not run CoreDNS. On Agent side is only necessary check for IsDNSMode, which we will pass.
|
||||
|
||||
var waitnetwork sync.WaitGroup
|
||||
|
||||
if config.Config.Server.AgentBackend {
|
||||
//Run Agent Server
|
||||
if servercfg.IsAgentBackend() {
|
||||
if !(servercfg.DisableRemoteIPCheck()) && servercfg.GetGRPCHost() == "127.0.0.1" {
|
||||
err := servercfg.SetHost()
|
||||
if err != nil {
|
||||
fmt.Println("Unable to Set host. Exiting.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
waitnetwork.Add(1)
|
||||
go runGRPC(&waitnetwork, installserver)
|
||||
}
|
||||
|
||||
if config.Config.Server.RestBackend {
|
||||
//Run Rest Server
|
||||
if servercfg.IsRestBackend() {
|
||||
if !servercfg.DisableRemoteIPCheck() && servercfg.GetAPIHost() == "127.0.0.1" {
|
||||
err := servercfg.SetHost()
|
||||
if err != nil {
|
||||
fmt.Println("Unable to Set host. Exiting.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
waitnetwork.Add(1)
|
||||
controller.HandleRESTRequests(&waitnetwork)
|
||||
}
|
||||
if !config.Config.Server.RestBackend && !config.Config.Server.AgentBackend {
|
||||
fmt.Println("Oops! No Server Mode selected. Nothing being served.")
|
||||
if !servercfg.IsAgentBackend() && !servercfg.IsRestBackend() {
|
||||
fmt.Println("Oops! No Server Mode selected. Nothing is being served! Set either Agent mode (AGENT_BACKEND) or Rest mode (REST_BACKEND) to 'true'.")
|
||||
}
|
||||
waitnetwork.Wait()
|
||||
fmt.Println("Exiting now.")
|
||||
|
@ -105,38 +108,9 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
|
|||
// Pipe flags to one another (log.LstdFLags = log.Ldate | log.Ltime)
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
|
||||
// Start our listener, 50051 is the default gRPC port
|
||||
grpcport := ":50051"
|
||||
if config.Config.Server.GrpcPort != "" {
|
||||
grpcport = ":" + config.Config.Server.GrpcPort
|
||||
}
|
||||
if os.Getenv("GRPC_PORT") != "" {
|
||||
grpcport = ":" + os.Getenv("GRPC_PORT")
|
||||
}
|
||||
PortGRPC = grpcport
|
||||
if os.Getenv("BACKEND_URL") == "" {
|
||||
if config.Config.Server.Host == "" {
|
||||
ServerGRPC, _ = getPublicIP()
|
||||
} else {
|
||||
ServerGRPC = config.Config.Server.Host
|
||||
}
|
||||
} else {
|
||||
ServerGRPC = os.Getenv("BACKEND_URL")
|
||||
}
|
||||
fmt.Println("GRPC Server set to: " + ServerGRPC)
|
||||
fmt.Println("GRPC Port set to: " + PortGRPC)
|
||||
var gconf models.GlobalConfig
|
||||
gconf.ServerGRPC = ServerGRPC
|
||||
gconf.PortGRPC = PortGRPC
|
||||
gconf.Name = "netmaker"
|
||||
err := setGlobalConfig(gconf)
|
||||
grpcport := servercfg.GetGRPCPort()
|
||||
|
||||
if err != nil && err != mongo.ErrNoDocuments{
|
||||
log.Fatalf("Unable to set global config: %v", err)
|
||||
}
|
||||
|
||||
|
||||
listener, err := net.Listen("tcp", grpcport)
|
||||
listener, err := net.Listen("tcp", ":"+grpcport)
|
||||
// Handle errors if any
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to listen on port" + grpcport + ": %v", err)
|
||||
|
@ -163,8 +137,8 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
|
|||
fmt.Println("Agent Server succesfully started on port " + grpcport + " (gRPC)")
|
||||
|
||||
if installserver {
|
||||
fmt.Println("Adding server to " + config.Config.Server.DefaultNetName)
|
||||
success, err := serverctl.AddNetwork(config.Config.Server.DefaultNetName)
|
||||
fmt.Println("Adding server to default network")
|
||||
success, err := serverctl.AddNetwork("default")
|
||||
if err != nil {
|
||||
fmt.Printf("Error adding to default network: %v", err)
|
||||
fmt.Println("")
|
||||
|
@ -179,8 +153,6 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
|
|||
}
|
||||
fmt.Println("Setup complete. You are ready to begin using netmaker.")
|
||||
|
||||
|
||||
|
||||
// Right way to stop the server using a SHUTDOWN HOOK
|
||||
// Create a channel to receive OS signals
|
||||
c := make(chan os.Signal)
|
||||
|
@ -202,113 +174,6 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
|
|||
mongoconn.Client.Disconnect(context.TODO())
|
||||
fmt.Println("MongoDB connection closed.")
|
||||
}
|
||||
func setGlobalConfig(globalconf models.GlobalConfig) (error) {
|
||||
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("config")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
||||
create, _, err := functions.GetGlobalConfig()
|
||||
if create {
|
||||
_, err := collection.InsertOne(ctx, globalconf)
|
||||
defer cancel()
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments || strings.Contains(err.Error(), "no documents in result"){
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
filter := bson.M{"name": "netmaker"}
|
||||
update := bson.D{
|
||||
{"$set", bson.D{
|
||||
{"servergrpc", globalconf.ServerGRPC},
|
||||
{"portgrpc", globalconf.PortGRPC},
|
||||
}},
|
||||
}
|
||||
err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&globalconf)
|
||||
if err == mongo.ErrNoDocuments {
|
||||
//if err == mongo.ErrNoDocuments || strings.Contains(err.Error(), "no documents in result"){
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func createDefaultNetwork() (bool, error) {
|
||||
|
||||
iscreated := false
|
||||
exists, err := functions.NetworkExists(config.Config.Server.DefaultNetName)
|
||||
|
||||
if exists || err != nil {
|
||||
fmt.Println("Default network already exists")
|
||||
fmt.Println("Skipping default network create")
|
||||
return iscreated, err
|
||||
} else {
|
||||
|
||||
var network models.Network
|
||||
|
||||
network.NetID = config.Config.Server.DefaultNetName
|
||||
network.AddressRange = config.Config.Server.DefaultNetRange
|
||||
network.DisplayName = config.Config.Server.DefaultNetName
|
||||
network.SetDefaults()
|
||||
network.SetNodesLastModified()
|
||||
network.SetNetworkLastModified()
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
priv := false
|
||||
network.IsLocal = &priv
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
allow := true
|
||||
network.AllowManualSignUp = &allow
|
||||
|
||||
fmt.Println("Creating default network.")
|
||||
|
||||
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("networks")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
||||
|
||||
// insert our network into the network table
|
||||
_, err = collection.InsertOne(ctx, network)
|
||||
defer cancel()
|
||||
|
||||
}
|
||||
if err == nil {
|
||||
iscreated = true
|
||||
}
|
||||
return iscreated, err
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
func getPublicIP() (string, error) {
|
||||
|
||||
iplist := []string{"https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
endpoint := ""
|
||||
var err error
|
||||
for _, ipserver := range iplist {
|
||||
resp, err := http.Get(ipserver)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
endpoint = string(bodyBytes)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if err == nil && endpoint == "" {
|
||||
err = errors.New("Public Address Not Found.")
|
||||
}
|
||||
return endpoint, err
|
||||
}
|
||||
|
||||
|
||||
func authServerUnaryInterceptor() grpc.ServerOption {
|
||||
return grpc.UnaryInterceptor(controller.AuthServerUnaryInterceptor)
|
||||
|
@ -316,4 +181,3 @@ func authServerUnaryInterceptor() grpc.ServerOption {
|
|||
func authServerStreamInterceptor() grpc.ServerOption {
|
||||
return grpc.StreamInterceptor(controller.AuthServerStreamInterceptor)
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ type PeersResponse struct {
|
|||
PublicKey string `json:"publickey" bson:"publickey"`
|
||||
Endpoint string `json:"endpoint" bson:"endpoint"`
|
||||
Address string `json:"address" bson:"address"`
|
||||
Address6 string `json:"address6" bson:"address6"`
|
||||
LocalAddress string `json:"localaddress" bson:"localaddress"`
|
||||
IsGateway bool `json:"isgateway" bson:"isgateway"`
|
||||
GatewayRange string `json:"gatewayrange" bson:"gatewayrange"`
|
||||
|
|
|
@ -2,13 +2,10 @@ package mongoconn
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"os"
|
||||
"net/http"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
)
|
||||
|
||||
var Client *mongo.Client
|
||||
|
@ -21,53 +18,14 @@ var port string
|
|||
var opts string
|
||||
|
||||
func setVars() {
|
||||
|
||||
//defaults
|
||||
user = "admin"
|
||||
pass = "password"
|
||||
host = "localhost"
|
||||
port = "27017"
|
||||
opts = "/?authSource=admin"
|
||||
|
||||
//override with settings from config file
|
||||
if config.Config.MongoConn.User != "" {
|
||||
user = config.Config.MongoConn.User
|
||||
}
|
||||
if config.Config.MongoConn.Pass != "" {
|
||||
pass = config.Config.MongoConn.Pass
|
||||
}
|
||||
if config.Config.MongoConn.Host != "" {
|
||||
host = config.Config.MongoConn.Host
|
||||
}
|
||||
if config.Config.MongoConn.Port != "" {
|
||||
port = config.Config.MongoConn.Port
|
||||
}
|
||||
if config.Config.MongoConn.Opts != "" {
|
||||
opts = config.Config.MongoConn.Opts
|
||||
}
|
||||
|
||||
//override with settings from env
|
||||
if os.Getenv("MONGO_USER") != "" {
|
||||
user = os.Getenv("MONGO_USER")
|
||||
}
|
||||
if os.Getenv("MONGO_PASS") != "" {
|
||||
pass = os.Getenv("MONGO_PASS")
|
||||
}
|
||||
if os.Getenv("MONGO_HOST") != "" {
|
||||
host = os.Getenv("MONGO_HOST")
|
||||
}
|
||||
if os.Getenv("MONGO_PORT") != "" {
|
||||
port = os.Getenv("MONGO_PORT")
|
||||
}
|
||||
if os.Getenv("MONGO_OPTS") != "" {
|
||||
opts = os.Getenv("MONGO_OPTS")
|
||||
}
|
||||
user = servercfg.GetMongoUser()
|
||||
pass = servercfg.GetMongoPass()
|
||||
host = servercfg.GetMongoHost()
|
||||
port = servercfg.GetMongoPort()
|
||||
opts = servercfg.GetMongoOpts()
|
||||
}
|
||||
|
||||
//TODO: are we even using this besides at startup? Is it truely necessary?
|
||||
//TODO: Use config file instead of os.Getenv
|
||||
func ConnectDatabase() {
|
||||
log.Println("Database connecting...")
|
||||
// Set client options
|
||||
|
||||
setVars()
|
||||
|
@ -80,9 +38,11 @@ func ConnectDatabase() {
|
|||
opts )
|
||||
|
||||
// Connect to MongoDB
|
||||
log.Println("Connecting to MongoDB at " + host + ":" + port + "...")
|
||||
client, err := mongo.Connect(context.TODO(), clientOptions)
|
||||
Client = client
|
||||
if err != nil {
|
||||
log.Println("Error encountered connecting to MongoDB. Terminating.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -90,36 +50,14 @@ func ConnectDatabase() {
|
|||
err = Client.Ping(context.TODO(), nil)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Error encountered pinging MongoDB. Terminating.")
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
NodeDB = Client.Database("netmaker").Collection("nodes")
|
||||
NetworkDB = Client.Database("netmaker").Collection("networks")
|
||||
|
||||
log.Println("Database Connected.")
|
||||
}
|
||||
|
||||
//TODO: IDK if we're using ConnectDB any more.... I think we're just using Client.Database
|
||||
//Review and see if this is necessary
|
||||
// ConnectDB : This is helper function to connect mongoDB
|
||||
func ConnectDB(db string, targetCollection string) *mongo.Collection {
|
||||
|
||||
// Set client options
|
||||
//clientOptions := options.Client().ApplyURI("mongodb://mongoadmin:mongopassword@localhost:27017/?authSource=admin")
|
||||
clientOptions := options.Client().ApplyURI("mongodb://" + os.Getenv("MONGO_USER") + ":" +
|
||||
os.Getenv("MONGO_PASS") + "@" + os.Getenv("MONGO_HOST") + ":" + os.Getenv("MONGO_PORT") + os.Getenv("MONGO_OPTS") )
|
||||
|
||||
// Connect to MongoDB
|
||||
client, err := mongo.Connect(context.TODO(), clientOptions)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
//collection := client.Database("go_rest_api").Collection("wg")
|
||||
collection := client.Database(db).Collection(targetCollection)
|
||||
|
||||
return collection
|
||||
log.Println("MongoDB Connected.")
|
||||
}
|
||||
|
||||
// ErrorResponse : This is error model.
|
||||
|
@ -127,17 +65,3 @@ type ErrorResponse struct {
|
|||
StatusCode int `json:"status"`
|
||||
ErrorMessage string `json:"message"`
|
||||
}
|
||||
|
||||
// GetError : This is helper function to prepare error model.
|
||||
func GetError(err error, w http.ResponseWriter) {
|
||||
|
||||
var response = ErrorResponse{
|
||||
ErrorMessage: err.Error(),
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
}
|
||||
|
||||
message, _ := json.Marshal(response)
|
||||
|
||||
w.WriteHeader(response.StatusCode)
|
||||
w.Write(message)
|
||||
}
|
||||
|
|
|
@ -31,8 +31,11 @@ type NodeConfig struct {
|
|||
MacAddress string `yaml:"macaddress"`
|
||||
LocalAddress string `yaml:"localaddress"`
|
||||
WGAddress string `yaml:"wgaddress"`
|
||||
WGAddress6 string `yaml:"wgaddress6"`
|
||||
RoamingOff bool `yaml:"roamingoff"`
|
||||
DNSOff bool `yaml:"dnsoff"`
|
||||
IsLocal bool `yaml:"islocal"`
|
||||
IsDualStack bool `yaml:"isdualstack"`
|
||||
AllowedIPs string `yaml:"allowedips"`
|
||||
LocalRange string `yaml:"localrange"`
|
||||
PostUp string `yaml:"postup"`
|
||||
|
@ -43,6 +46,7 @@ type NodeConfig struct {
|
|||
PrivateKey string `yaml:"privatekey"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
PostChanges string `yaml:"postchanges"`
|
||||
IPForwarding string `yaml:"ipforwarding"`
|
||||
}
|
||||
|
||||
//reading in the env file
|
||||
|
@ -234,9 +238,3 @@ func ReadConfig(network string) (*ClientConfig, error) {
|
|||
}
|
||||
return &cfg, err
|
||||
}
|
||||
/*
|
||||
func init() {
|
||||
Config = readConfig()
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ func GetFreePort(rangestart int32) (int32, error){
|
|||
return portno, err
|
||||
}
|
||||
|
||||
func Install(accesskey string, password string, server string, network string, noauto bool, accesstoken string, inputname string) error {
|
||||
func Install(accesskey string, password string, server string, network string, noauto bool, accesstoken string, inputname string, pubip string, dnsoff bool, ipforward string) error {
|
||||
|
||||
tserver := ""
|
||||
tnetwork := ""
|
||||
|
@ -143,6 +143,9 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
servercfg := cfg.Server
|
||||
fmt.Println("SERVER SETTINGS:")
|
||||
|
||||
nodecfg.DNSOff = dnsoff
|
||||
nodecfg.IPForwarding = ipforward
|
||||
|
||||
if server == "" {
|
||||
if servercfg.Address == "" && tserver == "" {
|
||||
log.Fatal("no server provided")
|
||||
|
@ -252,6 +255,9 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
}
|
||||
fmt.Println(" Local Address: " + localaddress)
|
||||
|
||||
if pubip != "" && pubip != "nopubip" {
|
||||
endpoint = pubip
|
||||
} else {
|
||||
if nodecfg.Endpoint == "" {
|
||||
if islocal && localaddress != "" {
|
||||
endpoint = localaddress
|
||||
|
@ -269,6 +275,7 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
endpoint = nodecfg.Endpoint
|
||||
fmt.Println("Endpoint set in config. Setting to address: " + endpoint)
|
||||
}
|
||||
}
|
||||
fmt.Println(" Endpoint: " + endpoint)
|
||||
|
||||
|
||||
|
@ -404,6 +411,7 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
fmt.Println("NODE RECIEVED SETTINGS: ")
|
||||
fmt.Println(" Password: " + node.Password)
|
||||
fmt.Println(" WG Address: " + node.Address)
|
||||
fmt.Println(" WG ipv6 Address: " + node.Address6)
|
||||
fmt.Println(" Network: " + node.Nodenetwork)
|
||||
fmt.Println(" Public Endpoint: " + node.Endpoint)
|
||||
fmt.Println(" Local Address: " + node.Localaddress)
|
||||
|
@ -416,8 +424,12 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
fmt.Println(" Public Key: " + node.Publickey)
|
||||
fmt.Println(" Mac Address: " + node.Macaddress)
|
||||
fmt.Println(" Is Local?: " + strconv.FormatBool(node.Islocal))
|
||||
fmt.Println(" Is Dual Stack?: " + strconv.FormatBool(node.Isdualstack))
|
||||
fmt.Println(" Local Range: " + node.Localrange)
|
||||
|
||||
if node.Dnsoff==true && !nodecfg.DNSOff {
|
||||
nodecfg.DNSOff = true
|
||||
}
|
||||
if !islocal && node.Islocal && node.Localrange != "" {
|
||||
fmt.Println("Resetting local settings for local network.")
|
||||
node.Localaddress, err = getLocalIP(node.Localrange)
|
||||
|
@ -442,7 +454,7 @@ func Install(accesskey string, password string, server string, network string, n
|
|||
}
|
||||
}
|
||||
|
||||
peers, hasGateway, gateways, err := getPeers(node.Macaddress, network, server)
|
||||
peers, hasGateway, gateways, err := getPeers(node.Macaddress, network, server, node.Isdualstack)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -514,7 +526,7 @@ func getLocalIP(localrange string) (string, error) {
|
|||
|
||||
func getPublicIP() (string, error) {
|
||||
|
||||
iplist := []string{"https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
iplist := []string{"http://ip.client.gravitl.com","https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
endpoint := ""
|
||||
var err error
|
||||
for _, ipserver := range iplist {
|
||||
|
@ -588,9 +600,19 @@ func modConfig(node *nodepb.Node) error{
|
|||
if node.Address != ""{
|
||||
nodecfg.WGAddress = node.Address
|
||||
}
|
||||
if node.Address6 != ""{
|
||||
nodecfg.WGAddress6 = node.Address6
|
||||
}
|
||||
if node.Postchanges != "" {
|
||||
nodecfg.PostChanges = node.Postchanges
|
||||
}
|
||||
if node.Dnsoff == true {
|
||||
nodecfg.DNSOff = node.Dnsoff
|
||||
}
|
||||
if node.Isdualstack == true {
|
||||
nodecfg.IsDualStack = true
|
||||
}
|
||||
|
||||
if node.Localrange != "" && node.Islocal {
|
||||
nodecfg.IsLocal = true
|
||||
nodecfg.LocalRange = node.Localrange
|
||||
|
@ -638,6 +660,7 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
|
||||
|
||||
nodecfg := modcfg.Node
|
||||
servercfg := modcfg.Server
|
||||
fmt.Println("beginning local WG config")
|
||||
|
||||
|
||||
|
@ -659,7 +682,14 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
if node.Address == "" {
|
||||
log.Fatal("no address to configure")
|
||||
}
|
||||
|
||||
nameserver := servercfg.Address
|
||||
nameserver = strings.Split(nameserver, ":")[0]
|
||||
network := node.Nodenetwork
|
||||
if nodecfg.Network != "" {
|
||||
network = nodecfg.Network
|
||||
} else if node.Nodenetwork != "" {
|
||||
network = node.Nodenetwork
|
||||
}
|
||||
cmdIPDevLinkAdd := &exec.Cmd {
|
||||
Path: ipExec,
|
||||
Args: []string{ ipExec, "link", "add", "dev", ifacename, "type", "wireguard" },
|
||||
|
@ -673,7 +703,6 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
Stderr: os.Stdout,
|
||||
}
|
||||
|
||||
|
||||
currentiface, err := net.InterfaceByName(ifacename)
|
||||
|
||||
|
||||
|
@ -733,6 +762,33 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
fmt.Printf("This is inconvenient: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
//=========DNS Setup==========\\
|
||||
if nodecfg.DNSOff != true {
|
||||
|
||||
_, err := exec.LookPath("resolvectl")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("WARNING: resolvectl not present. Unable to set dns. Install resolvectl or run manually.")
|
||||
} else {
|
||||
_, err = exec.Command("resolvectl", "domain", ifacename, "~"+network).Output()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = exec.Command("resolvectl", "default-route", ifacename, "false").Output()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("WARNING: Error encountered setting dns. Aborted setting dns.")
|
||||
} else {
|
||||
_, err = exec.Command("resolvectl", "dns", ifacename, nameserver).Output()
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//=========End DNS Setup=======\\
|
||||
|
||||
cmdIPLinkUp := &exec.Cmd {
|
||||
Path: ipExec,
|
||||
Args: []string{ ipExec, "link", "set", "up", "dev", ifacename},
|
||||
|
@ -773,7 +829,15 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
|
|||
if err != nil {
|
||||
fmt.Println("Error encountered adding gateway: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.Address6 != "" && node.Isdualstack) {
|
||||
fmt.Println("Adding address: " + node.Address6)
|
||||
out, err := exec.Command(ipExec, "address", "add", "dev", ifacename, node.Address6+"/64").Output()
|
||||
if err != nil {
|
||||
fmt.Println(out)
|
||||
fmt.Println("Error encountered adding ipv6: " + err.Error())
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -867,7 +931,7 @@ func setWGConfig(network string) error {
|
|||
nodecfg := cfg.Node
|
||||
node := getNode(network)
|
||||
|
||||
peers, hasGateway, gateways, err := getPeers(node.Macaddress, nodecfg.Network, servercfg.Address)
|
||||
peers, hasGateway, gateways, err := getPeers(node.Macaddress, nodecfg.Network, servercfg.Address, node.Isdualstack)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -952,6 +1016,23 @@ func CheckIn(network string) error {
|
|||
setupcheck := true
|
||||
ipchange := false
|
||||
|
||||
if !(nodecfg.IPForwarding == "off") {
|
||||
out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
|
||||
} else {
|
||||
s := strings.Fields(string(out))
|
||||
if s[2] != "1" {
|
||||
_, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
fmt.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !nodecfg.RoamingOff {
|
||||
if !nodecfg.IsLocal {
|
||||
fmt.Println("Checking to see if public addresses have changed")
|
||||
|
@ -1220,6 +1301,7 @@ func getNode(network string) nodepb.Node {
|
|||
node.Nodenetwork = nodecfg.Network
|
||||
node.Localaddress = nodecfg.LocalAddress
|
||||
node.Address = nodecfg.WGAddress
|
||||
node.Address6 = nodecfg.WGAddress6
|
||||
node.Listenport = nodecfg.Port
|
||||
node.Keepalive = nodecfg.KeepAlive
|
||||
node.Postup = nodecfg.PostUp
|
||||
|
@ -1228,9 +1310,8 @@ func getNode(network string) nodepb.Node {
|
|||
node.Macaddress = nodecfg.MacAddress
|
||||
node.Endpoint = nodecfg.Endpoint
|
||||
node.Password = nodecfg.Password
|
||||
|
||||
//spew.Dump(node)
|
||||
|
||||
node.Dnsoff = nodecfg.DNSOff
|
||||
node.Isdualstack = nodecfg.IsDualStack
|
||||
return node
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1452,7 @@ func DeleteInterface(ifacename string, postdown string) error{
|
|||
return err
|
||||
}
|
||||
|
||||
func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
func getPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, bool, []string, error) {
|
||||
//need to implement checkin on server side
|
||||
hasGateway := false
|
||||
var gateways []string
|
||||
|
@ -1470,6 +1551,13 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
|
|||
allowedips = append(allowedips, *ipnet)
|
||||
}
|
||||
}
|
||||
if res.Peers.Address6 != "" && dualstack {
|
||||
var addr6 = net.IPNet{
|
||||
IP: net.ParseIP(res.Peers.Address6),
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
}
|
||||
allowedips = append(allowedips, addr6)
|
||||
}
|
||||
if keepalive != 0 {
|
||||
peer = wgtypes.PeerConfig{
|
||||
PublicKey: pubkey,
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"io"
|
||||
"strings"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -20,6 +21,27 @@ func FileExists(f string) bool {
|
|||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func SetDNS(nameserver string) error {
|
||||
bytes, err := ioutil.ReadFile("/etc/resolv.conf")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resolvstring := string(bytes)
|
||||
// //check whether s contains substring text
|
||||
hasdns := strings.Contains(resolvstring, nameserver)
|
||||
if hasdns {
|
||||
return nil
|
||||
}
|
||||
resolv, err := os.OpenFile("/etc/resolv.conf",os.O_APPEND|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resolv.Close()
|
||||
_, err = resolv.WriteString("nameserver " + nameserver + "\n")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func ConfigureSystemD(network string) error {
|
||||
/*
|
||||
path, err := os.Getwd()
|
||||
|
@ -118,40 +140,32 @@ WantedBy=timers.target
|
|||
return err
|
||||
}
|
||||
}
|
||||
sysExec, err := exec.LookPath("systemctl")
|
||||
//sysExec, err := exec.LookPath("systemctl")
|
||||
|
||||
cmdSysEnableService := &exec.Cmd {
|
||||
cmdSysEnableService := exec.Command("systemctl", "enable", "netclient@.service")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "enable", "netclient@.service" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
/*
|
||||
cmdSysStartService := &exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "start", "netclient@.service"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
*/
|
||||
cmdSysDaemonReload := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysDaemonReload := exec.Command("systemctl", "daemon-reload")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "daemon-reload"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysEnableTimer := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysEnableTimer := exec.Command("systemctl", "enable", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "enable", "netclient-"+network+".timer" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysStartTimer := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysStartTimer := exec.Command("systemctl", "start", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "start", "netclient-"+network+".timer"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
}*/
|
||||
|
||||
err = cmdSysEnableService.Run()
|
||||
if err != nil {
|
||||
|
@ -191,7 +205,7 @@ func isOnlyService(network string) (bool, error) {
|
|||
}
|
||||
|
||||
func RemoveSystemDServices(network string) error {
|
||||
sysExec, err := exec.LookPath("systemctl")
|
||||
//sysExec, err := exec.LookPath("systemctl")
|
||||
|
||||
|
||||
fullremove, err := isOnlyService(network)
|
||||
|
@ -199,36 +213,36 @@ func RemoveSystemDServices(network string) error {
|
|||
fmt.Println(err)
|
||||
}
|
||||
|
||||
cmdSysDisableService := &exec.Cmd {
|
||||
cmdSysDisableService := exec.Command("systemctl","disable","netclient@.service")/* &exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "disable", "netclient@.service"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysDaemonReload := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysDaemonReload := exec.Command("systemctl","daemon-reload")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "daemon-reload"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysResetFailed := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysResetFailed := exec.Command("systemctl","reset-failed")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "reset-failed"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysStopTimer := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysStopTimer := exec.Command("systemctl", "stop", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "stop", "netclient-"+network+".timer" },
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
cmdSysDisableTimer := &exec.Cmd {
|
||||
}*/
|
||||
cmdSysDisableTimer := exec.Command("systemctl", "disable", "netclient-"+network+".timer")/*&exec.Cmd {
|
||||
Path: sysExec,
|
||||
Args: []string{ sysExec, "disable", "netclient-"+network+".timer"},
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stdout,
|
||||
}
|
||||
}*/
|
||||
|
||||
//err = cmdSysStopService.Run()
|
||||
if err != nil {
|
||||
|
|
|
@ -39,8 +39,10 @@ func main() {
|
|||
tname := flag.String("name", "noname", "give the node a name at runtime")
|
||||
tserver := flag.String("s", "localhost:50051", "The location (including port) of the remote gRPC server.")
|
||||
tnetwork := flag.String("n", "nonetwork", "The node network you are attempting to join.")
|
||||
tdnsoff := flag.Bool("dnsoff", false, "DNS Mode. If true, netclient will not alter system dns. false by default.")
|
||||
tpublicip := flag.String("ip4", "nopubip", "The node network you are attempting to join.")
|
||||
tnoauto := flag.Bool("na", false, "No auto mode. If true, netmclient will not be installed as a system service and you will have to retrieve updates manually via checkin command.")
|
||||
tnoforward := flag.Bool("nf", false, "No Forward mode. If true, netclient will not check for IP forwarding. This may break functionality")
|
||||
tipforward := flag.String("nf", "on", "No Forward mode. If true, netclient will not check for IP forwarding. This may break functionality")
|
||||
command := flag.String("c", "required", "The command to run")
|
||||
|
||||
|
||||
|
@ -89,7 +91,7 @@ func main() {
|
|||
fmt.Println("Required, '-n'. No network provided. Exiting.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
/*
|
||||
if !*tnoforward {
|
||||
forward := exec.Command("sysctl", "net.ipv4.ip_forward")
|
||||
out, err := forward.Output()
|
||||
|
@ -106,9 +108,9 @@ func main() {
|
|||
log.Fatal("It is recommended to enable IP Forwarding. Current status is: " + s[2] + ", but should be 1. if you would like to run without IP Forwarding, re-run with flag '-nf true'")
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
fmt.Println("Beginning agent installation.")
|
||||
err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname)
|
||||
err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname, *tpublicip, *tdnsoff, *tipforward)
|
||||
if err != nil {
|
||||
fmt.Println("Error encountered while installing.")
|
||||
if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
|
||||
|
|
60
scripts/netmaker-install-clientmode.sh
Executable file
60
scripts/netmaker-install-clientmode.sh
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
[ -z "$SERVER_DOMAIN" ] && echo "Need to set SERVER_DOMAIN (format: 1.2.3.4 or mybackend.com)" && exit 1;
|
||||
|
||||
|
||||
docker volume create mongovol && docker run -d --name mongodb -v mongovol:/data/db --network host -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=mongopass mongo --bind_ip 0.0.0.0
|
||||
|
||||
mkdir -p /etc/netmaker/config/environments
|
||||
wget -O /etc/netmaker/netmaker https://github.com/gravitl/netmaker/releases/download/latest/netmaker
|
||||
chmod +x /etc/netmaker/netmaker
|
||||
|
||||
|
||||
cat >/etc/netmaker/config/environments/dev.yaml<<EOL
|
||||
server:
|
||||
host: "$SERVER_DOMAIN"
|
||||
apiport: "8081"
|
||||
grpcport: "50051"
|
||||
masterkey: "secretkey"
|
||||
allowedorigin: "*"
|
||||
restbackend: true
|
||||
agentbackend: true
|
||||
defaultnetname: "default"
|
||||
defaultnetrange: "10.10.10.0/24"
|
||||
createdefault: true
|
||||
mongoconn:
|
||||
user: "mongoadmin"
|
||||
pass: "mongopass"
|
||||
host: "localhost"
|
||||
port: "27017"
|
||||
opts: '/?authSource=admin'
|
||||
EOL
|
||||
|
||||
cat >/etc/netmaker/config/Corefile<<EOL
|
||||
. {
|
||||
hosts /root/netmaker.hosts
|
||||
}
|
||||
EOL
|
||||
|
||||
cat >/etc/systemd/system/netmaker.service<<EOL
|
||||
[Unit]
|
||||
Description=Netmaker Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
|
||||
WorkingDirectory=/etc/netmaker
|
||||
ExecStart=/etc/netmaker/netmaker
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
systemctl daemon-reload
|
||||
systemctl start netmaker.service
|
||||
|
||||
|
||||
docker run -d --name netmaker-ui -p 80:80 -e BACKEND_URL="http://$SERVER_DOMAIN:8081" gravitl/netmaker-ui:v0.2
|
||||
docker run -d --name coredns --restart=always --volume=/etc/netmaker/config/:/root/ -p 52:53/udp coredns/coredns -conf /root/Corefile
|
101
scripts/netmaker-install-local.sh
Executable file
101
scripts/netmaker-install-local.sh
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/bin/sh
|
||||
set -x
|
||||
|
||||
[ -z "$SERVER_DOMAIN" ] && echo "Need to set SERVER_DOMAIN (format: 1.2.3.4 or mybackend.com)" && exit 1;
|
||||
|
||||
|
||||
install() {
|
||||
|
||||
docker volume create mongovol && docker run -d --name mongodb -v mongovol:/data/db -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=mongopass mongo
|
||||
|
||||
echo "Giving Mongo Time to Start"
|
||||
sleep 10
|
||||
echo "Installing Netmaker API"
|
||||
|
||||
mkdir -p /etc/netmaker/config/environments
|
||||
mkdir -p /etc/netmaker/config/dnsconfig
|
||||
cp ../netmaker /etc/netmaker/netmaker
|
||||
chmod +x /etc/netmaker/netmaker
|
||||
|
||||
|
||||
cat >/etc/netmaker/config/environments/dev.yaml<<EOL
|
||||
server:
|
||||
host: "$SERVER_DOMAIN"
|
||||
apiport: "8081"
|
||||
grpcport: "50051"
|
||||
masterkey: "secretkey"
|
||||
allowedorigin: "*"
|
||||
restbackend: true
|
||||
agentbackend: true
|
||||
defaultnetname: "default"
|
||||
defaultnetrange: "10.10.10.0/24"
|
||||
createdefault: true
|
||||
mongoconn:
|
||||
user: "mongoadmin"
|
||||
pass: "mongopass"
|
||||
host: "127.0.0.1"
|
||||
port: "27017"
|
||||
opts: '/?authSource=admin'
|
||||
EOL
|
||||
|
||||
cat >/etc/netmaker/config/dnsconfig/Corefile<<EOL
|
||||
. {
|
||||
hosts ./root/netmaker.hosts {
|
||||
fallthrough
|
||||
}
|
||||
forward . 8.8.8.8 8.8.4.4
|
||||
log
|
||||
}
|
||||
EOL
|
||||
|
||||
cat >/etc/systemd/system/netmaker.service<<EOL
|
||||
[Unit]
|
||||
Description=Netmaker Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
|
||||
WorkingDirectory=/etc/netmaker
|
||||
ExecStart=/etc/netmaker/netmaker
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL
|
||||
systemctl daemon-reload
|
||||
systemctl start netmaker.service
|
||||
sudo docker pull coredns/coredns
|
||||
sudo docker pull gravitl/netmaker-ui:v0.3
|
||||
|
||||
systemctl stop systemd-resolved
|
||||
systemctl disable systemd-resolved
|
||||
echo "Running CoreDNS"
|
||||
sudo docker run -d --name coredns --restart=always --volume=/etc/netmaker/config/dnsconfig/:/root/ -p 53:53/udp coredns/coredns -conf /root/Corefile
|
||||
|
||||
echo "Running UI"
|
||||
sudo docker run -d --name netmaker-ui -p 80:80 -e BACKEND_URL="http://$SERVER_DOMAIN:8081" gravitl/netmaker-ui:v0.3
|
||||
|
||||
echo "Setup Complete"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
sudo docker kill mongodb || true
|
||||
sudo docker rm mongodb || true
|
||||
sudo docker volume rm mongovol || true
|
||||
sudo docker kill coredns || true
|
||||
sudo docker rm coredns || true
|
||||
sudo docker kill netmaker-ui || true
|
||||
sudo docker rm netmaker-ui || true
|
||||
sudo netclient -c remove -n default || true
|
||||
sudo rm -rf /etc/systemd/system/netmaker.service || true
|
||||
sudo rm -rf /etc/netmaker || true
|
||||
sudo systemctl enable systemd-resolved
|
||||
sudo systemctl start systemd-resolved
|
||||
sleep 5
|
||||
sudo systemctl restart systemd-resolved
|
||||
}
|
||||
|
||||
trap cleanup ERR
|
||||
cleanup
|
||||
install
|
12
scripts/uninstall-netclient.sh
Executable file
12
scripts/uninstall-netclient.sh
Executable file
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
set -x
|
||||
|
||||
echo "Starting."
|
||||
|
||||
sudo netclient -c remove-all || true
|
||||
sudo rm -rf /usr/local/bin/netclient || true
|
||||
sudo rm -rf /etc/netclient|| true
|
||||
find /etc/systemd/system/ -name 'netclient*' -exec rm {} \;
|
||||
sudo systemctl daemon-reload || true
|
||||
|
||||
echo "Done."
|
26
scripts/uninstall-netmaker.sh
Executable file
26
scripts/uninstall-netmaker.sh
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
set -x
|
||||
|
||||
echo "Starting."
|
||||
|
||||
sudo docker kill mongodb || true
|
||||
sudo docker rm mongodb || true
|
||||
sudo docker volume rm mongovol || true
|
||||
sudo docker volume rm `docker volume ls -q -f dangling=true` || true
|
||||
sudo docker kill coredns || true
|
||||
sudo docker rm coredns || true
|
||||
sudo docker kill netmaker-ui || true
|
||||
sudo docker rm netmaker-ui || true
|
||||
sudo netclient -c remove -n default || true
|
||||
sudo rm -rf /etc/systemd/system/netmaker.service || true
|
||||
sudo rm -rf /etc/netmaker || true
|
||||
sudo rm -rf /usr/local/bin/netclient || true
|
||||
sudo rm -rf /etc/netclient|| true
|
||||
find /etc/systemd/system/ -name 'netclient*' -exec rm {} \;
|
||||
sudo systemctl daemon-reload || true
|
||||
sudo systemctl enable systemd-resolved || true
|
||||
sudo systemctl start systemd-resolved || true
|
||||
sleep 5
|
||||
sudo systemctl restart systemd-resolved || true
|
||||
|
||||
echo "Done."
|
53
servercfg/mongoconf.go
Normal file
53
servercfg/mongoconf.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package servercfg
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"os"
|
||||
)
|
||||
|
||||
func GetMongoUser() string {
|
||||
user := "mongoadmin"
|
||||
if os.Getenv("MONGO_ADMIN") != "" {
|
||||
user = os.Getenv("MONGO_ADMIN")
|
||||
} else if config.Config.MongoConn.User != "" {
|
||||
user = config.Config.MongoConn.User
|
||||
}
|
||||
return user
|
||||
}
|
||||
func GetMongoPass() string {
|
||||
pass := "mongopass"
|
||||
if os.Getenv("MONGO_PASS") != "" {
|
||||
pass = os.Getenv("MONGO_PASS")
|
||||
} else if config.Config.MongoConn.Pass != "" {
|
||||
pass = config.Config.MongoConn.Pass
|
||||
}
|
||||
return pass
|
||||
}
|
||||
func GetMongoHost() string {
|
||||
host := "127.0.0.1"
|
||||
if os.Getenv("MONGO_HOST") != "" {
|
||||
host = os.Getenv("MONGO_HOST")
|
||||
} else if config.Config.MongoConn.Host != "" {
|
||||
host = config.Config.MongoConn.Host
|
||||
}
|
||||
return host
|
||||
}
|
||||
func GetMongoPort() string {
|
||||
port := "27017"
|
||||
if os.Getenv("MONGO_PORT") != "" {
|
||||
port = os.Getenv("MONGO_PORT")
|
||||
} else if config.Config.MongoConn.Port != "" {
|
||||
port = config.Config.MongoConn.Port
|
||||
}
|
||||
return port
|
||||
}
|
||||
func GetMongoOpts() string {
|
||||
opts := "/?authSource=admin"
|
||||
if os.Getenv("MONGO_OPTS") != "" {
|
||||
opts = os.Getenv("MONGO_OPTS")
|
||||
} else if config.Config.MongoConn.Opts != "" {
|
||||
opts = config.Config.MongoConn.Opts
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
199
servercfg/serverconf.go
Normal file
199
servercfg/serverconf.go
Normal file
|
@ -0,0 +1,199 @@
|
|||
package servercfg
|
||||
|
||||
import (
|
||||
"github.com/gravitl/netmaker/config"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func SetHost() error {
|
||||
remoteip, err := GetPublicIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
os.Setenv("SERVER_HOST", remoteip)
|
||||
return nil
|
||||
}
|
||||
func GetConfig() config.ServerConfig {
|
||||
var cfg config.ServerConfig
|
||||
cfg.APIHost = GetAPIHost()
|
||||
cfg.APIPort = GetAPIPort()
|
||||
cfg.GRPCHost = GetGRPCHost()
|
||||
cfg.GRPCPort = GetGRPCPort()
|
||||
cfg.MasterKey = "(hidden)"
|
||||
cfg.AllowedOrigin = GetAllowedOrigin()
|
||||
cfg.RestBackend = "off"
|
||||
if IsRestBackend() {
|
||||
cfg.RestBackend = "on"
|
||||
}
|
||||
cfg.AgentBackend = "off"
|
||||
if IsAgentBackend() {
|
||||
cfg.AgentBackend = "on"
|
||||
}
|
||||
cfg.ClientMode = "off"
|
||||
if IsClientMode() {
|
||||
cfg.ClientMode = "on"
|
||||
}
|
||||
cfg.DNSMode = "off"
|
||||
if IsDNSMode() {
|
||||
cfg.DNSMode = "on"
|
||||
}
|
||||
cfg.DisableRemoteIPCheck = "off"
|
||||
if DisableRemoteIPCheck() {
|
||||
cfg.DisableRemoteIPCheck = "on"
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func GetAPIHost() string {
|
||||
serverhost := "127.0.0.1"
|
||||
if os.Getenv("SERVER_HTTP_HOST") != "" {
|
||||
serverhost = os.Getenv("SERVER_HTTP_HOST")
|
||||
} else if config.Config.Server.APIHost != "" {
|
||||
serverhost = config.Config.Server.APIHost
|
||||
} else if os.Getenv("SERVER_HOST") != "" {
|
||||
serverhost = os.Getenv("SERVER_HOST")
|
||||
}
|
||||
return serverhost
|
||||
}
|
||||
func GetAPIPort() string {
|
||||
apiport := "8081"
|
||||
if os.Getenv("API_PORT") != "" {
|
||||
apiport = os.Getenv("API_PORT")
|
||||
} else if config.Config.Server.APIPort != "" {
|
||||
apiport = config.Config.Server.APIPort
|
||||
}
|
||||
return apiport
|
||||
}
|
||||
func GetGRPCHost() string {
|
||||
serverhost := "127.0.0.1"
|
||||
if os.Getenv("SERVER_GRPC_HOST") != "" {
|
||||
serverhost = os.Getenv("SERVER_GRPC_HOST")
|
||||
} else if config.Config.Server.GRPCHost != "" {
|
||||
serverhost = config.Config.Server.GRPCHost
|
||||
} else if os.Getenv("SERVER_HOST") != "" {
|
||||
serverhost = os.Getenv("SERVER_HOST")
|
||||
}
|
||||
return serverhost
|
||||
}
|
||||
func GetGRPCPort() string {
|
||||
grpcport := "50051"
|
||||
if os.Getenv("GRPC_PORT") != "" {
|
||||
grpcport = os.Getenv("GRPC_PORT")
|
||||
} else if config.Config.Server.GRPCPort != "" {
|
||||
grpcport = config.Config.Server.GRPCPort
|
||||
}
|
||||
return grpcport
|
||||
}
|
||||
func GetMasterKey() string {
|
||||
key := "secretkey"
|
||||
if os.Getenv("MASTER_KEY") != "" {
|
||||
key = os.Getenv("MASTER_KEY")
|
||||
} else if config.Config.Server.MasterKey != "" {
|
||||
key = config.Config.Server.MasterKey
|
||||
}
|
||||
return key
|
||||
}
|
||||
func GetAllowedOrigin() string {
|
||||
allowedorigin := "*"
|
||||
if os.Getenv("CORS_ALLOWED_ORIGIN") != "" {
|
||||
allowedorigin = os.Getenv("CORS_ALLOWED_ORIGIN")
|
||||
} else if config.Config.Server.AllowedOrigin != "" {
|
||||
allowedorigin = config.Config.Server.AllowedOrigin
|
||||
}
|
||||
return allowedorigin
|
||||
}
|
||||
func IsRestBackend() bool {
|
||||
isrest := true
|
||||
if os.Getenv("REST_BACKEND") != "" {
|
||||
if os.Getenv("REST_BACKEND") == "off" {
|
||||
isrest = false
|
||||
}
|
||||
} else if config.Config.Server.RestBackend != "" {
|
||||
if config.Config.Server.RestBackend == "off" {
|
||||
isrest = false
|
||||
}
|
||||
}
|
||||
return isrest
|
||||
}
|
||||
func IsAgentBackend() bool {
|
||||
isagent := true
|
||||
if os.Getenv("AGENT_BACKEND") != "" {
|
||||
if os.Getenv("AGENT_BACKEND") == "off" {
|
||||
isagent = false
|
||||
}
|
||||
} else if config.Config.Server.AgentBackend != "" {
|
||||
if config.Config.Server.AgentBackend == "off" {
|
||||
isagent = false
|
||||
}
|
||||
}
|
||||
return isagent
|
||||
}
|
||||
func IsClientMode() bool {
|
||||
isclient := true
|
||||
if os.Getenv("CLIENT_MODE") != "" {
|
||||
if os.Getenv("CLIENT_MODE") == "off" {
|
||||
isclient = false
|
||||
}
|
||||
} else if config.Config.Server.ClientMode != "" {
|
||||
if config.Config.Server.ClientMode == "off" {
|
||||
isclient = false
|
||||
}
|
||||
}
|
||||
return isclient
|
||||
}
|
||||
func IsDNSMode() bool {
|
||||
isdns := true
|
||||
if os.Getenv("DNS_MODE") != "" {
|
||||
if os.Getenv("DNS_MODE") == "off" {
|
||||
isdns = false
|
||||
}
|
||||
} else if config.Config.Server.DNSMode != "" {
|
||||
if config.Config.Server.DNSMode == "off" {
|
||||
isdns = false
|
||||
}
|
||||
}
|
||||
return isdns
|
||||
}
|
||||
func DisableRemoteIPCheck() bool {
|
||||
disabled := false
|
||||
if os.Getenv("DISABLE_REMOTE_IP_CHECK") != "" {
|
||||
if os.Getenv("DISABLE_REMOTE_IP_CHECK") == "on" {
|
||||
disabled = true
|
||||
}
|
||||
} else if config.Config.Server.DisableRemoteIPCheck != "" {
|
||||
if config.Config.Server.DisableRemoteIPCheck == "on" {
|
||||
disabled= true
|
||||
}
|
||||
}
|
||||
return disabled
|
||||
}
|
||||
func GetPublicIP() (string, error) {
|
||||
|
||||
endpoint := ""
|
||||
var err error
|
||||
|
||||
iplist := []string{"http://ip.server.gravitl.com", "https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
|
||||
for _, ipserver := range iplist {
|
||||
resp, err := http.Get(ipserver)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
bodyBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
endpoint = string(bodyBytes)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if err == nil && endpoint == "" {
|
||||
err = errors.New("Public Address Not Found.")
|
||||
}
|
||||
return endpoint, err
|
||||
}
|
|
@ -2,17 +2,65 @@ package serverctl
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/functions"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mongoconn"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"io"
|
||||
"time"
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func CreateDefaultNetwork() (bool, error) {
|
||||
|
||||
fmt.Println("Creating default network...")
|
||||
|
||||
iscreated := false
|
||||
exists, err := functions.NetworkExists("default")
|
||||
|
||||
if exists || err != nil {
|
||||
fmt.Println("Default network already exists. Skipping...")
|
||||
return iscreated, err
|
||||
} else {
|
||||
|
||||
var network models.Network
|
||||
|
||||
network.NetID = "default"
|
||||
network.AddressRange = "10.10.10.0/24"
|
||||
network.DisplayName = "default"
|
||||
network.SetDefaults()
|
||||
network.SetNodesLastModified()
|
||||
network.SetNetworkLastModified()
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
priv := false
|
||||
network.IsLocal = &priv
|
||||
network.KeyUpdateTimeStamp = time.Now().Unix()
|
||||
allow := true
|
||||
network.AllowManualSignUp = &allow
|
||||
|
||||
fmt.Println("Creating default network.")
|
||||
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("networks")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
|
||||
// insert our network into the network table
|
||||
_, err = collection.InsertOne(ctx, network)
|
||||
defer cancel()
|
||||
|
||||
}
|
||||
if err == nil {
|
||||
iscreated = true
|
||||
}
|
||||
return iscreated, err
|
||||
|
||||
|
||||
}
|
||||
|
||||
func DownloadNetclient() error {
|
||||
|
||||
/*
|
||||
// Get the data
|
||||
resp, err := http.Get("https://github.com/gravitl/netmaker/releases/download/latest/netclient")
|
||||
if err != nil {
|
||||
|
@ -23,16 +71,58 @@ func DownloadNetclient() error {
|
|||
|
||||
// Create the file
|
||||
out, err := os.Create("/etc/netclient/netclient")
|
||||
*/
|
||||
if !FileExists("/etc/netclient/netclient") {
|
||||
_, err := copy("./netclient/netclient", "/etc/netclient/netclient")
|
||||
if err != nil {
|
||||
fmt.Println("could not create /etc/netclient")
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
}
|
||||
//defer out.Close()
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
return err
|
||||
//_, err = io.Copy(out, resp.Body)
|
||||
return nil
|
||||
}
|
||||
|
||||
func FileExists(f string) bool {
|
||||
info, err := os.Stat(f)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func copy(src, dst string) (int64, error) {
|
||||
sourceFileStat, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !sourceFileStat.Mode().IsRegular() {
|
||||
return 0, fmt.Errorf("%s is not a regular file", src)
|
||||
}
|
||||
|
||||
source, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
destination, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer destination.Close()
|
||||
nBytes, err := io.Copy(destination, source)
|
||||
err = os.Chmod(dst, 0755)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return nBytes, err
|
||||
}
|
||||
|
||||
func RemoveNetwork(network string) (bool, error) {
|
||||
_, err := os.Stat("/etc/netclient/netclient")
|
||||
if err != nil {
|
||||
|
@ -50,7 +140,13 @@ func RemoveNetwork(network string) (bool, error) {
|
|||
}
|
||||
|
||||
func AddNetwork(network string) (bool, error) {
|
||||
_, err := os.Stat("/etc/netclient")
|
||||
pubip, err := servercfg.GetPublicIP()
|
||||
if err != nil {
|
||||
fmt.Println("could not get public IP.")
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, err = os.Stat("/etc/netclient")
|
||||
if os.IsNotExist(err) {
|
||||
os.Mkdir("/etc/netclient", 744)
|
||||
} else if err != nil {
|
||||
|
@ -78,7 +174,7 @@ func AddNetwork(network string) (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
fmt.Println("Client is ready. Running install.")
|
||||
out, err := exec.Command("/etc/netclient/netclient","-c","install","-t",token,"-name","netmaker").Output()
|
||||
out, err := exec.Command("/etc/netclient/netclient","-c","install","-t",token,"-name","netmaker","-ip4",pubip).Output()
|
||||
fmt.Println(string(out))
|
||||
if err != nil {
|
||||
return false, errors.New(string(out) + err.Error())
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -46,20 +45,6 @@ func TestMain(m *testing.M) {
|
|||
var waitgroup sync.WaitGroup
|
||||
waitgroup.Add(1)
|
||||
go controller.HandleRESTRequests(&waitgroup)
|
||||
var gconf models.GlobalConfig
|
||||
gconf.ServerGRPC = "localhost:8081"
|
||||
gconf.PortGRPC = "50051"
|
||||
//err := SetGlobalConfig(gconf)
|
||||
collection := mongoconn.Client.Database("netmaker").Collection("config")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
//create, _, err := functions.GetGlobalConfig()
|
||||
_, err := collection.InsertOne(ctx, gconf)
|
||||
if err != nil {
|
||||
panic("could not create config store")
|
||||
}
|
||||
|
||||
//wait for http server to start
|
||||
time.Sleep(time.Second * 1)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue