Prechádzať zdrojové kódy

Merge pull request #3595 from gravitl/release-v1.0.0

Release v1.0.0
Abhishek K 1 mesiac pred
rodič
commit
48de8ff4a2

+ 14 - 0
go.mod

@@ -46,6 +46,7 @@ require (
 	github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
 	github.com/guumaster/tablewriter v0.0.10
 	github.com/matryer/is v1.4.1
+	github.com/okta/okta-sdk-golang/v5 v5.0.6
 	github.com/pquerna/otp v1.5.0
 	github.com/spf13/cobra v1.9.1
 	google.golang.org/api v0.238.0
@@ -61,11 +62,15 @@ require (
 	cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
 	cloud.google.com/go/compute/metadata v0.7.0 // indirect
 	github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
+	github.com/cenkalti/backoff/v4 v4.1.3 // indirect
+	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.8 // indirect
+	github.com/go-jose/go-jose/v3 v3.0.3 // indirect
 	github.com/go-jose/go-jose/v4 v4.0.5 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/go-sql-driver/mysql v1.8.1 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
 	github.com/google/s2a-go v0.1.9 // indirect
 	github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
 	github.com/googleapis/gax-go/v2 v2.14.2 // indirect
@@ -77,6 +82,15 @@ require (
 	github.com/jackc/puddle/v2 v2.2.2 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/kelseyhightower/envconfig v1.4.0 // indirect
+	github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
+	github.com/lestrrat-go/blackmagic v1.0.2 // indirect
+	github.com/lestrrat-go/httpcc v1.0.1 // indirect
+	github.com/lestrrat-go/iter v1.0.2 // indirect
+	github.com/lestrrat-go/jwx v1.2.29 // indirect
+	github.com/lestrrat-go/option v1.0.1 // indirect
+	github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
 	github.com/rivo/uniseg v0.2.0 // indirect
 	github.com/rogpeppe/go-internal v1.14.1 // indirect
 	github.com/seancfoley/bintree v1.3.1 // indirect

+ 83 - 0
go.sum

@@ -12,18 +12,25 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8
 github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/c-robinson/iplib v1.0.8 h1:exDRViDyL9UBLcfmlxxkY5odWX5092nPsQIykHXhIn4=
 github.com/c-robinson/iplib v1.0.8/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo=
+github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
+github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
 github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
 github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 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/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
 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.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
 github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
+github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
+github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
 github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
 github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -42,6 +49,8 @@ github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAu
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
 github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
 github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
 github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
@@ -50,6 +59,7 @@ github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei
 github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
@@ -84,16 +94,33 @@ github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
 github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
 github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
 github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
+github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
+github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
+github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
+github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k=
+github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
+github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
+github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
+github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
+github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ=
+github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8=
+github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
+github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
 github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
 github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
@@ -105,6 +132,12 @@ github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEu
 github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
 github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
+github.com/okta/okta-sdk-golang/v5 v5.0.6 h1:p7ptDMB1KxQ/7xSh+6FhMSybwl+ubTV4f1oL4N0Bu6U=
+github.com/okta/okta-sdk-golang/v5 v5.0.6/go.mod h1:T/vmECtJX33YPZSVD+sorebd8LLhe38Bi/VrFTjgVX0=
+github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627 h1:pSCLCl6joCFRnjpeojzOpEYs4q7Vditq8fySFG5ap3Y=
+github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 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 v1.5.12 h1:nxK/z5QLCFxwzxV8GNvVd4Y1wJ++zJSWMGEtzU+/HLM=
@@ -132,12 +165,21 @@ github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wx
 github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
 github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
@@ -156,22 +198,63 @@ go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKr
 go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
 go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
 go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
+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.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
 golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
 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=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+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.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
 golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
 golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
 golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
 golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
 golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+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=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
 golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
 golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
 golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb h1:9aqVcYEDHmSNb0uOWukxV5lHV09WqiSiCuhEgWNETLY=
 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb/go.mod h1:mQqgjkW8GQQcJQsbBvK890TKqUK1DfKWkuBGbOkuMHQ=
 google.golang.org/api v0.238.0 h1:+EldkglWIg/pWjkq97sd+XxH7PxakNYoe/rkSTbnvOs=

+ 122 - 0
logic/acls.go

@@ -50,6 +50,43 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 		// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
 		// 	continue
 		// }
+		if IsNodeAllowedToCommunicateWithAllRsrcs(nodeI) {
+			if nodeI.Address.IP != nil {
+				rules = append(rules, models.FwRule{
+					SrcIP: net.IPNet{
+						IP:   nodeI.Address.IP,
+						Mask: net.CIDRMask(32, 32),
+					},
+					Allow: true,
+				})
+				rules = append(rules, models.FwRule{
+					SrcIP: node.NetworkRange,
+					DstIP: net.IPNet{
+						IP:   nodeI.Address.IP,
+						Mask: net.CIDRMask(32, 32),
+					},
+					Allow: true,
+				})
+			}
+			if nodeI.Address6.IP != nil {
+				rules = append(rules, models.FwRule{
+					SrcIP: net.IPNet{
+						IP:   nodeI.Address6.IP,
+						Mask: net.CIDRMask(128, 128),
+					},
+					Allow: true,
+				})
+				rules = append(rules, models.FwRule{
+					SrcIP: node.NetworkRange6,
+					DstIP: net.IPNet{
+						IP:   nodeI.Address.IP,
+						Mask: net.CIDRMask(128, 128),
+					},
+					Allow: true,
+				})
+			}
+			continue
+		}
 		for _, peer := range nodes {
 			if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
 				continue
@@ -74,6 +111,37 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 			}
 		}
 	}
+	if len(node.RelayedNodes) > 0 {
+		for _, relayedNodeID := range node.RelayedNodes {
+			relayedNode, err := GetNodeByID(relayedNodeID)
+			if err != nil {
+				continue
+			}
+
+			if relayedNode.Address.IP != nil {
+				relayedFwRule := models.FwRule{
+					AllowedProtocol: models.ALL,
+					AllowedPorts:    []string{},
+					Allow:           true,
+				}
+				relayedFwRule.DstIP = relayedNode.AddressIPNet4()
+				relayedFwRule.SrcIP = node.NetworkRange
+				rules = append(rules, relayedFwRule)
+			}
+
+			if relayedNode.Address6.IP != nil {
+				relayedFwRule := models.FwRule{
+					AllowedProtocol: models.ALL,
+					AllowedPorts:    []string{},
+					Allow:           true,
+				}
+				relayedFwRule.DstIP = relayedNode.AddressIPNet6()
+				relayedFwRule.SrcIP = node.NetworkRange6
+				rules = append(rules, relayedFwRule)
+			}
+
+		}
+	}
 	return
 }
 
