Promoting Binding to v1beta1 (#1483)

* binding to v1beta1

* improving coverage
This commit is contained in:
Ignacio (Nacho) Cano 2020-07-14 08:34:19 -07:00 committed by GitHub
parent ac02cac99b
commit 27fe4e1910
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 400 additions and 146 deletions

View File

@ -63,8 +63,10 @@ type AddressStatus struct {
Address *Addressable `json:"address,omitempty"`
}
// Verify AddressableType resources meet duck contracts.
var (
_ apis.Listable = (*AddressableType)(nil)
_ apis.Listable = (*AddressableType)(nil)
_ ducktypes.Populatable = (*AddressableType)(nil)
)
// GetFullType implements duck.Implementable

View File

@ -0,0 +1,58 @@
/*
Copyright 2020 The Knative 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 v1
import (
"testing"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
"knative.dev/pkg/apis/duck"
"knative.dev/pkg/apis/duck/ducktypes"
)
func TestTypesImplements(t *testing.T) {
testCases := []struct {
instance interface{}
iface ducktypes.Implementable
}{
{instance: &AddressableType{}, iface: &Addressable{}},
{instance: &KResource{}, iface: &Conditions{}},
}
for _, tc := range testCases {
if err := duck.VerifyType(tc.instance, tc.iface); err != nil {
t.Error(err)
}
}
}
func TestImplementsPodSpecable(t *testing.T) {
instances := []interface{}{
&WithPod{},
&appsv1.ReplicaSet{},
&appsv1.Deployment{},
&appsv1.StatefulSet{},
&appsv1.DaemonSet{},
&batchv1.Job{},
}
for _, instance := range instances {
if err := duck.VerifyType(instance, &PodSpecable{}); err != nil {
t.Error(err)
}
}
}

View File

@ -23,6 +23,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"knative.dev/pkg/apis/duck/ducktypes"
"knative.dev/pkg/apis"
)
@ -66,6 +67,12 @@ func (t *KResource) Populate() {
}}
}
// Verify KResource resources meet duck contracts.
var (
_ apis.Listable = (*KResource)(nil)
_ ducktypes.Populatable = (*KResource)(nil)
)
// GetListType implements apis.Listable
func (*KResource) GetListType() runtime.Object {
return &KResourceList{}

View File

@ -31,6 +31,9 @@ import (
// in the manner of ReplicaSet, Deployment, DaemonSet, StatefulSet.
type PodSpecable corev1.PodTemplateSpec
// PodSpecable is an Implementable duck type.
var _ ducktypes.Implementable = (*PodSpecable)(nil)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// WithPod is the shell that demonstrates how PodSpecable types wrap
@ -47,10 +50,10 @@ type WithPodSpec struct {
Template PodSpecable `json:"template,omitempty"`
}
// Assert that we implement the interfaces necessary to
// use duck.VerifyType.
// Verify WithPod resources meet duck contracts.
var (
_ apis.Listable = (*WithPod)(nil)
_ apis.Listable = (*WithPod)(nil)
_ ducktypes.Populatable = (*WithPod)(nil)
)
// GetFullType implements duck.Implementable

View File

@ -88,7 +88,6 @@ type SourceStatus struct {
// CloudEventAttributes specifies the attributes that a Source
// uses as part of its CloudEvents.
type CloudEventAttributes struct {
// Type refers to the CloudEvent type attribute.
Type string `json:"type,omitempty"`
@ -109,8 +108,11 @@ func (ss *SourceStatus) IsReady() bool {
return false
}
// Verify Source resources meet duck contracts.
var (
_ apis.Listable = (*Source)(nil)
_ apis.Listable = (*Source)(nil)
_ ducktypes.Implementable = (*Source)(nil)
_ ducktypes.Populatable = (*Source)(nil)
)
const (

View File

@ -29,6 +29,9 @@ import (
// Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable.
type Conditions apis.Conditions
// Conditions is an Implementable duck type.
var _ ducktypes.Implementable = (*Conditions)(nil)
// Status shows how we expect folks to embed Conditions in
// their Status field.
// WARNING: Adding fields to this struct will add them to all Knative resources.

View File

@ -1,78 +0,0 @@
/*
Copyright 2020 The Knative 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 duck
import (
"testing"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
v1 "knative.dev/pkg/apis/duck/v1"
)
// Conditions is an Implementable "duck type".
var _ Implementable = (*v1.Conditions)(nil)
// In order for Conditions to be Implementable, KResource must be Populatable.
var _ Populatable = (*v1.KResource)(nil)
// Source is an Implementable "duck type".
var _ Implementable = (*v1.Source)(nil)
// Verify Source resources meet duck contracts.
var _ Populatable = (*v1.Source)(nil)
var _ Populatable = (*v1.WithPod)(nil)
var _ Implementable = (*v1.PodSpecable)(nil)
func TestV1TypesImplements(t *testing.T) {
testCases := []struct {
instance interface{}
iface Implementable
}{
{instance: &v1.AddressableType{}, iface: &v1.Addressable{}},
{instance: &v1.KResource{}, iface: &v1.Conditions{}},
}
for _, tc := range testCases {
if err := VerifyType(tc.instance, tc.iface); err != nil {
t.Error(err)
}
}
}
func TestV1ImplementsPodSpecable(t *testing.T) {
instances := []interface{}{
&v1.WithPod{},
&appsv1.ReplicaSet{},
&appsv1.Deployment{},
&appsv1.StatefulSet{},
&appsv1.DaemonSet{},
&batchv1.Job{},
}
for _, instance := range instances {
if err := VerifyType(instance, &v1.PodSpecable{}); err != nil {
t.Error(err)
}
}
}
// Addressable is an Implementable "duck type".
var _ Implementable = (*v1.Addressable)(nil)
// Verify AddressableType resources meet duck contracts.
var _ Populatable = (*v1.AddressableType)(nil)

View File

@ -20,7 +20,6 @@ import (
"testing"
"knative.dev/pkg/apis/duck"
"knative.dev/pkg/apis/duck/v1beta1"
)
func TestTypesImplements(t *testing.T) {
@ -29,7 +28,6 @@ func TestTypesImplements(t *testing.T) {
iface duck.Implementable
}{
{instance: &AddressableType{}, iface: &Addressable{}},
{instance: &AddressableType{}, iface: &v1beta1.Addressable{}},
{instance: &LegacyTarget{}, iface: &LegacyTargetable{}},
{instance: &Target{}, iface: &Targetable{}},
{instance: &Binding{}, iface: &Binding{}},

View File

@ -43,6 +43,9 @@ type Addressable struct {
var (
// Addressable is a Convertible type.
_ apis.Convertible = (*Addressable)(nil)
// Addressable is an Implementable "duck type".
_ ducktypes.Implementable = (*Addressable)(nil)
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@ -64,8 +67,10 @@ type AddressStatus struct {
Address *Addressable `json:"address,omitempty"`
}
// Verify AddressableType resources meet duck contracts.
var (
_ apis.Listable = (*AddressableType)(nil)
_ apis.Listable = (*AddressableType)(nil)
_ ducktypes.Populatable = (*AddressableType)(nil)
)
// GetFullType implements duck.Implementable

View File

@ -0,0 +1,92 @@
/*
Copyright 2020 The Knative 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 v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"knative.dev/pkg/apis"
"knative.dev/pkg/apis/duck"
"knative.dev/pkg/tracker"
)
// +genduck
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Binding is a duck type that specifies the partial schema to which all
// Binding implementations should adhere.
type Binding struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec BindingSpec `json:"spec"`
}
// Verify that Binding implements the appropriate interfaces.
var (
_ duck.Implementable = (*Binding)(nil)
_ duck.Populatable = (*Binding)(nil)
_ apis.Listable = (*Binding)(nil)
)
// BindingSpec specifies the spec portion of the Binding partial-schema.
type BindingSpec struct {
// Subject references the resource(s) whose "runtime contract" should be
// augmented by Binding implementations.
Subject tracker.Reference `json:"subject"`
}
// GetFullType implements duck.Implementable
func (*Binding) GetFullType() duck.Populatable {
return &Binding{}
}
// Populate implements duck.Populatable
func (t *Binding) Populate() {
t.Spec = BindingSpec{
Subject: tracker.Reference{
APIVersion: "apps/v1",
Kind: "Deployment",
Namespace: "default",
// Name and Selector are mutually exclusive,
// but we fill them both in for this test.
Name: "bazinga",
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"foo": "bar",
"baz": "blah",
},
},
},
}
}
// GetListType implements apis.Listable
func (*Binding) GetListType() runtime.Object {
return &BindingList{}
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BindingList is a list of Binding resources
type BindingList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []Binding `json:"items"`
}

View File

@ -0,0 +1,40 @@
/*
Copyright 2020 The Knative 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 v1beta1
import (
"testing"
"knative.dev/pkg/apis/duck"
"knative.dev/pkg/apis/duck/ducktypes"
)
func TestTypesImplements(t *testing.T) {
testCases := []struct {
instance interface{}
iface ducktypes.Implementable
}{
{instance: &AddressableType{}, iface: &Addressable{}},
{instance: &KResource{}, iface: &Conditions{}},
{instance: &Source{}, iface: &Conditions{}},
}
for _, tc := range testCases {
if err := duck.VerifyType(tc.instance, tc.iface); err != nil {
t.Error(err)
}
}
}

View File

@ -50,6 +50,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
(&KResource{}).GetListType(),
&AddressableType{},
(&AddressableType{}).GetListType(),
&Binding{},
(&Binding{}).GetListType(),
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil

View File

@ -94,8 +94,11 @@ func (ss *SourceStatus) IsReady() bool {
return false
}
// Verify Source resources meet duck contracts.
var (
_ apis.Listable = (*Source)(nil)
_ apis.Listable = (*Source)(nil)
_ ducktypes.Implementable = (*Source)(nil)
_ ducktypes.Populatable = (*Source)(nil)
)
const (

View File

@ -34,6 +34,9 @@ import (
// Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable.
type Conditions apis.Conditions
// Conditions is an Implementable duck type.
var _ ducktypes.Implementable = (*Conditions)(nil)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// KResource is a skeleton type wrapping Conditions in the manner we expect
@ -81,8 +84,11 @@ func (s *Status) SetConditions(c apis.Conditions) {
s.Conditions = Conditions(c)
}
// Ensure KResource satisfies apis.Listable
var _ apis.Listable = (*KResource)(nil)
// Verify KResource resources meet duck contracts.
var (
_ apis.Listable = (*KResource)(nil)
_ ducktypes.Populatable = (*KResource)(nil)
)
// GetFullType implements duck.Implementable
func (*Conditions) GetFullType() ducktypes.Populatable {

View File

@ -128,6 +128,83 @@ func (in *AddressableTypeList) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Binding) DeepCopyInto(out *Binding) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Binding.
func (in *Binding) DeepCopy() *Binding {
if in == nil {
return nil
}
out := new(Binding)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Binding) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BindingList) DeepCopyInto(out *BindingList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Binding, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BindingList.
func (in *BindingList) DeepCopy() *BindingList {
if in == nil {
return nil
}
out := new(BindingList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BindingList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BindingSpec) DeepCopyInto(out *BindingSpec) {
*out = *in
in.Subject.DeepCopyInto(&out.Subject)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BindingSpec.
func (in *BindingSpec) DeepCopy() *BindingSpec {
if in == nil {
return nil
}
out := new(BindingSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CloudEventOverrides) DeepCopyInto(out *CloudEventOverrides) {
*out = *in

View File

@ -1,56 +0,0 @@
/*
Copyright 2020 The Knative 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 duck
import (
"testing"
"knative.dev/pkg/apis/duck/v1beta1"
)
// v1beta1.Conditions is an Implementable "duck type".
var _ Implementable = (*v1beta1.Conditions)(nil)
// In order for v1beta1.Conditions to be Implementable, v1beta1.KResource must be Populatable.
var _ Populatable = (*v1beta1.KResource)(nil)
// v1beta1.Source is an Implementable "duck type".
var _ Implementable = (*v1beta1.Source)(nil)
// Verify v1beta1.Source resources meet duck contracts.
var _ Populatable = (*v1beta1.Source)(nil)
// Addressable is an Implementable "duck type".
var _ Implementable = (*v1beta1.Addressable)(nil)
// Verify AddressableType resources meet duck contracts.
var _ Populatable = (*v1beta1.AddressableType)(nil)
func TestV1Beta1TypesImplements(t *testing.T) {
testCases := []struct {
instance interface{}
iface Implementable
}{
{instance: &v1beta1.AddressableType{}, iface: &v1beta1.Addressable{}},
{instance: &v1beta1.KResource{}, iface: &v1beta1.Conditions{}},
}
for _, tc := range testCases {
if err := VerifyType(tc.instance, tc.iface); err != nil {
t.Error(err)
}
}
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2020 The Knative 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.
*/
// Code generated by injection-gen. DO NOT EDIT.
package binding
import (
context "context"
duck "knative.dev/pkg/apis/duck"
v1beta1 "knative.dev/pkg/apis/duck/v1beta1"
controller "knative.dev/pkg/controller"
injection "knative.dev/pkg/injection"
dynamicclient "knative.dev/pkg/injection/clients/dynamicclient"
logging "knative.dev/pkg/logging"
)
func init() {
injection.Default.RegisterDuck(WithDuck)
}
// Key is used for associating the Informer inside the context.Context.
type Key struct{}
func WithDuck(ctx context.Context) context.Context {
dc := dynamicclient.Get(ctx)
dif := &duck.CachedInformerFactory{
Delegate: &duck.TypedInformerFactory{
Client: dc,
Type: (&v1beta1.Binding{}).GetFullType(),
ResyncPeriod: controller.GetResyncPeriod(ctx),
StopChannel: ctx.Done(),
},
}
return context.WithValue(ctx, Key{}, dif)
}
// Get extracts the typed informer from the context.
func Get(ctx context.Context) duck.InformerFactory {
untyped := ctx.Value(Key{})
if untyped == nil {
logging.FromContext(ctx).Panic(
"Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.")
}
return untyped.(duck.InformerFactory)
}

View File

@ -0,0 +1,30 @@
/*
Copyright 2020 The Knative 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.
*/
// Code generated by injection-gen. DO NOT EDIT.
package fake
import (
binding "knative.dev/pkg/client/injection/ducks/duck/v1beta1/binding"
injection "knative.dev/pkg/injection"
)
var Get = binding.Get
func init() {
injection.Fake.RegisterDuck(binding.WithDuck)
}