mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 04:04:00 -06:00
139 lines
4.3 KiB
Go
139 lines
4.3 KiB
Go
package featuremgmt
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
)
|
|
|
|
type FeatureToggles interface {
|
|
// IsEnabled checks if a feature is enabled for a given context.
|
|
// The settings may be per user, tenant, or globally set in the cloud
|
|
IsEnabled(ctx context.Context, flag string) bool
|
|
|
|
// IsEnabledGlobally checks if a flag is configured globally. For now, this is the same
|
|
// as the function above, however it will move to only checking flags that
|
|
// are configured by the operator and shared across all tenants.
|
|
// Use of global feature flags should be limited and careful as they require
|
|
// a full server restart for a change to take place.
|
|
IsEnabledGlobally(flag string) bool
|
|
|
|
// Get the enabled flags -- this *may* also include disabled flags (with value false)
|
|
// but it is guaranteed to have the enabled ones listed
|
|
GetEnabled(ctx context.Context) map[string]bool
|
|
}
|
|
|
|
// FeatureFlagStage indicates the quality level
|
|
type FeatureFlagStage int
|
|
|
|
const (
|
|
// FeatureStageUnknown indicates that no state is specified
|
|
FeatureStageUnknown FeatureFlagStage = iota
|
|
|
|
// FeatureStageExperimental -- Does this work for Grafana Labs?
|
|
FeatureStageExperimental
|
|
|
|
// FeatureStagePrivatePreview -- Does this work for a limited number of customers?
|
|
FeatureStagePrivatePreview
|
|
|
|
// FeatureStagePublicPreview -- Does this work for most customers?
|
|
FeatureStagePublicPreview
|
|
|
|
// FeatureStageGeneralAvailability -- Feature is available to all applicable customers
|
|
FeatureStageGeneralAvailability
|
|
|
|
// FeatureStageDeprecated the feature will be removed in the future
|
|
FeatureStageDeprecated
|
|
)
|
|
|
|
func (s FeatureFlagStage) String() string {
|
|
switch s {
|
|
case FeatureStageExperimental:
|
|
return "experimental"
|
|
case FeatureStagePrivatePreview:
|
|
return "privatePreview"
|
|
case FeatureStagePublicPreview:
|
|
return "preview"
|
|
case FeatureStageGeneralAvailability:
|
|
return "GA"
|
|
case FeatureStageDeprecated:
|
|
return "deprecated"
|
|
case FeatureStageUnknown:
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
// MarshalJSON marshals the enum as a quoted json string
|
|
func (s FeatureFlagStage) MarshalJSON() ([]byte, error) {
|
|
buffer := bytes.NewBufferString(`"`)
|
|
buffer.WriteString(s.String())
|
|
buffer.WriteString(`"`)
|
|
return buffer.Bytes(), nil
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals a quoted json string to the enum value
|
|
func (s *FeatureFlagStage) UnmarshalJSON(b []byte) error {
|
|
var j string
|
|
err := json.Unmarshal(b, &j)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch j {
|
|
case "alpha":
|
|
fallthrough
|
|
case "experimental":
|
|
*s = FeatureStageExperimental
|
|
|
|
case "privatePreview":
|
|
*s = FeatureStagePrivatePreview
|
|
|
|
case "beta":
|
|
fallthrough
|
|
case "preview":
|
|
*s = FeatureStagePublicPreview
|
|
|
|
case "stable":
|
|
fallthrough
|
|
case "ga":
|
|
fallthrough
|
|
case "GA":
|
|
*s = FeatureStageGeneralAvailability
|
|
|
|
case "deprecated":
|
|
*s = FeatureStageDeprecated
|
|
|
|
default:
|
|
*s = FeatureStageUnknown
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// These are properties about the feature, but not the current state or value for it
|
|
type FeatureFlag struct {
|
|
Name string `json:"name" yaml:"name"` // Unique name
|
|
Description string `json:"description"`
|
|
Stage FeatureFlagStage `json:"stage,omitempty"`
|
|
Owner codeowner `json:"-"` // Owner person or team that owns this feature flag
|
|
|
|
// Recommended properties - control behavior of the feature toggle management page in the UI
|
|
AllowSelfServe bool `json:"allowSelfServe,omitempty"` // allow users with the right privileges to toggle this from the UI (GeneralAvailability, PublicPreview, and Deprecated toggles only)
|
|
HideFromAdminPage bool `json:"hideFromAdminPage,omitempty"` // GA, Deprecated, and PublicPreview toggles only: don't display this feature in the UI; if this is a GA toggle, add a comment with the reasoning
|
|
|
|
// CEL-GO expression. Using the value "true" will mean this is on by default
|
|
Expression string `json:"expression,omitempty"`
|
|
|
|
// Special behavior properties
|
|
RequiresDevMode bool `json:"requiresDevMode,omitempty"` // can not be enabled in production
|
|
FrontendOnly bool `json:"frontend,omitempty"` // change is only seen in the frontend
|
|
HideFromDocs bool `json:"hideFromDocs,omitempty"` // don't add the values to docs
|
|
|
|
// The server must be initialized with the value
|
|
RequiresRestart bool `json:"requiresRestart,omitempty"`
|
|
}
|
|
|
|
type FeatureToggleWebhookPayload struct {
|
|
FeatureToggles map[string]string `json:"feature_toggles"`
|
|
User string `json:"user"`
|
|
}
|