resolve merge conflicts

This commit is contained in:
abhishek9686 2024-08-20 18:32:49 +05:30
commit 27ceaed739
24 changed files with 448 additions and 357 deletions

View file

@ -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 }}"

View file

@ -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 ./... ; }

View file

@ -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

View file

@ -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

View file

@ -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)
}
}

View file

@ -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{}{}
}
}

View file

@ -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)
}
}
}

View file

@ -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 {

View file

@ -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
View file

@ -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
View file

@ -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=

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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())
}
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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()
}
}

View file

@ -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
}

View file

@ -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

View file

@ -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")