* feat(go): add user schema;
* feat(go): migrate to user schema;
* feat(go): add audit fields;
* feat(go): remove unused fields from the network model;
* feat(go): add network schema;
* feat(go): migrate to network schema;
* refactor(go): add comment to clarify migration logic;
* fix(go): test failures;
* fix(go): test failures;
* feat(go): change membership table to store memberships at all scopes;
* feat(go): add schema for access grants;
* feat(go): remove nameservers from new networks table; ensure db passed for schema functions;
* feat(go): set max conns for sqlite to 1;
* fix(go): issues updating user account status;
* NM-236: streamline operations in HA mode
* NM-236: only master pod should subscribe to updates from clients
* refactor(go): remove converters and access grants;
* refactor(go): add json tags in schema models;
* refactor(go): rename file to migrate_v1_6_0.go;
* refactor(go): add user groups and user roles tables; use schema tables;
* refactor(go): inline get and list from schema package;
* refactor(go): inline get network and list users from schema package;
* fix(go): staticcheck issues;
* fix(go): remove test not in use; fix test case;
* fix(go): validate network;
* fix(go): resolve static checks;
* fix(go): new models errors;
* fix(go): test errors;
* fix(go): handle no records;
* fix(go): add validations for user object;
* fix(go): set correct extclient status;
* fix(go): test error;
* feat(go): make schema the base package;
* feat(go): add host schema;
* feat(go): use schema host everywhere;
* feat(go): inline get host, list hosts and delete host;
* feat(go): use non-ptr value;
* feat(go): use save to upsert all fields;
* feat(go): use save to upsert all fields;
* feat(go): save turn endpoint as string;
* feat(go): check for gorm error record not found;
* fix(go): test failures;
* fix(go): update all network fields;
* fix(go): update all network fields;
* feat(go): add paginated list networks api;
* feat(go): add paginated list users api;
* feat(go): add paginated list hosts api;
* feat(go): add pagination to list groups api;
* fix(go): comment;
* fix(go): implement marshal and unmarshal text for custom types;
* fix(go): implement marshal and unmarshal json for custom types;
* fix(go): just use the old model for unmarshalling;
* fix(go): implement marshal and unmarshal json for custom types;
* NM-271:Import swap: compress/gzip replaced with github.com/klauspost/compress/gzip (2-4x faster, wire-compatible output). Added sync import.
Two sync.Pool variables (gzipWriterPool, bufferPool): reuse gzip.Writer and bytes.Buffer across calls instead of allocating fresh ones per publish.
compressPayload rewritten: pulls writer + buffer from pools, resets them, compresses at gzip.BestSpeed (level 1), copies the result out of the pooled buffer, and returns both objects to the pools.
* feat(go): remove paginated list networks api;
* feat(go): use custom paginated response object;
* NM-271: Improve server scalability under high host count
- Replace stdlib compress/gzip with klauspost/compress at BestSpeed and
pool gzip writers and buffers via sync.Pool to eliminate compression
as the dominant CPU hotspot.
- Debounce peer update broadcasts with a 500ms resettable window capped
at 3s max-wait, coalescing rapid-fire PublishPeerUpdate calls into a
single broadcast cycle.
- Cache HostPeerInfo (batch-refreshed by debounce worker) and
HostPeerUpdate (stored as side-effect of each publish) so the pull API
and peer_info API serve from pre-computed maps instead of triggering
expensive per-host computations under thundering herd conditions.
- Warm both caches synchronously at startup before the first publish
cycle so early pull requests are served instantly.
- Bound concurrent MQTT publishes to 5 via semaphore to prevent
broker TCP buffer overflows that caused broken pipe disconnects.
- Remove manual Disconnect+SetupMQTT from ConnectionLostHandler and
rely on the paho client's built-in AutoReconnect; add a 5s retry
wait in publish() to ride out brief reconnection windows.
* NM-271: Reduce server CPU contention under high concurrent load
- Cache ServerSettings with atomic.Value to eliminate repeated DB reads
on every pull request (was 32+ goroutines blocked on read lock)
- Batch UpdateNodeCheckin writes in memory, flush every 30s to reduce
per-checkin write lock contention (was 88+ goroutines blocked)
- Enable SQLite WAL mode + busy_timeout and remove global dbMutex;
let SQLite handle concurrency natively (reads no longer block writes)
- Move ResetFailedOverPeer/ResetAutoRelayedPeer to async in pull()
handler since results don't affect the cached response
- Skip no-op UpsertNode writes in failover/relay reset functions
(early return when node has no failover/relay state)
- Remove CheckHostPorts from hostUpdateFallback hot path
- Switch to pure-Go SQLite driver (glebarez/sqlite), set CGO_ENABLED=0
* fix(go): ensure default values for page and per_page are used when not passed;
* fix(go): rename v1.6.0 to v1.5.1;
* fix(go): check for gorm.ErrRecordNotFound instead of database.IsEmptyRecord;
* fix(go): use host id, not pending host id;
* NM-271: Revert pure-Go SQLite and FIPS disable to verify impact
Revert to CGO-based mattn/go-sqlite3 driver and re-enable FIPS to
isolate whether these changes are still needed now that the global
dbMutex has been removed and WAL mode is enabled. Keep WAL mode
pragma with mattn-compatible DSN format.
* feat(go): add filters to paginated apis;
* feat(go): add filters to paginated apis;
* feat(go): remove check for max username length;
* feat(go): add filters to count as well;
* feat(go): use library to check email address validity;
* feat(go): ignore pagination if params not passed;
* fix(go): pagination issues;
* fix(go): check exists before using;
* fix(go): remove debug log;
* NM-271: rm debug logs
* NM-271: check if caching is enabled
* NM-271: add server sync mq topic for HA mode
* NM-271: fix build
* NM-271: push metrics in batch to exproter over api
* NM-271: use basic auth for exporter metrics api
* fix(go): use gorm err record not found;
* NM-271: Add monitoring stack on demand
* NM-271: -m arg for install script should only add monitoring stack
* fix(go): use gorm err record not found;
* NM-271: update docker compose file for prometheus
* NM-271: update docker compose file for prometheus
* fix(go): use user principal name when creating pending user;
* fix(go): use schema package for consts;
* NM-236: rm duplicate network hook
* NM-271: add server topic to reset idp hooks on master node
* fix(go): prevent disabling superadmin user;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): swap is admin and is superadmin;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): remove dead code block;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2928837937
* fix(go): incorrect message when trying to disable self;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2928837934
* NM-271: fix stale peers on reset_failovered pull and add HTTP timeout to metrics exporter
Run the failover/relay reset synchronously in the pull handler so the
response reflects post-reset topology instead of serving stale cached
peers. Add a 30s timeout to the metrics exporter HTTP client to prevent
PushAllMetricsToExporter from blocking the Keepalive loop.
* NM-271: fix gzip pool corruption, MQTT topic mismatch, stale settings cache, and reduce redundant DB fetches
- Only return gzip.Writer to pool after successful Close to prevent
silently malformed MQTT payloads from a previously errored writer.
- Fix serversync subscription to exact topic match since syncType is
now in the message payload, not the topic path.
- Prevent zero-value ServerSettings from being cached indefinitely
when the DB record is missing or unmarshal fails on startup.
- Return fetched hosts/nodes from RefreshHostPeerInfoCache so
warmPeerCaches reuses them instead of querying the DB twice.
- Compute fresh HostPeerUpdate on reset_failovered pull instead of
serving stale cache, and store result back for subsequent requests.
* NM-271: fix gzip writer pool leak, log checkin flush errors, and fix master pod ordinal parsing
- Reset gzip.Writer to io.Discard before returning to pool so errored
writers are never leaked or silently reused with corrupt state.
- Track and log failed DB inserts in FlushNodeCheckins so operators
have visibility when check-in timestamps are lost.
- Parse StatefulSet pod ordinal as integer instead of using HasSuffix
to prevent netmaker-10 from being misidentified as master pod.
* NM-271: simplify masterpod logic
* fix(go): use correct header;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): return after error response;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): use correct order of params;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2929593036
* fix(go): set default values for page and page size; use v2 instead of /list;
* NM-271: use host name
* Update mq/serversync.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* NM-271: fix duplicate serversynce case
* NM-271: streamline gw updates
* Update logic/auth.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* Update schema/user_roles.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): syntax error;
* fix(go): set default values when page and per_page are not passed or 0;
* fix(go): use uuid.parse instead of uuid.must parse;
* fix(go): review errors;
* fix(go): review errors;
* Update controllers/user.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* Update controllers/user.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* NM-163: fix errors:
* Update db/types/options.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): persist return user in event;
* Update db/types/options.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* NM-271: signal pull on ip changes
* NM-163: duplicate lines of code
* NM-163: fix(go): fix missing return and filter parsing in user controller
- Add missing return after error response in updateUserAccountStatus
to prevent double-response and spurious ext-client side-effects
- Use switch statements in listUsers to skip unrecognized
account_status and mfa_status filter values
* NM-271: signal pull req on node ip change
* fix(go): check for both min and max page size;
* NM-271: refresh node object before update
* fix(go): enclose transfer superadmin in transaction;
* fix(go): review errors;
* fix(go): remove free tier checks;
* fix(go): review fixes;
* NM-271: streamline ip pool ops
* NM-271: fix tests, set max idle conns
* NM-271: fix(go): fix data races in settings cache and peer update worker
- Use pointer type in atomic.Value for serverSettingsCache to avoid
replacing the variable non-atomically in InvalidateServerSettingsCache
- Swap peerUpdateReplace flag before draining the channel to prevent
a concurrent replacePeers=true from being consumed by the wrong cycle
---------
Co-authored-by: VishalDalwadi <dalwadivishal26@gmail.com>
Co-authored-by: Vishal Dalwadi <51291657+VishalDalwadi@users.noreply.github.com>
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* feat(go): add user schema;
* feat(go): migrate to user schema;
* feat(go): add audit fields;
* feat(go): remove unused fields from the network model;
* feat(go): add network schema;
* feat(go): migrate to network schema;
* refactor(go): add comment to clarify migration logic;
* fix(go): test failures;
* fix(go): test failures;
* feat(go): change membership table to store memberships at all scopes;
* feat(go): add schema for access grants;
* feat(go): remove nameservers from new networks table; ensure db passed for schema functions;
* feat(go): set max conns for sqlite to 1;
* fix(go): issues updating user account status;
* refactor(go): remove converters and access grants;
* refactor(go): add json tags in schema models;
* refactor(go): rename file to migrate_v1_6_0.go;
* refactor(go): add user groups and user roles tables; use schema tables;
* refactor(go): inline get and list from schema package;
* refactor(go): inline get network and list users from schema package;
* fix(go): staticcheck issues;
* fix(go): remove test not in use; fix test case;
* fix(go): validate network;
* fix(go): resolve static checks;
* fix(go): new models errors;
* fix(go): test errors;
* fix(go): handle no records;
* fix(go): add validations for user object;
* fix(go): set correct extclient status;
* fix(go): test error;
* feat(go): make schema the base package;
* feat(go): add host schema;
* feat(go): use schema host everywhere;
* feat(go): inline get host, list hosts and delete host;
* feat(go): use non-ptr value;
* feat(go): use save to upsert all fields;
* feat(go): use save to upsert all fields;
* feat(go): save turn endpoint as string;
* feat(go): check for gorm error record not found;
* fix(go): test failures;
* fix(go): update all network fields;
* fix(go): update all network fields;
* feat(go): add paginated list networks api;
* feat(go): add paginated list users api;
* feat(go): add paginated list hosts api;
* feat(go): add pagination to list groups api;
* fix(go): comment;
* fix(go): implement marshal and unmarshal text for custom types;
* fix(go): implement marshal and unmarshal json for custom types;
* fix(go): just use the old model for unmarshalling;
* fix(go): implement marshal and unmarshal json for custom types;
* feat(go): remove paginated list networks api;
* feat(go): use custom paginated response object;
* fix(go): ensure default values for page and per_page are used when not passed;
* fix(go): rename v1.6.0 to v1.5.1;
* fix(go): check for gorm.ErrRecordNotFound instead of database.IsEmptyRecord;
* fix(go): use host id, not pending host id;
* feat(go): add filters to paginated apis;
* feat(go): add filters to paginated apis;
* feat(go): remove check for max username length;
* feat(go): add filters to count as well;
* feat(go): use library to check email address validity;
* feat(go): ignore pagination if params not passed;
* fix(go): pagination issues;
* fix(go): check exists before using;
* fix(go): remove debug log;
* fix(go): use gorm err record not found;
* fix(go): use gorm err record not found;
* fix(go): use user principal name when creating pending user;
* fix(go): use schema package for consts;
* fix(go): prevent disabling superadmin user;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): swap is admin and is superadmin;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): remove dead code block;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2928837937
* fix(go): incorrect message when trying to disable self;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2928837934
* fix(go): use correct header;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): return after error response;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): use correct order of params;
https://github.com/gravitl/netmaker/pull/3910#discussion_r2929593036
* fix(go): set default values for page and page size; use v2 instead of /list;
* Update logic/auth.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* Update schema/user_roles.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): syntax error;
* fix(go): set default values when page and per_page are not passed or 0;
* fix(go): use uuid.parse instead of uuid.must parse;
* fix(go): review errors;
* fix(go): review errors;
* Update controllers/user.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* Update controllers/user.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* NM-163: fix errors:
* Update db/types/options.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* fix(go): persist return user in event;
* Update db/types/options.go
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* NM-163: duplicate lines of code
* NM-163: fix(go): fix missing return and filter parsing in user controller
- Add missing return after error response in updateUserAccountStatus
to prevent double-response and spurious ext-client side-effects
- Use switch statements in listUsers to skip unrecognized
account_status and mfa_status filter values
* fix(go): check for both min and max page size;
* fix(go): enclose transfer superadmin in transaction;
* fix(go): review errors;
* fix(go): remove free tier checks;
* fix(go): review fixes;
---------
Co-authored-by: VishalDalwadi <dalwadivishal26@gmail.com>
Co-authored-by: Vishal Dalwadi <51291657+VishalDalwadi@users.noreply.github.com>
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* add host node update action
* add peer signal action to fallback api
* add replace peers to host pull
* add delete host action to fallback api
* update base go builder image
* update go builder tag
* check host port to avoid conflicts behind NAT
* fix connect/disconnect on api
* send pull signal on disconnect from UI
* fix panic on host join via user auth
* reset failover on disconnect
* feat(go): allow different session durations for client apps;
* feat(go): assume call is from netdesk app if header absent;
* feat(go): allow header;
* feat(go): set client jwt validity duration on migration.
* feat(git): ignore run configurations;
* feat(go): add support for TOTP authentication;
* fix(go): api docs;
* fix(go): static checks failing;
* fix(go): ignore mfa enforcement for user auth;
* feat(go): allow resetting mfa;
* feat(go): allow resetting mfa;
* feat(go): use library function;
* fix(go): signature;
* feat(go): allow only master user to unset user's mfa;
* feat(go): set caller when master to prevent panic;
* feat(go): make messages more user friendly;
* fix(go): run go mod tidy;
* fix(go): optimize imports;
* fix(go): return unauthorized on token expiry;
* fix(go): move mfa endpoints under username;
* fix(go): set is mfa enabled when converting;
* feat(go): allow authenticated users to use preauth apis;
* feat(go): set correct header value;
* feat(go): allow super-admins and admins to unset mfa;
* feat(go): allow user to unset mfa if not enforced;
* feat: api access tokens
* revoke all user tokens
* redefine access token api routes, add auto egress option to enrollment keys
* add server settings apis, add db table for settigs
* handle server settings updates
* switch to using settings from DB
* fix sever settings migration
* revet force migration for settings
* fix server settings database write
* fix revoked tokens to be unauthorized
* remove unused functions
* convert access token to sql schema
* switch access token to sql schema
* fix merge conflicts
* fix server settings types
* bypass basic auth setting for super admin
* add TODO comment
* feat(go): add types for idp package;
* feat(go): import azure sdk;
* feat(go): add stub for google workspace client;
* feat(go): implement azure ad client;
* feat(go): sync users and groups using idp client;
* publish peer update on settings update
* feat(go): read creds from env vars;
* feat(go): add api endpoint to trigger idp sync;
* fix(go): sync member changes;
* fix(go): handle error;
* fix(go): set correct response type;
* feat(go): support disabling user accounts;
1. Add api endpoints to enable and disable user accounts.
2. Add checks in authenticators to prevent disabled users from logging in.
3. Add checks in middleware to prevent api usage by disabled users.
* feat(go): use string slice for group members;
* feat(go): sync user account status from idp;
* feat(go): import google admin sdk;
* feat(go): add support for google workspace idp;
* feat(go): initialize idp client on sync;
* feat(go): sync from idp periodically;
* feat(go): improvements for google idp;
1. Use the impersonate package to authenticate.
2. Use Pages method to get all data.
* chore(go): import style changes from migration branch;
1. Singular file names for table schema.
2. No table name method.
3. Use .Model instead of .Table.
4. No unnecessary tagging.
* remove nat check on egress gateway request
* Revert "remove nat check on egress gateway request"
This reverts commit 0aff12a189.
* feat(go): add db middleware;
* feat(go): restore method;
* feat(go): add user access token schema;
* fix user auth api:
* re initalise oauth and email config
* feat(go): fetch idp creds from server settings;
* feat(go): add filters for users and groups;
* feat(go): skip sync from idp if disabled;
* feat(go): add endpoint to remove idp integration;
* feat(go): import all users if no filters;
* feat(go): assign service-user role on sync;
* feat(go): remove microsoft-go-sdk;
* feat(go): add display name field for user;
* fix(go): set account disabled correctly;
* fix(go): update user if display name changes;
* fix(go): remove auth provider when removing idp integration;
* fix(go): ignore display name if empty;
* feat(go): add idp sync interval setting;
* fix(go): error on invalid auth provider;
* fix(go): no error if no user on group delete;
* fix(go): check superadmin using platform role id;
* feat(go): add display name and account disabled to return user as well;
* feat(go): tidy go mod after merge;
* feat(go): reinitialize auth provider and idp sync hook;
* fix(go): merge error;
* fix(go): merge error;
* feat(go): use id as the external provider id;
* fix(go): comments;
* feat(go): add function to return pending users;
* feat(go): prevent external id erasure;
* fix(go): user and group sync errors;
* chore(go): cleanup;
* fix(go): delete only oauth users;
* feat(go): use uuid group id;
* export ipd id to in rest api
* feat(go): don't use uuid for default groups;
* feat(go): migrate group only if id not uuid;
* chore(go): go mod tidy;
---------
Co-authored-by: abhishek9686 <abhi281342@gmail.com>
Co-authored-by: Abhishek K <abhishek@netmaker.io>
Co-authored-by: the_aceix <aceixsmartx@gmail.com>
* feat: api access tokens
* revoke all user tokens
* redefine access token api routes, add auto egress option to enrollment keys
* add server settings apis, add db table for settigs
* handle server settings updates
* switch to using settings from DB
* fix sever settings migration
* revet force migration for settings
* fix server settings database write
* fix revoked tokens to be unauthorized
* remove unused functions
* convert access token to sql schema
* switch access token to sql schema
* fix merge conflicts
* fix server settings types
* bypass basic auth setting for super admin
* add TODO comment
* publish peer update on settings update
* chore(go): import style changes from migration branch;
1. Singular file names for table schema.
2. No table name method.
3. Use .Model instead of .Table.
4. No unnecessary tagging.
* remove nat check on egress gateway request
* Revert "remove nat check on egress gateway request"
This reverts commit 0aff12a189.
* feat(go): add db middleware;
* feat(go): restore method;
* feat(go): add user access token schema;
* fix user auth api:
* re initalise oauth and email config
* set verbosity
* sync auto update settings with hosts
* sync auto update settings with hosts
* mask secret and convert jwt duration to minutes
* convert jwt duration to minutes
* notify peers after settings update
* compare with curr settings before updating
* send host update to devices on auto update
---------
Co-authored-by: Vishal Dalwadi <dalwadivishal26@gmail.com>