Skip to content

Commit

Permalink
Moving config schema out of pilot (istio#16061)
Browse files Browse the repository at this point in the history
  • Loading branch information
nmittler authored and istio-testing committed Aug 14, 2019
1 parent c58f4bc commit d51f81d
Show file tree
Hide file tree
Showing 63 changed files with 1,577 additions and 1,034 deletions.
11 changes: 6 additions & 5 deletions galley/pkg/crd/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ import (
"regexp"
"time"

multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-multierror"

"istio.io/pkg/log"
"istio.io/pkg/probe"

mixervalidate "istio.io/istio/mixer/pkg/validate"
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pkg/cmd"
"istio.io/istio/pkg/config/schemas"
"istio.io/istio/pkg/kube"
"istio.io/pkg/log"
"istio.io/pkg/probe"
)

const (
Expand Down Expand Up @@ -81,7 +82,7 @@ func RunValidation(ready, stopCh chan struct{}, vc *WebhookParameters, kubeConfi
log.Fatalf("could not create k8s clientset: %v", err)
}
vc.MixerValidator = mixerValidator
vc.PilotDescriptor = model.IstioConfigTypes
vc.PilotDescriptor = schemas.Istio
vc.Clientset = clientset
wh, err := NewWebhook(*vc)
if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions galley/pkg/crd/validation/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import (
mixerCrd "istio.io/istio/mixer/pkg/config/crd"
"istio.io/istio/mixer/pkg/config/store"
"istio.io/istio/pilot/pkg/config/kube/crd"
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pkg/config/schema"
)

var (
Expand Down Expand Up @@ -73,7 +73,7 @@ type WebhookParameters struct {
MixerValidator store.BackendValidator

// PilotDescriptor provides a description of all pilot configuration resources.
PilotDescriptor model.ConfigDescriptor
PilotDescriptor schema.Set

// DomainSuffix is the DNS domain suffix for Pilot CRD resources,
// e.g. cluster.local.
Expand Down Expand Up @@ -176,7 +176,7 @@ type Webhook struct {
cert *tls.Certificate

// pilot
descriptor model.ConfigDescriptor
descriptor schema.Set
domainSuffix string

// mixer
Expand Down Expand Up @@ -344,21 +344,21 @@ func (wh *Webhook) admitPilot(request *admissionv1beta1.AdmissionRequest) *admis
return toAdmissionResponse(fmt.Errorf("cannot decode configuration: %v", err))
}

schema, exists := wh.descriptor.GetByType(crd.CamelCaseToKebabCase(obj.Kind))
s, exists := wh.descriptor.GetByType(crd.CamelCaseToKebabCase(obj.Kind))
if !exists {
scope.Infof("unrecognized type %v", obj.Kind)
reportValidationFailed(request, reasonUnknownType)
return toAdmissionResponse(fmt.Errorf("unrecognized type %v", obj.Kind))
}

out, err := crd.ConvertObject(schema, &obj, wh.domainSuffix)
out, err := crd.ConvertObject(s, &obj, wh.domainSuffix)
if err != nil {
scope.Infof("error decoding configuration: %v", err)
reportValidationFailed(request, reasonCRDConversionError)
return toAdmissionResponse(fmt.Errorf("error decoding configuration: %v", err))
}

if err := schema.Validate(out.Name, out.Namespace, out.Spec); err != nil {
if err := s.Validate(out.Name, out.Namespace, out.Spec); err != nil {
scope.Infof("configuration is invalid: %v", err)
reportValidationFailed(request, reasonInvalidConfig)
return toAdmissionResponse(fmt.Errorf("configuration is invalid: %v", err))
Expand Down
5 changes: 3 additions & 2 deletions galley/pkg/crd/validation/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
"istio.io/istio/pilot/pkg/config/kube/crd"
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pilot/test/mock"
"istio.io/istio/pkg/config/schemas"
"istio.io/istio/pkg/mcp/testing/testcerts"
testConfig "istio.io/istio/pkg/test/config"
)
Expand Down Expand Up @@ -224,7 +225,7 @@ func makePilotConfig(t *testing.T, i int, validConfig bool, includeBogusKey bool
name := fmt.Sprintf("%s%d", "mock-config", i)
config := model.Config{
ConfigMeta: model.ConfigMeta{
Type: model.MockConfig.Type,
Type: schemas.MockConfig.Type,
Name: name,
Labels: map[string]string{
"key": name,
Expand All @@ -241,7 +242,7 @@ func makePilotConfig(t *testing.T, i int, validConfig bool, includeBogusKey bool
}},
},
}
obj, err := crd.ConvertConfig(model.MockConfig, config)
obj, err := crd.ConvertConfig(schemas.MockConfig, config)
if err != nil {
t.Fatalf("ConvertConfig(%v) failed: %v", config.Name, err)
}
Expand Down
16 changes: 9 additions & 7 deletions istioctl/cmd/convert_ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"istio.io/istio/istioctl/pkg/convert"
"istio.io/istio/pilot/pkg/config/kube/crd"
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pkg/config/schema"
"istio.io/istio/pkg/config/schemas"
"istio.io/istio/pkg/config/validation"

"istio.io/pkg/log"
Expand All @@ -40,9 +42,9 @@ var (
)

func convertConfigs(readers []io.Reader, writer io.Writer) error {
configDescriptor := model.ConfigDescriptor{
model.VirtualService,
model.Gateway,
configDescriptor := schema.Set{
schemas.VirtualService,
schemas.Gateway,
}

configs, ingresses, err := readConfigs(readers)
Expand Down Expand Up @@ -130,14 +132,14 @@ func readConfigs(readers []io.Reader) ([]model.Config, []*v1beta1.Ingress, error
return out, outIngresses, nil
}

func writeYAMLOutput(descriptor model.ConfigDescriptor, configs []model.Config, writer io.Writer) {
func writeYAMLOutput(descriptor schema.Set, configs []model.Config, writer io.Writer) {
for i, cfg := range configs {
schema, exists := descriptor.GetByType(cfg.Type)
s, exists := descriptor.GetByType(cfg.Type)
if !exists {
log.Errorf("Unknown kind %q for %v", crd.ResourceName(cfg.Type), cfg.Name)
continue
}
obj, err := crd.ConvertConfig(schema, cfg)
obj, err := crd.ConvertConfig(s, cfg)
if err != nil {
log.Errorf("Could not decode %v: %v", cfg.Name, err)
continue
Expand All @@ -157,7 +159,7 @@ func writeYAMLOutput(descriptor model.ConfigDescriptor, configs []model.Config,
func validateConfigs(configs []model.Config) error {
var errs error
for _, cfg := range configs {
if cfg.Type == model.VirtualService.Type {
if cfg.Type == schemas.VirtualService.Type {
if err := validation.ValidateVirtualService(cfg.Name, cfg.Namespace, cfg.Spec); err != nil {
errs = multierror.Append(err, errs)
}
Expand Down
71 changes: 37 additions & 34 deletions istioctl/cmd/deprecated_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,28 @@ import (
"time"

"github.com/ghodss/yaml"
multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
kubeSchema "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

"istio.io/api/networking/v1alpha3"
"istio.io/pkg/log"

"istio.io/istio/istioctl/pkg/util/handlers"
"istio.io/istio/pilot/pkg/config/kube/crd"
"istio.io/istio/pilot/pkg/config/kube/crd/controller"
"istio.io/istio/pilot/pkg/model"
"istio.io/istio/pkg/config/schema"
"istio.io/istio/pkg/config/schemas"
kubecfg "istio.io/istio/pkg/kube"
"istio.io/pkg/log"
)

const (
Expand All @@ -65,28 +68,28 @@ var (

// sortWeight defines the output order for "get all". We show the V3 types first.
sortWeight = map[string]int{
model.Gateway.Type: 10,
model.VirtualService.Type: 5,
model.DestinationRule.Type: 3,
model.ServiceEntry.Type: 1,
schemas.Gateway.Type: 10,
schemas.VirtualService.Type: 5,
schemas.DestinationRule.Type: 3,
schemas.ServiceEntry.Type: 1,
}

// mustList tracks which Istio types we SHOULD NOT silently ignore if we can't list.
// The user wants reasonable error messages when doing `get all` against a different
// server version.
mustList = map[string]bool{
model.Gateway.Type: true,
model.VirtualService.Type: true,
model.DestinationRule.Type: true,
model.ServiceEntry.Type: true,
model.HTTPAPISpec.Type: true,
model.HTTPAPISpecBinding.Type: true,
model.QuotaSpec.Type: true,
model.QuotaSpecBinding.Type: true,
model.AuthenticationPolicy.Type: true,
model.ServiceRole.Type: true,
model.ServiceRoleBinding.Type: true,
model.RbacConfig.Type: true,
schemas.Gateway.Type: true,
schemas.VirtualService.Type: true,
schemas.DestinationRule.Type: true,
schemas.ServiceEntry.Type: true,
schemas.HTTPAPISpec.Type: true,
schemas.HTTPAPISpecBinding.Type: true,
schemas.QuotaSpec.Type: true,
schemas.QuotaSpecBinding.Type: true,
schemas.AuthenticationPolicy.Type: true,
schemas.ServiceRole.Type: true,
schemas.ServiceRoleBinding.Type: true,
schemas.RbacConfig.Type: true,
}

// Headings for short format listing specific to type
Expand All @@ -107,7 +110,7 @@ var (

// all resources will be migrated out of config.istio.io to their own api group mapping to package path.
// TODO(xiaolanz) legacy group exists until we find out a client for mixer
legacyIstioAPIGroupVersion = schema.GroupVersion{
legacyIstioAPIGroupVersion = kubeSchema.GroupVersion{
Group: "config.istio.io",
Version: "v1alpha2",
}
Expand Down Expand Up @@ -306,7 +309,7 @@ istioctl get virtualservice bookinfo
return errors.New("a resource cannot be retrieved by name across all namespaces")
}

var typs []model.ProtoSchema
var typs []schema.Instance
if !getByName && strings.EqualFold(args[0], "all") {
typs = configClient.ConfigDescriptor()
} else {
Expand All @@ -315,7 +318,7 @@ istioctl get virtualservice bookinfo
c.Println(c.UsageString())
return err
}
typs = []model.ProtoSchema{typ}
typs = []schema.Instance{typ}
}

var ns string
Expand Down Expand Up @@ -364,8 +367,8 @@ istioctl get virtualservice bookinfo
return errs
},

ValidArgs: configTypeResourceNames(model.IstioConfigTypes),
ArgAliases: configTypePluralResourceNames(model.IstioConfigTypes),
ValidArgs: configTypeResourceNames(schemas.Istio),
ArgAliases: configTypePluralResourceNames(schemas.Istio),
}

deleteCmd = &cobra.Command{
Expand Down Expand Up @@ -464,8 +467,8 @@ istioctl delete virtualservice bookinfo
return errs
},

ValidArgs: configTypeResourceNames(model.IstioConfigTypes),
ArgAliases: configTypePluralResourceNames(model.IstioConfigTypes),
ValidArgs: configTypeResourceNames(schemas.Istio),
ArgAliases: configTypePluralResourceNames(schemas.Istio),
}

contextCmd = &cobra.Command{
Expand Down Expand Up @@ -535,17 +538,17 @@ istioctl context-create --api-server http://127.0.0.1:8080
)

// The protoSchema is based on the kind (for example "virtualservice" or "destinationrule")
func protoSchema(configClient model.ConfigStore, typ string) (model.ProtoSchema, error) {
func protoSchema(configClient model.ConfigStore, typ string) (schema.Instance, error) {
for _, desc := range configClient.ConfigDescriptor() {
switch strings.ToLower(typ) {
case crd.ResourceName(desc.Type), crd.ResourceName(desc.Plural):
return desc, nil
case desc.Type, desc.Plural: // legacy hyphenated resources names
return model.ProtoSchema{}, fmt.Errorf("%q not recognized. Please use non-hyphenated resource name %q",
return schema.Instance{}, fmt.Errorf("%q not recognized. Please use non-hyphenated resource name %q",
typ, crd.ResourceName(typ))
}
}
return model.ProtoSchema{}, fmt.Errorf("configuration type %s not found, the types are %v",
return schema.Instance{}, fmt.Errorf("configuration type %s not found, the types are %v",
typ, strings.Join(supportedTypes(configClient), ", "))
}

Expand Down Expand Up @@ -710,12 +713,12 @@ func printShortGateway(config model.Config, w io.Writer) {
func printYamlOutput(writer io.Writer, configClient model.ConfigStore, configList []model.Config) {
descriptor := configClient.ConfigDescriptor()
for _, config := range configList {
schema, exists := descriptor.GetByType(config.Type)
s, exists := descriptor.GetByType(config.Type)
if !exists {
log.Errorf("Unknown kind %q for %v", crd.ResourceName(config.Type), config.Name)
continue
}
obj, err := crd.ConvertConfig(schema, config)
obj, err := crd.ConvertConfig(s, config)
if err != nil {
log.Errorf("Could not decode %v: %v", config.Name, err)
continue
Expand All @@ -731,7 +734,7 @@ func printYamlOutput(writer io.Writer, configClient model.ConfigStore, configLis
}

func newClient() (model.ConfigStore, error) {
return controller.NewClient(kubeconfig, configContext, model.IstioConfigTypes, "")
return controller.NewClient(kubeconfig, configContext, schemas.Istio, "")
}

func supportedTypes(configClient model.ConfigStore) []string {
Expand Down Expand Up @@ -823,15 +826,15 @@ func prepareClientForOthers(configs []crd.IstioKind) (*rest.RESTClient, map[stri
return client, resources, nil
}

func configTypeResourceNames(configTypes model.ConfigDescriptor) []string {
func configTypeResourceNames(configTypes schema.Set) []string {
resourceNames := make([]string, len(configTypes))
for _, typ := range configTypes {
resourceNames = append(resourceNames, crd.ResourceName(typ.Type))
}
return resourceNames
}

func configTypePluralResourceNames(configTypes model.ConfigDescriptor) []string {
func configTypePluralResourceNames(configTypes schema.Set) []string {
resourceNames := make([]string, len(configTypes))
for _, typ := range configTypes {
resourceNames = append(resourceNames, crd.ResourceName(typ.Plural))
Expand Down
Loading

0 comments on commit d51f81d

Please sign in to comment.