|
@@ -0,0 +1,126 @@
|
|
|
|
+package main
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "fmt"
|
|
|
|
+
|
|
|
|
+ "github.com/fatih/color"
|
|
|
|
+ "github.com/spf13/cobra"
|
|
|
|
+
|
|
|
|
+ "github.com/crowdsecurity/crowdsec/pkg/fflag"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+func runConfigFeatureFlags(cmd *cobra.Command, args []string) error {
|
|
|
|
+ flags := cmd.Flags()
|
|
|
|
+
|
|
|
|
+ showRetired, err := flags.GetBool("retired")
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ green := color.New(color.FgGreen).SprintFunc()
|
|
|
|
+ red := color.New(color.FgRed).SprintFunc()
|
|
|
|
+ yellow := color.New(color.FgYellow).SprintFunc()
|
|
|
|
+ magenta := color.New(color.FgMagenta).SprintFunc()
|
|
|
|
+
|
|
|
|
+ printFeature := func(feat fflag.Feature) {
|
|
|
|
+ nameDesc := feat.Name
|
|
|
|
+ if feat.Description != "" {
|
|
|
|
+ nameDesc += ": " + feat.Description
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ status := red("✗")
|
|
|
|
+ if feat.IsEnabled() {
|
|
|
|
+ status = green("✓")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Printf("%s %s", status, nameDesc)
|
|
|
|
+
|
|
|
|
+ if feat.State == fflag.DeprecatedState {
|
|
|
|
+ fmt.Printf("\n %s %s", yellow("DEPRECATED"), feat.DeprecationMsg)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if feat.State == fflag.RetiredState {
|
|
|
|
+ fmt.Printf("\n %s %s", magenta("RETIRED"), feat.DeprecationMsg)
|
|
|
|
+ }
|
|
|
|
+ fmt.Println()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ feats := fflag.Crowdsec.GetAllFeatures()
|
|
|
|
+
|
|
|
|
+ enabled := []fflag.Feature{}
|
|
|
|
+ disabled := []fflag.Feature{}
|
|
|
|
+ retired := []fflag.Feature{}
|
|
|
|
+
|
|
|
|
+ for _, feat := range feats {
|
|
|
|
+ if feat.State == fflag.RetiredState {
|
|
|
|
+ retired = append(retired, feat)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ if feat.IsEnabled() {
|
|
|
|
+ enabled = append(enabled, feat)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ disabled = append(disabled, feat)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(enabled) > 0 {
|
|
|
|
+ fmt.Println(" --- Enabled features ---")
|
|
|
|
+ fmt.Println()
|
|
|
|
+
|
|
|
|
+ for _, feat := range enabled {
|
|
|
|
+ printFeature(feat)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Println()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(disabled) > 0 {
|
|
|
|
+ fmt.Println(" --- Disabled features ---")
|
|
|
|
+ fmt.Println()
|
|
|
|
+
|
|
|
|
+ for _, feat := range disabled {
|
|
|
|
+ printFeature(feat)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Println()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Println("To enable a feature you can: ")
|
|
|
|
+ fmt.Println(" - set the environment variable CROWDSEC_FEATURE_<uppercase_feature_name> to true")
|
|
|
|
+ fmt.Printf(" - add the line '- <feature_name>' to the file %s/feature.yaml\n", csConfig.ConfigPaths.ConfigDir)
|
|
|
|
+ fmt.Println()
|
|
|
|
+
|
|
|
|
+ if len(enabled) == 0 && len(disabled) == 0 {
|
|
|
|
+ fmt.Println("However, no feature flag is available in this release.")
|
|
|
|
+ fmt.Println()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if showRetired && len(retired) > 0 {
|
|
|
|
+ fmt.Println(" --- Retired features ---")
|
|
|
|
+ fmt.Println()
|
|
|
|
+
|
|
|
|
+ for _, feat := range retired {
|
|
|
|
+ printFeature(feat)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Println()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func NewConfigFeatureFlagsCmd() *cobra.Command {
|
|
|
|
+ cmdConfigFeatureFlags := &cobra.Command{
|
|
|
|
+ Use: "feature-flags",
|
|
|
|
+ Short: "Displays feature flag status",
|
|
|
|
+ Long: `Displays the supported feature flags and their current status.`,
|
|
|
|
+ Args: cobra.ExactArgs(0),
|
|
|
|
+ DisableAutoGenTag: true,
|
|
|
|
+ RunE: runConfigFeatureFlags,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ flags := cmdConfigFeatureFlags.Flags()
|
|
|
|
+ flags.Bool("retired", false, "Show retired features")
|
|
|
|
+
|
|
|
|
+ return cmdConfigFeatureFlags
|
|
|
|
+}
|