@@ -851,6 +919,60 @@ func MigrateAclPolicies() {
 
 }
 
+func IsNodeAllowedToCommunicateWithAllRsrcs(node models.Node) bool {
+	// check default policy if all allowed return true
+	defaultPolicy, err := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
+	if err == nil {
+		if defaultPolicy.Enabled {
+			return true
+		}
+	}
+	var nodeId string
+	if node.IsStatic {
+		nodeId = node.StaticNode.ClientID
+		node = node.StaticNode.ConvertToStaticNode()
+	} else {
+		nodeId = node.ID.String()
+	}
+	nodeTags := make(map[models.TagID]struct{})
+
+	nodeTags[models.TagID(nodeId)] = struct{}{}
+	if node.IsGw {
+		nodeTags[models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName))] = struct{}{}
+	}
+	// list device policies
+	policies := ListDevicePolicies(models.NetworkID(node.Network))
+	srcMap := make(map[string]struct{})
+	dstMap := make(map[string]struct{})
+	defer func() {
+		srcMap = nil
+		dstMap = nil
+	}()
+	for _, policy := range policies {
+		if !policy.Enabled {
+			continue
+		}
+		srcMap = ConvAclTagToValueMap(policy.Src)
+		dstMap = ConvAclTagToValueMap(policy.Dst)
+		_, srcAll := srcMap["*"]
+		_, dstAll := dstMap["*"]
+
+		for tagID := range nodeTags {
+			if srcAll {
+				if _, ok := dstMap[tagID.String()]; ok {
+					return true
+				}
+			}
+			if dstAll {
+				if _, ok := srcMap[tagID.String()]; ok {
+					return true
+				}
+			}
+		}
+	}
+	return false
+}
+
 // IsNodeAllowedToCommunicate - check node is allowed to communicate with the peer // ADD ALLOWED DIRECTION - 0 => node -> peer, 1 => peer-> node,
 func isNodeAllowedToCommunicate(node, peer models.Node, checkDefaultPolicy bool) (bool, []models.Acl) {
 	var nodeId, peerId string

+ 1 - 6
logic/extpeers.go

@@ -729,12 +729,7 @@ func GetStaticNodesByNetwork(network models.NetworkID, onlyWg bool) (staticNode
 			if onlyWg && extI.RemoteAccessClientID != "" {
 				continue
 			}
-			n := models.Node{
-				IsStatic:   true,
-				StaticNode: extI,
-				IsUserNode: extI.RemoteAccessClientID != "",
-			}
-			staticNode = append(staticNode, n)
+			staticNode = append(staticNode, extI.ConvertToStaticNode())
 		}
 	}
 

+ 6 - 0
logic/peers.go

@@ -242,7 +242,13 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 			if peer.EgressDetails.IsEgressGateway {
 				AddEgressInfoToPeerByAccess(&node, &peer, eli, acls, defaultDevicePolicy.Enabled)
 			}
+			if node.Mutex != nil {
+				node.Mutex.Lock()
+			}
 			_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
