| /* |
| Copyright 2018 The Kubernetes 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 generators |
| |
| import ( |
| "fmt" |
| "io" |
| |
| "k8s.io/kube-openapi/pkg/generators/rules" |
| |
| "github.com/golang/glog" |
| "k8s.io/gengo/types" |
| ) |
| |
| // apiLinter is the framework hosting mutliple API rules and recording API rule |
| // violations |
| type apiLinter struct { |
| // API rules that implement APIRule interface and output API rule violations |
| rules []APIRule |
| violations []apiViolation |
| } |
| |
| // newAPILinter creates an apiLinter object with API rules in package rules. Please |
| // add APIRule here when new API rule is implemented. |
| func newAPILinter() *apiLinter { |
| return &apiLinter{ |
| rules: []APIRule{ |
| &rules.NamesMatch{}, |
| }, |
| } |
| } |
| |
| // apiViolation uniquely identifies single API rule violation |
| type apiViolation struct { |
| // Name of rule from APIRule.Name() |
| rule string |
| |
| packageName string |
| typeName string |
| |
| // Optional: name of field that violates API rule. Empty fieldName implies that |
| // the entire type violates the rule. |
| field string |
| } |
| |
| // APIRule is the interface for validating API rule on Go types |
| type APIRule interface { |
| // Validate evaluates API rule on type t and returns a list of field names in |
| // the type that violate the rule. Empty field name [""] implies the entire |
| // type violates the rule. |
| Validate(t *types.Type) ([]string, error) |
| |
| // Name returns the name of APIRule |
| Name() string |
| } |
| |
| // validate runs all API rules on type t and records any API rule violation |
| func (l *apiLinter) validate(t *types.Type) error { |
| for _, r := range l.rules { |
| glog.V(5).Infof("validating API rule %v for type %v", r.Name(), t) |
| fields, err := r.Validate(t) |
| if err != nil { |
| return err |
| } |
| for _, field := range fields { |
| l.violations = append(l.violations, apiViolation{ |
| rule: r.Name(), |
| packageName: t.Name.Package, |
| typeName: t.Name.Name, |
| field: field, |
| }) |
| } |
| } |
| return nil |
| } |
| |
| // report prints any API rule violation to writer w and returns error if violation exists |
| func (l *apiLinter) report(w io.Writer) error { |
| for _, v := range l.violations { |
| fmt.Fprintf(w, "API rule violation: %s,%s,%s,%s\n", v.rule, v.packageName, v.typeName, v.field) |
| } |
| if len(l.violations) > 0 { |
| return fmt.Errorf("API rule violations exist") |
| } |
| return nil |
| } |