// Copyright © 2019 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 v1alpha2 import ( "context" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" v1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2" clientv1alpha2 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" knerrors "knative.dev/client/pkg/errors" "knative.dev/client/pkg/util" ) // KnAPIServerSourcesClient interface for working with ApiServer sources type KnAPIServerSourcesClient interface { // Get an ApiServerSource by name GetAPIServerSource(name string) (*v1alpha2.ApiServerSource, error) // Create an ApiServerSource by object CreateAPIServerSource(apiSource *v1alpha2.ApiServerSource) error // Update an ApiServerSource by object UpdateAPIServerSource(apiSource *v1alpha2.ApiServerSource) error // Delete an ApiServerSource by name DeleteAPIServerSource(name string) error // List ApiServerSource // TODO: Support list configs like in service list ListAPIServerSource() (*v1alpha2.ApiServerSourceList, error) // Get namespace for this client Namespace() string } // knSourcesClient is a combination of Sources client interface and namespace // Temporarily help to add sources dependencies // May be changed when adding real sources features type apiServerSourcesClient struct { client clientv1alpha2.ApiServerSourceInterface namespace string } // newKnAPIServerSourcesClient is to invoke Eventing Sources Client API to create object func newKnAPIServerSourcesClient(client clientv1alpha2.ApiServerSourceInterface, namespace string) KnAPIServerSourcesClient { return &apiServerSourcesClient{ client: client, namespace: namespace, } } //GetAPIServerSource returns apiSource object if present func (c *apiServerSourcesClient) GetAPIServerSource(name string) (*v1alpha2.ApiServerSource, error) { apiSource, err := c.client.Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { return nil, knerrors.GetError(err) } return apiSource, nil } //CreateAPIServerSource is used to create an instance of ApiServerSource func (c *apiServerSourcesClient) CreateAPIServerSource(apiSource *v1alpha2.ApiServerSource) error { _, err := c.client.Create(context.TODO(), apiSource, metav1.CreateOptions{}) if err != nil { return knerrors.GetError(err) } return nil } //UpdateAPIServerSource is used to update an instance of ApiServerSource func (c *apiServerSourcesClient) UpdateAPIServerSource(apiSource *v1alpha2.ApiServerSource) error { _, err := c.client.Update(context.TODO(), apiSource, metav1.UpdateOptions{}) if err != nil { return knerrors.GetError(err) } return nil } //DeleteAPIServerSource is used to create an instance of ApiServerSource func (c *apiServerSourcesClient) DeleteAPIServerSource(name string) error { err := c.client.Delete(context.TODO(), name, metav1.DeleteOptions{}) return err } // Return the client's namespace func (c *apiServerSourcesClient) Namespace() string { return c.namespace } // ListAPIServerSource returns the available ApiServer type sources func (c *apiServerSourcesClient) ListAPIServerSource() (*v1alpha2.ApiServerSourceList, error) { sourceList, err := c.client.List(context.TODO(), metav1.ListOptions{}) if err != nil { return nil, knerrors.GetError(err) } return updateAPIServerSourceListGVK(sourceList) } func updateAPIServerSourceListGVK(sourceList *v1alpha2.ApiServerSourceList) (*v1alpha2.ApiServerSourceList, error) { sourceListNew := sourceList.DeepCopy() err := updateSourceGVK(sourceListNew) if err != nil { return nil, err } sourceListNew.Items = make([]v1alpha2.ApiServerSource, len(sourceList.Items)) for idx, source := range sourceList.Items { sourceClone := source.DeepCopy() err := updateSourceGVK(sourceClone) if err != nil { return nil, err } sourceListNew.Items[idx] = *sourceClone } return sourceListNew, nil } func updateSourceGVK(obj runtime.Object) error { return util.UpdateGroupVersionKindWithScheme(obj, v1alpha2.SchemeGroupVersion, scheme.Scheme) } // APIServerSourceBuilder is for building the source type APIServerSourceBuilder struct { apiServerSource *v1alpha2.ApiServerSource } // NewAPIServerSourceBuilder for building ApiServer source object func NewAPIServerSourceBuilder(name string) *APIServerSourceBuilder { return &APIServerSourceBuilder{apiServerSource: &v1alpha2.ApiServerSource{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, }} } // NewAPIServerSourceBuilderFromExisting for building the object from existing ApiServerSource object func NewAPIServerSourceBuilderFromExisting(apiServerSource *v1alpha2.ApiServerSource) *APIServerSourceBuilder { return &APIServerSourceBuilder{apiServerSource: apiServerSource.DeepCopy()} } // Resources which should be streamed func (b *APIServerSourceBuilder) Resources(resources []v1alpha2.APIVersionKindSelector) *APIServerSourceBuilder { b.apiServerSource.Spec.Resources = resources return b } // ServiceAccount with which this source should operate func (b *APIServerSourceBuilder) ServiceAccount(sa string) *APIServerSourceBuilder { b.apiServerSource.Spec.ServiceAccountName = sa return b } // EventMode for whether to send resource 'Ref' or complete 'Resource' func (b *APIServerSourceBuilder) EventMode(eventMode string) *APIServerSourceBuilder { b.apiServerSource.Spec.EventMode = eventMode return b } // Sink or destination of the source func (b *APIServerSourceBuilder) Sink(sink duckv1.Destination) *APIServerSourceBuilder { b.apiServerSource.Spec.Sink = sink return b } // CloudEventOverrides adds given Cloud Event override extensions map to source spec func (b *APIServerSourceBuilder) CloudEventOverrides(ceo map[string]string, toRemove []string) *APIServerSourceBuilder { if ceo == nil && len(toRemove) == 0 { return b } ceOverrides := b.apiServerSource.Spec.CloudEventOverrides if ceOverrides == nil { ceOverrides = &duckv1.CloudEventOverrides{Extensions: map[string]string{}} b.apiServerSource.Spec.CloudEventOverrides = ceOverrides } for k, v := range ceo { ceOverrides.Extensions[k] = v } for _, r := range toRemove { delete(ceOverrides.Extensions, r) } return b } // Build the ApiServerSource object func (b *APIServerSourceBuilder) Build() *v1alpha2.ApiServerSource { return b.apiServerSource }