Skip to content

Get rid of empty-kind check - take 2 #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: crd_versioning_nop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions api/openapi-spec/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 28 additions & 25 deletions pkg/master/controller/crdregistration/crdregistration_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ func NewAutoRegistrationController(crdinformer crdinformers.CustomResourceDefini
cast := obj.(*apiextensions.CustomResourceDefinition)
c.enqueueCRD(cast)
},
UpdateFunc: func(_, obj interface{}) {
cast := obj.(*apiextensions.CustomResourceDefinition)
c.enqueueCRD(cast)
UpdateFunc: func(oldObj, newObj interface{}) {
c.enqueueCRD(oldObj.(*apiextensions.CustomResourceDefinition))
c.enqueueCRD(newObj.(*apiextensions.CustomResourceDefinition))
},
DeleteFunc: func(obj interface{}) {
cast, ok := obj.(*apiextensions.CustomResourceDefinition)
Expand Down Expand Up @@ -120,8 +120,10 @@ func (c *crdRegistrationController) Run(threadiness int, stopCh <-chan struct{})
utilruntime.HandleError(err)
} else {
for _, crd := range crds {
if err := c.syncHandler(schema.GroupVersion{Group: crd.Spec.Group, Version: crd.Spec.Version}); err != nil {
utilruntime.HandleError(err)
for _, version := range crd.Spec.Versions {
if err := c.syncHandler(schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name}); err != nil {
utilruntime.HandleError(err)
}
}
}
}
Expand Down Expand Up @@ -182,11 +184,12 @@ func (c *crdRegistrationController) processNextWorkItem() bool {
}

func (c *crdRegistrationController) enqueueCRD(crd *apiextensions.CustomResourceDefinition) {
c.queue.Add(schema.GroupVersion{Group: crd.Spec.Group, Version: crd.Spec.Version})
for _, version := range crd.Spec.Versions {
c.queue.Add(schema.GroupVersion{Group: crd.Spec.Group, Version: version.Name})
}
}

func (c *crdRegistrationController) handleVersionUpdate(groupVersion schema.GroupVersion) error {
found := false
apiServiceName := groupVersion.Version + "." + groupVersion.Group

// check all CRDs. There shouldn't that many, but if we have problems later we can index them
Expand All @@ -195,26 +198,26 @@ func (c *crdRegistrationController) handleVersionUpdate(groupVersion schema.Grou
return err
}
for _, crd := range crds {
if crd.Spec.Version == groupVersion.Version && crd.Spec.Group == groupVersion.Group {
found = true
break
if crd.Spec.Group != groupVersion.Group {
continue
}
for index, version := range crd.Spec.Versions {
if version.Name != groupVersion.Version || !version.Served {
continue
}
c.apiServiceRegistration.AddAPIServiceToSync(&apiregistration.APIService{
ObjectMeta: metav1.ObjectMeta{Name: apiServiceName},
Spec: apiregistration.APIServiceSpec{
Group: groupVersion.Group,
Version: groupVersion.Version,
GroupPriorityMinimum: 1000, // CRDs should have relatively low priority
VersionPriority: int32(100 + len(crd.Spec.Versions) - index), // CRDs should have relatively low priority
},
})
return nil
}
}

if !found {
c.apiServiceRegistration.RemoveAPIServiceToSync(apiServiceName)
return nil
}

c.apiServiceRegistration.AddAPIServiceToSync(&apiregistration.APIService{
ObjectMeta: metav1.ObjectMeta{Name: apiServiceName},
Spec: apiregistration.APIServiceSpec{
Group: groupVersion.Group,
Version: groupVersion.Version,
GroupPriorityMinimum: 1000, // CRDs should have relatively low priority
VersionPriority: 100, // CRDs should have relatively low priority
},
})

c.apiServiceRegistration.RemoveAPIServiceToSync(apiServiceName)
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,16 @@ func TestHandleVersionUpdate(t *testing.T) {
startingCRDs: []*apiextensions.CustomResourceDefinition{
{
Spec: apiextensions.CustomResourceDefinitionSpec{
Group: "group.com",
Version: "v1",
Group: "group.com",
// Version field is deprecated and crd registration won't rely on it at all.
// defaulting route will fill up Versions field if user only provided version field.
Versions: []apiextensions.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
},
},
},
},
},
Expand All @@ -56,7 +64,7 @@ func TestHandleVersionUpdate(t *testing.T) {
Group: "group.com",
Version: "v1",
GroupPriorityMinimum: 1000,
VersionPriority: 100,
VersionPriority: 101,
},
},
},
Expand All @@ -66,8 +74,14 @@ func TestHandleVersionUpdate(t *testing.T) {
startingCRDs: []*apiextensions.CustomResourceDefinition{
{
Spec: apiextensions.CustomResourceDefinitionSpec{
Group: "group.com",
Version: "v1",
Group: "group.com",
Versions: []apiextensions.CustomResourceDefinitionVersion{
{
Name: "v1",
Served: true,
Storage: true,
},
},
},
},
},
Expand Down Expand Up @@ -98,7 +112,6 @@ func TestHandleVersionUpdate(t *testing.T) {
t.Errorf("%s expected %v, got %v", test.name, test.expectedRemoved, registration.removed)
}
}

}

