Skip to content
Merged
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
14 changes: 7 additions & 7 deletions lib/resourceapply/apiext.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package resourceapply

import (
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
apiextclientv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
apiextlistersv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
)

func ApplyCustomResourceDefinition(client apiextclientv1beta1.CustomResourceDefinitionsGetter, required *apiextv1beta1.CustomResourceDefinition) (*apiextv1beta1.CustomResourceDefinition, bool, error) {
func ApplyCustomResourceDefinitionV1beta1(client apiextclientv1beta1.CustomResourceDefinitionsGetter, required *apiextv1beta1.CustomResourceDefinition) (*apiextv1beta1.CustomResourceDefinition, bool, error) {
existing, err := client.CustomResourceDefinitions().Get(required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
actual, err := client.CustomResourceDefinitions().Create(required)
Expand All @@ -25,7 +26,7 @@ func ApplyCustomResourceDefinition(client apiextclientv1beta1.CustomResourceDefi
}

modified := pointer.BoolPtr(false)
resourcemerge.EnsureCustomResourceDefinition(modified, existing, *required)
resourcemerge.EnsureCustomResourceDefinitionV1beta1(modified, existing, *required)
if !*modified {
return existing, false, nil
}
Expand All @@ -34,8 +35,8 @@ func ApplyCustomResourceDefinition(client apiextclientv1beta1.CustomResourceDefi
return actual, true, err
}

func ApplyCustomResourceDefinitionFromCache(lister apiextlistersv1beta1.CustomResourceDefinitionLister, client apiextclientv1beta1.CustomResourceDefinitionsGetter, required *apiextv1beta1.CustomResourceDefinition) (*apiextv1beta1.CustomResourceDefinition, bool, error) {
existing, err := lister.Get(required.Name)
func ApplyCustomResourceDefinitionV1(client apiextclientv1.CustomResourceDefinitionsGetter, required *apiextv1.CustomResourceDefinition) (*apiextv1.CustomResourceDefinition, bool, error) {
existing, err := client.CustomResourceDefinitions().Get(required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
actual, err := client.CustomResourceDefinitions().Create(required)
return actual, true, err
Expand All @@ -48,9 +49,8 @@ func ApplyCustomResourceDefinitionFromCache(lister apiextlistersv1beta1.CustomRe
return nil, false, nil
}

existing = existing.DeepCopy()
modified := pointer.BoolPtr(false)
resourcemerge.EnsureCustomResourceDefinition(modified, existing, *required)
resourcemerge.EnsureCustomResourceDefinitionV1(modified, existing, *required)
if !*modified {
return existing, false, nil
}
Expand Down
57 changes: 40 additions & 17 deletions lib/resourcebuilder/apiext.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
"github.com/openshift/cluster-version-operator/lib"
"github.com/openshift/cluster-version-operator/lib/resourceapply"
"github.com/openshift/cluster-version-operator/lib/resourceread"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
apiextclientv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -17,15 +19,17 @@ import (
)

type crdBuilder struct {
client *apiextclientv1beta1.ApiextensionsV1beta1Client
raw []byte
modifier MetaV1ObjectModifierFunc
raw []byte
modifier MetaV1ObjectModifierFunc
clientV1beta1 *apiextclientv1beta1.ApiextensionsV1beta1Client
clientV1 *apiextclientv1.ApiextensionsV1Client
}

func newCRDBuilder(config *rest.Config, m lib.Manifest) Interface {
return &crdBuilder{
client: apiextclientv1beta1.NewForConfigOrDie(withProtobuf(config)),
raw: m.Raw,
raw: m.Raw,
clientV1beta1: apiextclientv1beta1.NewForConfigOrDie(withProtobuf(config)),
clientV1: apiextclientv1.NewForConfigOrDie(withProtobuf(config)),
}
}

Expand All @@ -39,34 +43,53 @@ func (b *crdBuilder) WithModifier(f MetaV1ObjectModifierFunc) Interface {
}

func (b *crdBuilder) Do(ctx context.Context) error {
crd := resourceread.ReadCustomResourceDefinitionV1Beta1OrDie(b.raw)
if b.modifier != nil {
b.modifier(crd)
}
_, updated, err := resourceapply.ApplyCustomResourceDefinition(b.client, crd)
if err != nil {
return err
crd := resourceread.ReadCustomResourceDefinitionOrDie(b.raw)

var updated bool
var err error
var name string

switch crd := crd.(type) {
case *apiextv1beta1.CustomResourceDefinition:
if b.modifier != nil {
b.modifier(crd)
}
_, updated, err = resourceapply.ApplyCustomResourceDefinitionV1beta1(b.clientV1beta1, crd)
if err != nil {
return err
}
name = crd.Name
case *apiextv1.CustomResourceDefinition:
if b.modifier != nil {
b.modifier(crd)
}
_, updated, err = resourceapply.ApplyCustomResourceDefinitionV1(b.clientV1, crd)
if err != nil {
return err
}
name = crd.Name
}

if updated {
return waitForCustomResourceDefinitionCompletion(ctx, b.client, crd)
return waitForCustomResourceDefinitionCompletion(ctx, b.clientV1, name)
}
return nil
}

func waitForCustomResourceDefinitionCompletion(ctx context.Context, client apiextclientv1beta1.CustomResourceDefinitionsGetter, crd *apiextv1beta1.CustomResourceDefinition) error {
func waitForCustomResourceDefinitionCompletion(ctx context.Context, client apiextclientv1.CustomResourceDefinitionsGetter, crd string) error {
return wait.PollImmediateUntil(defaultObjectPollInterval, func() (bool, error) {
c, err := client.CustomResourceDefinitions().Get(crd.Name, metav1.GetOptions{})
c, err := client.CustomResourceDefinitions().Get(crd, metav1.GetOptions{})
if errors.IsNotFound(err) {
// exit early to recreate the crd.
return false, err
}
if err != nil {
klog.Errorf("error getting CustomResourceDefinition %s: %v", crd.Name, err)
klog.Errorf("error getting CustomResourceDefinition %s: %v", crd, err)
return false, nil
}

for _, condition := range c.Status.Conditions {
if condition.Type == apiextv1beta1.Established && condition.Status == apiextv1beta1.ConditionTrue {
if condition.Type == apiextv1.Established && condition.Status == apiextv1.ConditionTrue {
return true, nil
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/resourcebuilder/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiregv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
apiregv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
Expand All @@ -15,6 +16,7 @@ import (
func init() {
rm := NewResourceMapper()
rm.RegisterGVK(apiextv1beta1.SchemeGroupVersion.WithKind("CustomResourceDefinition"), newCRDBuilder)
rm.RegisterGVK(apiextv1.SchemeGroupVersion.WithKind("CustomResourceDefinition"), newCRDBuilder)
rm.RegisterGVK(apiregv1.SchemeGroupVersion.WithKind("APIService"), newAPIServiceBuilder)
rm.RegisterGVK(apiregv1beta1.SchemeGroupVersion.WithKind("APIService"), newAPIServiceBuilder)
rm.RegisterGVK(appsv1.SchemeGroupVersion.WithKind("Deployment"), newDeploymentBuilder)
Expand Down
52 changes: 50 additions & 2 deletions lib/resourcemerge/apiext.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,63 @@
package resourcemerge

import (
"strings"

apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/utils/pointer"

"k8s.io/apimachinery/pkg/api/equality"
)

// EnsureCustomResourceDefinition ensures that the existing matches the required.
// EnsureCustomResourceDefinitionV1beta1 ensures that the existing matches the required.
// modified is set to true when existing had to be updated with required.
func EnsureCustomResourceDefinition(modified *bool, existing *apiextv1beta1.CustomResourceDefinition, required apiextv1beta1.CustomResourceDefinition) {
func EnsureCustomResourceDefinitionV1beta1(modified *bool, existing *apiextv1beta1.CustomResourceDefinition, required apiextv1beta1.CustomResourceDefinition) {
EnsureObjectMeta(modified, &existing.ObjectMeta, required.ObjectMeta)

// apply defaults to blue print
if len(required.Spec.Versions) > 0 && len(required.Spec.Version) == 0 {
required.Spec.Version = required.Spec.Versions[0].Name
}
if len(required.Spec.Versions) == 0 && len(required.Spec.Version) > 0 {
required.Spec.Versions = []apiextv1beta1.CustomResourceDefinitionVersion{
{
Name: required.Spec.Version,
Served: true,
Storage: true,
},
}
}
if required.Spec.PreserveUnknownFields == nil {
required.Spec.PreserveUnknownFields = pointer.BoolPtr(true)
}
if len(required.Spec.Names.Singular) == 0 {
required.Spec.Names.Singular = strings.ToLower(required.Spec.Names.Kind)
}
if len(required.Spec.Names.ListKind) == 0 {
required.Spec.Names.ListKind = required.Spec.Names.Kind + "List"
}

// we stomp everything
if !equality.Semantic.DeepEqual(existing.Spec, required.Spec) {
*modified = true
existing.Spec = required.Spec
}
}

// EnsureCustomResourceDefinitionV1 ensures that the existing matches the required.
// modified is set to true when existing had to be updated with required.
func EnsureCustomResourceDefinitionV1(modified *bool, existing *apiextv1.CustomResourceDefinition, required apiextv1.CustomResourceDefinition) {
EnsureObjectMeta(modified, &existing.ObjectMeta, required.ObjectMeta)

// apply defaults to blue print
if len(required.Spec.Names.Singular) == 0 {
required.Spec.Names.Singular = strings.ToLower(required.Spec.Names.Kind)
}
if len(required.Spec.Names.ListKind) == 0 {
required.Spec.Names.ListKind = required.Spec.Names.Kind + "List"
}

// we stomp everything
if !equality.Semantic.DeepEqual(existing.Spec, required.Spec) {
*modified = true
Expand Down
10 changes: 7 additions & 3 deletions lib/resourceread/apiext.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package resourceread

import (
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
Expand All @@ -15,13 +16,16 @@ func init() {
if err := apiextv1beta1.AddToScheme(apiExtensionsScheme); err != nil {
panic(err)
}
if err := apiextv1.AddToScheme(apiExtensionsScheme); err != nil {
panic(err)
}
}

// ReadCustomResourceDefinitionV1Beta1OrDie reads crd object from bytes. Panics on error.
func ReadCustomResourceDefinitionV1Beta1OrDie(objBytes []byte) *apiextv1beta1.CustomResourceDefinition {
// ReadCustomResourceDefinitionOrDie reads crd object from bytes as v1 or v1beta1. Panics on error.
func ReadCustomResourceDefinitionOrDie(objBytes []byte) runtime.Object {
requiredObj, err := runtime.Decode(apiExtensionsCodecs.UniversalDecoder(apiextv1beta1.SchemeGroupVersion), objBytes)
if err != nil {
panic(err)
}
return requiredObj.(*apiextv1beta1.CustomResourceDefinition)
return requiredObj
}