mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-07 13:44:17 +08:00
resolve merge conflicts
This commit is contained in:
commit
27ceaed739
24 changed files with 448 additions and 357 deletions
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
|
@ -36,7 +36,7 @@ jobs:
|
|||
run: echo "timestamp=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "Update documentation ${{ steps.timestamp.outputs.timestamp }}"
|
||||
|
|
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
@ -70,5 +70,5 @@ jobs:
|
|||
- name: run static checks
|
||||
run: |
|
||||
sudo apt update
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
go install honnef.co/go/tools/cmd/staticcheck@v0.4.7
|
||||
{ ~/go/bin/staticcheck -tags=ee ./... ; }
|
||||
|
|
|
@ -6,7 +6,7 @@ COPY . .
|
|||
|
||||
RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -w " -tags ${tags} .
|
||||
# RUN go build -tags=ee . -o netmaker main.go
|
||||
FROM alpine:3.20.0
|
||||
FROM alpine:3.20.2
|
||||
|
||||
# add a c lib
|
||||
# set the working directory
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#first stage - builder
|
||||
FROM alpine:3.20.0
|
||||
FROM alpine:3.20.2
|
||||
ARG version
|
||||
WORKDIR /app
|
||||
COPY ./netmaker /root/netmaker
|
||||
|
|
|
@ -657,13 +657,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
|
|||
slog.Error("Failed to get nodes", "error", err)
|
||||
return
|
||||
}
|
||||
go mq.PublishSingleHostPeerUpdate(
|
||||
ingressHost,
|
||||
nodes,
|
||||
nil,
|
||||
[]models.ExtClient{oldExtClient},
|
||||
false,
|
||||
)
|
||||
go mq.PublishSingleHostPeerUpdate(ingressHost, nodes, nil, []models.ExtClient{oldExtClient}, false, nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ func upgradeHost(w http.ResponseWriter, r *http.Request) {
|
|||
// @Success 200 {array} models.ApiHost
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func getHosts(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
currentHosts := []models.Host{}
|
||||
username := r.Header.Get("user")
|
||||
user, err := logic.GetUser(username)
|
||||
|
@ -90,7 +90,7 @@ func getHosts(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
respHostsMap := make(map[string]struct{})
|
||||
if !userPlatformRole.FullAccess {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
|
@ -107,9 +107,12 @@ func getHosts(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
for _, node := range filteredNodes {
|
||||
if _, ok := respHostsMap[node.HostID.String()]; ok {
|
||||
continue
|
||||
}
|
||||
if host, ok := currentHostsMap[node.HostID.String()]; ok {
|
||||
currentHosts = append(currentHosts, host)
|
||||
delete(currentHostsMap, host.ID.String())
|
||||
respHostsMap[host.ID.String()] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -340,14 +340,8 @@ func updateNetworkACLv2(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
for hostId, clients := range assocClientsToDisconnectPerHost {
|
||||
if host, ok := hostsMap[hostId]; ok {
|
||||
if err = mq.PublishSingleHostPeerUpdate(&host, allNodes, nil, clients, false); err != nil {
|
||||
slog.Error(
|
||||
"failed to publish peer update to ingress after ACL update on network",
|
||||
"network",
|
||||
netname,
|
||||
"host",
|
||||
hostId,
|
||||
)
|
||||
if err = mq.PublishSingleHostPeerUpdate(&host, allNodes, nil, clients, false, nil); err != nil {
|
||||
slog.Error("failed to publish peer update to ingress after ACL update on network", "network", netname, "host", hostId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -624,7 +624,7 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
go func() {
|
||||
if err := mq.PublishSingleHostPeerUpdate(host, allNodes, nil, removedClients[:], false); err != nil {
|
||||
if err := mq.PublishSingleHostPeerUpdate(host, allNodes, nil, removedClients[:], false, nil); err != nil {
|
||||
slog.Error("publishSingleHostUpdate", "host", host.Name, "error", err)
|
||||
}
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
|
|
|
@ -676,10 +676,14 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.OwnerID == user.UserName {
|
||||
err = logic.DeleteExtClient(extclient.Network, extclient.ClientID)
|
||||
err = logic.DeleteExtClientAndCleanup(extclient)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete extclient",
|
||||
"id", extclient.ClientID, "owner", user.UserName, "error", err)
|
||||
"id", extclient.ClientID, "owner", username, "error", err)
|
||||
} else {
|
||||
if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
|
||||
slog.Error("error setting ext peers: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
go.mod
11
go.mod
|
@ -3,7 +3,7 @@ module github.com/gravitl/netmaker
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.3
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/google/uuid v1.6.0
|
||||
|
@ -16,10 +16,10 @@ require (
|
|||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/txn2/txeh v1.5.5
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/oauth2 v0.21.0
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
@ -28,7 +28,7 @@ require (
|
|||
require (
|
||||
filippo.io/edwards25519 v1.1.0
|
||||
github.com/c-robinson/iplib v1.0.8
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0
|
||||
github.com/posthog/posthog-go v1.2.18
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -66,6 +66,5 @@ require (
|
|||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
)
|
||||
|
|
28
go.sum
28
go.sum
|
@ -2,18 +2,16 @@ cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2Qx
|
|||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/c-robinson/iplib v1.0.8 h1:exDRViDyL9UBLcfmlxxkY5odWX5092nPsQIykHXhIn4=
|
||||
github.com/c-robinson/iplib v1.0.8/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo=
|
||||
github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
|
||||
github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik=
|
||||
github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE=
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
|
@ -61,8 +59,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
|
|||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0 h1:Y2hUrkfuM0on62KZOci/VLijlkdF/yeWU262BQgvcjE=
|
||||
github.com/posthog/posthog-go v0.0.0-20211028072449-93c17c49e2b0/go.mod h1:oa2sAs9tGai3VldabTV0eWejt/O4/OOD7azP8GaikqU=
|
||||
github.com/posthog/posthog-go v1.2.18 h1:2CBA0LOB0up+gon+xpeXuhFw69gZpjAYxQoBBGwiDWw=
|
||||
github.com/posthog/posthog-go v1.2.18/go.mod h1:QjlpryJtfYLrZF2GUkAhejH4E7WlDbdKkvOi5hLmkdg=
|
||||
github.com/resendlabs/resend-go v1.7.0 h1:DycOqSXtw2q7aB+Nt9DDJUDtaYcrNPGn1t5RFposas0=
|
||||
github.com/resendlabs/resend-go v1.7.0/go.mod h1:yip1STH7Bqfm4fD0So5HgyNbt5taG5Cplc4xXxETyLI=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
|
@ -70,13 +68,11 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
|||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rqlite/gorqlite v0.0.0-20240122221808-a8a425b1a6aa h1:hxMLFbj+F444JAS5nUQxTDZwUxwCRqg3WkNqhiDzXrM=
|
||||
github.com/rqlite/gorqlite v0.0.0-20240122221808-a8a425b1a6aa/go.mod h1:xF/KoXmrRyahPfo5L7Szb5cAAUl53dMWBh9cMruGEZg=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seancfoley/bintree v1.3.1 h1:cqmmQK7Jm4aw8gna0bP+huu5leVOgHGSJBEpUx3EXGI=
|
||||
github.com/seancfoley/bintree v1.3.1/go.mod h1:hIUabL8OFYyFVTQ6azeajbopogQc2l5C/hiXMcemWNU=
|
||||
github.com/seancfoley/ipaddress-go v1.6.0 h1:9z7yGmOnV4P2ML/dlR/kCJiv5tp8iHOOetJvxJh/R5w=
|
||||
github.com/seancfoley/ipaddress-go v1.6.0/go.mod h1:TQRZgv+9jdvzHmKoPGBMxyiaVmoI0rYpfEk8Q/sL/Iw=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
|
@ -89,15 +85,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
|||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/txn2/txeh v1.5.5 h1:UN4e/lCK5HGw/gGAi2GCVrNKg0GTCUWs7gs5riaZlz4=
|
||||
github.com/txn2/txeh v1.5.5/go.mod h1:qYzGG9kCzeVEI12geK4IlanHWY8X4uy/I3NcW7mk8g4=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
|
@ -107,8 +100,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -124,8 +117,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
|
@ -152,7 +145,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
|
||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -295,6 +295,8 @@ func UpdateUser(userchange, user *models.User) (*models.User, error) {
|
|||
if err := IsNetworkRolesValid(userchange.NetworkRoles); err != nil {
|
||||
return userchange, errors.New("invalid network roles: " + err.Error())
|
||||
}
|
||||
// Reset Gw Access for service users
|
||||
go UpdateUserGwAccess(*user, *userchange)
|
||||
user.PlatformRoleID = userchange.PlatformRoleID
|
||||
user.UserGroups = userchange.UserGroups
|
||||
user.NetworkRoles = userchange.NetworkRoles
|
||||
|
|
|
@ -43,6 +43,8 @@ var IsNetworkRolesValid = func(networkRoles map[models.NetworkID]map[models.User
|
|||
return nil
|
||||
}
|
||||
|
||||
var UpdateUserGwAccess = func(currentUser, changeUser models.User) {}
|
||||
|
||||
var UpdateRole = func(r models.UserRolePermissionTemplate) error { return nil }
|
||||
|
||||
var InitialiseRoles = userRolesInit
|
||||
|
|
|
@ -129,6 +129,22 @@ func ListPendingUsers() ([]models.ReturnUser, error) {
|
|||
return pendingUsers, nil
|
||||
}
|
||||
|
||||
func GetUserMap() (map[string]models.User, error) {
|
||||
userMap := make(map[string]models.User)
|
||||
records, err := database.FetchRecords(database.USERS_TABLE_NAME)
|
||||
if err != nil && !database.IsEmptyRecord(err) {
|
||||
return userMap, err
|
||||
}
|
||||
for _, record := range records {
|
||||
u := models.User{}
|
||||
err = json.Unmarshal([]byte(record), &u)
|
||||
if err == nil {
|
||||
userMap[u.UserName] = u
|
||||
}
|
||||
}
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
func InsertUserInvite(invite models.UserInvite) error {
|
||||
data, err := json.Marshal(invite)
|
||||
if err != nil {
|
||||
|
|
|
@ -65,7 +65,7 @@ func UpdateNode(client mqtt.Client, msg mqtt.Message) {
|
|||
}
|
||||
allNodes, err := logic.GetAllNodes()
|
||||
if err == nil {
|
||||
PublishSingleHostPeerUpdate(host, allNodes, nil, nil, false)
|
||||
PublishSingleHostPeerUpdate(host, allNodes, nil, nil, false, nil)
|
||||
}
|
||||
} else {
|
||||
err = PublishPeerUpdate(false)
|
||||
|
@ -117,7 +117,7 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = PublishSingleHostPeerUpdate(currentHost, nodes, nil, nil, false); err != nil {
|
||||
if err = PublishSingleHostPeerUpdate(currentHost, nodes, nil, nil, false, nil); err != nil {
|
||||
slog.Error("failed peers publish after join acknowledged", "name", hostUpdate.Host.Name, "id", currentHost.ID, "error", err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
|
@ -13,6 +14,9 @@ import (
|
|||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
var batchSize = servercfg.GetPeerUpdateBatchSize()
|
||||
var batchUpdate = servercfg.GetBatchPeerUpdate()
|
||||
|
||||
// PublishPeerUpdate --- determines and publishes a peer update to all the hosts
|
||||
func PublishPeerUpdate(replacePeers bool) error {
|
||||
if !servercfg.IsMessageQueueBackend() {
|
||||
|
@ -28,15 +32,37 @@ func PublishPeerUpdate(replacePeers bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, host := range hosts {
|
||||
host := host
|
||||
go func(host models.Host) {
|
||||
if err = PublishSingleHostPeerUpdate(&host, allNodes, nil, nil, replacePeers); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", host.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}(host)
|
||||
|
||||
//if batch peer update disabled
|
||||
if !batchUpdate {
|
||||
for _, host := range hosts {
|
||||
host := host
|
||||
go func(host models.Host) {
|
||||
if err = PublishSingleHostPeerUpdate(&host, allNodes, nil, nil, replacePeers, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", host.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}(host)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
||||
//if batch peer update enabled
|
||||
batchHost := BatchItems(hosts, batchSize)
|
||||
var wg sync.WaitGroup
|
||||
for _, v := range batchHost {
|
||||
hostLen := len(v)
|
||||
wg.Add(hostLen)
|
||||
for i := 0; i < hostLen; i++ {
|
||||
host := hosts[i]
|
||||
go func(host models.Host) {
|
||||
if err = PublishSingleHostPeerUpdate(&host, allNodes, nil, nil, replacePeers, &wg); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", host.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}(host)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PublishDeletedNodePeerUpdate --- determines and publishes a peer update
|
||||
|
@ -57,7 +83,7 @@ func PublishDeletedNodePeerUpdate(delNode *models.Node) error {
|
|||
}
|
||||
for _, host := range hosts {
|
||||
host := host
|
||||
if err = PublishSingleHostPeerUpdate(&host, allNodes, delNode, nil, false); err != nil {
|
||||
if err = PublishSingleHostPeerUpdate(&host, allNodes, delNode, nil, false, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", host.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +109,7 @@ func PublishDeletedClientPeerUpdate(delClient *models.ExtClient) error {
|
|||
for _, host := range hosts {
|
||||
host := host
|
||||
if host.OS != models.OS_Types.IoT {
|
||||
if err = PublishSingleHostPeerUpdate(&host, nodes, nil, []models.ExtClient{*delClient}, false); err != nil {
|
||||
if err = PublishSingleHostPeerUpdate(&host, nodes, nil, []models.ExtClient{*delClient}, false, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", host.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +118,10 @@ func PublishDeletedClientPeerUpdate(delClient *models.ExtClient) error {
|
|||
}
|
||||
|
||||
// PublishSingleHostPeerUpdate --- determines and publishes a peer update to one host
|
||||
func PublishSingleHostPeerUpdate(host *models.Host, allNodes []models.Node, deletedNode *models.Node, deletedClients []models.ExtClient, replacePeers bool) error {
|
||||
func PublishSingleHostPeerUpdate(host *models.Host, allNodes []models.Node, deletedNode *models.Node, deletedClients []models.ExtClient, replacePeers bool, wg *sync.WaitGroup) error {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
peerUpdate, err := logic.GetPeerUpdateForHost("", host, allNodes, deletedNode, deletedClients)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
21
mq/util.go
21
mq/util.go
|
@ -3,6 +3,7 @@ package mq
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -45,6 +46,26 @@ func DecryptMsg(node *models.Node, msg []byte) ([]byte, error) {
|
|||
return decryptMsgWithHost(host, msg)
|
||||
}
|
||||
|
||||
func BatchItems[T any](items []T, batchSize int) [][]T {
|
||||
if batchSize <= 0 {
|
||||
return nil
|
||||
}
|
||||
remainderBatchSize := len(items) % batchSize
|
||||
nBatches := int(math.Ceil(float64(len(items)) / float64(batchSize)))
|
||||
batches := make([][]T, nBatches)
|
||||
for i := range batches {
|
||||
if i == nBatches-1 && remainderBatchSize > 0 {
|
||||
batches[i] = make([]T, remainderBatchSize)
|
||||
} else {
|
||||
batches[i] = make([]T, batchSize)
|
||||
}
|
||||
for j := range batches[i] {
|
||||
batches[i][j] = items[i*batchSize+j]
|
||||
}
|
||||
}
|
||||
return batches
|
||||
}
|
||||
|
||||
func encryptMsg(host *models.Host, msg []byte) ([]byte, error) {
|
||||
if host.OS == models.OS_Types.IoT {
|
||||
return msg, nil
|
||||
|
|
|
@ -130,14 +130,8 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
node.IsRelay = true // for iot update to recognise that it has to delete relay peer
|
||||
if err = mq.PublishSingleHostPeerUpdate(h, nodes, &node, nil, false); err != nil {
|
||||
logger.Log(
|
||||
1,
|
||||
"failed to publish peer update to host",
|
||||
h.ID.String(),
|
||||
": ",
|
||||
err.Error(),
|
||||
)
|
||||
if err = mq.PublishSingleHostPeerUpdate(h, nodes, &node, nil, false, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", h.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,6 +174,10 @@ func inviteUsers(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("super admin cannot be invited"), "badrequest"))
|
||||
return
|
||||
}
|
||||
if inviteReq.PlatformRoleID == "" {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("platform role id cannot be empty"), "badrequest"))
|
||||
return
|
||||
}
|
||||
if (inviteReq.PlatformRoleID == models.AdminRole.String() ||
|
||||
inviteReq.PlatformRoleID == models.SuperAdminRole.String()) && caller.PlatformRoleID != models.SuperAdminRole {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can invite admin users"), "forbidden"))
|
||||
|
@ -429,6 +433,12 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
// fetch curr group
|
||||
currUserG, err := proLogic.GetUserGroup(userGroup.ID)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateUpdateGroupReq(userGroup)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
|
@ -439,6 +449,8 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
// reset configs for service user
|
||||
go proLogic.UpdatesUserGwAccessOnGrpUpdates(currUserG.NetworkRoles, userGroup.NetworkRoles)
|
||||
logic.ReturnSuccessResponseWithJson(w, r, userGroup, "updated user group")
|
||||
}
|
||||
|
||||
|
@ -453,6 +465,13 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
|
|||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
//
|
||||
// @Summary Delete user group.
|
||||
// @Router /api/v1/user/group [delete]
|
||||
// @Tags Users
|
||||
// @Param group_id param string true "group id required to delete the role"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
gid, _ := url.QueryUnescape(r.URL.Query().Get("group_id"))
|
||||
|
@ -460,25 +479,26 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err := proLogic.DeleteUserGroup(models.UserGroupID(gid))
|
||||
userG, err := proLogic.GetUserGroup(models.UserGroupID(gid))
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.DeleteUserGroup(models.UserGroupID(gid))
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
|
||||
logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
|
||||
}
|
||||
|
||||
// swagger:route GET /api/v1/user/roles user listRoles
|
||||
//
|
||||
// lists all user roles.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
// @Summary lists all user roles.
|
||||
// @Router /api/v1/user/roles [get]
|
||||
// @Tags Users
|
||||
// @Param role_id param string true "roleid required to get the role details"
|
||||
// @Success 200 {object} []models.UserRolePermissionTemplate
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func listRoles(w http.ResponseWriter, r *http.Request) {
|
||||
platform, _ := url.QueryUnescape(r.URL.Query().Get("platform"))
|
||||
var roles []models.UserRolePermissionTemplate
|
||||
|
@ -499,17 +519,12 @@ func listRoles(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnSuccessResponseWithJson(w, r, roles, "successfully fetched user roles permission templates")
|
||||
}
|
||||
|
||||
// swagger:route GET /api/v1/user/role user getRole
|
||||
//
|
||||
// Get user role permission templates.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
// @Summary Get user role permission template.
|
||||
// @Router /api/v1/user/role [get]
|
||||
// @Tags Users
|
||||
// @Param role_id param string true "roleid required to get the role details"
|
||||
// @Success 200 {object} models.UserRolePermissionTemplate
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func getRole(w http.ResponseWriter, r *http.Request) {
|
||||
rid, _ := url.QueryUnescape(r.URL.Query().Get("role_id"))
|
||||
if rid == "" {
|
||||
|
@ -527,17 +542,12 @@ func getRole(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnSuccessResponseWithJson(w, r, role, "successfully fetched user role permission templates")
|
||||
}
|
||||
|
||||
// swagger:route POST /api/v1/user/role user createRole
|
||||
//
|
||||
// Create user role permission template.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
// @Summary Create user role permission template.
|
||||
// @Router /api/v1/user/role [post]
|
||||
// @Tags Users
|
||||
// @Param body models.UserRolePermissionTemplate true "user role template"
|
||||
// @Success 200 {object} models.UserRolePermissionTemplate
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func createRole(w http.ResponseWriter, r *http.Request) {
|
||||
var userRole models.UserRolePermissionTemplate
|
||||
err := json.NewDecoder(r.Body).Decode(&userRole)
|
||||
|
@ -562,17 +572,12 @@ func createRole(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnSuccessResponseWithJson(w, r, userRole, "created user role")
|
||||
}
|
||||
|
||||
// swagger:route PUT /api/v1/user/role user updateRole
|
||||
//
|
||||
// Update user role permission template.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
// @Summary Update user role permission template.
|
||||
// @Router /api/v1/user/role [put]
|
||||
// @Tags Users
|
||||
// @Param body models.UserRolePermissionTemplate true "user role template"
|
||||
// @Success 200 {object} userBodyResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func updateRole(w http.ResponseWriter, r *http.Request) {
|
||||
var userRole models.UserRolePermissionTemplate
|
||||
err := json.NewDecoder(r.Body).Decode(&userRole)
|
||||
|
@ -582,6 +587,11 @@ func updateRole(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
currRole, err := logic.GetRole(userRole.ID)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateUpdateRoleReq(&userRole)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
|
@ -593,20 +603,17 @@ func updateRole(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
// reset configs for service user
|
||||
go proLogic.UpdatesUserGwAccessOnRoleUpdates(currRole.NetworkLevelAccess, userRole.NetworkLevelAccess, string(userRole.NetworkID))
|
||||
logic.ReturnSuccessResponseWithJson(w, r, userRole, "updated user role")
|
||||
}
|
||||
|
||||
// swagger:route DELETE /api/v1/user/role user deleteRole
|
||||
//
|
||||
// Delete user role permission template.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: userBodyResponse
|
||||
// @Summary Delete user role permission template.
|
||||
// @Router /api/v1/user/role [delete]
|
||||
// @Tags Users
|
||||
// @Param role_id param string true "roleid required to delete the role"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func deleteRole(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
rid, _ := url.QueryUnescape(r.URL.Query().Get("role_id"))
|
||||
|
@ -614,12 +621,18 @@ func deleteRole(w http.ResponseWriter, r *http.Request) {
|
|||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err := proLogic.DeleteRole(models.UserRoleID(rid), false)
|
||||
role, err := logic.GetRole(models.UserRoleID(rid))
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.DeleteRole(models.UserRoleID(rid), false)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logic.ReturnSuccessResponseWithJson(w, r, nil, "created user role")
|
||||
go proLogic.UpdatesUserGwAccessOnRoleUpdates(role.NetworkLevelAccess, make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope), role.NetworkID.String())
|
||||
logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user role")
|
||||
}
|
||||
|
||||
// @Summary Attach user to a remote access gateway
|
||||
|
@ -791,6 +804,12 @@ func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
|
||||
}
|
||||
|
||||
// @Summary Get Users Remote Access Gw.
|
||||
// @Router /api/users/{username}/remote_access_gw [get]
|
||||
// @Tags Users
|
||||
// @Param username path string true "Username to fetch all the gateways with access"
|
||||
// @Success 200 {object} map[string][]models.UserRemoteGws
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
|
||||
// set header.
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
@ -927,222 +946,6 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(userGws)
|
||||
}
|
||||
|
||||
// swagger:route GET "/api/users/{username}/remote_access_gw" nodes getUserRemoteAccessGws
|
||||
//
|
||||
// Get an individual node.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: nodeResponse
|
||||
func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
|
||||
// set header.
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params = mux.Vars(r)
|
||||
username := params["username"]
|
||||
if username == "" {
|
||||
logic.ReturnErrorResponse(
|
||||
w,
|
||||
r,
|
||||
logic.FormatError(errors.New("required params username"), "badrequest"),
|
||||
)
|
||||
return
|
||||
}
|
||||
remoteAccessClientID := r.URL.Query().Get("remote_access_clientid")
|
||||
var req models.UserRemoteGwsReq
|
||||
if remoteAccessClientID == "" {
|
||||
err := json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
slog.Error("error decoding request body: ", "error", err)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
}
|
||||
reqFromMobile := r.URL.Query().Get("from_mobile") == "true"
|
||||
if req.RemoteAccessClientID == "" && remoteAccessClientID == "" {
|
||||
logic.ReturnErrorResponse(
|
||||
w,
|
||||
r,
|
||||
logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest"),
|
||||
)
|
||||
return
|
||||
}
|
||||
if req.RemoteAccessClientID == "" {
|
||||
req.RemoteAccessClientID = remoteAccessClientID
|
||||
}
|
||||
userGws := make(map[string][]models.UserRemoteGws)
|
||||
user, err := logic.GetUser(username)
|
||||
if err != nil {
|
||||
logger.Log(0, username, "failed to fetch user: ", err.Error())
|
||||
logic.ReturnErrorResponse(
|
||||
w,
|
||||
r,
|
||||
logic.FormatError(
|
||||
fmt.Errorf("failed to fetch user %s, error: %v", username, err),
|
||||
"badrequest",
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
allextClients, err := logic.GetAllExtClients()
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
processedAdminNodeIds := make(map[string]struct{})
|
||||
for _, extClient := range allextClients {
|
||||
if extClient.RemoteAccessClientID == req.RemoteAccessClientID &&
|
||||
extClient.OwnerID == username {
|
||||
node, err := logic.GetNodeByID(extClient.IngressGatewayID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if node.PendingDelete {
|
||||
continue
|
||||
}
|
||||
if !node.IsIngressGateway {
|
||||
continue
|
||||
}
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
network, err := logic.GetNetwork(node.Network)
|
||||
if err != nil {
|
||||
slog.Error("failed to get node network", "error", err)
|
||||
}
|
||||
|
||||
if _, ok := user.RemoteGwIDs[node.ID.String()]; (user.PlatformRoleID != models.AdminRole && user.PlatformRoleID != models.SuperAdminRole) && ok {
|
||||
gws := userGws[node.Network]
|
||||
extClient.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
GwClient: extClient,
|
||||
Connected: true,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
GwPeerPublicKey: host.PublicKey.String(),
|
||||
GwListenPort: logic.GetPeerListenPort(host),
|
||||
Metadata: node.Metadata,
|
||||
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
|
||||
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
delete(user.RemoteGwIDs, node.ID.String())
|
||||
} else {
|
||||
gws := userGws[node.Network]
|
||||
extClient.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
GwClient: extClient,
|
||||
Connected: true,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
GwPeerPublicKey: host.PublicKey.String(),
|
||||
GwListenPort: logic.GetPeerListenPort(host),
|
||||
Metadata: node.Metadata,
|
||||
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
|
||||
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
processedAdminNodeIds[node.ID.String()] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add remaining gw nodes to resp
|
||||
if user.PlatformRoleID != models.AdminRole && user.PlatformRoleID != models.SuperAdminRole {
|
||||
for gwID := range user.RemoteGwIDs {
|
||||
node, err := logic.GetNodeByID(gwID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if !node.IsIngressGateway {
|
||||
continue
|
||||
}
|
||||
if node.PendingDelete {
|
||||
continue
|
||||
}
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
network, err := logic.GetNetwork(node.Network)
|
||||
if err != nil {
|
||||
slog.Error("failed to get node network", "error", err)
|
||||
}
|
||||
gws := userGws[node.Network]
|
||||
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
GwPeerPublicKey: host.PublicKey.String(),
|
||||
GwListenPort: logic.GetPeerListenPort(host),
|
||||
Metadata: node.Metadata,
|
||||
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
|
||||
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
}
|
||||
} else {
|
||||
allNodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch all nodes", "error", err)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
for _, node := range allNodes {
|
||||
_, ok := processedAdminNodeIds[node.ID.String()]
|
||||
if node.IsIngressGateway && !node.PendingDelete && !ok {
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch host", "error", err)
|
||||
continue
|
||||
}
|
||||
network, err := logic.GetNetwork(node.Network)
|
||||
if err != nil {
|
||||
slog.Error("failed to get node network", "error", err)
|
||||
}
|
||||
gws := userGws[node.Network]
|
||||
|
||||
gws = append(gws, models.UserRemoteGws{
|
||||
GwID: node.ID.String(),
|
||||
GWName: host.Name,
|
||||
Network: node.Network,
|
||||
IsInternetGateway: node.IsInternetGateway,
|
||||
GwPeerPublicKey: host.PublicKey.String(),
|
||||
GwListenPort: logic.GetPeerListenPort(host),
|
||||
Metadata: node.Metadata,
|
||||
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
|
||||
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
|
||||
})
|
||||
userGws[node.Network] = gws
|
||||
}
|
||||
}
|
||||
}
|
||||
if reqFromMobile {
|
||||
// send resp in array format
|
||||
userGwsArr := []models.UserRemoteGws{}
|
||||
for _, userGwI := range userGws {
|
||||
userGwsArr = append(userGwsArr, userGwI...)
|
||||
}
|
||||
logic.ReturnSuccessResponseWithJson(w, r, userGwsArr, "fetched gateways for user"+username)
|
||||
return
|
||||
}
|
||||
slog.Debug("returned user gws", "user", username, "gws", userGws)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(userGws)
|
||||
}
|
||||
|
||||
// @Summary List users attached to an remote access gateway
|
||||
// @Router /api/nodes/{network}/{nodeid}/ingress/users [get]
|
||||
// @Tags PRO
|
||||
|
|
|
@ -131,6 +131,7 @@ func InitPro() {
|
|||
logic.IsGroupsValid = proLogic.IsGroupsValid
|
||||
logic.IsNetworkRolesValid = proLogic.IsNetworkRolesValid
|
||||
logic.InitialiseRoles = proLogic.UserRolesInit
|
||||
logic.UpdateUserGwAccess = proLogic.UpdateUserGwAccess
|
||||
}
|
||||
|
||||
func retrieveProLogo() string {
|
||||
|
|
|
@ -9,6 +9,9 @@ import (
|
|||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
var ServiceUserPermissionTemplate = models.UserRolePermissionTemplate{
|
||||
|
@ -351,8 +354,19 @@ func DeleteRole(rid models.UserRoleID, force bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !force && role.Default {
|
||||
return errors.New("cannot delete default role")
|
||||
if role.NetworkID == "" {
|
||||
return errors.New("cannot delete platform role")
|
||||
}
|
||||
// allow deletion of default network roles if network doesn't exist
|
||||
if role.NetworkID == models.AllNetworks {
|
||||
return errors.New("cannot delete default network role")
|
||||
}
|
||||
// check if network exists
|
||||
exists, _ := logic.NetworkExists(role.NetworkID.String())
|
||||
if role.Default {
|
||||
if exists && !force {
|
||||
return errors.New("cannot delete default role")
|
||||
}
|
||||
}
|
||||
for _, user := range users {
|
||||
for userG := range user.UserGroups {
|
||||
|
@ -516,7 +530,6 @@ func HasNetworkRsrcScope(permissionTemplate models.UserRolePermissionTemplate, n
|
|||
return ok
|
||||
}
|
||||
func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {
|
||||
logger.Log(0, "------------> 7. getUserRemoteAccessGwsV1")
|
||||
gws = make(map[string]models.Node)
|
||||
userGwAccessScope := GetUserNetworkRolesWithRemoteVPNAccess(user)
|
||||
logger.Log(0, fmt.Sprintf("User Gw Access Scope: %+v", userGwAccessScope))
|
||||
|
@ -525,7 +538,6 @@ func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
logger.Log(0, fmt.Sprintf("------------> 8. getUserRemoteAccessGwsV1 %+v", allNetAccess))
|
||||
for _, node := range nodes {
|
||||
if node.IsIngressGateway && !node.PendingDelete {
|
||||
if allNetAccess {
|
||||
|
@ -545,14 +557,12 @@ func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.Log(0, "------------> 9. getUserRemoteAccessGwsV1")
|
||||
return
|
||||
}
|
||||
|
||||
// GetUserNetworkRoles - get user network roles
|
||||
func GetUserNetworkRolesWithRemoteVPNAccess(user models.User) (gwAccess map[models.NetworkID]map[models.RsrcID]models.RsrcPermissionScope) {
|
||||
gwAccess = make(map[models.NetworkID]map[models.RsrcID]models.RsrcPermissionScope)
|
||||
logger.Log(0, "------------> 7.1 getUserRemoteAccessGwsV1")
|
||||
platformRole, err := logic.GetRole(user.PlatformRoleID)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -564,7 +574,6 @@ func GetUserNetworkRolesWithRemoteVPNAccess(user models.User) (gwAccess map[mode
|
|||
if _, ok := user.NetworkRoles[models.AllNetworks]; ok {
|
||||
gwAccess[models.NetworkID("*")] = make(map[models.RsrcID]models.RsrcPermissionScope)
|
||||
}
|
||||
logger.Log(0, "------------> 7.2 getUserRemoteAccessGwsV1")
|
||||
if len(user.UserGroups) > 0 {
|
||||
for gID := range user.UserGroups {
|
||||
userG, err := GetUserGroup(gID)
|
||||
|
@ -664,18 +673,18 @@ func GetUserNetworkRolesWithRemoteVPNAccess(user models.User) (gwAccess map[mode
|
|||
}
|
||||
}
|
||||
|
||||
logger.Log(0, "------------> 7.3 getUserRemoteAccessGwsV1")
|
||||
return
|
||||
}
|
||||
|
||||
func GetFilteredNodesByUserAccess(user models.User, nodes []models.Node) (filteredNodes []models.Node) {
|
||||
|
||||
nodesMap := make(map[string]struct{})
|
||||
allNetworkRoles := []models.UserRoleID{}
|
||||
allNetworkRoles := make(map[models.UserRoleID]struct{})
|
||||
|
||||
if len(user.NetworkRoles) > 0 {
|
||||
for _, netRoles := range user.NetworkRoles {
|
||||
for netRoleI := range netRoles {
|
||||
allNetworkRoles = append(allNetworkRoles, netRoleI)
|
||||
allNetworkRoles[netRoleI] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -692,14 +701,14 @@ func GetFilteredNodesByUserAccess(user models.User, nodes []models.Node) (filter
|
|||
}
|
||||
for _, netRoles := range userG.NetworkRoles {
|
||||
for netRoleI := range netRoles {
|
||||
allNetworkRoles = append(allNetworkRoles, netRoleI)
|
||||
allNetworkRoles[netRoleI] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, networkRoleID := range allNetworkRoles {
|
||||
for networkRoleID := range allNetworkRoles {
|
||||
userPermTemplate, err := logic.GetRole(networkRoleID)
|
||||
if err != nil {
|
||||
continue
|
||||
|
@ -735,6 +744,7 @@ func GetFilteredNodesByUserAccess(user models.User, nodes []models.Node) (filter
|
|||
if scope.Read {
|
||||
gwNode, err := logic.GetNodeByID(gwID.String())
|
||||
if err == nil && gwNode.IsIngressGateway {
|
||||
nodesMap[gwNode.ID.String()] = struct{}{}
|
||||
filteredNodes = append(filteredNodes, gwNode)
|
||||
}
|
||||
}
|
||||
|
@ -840,3 +850,207 @@ func PrepareOauthUserFromInvite(in models.UserInvite) (models.User, error) {
|
|||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func UpdatesUserGwAccessOnRoleUpdates(currNetworkAccess,
|
||||
changeNetworkAccess map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope, netID string) {
|
||||
networkChangeMap := make(map[models.RsrcID]models.RsrcPermissionScope)
|
||||
for rsrcType, RsrcPermsMap := range currNetworkAccess {
|
||||
if rsrcType != models.RemoteAccessGwRsrc {
|
||||
continue
|
||||
}
|
||||
if _, ok := changeNetworkAccess[rsrcType]; !ok {
|
||||
for rsrcID, scope := range RsrcPermsMap {
|
||||
networkChangeMap[rsrcID] = scope
|
||||
}
|
||||
} else {
|
||||
for rsrcID, scope := range RsrcPermsMap {
|
||||
if _, ok := changeNetworkAccess[rsrcType][rsrcID]; !ok {
|
||||
networkChangeMap[rsrcID] = scope
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extclients, err := logic.GetAllExtClients()
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch extclients", "error", err)
|
||||
return
|
||||
}
|
||||
userMap, err := logic.GetUserMap()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.Network != netID {
|
||||
continue
|
||||
}
|
||||
if _, ok := networkChangeMap[models.AllRemoteAccessGwRsrcID]; ok {
|
||||
if user, ok := userMap[extclient.OwnerID]; ok {
|
||||
if user.PlatformRoleID != models.ServiceUser {
|
||||
continue
|
||||
}
|
||||
err = logic.DeleteExtClientAndCleanup(extclient)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete extclient",
|
||||
"id", extclient.ClientID, "owner", user.UserName, "error", err)
|
||||
} else {
|
||||
if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
|
||||
slog.Error("error setting ext peers: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, ok := networkChangeMap[models.RsrcID(extclient.IngressGatewayID)]; ok {
|
||||
if user, ok := userMap[extclient.OwnerID]; ok {
|
||||
if user.PlatformRoleID != models.ServiceUser {
|
||||
continue
|
||||
}
|
||||
err = logic.DeleteExtClientAndCleanup(extclient)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete extclient",
|
||||
"id", extclient.ClientID, "owner", user.UserName, "error", err)
|
||||
} else {
|
||||
if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
|
||||
slog.Error("error setting ext peers: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatesUserGwAccessOnGrpUpdates(currNetworkRoles, changeNetworkRoles map[models.NetworkID]map[models.UserRoleID]struct{}) {
|
||||
networkChangeMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
|
||||
for netID, networkUserRoles := range currNetworkRoles {
|
||||
if _, ok := changeNetworkRoles[netID]; !ok {
|
||||
for netRoleID := range networkUserRoles {
|
||||
if _, ok := networkChangeMap[netID]; !ok {
|
||||
networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
|
||||
}
|
||||
networkChangeMap[netID][netRoleID] = struct{}{}
|
||||
}
|
||||
} else {
|
||||
for netRoleID := range networkUserRoles {
|
||||
if _, ok := changeNetworkRoles[netID][netRoleID]; !ok {
|
||||
if _, ok := networkChangeMap[netID]; !ok {
|
||||
networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
|
||||
}
|
||||
networkChangeMap[netID][netRoleID] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
extclients, err := logic.GetAllExtClients()
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch extclients", "error", err)
|
||||
return
|
||||
}
|
||||
userMap, err := logic.GetUserMap()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
|
||||
if _, ok := networkChangeMap[models.NetworkID(extclient.Network)]; ok {
|
||||
if user, ok := userMap[extclient.OwnerID]; ok {
|
||||
if user.PlatformRoleID != models.ServiceUser {
|
||||
continue
|
||||
}
|
||||
err = logic.DeleteExtClientAndCleanup(extclient)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete extclient",
|
||||
"id", extclient.ClientID, "owner", user.UserName, "error", err)
|
||||
} else {
|
||||
if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
|
||||
slog.Error("error setting ext peers: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func UpdateUserGwAccess(currentUser, changeUser models.User) {
|
||||
if changeUser.PlatformRoleID != models.ServiceUser {
|
||||
return
|
||||
}
|
||||
|
||||
networkChangeMap := make(map[models.NetworkID]map[models.UserRoleID]struct{})
|
||||
for netID, networkUserRoles := range currentUser.NetworkRoles {
|
||||
if _, ok := changeUser.NetworkRoles[netID]; !ok {
|
||||
for netRoleID := range networkUserRoles {
|
||||
if _, ok := networkChangeMap[netID]; !ok {
|
||||
networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
|
||||
}
|
||||
networkChangeMap[netID][netRoleID] = struct{}{}
|
||||
}
|
||||
} else {
|
||||
for netRoleID := range networkUserRoles {
|
||||
if _, ok := changeUser.NetworkRoles[netID][netRoleID]; !ok {
|
||||
if _, ok := networkChangeMap[netID]; !ok {
|
||||
networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
|
||||
}
|
||||
networkChangeMap[netID][netRoleID] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for gID := range currentUser.UserGroups {
|
||||
if _, ok := changeUser.UserGroups[gID]; ok {
|
||||
continue
|
||||
}
|
||||
userG, err := GetUserGroup(gID)
|
||||
if err == nil {
|
||||
for netID, networkUserRoles := range userG.NetworkRoles {
|
||||
for netRoleID := range networkUserRoles {
|
||||
if _, ok := networkChangeMap[netID]; !ok {
|
||||
networkChangeMap[netID] = make(map[models.UserRoleID]struct{})
|
||||
}
|
||||
networkChangeMap[netID][netRoleID] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(networkChangeMap) == 0 {
|
||||
return
|
||||
}
|
||||
// TODO - cleanup gw access when role and groups are updated
|
||||
//removedGwAccess
|
||||
extclients, err := logic.GetAllExtClients()
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch extclients", "error", err)
|
||||
return
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.OwnerID == currentUser.UserName {
|
||||
if _, ok := networkChangeMap[models.NetworkID(extclient.Network)]; ok {
|
||||
err = logic.DeleteExtClientAndCleanup(extclient)
|
||||
if err != nil {
|
||||
slog.Error("failed to delete extclient",
|
||||
"id", extclient.ClientID, "owner", changeUser.UserName, "error", err)
|
||||
} else {
|
||||
if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
|
||||
slog.Error("error setting ext peers: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ func disableExtClient(client *models.ExtClient) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go mq.PublishSingleHostPeerUpdate(ingressHost, nodes, nil, []models.ExtClient{*client}, false)
|
||||
go mq.PublishSingleHostPeerUpdate(ingressHost, nodes, nil, []models.ExtClient{*client}, false, nil)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ save_config() { (
|
|||
fi
|
||||
if [ -n "$NETMAKER_BASE_DOMAIN" ]; then
|
||||
save_config_item NM_DOMAIN "$NETMAKER_BASE_DOMAIN"
|
||||
save_config_item FRONTEND_URL "https://dashboard.$NETMAKER_BASE_DOMAIN"
|
||||
fi
|
||||
save_config_item UI_IMAGE_TAG "$IMAGE_TAG"
|
||||
# version-specific entries
|
||||
|
|
|
@ -650,6 +650,28 @@ func GetMetricInterval() string {
|
|||
return mi
|
||||
}
|
||||
|
||||
// GetBatchPeerUpdate - if batch peer update
|
||||
func GetBatchPeerUpdate() bool {
|
||||
enabled := true
|
||||
if os.Getenv("PEER_UPDATE_BATCH") != "" {
|
||||
enabled = os.Getenv("PEER_UPDATE_BATCH") == "true"
|
||||
}
|
||||
return enabled
|
||||
}
|
||||
|
||||
// GetPeerUpdateBatchSize - get the batch size for peer update
|
||||
func GetPeerUpdateBatchSize() int {
|
||||
//default 50
|
||||
batchSize := 50
|
||||
if os.Getenv("PEER_UPDATE_BATCH_SIZE") != "" {
|
||||
b, e := strconv.Atoi(os.Getenv("PEER_UPDATE_BATCH_SIZE"))
|
||||
if e == nil && b > 0 && b < 1000 {
|
||||
batchSize = b
|
||||
}
|
||||
}
|
||||
return batchSize
|
||||
}
|
||||
|
||||
// GetEmqxRestEndpoint - returns the REST API Endpoint of EMQX
|
||||
func GetEmqxRestEndpoint() string {
|
||||
return os.Getenv("EMQX_REST_ENDPOINT")
|
||||
|
|
Loading…
Add table
Reference in a new issue