1// Copyright 2017 Istio 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 15package validate 16 17import ( 18 "github.com/gogo/protobuf/proto" 19 20 "istio.io/istio/mixer/adapter/metadata" 21 "istio.io/istio/mixer/pkg/adapter" 22 "istio.io/istio/mixer/pkg/config/store" 23 runtimeConfig "istio.io/istio/mixer/pkg/runtime/config" 24 "istio.io/istio/mixer/pkg/template" 25 generatedTmplRepo "istio.io/istio/mixer/template" 26 "istio.io/pkg/log" 27) 28 29// validator provides the default structural validation 30type validator struct { 31 kinds map[string]proto.Message 32 config *runtimeConfig.Ephemeral 33} 34 35// NewValidator creates a default validator which validates the structure through registered 36// kinds and optionally referential integrity and expressions if stateful verification is enabled. 37func NewValidator(adapters map[string]*adapter.Info, templates map[string]*template.Info, stateful bool) store.BackendValidator { 38 out := &validator{ 39 kinds: runtimeConfig.KindMap(adapters, templates), 40 } 41 if stateful { 42 out.config = runtimeConfig.NewEphemeral(templates, adapters) 43 } 44 return out 45} 46 47// NewDefaultValidator creates a validator using compiled templates and adapter descriptors. 48// It does not depend on actual handler/builder interfaces from the compiled-in adapters. 49func NewDefaultValidator(stateful bool) store.BackendValidator { 50 info := generatedTmplRepo.SupportedTmplInfo 51 templates := make(map[string]*template.Info, len(info)) 52 for k := range info { 53 t := info[k] 54 templates[k] = &t 55 } 56 adapters := metadata.InfoMap() 57 return NewValidator(adapters, templates, stateful) 58} 59 60func (v *validator) Validate(bev *store.BackendEvent) error { 61 _, ok := v.kinds[bev.Key.Kind] 62 if !ok { 63 // Pass unrecognized kinds -- they should be validated by somewhere else. 64 log.Debugf("unrecognized kind %s is requested to validate", bev.Key.Kind) 65 return nil 66 } 67 68 ev, err := store.ConvertValue(*bev, v.kinds) 69 if err != nil { 70 return err 71 } 72 73 // optional deep validation 74 if v.config != nil { 75 v.config.ApplyEvent([]*store.Event{&ev}) 76 if _, err = v.config.BuildSnapshot(); err != nil { 77 return err 78 } 79 } 80 81 return nil 82} 83 84func (v *validator) SupportsKind(kind string) bool { 85 _, exists := v.kinds[kind] 86 return exists 87} 88