github.com/google/cloudprober@v0.11.3/validators/validators.go (about) 1 // Copyright 2018-2019 The Cloudprober Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package validators provides an entrypoint for the cloudprober's validators 16 // framework. 17 package validators 18 19 import ( 20 "fmt" 21 22 "github.com/google/cloudprober/logger" 23 "github.com/google/cloudprober/metrics" 24 "github.com/google/cloudprober/validators/http" 25 "github.com/google/cloudprober/validators/integrity" 26 configpb "github.com/google/cloudprober/validators/proto" 27 "github.com/google/cloudprober/validators/regex" 28 ) 29 30 // Validator implements a validator. 31 // 32 // A validator runs a test on the provided input, usually the probe response, 33 // and returns the test result. If test cannot be run successfully for some 34 // reason (e.g. for malformed input), an error is returned. 35 type Validator struct { 36 Name string 37 Validate func(input *Input) (bool, error) 38 } 39 40 // Init initializes the validators defined in the config. 41 func Init(validatorConfs []*configpb.Validator, l *logger.Logger) ([]*Validator, error) { 42 var validators []*Validator 43 names := make(map[string]bool) 44 45 for _, vc := range validatorConfs { 46 if names[vc.GetName()] { 47 return nil, fmt.Errorf("validator %s is defined twice", vc.GetName()) 48 } 49 50 v, err := initValidator(vc, l) 51 if err != nil { 52 return nil, err 53 } 54 55 validators = append(validators, v) 56 names[vc.GetName()] = true 57 } 58 59 return validators, nil 60 } 61 62 func initValidator(validatorConf *configpb.Validator, l *logger.Logger) (validator *Validator, err error) { 63 validator = &Validator{Name: validatorConf.GetName()} 64 65 switch validatorConf.Type.(type) { 66 case *configpb.Validator_HttpValidator: 67 v := &http.Validator{} 68 if err := v.Init(validatorConf.GetHttpValidator(), l); err != nil { 69 return nil, err 70 } 71 validator.Validate = func(input *Input) (bool, error) { 72 return v.Validate(input.Response, input.ResponseBody) 73 } 74 return 75 76 case *configpb.Validator_IntegrityValidator: 77 v := &integrity.Validator{} 78 if err := v.Init(validatorConf.GetIntegrityValidator(), l); err != nil { 79 return nil, err 80 } 81 validator.Validate = func(input *Input) (bool, error) { 82 return v.Validate(input.ResponseBody) 83 } 84 return 85 86 case *configpb.Validator_Regex: 87 v := ®ex.Validator{} 88 if err := v.Init(validatorConf.GetRegex(), l); err != nil { 89 return nil, err 90 } 91 validator.Validate = func(input *Input) (bool, error) { 92 return v.Validate(input.ResponseBody) 93 } 94 return 95 default: 96 err = fmt.Errorf("unknown validator type: %v", validatorConf.Type) 97 return 98 } 99 } 100 101 // Input encapsulates the input for validators. 102 type Input struct { 103 Response interface{} 104 ResponseBody []byte 105 } 106 107 // RunValidators runs the list of validators on the given response and 108 // responseBody, updates the given validationFailure map and returns the list 109 // of failures. 110 func RunValidators(vs []*Validator, input *Input, validationFailure *metrics.Map, l *logger.Logger) []string { 111 var failures []string 112 113 for _, v := range vs { 114 success, err := v.Validate(input) 115 if err != nil { 116 l.Error("Error while running the validator ", v.Name, ": ", err.Error()) 117 continue 118 } 119 if !success { 120 validationFailure.IncKey(v.Name) 121 failures = append(failures, v.Name) 122 } 123 } 124 125 return failures 126 } 127 128 // ValidationFailureMap returns an initialized validation failures map. 129 func ValidationFailureMap(vs []*Validator) *metrics.Map { 130 m := metrics.NewMap("validator", metrics.NewInt(0)) 131 // Initialize validation failure map with validator keys, so that we always 132 // export the metrics. 133 for _, v := range vs { 134 m.IncKeyBy(v.Name, metrics.NewInt(0)) 135 } 136 return m 137 }