+			if node.Mutex != nil {
+				node.Mutex.Unlock()
+			}
 			if peer.EgressDetails.IsEgressGateway {
 				peerKey := peerHost.PublicKey.String()
 				if isFailOverPeer && peer.FailedOverBy.String() != node.ID.String() {

+ 2 - 2
logic/settings.go

@@ -245,7 +245,7 @@ func GetAuthProviderInfo(settings models.ServerSettings) (pi []string) {
 	var authProvider = ""
 
 	defer func() {
-		if authProvider == "oidc" {
+		if authProvider == "okta" || authProvider == "oidc" {
 			if settings.OIDCIssuer != "" {
 				pi = append(pi, settings.OIDCIssuer)
 			} else {
@@ -256,7 +256,7 @@ func GetAuthProviderInfo(settings models.ServerSettings) (pi []string) {
 
 	if settings.AuthProvider != "" && settings.ClientID != "" && settings.ClientSecret != "" {
 		authProvider = strings.ToLower(settings.AuthProvider)
-		if authProvider == "google" || authProvider == "azure-ad" || authProvider == "github" || authProvider == "oidc" {
+		if authProvider == "google" || authProvider == "azure-ad" || authProvider == "github" || authProvider == "oidc" || authProvider == "okta" {
 			return []string{authProvider, settings.ClientID, settings.ClientSecret}
 		} else {
 			authProvider = ""

+ 2 - 0
models/settings.go

@@ -19,6 +19,8 @@ type ServerSettings struct {
 	GoogleAdminEmail               string   `json:"google_admin_email"`
 	GoogleSACredsJson              string   `json:"google_sa_creds_json"`
 	AzureTenant                    string   `json:"azure_tenant"`
+	OktaOrgURL                     string   `json:"okta_org_url"`
+	OktaAPIToken                   string   `json:"okta_api_token"`
 	UserFilters                    []string `json:"user_filters"`
 	GroupFilters                   []string `json:"group_filters"`
 	IDPSyncInterval                string   `json:"idp_sync_interval"`

+ 4 - 1
pro/auth/auth.go

@@ -27,6 +27,7 @@ const (
 	google_provider_name   = "google"
 	azure_ad_provider_name = "azure-ad"
 	github_provider_name   = "github"
+	okta_provider_name     = "okta"
 	oidc_provider_name     = "oidc"
 	verify_user            = "verifyuser"
 	user_signin_length     = 16
@@ -85,6 +86,8 @@ func getCurrentAuthFunctions() map[string]interface{} {
 		return azure_ad_functions
 	case github_provider_name:
 		return github_functions
+	case okta_provider_name:
+		return okta_functions
 	case oidc_provider_name:
 		return oidc_functions
 	default:
@@ -124,7 +127,7 @@ func InitializeAuthProvider() string {
 		logger.Log(1, "external OAuth detected, proceeding with https redirect: ("+serverConn+")")
 	}
 
-	if authInfo[0] == "oidc" {
+	if authInfo[0] == "okta" || authInfo[0] == "oidc" {
 		functions[init_provider].(func(string, string, string, string))(serverConn+"/api/oauth/callback", authInfo[1], authInfo[2], authInfo[3])
 		return authInfo[0]
 	}

+ 1 - 1
pro/auth/error.go

@@ -93,7 +93,7 @@ var htmlBaseTemplate = `<!DOCTYPE html>
 </html>`
 
 var oauthNotConfigured = fmt.Sprintf(htmlBaseTemplate, `<h2>Your Netmaker server does not have OAuth configured.</h2>
-<p>Please visit the docs <a href="https://docs.netmaker.io/docs/server-installation/identity-provider-integration-guide" target="_blank" rel="noopener">here</a> to learn how to.</p>`)
+<p>Please visit the docs <a href="https://docs.netmaker.io/docs/how-to-guides/identity-provider-integration-guide" target="_blank" rel="noopener">here</a> to learn how to.</p>`)
 
 var oauthStateInvalid = fmt.Sprintf(htmlBaseTemplate, `<h2>Invalid OAuth Session. Please re-try again.</h2>`)
 

+ 9 - 0
pro/auth/okta.go

@@ -0,0 +1,9 @@
+package auth
+
+var okta_functions = map[string]interface{}{
+	init_provider:   initOIDC,
+	get_user_info:   getOIDCUserInfo,
+	handle_callback: handleOIDCCallback,
+	handle_login:    handleOIDCLogin,
+	verify_user:     verifyOIDCUser,
+}

+ 6 - 0
pro/auth/sync.go

@@ -10,6 +10,7 @@ import (
 	"github.com/gravitl/netmaker/pro/idp"
 	"github.com/gravitl/netmaker/pro/idp/azure"
 	"github.com/gravitl/netmaker/pro/idp/google"
+	"github.com/gravitl/netmaker/pro/idp/okta"
 	proLogic "github.com/gravitl/netmaker/pro/logic"
 	"strings"
 	"sync"
@@ -72,6 +73,11 @@ func SyncFromIDP() error {
 		}
 	case "azure-ad":
 		idpClient = azure.NewAzureEntraIDClient()
+	case "okta":
+		idpClient, err = okta.NewOktaClientFromSettings()
+		if err != nil {
+			return err
+		}
 	default:
 		if settings.AuthProvider != "" {
 			return fmt.Errorf("invalid auth provider: %s", settings.AuthProvider)

+ 2 - 2
pro/auth/templates.go

@@ -115,10 +115,10 @@ var ssoErrCallbackTemplate = template.Must(
 			id="logo"
 		>
 		<h3>Server SSO Error</h3>
-		<h4>Error reason: {.Verb}</h4>
+		<h4>Error reason: {{.Verb}}</h4>
 		<em>Your Netmaker server may not have SSO configured properly.</em>
 		<em>
-			Please visit the <a href="https://docs.netmaker.io/docs/server-installation/integrating-oauth" target="_blank" rel="noopener">docs</a> for more information.
+			Please visit the <a href="https://docs.netmaker.io/docs/how-to-guides/identity-provider-integration-guide" target="_blank" rel="noopener">docs</a> for more information.
 		</em>
 		<p>
 			If you feel this is a mistake, please contact your network administrator.

+ 6 - 0
pro/controllers/failover.go

@@ -110,7 +110,13 @@ func resetFailOver(w http.ResponseWriter, r *http.Request) {
 	for _, node := range nodes {
 		if node.FailedOverBy != uuid.Nil {
 			node.FailedOverBy = uuid.Nil
+			if node.Mutex != nil {
+				node.Mutex.Lock()
+			}
 			node.FailOverPeers = make(map[string]struct{})
+			if node.Mutex != nil {
+				node.Mutex.Unlock()
+			}
 			logic.UpsertNode(&node)
 		}
 	}

+ 124 - 0
pro/idp/okta/okta.go

@@ -0,0 +1,124 @@
+package okta
+
+import (
+	"context"
+	"fmt"
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/pro/idp"
+	"github.com/okta/okta-sdk-golang/v5/okta"
+)
+
+type Client struct {
+	client *okta.APIClient
+}
+
+func NewOktaClient(oktaOrgURL, oktaAPIToken string) (*Client, error) {
+	config, err := okta.NewConfiguration(
+		okta.WithOrgUrl(oktaOrgURL),
+		okta.WithToken(oktaAPIToken),
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	return &Client{
+		client: okta.NewAPIClient(config),
+	}, nil
+}
+
+func NewOktaClientFromSettings() (*Client, error) {
+	settings := logic.GetServerSettings()
+
+	return NewOktaClient(settings.OktaOrgURL, settings.OktaAPIToken)
+}
+
+func (o *Client) Verify() error {
+	_, _, err := o.client.UserAPI.ListUsers(context.TODO()).Limit(1).Execute()
+	if err != nil {
+		return err
+	}
+
+	_, _, err = o.client.GroupAPI.ListGroups(context.TODO()).Limit(1).Execute()
+	return err
+}
+
+func (o *Client) GetUsers() ([]idp.User, error) {
+	var retval []idp.User
+	var allUsersFetched bool
+
+	for !allUsersFetched {
+		users, resp, err := o.client.UserAPI.ListUsers(context.TODO()).Execute()
+		if err != nil {
+			return nil, err
+		}
+
+		allUsersFetched = !resp.HasNextPage()
+
+		for _, user := range users {
+			id := *user.Id
+			username := *user.Profile.Login
+
+			displayName := ""
+			if user.Profile.FirstName.IsSet() && user.Profile.LastName.IsSet() {
+				displayName = fmt.Sprintf("%s %s", *user.Profile.FirstName.Get(), *user.Profile.LastName.Get())
+			}
+
+			accountDisabled := false
+			if *user.Status == "SUSPENDED" {
+				accountDisabled = true
+			}
+
+			retval = append(retval, idp.User{
+				ID:              id,
+				Username:        username,
+				DisplayName:     displayName,
+				AccountDisabled: accountDisabled,
+				AccountArchived: false,
+			})
+		}
+	}
+
+	return retval, nil
+}
+
+func (o *Client) GetGroups() ([]idp.Group, error) {
+	var retval []idp.Group
+	var allGroupsFetched bool
+
+	for !allGroupsFetched {
+		groups, resp, err := o.client.GroupAPI.ListGroups(context.TODO()).Execute()
+		if err != nil {
+			return nil, err
+		}
+
+		allGroupsFetched = !resp.HasNextPage()
+
+		for _, group := range groups {
+			var allMembersFetched bool
+			id := *group.Id
+			name := *group.Profile.Name
+
+			var members []string
+			for !allMembersFetched {
+				groupUsers, resp, err := o.client.GroupAPI.ListGroupUsers(context.TODO(), id).Execute()
+				if err != nil {
+					return nil, err
+				}
+
+				allMembersFetched = !resp.HasNextPage()
+
+				for _, groupUser := range groupUsers {
+					members = append(members, *groupUser.Id)
+				}
+			}
+
+			retval = append(retval, idp.Group{
+				ID:      id,
+				Name:    name,
+				Members: members,
+			})
+		}
+	}
+
+	return retval, nil
+}

+ 270 - 184
pro/logic/acls.go

@@ -17,6 +17,27 @@ func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []
 	defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
 	userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
 	for _, userNodeI := range userNodes {
+		if defaultUserPolicy.Enabled {
+			if userNodeI.StaticNode.Address != "" {
+				rules = append(rules, models.FwRule{
+					SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
+					DstIP:           net.IPNet{},
+					AllowedProtocol: models.ALL,
+					AllowedPorts:    []string{},
+					Allow:           true,
+				})
+			}
+			if userNodeI.StaticNode.Address6 != "" {
+				rules = append(rules, models.FwRule{
+					SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
+					DstIP:           net.IPNet{},
+					AllowedProtocol: models.ALL,
+					AllowedPorts:    []string{},
+					Allow:           true,
+				})
+			}
+			continue
+		}
 		for _, peer := range nodes {
 			if peer.IsUserNode {
 				continue
@@ -26,68 +47,76 @@ func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []
 				if peer.IsStatic {
 					peer = peer.StaticNode.ConvertToStaticNode()
 				}
-				if !defaultUserPolicy.Enabled {
-					for _, policy := range allowedPolicies {
-						if userNodeI.StaticNode.Address != "" {
-							rules = append(rules, models.FwRule{
-								SrcIP: userNodeI.StaticNode.AddressIPNet4(),
-								DstIP: net.IPNet{
-									IP:   peer.Address.IP,
-									Mask: net.CIDRMask(32, 32),
-								},
-								AllowedProtocol: policy.Proto,
-								AllowedPorts:    policy.Port,
-								Allow:           true,
-							})
-						}
-						if userNodeI.StaticNode.Address6 != "" {
+				for _, policy := range allowedPolicies {
+					if userNodeI.StaticNode.Address != "" {
+						rules = append(rules, models.FwRule{
+							SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+							DstIP: net.IPNet{
+								IP:   peer.Address.IP,
+								Mask: net.CIDRMask(32, 32),
+							},
+							AllowedProtocol: policy.Proto,
+							AllowedPorts:    policy.Port,
+							Allow:           true,
+						})
+					}
+					if userNodeI.StaticNode.Address6 != "" {
+						rules = append(rules, models.FwRule{
+							SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+							DstIP: net.IPNet{
+								IP:   peer.Address6.IP,
+								Mask: net.CIDRMask(128, 128),
+							},
+							AllowedProtocol: policy.Proto,
+							AllowedPorts:    policy.Port,
+							Allow:           true,
+						})
+					}
+
+					// add egress ranges
+					for _, dstI := range policy.Dst {
+						if dstI.Value == "*" {
 							rules = append(rules, models.FwRule{
-								SrcIP: userNodeI.StaticNode.AddressIPNet6(),
-								DstIP: net.IPNet{
-									IP:   peer.Address6.IP,
-									Mask: net.CIDRMask(128, 128),
-								},
+								SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
+								DstIP:           net.IPNet{},
 								AllowedProtocol: policy.Proto,
 								AllowedPorts:    policy.Port,
 								Allow:           true,
 							})
+							break
 						}
+						if dstI.ID == models.EgressID {
 
-						// add egress ranges
-						for _, dstI := range policy.Dst {
-							if dstI.ID == models.EgressID {
+							e := schema.Egress{ID: dstI.Value}
+							err := e.Get(db.WithContext(context.TODO()))
+							if err != nil {
+								continue
+							}
+							dstI.Value = e.Range
 
-								e := schema.Egress{ID: dstI.Value}
-								err := e.Get(db.WithContext(context.TODO()))
-								if err != nil {
-									continue
-								}
-								dstI.Value = e.Range
-
-								ip, cidr, err := net.ParseCIDR(dstI.Value)
-								if err == nil {
-									if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
-										rules = append(rules, models.FwRule{
-											SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
-											DstIP:           *cidr,
-											AllowedProtocol: policy.Proto,
-											AllowedPorts:    policy.Port,
-											Allow:           true,
-										})
-									} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
-										rules = append(rules, models.FwRule{
-											SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
-											DstIP:           *cidr,
-											AllowedProtocol: policy.Proto,
-											AllowedPorts:    policy.Port,
-											Allow:           true,
-										})
-									}
+							ip, cidr, err := net.ParseCIDR(dstI.Value)
+							if err == nil {
+								if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
+									rules = append(rules, models.FwRule{
+										SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
+										DstIP:           *cidr,
+										AllowedProtocol: policy.Proto,
+										AllowedPorts:    policy.Port,
+										Allow:           true,
+									})
+								} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
+									rules = append(rules, models.FwRule{
+										SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
+										DstIP:           *cidr,
+										AllowedProtocol: policy.Proto,
+										AllowedPorts:    policy.Port,
+										Allow:           true,
+									})
 								}
 							}
 						}
-
 					}
+
 				}
 
 			}
@@ -922,6 +951,8 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 	if len(egs) == 0 {
 		return rules
 	}
+	defaultPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(targetnode.Network), models.UserPolicy)
+
 	for _, egI := range egs {
 		if !egI.Status {
 			continue
@@ -931,74 +962,69 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 			targetNodeTags[models.TagID(egI.ID)] = struct{}{}
 		}
 	}
-	for _, acl := range acls {
-		if !acl.Enabled {
-			continue
-		}
-		dstTags := logic.ConvAclTagToValueMap(acl.Dst)
-		for _, dst := range acl.Dst {
-			if dst.ID == models.EgressID {
-				e := schema.Egress{ID: dst.Value}
-				err := e.Get(db.WithContext(context.TODO()))
-				if err == nil && e.Status {
-					for nodeID := range e.Nodes {
-						dstTags[nodeID] = struct{}{}
+	if !defaultPolicy.Enabled {
+		for _, acl := range acls {
+			if !acl.Enabled {
+				continue
+			}
+			dstTags := logic.ConvAclTagToValueMap(acl.Dst)
+			for _, dst := range acl.Dst {
+				if dst.ID == models.EgressID {
+					e := schema.Egress{ID: dst.Value}
+					err := e.Get(db.WithContext(context.TODO()))
+					if err == nil && e.Status {
+						for nodeID := range e.Nodes {
+							dstTags[nodeID] = struct{}{}
+						}
+						dstTags[e.Range] = struct{}{}
 					}
-					dstTags[e.Range] = struct{}{}
 				}
 			}
-		}
-		_, all := dstTags["*"]
-		addUsers := false
-		if !all {
-			for nodeTag := range targetNodeTags {
-				if _, ok := dstTags[nodeTag.String()]; ok {
-					addUsers = true
-					break
+			_, all := dstTags["*"]
+			addUsers := false
+			if !all {
+				for nodeTag := range targetNodeTags {
+					if _, ok := dstTags[nodeTag.String()]; ok {
+						addUsers = true
+						break
+					}
 				}
-			}
-		} else {
-			addUsers = true
-		}
-
-		if addUsers {
-			// get all src tags
-			for _, srcAcl := range acl.Src {
-				if srcAcl.ID == models.UserAclID {
-					allowedUsers[srcAcl.Value] = append(allowedUsers[srcAcl.Value], acl)
-				} else if srcAcl.ID == models.UserGroupAclID {
-					// fetch all users in the group
-					if usersMap, ok := userGrpMap[models.UserGroupID(srcAcl.Value)]; ok {
-						for userName := range usersMap {
-							allowedUsers[userName] = append(allowedUsers[userName], acl)
+			} else {
+				addUsers = true
+			}
+
+			if addUsers {
+				// get all src tags
+				for _, srcAcl := range acl.Src {
+					if srcAcl.ID == models.UserAclID {
+						allowedUsers[srcAcl.Value] = append(allowedUsers[srcAcl.Value], acl)
+					} else if srcAcl.ID == models.UserGroupAclID {
+						// fetch all users in the group
+						if usersMap, ok := userGrpMap[models.UserGroupID(srcAcl.Value)]; ok {
+							for userName := range usersMap {
+								allowedUsers[userName] = append(allowedUsers[userName], acl)
+							}
 						}
 					}
 				}
 			}
-		}
 
+		}
 	}
 
-	for _, userNode := range userNodes {
-		if !userNode.StaticNode.Enabled {
-			continue
-		}
-		acls, ok := allowedUsers[userNode.StaticNode.OwnerID]
-		if !ok {
-			continue
+	if defaultPolicy.Enabled {
+		r := models.AclRule{
+			ID:              defaultPolicy.ID,
+			AllowedProtocol: defaultPolicy.Proto,
+			AllowedPorts:    defaultPolicy.Port,
+			Direction:       defaultPolicy.AllowedDirection,
+			Allowed:         true,
 		}
-		for _, acl := range acls {
-
-			if !acl.Enabled {
+		for _, userNode := range userNodes {
+			if !userNode.StaticNode.Enabled {
 				continue
 			}
-			r := models.AclRule{
-				ID:              acl.ID,
-				AllowedProtocol: acl.Proto,
-				AllowedPorts:    acl.Port,
-				Direction:       acl.AllowedDirection,
-				Allowed:         true,
-			}
+
 			// Get peers in the tags and add allowed rules
 			if userNode.StaticNode.Address != "" {
 				r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
@@ -1006,36 +1032,70 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 			if userNode.StaticNode.Address6 != "" {
 				r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
 			}
-			for _, dstI := range acl.Dst {
-				if dstI.ID == models.EgressID {
-					e := schema.Egress{ID: dstI.Value}
-					err := e.Get(db.WithContext(context.TODO()))
-					if err != nil {
-						continue
-					}
+		}
+		rules[defaultPolicy.ID] = r
+	} else {
+		for _, userNode := range userNodes {
+			if !userNode.StaticNode.Enabled {
+				continue
+			}
+
+			acls, ok := allowedUsers[userNode.StaticNode.OwnerID]
+			if !ok {
+				continue
+			}
+			for _, acl := range acls {
+
+				if !acl.Enabled {
+					continue
+				}
+				r := models.AclRule{
+					ID:              acl.ID,
+					AllowedProtocol: acl.Proto,
+					AllowedPorts:    acl.Port,
+					Direction:       acl.AllowedDirection,
+					Allowed:         true,
+				}
+				// Get peers in the tags and add allowed rules
+				if userNode.StaticNode.Address != "" {
+					r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
+				}
+				if userNode.StaticNode.Address6 != "" {
+					r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
+				}
+				for _, dstI := range acl.Dst {
+					if dstI.ID == models.EgressID {
+						e := schema.Egress{ID: dstI.Value}
+						err := e.Get(db.WithContext(context.TODO()))
+						if err != nil {
+							continue
+						}
+
+						ip, cidr, err := net.ParseCIDR(e.Range)
+						if err == nil {
+							if ip.To4() != nil {
+								r.Dst = append(r.Dst, *cidr)
+							} else {
+								r.Dst6 = append(r.Dst6, *cidr)
+							}
 
-					ip, cidr, err := net.ParseCIDR(e.Range)
-					if err == nil {
-						if ip.To4() != nil {
-							r.Dst = append(r.Dst, *cidr)
-						} else {
-							r.Dst6 = append(r.Dst6, *cidr)
 						}
 
 					}
 
 				}
-
-			}
-			if aclRule, ok := rules[acl.ID]; ok {
-				aclRule.IPList = append(aclRule.IPList, r.IPList...)
-				aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
-				rules[acl.ID] = aclRule
-			} else {
-				rules[acl.ID] = r
+				if aclRule, ok := rules[acl.ID]; ok {
+					aclRule.IPList = append(aclRule.IPList, r.IPList...)
+					aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
+					rules[acl.ID] = aclRule
+				} else {
+					rules[acl.ID] = r
+				}
 			}
+
 		}
 	}
+
 	return rules
 }
 
@@ -1056,63 +1116,58 @@ func getUserAclRulesForNode(targetnode *models.Node,
 	if targetNodeTags == nil {
 		targetNodeTags = make(map[models.TagID]struct{})
 	}
+	defaultPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(targetnode.Network), models.UserPolicy)
 	targetNodeTags[models.TagID(targetnode.ID.String())] = struct{}{}
-	for _, acl := range acls {
-		if !acl.Enabled {
-			continue
-		}
-		dstTags := logic.ConvAclTagToValueMap(acl.Dst)
-		_, all := dstTags["*"]
-		addUsers := false
-		if !all {
-			for nodeTag := range targetNodeTags {
-				if _, ok := dstTags[nodeTag.String()]; ok {
-					addUsers = true
-					break
-				}
+	if !defaultPolicy.Enabled {
+		for _, acl := range acls {
+			if !acl.Enabled {
+				continue
 			}
-		} else {
-			addUsers = true
-		}
-
-		if addUsers {
-			// get all src tags
-			for _, srcAcl := range acl.Src {
-				if srcAcl.ID == models.UserAclID {
-					allowedUsers[srcAcl.Value] = append(allowedUsers[srcAcl.Value], acl)
-				} else if srcAcl.ID == models.UserGroupAclID {
-					// fetch all users in the group
-					if usersMap, ok := userGrpMap[models.UserGroupID(srcAcl.Value)]; ok {
-						for userName := range usersMap {
-							allowedUsers[userName] = append(allowedUsers[userName], acl)
+			dstTags := logic.ConvAclTagToValueMap(acl.Dst)
+			_, all := dstTags["*"]
+			addUsers := false
+			if !all {
+				for nodeTag := range targetNodeTags {
+					if _, ok := dstTags[nodeTag.String()]; ok {
+						addUsers = true
+						break
+					}
+				}
+			} else {
+				addUsers = true
+			}
+
+			if addUsers {
+				// get all src tags
+				for _, srcAcl := range acl.Src {
+					if srcAcl.ID == models.UserAclID {
+						allowedUsers[srcAcl.Value] = append(allowedUsers[srcAcl.Value], acl)
+					} else if srcAcl.ID == models.UserGroupAclID {
+						// fetch all users in the group
+						if usersMap, ok := userGrpMap[models.UserGroupID(srcAcl.Value)]; ok {
+							for userName := range usersMap {
+								allowedUsers[userName] = append(allowedUsers[userName], acl)
+							}
 						}
 					}
 				}
 			}
-		}
 
-	}
-
-	for _, userNode := range userNodes {
-		if !userNode.StaticNode.Enabled {
-			continue
 		}
-		acls, ok := allowedUsers[userNode.StaticNode.OwnerID]
-		if !ok {
-			continue
+	}
+	if defaultPolicy.Enabled {
+		r := models.AclRule{
+			ID:              defaultPolicy.ID,
+			AllowedProtocol: defaultPolicy.Proto,
+			AllowedPorts:    defaultPolicy.Port,
+			Direction:       defaultPolicy.AllowedDirection,
+			Allowed:         true,
 		}
-		for _, acl := range acls {
-
-			if !acl.Enabled {
+		for _, userNode := range userNodes {
+			if !userNode.StaticNode.Enabled {
 				continue
 			}
-			r := models.AclRule{
-				ID:              acl.ID,
-				AllowedProtocol: acl.Proto,
-				AllowedPorts:    acl.Port,
-				Direction:       acl.AllowedDirection,
-				Allowed:         true,
-			}
+
 			// Get peers in the tags and add allowed rules
 			if userNode.StaticNode.Address != "" {
 				r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
@@ -1120,16 +1175,47 @@ func getUserAclRulesForNode(targetnode *models.Node,
 			if userNode.StaticNode.Address6 != "" {
 				r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
 			}
-			if aclRule, ok := rules[acl.ID]; ok {
-				aclRule.IPList = append(aclRule.IPList, r.IPList...)
-				aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
-				aclRule.IPList = logic.UniqueIPNetList(aclRule.IPList)
-				aclRule.IP6List = logic.UniqueIPNetList(aclRule.IP6List)
-				rules[acl.ID] = aclRule
-			} else {
-				r.IPList = logic.UniqueIPNetList(r.IPList)
-				r.IP6List = logic.UniqueIPNetList(r.IP6List)
-				rules[acl.ID] = r
+		}
+		rules[defaultPolicy.ID] = r
+	} else {
+		for _, userNode := range userNodes {
+			if !userNode.StaticNode.Enabled {
+				continue
+			}
+			acls, ok := allowedUsers[userNode.StaticNode.OwnerID]
+			if !ok {
+				continue
+			}
+			for _, acl := range acls {
+
+				if !acl.Enabled {
+					continue
+				}
+				r := models.AclRule{
+					ID:              acl.ID,
+					AllowedProtocol: acl.Proto,
+					AllowedPorts:    acl.Port,
+					Direction:       acl.AllowedDirection,
+					Allowed:         true,
+				}
+				// Get peers in the tags and add allowed rules
+				if userNode.StaticNode.Address != "" {
+					r.IPList = append(r.IPList, userNode.StaticNode.AddressIPNet4())
+				}
+				if userNode.StaticNode.Address6 != "" {
+					r.IP6List = append(r.IP6List, userNode.StaticNode.AddressIPNet6())
+				}
+				if aclRule, ok := rules[acl.ID]; ok {
+					aclRule.IPList = append(aclRule.IPList, r.IPList...)
+					aclRule.IP6List = append(aclRule.IP6List, r.IP6List...)
+					aclRule.IPList = logic.UniqueIPNetList(aclRule.IPList)
+					aclRule.IP6List = logic.UniqueIPNetList(aclRule.IP6List)
+					rules[acl.ID] = aclRule
+				} else {
+					r.IPList = logic.UniqueIPNetList(r.IPList)
+					r.IP6List = logic.UniqueIPNetList(r.IP6List)
+					rules[acl.ID] = r
+				}
 			}
 		}
 	}
@@ -1228,9 +1314,9 @@ func CheckIfAnyPolicyisUniDirectional(targetNode models.Node, acls []models.Acl)
 func GetAclRulesForNode(targetnodeI *models.Node) (rules map[string]models.AclRule) {
 	targetnode := *targetnodeI
 	defer func() {
-		if !targetnode.IsIngressGateway {
-			rules = getUserAclRulesForNode(&targetnode, rules)
-		}
+		//if !targetnode.IsIngressGateway {
+		rules = getUserAclRulesForNode(&targetnode, rules)
+		//}
 	}()
 	rules = make(map[string]models.AclRule)
 	var taggedNodes map[models.TagID][]models.Node

+ 36 - 0
pro/logic/failover.go

@@ -51,8 +51,20 @@ func CheckFailOverCtx(failOverNode, victimNode, peerNode models.Node) error {
 	if victimNode.FailOverPeers == nil {
 		return nil
 	}
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Lock()
+	}
 	_, peerHasFailovered := peerNode.FailOverPeers[victimNode.ID.String()]
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Unlock()
+	}
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Lock()
+	}
 	_, victimHasFailovered := victimNode.FailOverPeers[peerNode.ID.String()]
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Unlock()
+	}
 	if peerHasFailovered && victimHasFailovered &&
 		victimNode.FailedOverBy == failOverNode.ID && peerNode.FailedOverBy == failOverNode.ID {
 		return errors.New("failover ctx is already set")
@@ -68,14 +80,38 @@ func SetFailOverCtx(failOverNode, victimNode, peerNode models.Node) error {
 	if victimNode.FailOverPeers == nil {
 		victimNode.FailOverPeers = make(map[string]struct{})
 	}
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Lock()
+	}
 	_, peerHasFailovered := peerNode.FailOverPeers[victimNode.ID.String()]
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Unlock()
+	}
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Lock()
+	}
 	_, victimHasFailovered := victimNode.FailOverPeers[peerNode.ID.String()]
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Unlock()
+	}
 	if peerHasFailovered && victimHasFailovered &&
 		victimNode.FailedOverBy == failOverNode.ID && peerNode.FailedOverBy == failOverNode.ID {
 		return errors.New("failover ctx is already set")
 	}
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Lock()
+	}
 	peerNode.FailOverPeers[victimNode.ID.String()] = struct{}{}
+	if peerNode.Mutex != nil {
+		peerNode.Mutex.Unlock()
+	}
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Lock()
+	}
 	victimNode.FailOverPeers[peerNode.ID.String()] = struct{}{}
+	if victimNode.Mutex != nil {
+		victimNode.Mutex.Unlock()
+	}
 	victimNode.FailedOverBy = failOverNode.ID
 	peerNode.FailedOverBy = failOverNode.ID
 	if err := logic.UpsertNode(&victimNode); err != nil {

+ 1 - 0
pro/util.go

@@ -5,6 +5,7 @@ package pro
 
 import (
 	"encoding/base64"
+
 	"github.com/gravitl/netmaker/models"
 
 	"github.com/gravitl/netmaker/logic"