mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-14 00:54:21 +08:00
Merge pull request #257 from gravitl/v0.7.3
V0.7.3 - Added ext client automation
This commit is contained in:
commit
4ad47f1e4e
9 changed files with 93 additions and 27 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gravitl/netmaker/database"
|
"github.com/gravitl/netmaker/database"
|
||||||
"github.com/gravitl/netmaker/functions"
|
"github.com/gravitl/netmaker/functions"
|
||||||
|
@ -91,7 +92,7 @@ func getAllExtClients(w http.ResponseWriter, r *http.Request) {
|
||||||
err := errors.New("Networks Error")
|
err := errors.New("Networks Error")
|
||||||
if networksSlice[0] == ALL_NETWORK_ACCESS {
|
if networksSlice[0] == ALL_NETWORK_ACCESS {
|
||||||
clients, err = functions.GetAllExtClients()
|
clients, err = functions.GetAllExtClients()
|
||||||
if err != nil && !database.IsEmptyRecord(err){
|
if err != nil && !database.IsEmptyRecord(err) {
|
||||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -159,14 +160,14 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
gwnode, err := functions.GetNodeByMacAddress(client.Network, client.IngressGatewayID)
|
gwnode, err := functions.GetNodeByMacAddress(client.Network, client.IngressGatewayID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
functions.PrintUserLog(r.Header.Get("user"),"Could not retrieve Ingress Gateway Node " + client.IngressGatewayID,1)
|
functions.PrintUserLog(r.Header.Get("user"), "Could not retrieve Ingress Gateway Node "+client.IngressGatewayID, 1)
|
||||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := functions.GetParentNetwork(client.Network)
|
network, err := functions.GetParentNetwork(client.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
functions.PrintUserLog(r.Header.Get("user"),"Could not retrieve Ingress Gateway Network " + client.Network,1)
|
functions.PrintUserLog(r.Header.Get("user"), "Could not retrieve Ingress Gateway Network "+client.Network, 1)
|
||||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -175,6 +176,16 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
|
||||||
keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
|
keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
|
||||||
}
|
}
|
||||||
gwendpoint := gwnode.Endpoint + ":" + strconv.Itoa(int(gwnode.ListenPort))
|
gwendpoint := gwnode.Endpoint + ":" + strconv.Itoa(int(gwnode.ListenPort))
|
||||||
|
newAllowedIPs := network.AddressRange
|
||||||
|
if egressGatewayRanges, err := client.GetEgressRangesOnNetwork(); err == nil {
|
||||||
|
for _, egressGatewayRange := range egressGatewayRanges {
|
||||||
|
newAllowedIPs += "," + egressGatewayRange
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultDNS := ""
|
||||||
|
if network.DefaultExtClientDNS != "" {
|
||||||
|
defaultDNS = "DNS = " + network.DefaultExtClientDNS
|
||||||
|
}
|
||||||
config := fmt.Sprintf(`[Interface]
|
config := fmt.Sprintf(`[Interface]
|
||||||
Address = %s
|
Address = %s
|
||||||
PrivateKey = %s
|
PrivateKey = %s
|
||||||
|
@ -184,13 +195,15 @@ PublicKey = %s
|
||||||
AllowedIPs = %s
|
AllowedIPs = %s
|
||||||
Endpoint = %s
|
Endpoint = %s
|
||||||
%s
|
%s
|
||||||
|
%s
|
||||||
|
|
||||||
`, client.Address+"/32",
|
`, client.Address+"/32",
|
||||||
client.PrivateKey,
|
client.PrivateKey,
|
||||||
gwnode.PublicKey,
|
gwnode.PublicKey,
|
||||||
network.AddressRange,
|
newAllowedIPs,
|
||||||
gwendpoint,
|
gwendpoint,
|
||||||
keepalive)
|
keepalive,
|
||||||
|
defaultDNS)
|
||||||
|
|
||||||
if params["type"] == "qr" {
|
if params["type"] == "qr" {
|
||||||
bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
|
bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
|
||||||
|
@ -219,7 +232,7 @@ Endpoint = %s
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
functions.PrintUserLog(r.Header.Get("user"),"retrieved ext client config",2)
|
functions.PrintUserLog(r.Header.Get("user"), "retrieved ext client config", 2)
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
json.NewEncoder(w).Encode(client)
|
json.NewEncoder(w).Encode(client)
|
||||||
}
|
}
|
||||||
|
@ -263,6 +276,7 @@ func CreateExtClient(extclient models.ExtClient) error {
|
||||||
err = SetNetworkNodesLastModified(extclient.Network)
|
err = SetNetworkNodesLastModified(extclient.Network)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To create a extclient
|
* To create a extclient
|
||||||
* Must have valid key and be unique
|
* Must have valid key and be unique
|
||||||
|
@ -289,7 +303,6 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
|
extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
|
||||||
|
|
||||||
err = json.NewDecoder(r.Body).Decode(&extclient)
|
err = json.NewDecoder(r.Body).Decode(&extclient)
|
||||||
if err != nil && !errors.Is(err, io.EOF) {
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
returnErrorResponse(w, r, formatError(err, "internal"))
|
returnErrorResponse(w, r, formatError(err, "internal"))
|
||||||
|
|
|
@ -57,3 +57,16 @@ Example config file:
|
||||||
.. literalinclude:: ./examplecode/myclient.conf
|
.. literalinclude:: ./examplecode/myclient.conf
|
||||||
|
|
||||||
Your client should now be able to access the network! A client can be invalidated at any time by simply deleting it from the UI.
|
Your client should now be able to access the network! A client can be invalidated at any time by simply deleting it from the UI.
|
||||||
|
|
||||||
|
Configuring DNS for Ext Clients (OPTIONAL)
|
||||||
|
============================================
|
||||||
|
|
||||||
|
If you wish to have a DNS field on your ext clients conf, simply edit the network field as shown below to 1.1.1.1 or 8.8.8.8 for example.
|
||||||
|
If you do not want DNS on your ext client conf files, simply leave it blank.
|
||||||
|
|
||||||
|
.. image:: images/exclient5.png
|
||||||
|
:width: 80%
|
||||||
|
:alt: Gateway
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
Important to note, your client automatically adds egress gateway ranges (if any on the same network) to it's allowed IPs.
|
||||||
|
|
BIN
docs/images/extclient5.png
Normal file
BIN
docs/images/extclient5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
|
@ -117,10 +117,11 @@ On Ubuntu 20.04, by default there is a service consuming port 53 related to DNS
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
systemctl stop systemd-resolved
|
systemctl stop systemd-resolved
|
||||||
systemctl disable systemd-resolved
|
|
||||||
vim /etc/systemd/resolved.conf
|
vim /etc/systemd/resolved.conf
|
||||||
* uncomment DNS and add 8.8.8.8 or whatever reachable nameserver is your preference *
|
* uncomment DNS and add 8.8.8.8 or whatever reachable nameserver is your preference *
|
||||||
* uncomment DNSStubListener and set to "no" *
|
* uncomment DNSStubListener and set to "no" *
|
||||||
|
systemctl start systemd-resolved
|
||||||
|
systemctl disable --now systemd-resolved
|
||||||
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,8 +138,10 @@ Insert your domain in the configuration file and add to nginx:
|
||||||
|
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
sed -i 's/NETMAKER_BASE_DOMAIN/<your base domain>/g' netmaker-nginx-template.conf
|
NETMAKER_BASE_DOMAIN=<your base domain>
|
||||||
sudo cp netmaker-nginx-template.conf /etc/nginx/conf.d/<your base domain>.conf
|
sed -i 's/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g' netmaker-nginx-template.conf
|
||||||
|
sudo cp netmaker-nginx-template.conf /etc/nginx/sites-available/netmaker-nginx.conf
|
||||||
|
sudo ln -s /etc/nginx/sites-available/netmaker-nginx.conf /etc/nginx/sites-enabled/netmaker.nginx.conf
|
||||||
nginx -t && nginx -s reload
|
nginx -t && nginx -s reload
|
||||||
systemctl restart nginx
|
systemctl restart nginx
|
||||||
|
|
||||||
|
@ -151,7 +154,7 @@ Prepare Templates
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
wget https://raw.githubusercontent.com/gravitl/netmaker/develop/compose/docker-compose.quickstart.yml
|
wget https://raw.githubusercontent.com/gravitl/netmaker/develop/compose/docker-compose.quickstart.yml
|
||||||
sed -i 's/NETMAKER_BASE_DOMAIN/<your base domain>/g' docker-compose.quickstart.yml
|
sed -i 's/NETMAKER_BASE_DOMAIN/$NETMAKER_BASE_DOMAIN/g' docker-compose.quickstart.yml
|
||||||
sed -i 's/SERVER_PUBLIC_IP/<your server ip>/g' docker-compose.quickstart.yml
|
sed -i 's/SERVER_PUBLIC_IP/<your server ip>/g' docker-compose.quickstart.yml
|
||||||
|
|
||||||
Generate a unique master key and insert it:
|
Generate a unique master key and insert it:
|
||||||
|
@ -172,4 +175,4 @@ To troubleshoot issues, start with:
|
||||||
|
|
||||||
``docker logs netmaker``
|
``docker logs netmaker``
|
||||||
|
|
||||||
Or check out the :doc:`troubleshoooting docs <./troubleshoot>`.
|
Or check out the :doc:`troubleshoooting docs <./troubleshoot>`.
|
||||||
|
|
|
@ -1,13 +1,48 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/gravitl/netmaker/database"
|
||||||
|
)
|
||||||
|
|
||||||
type ExtClient struct {
|
type ExtClient struct {
|
||||||
ClientID string `json:"clientid" bson:"clientid"`
|
ClientID string `json:"clientid" bson:"clientid"`
|
||||||
Description string `json:"description" bson:"description"`
|
Description string `json:"description" bson:"description"`
|
||||||
PrivateKey string `json:"privatekey" bson:"privatekey"`
|
PrivateKey string `json:"privatekey" bson:"privatekey"`
|
||||||
PublicKey string `json:"publickey" bson:"publickey"`
|
PublicKey string `json:"publickey" bson:"publickey"`
|
||||||
Network string `json:"network" bson:"network"`
|
Network string `json:"network" bson:"network"`
|
||||||
Address string `json:"address" bson:"address"`
|
Address string `json:"address" bson:"address"`
|
||||||
LastModified int64 `json:"lastmodified" bson:"lastmodified"`
|
IngressGatewayID string `json:"ingressgatewayid" bson:"ingressgatewayid"`
|
||||||
IngressGatewayID string `json:"ingressgatewayid" bson:"ingressgatewayid"`
|
IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
|
||||||
IngressGatewayEndpoint string `json:"ingressgatewayendpoint" bson:"ingressgatewayendpoint"`
|
LastModified int64 `json:"lastmodified" bson:"lastmodified"`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the egress gateway ips of a given ExtClient struct
|
||||||
|
* returns as []string
|
||||||
|
*/
|
||||||
|
func (client *ExtClient) GetEgressRangesOnNetwork() ([]string, error) {
|
||||||
|
|
||||||
|
var result []string
|
||||||
|
nodesData, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
for _, nodeData := range nodesData {
|
||||||
|
var currentNode Node
|
||||||
|
if err = json.Unmarshal([]byte(nodeData), ¤tNode); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if currentNode.Network != client.Network {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if currentNode.IsEgressGateway == "yes" { // add the egress gateway range(s) to the result
|
||||||
|
if len(currentNode.EgressGatewayRanges) > 0 {
|
||||||
|
result = append(result, currentNode.EgressGatewayRanges...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"github.com/gravitl/netmaker/servercfg"
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/gravitl/netmaker/database"
|
"github.com/gravitl/netmaker/database"
|
||||||
|
"github.com/gravitl/netmaker/servercfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Network Struct
|
//Network Struct
|
||||||
|
@ -39,6 +40,7 @@ type Network struct {
|
||||||
LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
|
LocalRange string `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
|
||||||
DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
|
DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
|
||||||
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
DefaultUDPHolePunch string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
|
||||||
|
DefaultExtClientDNS string `json:"defaultextclientdns" bson:"defaultextclientdns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SaveData struct { // put sensitive fields here
|
type SaveData struct { // put sensitive fields here
|
||||||
|
|
BIN
netclient/netclient32
Executable file
BIN
netclient/netclient32
Executable file
Binary file not shown.
BIN
netmaker32
Executable file
BIN
netmaker32
Executable file
Binary file not shown.
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
PUBKEY="DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
|
PUBKEY="DM5qhLAE20EG9BbfBEger+Ac9D2NDOwCtY1rbYDLf34="
|
||||||
IPADDR="69.173.21.202"
|
IPADDR="70.173.21.212"
|
||||||
MACADDRESS="59:2a:9c:d4:e2:49"
|
MACADDRESS="59:23:9c:f2:e4:49"
|
||||||
ACCESSKEY="6Cc1m3x0B0LQhHWF"
|
ACCESSKEY="Gsl6FKOjWi2qPGXy"
|
||||||
PASSWORD="ppppppp"
|
PASSWORD="ppppppp"
|
||||||
|
|
||||||
generate_post_json ()
|
generate_post_json ()
|
||||||
|
@ -15,7 +15,7 @@ generate_post_json ()
|
||||||
"macaddress": "$MACADDRESS",
|
"macaddress": "$MACADDRESS",
|
||||||
"password": "$PASSWORD",
|
"password": "$PASSWORD",
|
||||||
"localaddress": "172.123.123.3",
|
"localaddress": "172.123.123.3",
|
||||||
"accesskey": "zKfzHn9W6uL5KuIg"
|
"accesskey": "$ACCESSKEY"
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue