This repository has been archived by the owner on Apr 7, 2020. It is now read-only.
forked from istio/istio
/
validator.go
99 lines (88 loc) · 2.77 KB
/
validator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2017 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package store
import (
"errors"
"github.com/gogo/protobuf/proto"
"istio.io/istio/pkg/log"
)
type perKindValidateFunc func(br *BackEndResource) error
type perKindValidator struct {
pbSpec proto.Message
validate perKindValidateFunc
}
func (pv *perKindValidator) validateAndConvert(key Key, br *BackEndResource, res *Resource) error {
if pv.validate != nil {
if err := pv.validate(br); err != nil {
return err
}
}
res.Spec = proto.Clone(pv.pbSpec)
return convert(key, br.Spec, res.Spec)
}
func validateRule(br *BackEndResource) error {
_, matchExists := br.Spec[matchField]
_, selectorExists := br.Spec[selectorField]
if !matchExists && selectorExists {
return errors.New("field 'selector' is deprecated, use 'match' instead")
}
if selectorExists {
log.Warnf("Deprecated field 'selector' used in %s. Use 'match' instead.", br.Metadata.Name)
}
return nil
}
// validator provides the default structural validation with delegating
// an external validator for the referential integrity.
type validator struct {
externalValidator Validator
perKindValidators map[string]*perKindValidator
}
// NewValidator creates a default validator which validates the structure through registered
// kinds and referential integrity through ev.
func NewValidator(ev Validator, kinds map[string]proto.Message) BackendValidator {
vs := make(map[string]*perKindValidator, len(kinds))
for k, pb := range kinds {
var validateFunc perKindValidateFunc
if k == ruleKind {
validateFunc = validateRule
}
vs[k] = &perKindValidator{pb, validateFunc}
}
return &validator{
externalValidator: ev,
perKindValidators: vs,
}
}
func (v *validator) Validate(bev *BackendEvent) error {
pkv, ok := v.perKindValidators[bev.Key.Kind]
if !ok {
// Pass unrecognized kinds -- they should be validated by somewhere else.
log.Debugf("unrecognized kind %s is requested to validate", bev.Key.Kind)
return nil
}
ev := &Event{
Type: bev.Type,
Key: bev.Key,
}
if bev.Type == Update {
ev.Value = &Resource{Metadata: bev.Value.Metadata}
if err := pkv.validateAndConvert(bev.Key, bev.Value, ev.Value); err != nil {
return err
}
}
if v.externalValidator == nil {
return nil
}
return v.externalValidator.Validate(ev)
}