From 59e56e1b6099acfe1ee7000527dfef9f3eb944c3 Mon Sep 17 00:00:00 2001 From: Vishal Dalwadi Date: Fri, 4 Sep 2026 16:47:42 +0530 Subject: [PATCH] feat(go): add feature flags for mdm and edr integrations; --- models/structs.go | 2 ++ pro/controllers/integrations.go | 39 +++++++++++++++++++++++++++++++++ pro/integration/edr/sync.go | 7 ++++++ pro/integration/mdm/sync.go | 7 ++++++ 4 files changed, 55 insertions(+) diff --git a/models/structs.go b/models/structs.go index 67dd01c16..5df74dcf0 100644 --- a/models/structs.go +++ b/models/structs.go @@ -21,6 +21,8 @@ type FeatureFlags struct { EnableJIT bool `json:"enable_jit"` EnableOverlappingEgressRanges bool `json:"enable_overlapping_egress_ranges"` EnableSIEMIntegration bool `json:"enable_siem_integration"` + EnableMDMIntegration bool `json:"enable_mdm_integration"` + EnableEDRIntegration bool `json:"enable_edr_integration"` } // AuthParams - struct for auth params diff --git a/pro/controllers/integrations.go b/pro/controllers/integrations.go index accbdb283..0291556d5 100644 --- a/pro/controllers/integrations.go +++ b/pro/controllers/integrations.go @@ -55,6 +55,20 @@ func extractAndValidateIntegration(w http.ResponseWriter, r *http.Request) (inte return intType, id, true } +func integrationFeatureEnabled(ctx context.Context, intType integration.Type) bool { + flags := logic.GetFeatureFlags(ctx) + switch intType { + case integration.TypeSIEM: + return flags.EnableSIEMIntegration + case integration.TypeMDM: + return flags.EnableMDMIntegration + case integration.TypeEDR: + return flags.EnableEDRIntegration + default: + return true + } +} + // @Summary Get an integration // @Router /api/v1/integrations/{type} [get] // @Tags Integrations @@ -117,6 +131,11 @@ func upsertIntegration(w http.ResponseWriter, r *http.Request) { return } + if !integrationFeatureEnabled(r.Context(), intType) { + logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("%s integration is not enabled on your plan", intType), logic.BadReq)) + return + } + intg := &schema.Integration{Type: string(intType)} integrations, err := intg.ListByType(r.Context()) if err != nil { @@ -361,6 +380,11 @@ func listMDMProviders(w http.ResponseWriter, r *http.Request) { // @Success 202 {object} models.SuccessResponse // @Failure 400 {object} models.ErrorResponse func triggerMDMSync(w http.ResponseWriter, r *http.Request) { + if !logic.GetFeatureFlags(r.Context()).EnableMDMIntegration { + logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("mdm integration is not enabled on your plan"), logic.BadReq)) + return + } + active, err := mdmpkg.GetActive(r.Context()) if err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.Internal)) @@ -408,6 +432,11 @@ func triggerMDMSync(w http.ResponseWriter, r *http.Request) { // @Param provider query string false "Filter by provider name" // @Success 200 {array} schema.DeviceMDMState func listMDMDeviceState(w http.ResponseWriter, r *http.Request) { + if !logic.GetFeatureFlags(r.Context()).EnableMDMIntegration { + logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("mdm integration is not enabled on your plan"), logic.BadReq)) + return + } + ctx := r.Context() hostID := r.URL.Query().Get("host_id") provider := r.URL.Query().Get("provider") @@ -445,6 +474,11 @@ func listEDRProviders(w http.ResponseWriter, r *http.Request) { } func triggerEDRSync(w http.ResponseWriter, r *http.Request) { + if !logic.GetFeatureFlags(r.Context()).EnableEDRIntegration { + logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("edr integration is not enabled on your plan"), logic.BadReq)) + return + } + active, err := edrpkg.GetActive(r.Context()) if err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.Internal)) @@ -465,6 +499,11 @@ func triggerEDRSync(w http.ResponseWriter, r *http.Request) { } func listEDRDeviceState(w http.ResponseWriter, r *http.Request) { + if !logic.GetFeatureFlags(r.Context()).EnableEDRIntegration { + logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("edr integration is not enabled on your plan"), logic.BadReq)) + return + } + ctx := r.Context() hostID := r.URL.Query().Get("host_id") provider := r.URL.Query().Get("provider") diff --git a/pro/integration/edr/sync.go b/pro/integration/edr/sync.go index d25873185..abd304f24 100644 --- a/pro/integration/edr/sync.go +++ b/pro/integration/edr/sync.go @@ -10,6 +10,7 @@ import ( "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/schema" ) @@ -19,6 +20,9 @@ var ( ) func RunEDRSync(ctx context.Context) error { + if !logic.GetFeatureFlags(ctx).EnableEDRIntegration { + return nil + } intg, err := GetActive(ctx) if err != nil { return err @@ -37,6 +41,9 @@ func RunEDRSync(ctx context.Context) error { } func RunEDRSyncForce(ctx context.Context) error { + if !logic.GetFeatureFlags(ctx).EnableEDRIntegration { + return errors.New("edr integration is not enabled on your plan") + } intg, err := GetActive(ctx) if err != nil { return err diff --git a/pro/integration/mdm/sync.go b/pro/integration/mdm/sync.go index aef31e842..da5b2e445 100644 --- a/pro/integration/mdm/sync.go +++ b/pro/integration/mdm/sync.go @@ -10,6 +10,7 @@ import ( "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/logger" + "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/schema" ) @@ -24,6 +25,9 @@ var ( // Honours sync_interval_minutes from integration config as an optional per-tick // rate-limit hint. Returns nil (no-op) if MDM is not configured. func RunMDMSync(ctx context.Context) error { + if !logic.GetFeatureFlags(ctx).EnableMDMIntegration { + return nil + } intg, err := GetActive(ctx) if err != nil { return err @@ -43,6 +47,9 @@ func RunMDMSync(ctx context.Context) error { // RunMDMSyncForce ignores the rate-limit hint and triggers a fresh sync. func RunMDMSyncForce(ctx context.Context) error { + if !logic.GetFeatureFlags(ctx).EnableMDMIntegration { + return errors.New("mdm integration is not enabled on your plan") + } intg, err := GetActive(ctx) if err != nil { return err