github.com/m3db/m3@v1.5.0/src/metrics/rules/validator/config.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package validator 22 23 import ( 24 "errors" 25 26 "github.com/m3db/m3/src/cluster/client" 27 "github.com/m3db/m3/src/metrics/aggregation" 28 "github.com/m3db/m3/src/metrics/filters" 29 "github.com/m3db/m3/src/metrics/metric" 30 "github.com/m3db/m3/src/metrics/policy" 31 "github.com/m3db/m3/src/metrics/rules" 32 "github.com/m3db/m3/src/metrics/rules/validator/namespace" 33 "github.com/m3db/m3/src/metrics/rules/validator/namespace/kv" 34 "github.com/m3db/m3/src/metrics/rules/validator/namespace/static" 35 ) 36 37 var ( 38 errNoNamespaceValidatorConfiguration = errors.New("no namespace validator configuration provided") 39 errMultipleNamespaceValidatorConfigurations = errors.New("multiple namespace validator configurations provided") 40 ) 41 42 // Configuration is the configuration for rules validation. 43 type Configuration struct { 44 Namespace namespaceValidatorConfiguration `yaml:"namespace"` 45 RequiredRollupTags []string `yaml:"requiredRollupTags"` 46 MaxTransformationDerivativeOrder *int `yaml:"maxTransformationDerivativeOrder"` 47 MaxRollupLevels *int `yaml:"maxRollupLevels"` 48 MetricTypes metricTypesValidationConfiguration `yaml:"metricTypes"` 49 Policies policiesValidationConfiguration `yaml:"policies"` 50 TagNameInvalidChars string `yaml:"tagNameInvalidChars"` 51 FilterInvalidTagNames []string `yaml:"filterInvalidTagNames"` 52 MetricNameInvalidChars string `yaml:"metricNameInvalidChars"` 53 } 54 55 // NewValidator creates a new rules validator based on the given configuration. 56 func (c Configuration) NewValidator( 57 kvClient client.Client, 58 ) (rules.Validator, error) { 59 nsValidator, err := c.Namespace.NewNamespaceValidator(kvClient) 60 if err != nil { 61 return nil, err 62 } 63 opts := c.newValidatorOptions(nsValidator) 64 return NewValidator(opts), nil 65 } 66 67 func (c Configuration) newValidatorOptions( 68 nsValidator namespace.Validator, 69 ) Options { 70 opts := NewOptions(). 71 SetNamespaceValidator(nsValidator). 72 SetRequiredRollupTags(c.RequiredRollupTags). 73 SetMetricTypesFn(c.MetricTypes.NewMetricTypesFn()). 74 SetTagNameInvalidChars(toRunes(c.TagNameInvalidChars)). 75 SetMetricNameInvalidChars(toRunes(c.MetricNameInvalidChars)). 76 SetFilterInvalidTagNames(c.FilterInvalidTagNames) 77 if c.MetricTypes.MultiAggregationTypesEnabledFor != nil { 78 opts = opts.SetMultiAggregationTypesEnabledFor(*c.MetricTypes.MultiAggregationTypesEnabledFor) 79 } 80 if c.Policies.DefaultAllowed.StoragePolicies != nil { 81 opts = opts.SetDefaultAllowedStoragePolicies(*c.Policies.DefaultAllowed.StoragePolicies) 82 } 83 if c.Policies.DefaultAllowed.FirstLevelAggregationTypes != nil { 84 opts = opts.SetDefaultAllowedFirstLevelAggregationTypes(*c.Policies.DefaultAllowed.FirstLevelAggregationTypes) 85 } 86 if c.Policies.DefaultAllowed.NonFirstLevelAggregationTypes != nil { 87 opts = opts.SetDefaultAllowedNonFirstLevelAggregationTypes(*c.Policies.DefaultAllowed.NonFirstLevelAggregationTypes) 88 } 89 for _, override := range c.Policies.Overrides { 90 if override.Allowed.StoragePolicies != nil { 91 opts = opts.SetAllowedStoragePoliciesFor(override.Type, *override.Allowed.StoragePolicies) 92 } 93 if override.Allowed.FirstLevelAggregationTypes != nil { 94 opts = opts.SetAllowedFirstLevelAggregationTypesFor(override.Type, *override.Allowed.FirstLevelAggregationTypes) 95 } 96 if override.Allowed.NonFirstLevelAggregationTypes != nil { 97 opts = opts.SetAllowedNonFirstLevelAggregationTypesFor(override.Type, *override.Allowed.NonFirstLevelAggregationTypes) 98 } 99 } 100 if c.MaxTransformationDerivativeOrder != nil { 101 opts = opts.SetMaxTransformationDerivativeOrder(*c.MaxTransformationDerivativeOrder) 102 } 103 if c.MaxRollupLevels != nil { 104 opts = opts.SetMaxRollupLevels(*c.MaxRollupLevels) 105 } 106 return opts 107 } 108 109 type namespaceValidatorConfiguration struct { 110 KV *kv.NamespaceValidatorConfiguration `yaml:"kv"` 111 Static *static.NamespaceValidatorConfiguration `yaml:"static"` 112 } 113 114 func (c namespaceValidatorConfiguration) NewNamespaceValidator( 115 kvClient client.Client, 116 ) (namespace.Validator, error) { 117 if c.KV == nil && c.Static == nil { 118 return nil, errNoNamespaceValidatorConfiguration 119 } 120 if c.KV != nil && c.Static != nil { 121 return nil, errMultipleNamespaceValidatorConfigurations 122 } 123 if c.KV != nil { 124 return c.KV.NewNamespaceValidator(kvClient) 125 } 126 return c.Static.NewNamespaceValidator(), nil 127 } 128 129 // metricTypesValidationConfiguration is th configuration for metric types validation. 130 type metricTypesValidationConfiguration struct { 131 // Metric type tag. 132 TypeTag string `yaml:"typeTag"` 133 134 // Allowed metric types. 135 Allowed []metric.Type `yaml:"allowed"` 136 137 // Metric types that support multiple aggregation types. 138 MultiAggregationTypesEnabledFor *[]metric.Type `yaml:"multiAggregationTypesEnabledFor"` 139 } 140 141 // NewMetricTypesFn creates a new metric types fn from the given configuration. 142 func (c metricTypesValidationConfiguration) NewMetricTypesFn() MetricTypesFn { 143 return func(tagFilters filters.TagFilterValueMap) ([]metric.Type, error) { 144 allowed := make([]metric.Type, 0, len(c.Allowed)) 145 filterValue, exists := tagFilters[c.TypeTag] 146 if !exists { 147 // If there is not type filter provided, the filter may match any allowed type. 148 allowed = append(allowed, c.Allowed...) 149 return allowed, nil 150 } 151 f, err := filters.NewFilterFromFilterValue(filterValue) 152 if err != nil { 153 return nil, err 154 } 155 for _, t := range c.Allowed { 156 if f.Matches([]byte(t.String())) { 157 allowed = append(allowed, t) 158 } 159 } 160 return allowed, nil 161 } 162 } 163 164 // policiesValidationConfiguration is the configuration for policies validation. 165 type policiesValidationConfiguration struct { 166 // DefaultAllowed defines the policies allowed by default. 167 DefaultAllowed policiesConfiguration `yaml:"defaultAllowed"` 168 169 // Overrides define the metric type specific policy overrides. 170 Overrides []policiesOverrideConfiguration `yaml:"overrides"` 171 } 172 173 // policiesOverrideConfiguration is the configuration for metric type specific policy overrides. 174 type policiesOverrideConfiguration struct { 175 Type metric.Type `yaml:"type"` 176 Allowed policiesConfiguration `yaml:"allowed"` 177 } 178 179 // policiesConfiguration is the configuration for storage policies and aggregation types. 180 type policiesConfiguration struct { 181 StoragePolicies *[]policy.StoragePolicy `yaml:"storagePolicies"` 182 FirstLevelAggregationTypes *aggregation.Types `yaml:"firstLevelAggregationTypes"` 183 NonFirstLevelAggregationTypes *aggregation.Types `yaml:"nonFirstLevelAggregationTypes"` 184 } 185 186 func toRunes(s string) []rune { 187 r := make([]rune, 0, len(s)) 188 for _, c := range s { 189 r = append(r, c) 190 } 191 return r 192 }