Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.20.3 #488

Merged
merged 20 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions .github/workflows/branchtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ jobs:
skip-check:
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
skip: ${{ steps.skip.outputs.skip }}
steps:
- id: skip
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: 'always'

getbranch:
runs-on: ubuntu-latest
needs: skip-check
Expand All @@ -38,12 +39,56 @@ jobs:
echo "netmakerbranch=develop" >> $GITHUB_OUTPUT
fi

getserver:
runs-on: ubuntu-latest
needs: skip-check
if: ${{ needs.skip-check.outputs.skip != 'true' }}
outputs:
netmakerserver: ${{ steps.getserver.outputs.server }}
steps:
- name: setup ssh
run: |
mkdir -p ~/.ssh/
echo "$SSH_KEY" > ~/.ssh/id_devops
chmod 600 ~/.ssh/id_devops
cat >>~/.ssh/config <<END
Host *.clustercat.com
User root
IdentityFile ~/.ssh/id_devops
StrictHostKeyChecking no
END
env:
SSH_KEY: ${{ secrets.TESTING_SSH_KEY }}
- name: getserver
id: getserver
run: |
server=""
for arg in "branch1" "branch2" "branch3" "branch4" "branch5"; do
echo checking $arg
result=$( ssh root@server.${arg}.clustercat.com '~/branchtesting/check.sh')
echo $result
if [ "$result" == "pass" ]
then
server=$arg
echo $server>>/tmp/server
break
fi
done
echo server is $server
if [ "$server" == "" ]
then
echo server not set
exit 1
fi
echo "netmakerserver=$server" >> $GITHUB_OUTPUT

terraform:
needs: getbranch
needs: [getbranch, getserver]
uses: gravitl/devops/.github/workflows/terraform.yml@master
with:
netclientbranch: ${{ github.head_ref }}
netmakerbranch: ${{ needs.getbranch.outputs.netmakerbranch }}
server: ${{ needs.getserver.outputs.netmakerserver }}
secrets: inherit


Expand Down
28 changes: 26 additions & 2 deletions .github/workflows/deletedroplets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
with:
run_id: ${{ github.event.workflow_run.id}}
if_no_artifact_found: warn
- name: get server name
run: |
echo "SERVER=$(cat ./server/server) >> $GITHUB_ENV"
- name: get PR
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -42,6 +45,14 @@ jobs:
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
TAG: ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}
- name: mark server as available
uses: appleboy/ssh-action@master
with:
host: server.${{ env.SERVER }}.clustercat.com
username: root
key: ${{ secrets.TESTING_SSH_KEY }}
script: |
rm /tmp/branchtest

on-failure:
runs-on: ubuntu-latest
Expand All @@ -52,6 +63,9 @@ jobs:
with:
run_id: ${{ github.event.workflow_run.id}}
if_no_artifact_found: warn
- name: get server name
run: |
echo "SERVER=$(cat ./server/server) >> $GITHUB_ENV"
- name: get PR
env:
GH_TOKEN: ${{ github.token }}
Expand All @@ -65,7 +79,7 @@ jobs:
webhook_token: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
color: "#990000"
username: "GitHub Bot"
message: " ${{ github.repository}}:${{ github.event.workflow_run.name }}:PR ${{ env.pull_request}} failed: droplets from this workflow (tag ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}) will be deleted in 5 hours"
message: " ${{ github.repository}}:${{ github.event.workflow_run.name }}:PR ${{ env.pull_request}} failed: droplets from this workflow (tag ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}) will be deleted in 3 hours"
file: ./results/results.log
- name: discord error message
uses: appleboy/discord-action@master
Expand All @@ -79,11 +93,21 @@ jobs:
- name: delete droplets
if: success() || failure()
run: |
sleep 5h
sleep 3h
curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
"https://api.digitalocean.com/v2/droplets?tag_name=$TAG"
env:
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
TAG: ${{ github.event.workflow_run.id }}-${{ github.event.workflow_run.run_attempt }}
- name: mark server as available
if: success() || failure()
uses: appleboy/ssh-action@master
with:
host: server.${{ env.SERVER }}.clustercat.com
username: root
key: ${{ secrets.TESTING_SSH_KEY }}
script: |
rm /tmp/branchtest

2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ COPY . .
RUN go mod tidy
RUN GOOS=linux CGO_ENABLED=0 /usr/local/go/bin/go build -ldflags="-s -w" -o netclient-app .

FROM alpine:3.18.0
FROM alpine:3.18.2

WORKDIR /root/

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-netclient-multiarch-userspace
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WORKDIR /app
COPY . .
RUN GOOS=linux CGO_ENABLED=0 /usr/local/go/bin/go build -ldflags="-w -s" -o netclient-app .

FROM alpine:3.18.0
FROM alpine:3.18.2

