...
1
16
17 package metrics
18
19 import (
20 "fmt"
21 "regexp"
22
23 "github.com/blang/semver/v4"
24 "github.com/spf13/pflag"
25
26 "k8s.io/component-base/version"
27 )
28
29
30 type Options struct {
31 ShowHiddenMetricsForVersion string
32 DisabledMetrics []string
33 AllowListMapping map[string]string
34 AllowListMappingManifest string
35 }
36
37
38 func NewOptions() *Options {
39 return &Options{}
40 }
41
42
43 func (o *Options) Validate() []error {
44 if o == nil {
45 return nil
46 }
47
48 var errs []error
49 err := validateShowHiddenMetricsVersion(parseVersion(version.Get()), o.ShowHiddenMetricsForVersion)
50 if err != nil {
51 errs = append(errs, err)
52 }
53
54 if err := validateAllowMetricLabel(o.AllowListMapping); err != nil {
55 errs = append(errs, err)
56 }
57
58 if len(errs) == 0 {
59 return nil
60 }
61 return errs
62 }
63
64
65 func (o *Options) AddFlags(fs *pflag.FlagSet) {
66 if o == nil {
67 return
68 }
69 fs.StringVar(&o.ShowHiddenMetricsForVersion, "show-hidden-metrics-for-version", o.ShowHiddenMetricsForVersion,
70 "The previous version for which you want to show hidden metrics. "+
71 "Only the previous minor version is meaningful, other values will not be allowed. "+
72 "The format is <major>.<minor>, e.g.: '1.16'. "+
73 "The purpose of this format is make sure you have the opportunity to notice if the next release hides additional metrics, "+
74 "rather than being surprised when they are permanently removed in the release after that.")
75 fs.StringSliceVar(&o.DisabledMetrics,
76 "disabled-metrics",
77 o.DisabledMetrics,
78 "This flag provides an escape hatch for misbehaving metrics. "+
79 "You must provide the fully qualified metric name in order to disable it. "+
80 "Disclaimer: disabling metrics is higher in precedence than showing hidden metrics.")
81 fs.StringToStringVar(&o.AllowListMapping, "allow-metric-labels", o.AllowListMapping,
82 "The map from metric-label to value allow-list of this label. The key's format is <MetricName>,<LabelName>. "+
83 "The value's format is <allowed_value>,<allowed_value>..."+
84 "e.g. metric1,label1='v1,v2,v3', metric1,label2='v1,v2,v3' metric2,label1='v1,v2,v3'.")
85 fs.StringVar(&o.AllowListMappingManifest, "allow-metric-labels-manifest", o.AllowListMappingManifest,
86 "The path to the manifest file that contains the allow-list mapping. "+
87 "The format of the file is the same as the flag --allow-metric-labels. "+
88 "Note that the flag --allow-metric-labels will override the manifest file.")
89 }
90
91
92 func (o *Options) Apply() {
93 if o == nil {
94 return
95 }
96 if len(o.ShowHiddenMetricsForVersion) > 0 {
97 SetShowHidden()
98 }
99
100 for _, metricName := range o.DisabledMetrics {
101 SetDisabledMetric(metricName)
102 }
103 if o.AllowListMapping != nil {
104 SetLabelAllowListFromCLI(o.AllowListMapping)
105 } else if len(o.AllowListMappingManifest) > 0 {
106 SetLabelAllowListFromManifest(o.AllowListMappingManifest)
107 }
108 }
109
110 func validateShowHiddenMetricsVersion(currentVersion semver.Version, targetVersionStr string) error {
111 if targetVersionStr == "" {
112 return nil
113 }
114
115 validVersionStr := fmt.Sprintf("%d.%d", currentVersion.Major, currentVersion.Minor-1)
116 if targetVersionStr != validVersionStr {
117 return fmt.Errorf("--show-hidden-metrics-for-version must be omitted or have the value '%v'. Only the previous minor version is allowed", validVersionStr)
118 }
119
120 return nil
121 }
122
123 func validateAllowMetricLabel(allowListMapping map[string]string) error {
124 if allowListMapping == nil {
125 return nil
126 }
127 metricNameRegex := `[a-zA-Z_:][a-zA-Z0-9_:]*`
128 labelRegex := `[a-zA-Z_][a-zA-Z0-9_]*`
129 for k := range allowListMapping {
130 reg := regexp.MustCompile(metricNameRegex + `,` + labelRegex)
131 if reg.FindString(k) != k {
132 return fmt.Errorf("--allow-metric-labels must have a list of kv pair with format `metricName:labelName=labelValue, labelValue,...`")
133 }
134 }
135 return nil
136 }
137
View as plain text