/* 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 ( "context" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" eventingduckv1beta1 "knative.dev/eventing/pkg/apis/duck/v1beta1" "knative.dev/eventing/pkg/apis/messaging/v1beta1" clientv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1beta1" duckv1 "knative.dev/pkg/apis/duck/v1" knerrors "knative.dev/client/pkg/errors" ) // KnSubscriptionsClient for interacting with Subscriptions type KnSubscriptionsClient interface { // GetSubscription returns a Subscription by its name GetSubscription(name string) (*v1beta1.Subscription, error) // CreteSubscription creates a Subscription with given spec CreateSubscription(subscription *v1beta1.Subscription) error // UpdateSubscription updates a Subscription with given spec UpdateSubscription(subscription *v1beta1.Subscription) error // DeleteSubscription deletes a Subscription by its name DeleteSubscription(name string) error // ListSubscription lists all Subscriptions ListSubscription() (*v1beta1.SubscriptionList, error) // Namespace returns the namespace for this subscription client Namespace() string } // subscriptionsClient struct holds the client interface and namespace type subscriptionsClient struct { client clientv1beta1.SubscriptionInterface namespace string } // newKnSubscriptionsClient returns kn subscriptions client func newKnSubscriptionsClient(client clientv1beta1.SubscriptionInterface, namespace string) KnSubscriptionsClient { return &subscriptionsClient{ client: client, namespace: namespace, } } // Get the namespace for which this client is created func (c *subscriptionsClient) Namespace() string { return c.namespace } // GetSubscription gets Subscription by its name func (c *subscriptionsClient) GetSubscription(name string) (*v1beta1.Subscription, error) { subscription, err := c.client.Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { return nil, knerrors.GetError(err) } err = updateMessagingGVK(subscription) if err != nil { return nil, err } return subscription, nil } // CreateSubscription creates Subscription with given spec func (c *subscriptionsClient) CreateSubscription(subscription *v1beta1.Subscription) error { _, err := c.client.Create(context.TODO(), subscription, metav1.CreateOptions{}) return knerrors.GetError(err) } // UpdateSubscription creates Subscription with given spec func (c *subscriptionsClient) UpdateSubscription(subscription *v1beta1.Subscription) error { _, err := c.client.Update(context.TODO(), subscription, metav1.UpdateOptions{}) return knerrors.GetError(err) } // DeleteSubscription deletes Subscription by its name func (c *subscriptionsClient) DeleteSubscription(name string) error { return knerrors.GetError(c.client.Delete(context.TODO(), name, metav1.DeleteOptions{})) } // ListSubscription lists subscriptions in configured namespace func (c *subscriptionsClient) ListSubscription() (*v1beta1.SubscriptionList, error) { subscriptionList, err := c.client.List(context.TODO(), metav1.ListOptions{}) if err != nil { return nil, knerrors.GetError(err) } return updateSubscriptionListGVK(subscriptionList) } func updateSubscriptionListGVK(subscriptionList *v1beta1.SubscriptionList) (*v1beta1.SubscriptionList, error) { subscriptionListNew := subscriptionList.DeepCopy() err := updateMessagingGVK(subscriptionListNew) if err != nil { return nil, err } subscriptionListNew.Items = make([]v1beta1.Subscription, len(subscriptionList.Items)) for idx, subscription := range subscriptionList.Items { subscriptionClone := subscription.DeepCopy() err := updateMessagingGVK(subscriptionClone) if err != nil { return nil, err } subscriptionListNew.Items[idx] = *subscriptionClone } return subscriptionListNew, nil } // SubscriptionBuilder is for building the Subscription object type SubscriptionBuilder struct { subscription *v1beta1.Subscription } // NewSubscriptionBuilder for building Subscription object func NewSubscriptionBuilder(name string) *SubscriptionBuilder { return &SubscriptionBuilder{subscription: &v1beta1.Subscription{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, }} } // NewSubscriptionBuilderFromExisting for building Subscription object from existing Subscription object func NewSubscriptionBuilderFromExisting(subs *v1beta1.Subscription) *SubscriptionBuilder { return &SubscriptionBuilder{subscription: subs.DeepCopy()} } // Channel sets the channel reference for this subscription func (s *SubscriptionBuilder) Channel(channel *corev1.ObjectReference) *SubscriptionBuilder { if channel == nil { return s } s.subscription.Spec.Channel = *channel return s } func (s *SubscriptionBuilder) Subscriber(subs *duckv1.Destination) *SubscriptionBuilder { if subs == nil { return s } s.subscription.Spec.Subscriber = subs return s } func (s *SubscriptionBuilder) Reply(reply *duckv1.Destination) *SubscriptionBuilder { if reply == nil { return s } s.subscription.Spec.Reply = reply return s } func (s *SubscriptionBuilder) DeadLetterSink(dls *duckv1.Destination) *SubscriptionBuilder { if dls == nil { return s } ds := &eventingduckv1beta1.DeliverySpec{} ds.DeadLetterSink = dls s.subscription.Spec.Delivery = ds return s } // Build returns the Subscription object from the builder func (s *SubscriptionBuilder) Build() *v1beta1.Subscription { return s.subscription }