WORKDIR /root/

Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ func UpdateHost(host *models.Host) (resetInterface, restart bool) {
host.MacAddress = hostCfg.MacAddress
host.PublicKey = hostCfg.PublicKey
host.TrafficKeyPublic = hostCfg.TrafficKeyPublic
// don't update any public ports coming from server,overwrite the values
host.WgPublicListenPort = hostCfg.WgPublicListenPort
host.PublicListenPort = hostCfg.PublicListenPort
// store password before updating
host.HostPass = hostCfg.HostPass
hostCfg.Host = *host
Expand Down
57 changes: 40 additions & 17 deletions functions/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"log"
"net"
"os"
"os/signal"
Expand Down Expand Up @@ -123,15 +124,37 @@ func closeRoutines(closers []context.CancelFunc, wg *sync.WaitGroup) {
func startGoRoutines(wg *sync.WaitGroup) context.CancelFunc {
ctx, cancel := context.WithCancel(context.Background())
if _, err := config.ReadNetclientConfig(); err != nil {
slog.Error("error reading neclient config file", "error", err)
slog.Error("error reading netclient config file", "error", err)
}
config.UpdateNetclient(*config.Netclient())
if err := config.ReadServerConf(); err != nil {
slog.Warn("error reading server map from disk", "error", err)
}
updateConfig := false
if freeport, err := ncutils.GetFreePort(config.Netclient().ListenPort); err != nil {
log.Fatal("no free ports available for use by netclient")
} else if freeport != config.Netclient().ListenPort {
slog.Info("port has changed", "old port", config.Netclient().ListenPort, "new port", freeport)
config.Netclient().ListenPort = freeport
updateConfig = true
}
config.SetServerCtx()
config.HostPublicIP, config.WgPublicListenPort = holePunchWgPort()
slog.Info("wireguard public listen port: ", "port", config.WgPublicListenPort)

if config.Netclient().WgPublicListenPort == 0 {
config.Netclient().WgPublicListenPort = config.WgPublicListenPort
updateConfig = true
}
if config.Netclient().EndpointIP == nil {
config.Netclient().EndpointIP = config.HostPublicIP
updateConfig = true
}
if updateConfig {
if err := config.WriteNetclientConfig(); err != nil {
slog.Error("error writing endpoint/port netclient config file", "error", err)
}
}
setNatInfo()
slog.Info("configuring netmaker wireguard interface")
if len(config.Servers) == 0 {
Expand Down Expand Up @@ -211,7 +234,7 @@ func setupMQTT(server *config.Server) error {
setHostSubscription(client, server.Name)
checkin()
})
opts.SetOrderMatters(true)
opts.SetOrderMatters(false)
opts.SetResumeSubs(true)
opts.SetConnectionLostHandler(func(c mqtt.Client, e error) {
slog.Warn("detected broker connection lost for", "server", server.Broker)
Expand Down Expand Up @@ -313,22 +336,22 @@ func setHostSubscription(client mqtt.Client, server string) {
hostID := config.Netclient().ID
slog.Info("subscribing to host updates for", "host", hostID, "server", server)
if token := client.Subscribe(fmt.Sprintf("peers/host/%s/%s", hostID.String(), server), 0, mqtt.MessageHandler(HostPeerUpdate)); token.Wait() && token.Error() != nil {
slog.Error("unable to subscribe to host peer updates", "host", hostID, "server", server, "error", token.Error)
slog.Error("unable to subscribe to host peer updates", "host", hostID, "server", server, "error", token.Error())
return
}
slog.Info("subscribing to host updates for", "host", hostID, "server", server)
if token := client.Subscribe(fmt.Sprintf("host/update/%s/%s", hostID.String(), server), 0, mqtt.MessageHandler(HostUpdate)); token.Wait() && token.Error() != nil {
slog.Error("unable to subscribe to host updates", "host", hostID, "server", server, "error", token.Error)
slog.Error("unable to subscribe to host updates", "host", hostID, "server", server, "error", token.Error())
return
}
slog.Info("subscribing to dns updates for", "host", hostID, "server", server)
if token := client.Subscribe(fmt.Sprintf("dns/update/%s/%s", hostID.String(), server), 0, mqtt.MessageHandler(dnsUpdate)); token.Wait() && token.Error() != nil {
slog.Error("unable to subscribe to dns updates", "host", hostID, "server", server, "error", token.Error)
slog.Error("unable to subscribe to dns updates", "host", hostID, "server", server, "error", token.Error())
return
}
slog.Info("subscribing to all dns updates for", "host", hostID, "server", server)
if token := client.Subscribe(fmt.Sprintf("dns/all/%s/%s", hostID.String(), server), 0, mqtt.MessageHandler(dnsAll)); token.Wait() && token.Error() != nil {
slog.Error("unable to subscribe to all dns updates", "host", hostID, "server", server, "error", token.Error)
slog.Error("unable to subscribe to all dns updates", "host", hostID, "server", server, "error", token.Error())
return
}
}
Expand All @@ -340,7 +363,7 @@ func setSubscriptions(client mqtt.Client, node *config.Node) {
if token.Error() == nil {
slog.Error("unable to subscribe to updates for node ", "node", node.ID, "error", "connection timeout")
} else {
slog.Error("unable to subscribe to updates for node ", "node", node.ID, "error", token.Error)
slog.Error("unable to subscribe to updates for node ", "node", node.ID, "error", token.Error())
}
return
}
Expand Down Expand Up @@ -402,7 +425,7 @@ func unsubscribeNode(client mqtt.Client, node *config.Node) {
if token.Error() == nil {
slog.Error("unable to unsubscribe from updates for node ", "node", node.ID, "error", "connection timeout")
} else {
slog.Error("unable to unsubscribe from updates for node ", "node", node.ID, "error", token.Error)
slog.Error("unable to unsubscribe from updates for node ", "node", node.ID, "error", token.Error())
}
ok = false
} // peer updates belong to host now
Expand All @@ -417,7 +440,7 @@ func unsubscribeHost(client mqtt.Client, server string) {
hostID := config.Netclient().ID
slog.Info("removing subscription for host peer updates", "host", hostID, "server", server)
if token := client.Unsubscribe(fmt.Sprintf("peers/host/%s/%s", hostID.String(), server)); token.WaitTimeout(mq.MQ_TIMEOUT*time.Second) && token.Error() != nil {
slog.Error("unable to unsubscribe from host peer updates", "host", hostID, "server", server, "error", token.Error)
slog.Error("unable to unsubscribe from host peer updates", "host", hostID, "server", server, "error", token.Error())
return
}
slog.Info("removing subscription for host updates", "host", hostID, "server", server)
Expand Down Expand Up @@ -447,14 +470,14 @@ func UpdateKeys() error {
}

func holePunchWgPort() (pubIP net.IP, pubPort int) {
for _, server := range config.Servers {
portToStun := config.Netclient().ListenPort
pubIP, pubPort = stun.HolePunch(server.StunList, portToStun)
if pubPort == 0 || pubIP == nil || pubIP.IsUnspecified() {
continue
}
break
}
stunServers := []models.StunServer{
{Domain: "stun1.netmaker.io", Port: 3478},
{Domain: "stun2.netmaker.io", Port: 3478},
{Domain: "stun1.l.google.com", Port: 19302},
{Domain: "stun2.l.google.com", Port: 19302},
}
portToStun := config.Netclient().ListenPort
pubIP, pubPort = stun.HolePunch(stunServers, portToStun)
return
}

Expand Down
22 changes: 15 additions & 7 deletions functions/httpserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"log"
"net/http"
"runtime"
"strings"
"sync"

Expand All @@ -22,19 +23,26 @@ type Network struct {
Server config.Server
}

const DefaultHttpServerPort = "18095"
const DefaultHttpServerAddr = "127.0.0.1"

func HttpServer(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
if config.Netclient().DisableGUIServer {
return
}
port, err := ncutils.GetFreeTCPPort()
if err != nil {
logger.Log(0, "failed to get free port", err.Error())
logger.Log(0, "unable to start http server", "exiting")
logger.Log(0, "netclient-gui will not be available")
return
port := DefaultHttpServerPort
if runtime.GOOS != "windows" {
p, err := ncutils.GetFreeTCPPort()
if err != nil {
logger.Log(0, "failed to get free port", err.Error())
logger.Log(0, "unable to start http server", "exiting")
logger.Log(0, "netclient-gui will not be available")
return
}
port = p
}
config.SetGUI("127.0.0.1", port)
config.SetGUI(DefaultHttpServerAddr, port)
config.WriteGUIConfig()

router := SetupRouter()
Expand Down
7 changes: 3 additions & 4 deletions functions/mqhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) {
slog.Error("error unmarshalling peer data", "error", err)
return
}
turn.ResetCh <- struct{}{}
if peerUpdate.ServerVersion != config.Version {
slog.Warn("server/client version mismatch", "server", peerUpdate.ServerVersion, "client", config.Version)
if versionLessThan(config.Version, peerUpdate.ServerVersion) && config.Netclient().Host.AutoUpdate {
Expand All @@ -140,8 +141,6 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) {
server.Version = peerUpdate.ServerVersion
config.WriteServerConfig()
}
// endpoint detection always comes from the server
config.Netclient().Host.EndpointDetection = peerUpdate.Host.EndpointDetection
gwDetected := config.GW4PeerDetected || config.GW6PeerDetected
currentGW4 := config.GW4Addr
currentGW6 := config.GW6Addr
Expand All @@ -165,7 +164,7 @@ func HostPeerUpdate(client mqtt.Client, msg mqtt.Message) {
gwDelta,
&originalGW,
)
if config.Netclient().Host.EndpointDetection {
if peerUpdate.EndpointDetection {
slog.Debug("endpoint detection enabled")
go handleEndpointDetection(&peerUpdate)
} else {
Expand Down Expand Up @@ -307,7 +306,7 @@ func handleEndpointDetection(peerUpdate *models.HostPeerUpdate) {
peerPubKey,
peerInfo.ProxyListenPort,
); err != nil { // happens v often
slog.Error("failed to check for endpoint on peer", "peer", peerPubKey, "error", err)
slog.Debug("failed to check for endpoint on peer", "peer", peerPubKey, "error", err)
}
}
}
Expand Down
Loading