crossplane-runtime/pkg/resource/resource.go

146 lines
4.8 KiB
Go

/*
Copyright 2019 The Crossplane 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 resource
import (
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"github.com/crossplaneio/crossplane-runtime/apis/core/v1alpha1"
"github.com/crossplaneio/crossplane-runtime/pkg/meta"
)
// A ConnectionSecretOwner may create and manage a connection secret.
type ConnectionSecretOwner interface {
metav1.Object
ConnectionSecretWriterTo
}
// ConnectionSecretFor the supplied ConnectionSecretOwner, assumed to be of the
// supplied kind.
func ConnectionSecretFor(o ConnectionSecretOwner, kind schema.GroupVersionKind) *corev1.Secret {
return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: o.GetNamespace(),
Name: o.GetWriteConnectionSecretToReference().Name,
OwnerReferences: []metav1.OwnerReference{meta.AsController(meta.ReferenceTo(o, kind))},
},
Data: make(map[string][]byte),
}
}
// MustCreateObject returns a new Object of the supplied kind. It panics if the
// kind is unknown to the supplied ObjectCreator.
func MustCreateObject(kind schema.GroupVersionKind, oc runtime.ObjectCreater) runtime.Object {
obj, err := oc.New(kind)
if err != nil {
panic(err)
}
return obj
}
// GetKind returns the GroupVersionKind of the supplied object. It return an
// error if the object is unknown to the supplied ObjectTyper, the object is
// unversioned, or the object does not have exactly one registered kind.
func GetKind(obj runtime.Object, ot runtime.ObjectTyper) (schema.GroupVersionKind, error) {
kinds, unversioned, err := ot.ObjectKinds(obj)
if err != nil {
return schema.GroupVersionKind{}, errors.Wrap(err, "cannot get kind of supplied object")
}
if unversioned {
return schema.GroupVersionKind{}, errors.New("supplied object is unversioned")
}
if len(kinds) != 1 {
return schema.GroupVersionKind{}, errors.New("supplied object does not have exactly one kind")
}
return kinds[0], nil
}
// MustGetKind returns the GroupVersionKind of the supplied object. It panics if
// the object is unknown to the supplied ObjectTyper, the object is unversioned,
// or the object does not have exactly one registered kind.
func MustGetKind(obj runtime.Object, ot runtime.ObjectTyper) schema.GroupVersionKind {
gvk, err := GetKind(obj, ot)
if err != nil {
panic(err)
}
return gvk
}
// An ErrorIs function returns true if an error satisfies a particular condition.
type ErrorIs func(err error) bool
// Ignore any errors that satisfy the supplied ErrorIs function by returning
// nil. Errors that do not satisfy the suppled function are returned unmodified.
func Ignore(is ErrorIs, err error) error {
if is(err) {
return nil
}
return err
}
// IgnoreNotFound returns the supplied error, or nil if the error indicates a
// Kubernetes resource was not found.
func IgnoreNotFound(err error) error {
return Ignore(kerrors.IsNotFound, err)
}
// ResolveClassClaimValues validates the supplied claim value against the
// supplied resource class value. If both are non-zero they must match.
func ResolveClassClaimValues(classValue, claimValue string) (string, error) {
if classValue == "" {
return claimValue, nil
}
if claimValue == "" {
return classValue, nil
}
if classValue != claimValue {
return "", errors.Errorf("claim value [%s] does not match class value [%s]", claimValue, classValue)
}
return claimValue, nil
}
// SetBindable indicates that the supplied Bindable is ready for binding to
// another Bindable, such as a resource claim or managed resource.
func SetBindable(b Bindable) {
if b.GetBindingPhase() == v1alpha1.BindingPhaseBound {
return
}
b.SetBindingPhase(v1alpha1.BindingPhaseUnbound)
}
// IsBindable returns true if the supplied Bindable is ready for binding to
// another Bindable, such as a resource claim or managed resource.
func IsBindable(b Bindable) bool {
return b.GetBindingPhase() == v1alpha1.BindingPhaseUnbound
}
// IsBound returns true if the supplied Bindable is bound to another Bindable,
// such as a resource claim or managed resource.
func IsBound(b Bindable) bool {
return b.GetBindingPhase() == v1alpha1.BindingPhaseBound
}
// IsConditionTrue returns if condition status is true
func IsConditionTrue(c v1alpha1.Condition) bool {
return c.Status == corev1.ConditionTrue
}