type fakeAPIServiceRegistration struct {
Expand Down
4 changes: 4 additions & 0 deletions staging/src/k8s.io/api/Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
if len(obj.Names.ListKind) == 0 && len(obj.Names.Kind) > 0 {
obj.Names.ListKind = obj.Names.Kind + "List"
}
if len(obj.Versions) == 0 && len(obj.Version) != 0 {
obj.Versions = []apiextensions.CustomResourceDefinitionVersion{
{
Name: obj.Version,
Served: true,
Storage: true,
},
}
} else if len(obj.Versions) != 0 {
obj.Version = obj.Versions[0].Name
}
},
func(obj *apiextensions.JSONSchemaProps, c fuzz.Continue) {
// we cannot use c.FuzzNoCustom because of the interface{} fields. So let's loop with reflection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package apiextensions

import (
"fmt"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -116,3 +117,24 @@ func CRDRemoveFinalizer(crd *CustomResourceDefinition, needle string) {
}
crd.Finalizers = newFinalizers
}

// HasCRDVersion returns true if `version` is in the list of CRD's versions.
func HasCRDVersion(crd *CustomResourceDefinition, version string) bool {
for _, v := range crd.Spec.Versions {
if v.Name == version {
return true
}
}
return false
}

// GetCRDStorageVersion returns the storage version for given CRD.
func GetCRDStorageVersion(crd *CustomResourceDefinition) (string, error) {
for _, v := range crd.Spec.Versions {
if v.Storage {
return v.Name, nil
}
}
// This should not happened if crd is valid
return "", fmt.Errorf("invalid CustomResourceDefinition, no storage version")
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type CustomResourceDefinitionSpec struct {
// Group is the group this resource belongs in
Group string
// Version is the version this resource belongs in
// Should be always first item in Versions field if provided.
// Optional, but at least one of Version or Versions must be set.
// Deprecated: Please use `Versions`.
Version string
// Names are the names used to describe this custom resource
Names CustomResourceDefinitionNames
Expand All @@ -34,6 +37,23 @@ type CustomResourceDefinitionSpec struct {
Validation *CustomResourceValidation
// Subresources describes the subresources for CustomResources
Subresources *CustomResourceSubresources
// Versions is the list of all supported versions for this resource.
// If Version field is provided, this field is optional.
// Validation: All versions must use the same validation schema for now. i.e., top
// level Validation field is applied to all of these versions.
// Order: The order of these versions is used to determine the order in discovery API
// (preferred version first).
Versions []CustomResourceDefinitionVersion
}

type CustomResourceDefinitionVersion struct {
// Name is the version name, e.g. “v1”, “v2beta1”, etc.
Name string
// Served is a flag enabling/disabling this version from being served via REST APIs
Served bool
// Storage flags the version as storage version. There must be exactly one flagged
// as storage version.
Storage bool
}

// CustomResourceDefinitionNames indicates the names to serve this CustomResourceDefinition
Expand Down Expand Up @@ -115,6 +135,14 @@ type CustomResourceDefinitionStatus struct {
// AcceptedNames are the names that are actually being used to serve discovery
// They may be different than the names in spec.
AcceptedNames CustomResourceDefinitionNames

// StoredVersions are all versions of CustomResources that were ever persisted. Tracking these
// versions allows a migration path for stored versions in etcd. The field is mutable
// so the migration controller can first finish a migration to another version (i.e.
// that no old objects are left in the storage), and then remove the rest of the
// versions from this list.
// None of the versions in this list can be removed from the spec.Versions field.
StoredVersions []string
}

// CustomResourceCleanupFinalizer is the name of the finalizer which will delete instances of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,16 @@ func SetDefaults_CustomResourceDefinitionSpec(obj *CustomResourceDefinitionSpec)
if len(obj.Names.ListKind) == 0 && len(obj.Names.Kind) > 0 {
obj.Names.ListKind = obj.Names.Kind + "List"
}
// If there is no list of versions, create on using deprecated Version field.
if len(obj.Versions) == 0 && len(obj.Version) != 0 {
obj.Versions = []CustomResourceDefinitionVersion{{
Name: obj.Version,
Storage: true,
Served: true,
}}
}
// For backward compatibility set the version field to the first item in versions list.
if len(obj.Version) == 0 && len(obj.Versions) != 0 {
obj.Version = obj.Versions[0].Name
}
}
Loading