From d38ca4cdd39317409b0d1b67674b347519ae229d Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 6 Dec 2019 14:32:24 -0800 Subject: [PATCH 01/26] API --- config/300-configmappropagation.yaml | 58 ++++++++++++++++ .../v1alpha1/configmappropagation_types.go | 66 +++++++++++++++++++ pkg/apis/configs/v1alpha1/doc.go | 20 ++++++ pkg/apis/configs/v1alpha1/register.go | 1 + 4 files changed, 145 insertions(+) create mode 100644 config/300-configmappropagation.yaml create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_types.go create mode 100644 pkg/apis/configs/v1alpha1/doc.go create mode 100644 pkg/apis/configs/v1alpha1/register.go diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml new file mode 100644 index 00000000000..0837f2aa382 --- /dev/null +++ b/config/300-configmappropagation.yaml @@ -0,0 +1,58 @@ +# 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. + +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: configmappropagation.configs.knative.dev + labels: + eventing.knative.dev/release: devel + knative.dev/crd-install: "true" +spec: + group: configs.knative.dev + versions: + - name: v1alpha1 + served: true + storage: true + names: + kind: ConfigMapPropagation + plural: configmappropagations + singular: configmappropagation + categories: + - all + - knative + - eventing + scope: Namespaced + subresources: + status: {} + additionalPrinterColumns: + - name: Propagated + type: string + JSONPath: ".status.conditions[?(@.type==\"Ready\")].status" + - name: Reason + type: string + JSONPath: ".status.conditions[?(@.type==\"Ready\")].reason" + validation: + openAPIV3Schema: + properties: + spec: + required: + - originalNamespace + - selector + properties: + originalNamespace: + type: string + description: "The namespace where original configmaps exist in." + selector: + type: object diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go new file mode 100644 index 00000000000..57d75fff04d --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -0,0 +1,66 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/kmeta" +) + +// ConfigMapPropagation +type ConfigMapPropagation struct { + metav1.TypeMeta `json:". inline"` + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the + Spec ConfigMapPropagationSpec `json:"spec,omitempty"` + + // +optional + Status ConfigMapPropagationStatus `json:"status,omitempty"` +} + +var ( + // Check that ConfigMapPropagation can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*ConfigMapPropagation)(nil) + _ apis.Defaultable = (*ConfigMapPropagation)(nil) + + // Check that EventType can return its spec untyped. + _ apis.HasSpec = (*ConfigMapPropagation)(nil) + + _ runtime.Object = (*ConfigMapPropagation)(nil) + + // Check that we can create OwnerReferences to an EventType. + _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) +) + +type ConfigMapPropagationSpec struct { + OriginalNamespace string `json:"originalNamespace,omitempty"` + Selector *fields.Selector `json:"selector,omitempty"` +} + +// ConfigMapPropagationStatus represents the current state of a ConfigMapPropagation. +type ConfigMapPropagationStatus struct { + // inherits duck/v1 Status, which currently provides: + // * ObservedGeneration - the 'Generation' of the Service that was last processed by the controller. + // * Conditions - the latest available observations of a resource's current state. + duckv1.Status `json:",inline"` +} diff --git a/pkg/apis/configs/v1alpha1/doc.go b/pkg/apis/configs/v1alpha1/doc.go new file mode 100644 index 00000000000..7417f460d83 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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 v1alpha1 is the v1alpha1 version of the API. +// +k8s:deepcopy-gen=package +// +groupName=configs.knative.dev +package v1alpha1 diff --git a/pkg/apis/configs/v1alpha1/register.go b/pkg/apis/configs/v1alpha1/register.go new file mode 100644 index 00000000000..1c267880d8d --- /dev/null +++ b/pkg/apis/configs/v1alpha1/register.go @@ -0,0 +1 @@ +package v1alpha1 From e95fb2f4738bdb941049b4cf279e2d25a7e2d2ac Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 6 Dec 2019 17:02:36 -0800 Subject: [PATCH 02/26] API-2 --- config/300-configmappropagation.yaml | 8 ++- hack/update-codegen.sh | 4 +- pkg/apis/configs/register.go | 21 ++++++ .../v1alpha1/configmappropagation_types.go | 66 +++++++++++++------ pkg/apis/configs/v1alpha1/register.go | 52 +++++++++++++++ 5 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 pkg/apis/configs/register.go diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index 0837f2aa382..4fbde6fc904 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -43,6 +43,12 @@ spec: - name: Reason type: string JSONPath: ".status.conditions[?(@.type==\"Ready\")].reason" + - name: OriginalNamepsace + type: string + JSONPath: ".spec.originalNamespace" + - name: Selector + type: string + JSONPath: ".spec.selector" validation: openAPIV3Schema: properties: @@ -55,4 +61,4 @@ spec: type: string description: "The namespace where original configmaps exist in." selector: - type: object + type: string diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 821d7c5cdf6..7a30bc690e7 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -30,7 +30,7 @@ KNATIVE_CODEGEN_PKG=${KNATIVE_CODEGEN_PKG:-$(cd ${REPO_ROOT_DIR}; ls -d -1 $(dir # instead of the $GOPATH directly. For normal projects this can be dropped. ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \ - "eventing:v1alpha1 sources:v1alpha1 messaging:v1alpha1 flows:v1alpha1" \ + "eventing:v1alpha1 sources:v1alpha1 messaging:v1alpha1 flows:v1alpha1 configs:v1alpha1" \ --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt # Only deepcopy the Duck types, as they are not real resources. @@ -42,7 +42,7 @@ ${CODEGEN_PKG}/generate-groups.sh "deepcopy" \ # Knative Injection ${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \ knative.dev/eventing/pkg/client knative.dev/eventing/pkg/apis \ - "eventing:v1alpha1 sources:v1alpha1 messaging:v1alpha1 flows:v1alpha1 duck:v1alpha1" \ + "eventing:v1alpha1 sources:v1alpha1 messaging:v1alpha1 flows:v1alpha1 duck:v1alpha1 configs:v1alpha1" \ --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt # Make sure our dependencies are up-to-date diff --git a/pkg/apis/configs/register.go b/pkg/apis/configs/register.go new file mode 100644 index 00000000000..cf929487ac4 --- /dev/null +++ b/pkg/apis/configs/register.go @@ -0,0 +1,21 @@ +/* +Copyright 2018 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 configs + +const ( + GroupName = "configs.knative.dev" +) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 57d75fff04d..20cc0a42ee5 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -18,43 +18,47 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/runtime" - "knative.dev/pkg/apis" + "k8s.io/apimachinery/pkg/runtime/schema" duckv1 "knative.dev/pkg/apis/duck/v1" - "knative.dev/pkg/kmeta" ) -// ConfigMapPropagation +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ConfigMapPropagation is used to propagate configMaps from source namespace to target namespace type ConfigMapPropagation struct { metav1.TypeMeta `json:". inline"` // +optional metav1.ObjectMeta `json:"metadata,omitempty"` - // Spec defines the + // Spec defines the desired state of the ConfigMapPropagation Spec ConfigMapPropagationSpec `json:"spec,omitempty"` + // Status represents the current state of the EventType. + // This data may be out of date. // +optional Status ConfigMapPropagationStatus `json:"status,omitempty"` } -var ( - // Check that ConfigMapPropagation can be validated, can be defaulted, and has immutable fields. - _ apis.Validatable = (*ConfigMapPropagation)(nil) - _ apis.Defaultable = (*ConfigMapPropagation)(nil) - - // Check that EventType can return its spec untyped. - _ apis.HasSpec = (*ConfigMapPropagation)(nil) - - _ runtime.Object = (*ConfigMapPropagation)(nil) - - // Check that we can create OwnerReferences to an EventType. - _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) -) +//var ( +// // Check that ConfigMapPropagation can be validated, can be defaulted, and has immutable fields. +// _ apis.Validatable = (*ConfigMapPropagation)(nil) +// _ apis.Defaultable = (*ConfigMapPropagation)(nil) +// +// // Check that EventType can return its spec untyped. +// _ apis.HasSpec = (*ConfigMapPropagation)(nil) +// +// _ runtime.Object = (*ConfigMapPropagation)(nil) +// +// // Check that we can create OwnerReferences to an EventType. +// _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) +//) type ConfigMapPropagationSpec struct { - OriginalNamespace string `json:"originalNamespace,omitempty"` - Selector *fields.Selector `json:"selector,omitempty"` + // OriginalNamespace represents the namespace where the original configMaps are in + OriginalNamespace string `json:"originalNamespace,omitempty"` + // Selector only selects original configMaps with labels under Selector + Selector string `json:"selector,omitempty"` } // ConfigMapPropagationStatus represents the current state of a ConfigMapPropagation. @@ -64,3 +68,23 @@ type ConfigMapPropagationStatus struct { // * Conditions - the latest available observations of a resource's current state. duckv1.Status `json:",inline"` } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ConfigMapPropagationList is a collection of EventTypes. +type ConfigMapPropagationList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []ConfigMapPropagation `json:"items"` +} + +// GetGroupVersionKind returns GroupVersionKind for EventType +func (p *ConfigMapPropagation) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("EventType") +} + +// GetUntypedSpec returns the spec of the EventType. +func (e *ConfigMapPropagation) GetUntypedSpec() interface{} { + return e.Spec +} diff --git a/pkg/apis/configs/v1alpha1/register.go b/pkg/apis/configs/v1alpha1/register.go index 1c267880d8d..7460a266590 100644 --- a/pkg/apis/configs/v1alpha1/register.go +++ b/pkg/apis/configs/v1alpha1/register.go @@ -1 +1,53 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + //metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + // + //"k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/eventing/pkg/apis/configs" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: configs.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +//var ( +// SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) +// AddToScheme = SchemeBuilder.AddToScheme +//) + +//// Adds the list of known types to Scheme. +//func addKnownTypes(scheme *runtime.Scheme) error { +// scheme.AddKnownTypes(SchemeGroupVersion, +// &ConfigMapPropagation{}, +// &ConfigMapPropagationList{}, +// ) +// metav1.AddToGroupVersion(scheme, SchemeGroupVersion) +// return nil +//} From 610ac33c131fba29debc3adc51649dcff682946b Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 11 Dec 2019 14:42:14 -0800 Subject: [PATCH 03/26] API-3 --- config/300-configmappropagation.yaml | 2 +- .../v1alpha1/configmappropagation_defaults.go | 29 +++ .../configmappropagation_defaults_test.go | 57 +++++ .../configmappropagation_lifecycle.go | 54 +++++ .../configmappropagation_lifecycle_test.go | 204 ++++++++++++++++++ .../v1alpha1/configmappropagation_types.go | 37 ++-- .../configmappropagation_types_test.go | 27 +++ .../configmappropagation_validation.go | 62 ++++++ .../configmappropagation_validation_test.go | 144 +++++++++++++ pkg/apis/configs/v1alpha1/register.go | 36 ++-- pkg/apis/configs/v1alpha1/register_test.go | 66 ++++++ .../configs/v1alpha1/zz_generated.deepcopy.go | 119 ++++++++++ pkg/client/clientset/versioned/clientset.go | 14 ++ .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 2 + .../clientset/versioned/scheme/register.go | 2 + .../configs/v1alpha1/configmappropagation.go | 191 ++++++++++++++++ .../typed/configs/v1alpha1/configs_client.go | 89 ++++++++ .../versioned/typed/configs/v1alpha1/doc.go | 20 ++ .../typed/configs/v1alpha1/fake/doc.go | 20 ++ .../fake/fake_configmappropagation.go | 140 ++++++++++++ .../v1alpha1/fake/fake_configs_client.go | 40 ++++ .../configs/v1alpha1/generated_expansion.go | 21 ++ .../externalversions/configs/interface.go | 46 ++++ .../configs/v1alpha1/configmappropagation.go | 89 ++++++++ .../configs/v1alpha1/interface.go | 45 ++++ .../informers/externalversions/factory.go | 6 + .../informers/externalversions/generic.go | 15 +- .../configmappropagation.go | 52 +++++ .../configmappropagation/fake/fake.go | 40 ++++ .../configs/v1alpha1/configmappropagation.go | 94 ++++++++ .../configs/v1alpha1/expansion_generated.go | 27 +++ 32 files changed, 1756 insertions(+), 41 deletions(-) create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_defaults.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_types_test.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_validation.go create mode 100644 pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go create mode 100644 pkg/apis/configs/v1alpha1/register_test.go create mode 100644 pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go create mode 100644 pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go create mode 100644 pkg/client/informers/externalversions/configs/interface.go create mode 100644 pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go create mode 100644 pkg/client/informers/externalversions/configs/v1alpha1/interface.go create mode 100644 pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go create mode 100644 pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go create mode 100644 pkg/client/listers/configs/v1alpha1/configmappropagation.go create mode 100644 pkg/client/listers/configs/v1alpha1/expansion_generated.go diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index 4fbde6fc904..479a1bf38cc 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -37,7 +37,7 @@ spec: subresources: status: {} additionalPrinterColumns: - - name: Propagated + - name: Ready type: string JSONPath: ".status.conditions[?(@.type==\"Ready\")].status" - name: Reason diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go new file mode 100644 index 00000000000..895ab789cd8 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go @@ -0,0 +1,29 @@ +/* +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 v1alpha1 + +import ( + "context" +) + +func (cmp *ConfigMapPropagation) SetDefaults(ctx context.Context) { + // If we haven't configured the original namespace, + // then set the default original namespace to the knative-eventing. + if cmp != nil && cmp.Spec.OriginalNamespace == "" { + cmp.Spec.OriginalNamespace = "knative-eventing" + } +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go new file mode 100644 index 00000000000..f6130d62d4e --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -0,0 +1,57 @@ +/* +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 v1alpha1 + +import ( + "context" + "github.com/google/go-cmp/cmp" + "testing" +) + +var ( + defaultNamespace = "knative-eventing" + otherNamespace = "testing-eventing" + selector = "knative.dev/testing: eventing" +) + +func TestConfigMapPropagationDefaults(t *testing.T) { + testCases := map[string]struct { + initial ConfigMapPropagation + expected ConfigMapPropagation + }{ + "nil spec": { + initial: ConfigMapPropagation{}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: defaultNamespace}}, + }, + "original namespace empty": { + initial: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: selector}}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: defaultNamespace, Selector: selector}}, + }, + "with namespace": { + initial: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: otherNamespace}}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: otherNamespace}}, + }, + } + for n, tc := range testCases { + t.Run(n, func(t *testing.T) { + tc.initial.SetDefaults(context.TODO()) + if diff := cmp.Diff(tc.expected, tc.initial); diff != "" { + t.Fatalf("Unexpected defaults (-want, +got): %s", diff) + } + }) + } +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go new file mode 100644 index 00000000000..c0f8077ecc0 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -0,0 +1,54 @@ +/* +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 v1alpha1 + +import ( + "knative.dev/pkg/apis" +) + +var configMapPropagationCondSet = apis.NewLivingConditionSet(ConfigMapPropagationConditionReady, ConfigMapPropagationConditionPropagated) + +const ( + // ConfigMapPropagationConditionReay has status True when all subconditions below have been set to True. + ConfigMapPropagationConditionReady = apis.ConditionReady + // ConfigMapPropagationConditionPropagated has status True when the ConfigMaps in original namespace are all propagated to target namespace. + ConfigMapPropagationConditionPropagated apis.ConditionType = "ConfigMapPropagated" +) + +// GetCondition returns the condition currently associated with the given type, or nil. +func (cmps *ConfigMapPropagationStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return configMapPropagationCondSet.Manage(cmps).GetCondition(t) +} + +// IsReady returns true if the resource is ready overall. +func (cmps *ConfigMapPropagationStatus) IsReady() bool { + return configMapPropagationCondSet.Manage(cmps).IsHappy() +} + +// InitializeConditions sets relevant unset conditions to Unknown state. +func (cmps *ConfigMapPropagationStatus) InitializeConditions() { + configMapPropagationCondSet.Manage(cmps).InitializeConditions() +} + +func (cmps *ConfigMapPropagationStatus) MarkConfigMapPropagationPropagated() { + configMapPropagationCondSet.Manage(cmps).MarkTrue(ConfigMapPropagationConditionPropagated) +} + +func (cmps *ConfigMapPropagationStatus) MarkConfigMapPropagationNotPropagated() { + configMapPropagationCondSet.Manage(cmps).MarkFalse(ConfigMapPropagationConditionPropagated, "PropagationFailed", + "ConfigMapPropagation does not propagate ConfigMaps from original namespace to target namespace") +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go new file mode 100644 index 00000000000..0b8cf1dece7 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -0,0 +1,204 @@ +/* +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 v1alpha1 + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +var ( + trueValue = true + falseValue = false +) + +var ignoreAllButTypeAndStatus = cmpopts.IgnoreFields( + apis.Condition{}, + "LastTransitionTime", "Message", "Reason", "Severity") + +var ( + configMapPropagationConditionReady = apis.Condition{ + Type: ConfigMapPropagationConditionReady, + Status: corev1.ConditionTrue, + } + + configMapPropagationConditionPropagated = apis.Condition{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionTrue, + } +) + +func TestConfigMapPropagationGetCondition(t *testing.T) { + tests := []struct { + name string + cmps *ConfigMapPropagationStatus + condQuery apis.ConditionType + want *apis.Condition + }{{ + name: "single condition", + cmps: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{ + configMapPropagationConditionReady, + }, + }, + }, + condQuery: apis.ConditionReady, + want: &configMapPropagationConditionReady, + }, { + name: "multiple conditions", + cmps: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{ + configMapPropagationConditionPropagated, + }, + }, + }, + condQuery: ConfigMapPropagationConditionPropagated, + want: &configMapPropagationConditionPropagated, + }, { + name: "unknown condition", + cmps: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{ + configMapPropagationConditionPropagated, + }, + }, + }, + condQuery: apis.ConditionType("foo"), + want: nil, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.cmps.GetCondition(test.condQuery) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("unexpected condition (-want, +got) = %v", diff) + } + }) + } +} + +func TestConfigMapPropagationInitializeConditions(t *testing.T) { + tests := []struct { + name string + cmps *ConfigMapPropagationStatus + want *ConfigMapPropagationStatus + }{{ + name: "empty", + cmps: &ConfigMapPropagationStatus{}, + want: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionUnknown, + }, { + Type: ConfigMapPropagationConditionReady, + Status: corev1.ConditionUnknown, + }}, + }, + }, + }, { + name: "one false", + cmps: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionFalse, + }}, + }, + }, + want: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionFalse, + }, { + Type: ConfigMapPropagationConditionReady, + Status: corev1.ConditionUnknown, + }}, + }, + }, + }, { + name: "one true", + cmps: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionTrue, + }}, + }, + }, + want: &ConfigMapPropagationStatus{ + Status: duckv1.Status{ + Conditions: []apis.Condition{{ + Type: ConfigMapPropagationConditionPropagated, + Status: corev1.ConditionTrue, + }, { + Type: ConfigMapPropagationConditionReady, + Status: corev1.ConditionUnknown, + }}, + }, + }, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.cmps.InitializeConditions() + if diff := cmp.Diff(test.want, test.cmps, ignoreAllButTypeAndStatus); diff != "" { + t.Errorf("unexpected conditions (-want, +got) = %v", diff) + } + }) + } +} + +func TestConfigMapPropagationIsReady(t *testing.T) { + tests := []struct { + name string + markPropagation *bool + wantReady bool + }{{ + name: "all happy", + markPropagation: &trueValue, + wantReady: true, + }, { + name: "propagation sad", + markPropagation: &falseValue, + wantReady: false, + }} + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cmps := &ConfigMapPropagationStatus{} + if test.markPropagation != nil { + if *test.markPropagation { + cmps.MarkConfigMapPropagationPropagated() + } else { + cmps.MarkConfigMapPropagationNotPropagated() + } + } + got := cmps.IsReady() + if test.wantReady != got { + t.Errorf("unexpected readiness: want %v, got %v", test.wantReady, got) + } + }) + } +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 20cc0a42ee5..08d7f45ce44 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -18,8 +18,11 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/kmeta" ) // +genclient @@ -40,19 +43,19 @@ type ConfigMapPropagation struct { Status ConfigMapPropagationStatus `json:"status,omitempty"` } -//var ( -// // Check that ConfigMapPropagation can be validated, can be defaulted, and has immutable fields. -// _ apis.Validatable = (*ConfigMapPropagation)(nil) -// _ apis.Defaultable = (*ConfigMapPropagation)(nil) -// -// // Check that EventType can return its spec untyped. -// _ apis.HasSpec = (*ConfigMapPropagation)(nil) -// -// _ runtime.Object = (*ConfigMapPropagation)(nil) -// -// // Check that we can create OwnerReferences to an EventType. -// _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) -//) +var ( + // Check that ConfigMapPropagation can be validated, can be defaulted, and has immutable fields. + _ apis.Validatable = (*ConfigMapPropagation)(nil) + _ apis.Defaultable = (*ConfigMapPropagation)(nil) + + // Check that ConfigMapPropagation can return its spec untyped. + _ apis.HasSpec = (*ConfigMapPropagation)(nil) + + _ runtime.Object = (*ConfigMapPropagation)(nil) + + // Check that we can create OwnerReferences to an ConfigMapPropagation. + _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) +) type ConfigMapPropagationSpec struct { // OriginalNamespace represents the namespace where the original configMaps are in @@ -80,11 +83,11 @@ type ConfigMapPropagationList struct { } // GetGroupVersionKind returns GroupVersionKind for EventType -func (p *ConfigMapPropagation) GetGroupVersionKind() schema.GroupVersionKind { - return SchemeGroupVersion.WithKind("EventType") +func (cmp *ConfigMapPropagation) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("ConfigMapPropagation") } // GetUntypedSpec returns the spec of the EventType. -func (e *ConfigMapPropagation) GetUntypedSpec() interface{} { - return e.Spec +func (cmp *ConfigMapPropagation) GetUntypedSpec() interface{} { + return cmp.Spec } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go new file mode 100644 index 00000000000..3117d21ca95 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go @@ -0,0 +1,27 @@ +/* + * 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 v1alpha1 + +import "testing" + +func TestConfigMapPropagation_GetGroupVersionKind(t *testing.T) { + b := ConfigMapPropagation{} + gvk := b.GetGroupVersionKind() + if gvk.Kind != "ConfigMapPropagation" { + t.Errorf("Should be ConfigMapPropagation.") + } +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go new file mode 100644 index 00000000000..dc38f1c4456 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -0,0 +1,62 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + "context" + "knative.dev/pkg/apis" + "knative.dev/pkg/kmp" +) + +func (cmp *ConfigMapPropagation) Validate(ctx context.Context) *apis.FieldError { + return cmp.Spec.Validate(ctx).ViaField("spec") +} + +func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldError { + var errs *apis.FieldError + if cmps.OriginalNamespace == "" { + fe := apis.ErrMissingField("originalNamespace") + errs = errs.Also(fe) + } + if cmps.Selector == "" { + fe := apis.ErrMissingField("selector") + errs = errs.Also(fe) + } + // TODO validate selector must be in right format + return errs +} + +func (cmp *ConfigMapPropagation) CheckImmutableFields(ctx context.Context, original *ConfigMapPropagation) *apis.FieldError { + if original == nil { + return nil + } + + if diff, err := kmp.ShortDiff(original.Spec, cmp.Spec); err != nil { + return &apis.FieldError{ + Message: "Failed to diff ConfigMapPropagation", + Paths: []string{"spec"}, + Details: err.Error(), + } + } else if diff != "" { + return &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: diff, + } + } + return nil +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go new file mode 100644 index 00000000000..666677fe304 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -0,0 +1,144 @@ +/* +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 v1alpha1 + +import ( + "context" + "github.com/google/go-cmp/cmp" + "knative.dev/pkg/apis" + "testing" +) + +var ( + originalNamespace = "original" + currentNamespace = "current" + validSelector = " " +) + +func TestConfigMapPropagationValidation(t *testing.T) { + tests := []struct { + name string + cmp *ConfigMapPropagation + want *apis.FieldError + }{{ + name: "empty configmappropagation spec", + cmp: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{}}, + want: &apis.FieldError{ + Paths: []string{"spec.originalNamespace, spec.selector"}, + Message: "missing field(s)", + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.cmp.Validate(context.TODO()) + if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" { + t.Errorf("ConfigMapPropagation.Validate (-want, +got) = %v", diff) + } + }) + } +} + +func TestConfigMapPropagationSpecValidation(t *testing.T) { + tests := []struct { + name string + cmps *ConfigMapPropagationSpec + want *apis.FieldError + }{{ + name: "missing configmappropagation spec", + cmps: &ConfigMapPropagationSpec{}, + want: func() *apis.FieldError { + fe := apis.ErrMissingField("originalNamespace", "selector") + return fe + }(), + }, { + name: "missing original namespace", + cmps: &ConfigMapPropagationSpec{OriginalNamespace: originalNamespace}, + want: func() *apis.FieldError { + fe := apis.ErrMissingField("selector") + return fe + }(), + }, { + name: "missing selector", + cmps: &ConfigMapPropagationSpec{Selector: validSelector}, + want: func() *apis.FieldError { + fe := apis.ErrMissingField("originalNamespace") + return fe + }(), + }, + //TODO invalid selectors + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.cmps.Validate(context.TODO()) + if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" { + t.Errorf("%s: Validate ConfigMapPropagationSpec (-want, +got) = %v", test.name, diff) + } + }) + } +} + +func TestConfigMapPropagationImmutableFields(t *testing.T) { + tests := []struct { + name string + current *ConfigMapPropagation + original *ConfigMapPropagation + want *apis.FieldError + }{{ + name: "good (no change)", + current: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{ + OriginalNamespace: currentNamespace, + }}, + original: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{ + OriginalNamespace: currentNamespace, + }}, + want: nil, + }, { + name: "new nil is ok", + current: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{ + OriginalNamespace: currentNamespace, + }}, + original: nil, + want: nil, + }, { + name: "bad (spec change)", + current: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{ + OriginalNamespace: currentNamespace, + }}, + original: &ConfigMapPropagation{Spec: ConfigMapPropagationSpec{ + OriginalNamespace: originalNamespace, + }}, + want: &apis.FieldError{ + Message: "Immutable fields changed (-old +new)", + Paths: []string{"spec"}, + Details: `{v1alpha1.ConfigMapPropagationSpec}.OriginalNamespace: + -: "original" + +: "current" +`, + }, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + gotErr := test.current.CheckImmutableFields(context.Background(), test.original) + if diff := cmp.Diff(test.want.Error(), gotErr.Error()); diff != "" { + t.Errorf("CheckImmutableFields (-want, +got) = %v", diff) + } + }) + } +} diff --git a/pkg/apis/configs/v1alpha1/register.go b/pkg/apis/configs/v1alpha1/register.go index 7460a266590..cd1bdb3638f 100644 --- a/pkg/apis/configs/v1alpha1/register.go +++ b/pkg/apis/configs/v1alpha1/register.go @@ -17,11 +17,11 @@ limitations under the License. package v1alpha1 import ( - //metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - // - //"k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" "knative.dev/eventing/pkg/apis/configs" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) // SchemeGroupVersion is group version used to register these objects @@ -37,17 +37,17 @@ func Resource(resource string) schema.GroupResource { return SchemeGroupVersion.WithResource(resource).GroupResource() } -//var ( -// SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) -// AddToScheme = SchemeBuilder.AddToScheme -//) - -//// Adds the list of known types to Scheme. -//func addKnownTypes(scheme *runtime.Scheme) error { -// scheme.AddKnownTypes(SchemeGroupVersion, -// &ConfigMapPropagation{}, -// &ConfigMapPropagationList{}, -// ) -// metav1.AddToGroupVersion(scheme, SchemeGroupVersion) -// return nil -//} +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &ConfigMapPropagation{}, + &ConfigMapPropagationList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/configs/v1alpha1/register_test.go b/pkg/apis/configs/v1alpha1/register_test.go new file mode 100644 index 00000000000..e04cafbc1e9 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/register_test.go @@ -0,0 +1,66 @@ +/* +Copyright 2018 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 v1alpha1 + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func TestResource(t *testing.T) { + want := schema.GroupResource{ + Group: "configs.knative.dev", + Resource: "foo", + } + + got := Resource("foo") + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected resource (-want, +got) = %v", diff) + } +} + +// Kind takes an unqualified resource and returns a Group qualified GroupKind +func TestKind(t *testing.T) { + want := schema.GroupKind{ + Group: "configs.knative.dev", + Kind: "kind", + } + + got := Kind("kind") + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("unexpected resource (-want, +got) = %v", diff) + } +} + +// TestKnownTypes makes sure that expected types get added. +func TestKnownTypes(t *testing.T) { + scheme := runtime.NewScheme() + addKnownTypes(scheme) + types := scheme.KnownTypes(SchemeGroupVersion) + + for _, name := range []string{ + "ConfigMapPropagation", + "ConfigMapPropagationList", + } { + if _, ok := types[name]; !ok { + t.Errorf("Did not find %q as registered type", name) + } + } + +} diff --git a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..156d1b56554 --- /dev/null +++ b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,119 @@ +// +build !ignore_autogenerated + +/* +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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapPropagation) DeepCopyInto(out *ConfigMapPropagation) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapPropagation. +func (in *ConfigMapPropagation) DeepCopy() *ConfigMapPropagation { + if in == nil { + return nil + } + out := new(ConfigMapPropagation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConfigMapPropagation) 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 *ConfigMapPropagationList) DeepCopyInto(out *ConfigMapPropagationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ConfigMapPropagation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapPropagationList. +func (in *ConfigMapPropagationList) DeepCopy() *ConfigMapPropagationList { + if in == nil { + return nil + } + out := new(ConfigMapPropagationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConfigMapPropagationList) 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 *ConfigMapPropagationSpec) DeepCopyInto(out *ConfigMapPropagationSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapPropagationSpec. +func (in *ConfigMapPropagationSpec) DeepCopy() *ConfigMapPropagationSpec { + if in == nil { + return nil + } + out := new(ConfigMapPropagationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapPropagationStatus) DeepCopyInto(out *ConfigMapPropagationStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapPropagationStatus. +func (in *ConfigMapPropagationStatus) DeepCopy() *ConfigMapPropagationStatus { + if in == nil { + return nil + } + out := new(ConfigMapPropagationStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 7315a7ac9a7..56c03f40c09 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -22,6 +22,7 @@ import ( discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" + configsv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/configs/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1alpha1" @@ -30,6 +31,7 @@ import ( type Interface interface { Discovery() discovery.DiscoveryInterface + ConfigsV1alpha1() configsv1alpha1.ConfigsV1alpha1Interface EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface FlowsV1alpha1() flowsv1alpha1.FlowsV1alpha1Interface MessagingV1alpha1() messagingv1alpha1.MessagingV1alpha1Interface @@ -40,12 +42,18 @@ type Interface interface { // version included in a Clientset. type Clientset struct { *discovery.DiscoveryClient + configsV1alpha1 *configsv1alpha1.ConfigsV1alpha1Client eventingV1alpha1 *eventingv1alpha1.EventingV1alpha1Client flowsV1alpha1 *flowsv1alpha1.FlowsV1alpha1Client messagingV1alpha1 *messagingv1alpha1.MessagingV1alpha1Client sourcesV1alpha1 *sourcesv1alpha1.SourcesV1alpha1Client } +// ConfigsV1alpha1 retrieves the ConfigsV1alpha1Client +func (c *Clientset) ConfigsV1alpha1() configsv1alpha1.ConfigsV1alpha1Interface { + return c.configsV1alpha1 +} + // EventingV1alpha1 retrieves the EventingV1alpha1Client func (c *Clientset) EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface { return c.eventingV1alpha1 @@ -82,6 +90,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { } var cs Clientset var err error + cs.configsV1alpha1, err = configsv1alpha1.NewForConfig(&configShallowCopy) + if err != nil { + return nil, err + } cs.eventingV1alpha1, err = eventingv1alpha1.NewForConfig(&configShallowCopy) if err != nil { return nil, err @@ -110,6 +122,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { // panics if there is an error in the config. func NewForConfigOrDie(c *rest.Config) *Clientset { var cs Clientset + cs.configsV1alpha1 = configsv1alpha1.NewForConfigOrDie(c) cs.eventingV1alpha1 = eventingv1alpha1.NewForConfigOrDie(c) cs.flowsV1alpha1 = flowsv1alpha1.NewForConfigOrDie(c) cs.messagingV1alpha1 = messagingv1alpha1.NewForConfigOrDie(c) @@ -122,6 +135,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { // New creates a new Clientset for the given RESTClient. func New(c rest.Interface) *Clientset { var cs Clientset + cs.configsV1alpha1 = configsv1alpha1.New(c) cs.eventingV1alpha1 = eventingv1alpha1.New(c) cs.flowsV1alpha1 = flowsv1alpha1.New(c) cs.messagingV1alpha1 = messagingv1alpha1.New(c) diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 9b1def4c3c6..889baefa076 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -25,6 +25,8 @@ import ( fakediscovery "k8s.io/client-go/discovery/fake" "k8s.io/client-go/testing" clientset "knative.dev/eventing/pkg/client/clientset/versioned" + configsv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/configs/v1alpha1" + fakeconfigsv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake" eventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1" fakeeventingv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1alpha1/fake" flowsv1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/flows/v1alpha1" @@ -82,6 +84,11 @@ func (c *Clientset) Tracker() testing.ObjectTracker { var _ clientset.Interface = &Clientset{} +// ConfigsV1alpha1 retrieves the ConfigsV1alpha1Client +func (c *Clientset) ConfigsV1alpha1() configsv1alpha1.ConfigsV1alpha1Interface { + return &fakeconfigsv1alpha1.FakeConfigsV1alpha1{Fake: &c.Fake} +} + // EventingV1alpha1 retrieves the EventingV1alpha1Client func (c *Clientset) EventingV1alpha1() eventingv1alpha1.EventingV1alpha1Interface { return &fakeeventingv1alpha1.FakeEventingV1alpha1{Fake: &c.Fake} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index 0db5432ae03..b7b1d2a09f1 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -24,6 +24,7 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" @@ -34,6 +35,7 @@ var scheme = runtime.NewScheme() var codecs = serializer.NewCodecFactory(scheme) var parameterCodec = runtime.NewParameterCodec(scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + configsv1alpha1.AddToScheme, eventingv1alpha1.AddToScheme, flowsv1alpha1.AddToScheme, messagingv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 9c2239c0dd7..3073091aa24 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -24,6 +24,7 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" serializer "k8s.io/apimachinery/pkg/runtime/serializer" utilruntime "k8s.io/apimachinery/pkg/util/runtime" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" @@ -34,6 +35,7 @@ var Scheme = runtime.NewScheme() var Codecs = serializer.NewCodecFactory(Scheme) var ParameterCodec = runtime.NewParameterCodec(Scheme) var localSchemeBuilder = runtime.SchemeBuilder{ + configsv1alpha1.AddToScheme, eventingv1alpha1.AddToScheme, flowsv1alpha1.AddToScheme, messagingv1alpha1.AddToScheme, diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go new file mode 100644 index 00000000000..d8e29c04011 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go @@ -0,0 +1,191 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" + scheme "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +// ConfigMapPropagationsGetter has a method to return a ConfigMapPropagationInterface. +// A group's client should implement this interface. +type ConfigMapPropagationsGetter interface { + ConfigMapPropagations(namespace string) ConfigMapPropagationInterface +} + +// ConfigMapPropagationInterface has methods to work with ConfigMapPropagation resources. +type ConfigMapPropagationInterface interface { + Create(*v1alpha1.ConfigMapPropagation) (*v1alpha1.ConfigMapPropagation, error) + Update(*v1alpha1.ConfigMapPropagation) (*v1alpha1.ConfigMapPropagation, error) + UpdateStatus(*v1alpha1.ConfigMapPropagation) (*v1alpha1.ConfigMapPropagation, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.ConfigMapPropagation, error) + List(opts v1.ListOptions) (*v1alpha1.ConfigMapPropagationList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ConfigMapPropagation, err error) + ConfigMapPropagationExpansion +} + +// configMapPropagations implements ConfigMapPropagationInterface +type configMapPropagations struct { + client rest.Interface + ns string +} + +// newConfigMapPropagations returns a ConfigMapPropagations +func newConfigMapPropagations(c *ConfigsV1alpha1Client, namespace string) *configMapPropagations { + return &configMapPropagations{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the configMapPropagation, and returns the corresponding configMapPropagation object, and an error if there is any. +func (c *configMapPropagations) Get(name string, options v1.GetOptions) (result *v1alpha1.ConfigMapPropagation, err error) { + result = &v1alpha1.ConfigMapPropagation{} + err = c.client.Get(). + Namespace(c.ns). + Resource("configmappropagations"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ConfigMapPropagations that match those selectors. +func (c *configMapPropagations) List(opts v1.ListOptions) (result *v1alpha1.ConfigMapPropagationList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ConfigMapPropagationList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("configmappropagations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested configMapPropagations. +func (c *configMapPropagations) Watch(opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("configmappropagations"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch() +} + +// Create takes the representation of a configMapPropagation and creates it. Returns the server's representation of the configMapPropagation, and an error, if there is any. +func (c *configMapPropagations) Create(configMapPropagation *v1alpha1.ConfigMapPropagation) (result *v1alpha1.ConfigMapPropagation, err error) { + result = &v1alpha1.ConfigMapPropagation{} + err = c.client.Post(). + Namespace(c.ns). + Resource("configmappropagations"). + Body(configMapPropagation). + Do(). + Into(result) + return +} + +// Update takes the representation of a configMapPropagation and updates it. Returns the server's representation of the configMapPropagation, and an error, if there is any. +func (c *configMapPropagations) Update(configMapPropagation *v1alpha1.ConfigMapPropagation) (result *v1alpha1.ConfigMapPropagation, err error) { + result = &v1alpha1.ConfigMapPropagation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("configmappropagations"). + Name(configMapPropagation.Name). + Body(configMapPropagation). + Do(). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + +func (c *configMapPropagations) UpdateStatus(configMapPropagation *v1alpha1.ConfigMapPropagation) (result *v1alpha1.ConfigMapPropagation, err error) { + result = &v1alpha1.ConfigMapPropagation{} + err = c.client.Put(). + Namespace(c.ns). + Resource("configmappropagations"). + Name(configMapPropagation.Name). + SubResource("status"). + Body(configMapPropagation). + Do(). + Into(result) + return +} + +// Delete takes name of the configMapPropagation and deletes it. Returns an error if one occurs. +func (c *configMapPropagations) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("configmappropagations"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *configMapPropagations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + var timeout time.Duration + if listOptions.TimeoutSeconds != nil { + timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("configmappropagations"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Timeout(timeout). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched configMapPropagation. +func (c *configMapPropagations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ConfigMapPropagation, err error) { + result = &v1alpha1.ConfigMapPropagation{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("configmappropagations"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go new file mode 100644 index 00000000000..234ae8e2ad3 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go @@ -0,0 +1,89 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + rest "k8s.io/client-go/rest" + v1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" +) + +type ConfigsV1alpha1Interface interface { + RESTClient() rest.Interface + ConfigMapPropagationsGetter +} + +// ConfigsV1alpha1Client is used to interact with features provided by the configs.knative.dev group. +type ConfigsV1alpha1Client struct { + restClient rest.Interface +} + +func (c *ConfigsV1alpha1Client) ConfigMapPropagations(namespace string) ConfigMapPropagationInterface { + return newConfigMapPropagations(c, namespace) +} + +// NewForConfig creates a new ConfigsV1alpha1Client for the given config. +func NewForConfig(c *rest.Config) (*ConfigsV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientFor(&config) + if err != nil { + return nil, err + } + return &ConfigsV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new ConfigsV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *ConfigsV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new ConfigsV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *ConfigsV1alpha1Client { + return &ConfigsV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *ConfigsV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go new file mode 100644 index 00000000000..a1c6bb9fe8f --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go new file mode 100644 index 00000000000..a00e5d7b21a --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go new file mode 100644 index 00000000000..8f37589d0aa --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go @@ -0,0 +1,140 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" + v1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" +) + +// FakeConfigMapPropagations implements ConfigMapPropagationInterface +type FakeConfigMapPropagations struct { + Fake *FakeConfigsV1alpha1 + ns string +} + +var configmappropagationsResource = schema.GroupVersionResource{Group: "configs.knative.dev", Version: "v1alpha1", Resource: "configmappropagations"} + +var configmappropagationsKind = schema.GroupVersionKind{Group: "configs.knative.dev", Version: "v1alpha1", Kind: "ConfigMapPropagation"} + +// Get takes name of the configMapPropagation, and returns the corresponding configMapPropagation object, and an error if there is any. +func (c *FakeConfigMapPropagations) Get(name string, options v1.GetOptions) (result *v1alpha1.ConfigMapPropagation, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(configmappropagationsResource, c.ns, name), &v1alpha1.ConfigMapPropagation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ConfigMapPropagation), err +} + +// List takes label and field selectors, and returns the list of ConfigMapPropagations that match those selectors. +func (c *FakeConfigMapPropagations) List(opts v1.ListOptions) (result *v1alpha1.ConfigMapPropagationList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(configmappropagationsResource, configmappropagationsKind, c.ns, opts), &v1alpha1.ConfigMapPropagationList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ConfigMapPropagationList{ListMeta: obj.(*v1alpha1.ConfigMapPropagationList).ListMeta} + for _, item := range obj.(*v1alpha1.ConfigMapPropagationList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested configMapPropagations. +func (c *FakeConfigMapPropagations) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(configmappropagationsResource, c.ns, opts)) + +} + +// Create takes the representation of a configMapPropagation and creates it. Returns the server's representation of the configMapPropagation, and an error, if there is any. +func (c *FakeConfigMapPropagations) Create(configMapPropagation *v1alpha1.ConfigMapPropagation) (result *v1alpha1.ConfigMapPropagation, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(configmappropagationsResource, c.ns, configMapPropagation), &v1alpha1.ConfigMapPropagation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ConfigMapPropagation), err +} + +// Update takes the representation of a configMapPropagation and updates it. Returns the server's representation of the configMapPropagation, and an error, if there is any. +func (c *FakeConfigMapPropagations) Update(configMapPropagation *v1alpha1.ConfigMapPropagation) (result *v1alpha1.ConfigMapPropagation, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(configmappropagationsResource, c.ns, configMapPropagation), &v1alpha1.ConfigMapPropagation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ConfigMapPropagation), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeConfigMapPropagations) UpdateStatus(configMapPropagation *v1alpha1.ConfigMapPropagation) (*v1alpha1.ConfigMapPropagation, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(configmappropagationsResource, "status", c.ns, configMapPropagation), &v1alpha1.ConfigMapPropagation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ConfigMapPropagation), err +} + +// Delete takes name of the configMapPropagation and deletes it. Returns an error if one occurs. +func (c *FakeConfigMapPropagations) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(configmappropagationsResource, c.ns, name), &v1alpha1.ConfigMapPropagation{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeConfigMapPropagations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(configmappropagationsResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.ConfigMapPropagationList{}) + return err +} + +// Patch applies the patch and returns the patched configMapPropagation. +func (c *FakeConfigMapPropagations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ConfigMapPropagation, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(configmappropagationsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ConfigMapPropagation{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ConfigMapPropagation), err +} diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go new file mode 100644 index 00000000000..f557cf3e2c5 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go @@ -0,0 +1,40 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" + v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/configs/v1alpha1" +) + +type FakeConfigsV1alpha1 struct { + *testing.Fake +} + +func (c *FakeConfigsV1alpha1) ConfigMapPropagations(namespace string) v1alpha1.ConfigMapPropagationInterface { + return &FakeConfigMapPropagations{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeConfigsV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go new file mode 100644 index 00000000000..978ee9a77f8 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go @@ -0,0 +1,21 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type ConfigMapPropagationExpansion interface{} diff --git a/pkg/client/informers/externalversions/configs/interface.go b/pkg/client/informers/externalversions/configs/interface.go new file mode 100644 index 00000000000..8110f0edbec --- /dev/null +++ b/pkg/client/informers/externalversions/configs/interface.go @@ -0,0 +1,46 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package configs + +import ( + v1alpha1 "knative.dev/eventing/pkg/client/informers/externalversions/configs/v1alpha1" + internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go b/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go new file mode 100644 index 00000000000..e85aa1edcbf --- /dev/null +++ b/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go @@ -0,0 +1,89 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" + versioned "knative.dev/eventing/pkg/client/clientset/versioned" + internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "knative.dev/eventing/pkg/client/listers/configs/v1alpha1" +) + +// ConfigMapPropagationInformer provides access to a shared informer and lister for +// ConfigMapPropagations. +type ConfigMapPropagationInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ConfigMapPropagationLister +} + +type configMapPropagationInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewConfigMapPropagationInformer constructs a new informer for ConfigMapPropagation type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConfigMapPropagationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredConfigMapPropagationInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredConfigMapPropagationInformer constructs a new informer for ConfigMapPropagation type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredConfigMapPropagationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ConfigsV1alpha1().ConfigMapPropagations(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ConfigsV1alpha1().ConfigMapPropagations(namespace).Watch(options) + }, + }, + &configsv1alpha1.ConfigMapPropagation{}, + resyncPeriod, + indexers, + ) +} + +func (f *configMapPropagationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredConfigMapPropagationInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *configMapPropagationInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&configsv1alpha1.ConfigMapPropagation{}, f.defaultInformer) +} + +func (f *configMapPropagationInformer) Lister() v1alpha1.ConfigMapPropagationLister { + return v1alpha1.NewConfigMapPropagationLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/configs/v1alpha1/interface.go b/pkg/client/informers/externalversions/configs/v1alpha1/interface.go new file mode 100644 index 00000000000..7f699aadd55 --- /dev/null +++ b/pkg/client/informers/externalversions/configs/v1alpha1/interface.go @@ -0,0 +1,45 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ConfigMapPropagations returns a ConfigMapPropagationInformer. + ConfigMapPropagations() ConfigMapPropagationInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ConfigMapPropagations returns a ConfigMapPropagationInformer. +func (v *version) ConfigMapPropagations() ConfigMapPropagationInformer { + return &configMapPropagationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index e476d75ac48..6f8a36c221e 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -28,6 +28,7 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" versioned "knative.dev/eventing/pkg/client/clientset/versioned" + configs "knative.dev/eventing/pkg/client/informers/externalversions/configs" eventing "knative.dev/eventing/pkg/client/informers/externalversions/eventing" flows "knative.dev/eventing/pkg/client/informers/externalversions/flows" internalinterfaces "knative.dev/eventing/pkg/client/informers/externalversions/internalinterfaces" @@ -175,12 +176,17 @@ type SharedInformerFactory interface { ForResource(resource schema.GroupVersionResource) (GenericInformer, error) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + Configs() configs.Interface Eventing() eventing.Interface Flows() flows.Interface Messaging() messaging.Interface Sources() sources.Interface } +func (f *sharedInformerFactory) Configs() configs.Interface { + return configs.New(f, f.namespace, f.tweakListOptions) +} + func (f *sharedInformerFactory) Eventing() eventing.Interface { return eventing.New(f, f.namespace, f.tweakListOptions) } diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 23e33201a96..614630f2f9a 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -23,7 +23,8 @@ import ( schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" - v1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" + v1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" + eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" @@ -55,12 +56,16 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=eventing.knative.dev, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("brokers"): + // Group=configs.knative.dev, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("configmappropagations"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Configs().V1alpha1().ConfigMapPropagations().Informer()}, nil + + // Group=eventing.knative.dev, Version=v1alpha1 + case eventingv1alpha1.SchemeGroupVersion.WithResource("brokers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1alpha1().Brokers().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("eventtypes"): + case eventingv1alpha1.SchemeGroupVersion.WithResource("eventtypes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1alpha1().EventTypes().Informer()}, nil - case v1alpha1.SchemeGroupVersion.WithResource("triggers"): + case eventingv1alpha1.SchemeGroupVersion.WithResource("triggers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Eventing().V1alpha1().Triggers().Informer()}, nil // Group=flows.knative.dev, Version=v1alpha1 diff --git a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go new file mode 100644 index 00000000000..52776dd173f --- /dev/null +++ b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go @@ -0,0 +1,52 @@ +/* +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package configmappropagation + +import ( + "context" + + v1alpha1 "knative.dev/eventing/pkg/client/informers/externalversions/configs/v1alpha1" + factory "knative.dev/eventing/pkg/client/injection/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Configs().V1alpha1().ConfigMapPropagations() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1alpha1.ConfigMapPropagationInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/eventing/pkg/client/informers/externalversions/configs/v1alpha1.ConfigMapPropagationInformer from context.") + } + return untyped.(v1alpha1.ConfigMapPropagationInformer) +} diff --git a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go new file mode 100644 index 00000000000..cd0b6324351 --- /dev/null +++ b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go @@ -0,0 +1,40 @@ +/* +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + configmappropagation "knative.dev/eventing/pkg/client/injection/informers/configs/v1alpha1/configmappropagation" + fake "knative.dev/eventing/pkg/client/injection/informers/factory/fake" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" +) + +var Get = configmappropagation.Get + +func init() { + injection.Fake.RegisterInformer(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := fake.Get(ctx) + inf := f.Configs().V1alpha1().ConfigMapPropagations() + return context.WithValue(ctx, configmappropagation.Key{}, inf), inf.Informer() +} diff --git a/pkg/client/listers/configs/v1alpha1/configmappropagation.go b/pkg/client/listers/configs/v1alpha1/configmappropagation.go new file mode 100644 index 00000000000..abdbecd0724 --- /dev/null +++ b/pkg/client/listers/configs/v1alpha1/configmappropagation.go @@ -0,0 +1,94 @@ +/* +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" + v1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" +) + +// ConfigMapPropagationLister helps list ConfigMapPropagations. +type ConfigMapPropagationLister interface { + // List lists all ConfigMapPropagations in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.ConfigMapPropagation, err error) + // ConfigMapPropagations returns an object that can list and get ConfigMapPropagations. + ConfigMapPropagations(namespace string) ConfigMapPropagationNamespaceLister + ConfigMapPropagationListerExpansion +} + +// configMapPropagationLister implements the ConfigMapPropagationLister interface. +type configMapPropagationLister struct { + indexer cache.Indexer +} + +// NewConfigMapPropagationLister returns a new ConfigMapPropagationLister. +func NewConfigMapPropagationLister(indexer cache.Indexer) ConfigMapPropagationLister { + return &configMapPropagationLister{indexer: indexer} +} + +// List lists all ConfigMapPropagations in the indexer. +func (s *configMapPropagationLister) List(selector labels.Selector) (ret []*v1alpha1.ConfigMapPropagation, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ConfigMapPropagation)) + }) + return ret, err +} + +// ConfigMapPropagations returns an object that can list and get ConfigMapPropagations. +func (s *configMapPropagationLister) ConfigMapPropagations(namespace string) ConfigMapPropagationNamespaceLister { + return configMapPropagationNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ConfigMapPropagationNamespaceLister helps list and get ConfigMapPropagations. +type ConfigMapPropagationNamespaceLister interface { + // List lists all ConfigMapPropagations in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1alpha1.ConfigMapPropagation, err error) + // Get retrieves the ConfigMapPropagation from the indexer for a given namespace and name. + Get(name string) (*v1alpha1.ConfigMapPropagation, error) + ConfigMapPropagationNamespaceListerExpansion +} + +// configMapPropagationNamespaceLister implements the ConfigMapPropagationNamespaceLister +// interface. +type configMapPropagationNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ConfigMapPropagations in the indexer for a given namespace. +func (s configMapPropagationNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ConfigMapPropagation, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ConfigMapPropagation)) + }) + return ret, err +} + +// Get retrieves the ConfigMapPropagation from the indexer for a given namespace and name. +func (s configMapPropagationNamespaceLister) Get(name string) (*v1alpha1.ConfigMapPropagation, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("configmappropagation"), name) + } + return obj.(*v1alpha1.ConfigMapPropagation), nil +} diff --git a/pkg/client/listers/configs/v1alpha1/expansion_generated.go b/pkg/client/listers/configs/v1alpha1/expansion_generated.go new file mode 100644 index 00000000000..12e98d74c4c --- /dev/null +++ b/pkg/client/listers/configs/v1alpha1/expansion_generated.go @@ -0,0 +1,27 @@ +/* +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// ConfigMapPropagationListerExpansion allows custom methods to be added to +// ConfigMapPropagationLister. +type ConfigMapPropagationListerExpansion interface{} + +// ConfigMapPropagationNamespaceListerExpansion allows custom methods to be added to +// ConfigMapPropagationNamespaceLister. +type ConfigMapPropagationNamespaceListerExpansion interface{} From 183fbf614350b4ce8d7f4a38f55be72220818345 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Tue, 17 Dec 2019 14:08:30 -0800 Subject: [PATCH 04/26] Controller --- cmd/controller/main.go | 2 + ...200-addressable-resolvers-clusterrole.yaml | 21 + config/200-controller-clusterrole.yaml | 8 + config/300-configmappropagation.yaml | 10 +- .../configmappropagation_defaults_test.go | 4 +- .../configmappropagation_lifecycle.go | 4 +- .../configmappropagation_lifecycle_test.go | 2 + .../v1alpha1/configmappropagation_types.go | 19 +- .../configmappropagation_validation.go | 34 +- .../configmappropagation_validation_test.go | 36 +- .../configmappropagation.go | 318 +++++++++++++ .../configmappropagation_test.go | 436 ++++++++++++++++++ .../configmappropagation/controller.go | 71 +++ .../configmappropagation/controller_test.go | 40 ++ .../resources/configmap.go | 51 ++ .../resources/configmap_test.go | 77 ++++ .../configmappropagation/resources/labels.go | 28 ++ pkg/reconciler/testing/configmap.go | 62 +++ .../testing/configmappropagation.go | 69 +++ pkg/reconciler/testing/listers.go | 6 + 20 files changed, 1279 insertions(+), 19 deletions(-) create mode 100644 pkg/reconciler/configmappropagation/configmappropagation.go create mode 100644 pkg/reconciler/configmappropagation/configmappropagation_test.go create mode 100644 pkg/reconciler/configmappropagation/controller.go create mode 100644 pkg/reconciler/configmappropagation/controller_test.go create mode 100644 pkg/reconciler/configmappropagation/resources/configmap.go create mode 100644 pkg/reconciler/configmappropagation/resources/configmap_test.go create mode 100644 pkg/reconciler/configmappropagation/resources/labels.go create mode 100644 pkg/reconciler/testing/configmap.go create mode 100644 pkg/reconciler/testing/configmappropagation.go diff --git a/cmd/controller/main.go b/cmd/controller/main.go index b67125e476d..bbc8c0e6ea3 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -24,6 +24,7 @@ import ( "knative.dev/eventing/pkg/reconciler/broker" "knative.dev/eventing/pkg/reconciler/channel" + "knative.dev/eventing/pkg/reconciler/configmappropagation" "knative.dev/eventing/pkg/reconciler/eventtype" flowsparallel "knative.dev/eventing/pkg/reconciler/flowsparallel" flowssequence "knative.dev/eventing/pkg/reconciler/flowssequence" @@ -46,5 +47,6 @@ func main() { parallel.NewController, flowsparallel.NewController, flowssequence.NewController, + configmappropagation.NewController, ) } diff --git a/config/200-addressable-resolvers-clusterrole.yaml b/config/200-addressable-resolvers-clusterrole.yaml index b1d66f06edb..96ebe13551a 100644 --- a/config/200-addressable-resolvers-clusterrole.yaml +++ b/config/200-addressable-resolvers-clusterrole.yaml @@ -155,3 +155,24 @@ rules: - get - list - watch + +--- + +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: configs-addressable-resolver + labels: + eventing.knative.dev/release: devel + duck.knative.dev/addressable: "true" +# Do not use this role directly. These rules will be added to the "addressable-resolver" role. +rules: + - apiGroups: + - configs.knative.dev + resources: + - configmappropagations + - configmappropagations/status + verbs: + - get + - list + - watch diff --git a/config/200-controller-clusterrole.yaml b/config/200-controller-clusterrole.yaml index d8e8dcd8e84..f83e188c0df 100644 --- a/config/200-controller-clusterrole.yaml +++ b/config/200-controller-clusterrole.yaml @@ -86,6 +86,14 @@ rules: - "subscriptions/status" verbs: *everything + # config resources and statuses we care about. + - apiGroups: + - "configs.knative.dev" + resources: + - "configmappropagations" + - "configmappropagations/status" + verbs: *everything + # Flow resources and statuses we care about. - apiGroups: - "flows.knative.dev" diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index 479a1bf38cc..a1fb59cd7fb 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -15,7 +15,7 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: configmappropagation.configs.knative.dev + name: configmappropagations.configs.knative.dev labels: eventing.knative.dev/release: devel knative.dev/crd-install: "true" @@ -59,6 +59,10 @@ spec: properties: originalNamespace: type: string - description: "The namespace where original configmaps exist in." + description: "The namespace where original ConfigMaps exist in." selector: - type: string + type: object + description: "Map of selectors used for select specific group of ConfigMaps." + additionalProperties: + type: string + diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go index f6130d62d4e..b0f57d8aa08 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -25,7 +25,9 @@ import ( var ( defaultNamespace = "knative-eventing" otherNamespace = "testing-eventing" - selector = "knative.dev/testing: eventing" + selector = map[string]string{ + "knative.dev/testing": "eventing", + } ) func TestConfigMapPropagationDefaults(t *testing.T) { diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index c0f8077ecc0..1e72a4b1b01 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -23,7 +23,7 @@ import ( var configMapPropagationCondSet = apis.NewLivingConditionSet(ConfigMapPropagationConditionReady, ConfigMapPropagationConditionPropagated) const ( - // ConfigMapPropagationConditionReay has status True when all subconditions below have been set to True. + // ConfigMapPropagationConditionReady has status True when all subconditions below have been set to True. ConfigMapPropagationConditionReady = apis.ConditionReady // ConfigMapPropagationConditionPropagated has status True when the ConfigMaps in original namespace are all propagated to target namespace. ConfigMapPropagationConditionPropagated apis.ConditionType = "ConfigMapPropagated" @@ -50,5 +50,5 @@ func (cmps *ConfigMapPropagationStatus) MarkConfigMapPropagationPropagated() { func (cmps *ConfigMapPropagationStatus) MarkConfigMapPropagationNotPropagated() { configMapPropagationCondSet.Manage(cmps).MarkFalse(ConfigMapPropagationConditionPropagated, "PropagationFailed", - "ConfigMapPropagation does not propagate ConfigMaps from original namespace to target namespace") + "ConfigMapPropagation does not fully propagate ConfigMaps from original namespace to current namespace") } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index 0b8cf1dece7..6788f5bd4b0 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -21,7 +21,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + corev1 "k8s.io/api/core/v1" + "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" ) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 08d7f45ce44..63cb47685cf 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -20,6 +20,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" duckv1 "knative.dev/pkg/apis/duck/v1" "knative.dev/pkg/kmeta" @@ -28,9 +29,9 @@ import ( // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// ConfigMapPropagation is used to propagate configMaps from source namespace to target namespace +// ConfigMapPropagation is used to propagate configMaps from original namespace to current namespace type ConfigMapPropagation struct { - metav1.TypeMeta `json:". inline"` + metav1.TypeMeta `json:",inline"` // +optional metav1.ObjectMeta `json:"metadata,omitempty"` @@ -53,15 +54,15 @@ var ( _ runtime.Object = (*ConfigMapPropagation)(nil) - // Check that we can create OwnerReferences to an ConfigMapPropagation. + // Check that we can create OwnerReferences to a ConfigMapPropagation. _ kmeta.OwnerRefable = (*ConfigMapPropagation)(nil) ) type ConfigMapPropagationSpec struct { - // OriginalNamespace represents the namespace where the original configMaps are in + // OriginalNamespace is the namespace where the original configMaps are in OriginalNamespace string `json:"originalNamespace,omitempty"` - // Selector only selects original configMaps with labels under Selector - Selector string `json:"selector,omitempty"` + // Selector only selects original configMaps with corresponding labels + Selector map[string]string `json:"selector,omitempty"` } // ConfigMapPropagationStatus represents the current state of a ConfigMapPropagation. @@ -74,7 +75,7 @@ type ConfigMapPropagationStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// ConfigMapPropagationList is a collection of EventTypes. +// ConfigMapPropagationList is a collection of ConfigMapPropagation. type ConfigMapPropagationList struct { metav1.TypeMeta `json:",inline"` // +optional @@ -82,12 +83,12 @@ type ConfigMapPropagationList struct { Items []ConfigMapPropagation `json:"items"` } -// GetGroupVersionKind returns GroupVersionKind for EventType +// GetGroupVersionKind returns GroupVersionKind for ConfigMapPropagation func (cmp *ConfigMapPropagation) GetGroupVersionKind() schema.GroupVersionKind { return SchemeGroupVersion.WithKind("ConfigMapPropagation") } -// GetUntypedSpec returns the spec of the EventType. +// GetUntypedSpec returns the spec of the ConfigMapPropagation. func (cmp *ConfigMapPropagation) GetUntypedSpec() interface{} { return cmp.Spec } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index dc38f1c4456..e2de735656c 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -18,28 +18,58 @@ package v1alpha1 import ( "context" + "fmt" + "regexp" + "knative.dev/pkg/apis" "knative.dev/pkg/kmp" ) +var ( + // Only allow lowercase alphanumeric, starting with letters. + validSelectorName = regexp.MustCompile(`^[a-z][a-z0-9./-]*$`) +) + +// Validate the ConfigMapPropagation. func (cmp *ConfigMapPropagation) Validate(ctx context.Context) *apis.FieldError { return cmp.Spec.Validate(ctx).ViaField("spec") } +// Validate the ConfigMapPropagationSpec. func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldError { var errs *apis.FieldError if cmps.OriginalNamespace == "" { fe := apis.ErrMissingField("originalNamespace") errs = errs.Also(fe) } - if cmps.Selector == "" { + if cmps.Selector == nil { fe := apis.ErrMissingField("selector") errs = errs.Also(fe) } - // TODO validate selector must be in right format + + if cmps.Selector != nil { + if len(cmps.Selector) == 0 { + fe := &apis.FieldError{ + Message: "At least one selector must be specified", + Paths: []string{"selector"}, + } + errs = errs.Also(fe) + } else { + for s := range cmps.Selector { + if !validSelectorName.MatchString(s) { + fe := &apis.FieldError{ + Message: fmt.Sprintf("Invalid selector name: %q", s), + Paths: []string{"selector"}, + } + errs = errs.Also(fe) + } + } + } + } return errs } +// CheckImmutableFields checks that any immutable fields were not changed. func (cmp *ConfigMapPropagation) CheckImmutableFields(ctx context.Context, original *ConfigMapPropagation) *apis.FieldError { if original == nil { return nil diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index 666677fe304..f71476fa920 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -26,7 +26,9 @@ import ( var ( originalNamespace = "original" currentNamespace = "current" - validSelector = " " + validSelector = map[string]string{ + "testing": "testing", + } ) func TestConfigMapPropagationValidation(t *testing.T) { @@ -79,8 +81,38 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { fe := apis.ErrMissingField("originalNamespace") return fe }(), + }, { + name: "missing selector keys", + cmps: &ConfigMapPropagationSpec{ + OriginalNamespace: originalNamespace, + Selector: map[string]string{}}, + want: &apis.FieldError{ + Message: "At least one selector must be specified", + Paths: []string{"selector"}, + }, + }, { + name: "invalid selector keys, start with number", + cmps: &ConfigMapPropagationSpec{ + OriginalNamespace: originalNamespace, + Selector: map[string]string{ + "0nvalid": "testing", + }}, + want: &apis.FieldError{ + Message: `Invalid selector name: "0nvalid"`, + Paths: []string{"selector"}, + }, + }, { + name: "invalid attribute name, capital letters", + cmps: &ConfigMapPropagationSpec{ + OriginalNamespace: originalNamespace, + Selector: map[string]string{ + "inValid": "testing", + }}, + want: &apis.FieldError{ + Message: `Invalid selector name: "inValid"`, + Paths: []string{"selector"}, + }, }, - //TODO invalid selectors } for _, test := range tests { diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go new file mode 100644 index 00000000000..bfecb847b02 --- /dev/null +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -0,0 +1,318 @@ +/* +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 configmappropagation + +import ( + "context" + "fmt" + "reflect" + "strings" + "time" + + "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + apierrs "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + corev1listers "k8s.io/client-go/listers/core/v1" + "k8s.io/client-go/tools/cache" + + "knative.dev/eventing/pkg/apis/configs/v1alpha1" + configslisters "knative.dev/eventing/pkg/client/listers/configs/v1alpha1" + "knative.dev/eventing/pkg/logging" + "knative.dev/eventing/pkg/reconciler" + "knative.dev/eventing/pkg/reconciler/configmappropagation/resources" + "knative.dev/pkg/controller" + "knative.dev/pkg/tracker" +) + +const ( + // Name of the corev1.Events emitted from the reconciliation process + configMapPropagationReconcileError = "configMapPropagationReconcileError" + configMapPropagationUpdateStatusFailed = "ConfigMapPropagationStatusFailed" + configMapPropagationReadinessChanged = "ConfigMapPropagationReadinessChanged" + configMapPropagationPropagateSingleConfigMapFailed = "ConfigMapPropagationPropagateSingleConfigMapFailed" + configMapPropagationPropagateSingleConfigMapSucceed = "ConfigMapPropagationPropagateSingleConfigMapSucceed" +) + +type Reconciler struct { + *reconciler.Base + + // Listers index properties about resources + configMapPropagationLister configslisters.ConfigMapPropagationLister + configMapLister corev1listers.ConfigMapLister + + tracker tracker.Interface +} + +var configMapGVK = corev1.SchemeGroupVersion.WithKind("ConfigMap") + +// Check that our Reconciler implements controller.Reconciler +var _ controller.Reconciler = (*Reconciler)(nil) + +// Reconcile compares the actual state with the desired, and attempts to +// converge the two. It then updates the Status block of the ConfigMapPropagation resource +// with the current status of the resource. +func (r *Reconciler) Reconcile(ctx context.Context, key string) error { + // Convert the namespace/name string into a distinct namespace and name + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + logging.FromContext(ctx).Error("invalid resource key") + return nil + } + + // Get the ConfigMapPropagation resource with this namespace/name + original, err := r.configMapPropagationLister.ConfigMapPropagations(namespace).Get(name) + + if apierrs.IsNotFound(err) { + // The resource may no longer exist, in which case we stop processing. + logging.FromContext(ctx).Info("ConfigMapPropagation key in work queue no longer exists") + return nil + } else if err != nil { + return err + } + + // Don't modify the informers copy + configMapPropagation := original.DeepCopy() + + // Reconcile this copy of the ConfigMapPropagation and then write back any status + // updates regardless of whether the reconcile error out. + reconcileErr := r.reconcile(ctx, configMapPropagation) + if reconcileErr != nil { + logging.FromContext(ctx).Warn("Error reconciling ConfigMapPropagation", zap.Error(err)) + r.Recorder.Eventf(configMapPropagation, corev1.EventTypeWarning, configMapPropagationReconcileError, + fmt.Sprintf("ConfigMapPropagation reconcile error: %v", reconcileErr)) + } else { + logging.FromContext(ctx).Debug("ConfigMapPropagation reconciled") + } + + if _, updateStatusErr := r.updateStatus(ctx, configMapPropagation); updateStatusErr != nil { + logging.FromContext(ctx).Warn("Failed to update the ConfigMapPropagation status", zap.Error(updateStatusErr)) + r.Recorder.Eventf(configMapPropagation, corev1.EventTypeWarning, configMapPropagationUpdateStatusFailed, + fmt.Sprintf("Failed to update ConfigMapPropagation's status: %v", updateStatusErr)) + return updateStatusErr + } + // Requeue if the resource is not ready: + return reconcileErr +} + +func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { + logging.FromContext(ctx).Debug("Reconciling", zap.Any("ConfigMapPropagation", cmp)) + cmp.Status.InitializeConditions() + + // 1. Create/update ConfigMaps from original namespace to current namespace + // 2. Track changes of original ConfigMaps as well as copy ConfigMaps + + // No need to reconcile if the ConfigMapPropagation has been marked for deletion. + if cmp.DeletionTimestamp != nil { + return nil + } + + // Tell tracker to reconcile this ConfigMapPropagation whenever an original ConfigMap changes. + // Note: Temporarily set Selector to match all objects. + // If Selector is set to match specific labels (the required labels from ConfigMapPropagation), + // the tracker can't track changes when an original ConfigMap no longer has required labels. + // One alternative way is to track the name of every qualified original ConfigMap, + // but this requires to track specific Selector as well, in order to notice newly qualified original ConfigMaps + originalConfigMapObjRef := tracker.Reference{ + Kind: configMapGVK.Kind, + APIVersion: configMapGVK.GroupVersion().String(), + Namespace: cmp.Spec.OriginalNamespace, + Selector: metav1.SetAsLabelSelector(map[string]string{}), + } + if err := r.tracker.TrackReference(originalConfigMapObjRef, cmp); err != nil { + return err + } + + // Tell tracker to reconcile this ConfigMapPropagation whenever the a copy ConfigMap changes. + // Note: Temporarily set Selector to match all objects. + // If Selector is set to match specific labels (the required labels from creation), + // the tracker can't track changes when a copy ConfigMap no longer has required labels. + // One alternative way is to track the name of every qualified copy ConfigMap. + copyConfigMapObjRef := tracker.Reference{ + Kind: configMapGVK.Kind, + APIVersion: configMapGVK.GroupVersion().String(), + Namespace: cmp.Namespace, + Selector: metav1.SetAsLabelSelector(map[string]string{}), + } + if err := r.tracker.TrackReference(copyConfigMapObjRef, cmp); err != nil { + logging.FromContext(ctx).Error("Unable to track changes to ConfigMap", zap.Error(err)) + return err + } + + if err := r.reconcileConfigMap(ctx, cmp); err != nil { + cmp.Status.MarkConfigMapPropagationNotPropagated() + return err + } + + if err := r.checkConfigMap(ctx, cmp); err != nil { + cmp.Status.MarkConfigMapPropagationNotPropagated() + return err + } + + cmp.Status.MarkConfigMapPropagationPropagated() + return nil +} + +func (r *Reconciler) updateStatus(ctx context.Context, desired *v1alpha1.ConfigMapPropagation) (*v1alpha1.ConfigMapPropagation, error) { + configMapPropagation, err := r.configMapPropagationLister.ConfigMapPropagations(desired.Namespace).Get(desired.Name) + if err != nil { + return nil, err + } + + // If there's nothing to update, just return. + if reflect.DeepEqual(configMapPropagation.Status, desired.Status) { + return configMapPropagation, nil + } + + becomesReady := desired.Status.IsReady() && !configMapPropagation.Status.IsReady() + + // Don't modify the informers copy. + existing := configMapPropagation.DeepCopy() + existing.Status = desired.Status + + cmp, err := r.EventingClientSet.ConfigsV1alpha1().ConfigMapPropagations(desired.Namespace).UpdateStatus(existing) + if err == nil && becomesReady { + duration := time.Since(cmp.ObjectMeta.CreationTimestamp.Time) + r.Logger.Infof("ConfigMapPropagation %q became ready after %v", configMapPropagation.Name, duration) + r.Recorder.Event(configMapPropagation, corev1.EventTypeNormal, configMapPropagationReadinessChanged, + fmt.Sprintf("ConfigMapPropagation %q became ready", configMapPropagation.Name)) + if reportErr := r.StatsReporter.ReportReady("ConfigMapPropagation", configMapPropagation.Namespace, configMapPropagation.Name, duration); reportErr != nil { + logging.FromContext(ctx).Sugar().Infof("failed to record ready for ConfigMapPropagation, %v", reportErr) + } + } + return cmp, err +} + +func (r *Reconciler) getOriginalLabelSelector(cmp *v1alpha1.ConfigMapPropagation) labels.Selector { + return labels.SelectorFromSet(resources.OriginalLabels(cmp.Spec.Selector)) +} + +// reconcileConfigMap will list ConfigMaps in original namespace and create/update copy ConfigMap in current namespace. +func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { + originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(r.getOriginalLabelSelector(cmp)) + if err != nil { + logging.FromContext(ctx).Error("Unable to get the ConfigMap list in original namespace", zap.Error(err)) + return err + } + + var errs error + for _, configMap := range originalConfigMapList { + if err = r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { + logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) + r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + fmt.Sprintf("Failed to propagate ConfigMap %v: %v", configMap.Name, err)) + if errs == nil { + errs = fmt.Errorf("one or more ConfigMap propagation failed") + } + } else { + logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") + r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, + fmt.Sprintf("Propagate ConfigMap %v succeed", configMap.Name)) + } + } + + return errs +} + +func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, configMap *corev1.ConfigMap) error { + expected := resources.MakeConfigMap(resources.ConfigMapArgs{ + Original: configMap, + ConfigMapPropagation: cmp, + }) + current, err := r.configMapLister.ConfigMaps(cmp.Namespace).Get(expected.Name) + if err != nil && !apierrs.IsNotFound(err) { + logging.FromContext(ctx).Error("Unable to get ConfigMap: "+current.Name+" in current namespace", zap.Error(err)) + return fmt.Errorf("error getting ConfigMap in current namespace: %v", err) + } + + // Only update ConfigMap with knative.dev/eventing/config-propagation:copy label. + // If the ConfigMap does not have this label, the controller must not update the ConfigMap. + // Instead, it should record a k8s WARN-level Event on the ConfigMap. + if current != nil { + label := current.GetLabels() + if label[resources.PropagationLabelKey] != resources.PropagationLabelValueCopy { + return fmt.Errorf(`unable to update ConfigMap in current namespace, ConfigMap doesn't have "knative.dev/eventing/config-propagation:copy" label`) + } + if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Update(expected); err != nil { + return fmt.Errorf("error updating ConfigMap in current namespace: %v", err) + } + return nil + } + + if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Create(expected); err != nil { + return fmt.Errorf("error creating ConfigMap in current namespace: %v", err) + } + + return nil +} + +// checkConfigMap will delete copy ConfigMap if original ConfigMap no longer exists or no longer has the required label +func (r *Reconciler) checkConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { + copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) + if err != nil { + logging.FromContext(ctx).Error("Unable to get the ConfigMap list in current namespace", zap.Error(err)) + return err + } + + var errs error + for _, copyConfigMap := range copyConfigMapList { + // Select copy ConfigMap which is controlled by current ConfigMapPropagation + if metav1.IsControlledBy(copyConfigMap, cmp) { + // Get the name of original ConfigMap + // The name of Copy ConfigMap is followed by - + originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") + if err = r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName); err != nil { + logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) + r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + fmt.Sprintf("Failed to propagate ConfigMap %v: %v", originalConfigMapName, err)) + if errs == nil { + errs = fmt.Errorf("one or more ConfigMap propagation failed") + } + } + } + } + return errs +} + +func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string) error { + originalConfigMap, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).Get(originalConfigMapName) + if err != nil && !apierrs.IsNotFound(err) { + logging.FromContext(ctx).Error("Unable to get ConfigMap: "+originalConfigMap.Name+" in original namespace", zap.Error(err)) + return fmt.Errorf("error getting ConfigMap in original namespace: %v", err) + } + if apierrs.IsNotFound(err) || !r.isSubset(originalConfigMap.GetLabels(), resources.OriginalLabels(cmp.Spec.Selector)) { + // If Original ConfigMap no longer exists or no longer has the required label, delete copy ConfigMap. + logging.FromContext(ctx).Info("Original ConfigMap " + originalConfigMapName + + ` no longer exists/no longer has "knative.dev/eventing/config-propagation:original" label, delete corresponding copy ConfigMap ` + copyConfigMap.Name) + if err = r.KubeClientSet.CoreV1().ConfigMaps(cmp.Namespace).Delete(copyConfigMap.Name, &metav1.DeleteOptions{}); err != nil { + logging.FromContext(ctx).Error("error deleting ConfigMap in current namespace", zap.Error(err)) + } + return err + } + return nil +} + +// isSubset checks if sub is a subset of set +func (r *Reconciler) isSubset(set map[string]string, sub map[string]string) bool { + for element := range sub { + if sub[element] != set[element] { + return false + } + } + return true +} diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go new file mode 100644 index 00000000000..99bacf934ce --- /dev/null +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -0,0 +1,436 @@ +/* +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 configmappropagation + +import ( + "context" + "testing" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + clientgotesting "k8s.io/client-go/testing" + + "knative.dev/eventing/pkg/apis/configs/v1alpha1" + "knative.dev/eventing/pkg/client/clientset/versioned/scheme" + "knative.dev/eventing/pkg/reconciler" + "knative.dev/eventing/pkg/reconciler/configmappropagation/resources" + "knative.dev/pkg/configmap" + "knative.dev/pkg/controller" + logtesting "knative.dev/pkg/logging/testing" + "knative.dev/pkg/tracker" + + . "knative.dev/eventing/pkg/reconciler/testing" + . "knative.dev/pkg/reconciler/testing" +) + +const ( + currentNS = "test-current-ns" + configMapPropagationName = "test-cmp" + originalConfigMapName = "test-original-cm" + originalNS = "knative-eventing" + copyConfigMapName = configMapPropagationName + "-" + originalConfigMapName +) + +var ( + selector = map[string]string{ + "testings": "testing", + } + originalSelector = map[string]string{ + "testings": "testing", + resources.PropagationLabelKey: resources.PropagationLabelValueOriginal, + } + copySelector = map[string]string{ + resources.PropagationLabelKey: resources.PropagationLabelValueCopy, + resources.CopyLabelKey: currentNS + "-" + originalConfigMapName, + } + originalData = map[string]string{"data": "original"} + copyData = map[string]string{"data": "copy"} +) + +func init() { + // Add types to scheme + _ = v1alpha1.AddToScheme(scheme.Scheme) +} + +func TestAllCase(t *testing.T) { + testKey := currentNS + "/" + configMapPropagationName + table := TableTest{ + { + Name: "bad workqueue key", + // Make sure Reconcile handles bad keys. + Key: "too/many/parts", + }, { + Name: "key not found", + // Make sure Reconcile handles good keys that don't exist. + Key: "foo/not-found", + }, { + Name: "ConfigMapPropagation not found", + Key: testKey, + }, { + Name: "ConfigMapPropagation is being deleted", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationDeletionTimestamp), + }, + }, { + Name: "Original ConfigMap no longer has required labels", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(map[string]string{}), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantDeletes: []clientgotesting.DeleteActionImpl{{ + Name: copyConfigMapName, + }}, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationPropagated, + ), + }}, + WantEvents: []string{ + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), + }, + }, { + Name: "Original ConfigMap no longer exists, delete copy configMap succeeded", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantDeletes: []clientgotesting.DeleteActionImpl{{ + Name: copyConfigMapName, + }}, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationPropagated, + ), + }}, + WantEvents: []string{ + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), + }, + }, { + Name: "Original ConfigMap no longer exists, delete copy configMap failed", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WithReactors: []clientgotesting.ReactionFunc{ + InduceFailure("delete", "configmaps"), + }, + WantDeletes: []clientgotesting.DeleteActionImpl{{ + Name: copyConfigMapName, + }}, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationNotPropagated, + ), + }}, + WantErr: true, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + "Failed to propagate ConfigMap %v: inducing failure for delete configmaps", originalConfigMapName), + Eventf(corev1.EventTypeWarning, configMapPropagationReconcileError, + "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), + }, + }, { + Name: "Original ConfigMap has changed, update copy ConfigMap succeeded", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + WithConfigMapData(originalData), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapData(originalData), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }}, + WithReactors: []clientgotesting.ReactionFunc{ + InduceFailure("update", "configmaps"), + }, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationNotPropagated, + ), + }}, + WantErr: true, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + "Failed to propagate ConfigMap %v: error updating ConfigMap in current namespace: inducing failure for update configmaps", originalConfigMapName), + Eventf(corev1.EventTypeWarning, configMapPropagationReconcileError, + "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), + }, + }, { + Name: "Original ConfigMap has changed, update copy ConfigMap failed", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + WithConfigMapData(originalData), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapData(originalData), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }}, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationPropagated, + ), + }}, + WantEvents: []string{ + Eventf(corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, "Propagate ConfigMap test-original-cm succeed"), + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), + }, + }, { + Name: "Copy ConfigMap has changed", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + WithConfigMapData(originalData), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapData(copyData), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapData(originalData), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }}, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationPropagated, + ), + }}, + WantEvents: []string{ + Eventf(corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, "Propagate ConfigMap test-original-cm succeed"), + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), + }, + }, { + Name: "Copy ConfigMap no longer has required labels", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + ), + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(map[string]string{}), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationNotPropagated, + ), + }}, + WantErr: true, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + `Failed to propagate ConfigMap %v: unable to update ConfigMap in current namespace, ConfigMap doesn't have "knative.dev/eventing/config-propagation:copy" label`, originalConfigMapName), + Eventf(corev1.EventTypeWarning, configMapPropagationReconcileError, + "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), + }, + }, { + Name: "Create new ConfigMap failed", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + ), + }, + WantCreates: []runtime.Object{ + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WithReactors: []clientgotesting.ReactionFunc{ + InduceFailure("create", "configmaps"), + }, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationNotPropagated, + ), + }}, + WantErr: true, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + "Failed to propagate ConfigMap %v: error creating ConfigMap in current namespace: inducing failure for create configmaps", originalConfigMapName), + Eventf(corev1.EventTypeWarning, configMapPropagationReconcileError, + "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), + }, + }, { + Name: "Successfully reconcile, became ready", + Key: testKey, + Objects: []runtime.Object{ + NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + ), + NewConfigMap(originalConfigMapName, originalNS, + WithConfigMapLabels(originalSelector), + ), + }, + WantCreates: []runtime.Object{ + NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(copySelector), + WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + )), + ), + }, + WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMapPropagation(configMapPropagationName, currentNS, + WithInitConfigMapPropagationConditions, + WithConfigMapPropagationSelector(selector), + WithConfigMapPropagationPropagated, + ), + }}, + WantEvents: []string{ + Eventf(corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, "Propagate ConfigMap test-original-cm succeed"), + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), + }, + }, + } + logger := logtesting.TestLogger(t) + table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler { + return &Reconciler{ + Base: reconciler.NewBase(ctx, controllerAgentName, cmw), + configMapPropagationLister: listers.GetConfigMapPropagationLister(), + configMapLister: listers.GetConfigMapLister(), + tracker: tracker.New(func(types.NamespacedName) {}, 0), + } + }, + false, + logger, + )) +} diff --git a/pkg/reconciler/configmappropagation/controller.go b/pkg/reconciler/configmappropagation/controller.go new file mode 100644 index 00000000000..a5c1955a290 --- /dev/null +++ b/pkg/reconciler/configmappropagation/controller.go @@ -0,0 +1,71 @@ +/* +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 configmappropagation + +import ( + "context" + + "knative.dev/eventing/pkg/reconciler" + "knative.dev/pkg/configmap" + "knative.dev/pkg/controller" + "knative.dev/pkg/tracker" + + corev1 "k8s.io/api/core/v1" + configmappropagationinformer "knative.dev/eventing/pkg/client/injection/informers/configs/v1alpha1/configmappropagation" + configmapinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap" +) + +const ( + // ReconcilerName is the name of the reconciler. + ReconcilerName = "ConfigMapPropagation" + // controllerAgentName is the string used by this controller to identify + // itself when creating events. + controllerAgentName = "configmappropagation-controller" +) + +// NewController initializes the controller and is called by the generated code +// Registers event handlers to enqueue events +func NewController( + ctx context.Context, + cmw configmap.Watcher, +) *controller.Impl { + + configMapPropagationInformer := configmappropagationinformer.Get(ctx) + configMapInformer := configmapinformer.Get(ctx) + + r := &Reconciler{ + Base: reconciler.NewBase(ctx, controllerAgentName, cmw), + configMapPropagationLister: configMapPropagationInformer.Lister(), + configMapLister: configMapInformer.Lister(), + } + impl := controller.NewImpl(r, r.Logger, ReconcilerName) + + r.Logger.Info("Setting up event handlers") + configMapPropagationInformer.Informer().AddEventHandler(controller.HandleAll(impl.Enqueue)) + + // Tracker is used to notify us that a ConfigMap has changed so that + // we can reconcile. + r.tracker = tracker.New(impl.EnqueueKey, controller.GetTrackerLease(ctx)) + configMapInformer.Informer().AddEventHandler(controller.HandleAll( + controller.EnsureTypeMeta( + r.tracker.OnChanged, + corev1.SchemeGroupVersion.WithKind("ConfigMap"), + ), + )) + + return impl +} diff --git a/pkg/reconciler/configmappropagation/controller_test.go b/pkg/reconciler/configmappropagation/controller_test.go new file mode 100644 index 00000000000..f0a53ddbce1 --- /dev/null +++ b/pkg/reconciler/configmappropagation/controller_test.go @@ -0,0 +1,40 @@ +/* +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 configmappropagation + +import ( + "testing" + + "knative.dev/pkg/configmap" + + . "knative.dev/pkg/reconciler/testing" + + // Fake injection informers + _ "knative.dev/eventing/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake" + _ "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/fake" + _ "knative.dev/pkg/injection/clients/dynamicclient/fake" +) + +func TestNew(t *testing.T) { + ctx, _ := SetupFakeContext(t) + + c := NewController(ctx, configmap.NewStaticWatcher()) + + if c == nil { + t.Fatal("Expected NewController to return a non-nil value") + } +} diff --git a/pkg/reconciler/configmappropagation/resources/configmap.go b/pkg/reconciler/configmappropagation/resources/configmap.go new file mode 100644 index 00000000000..6cd11ed75a4 --- /dev/null +++ b/pkg/reconciler/configmappropagation/resources/configmap.go @@ -0,0 +1,51 @@ +/* +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 resources + +import ( + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" + "knative.dev/pkg/kmeta" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + CopyLabelKey = "knative.dev/config-original" +) + +type ConfigMapArgs struct { + Original *corev1.ConfigMap + ConfigMapPropagation *configsv1alpha1.ConfigMapPropagation +} + +func MakeConfigMap(args ConfigMapArgs) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: args.ConfigMapPropagation.Name + "-" + args.Original.Name, + Namespace: args.ConfigMapPropagation.Namespace, + Labels: map[string]string{ + PropagationLabelKey: PropagationLabelValueCopy, + CopyLabelKey: args.ConfigMapPropagation.Namespace + "-" + args.Original.Name, + }, + OwnerReferences: []metav1.OwnerReference{ + *kmeta.NewControllerRef(args.ConfigMapPropagation), + }, + }, + Data: args.Original.Data, + } +} diff --git a/pkg/reconciler/configmappropagation/resources/configmap_test.go b/pkg/reconciler/configmappropagation/resources/configmap_test.go new file mode 100644 index 00000000000..e4337a32873 --- /dev/null +++ b/pkg/reconciler/configmappropagation/resources/configmap_test.go @@ -0,0 +1,77 @@ +/* +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 resources + +import ( + "reflect" + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" +) + +func TestMakeSubscription(t *testing.T) { + testCases := map[string]struct { + original *corev1.ConfigMap + configmappropagation *configsv1alpha1.ConfigMapPropagation + }{ + "general configmap": { + original: &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "original-config-map", + }, + }, + configmappropagation: &configsv1alpha1.ConfigMapPropagation{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cmp", + Namespace: "testing", + }, + }, + }, + } + for n, tc := range testCases { + t.Run(n, func(t *testing.T) { + configmap := MakeConfigMap(ConfigMapArgs{ + tc.original, tc.configmappropagation, + }) + // If name and namespace are correct. + if name := configmap.Name; name != "cmp-original-config-map" { + t.Errorf("Expected name %q, actually %q", "cmp-original-config-map", name) + } + + if ns := configmap.Namespace; ns != tc.configmappropagation.Namespace { + t.Errorf("Expected namespace %q, actually %q", tc.configmappropagation.Namespace, ns) + } + + // If OwnerReferences is correct. + if !metav1.IsControlledBy(configmap, tc.configmappropagation) { + t.Errorf("Expected configmap to be controlled by the configmappropagation") + } + + // If labels are correct. + expectedLabels := map[string]string{ + PropagationLabelKey: PropagationLabelValueCopy, + CopyLabelKey: "testing-original-config-map", + } + if labels := configmap.Labels; !reflect.DeepEqual(labels, expectedLabels) { + t.Errorf("Expected labels %q, actually %q", expectedLabels, labels) + } + }) + } +} diff --git a/pkg/reconciler/configmappropagation/resources/labels.go b/pkg/reconciler/configmappropagation/resources/labels.go new file mode 100644 index 00000000000..1e910d355ba --- /dev/null +++ b/pkg/reconciler/configmappropagation/resources/labels.go @@ -0,0 +1,28 @@ +/* +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 resources + +const ( + PropagationLabelKey = "knative.dev/config-propagation" + PropagationLabelValueOriginal = "original" + PropagationLabelValueCopy = "copy" +) + +func OriginalLabels(selector map[string]string) map[string]string { + selector[PropagationLabelKey] = PropagationLabelValueOriginal + return selector +} diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go new file mode 100644 index 00000000000..165dc3ca7d4 --- /dev/null +++ b/pkg/reconciler/testing/configmap.go @@ -0,0 +1,62 @@ +/* +Copyright 2018 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 testing + +import ( + v1 "k8s.io/api/core/v1" + "knative.dev/eventing/pkg/apis/configs/v1alpha1" + "knative.dev/pkg/kmeta" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ConfigMapOption enables further configuration of a ConfigMap. +type ConfigMapOption func(*v1.ConfigMap) + +// NewConfigMap creates a eew ConfigMap. +func NewConfigMap(name, namespace string, o ...ConfigMapOption) *v1.ConfigMap { + cm := &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + } + for _, opt := range o { + opt(cm) + } + return cm +} + +func WithConfigMapLabels(labels map[string]string) ConfigMapOption { + return func(cm *v1.ConfigMap) { + cm.ObjectMeta.Labels = labels + } +} + +func WithConfigMapOwnerReference(ConfigMapPropagation *v1alpha1.ConfigMapPropagation) ConfigMapOption { + return func(cm *v1.ConfigMap) { + cm.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ + *kmeta.NewControllerRef(ConfigMapPropagation), + } + } +} + +func WithConfigMapData(data map[string]string) ConfigMapOption { + return func(cm *v1.ConfigMap) { + cm.Data = data + } +} diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go new file mode 100644 index 00000000000..0dd9aa8cfdf --- /dev/null +++ b/pkg/reconciler/testing/configmappropagation.go @@ -0,0 +1,69 @@ +/* +Copyright 2018 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 testing + +import ( + "context" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/eventing/pkg/apis/configs/v1alpha1" +) + +// ConfigMapPropagationOption enables further configuration of an ConfigMapPropagation. +type ConfigMapPropagationOption func(*v1alpha1.ConfigMapPropagation) + +// NewConfigMapPropagation creates a ConfigMapPropagation. +func NewConfigMapPropagation(name, namespace string, o ...ConfigMapPropagationOption) *v1alpha1.ConfigMapPropagation { + cmp := &v1alpha1.ConfigMapPropagation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + } + for _, opt := range o { + opt(cmp) + } + cmp.SetDefaults(context.Background()) + return cmp +} + +// WithInitConfigMapPropagationConditions initializes the ConfigMapPropagation's conditions. +func WithInitConfigMapPropagationConditions(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.InitializeConditions() +} + +func WithConfigMapPropagationDeletionTimestamp(cmp *v1alpha1.ConfigMapPropagation) { + t := metav1.NewTime(time.Unix(1e9, 0)) + cmp.ObjectMeta.SetDeletionTimestamp(&t) +} + +func WithConfigMapPropagationSelector(selector map[string]string) ConfigMapPropagationOption { + return func(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Spec.Selector = selector + } +} + +// WithConfigMapPropagationPropagated calls .Status.MarkConfigMapPropagationPropagated on the ConfigMapPropagation. +func WithConfigMapPropagationPropagated(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.MarkConfigMapPropagationPropagated() +} + +// WithConfigMapPropagationNotPropagated calls .Status.MarkConfigMapPropagationNotPropagated on the ConfigMapPropagation. +func WithConfigMapPropagationNotPropagated(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.MarkConfigMapPropagationNotPropagated() +} diff --git a/pkg/reconciler/testing/listers.go b/pkg/reconciler/testing/listers.go index 9e1c8d9a42b..62fde1a0709 100644 --- a/pkg/reconciler/testing/listers.go +++ b/pkg/reconciler/testing/listers.go @@ -31,11 +31,13 @@ import ( corev1listers "k8s.io/client-go/listers/core/v1" rbacv1listers "k8s.io/client-go/listers/rbac/v1" "k8s.io/client-go/tools/cache" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" sourcesv1alpha1 "knative.dev/eventing/pkg/apis/sources/v1alpha1" fakeeventingclientset "knative.dev/eventing/pkg/client/clientset/versioned/fake" + configslisters "knative.dev/eventing/pkg/client/listers/configs/v1alpha1" eventinglisters "knative.dev/eventing/pkg/client/listers/eventing/v1alpha1" flowslisters "knative.dev/eventing/pkg/client/listers/flows/v1alpha1" messaginglisters "knative.dev/eventing/pkg/client/listers/messaging/v1alpha1" @@ -194,3 +196,7 @@ func (l *Listers) GetConfigMapLister() corev1listers.ConfigMapLister { func (l *Listers) GetCustomResourceDefinitionLister() apiextensionsv1beta1listers.CustomResourceDefinitionLister { return apiextensionsv1beta1listers.NewCustomResourceDefinitionLister(l.indexerFor(&apiextensionsv1beta1.CustomResourceDefinition{})) } + +func (l *Listers) GetConfigMapPropagationLister() configslisters.ConfigMapPropagationLister { + return configslisters.NewConfigMapPropagationLister(l.indexerFor(&configsv1alpha1.ConfigMapPropagation{})) +} From 4f9bf6eaa019133542caa38aa3f9f7b68cffaf6c Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 18 Dec 2019 11:28:22 -0800 Subject: [PATCH 05/26] Controller-2 --- pkg/apis/configs/register.go | 2 +- .../configs/v1alpha1/configmappropagation_types.go | 2 +- .../v1alpha1/configmappropagation_validation.go | 2 +- pkg/apis/configs/v1alpha1/register.go | 2 +- pkg/apis/configs/v1alpha1/register_test.go | 2 +- .../configmappropagation_test.go | 8 ++++---- .../configmappropagation/resources/configmap.go | 12 ++++++++++-- pkg/reconciler/testing/configmap.go | 2 +- pkg/reconciler/testing/configmappropagation.go | 2 +- 9 files changed, 21 insertions(+), 13 deletions(-) diff --git a/pkg/apis/configs/register.go b/pkg/apis/configs/register.go index cf929487ac4..8e33b6faaeb 100644 --- a/pkg/apis/configs/register.go +++ b/pkg/apis/configs/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 63cb47685cf..7263ab8d04f 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index e2de735656c..898a067b22d 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/register.go b/pkg/apis/configs/v1alpha1/register.go index cd1bdb3638f..bb54a18d3b9 100644 --- a/pkg/apis/configs/v1alpha1/register.go +++ b/pkg/apis/configs/v1alpha1/register.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/register_test.go b/pkg/apis/configs/v1alpha1/register_test.go index e04cafbc1e9..f384ea8b431 100644 --- a/pkg/apis/configs/v1alpha1/register_test.go +++ b/pkg/apis/configs/v1alpha1/register_test.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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 diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 99bacf934ce..33a1f187ee1 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -43,7 +43,6 @@ const ( configMapPropagationName = "test-cmp" originalConfigMapName = "test-original-cm" originalNS = "knative-eventing" - copyConfigMapName = configMapPropagationName + "-" + originalConfigMapName ) var ( @@ -56,10 +55,11 @@ var ( } copySelector = map[string]string{ resources.PropagationLabelKey: resources.PropagationLabelValueCopy, - resources.CopyLabelKey: currentNS + "-" + originalConfigMapName, + resources.CopyLabelKey: resources.MakeCopyConfigMapLabel(currentNS, originalConfigMapName), } - originalData = map[string]string{"data": "original"} - copyData = map[string]string{"data": "copy"} + copyConfigMapName = resources.MakeCopyConfigMapName(configMapPropagationName, originalConfigMapName) + originalData = map[string]string{"data": "original"} + copyData = map[string]string{"data": "copy"} ) func init() { diff --git a/pkg/reconciler/configmappropagation/resources/configmap.go b/pkg/reconciler/configmappropagation/resources/configmap.go index 6cd11ed75a4..529425141d9 100644 --- a/pkg/reconciler/configmappropagation/resources/configmap.go +++ b/pkg/reconciler/configmappropagation/resources/configmap.go @@ -36,11 +36,11 @@ type ConfigMapArgs struct { func MakeConfigMap(args ConfigMapArgs) *corev1.ConfigMap { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: args.ConfigMapPropagation.Name + "-" + args.Original.Name, + Name: MakeCopyConfigMapName(args.ConfigMapPropagation.Name, args.Original.Name), Namespace: args.ConfigMapPropagation.Namespace, Labels: map[string]string{ PropagationLabelKey: PropagationLabelValueCopy, - CopyLabelKey: args.ConfigMapPropagation.Namespace + "-" + args.Original.Name, + CopyLabelKey: MakeCopyConfigMapLabel(args.ConfigMapPropagation.Namespace, args.Original.Name), }, OwnerReferences: []metav1.OwnerReference{ *kmeta.NewControllerRef(args.ConfigMapPropagation), @@ -49,3 +49,11 @@ func MakeConfigMap(args ConfigMapArgs) *corev1.ConfigMap { Data: args.Original.Data, } } + +func MakeCopyConfigMapName(configMapPropagationName string, configMapName string) string { + return configMapPropagationName + "-" + configMapName +} + +func MakeCopyConfigMapLabel(configMapPropagationNamespace string, configMapName string) string { + return configMapPropagationNamespace + "-" + configMapName +} diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go index 165dc3ca7d4..5460b4ae7f5 100644 --- a/pkg/reconciler/testing/configmap.go +++ b/pkg/reconciler/testing/configmap.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 0dd9aa8cfdf..46b758415b4 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2018 The Knative Authors +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. From 86be672b8e10e7daece2a8b39e5863040ca25610 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 18 Dec 2019 11:38:40 -0800 Subject: [PATCH 06/26] update-codegen --- Gopkg.lock | 4 ++++ pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Gopkg.lock b/Gopkg.lock index df5d8a6c144..55ab1d7f939 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1283,6 +1283,8 @@ "client/injection/kube/informers/admissionregistration/v1beta1/validatingwebhookconfiguration", "client/injection/kube/informers/apps/v1/deployment", "client/injection/kube/informers/apps/v1/deployment/fake", + "client/injection/kube/informers/core/v1/configmap", + "client/injection/kube/informers/core/v1/configmap/fake", "client/injection/kube/informers/core/v1/endpoints", "client/injection/kube/informers/core/v1/endpoints/fake", "client/injection/kube/informers/core/v1/namespace", @@ -1484,6 +1486,8 @@ "knative.dev/pkg/client/injection/kube/client/fake", "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment", "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment/fake", + "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap", + "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/fake", "knative.dev/pkg/client/injection/kube/informers/core/v1/endpoints", "knative.dev/pkg/client/injection/kube/informers/core/v1/endpoints/fake", "knative.dev/pkg/client/injection/kube/informers/core/v1/namespace", diff --git a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go index 156d1b56554..937ca1feadd 100644 --- a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go @@ -29,7 +29,7 @@ func (in *ConfigMapPropagation) DeepCopyInto(out *ConfigMapPropagation) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) return } @@ -88,6 +88,13 @@ func (in *ConfigMapPropagationList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConfigMapPropagationSpec) DeepCopyInto(out *ConfigMapPropagationSpec) { *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } return } From 9414727ef5d04787b13a81bf93077a12833ac187 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 18 Dec 2019 13:07:48 -0800 Subject: [PATCH 07/26] Add unit test --- .../configmappropagation_types_test.go | 16 ++++++++-- .../resources/configmap_test.go | 2 +- .../resources/labels_test.go | 31 +++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 pkg/reconciler/configmappropagation/resources/labels_test.go diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go index 3117d21ca95..ca9c8df5159 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go @@ -16,12 +16,22 @@ package v1alpha1 -import "testing" +import ( + "reflect" + "testing" +) func TestConfigMapPropagation_GetGroupVersionKind(t *testing.T) { - b := ConfigMapPropagation{} - gvk := b.GetGroupVersionKind() + cmp := ConfigMapPropagation{} + gvk := cmp.GetGroupVersionKind() if gvk.Kind != "ConfigMapPropagation" { t.Errorf("Should be ConfigMapPropagation.") } } +func TestConfigMapPropagation_GetUntypedSpec(t *testing.T) { + cmp := ConfigMapPropagation{} + int := cmp.GetUntypedSpec() + if !reflect.DeepEqual(int, cmp.Spec) { + t.Errorf("Should be ConfigMapPropagationSpec.") + } +} diff --git a/pkg/reconciler/configmappropagation/resources/configmap_test.go b/pkg/reconciler/configmappropagation/resources/configmap_test.go index e4337a32873..e79ef6977f8 100644 --- a/pkg/reconciler/configmappropagation/resources/configmap_test.go +++ b/pkg/reconciler/configmappropagation/resources/configmap_test.go @@ -26,7 +26,7 @@ import ( configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" ) -func TestMakeSubscription(t *testing.T) { +func TestMakeMakeConfigMap(t *testing.T) { testCases := map[string]struct { original *corev1.ConfigMap configmappropagation *configsv1alpha1.ConfigMapPropagation diff --git a/pkg/reconciler/configmappropagation/resources/labels_test.go b/pkg/reconciler/configmappropagation/resources/labels_test.go new file mode 100644 index 00000000000..780e4f88fd5 --- /dev/null +++ b/pkg/reconciler/configmappropagation/resources/labels_test.go @@ -0,0 +1,31 @@ +/* +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 resources + +import ( + "reflect" + "testing" +) + +func TestOriginalLabels(t *testing.T) { + label := OriginalLabels(map[string]string{}) + if !reflect.DeepEqual(label, map[string]string{ + PropagationLabelKey: PropagationLabelValueOriginal, + }) { + t.Errorf("Should have required labels") + } +} From 8f856dda962b8d40cd277b2172c557efb2bbc1be Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 18 Dec 2019 16:56:40 -0800 Subject: [PATCH 08/26] updating eventing --- cmd/broker/config.go | 39 +++++++++ cmd/broker/filter/main.go | 34 ++++---- cmd/broker/ingress/main.go | 31 ++++--- config/300-configmappropagation.yaml | 2 +- config/config-logging.yaml | 3 + config/config-observability.yaml | 3 + config/config-tracing.yaml | 4 +- .../inmemorychannel/dispatcher/controller.go | 3 +- pkg/reconciler/namespace/controller.go | 5 ++ pkg/reconciler/namespace/controller_test.go | 1 + pkg/reconciler/namespace/namespace.go | 80 ++++++++++++------- pkg/reconciler/namespace/namespace_test.go | 55 +++++-------- .../resources/configmappropagation.go | 40 ++++++++++ pkg/reconciler/namespace/resources/labels.go | 9 +++ pkg/reconciler/namespace/resources/names.go | 14 +--- pkg/tracing/setup.go | 10 +-- 16 files changed, 223 insertions(+), 110 deletions(-) create mode 100644 cmd/broker/config.go create mode 100644 pkg/reconciler/namespace/resources/configmappropagation.go diff --git a/cmd/broker/config.go b/cmd/broker/config.go new file mode 100644 index 00000000000..f53578c50bc --- /dev/null +++ b/cmd/broker/config.go @@ -0,0 +1,39 @@ +/* + * 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 broker + +import ( + "context" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + kubeclient "knative.dev/pkg/client/injection/kube/client" + "knative.dev/pkg/logging" +) + +// GetLoggingConfig will get config from a specific namespace +func GetLoggingConfig(ctx context.Context, namespace, loggingConfigMapName string) (*logging.Config, error) { + loggingConfigMap, err := kubeclient.Get(ctx).CoreV1().ConfigMaps(namespace).Get(loggingConfigMapName, metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return logging.NewConfigFromMap(nil) + } else { + return nil, err + } + } + return logging.NewConfigFromConfigMap(loggingConfigMap) +} diff --git a/cmd/broker/filter/main.go b/cmd/broker/filter/main.go index f45d28c6b4d..f6365ce8d22 100644 --- a/cmd/broker/filter/main.go +++ b/cmd/broker/filter/main.go @@ -25,6 +25,11 @@ import ( "go.opencensus.io/stats/view" "go.uber.org/zap" + "knative.dev/eventing/cmd/broker" + "knative.dev/eventing/pkg/broker/filter" + cmpresources "knative.dev/eventing/pkg/reconciler/configmappropagation/resources" + namespaceresources "knative.dev/eventing/pkg/reconciler/namespace/resources" + "knative.dev/eventing/pkg/tracing" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/configmap" "knative.dev/pkg/controller" @@ -32,10 +37,7 @@ import ( "knative.dev/pkg/logging" "knative.dev/pkg/metrics" "knative.dev/pkg/signals" - "knative.dev/pkg/system" - - "knative.dev/eventing/pkg/broker/filter" - "knative.dev/eventing/pkg/tracing" + tracingconfig "knative.dev/pkg/tracing/config" "knative.dev/pkg/injection/sharedmain" @@ -76,10 +78,18 @@ func main() { log.Fatal("Error building kubeconfig", err) } + var env envConfig + if err := envconfig.Process("", &env); err != nil { + log.Fatal("Failed to process env var", zap.Error(err)) + } + ctx, _ = injection.Default.SetupInformers(ctx, cfg) kubeClient := kubeclient.Get(ctx) - loggingConfig, err := sharedmain.GetLoggingConfig(ctx) + loggingConfigMapName := cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, logging.ConfigMapName()) + metricsConfigMapName := cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, metrics.ConfigMapName()) + + loggingConfig, err := broker.GetLoggingConfig(ctx, env.Namespace, loggingConfigMapName) if err != nil { log.Fatal("Error loading/parsing logging configuration:", err) } @@ -89,11 +99,6 @@ func main() { logger.Info("Starting the Broker Filter") - var env envConfig - if err := envconfig.Process("", &env); err != nil { - logger.Fatal("Failed to process env var", zap.Error(err)) - } - eventingClient := eventingv1alpha1.NewForConfigOrDie(cfg) eventingFactory := eventinginformers.NewSharedInformerFactoryWithOptions(eventingClient, controller.GetResyncPeriod(ctx), @@ -101,18 +106,19 @@ func main() { triggerInformer := eventingFactory.Eventing().V1alpha1().Triggers() // Watch the logging config map and dynamically update logging levels. - configMapWatcher := configmap.NewInformedWatcher(kubeClient, system.Namespace()) + configMapWatcher := configmap.NewInformedWatcher(kubeClient, env.Namespace) // Watch the observability config map and dynamically update metrics exporter. - configMapWatcher.Watch(metrics.ConfigMapName(), metrics.UpdateExporterFromConfigMap(component, sl)) + configMapWatcher.Watch(metricsConfigMapName, metrics.UpdateExporterFromConfigMap(component, sl)) // TODO change the component name to broker once Stackdriver metrics are approved. // Watch the observability config map and dynamically update request logs. - configMapWatcher.Watch(logging.ConfigMapName(), logging.UpdateLevelFromConfigMap(sl, atomicLevel, component)) + configMapWatcher.Watch(loggingConfigMapName, logging.UpdateLevelFromConfigMap(sl, atomicLevel, component)) bin := tracing.BrokerFilterName(tracing.BrokerFilterNameArgs{ Namespace: env.Namespace, BrokerName: env.Broker, }) - if err = tracing.SetupDynamicPublishing(sl, configMapWatcher, bin); err != nil { + if err = tracing.SetupDynamicPublishing(sl, configMapWatcher, bin, + cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, tracingconfig.ConfigName)); err != nil { logger.Fatal("Error setting up trace publishing", zap.Error(err)) } diff --git a/cmd/broker/ingress/main.go b/cmd/broker/ingress/main.go index 5ec45e7e240..13286f3a649 100644 --- a/cmd/broker/ingress/main.go +++ b/cmd/broker/ingress/main.go @@ -18,6 +18,7 @@ package main import ( "flag" + "knative.dev/eventing/cmd/broker" "log" "net/http" "net/url" @@ -28,11 +29,13 @@ import ( cloudevents "github.com/cloudevents/sdk-go" "github.com/kelseyhightower/envconfig" + "go.opencensus.io/stats/view" "go.uber.org/zap" - "go.opencensus.io/stats/view" "knative.dev/eventing/pkg/broker/ingress" "knative.dev/eventing/pkg/kncloudevents" + cmpresources "knative.dev/eventing/pkg/reconciler/configmappropagation/resources" + namespaceresources "knative.dev/eventing/pkg/reconciler/namespace/resources" "knative.dev/eventing/pkg/tracing" kubeclient "knative.dev/pkg/client/injection/kube/client" "knative.dev/pkg/configmap" @@ -42,8 +45,8 @@ import ( "knative.dev/pkg/logging" "knative.dev/pkg/metrics" "knative.dev/pkg/signals" - "knative.dev/pkg/system" pkgtracing "knative.dev/pkg/tracing" + tracingconfig "knative.dev/pkg/tracing/config" ) var ( @@ -88,13 +91,21 @@ func main() { log.Fatal("Error building kubeconfig", err) } + var env envConfig + if err := envconfig.Process("", &env); err != nil { + log.Fatal("Failed to process env var", zap.Error(err)) + } + log.Printf("Registering %d clients", len(injection.Default.GetClients())) log.Printf("Registering %d informer factories", len(injection.Default.GetInformerFactories())) log.Printf("Registering %d informers", len(injection.Default.GetInformers())) ctx, informers := injection.Default.SetupInformers(ctx, cfg) - loggingConfig, err := sharedmain.GetLoggingConfig(ctx) + loggingConfigMapName := cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, logging.ConfigMapName()) + metricsConfigMapName := cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, metrics.ConfigMapName()) + + loggingConfig, err := broker.GetLoggingConfig(ctx, env.Namespace, loggingConfigMapName) if err != nil { log.Fatal("Error loading/parsing logging configuration:", err) } @@ -104,11 +115,6 @@ func main() { logger.Info("Starting the Broker Ingress") - var env envConfig - if err := envconfig.Process("", &env); err != nil { - logger.Fatal("Failed to process env var", zap.Error(err)) - } - channelURI := &url.URL{ Scheme: "http", Host: env.Channel, @@ -116,18 +122,19 @@ func main() { } // Watch the logging config map and dynamically update logging levels. - configMapWatcher := configmap.NewInformedWatcher(kubeclient.Get(ctx), system.Namespace()) + configMapWatcher := configmap.NewInformedWatcher(kubeclient.Get(ctx), env.Namespace) // Watch the observability config map and dynamically update metrics exporter. - configMapWatcher.Watch(metrics.ConfigMapName(), metrics.UpdateExporterFromConfigMap(component, sl)) + configMapWatcher.Watch(metricsConfigMapName, metrics.UpdateExporterFromConfigMap(component, sl)) // TODO change the component name to broker once Stackdriver metrics are approved. // Watch the observability config map and dynamically update request logs. - configMapWatcher.Watch(logging.ConfigMapName(), logging.UpdateLevelFromConfigMap(sl, atomicLevel, component)) + configMapWatcher.Watch(loggingConfigMapName, logging.UpdateLevelFromConfigMap(sl, atomicLevel, component)) bin := tracing.BrokerIngressName(tracing.BrokerIngressNameArgs{ Namespace: env.Namespace, BrokerName: env.Broker, }) - if err = tracing.SetupDynamicPublishing(sl, configMapWatcher, bin); err != nil { + if err = tracing.SetupDynamicPublishing(sl, configMapWatcher, bin, + cmpresources.MakeCopyConfigMapName(namespaceresources.DefaultConfigMapPropagationName, tracingconfig.ConfigName)); err != nil { logger.Fatal("Error setting up trace publishing", zap.Error(err)) } diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index a1fb59cd7fb..07741731b5a 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -43,7 +43,7 @@ spec: - name: Reason type: string JSONPath: ".status.conditions[?(@.type==\"Ready\")].reason" - - name: OriginalNamepsace + - name: OriginalNamespace type: string JSONPath: ".spec.originalNamespace" - name: Selector diff --git a/config/config-logging.yaml b/config/config-logging.yaml index a742cb7ae90..2125564bd2d 100644 --- a/config/config-logging.yaml +++ b/config/config-logging.yaml @@ -17,6 +17,9 @@ kind: ConfigMap metadata: name: config-logging namespace: knative-eventing + labels: + knative.dev/config-category: eventing + knative.dev/config-propagation: original data: # Common configuration for all Knative codebase zap-logger-config: | diff --git a/config/config-observability.yaml b/config/config-observability.yaml index 7c883908485..1126dd9361c 100644 --- a/config/config-observability.yaml +++ b/config/config-observability.yaml @@ -17,6 +17,9 @@ kind: ConfigMap metadata: name: config-observability namespace: knative-eventing + labels: + knative.dev/config-category: eventing + knative.dev/config-propagation: original data: _example: | ################################ diff --git a/config/config-tracing.yaml b/config/config-tracing.yaml index 4523fa6ec7e..60abaed51f5 100644 --- a/config/config-tracing.yaml +++ b/config/config-tracing.yaml @@ -17,7 +17,9 @@ kind: ConfigMap metadata: name: config-tracing namespace: knative-eventing - + labels: + knative.dev/config-category: eventing + knative.dev/config-propagation: original data: _example: | ################################ diff --git a/pkg/reconciler/inmemorychannel/dispatcher/controller.go b/pkg/reconciler/inmemorychannel/dispatcher/controller.go index 0690480f828..36aa5894ba8 100644 --- a/pkg/reconciler/inmemorychannel/dispatcher/controller.go +++ b/pkg/reconciler/inmemorychannel/dispatcher/controller.go @@ -30,6 +30,7 @@ import ( "knative.dev/pkg/controller" inmemorychannelinformer "knative.dev/eventing/pkg/client/injection/informers/messaging/v1alpha1/inmemorychannel" + tracingconfig "knative.dev/pkg/tracing/config" ) const ( @@ -55,7 +56,7 @@ func NewController( // Setup trace publishing. iw := cmw.(*configmap.InformedWatcher) - if err := tracing.SetupDynamicPublishing(base.Logger, iw, "imc-dispatcher"); err != nil { + if err := tracing.SetupDynamicPublishing(base.Logger, iw, "imc-dispatcher", tracingconfig.ConfigName); err != nil { base.Logger.Fatalw("Error setting up trace publishing", zap.Error(err)) } diff --git a/pkg/reconciler/namespace/controller.go b/pkg/reconciler/namespace/controller.go index 6e8240b362b..b241cdfadd6 100644 --- a/pkg/reconciler/namespace/controller.go +++ b/pkg/reconciler/namespace/controller.go @@ -25,6 +25,7 @@ import ( "knative.dev/eventing/pkg/reconciler" + "knative.dev/eventing/pkg/client/injection/informers/configs/v1alpha1/configmappropagation" "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/broker" "knative.dev/pkg/client/injection/kube/informers/core/v1/namespace" "knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount" @@ -51,6 +52,7 @@ func NewController( serviceAccountInformer := serviceaccount.Get(ctx) roleBindingInformer := rolebinding.Get(ctx) brokerInformer := broker.Get(ctx) + configMapPropagationInformer := configmappropagation.Get(ctx) r := &Reconciler{ Base: reconciler.NewBase(ctx, controllerAgentName, cmw), @@ -75,6 +77,9 @@ func NewController( brokerInformer.Informer().AddEventHandler(controller.HandleAll( controller.EnsureTypeMeta(r.tracker.OnChanged, brokerGVK), )) + configMapPropagationInformer.Informer().AddEventHandler(controller.HandleAll( + controller.EnsureTypeMeta(r.tracker.OnChanged, configMapPropagationGVK), + )) return impl } diff --git a/pkg/reconciler/namespace/controller_test.go b/pkg/reconciler/namespace/controller_test.go index 7fa0f0b87fe..31d244f4ab0 100644 --- a/pkg/reconciler/namespace/controller_test.go +++ b/pkg/reconciler/namespace/controller_test.go @@ -23,6 +23,7 @@ import ( . "knative.dev/pkg/reconciler/testing" // Fake injection informers + _ "knative.dev/eventing/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake" _ "knative.dev/eventing/pkg/client/injection/informers/eventing/v1alpha1/broker/fake" _ "knative.dev/pkg/client/injection/kube/informers/core/v1/namespace/fake" _ "knative.dev/pkg/client/injection/kube/informers/core/v1/serviceaccount/fake" diff --git a/pkg/reconciler/namespace/namespace.go b/pkg/reconciler/namespace/namespace.go index 47a496f1c74..5991acc91d0 100644 --- a/pkg/reconciler/namespace/namespace.go +++ b/pkg/reconciler/namespace/namespace.go @@ -19,15 +19,14 @@ package namespace import ( "context" "fmt" - "k8s.io/client-go/tools/cache" "knative.dev/eventing/pkg/reconciler/namespace/resources" "knative.dev/eventing/pkg/utils" - "knative.dev/pkg/system" "knative.dev/pkg/tracker" corev1listers "k8s.io/client-go/listers/core/v1" rbacv1listers "k8s.io/client-go/listers/rbac/v1" + configslisters "knative.dev/eventing/pkg/client/listers/configs/v1alpha1" eventinglisters "knative.dev/eventing/pkg/client/listers/eventing/v1alpha1" "go.uber.org/zap" @@ -36,6 +35,7 @@ import ( apierrs "k8s.io/apimachinery/pkg/api/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + configsv1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" "knative.dev/eventing/pkg/apis/eventing/v1alpha1" "knative.dev/eventing/pkg/logging" "knative.dev/eventing/pkg/reconciler" @@ -47,26 +47,29 @@ const ( namespaceReconcileFailure = "NamespaceReconcileFailure" // Name of the corev1.Events emitted from the reconciliation process. - brokerCreated = "BrokerCreated" - serviceAccountCreated = "BrokerServiceAccountCreated" - serviceAccountRBACCreated = "BrokerServiceAccountRBACCreated" + brokerCreated = "BrokerCreated" + configMapPropagationCreated = "ConfigMapPropagationCreated" + serviceAccountCreated = "BrokerServiceAccountCreated" + serviceAccountRBACCreated = "BrokerServiceAccountRBACCreated" ) var ( - serviceAccountGVK = corev1.SchemeGroupVersion.WithKind("ServiceAccount") - roleBindingGVK = rbacv1.SchemeGroupVersion.WithKind("RoleBinding") - brokerGVK = v1alpha1.SchemeGroupVersion.WithKind("Broker") + serviceAccountGVK = corev1.SchemeGroupVersion.WithKind("ServiceAccount") + roleBindingGVK = rbacv1.SchemeGroupVersion.WithKind("RoleBinding") + brokerGVK = v1alpha1.SchemeGroupVersion.WithKind("Broker") + configMapPropagationGVK = configsv1.SchemeGroupVersion.WithKind("ConfigMapPropagation") ) type Reconciler struct { *reconciler.Base // listers index properties about resources - namespaceLister corev1listers.NamespaceLister - serviceAccountLister corev1listers.ServiceAccountLister - roleBindingLister rbacv1listers.RoleBindingLister - brokerLister eventinglisters.BrokerLister - tracker tracker.Interface + namespaceLister corev1listers.NamespaceLister + serviceAccountLister corev1listers.ServiceAccountLister + roleBindingLister rbacv1listers.RoleBindingLister + brokerLister eventinglisters.BrokerLister + configMapPropagationLister configslisters.ConfigMapPropagationLister + tracker tracker.Interface } // Check that our Reconciler implements controller.Reconciler @@ -117,11 +120,22 @@ func (r *Reconciler) reconcile(ctx context.Context, ns *corev1.Namespace) error if ns.DeletionTimestamp != nil { return nil } - if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.IngressServiceAccountName, resources.IngressRoleBindingName, resources.IngressClusterRoleName, resources.ConfigClusterRoleName); err != nil { + + cmp, err := r.reconcileConfigMapPropagation(ctx, ns) + if err != nil { + return fmt.Errorf("configMapPropagation: %v", err) + } + + // Tell tracker to reconcile this namespace whenever the ConfigMapPropagation changes. + if err = r.tracker.Track(utils.ObjectRef(cmp, configMapPropagationGVK), ns); err != nil { + return fmt.Errorf("track configMapPropagation: %v", err) + } + + if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.IngressServiceAccountName, resources.IngressRoleBindingName, resources.IngressClusterRoleName); err != nil { return fmt.Errorf("broker ingress: %v", err) } - if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.FilterServiceAccountName, resources.FilterRoleBindingName, resources.FilterClusterRoleName, resources.ConfigClusterRoleName); err != nil { + if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.FilterServiceAccountName, resources.FilterRoleBindingName, resources.FilterClusterRoleName); err != nil { return fmt.Errorf("broker filter: %v", err) } @@ -138,9 +152,30 @@ func (r *Reconciler) reconcile(ctx context.Context, ns *corev1.Namespace) error return nil } +// reconcileConfigMapPropagation reconciles the default ConfigMapPropagation for the Namespace 'ns'. +func (r *Reconciler) reconcileConfigMapPropagation(ctx context.Context, ns *corev1.Namespace) (*configsv1.ConfigMapPropagation, error) { + current, err := r.EventingClientSet.ConfigsV1alpha1().ConfigMapPropagations(ns.Name).Get(resources.DefaultConfigMapPropagationName, metav1.GetOptions{}) + + // If the resource doesn't exist, we'll create it. + if k8serrors.IsNotFound(err) { + cmp := resources.MakeConfigMapPropagation(ns.Name) + cmp, err = r.EventingClientSet.ConfigsV1alpha1().ConfigMapPropagations(ns.Name).Create(cmp) + if err != nil { + return nil, err + } + r.Recorder.Event(ns, corev1.EventTypeNormal, configMapPropagationCreated, + "Default ConfigMapPropagation: "+cmp.Name+" created") + return cmp, nil + } else if err != nil { + return nil, err + } + // Don't update anything that is already present. + return current, nil +} + // reconcileServiceAccountAndRoleBinding reconciles the service account and role binding for // Namespace 'ns'. -func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, ns *corev1.Namespace, saName, rbName, clusterRoleName, configClusterRoleName string) error { +func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, ns *corev1.Namespace, saName, rbName, clusterRoleName string) error { sa, err := r.reconcileBrokerServiceAccount(ctx, ns, resources.MakeServiceAccount(ns.Name, saName)) if err != nil { return fmt.Errorf("service account '%s': %v", saName, err) @@ -161,19 +196,6 @@ func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, return fmt.Errorf("track role binding '%s': %v", rb.Name, err) } - // Reconcile the RoleBinding allowing read access to the shared configmaps. - // Note this RoleBinding is created in the system namespace and points to a - // subject in the Broker's namespace. - rb, err = r.reconcileBrokerRBAC(ctx, ns, sa, resources.MakeRoleBinding(resources.ConfigRoleBindingName(sa.Name, ns.Name), system.Namespace(), sa, configClusterRoleName)) - if err != nil { - return fmt.Errorf("role binding '%s': %v", rbName, err) - } - - // Tell tracker to reconcile this namespace whenever the RoleBinding changes. - if err = r.tracker.Track(utils.ObjectRef(rb, roleBindingGVK), ns); err != nil { - return fmt.Errorf("track role binding '%s': %v", rb.Name, err) - } - return nil } diff --git a/pkg/reconciler/namespace/namespace_test.go b/pkg/reconciler/namespace/namespace_test.go index 637218545e6..183b38dacae 100644 --- a/pkg/reconciler/namespace/namespace_test.go +++ b/pkg/reconciler/namespace/namespace_test.go @@ -21,8 +21,6 @@ import ( "testing" "knative.dev/pkg/configmap" - "knative.dev/pkg/system" - "knative.dev/pkg/tracker" "k8s.io/apimachinery/pkg/runtime" @@ -72,12 +70,11 @@ func init() { func TestAllCases(t *testing.T) { // Events + cmpEvent := Eventf(corev1.EventTypeNormal, "ConfigMapPropagationCreated", "Default ConfigMapPropagation: eventing created") saIngressEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountCreated", "ServiceAccount 'eventing-broker-ingress' created for the Broker") rbIngressEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountRBACCreated", "RoleBinding 'test-namespace/eventing-broker-ingress' created for the Broker") - rbIngressConfigEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountRBACCreated", "RoleBinding 'knative-testing/eventing-broker-ingress-test-namespace' created for the Broker") saFilterEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountCreated", "ServiceAccount 'eventing-broker-filter' created for the Broker") rbFilterEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountRBACCreated", "RoleBinding 'test-namespace/eventing-broker-filter' created for the Broker") - rbFilterConfigEvent := Eventf(corev1.EventTypeNormal, "BrokerServiceAccountRBACCreated", "RoleBinding 'knative-testing/eventing-broker-filter-test-namespace' created for the Broker") brokerEvent := Eventf(corev1.EventTypeNormal, "BrokerCreated", "Default eventing.knative.dev Broker created.") nsEvent := Eventf(corev1.EventTypeNormal, "NamespaceReconciled", "Namespace reconciled: \"test-namespace\"") @@ -85,10 +82,9 @@ func TestAllCases(t *testing.T) { broker := resources.MakeBroker(testNS) saIngress := resources.MakeServiceAccount(testNS, resources.IngressServiceAccountName) rbIngress := resources.MakeRoleBinding(resources.IngressRoleBindingName, testNS, resources.MakeServiceAccount(testNS, resources.IngressServiceAccountName), resources.IngressClusterRoleName) - rbIngressConfig := resources.MakeRoleBinding(resources.ConfigRoleBindingName(resources.IngressServiceAccountName, testNS), system.Namespace(), resources.MakeServiceAccount(testNS, resources.IngressServiceAccountName), resources.ConfigClusterRoleName) saFilter := resources.MakeServiceAccount(testNS, resources.FilterServiceAccountName) rbFilter := resources.MakeRoleBinding(resources.FilterRoleBindingName, testNS, resources.MakeServiceAccount(testNS, resources.FilterServiceAccountName), resources.FilterClusterRoleName) - rbFilterConfig := resources.MakeRoleBinding(resources.ConfigRoleBindingName(resources.FilterServiceAccountName, testNS), system.Namespace(), resources.MakeServiceAccount(testNS, resources.FilterServiceAccountName), resources.ConfigClusterRoleName) + configMapPropagation := resources.MakeConfigMapPropagation(testNS) table := TableTest{{ Name: "bad workqueue key", @@ -134,23 +130,21 @@ func TestAllCases(t *testing.T) { SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, saIngressEvent, rbIngressEvent, - rbIngressConfigEvent, saFilterEvent, rbFilterEvent, - rbFilterConfigEvent, brokerEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, broker, saIngress, rbIngress, - rbIngressConfig, saFilter, rbFilter, - rbFilterConfig, }, }, { Name: "Namespace enabled, broker exists", @@ -164,21 +158,19 @@ func TestAllCases(t *testing.T) { SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, saIngressEvent, rbIngressEvent, - rbIngressConfigEvent, saFilterEvent, rbFilterEvent, - rbFilterConfigEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, saIngress, rbIngress, - rbIngressConfig, saFilter, rbFilter, - rbFilterConfig, }, }, { Name: "Namespace enabled, broker exists with no label", @@ -208,21 +200,19 @@ func TestAllCases(t *testing.T) { SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, rbIngressEvent, - rbIngressConfigEvent, saFilterEvent, rbFilterEvent, - rbFilterConfigEvent, brokerEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, broker, rbIngress, - rbIngressConfig, saFilter, rbFilter, - rbFilterConfig, }, }, { Name: "Namespace enabled, ingress role binding exists", @@ -231,25 +221,24 @@ func TestAllCases(t *testing.T) { WithNamespaceLabeled(resources.InjectionEnabledLabels()), ), rbIngress, - rbIngressConfig, }, Key: testNS, SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, saIngressEvent, saFilterEvent, rbFilterEvent, - rbFilterConfigEvent, brokerEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, broker, saIngress, saFilter, rbFilter, - rbFilterConfig, }, }, { Name: "Namespace enabled, filter service account exists", @@ -263,21 +252,19 @@ func TestAllCases(t *testing.T) { SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, saIngressEvent, rbIngressEvent, - rbIngressConfigEvent, rbFilterEvent, - rbFilterConfigEvent, brokerEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, broker, saIngress, rbIngress, - rbIngressConfig, rbFilter, - rbFilterConfig, }, }, { Name: "Namespace enabled, filter role binding exists", @@ -286,24 +273,23 @@ func TestAllCases(t *testing.T) { WithNamespaceLabeled(resources.InjectionEnabledLabels()), ), rbFilter, - rbFilterConfig, }, Key: testNS, SkipNamespaceValidation: true, WantErr: false, WantEvents: []string{ + cmpEvent, saIngressEvent, rbIngressEvent, - rbIngressConfigEvent, saFilterEvent, brokerEvent, nsEvent, }, WantCreates: []runtime.Object{ + configMapPropagation, broker, saIngress, rbIngress, - rbIngressConfig, saFilter, }, }, @@ -313,12 +299,13 @@ func TestAllCases(t *testing.T) { logger := logtesting.TestLogger(t) table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler { return &Reconciler{ - Base: reconciler.NewBase(ctx, controllerAgentName, cmw), - namespaceLister: listers.GetNamespaceLister(), - brokerLister: listers.GetBrokerLister(), - serviceAccountLister: listers.GetServiceAccountLister(), - roleBindingLister: listers.GetRoleBindingLister(), - tracker: tracker.New(func(types.NamespacedName) {}, 0), + Base: reconciler.NewBase(ctx, controllerAgentName, cmw), + namespaceLister: listers.GetNamespaceLister(), + brokerLister: listers.GetBrokerLister(), + serviceAccountLister: listers.GetServiceAccountLister(), + roleBindingLister: listers.GetRoleBindingLister(), + configMapPropagationLister: listers.GetConfigMapPropagationLister(), + tracker: tracker.New(func(types.NamespacedName) {}, 0), } }, false, logger)) } diff --git a/pkg/reconciler/namespace/resources/configmappropagation.go b/pkg/reconciler/namespace/resources/configmappropagation.go new file mode 100644 index 00000000000..71ce88f0510 --- /dev/null +++ b/pkg/reconciler/namespace/resources/configmappropagation.go @@ -0,0 +1,40 @@ +/* +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 resources + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/eventing/pkg/apis/configs/v1alpha1" +) + +const ( + defaultNamespace = "knative-eventing" +) + +// MakeConfigMapPropagation creates a default ConfigMapPropagation object for Namespace 'namespace'. +func MakeConfigMapPropagation(namespace string) *v1alpha1.ConfigMapPropagation { + return &v1alpha1.ConfigMapPropagation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: DefaultConfigMapPropagationName, + }, + Spec: v1alpha1.ConfigMapPropagationSpec{ + OriginalNamespace: defaultNamespace, + Selector: ConfigMapPropagationOwnedLabels(), + }, + } +} diff --git a/pkg/reconciler/namespace/resources/labels.go b/pkg/reconciler/namespace/resources/labels.go index 0bfeade1497..4512b5e2b04 100644 --- a/pkg/reconciler/namespace/resources/labels.go +++ b/pkg/reconciler/namespace/resources/labels.go @@ -22,6 +22,8 @@ const ( InjectionEnabledLabelValue = "enabled" InjectionDisabledLabelValue = "disabled" InjectedResourceLabel = "eventing.knative.dev/namespaceInjected" + CmpDefaultLabelKey = "knative.dev/config-category" + CmpDefaultLabelValue = "eventing" ) // OwnedLabels generates the labels present on injected broker resources. @@ -31,6 +33,13 @@ func OwnedLabels() map[string]string { } } +// ConfigMapPropagationOwnedLabels generates the labels present on injected broker resources. +func ConfigMapPropagationOwnedLabels() map[string]string { + return map[string]string{ + CmpDefaultLabelKey: CmpDefaultLabelValue, + } +} + func InjectionEnabledLabels() map[string]string { return map[string]string{ InjectionLabelKey: InjectionEnabledLabelValue, diff --git a/pkg/reconciler/namespace/resources/names.go b/pkg/reconciler/namespace/resources/names.go index 47e3b71a25d..5f7e36a04ec 100644 --- a/pkg/reconciler/namespace/resources/names.go +++ b/pkg/reconciler/namespace/resources/names.go @@ -16,10 +16,6 @@ limitations under the License. package resources -import ( - "knative.dev/pkg/kmeta" -) - const ( DefaultBrokerName = "default" @@ -31,13 +27,5 @@ const ( IngressRoleBindingName = "eventing-broker-ingress" IngressClusterRoleName = "eventing-broker-ingress" - ConfigClusterRoleName = "eventing-config-reader" + DefaultConfigMapPropagationName = "eventing" ) - -// ConfigRoleBindingName returns a name for a RoleBinding allowing access to the -// shared ConfigMaps from a service account in another namespace. Because these -// are all created in the system namespace, they must be named for their -// subject namespace. -func ConfigRoleBindingName(saName, ns string) string { - return kmeta.ChildName(saName, "-"+ns) -} diff --git a/pkg/tracing/setup.go b/pkg/tracing/setup.go index 7b806e9d02f..8ba5d5140c5 100644 --- a/pkg/tracing/setup.go +++ b/pkg/tracing/setup.go @@ -81,14 +81,14 @@ func SetupStaticPublishing(logger *zap.SugaredLogger, serviceName string, cfg *t // just ensures that if generated, they are collected appropriately. This is normally done by using // tracing.HTTPSpanMiddleware as a middleware HTTP handler. The configuration will be dynamically // updated when the ConfigMap is updated. -func SetupDynamicPublishing(logger *zap.SugaredLogger, configMapWatcher *configmap.InformedWatcher, serviceName string) error { +func SetupDynamicPublishing(logger *zap.SugaredLogger, configMapWatcher *configmap.InformedWatcher, serviceName string, tracingConfigName string) error { oct, err := setupPublishing(serviceName, logger) if err != nil { return err } tracerUpdater := func(name string, value interface{}) { - if name == tracingconfig.ConfigName { + if name == tracingConfigName { cfg := value.(*tracingconfig.Config) logger.Debugw("Updating tracing config", zap.Any("cfg", cfg)) err = oct.ApplyConfig(cfg) @@ -105,7 +105,7 @@ func SetupDynamicPublishing(logger *zap.SugaredLogger, configMapWatcher *configm logger, []eventingconfigmap.DefaultConstructor{ { - Default: enableZeroSamplingCM(configMapWatcher.Namespace), + Default: enableZeroSamplingCM(configMapWatcher.Namespace, tracingConfigName), Constructor: tracingconfig.NewTracingConfigFromConfigMap, }, }, @@ -114,10 +114,10 @@ func SetupDynamicPublishing(logger *zap.SugaredLogger, configMapWatcher *configm return nil } -func enableZeroSamplingCM(ns string) corev1.ConfigMap { +func enableZeroSamplingCM(ns string, tracingConfigName string) corev1.ConfigMap { return corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: tracingconfig.ConfigName, + Name: tracingConfigName, Namespace: ns, }, Data: map[string]string{ From b8b48b0e5e27de912b967280589d9ce4cff9f144 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Thu, 19 Dec 2019 11:25:34 -0800 Subject: [PATCH 09/26] add unit test & fix conformance test --- pkg/reconciler/namespace/namespace_test.go | 19 ++++++++ test/base/resources/eventing.go | 16 +++++++ test/common/creation.go | 46 ++++++++++++------- .../helpers/broker_tracing_test_helper.go | 6 ++- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/pkg/reconciler/namespace/namespace_test.go b/pkg/reconciler/namespace/namespace_test.go index f1ee4376538..be9c3386b9f 100644 --- a/pkg/reconciler/namespace/namespace_test.go +++ b/pkg/reconciler/namespace/namespace_test.go @@ -193,6 +193,25 @@ func TestAllCases(t *testing.T) { saIngress, rbIngress, }, + }, { + Name: "Namespace enabled - configmappropagation fails", + Objects: []runtime.Object{ + NewNamespace(testNS, + WithNamespaceLabeled(resources.InjectionEnabledLabels()), + ), + }, + Key: testNS, + SkipNamespaceValidation: true, + WantErr: true, + WithReactors: []clientgotesting.ReactionFunc{ + InduceFailure("create", "configmappropagations"), + }, + WantEvents: []string{ + Eventf(corev1.EventTypeWarning, "NamespaceReconcileFailure", "Failed to reconcile Namespace: configMapPropagation: inducing failure for create configmappropagations"), + }, + WantCreates: []runtime.Object{ + configMapPropagation, + }, }, { Name: "Namespace enabled, broker exists", Objects: []runtime.Object{ diff --git a/test/base/resources/eventing.go b/test/base/resources/eventing.go index 4959d3598b6..01fd7cb7a90 100644 --- a/test/base/resources/eventing.go +++ b/test/base/resources/eventing.go @@ -28,9 +28,11 @@ import ( duckv1 "knative.dev/pkg/apis/duck/v1" pkgTest "knative.dev/pkg/test" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" eventingduckv1alpha1 "knative.dev/eventing/pkg/apis/duck/v1alpha1" eventingv1alpha1 "knative.dev/eventing/pkg/apis/eventing/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" + "knative.dev/eventing/pkg/reconciler/namespace/resources" ) // BrokerOption enables further configuration of a Broker. @@ -117,6 +119,20 @@ func WithChannelTemplateForBroker(channelTypeMeta metav1.TypeMeta) BrokerOption } } +// ConfigMapPropagation returns a ConfigMapPropagation +func ConfigMapPropagation(name, namespace string) *configsv1alpha1.ConfigMapPropagation { + return &configsv1alpha1.ConfigMapPropagation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Spec: configsv1alpha1.ConfigMapPropagationSpec{ + OriginalNamespace: "knative-eventing", + Selector: resources.ConfigMapPropagationOwnedLabels(), + }, + } +} + // Broker returns a Broker. func Broker(name string, options ...BrokerOption) *eventingv1alpha1.Broker { broker := &eventingv1alpha1.Broker{ diff --git a/test/common/creation.go b/test/common/creation.go index 31e873a83c4..472169ef8a6 100644 --- a/test/common/creation.go +++ b/test/common/creation.go @@ -25,6 +25,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" "knative.dev/eventing/pkg/apis/eventing/v1alpha1" flowsv1alpha1 "knative.dev/eventing/pkg/apis/flows/v1alpha1" messagingv1alpha1 "knative.dev/eventing/pkg/apis/messaging/v1alpha1" @@ -32,7 +33,6 @@ import ( "knative.dev/eventing/pkg/utils" "knative.dev/eventing/test/base" "knative.dev/eventing/test/base/resources" - "knative.dev/pkg/test/helpers" ) // TODO(Fredy-Z): break this file into multiple files when it grows too large. @@ -100,6 +100,18 @@ func (client *Client) CreateSubscriptionsOrFail( } } +func (client *Client) CreateConfigMapPropagationOrFail(name string) *configsv1alpha1.ConfigMapPropagation { + namespace := client.Namespace + configMapPropagation := resources.ConfigMapPropagation(name, namespace) + configMapPropagations := client.Eventing.ConfigsV1alpha1().ConfigMapPropagations(namespace) + configMapPropagation, err := configMapPropagations.Create(configMapPropagation) + if err != nil { + client.T.Fatalf("Failed to create configMapPropagation %q: %v", name, err) + } + client.Tracker.AddObj(configMapPropagation) + return configMapPropagation +} + // CreateBrokerOrFail will create a Broker or fail the test if there is an error. func (client *Client) CreateBrokerOrFail(name string, channelTypeMeta *metav1.TypeMeta) *v1alpha1.Broker { namespace := client.Namespace @@ -395,20 +407,20 @@ func (client *Client) CreateRBACResourcesForBrokers() { fmt.Sprintf("%s-%s", saFilterName, crFilterName), client.Namespace, ) - // The two RoleBindings are required for access to shared configmaps for logging, - // tracing, and metrics configuration. - client.CreateRoleBindingOrFail( - saIngressName, - ClusterRoleKind, - crConfigReaderName, - fmt.Sprintf("%s-%s-%s", saIngressName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), - resources.SystemNamespace, - ) - client.CreateRoleBindingOrFail( - saFilterName, - ClusterRoleKind, - crConfigReaderName, - fmt.Sprintf("%s-%s-%s", saFilterName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), - resources.SystemNamespace, - ) + //// The two RoleBindings are required for access to shared configmaps for logging, + //// tracing, and metrics configuration. + //client.CreateRoleBindingOrFail( + // saIngressName, + // ClusterRoleKind, + // crConfigReaderName, + // fmt.Sprintf("%s-%s-%s", saIngressName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), + // resources.SystemNamespace, + //) + //client.CreateRoleBindingOrFail( + // saFilterName, + // ClusterRoleKind, + // crConfigReaderName, + // fmt.Sprintf("%s-%s-%s", saFilterName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), + // resources.SystemNamespace, + //) } diff --git a/test/conformance/helpers/broker_tracing_test_helper.go b/test/conformance/helpers/broker_tracing_test_helper.go index b06df47861b..e3733bbbcdc 100644 --- a/test/conformance/helpers/broker_tracing_test_helper.go +++ b/test/conformance/helpers/broker_tracing_test_helper.go @@ -76,10 +76,12 @@ func setupBrokerTracing( tc TracingTestCase, ) (tracinghelper.TestSpanTree, string) { const ( - etTransformer = "transformer" - etLogger = "logger" + etTransformer = "transformer" + etLogger = "logger" + defaultCMPName = "eventing" ) // Create the Broker. + client.CreateConfigMapPropagationOrFail(defaultCMPName) client.CreateRBACResourcesForBrokers() broker := client.CreateBrokerOrFail("br", channel) From 39ecc302cd70514444839b6715e4b1b19f3c23e0 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 20 Dec 2019 15:35:27 -0800 Subject: [PATCH 10/26] change after review --- .../v1alpha1/configmappropagation_defaults.go | 2 + .../configmappropagation_defaults_test.go | 2 +- .../configmappropagation_lifecycle_test.go | 3 +- .../configmappropagation_validation_test.go | 4 +- .../configmappropagation.go | 92 +++++++++---------- .../resources/configmap_test.go | 2 +- pkg/reconciler/namespace/namespace.go | 24 ++--- test/common/creation.go | 16 ---- 8 files changed, 63 insertions(+), 82 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go index 895ab789cd8..73995890396 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go @@ -23,6 +23,8 @@ import ( func (cmp *ConfigMapPropagation) SetDefaults(ctx context.Context) { // If we haven't configured the original namespace, // then set the default original namespace to the knative-eventing. + // TODO if this API starts to become commonly adopted by others, + // it will stop make sense defaulting to knative-eventing. if cmp != nil && cmp.Spec.OriginalNamespace == "" { cmp.Spec.OriginalNamespace = "knative-eventing" } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go index b0f57d8aa08..a5b13e75d60 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -50,7 +50,7 @@ func TestConfigMapPropagationDefaults(t *testing.T) { } for n, tc := range testCases { t.Run(n, func(t *testing.T) { - tc.initial.SetDefaults(context.TODO()) + tc.initial.SetDefaults(context.Background()) if diff := cmp.Diff(tc.expected, tc.initial); diff != "" { t.Fatalf("Unexpected defaults (-want, +got): %s", diff) } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index 6788f5bd4b0..d77be71c504 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -197,8 +197,7 @@ func TestConfigMapPropagationIsReady(t *testing.T) { cmps.MarkConfigMapPropagationNotPropagated() } } - got := cmps.IsReady() - if test.wantReady != got { + if got := cmps.IsReady(); test.wantReady != got { t.Errorf("unexpected readiness: want %v, got %v", test.wantReady, got) } }) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index f71476fa920..6e7127f3fdc 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -47,7 +47,7 @@ func TestConfigMapPropagationValidation(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got := test.cmp.Validate(context.TODO()) + got := test.cmp.Validate(context.Background()) if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" { t.Errorf("ConfigMapPropagation.Validate (-want, +got) = %v", diff) } @@ -117,7 +117,7 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got := test.cmps.Validate(context.TODO()) + got := test.cmps.Validate(context.Background()) if diff := cmp.Diff(test.want.Error(), got.Error()); diff != "" { t.Errorf("%s: Validate ConfigMapPropagationSpec (-want, +got) = %v", test.name, diff) } diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index bfecb847b02..4b9465e92e1 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -159,11 +159,6 @@ func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropa return err } - if err := r.checkConfigMap(ctx, cmp); err != nil { - cmp.Status.MarkConfigMapPropagationNotPropagated() - return err - } - cmp.Status.MarkConfigMapPropagationPropagated() return nil } @@ -202,15 +197,14 @@ func (r *Reconciler) getOriginalLabelSelector(cmp *v1alpha1.ConfigMapPropagation return labels.SelectorFromSet(resources.OriginalLabels(cmp.Spec.Selector)) } -// reconcileConfigMap will list ConfigMaps in original namespace and create/update copy ConfigMap in current namespace. func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { + // List ConfigMaps in original namespace and create/update copy ConfigMap in current namespace. + var errs error originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(r.getOriginalLabelSelector(cmp)) if err != nil { logging.FromContext(ctx).Error("Unable to get the ConfigMap list in original namespace", zap.Error(err)) return err } - - var errs error for _, configMap := range originalConfigMapList { if err = r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) @@ -226,6 +220,30 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi } } + // List ConfigMaps in current namespace and delete copy ConfigMap if the corresponding original ConfigMap no longer exists or no longer has the required label + copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) + if err != nil { + logging.FromContext(ctx).Error("Unable to get the ConfigMap list in current namespace", zap.Error(err)) + return err + } + + for _, copyConfigMap := range copyConfigMapList { + // Select copy ConfigMap which is controlled by current ConfigMapPropagation + if metav1.IsControlledBy(copyConfigMap, cmp) { + // Get the name of original ConfigMap + // The name of Copy ConfigMap is followed by - + originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") + if err = r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { + logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) + r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, + fmt.Sprintf("Failed to propagate ConfigMap %v: %v", originalConfigMapName, err)) + if errs == nil { + errs = fmt.Errorf("one or more ConfigMap propagation failed") + } + } + } + } + return errs } @@ -237,7 +255,7 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 current, err := r.configMapLister.ConfigMaps(cmp.Namespace).Get(expected.Name) if err != nil && !apierrs.IsNotFound(err) { logging.FromContext(ctx).Error("Unable to get ConfigMap: "+current.Name+" in current namespace", zap.Error(err)) - return fmt.Errorf("error getting ConfigMap in current namespace: %v", err) + return fmt.Errorf("error getting ConfigMap in current namespace: %w", err) } // Only update ConfigMap with knative.dev/eventing/config-propagation:copy label. @@ -249,60 +267,28 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 return fmt.Errorf(`unable to update ConfigMap in current namespace, ConfigMap doesn't have "knative.dev/eventing/config-propagation:copy" label`) } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Update(expected); err != nil { - return fmt.Errorf("error updating ConfigMap in current namespace: %v", err) + return fmt.Errorf("error updating ConfigMap in current namespace: %w", err) } return nil } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Create(expected); err != nil { - return fmt.Errorf("error creating ConfigMap in current namespace: %v", err) + return fmt.Errorf("error creating ConfigMap in current namespace: %w", err) } return nil } -// checkConfigMap will delete copy ConfigMap if original ConfigMap no longer exists or no longer has the required label -func (r *Reconciler) checkConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { - copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) - if err != nil { - logging.FromContext(ctx).Error("Unable to get the ConfigMap list in current namespace", zap.Error(err)) - return err - } - - var errs error - for _, copyConfigMap := range copyConfigMapList { - // Select copy ConfigMap which is controlled by current ConfigMapPropagation - if metav1.IsControlledBy(copyConfigMap, cmp) { - // Get the name of original ConfigMap - // The name of Copy ConfigMap is followed by - - originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") - if err = r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName); err != nil { - logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) - r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, - fmt.Sprintf("Failed to propagate ConfigMap %v: %v", originalConfigMapName, err)) - if errs == nil { - errs = fmt.Errorf("one or more ConfigMap propagation failed") - } - } - } - } - return errs -} - -func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string) error { - originalConfigMap, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).Get(originalConfigMapName) - if err != nil && !apierrs.IsNotFound(err) { - logging.FromContext(ctx).Error("Unable to get ConfigMap: "+originalConfigMap.Name+" in original namespace", zap.Error(err)) - return fmt.Errorf("error getting ConfigMap in original namespace: %v", err) - } - if apierrs.IsNotFound(err) || !r.isSubset(originalConfigMap.GetLabels(), resources.OriginalLabels(cmp.Spec.Selector)) { +func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string, originalConfigMapList []*corev1.ConfigMap) error { + originalConfigMap, contains := r.contains(originalConfigMapName, originalConfigMapList) + if !contains || !r.isSubset(originalConfigMap.GetLabels(), resources.OriginalLabels(cmp.Spec.Selector)) { // If Original ConfigMap no longer exists or no longer has the required label, delete copy ConfigMap. logging.FromContext(ctx).Info("Original ConfigMap " + originalConfigMapName + ` no longer exists/no longer has "knative.dev/eventing/config-propagation:original" label, delete corresponding copy ConfigMap ` + copyConfigMap.Name) - if err = r.KubeClientSet.CoreV1().ConfigMaps(cmp.Namespace).Delete(copyConfigMap.Name, &metav1.DeleteOptions{}); err != nil { + if err := r.KubeClientSet.CoreV1().ConfigMaps(cmp.Namespace).Delete(copyConfigMap.Name, &metav1.DeleteOptions{}); err != nil { logging.FromContext(ctx).Error("error deleting ConfigMap in current namespace", zap.Error(err)) + return err } - return err } return nil } @@ -316,3 +302,13 @@ func (r *Reconciler) isSubset(set map[string]string, sub map[string]string) bool } return true } + +// contains returns a configmap object if its name is in a configmaplist +func (r *Reconciler) contains(name string, list []*corev1.ConfigMap) (*corev1.ConfigMap, bool) { + for _, configMap := range list { + if configMap.Name == name { + return configMap, true + } + } + return nil, false +} diff --git a/pkg/reconciler/configmappropagation/resources/configmap_test.go b/pkg/reconciler/configmappropagation/resources/configmap_test.go index e79ef6977f8..78b8214d2e7 100644 --- a/pkg/reconciler/configmappropagation/resources/configmap_test.go +++ b/pkg/reconciler/configmappropagation/resources/configmap_test.go @@ -26,7 +26,7 @@ import ( configsv1alpha1 "knative.dev/eventing/pkg/apis/configs/v1alpha1" ) -func TestMakeMakeConfigMap(t *testing.T) { +func TestMakeConfigMap(t *testing.T) { testCases := map[string]struct { original *corev1.ConfigMap configmappropagation *configsv1alpha1.ConfigMapPropagation diff --git a/pkg/reconciler/namespace/namespace.go b/pkg/reconciler/namespace/namespace.go index 403fbcdb82a..dd3ce8eba43 100644 --- a/pkg/reconciler/namespace/namespace.go +++ b/pkg/reconciler/namespace/namespace.go @@ -129,30 +129,30 @@ func (r *Reconciler) reconcile(ctx context.Context, ns *corev1.Namespace) error cmp, err := r.reconcileConfigMapPropagation(ctx, ns) if err != nil { - return fmt.Errorf("configMapPropagation: %v", err) + return fmt.Errorf("configMapPropagation: %w", err) } // Tell tracker to reconcile this namespace whenever the ConfigMapPropagation changes. if err = r.tracker.Track(utils.ObjectRef(cmp, configMapPropagationGVK), ns); err != nil { - return fmt.Errorf("track configMapPropagation: %v", err) + return fmt.Errorf("track configMapPropagation: %w", err) } if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.IngressServiceAccountName, resources.IngressRoleBindingName, resources.IngressClusterRoleName); err != nil { - return fmt.Errorf("broker ingress: %v", err) + return fmt.Errorf("broker ingress: %w", err) } if err := r.reconcileServiceAccountAndRoleBindings(ctx, ns, resources.FilterServiceAccountName, resources.FilterRoleBindingName, resources.FilterClusterRoleName); err != nil { - return fmt.Errorf("broker filter: %v", err) + return fmt.Errorf("broker filter: %w", err) } b, err := r.reconcileBroker(ctx, ns) if err != nil { - return fmt.Errorf("broker: %v", err) + return fmt.Errorf("broker: %w", err) } // Tell tracker to reconcile this namespace whenever the Broker changes. if err = r.tracker.Track(utils.ObjectRef(b, brokerGVK), ns); err != nil { - return fmt.Errorf("track broker: %v", err) + return fmt.Errorf("track broker: %w", err) } return nil @@ -184,22 +184,22 @@ func (r *Reconciler) reconcileConfigMapPropagation(ctx context.Context, ns *core func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, ns *corev1.Namespace, saName, rbName, clusterRoleName string) error { sa, err := r.reconcileBrokerServiceAccount(ctx, ns, resources.MakeServiceAccount(ns.Name, saName)) if err != nil { - return fmt.Errorf("service account '%s': %v", saName, err) + return fmt.Errorf("service account '%s': %w", saName, err) } // Tell tracker to reconcile this namespace whenever the Service Account changes. if err = r.tracker.Track(utils.ObjectRef(sa, serviceAccountGVK), ns); err != nil { - return fmt.Errorf("track service account '%s': %v", sa.Name, err) + return fmt.Errorf("track service account '%s': %w", sa.Name, err) } rb, err := r.reconcileBrokerRBAC(ctx, ns, sa, resources.MakeRoleBinding(rbName, ns.Name, sa, clusterRoleName)) if err != nil { - return fmt.Errorf("role binding '%s': %v", rbName, err) + return fmt.Errorf("role binding '%s': %w", rbName, err) } // Tell tracker to reconcile this namespace whenever the RoleBinding changes. if err = r.tracker.Track(utils.ObjectRef(rb, roleBindingGVK), ns); err != nil { - return fmt.Errorf("track role binding '%s': %v", rb.Name, err) + return fmt.Errorf("track role binding '%s': %w", rb.Name, err) } // If the Broker pull secret has not been specified, then nothing to copy. @@ -217,8 +217,8 @@ func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, _, err := utils.CopySecret(r.KubeClientSet.CoreV1(), system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name) if err != nil { r.Recorder.Event(ns, corev1.EventTypeWarning, secretCopyFailure, - fmt.Sprintf("Error copying secret %s/%s => %s/%s : %s", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err)) - return fmt.Errorf("Error copying secret %s/%s => %s/%s : %s", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err) + fmt.Sprintf("Error copying secret %s/%s => %s/%s : %w", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err)) + return fmt.Errorf("Error copying secret %s/%s => %s/%s : %w", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err) } else { r.Recorder.Event(ns, corev1.EventTypeNormal, secretCopied, fmt.Sprintf("Secret copied into namespace %s/%s => %s/%s", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name)) diff --git a/test/common/creation.go b/test/common/creation.go index 472169ef8a6..51f34a99e57 100644 --- a/test/common/creation.go +++ b/test/common/creation.go @@ -407,20 +407,4 @@ func (client *Client) CreateRBACResourcesForBrokers() { fmt.Sprintf("%s-%s", saFilterName, crFilterName), client.Namespace, ) - //// The two RoleBindings are required for access to shared configmaps for logging, - //// tracing, and metrics configuration. - //client.CreateRoleBindingOrFail( - // saIngressName, - // ClusterRoleKind, - // crConfigReaderName, - // fmt.Sprintf("%s-%s-%s", saIngressName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), - // resources.SystemNamespace, - //) - //client.CreateRoleBindingOrFail( - // saFilterName, - // ClusterRoleKind, - // crConfigReaderName, - // fmt.Sprintf("%s-%s-%s", saFilterName, helpers.MakeK8sNamePrefix(client.Namespace), crConfigReaderName), - // resources.SystemNamespace, - //) } From 05fe27aa0121ae7befb03cb149bb7adbd50e4c70 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 20 Dec 2019 15:48:58 -0800 Subject: [PATCH 11/26] update fmt.Errorf --- pkg/reconciler/namespace/namespace.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/reconciler/namespace/namespace.go b/pkg/reconciler/namespace/namespace.go index dd3ce8eba43..922e3ade342 100644 --- a/pkg/reconciler/namespace/namespace.go +++ b/pkg/reconciler/namespace/namespace.go @@ -217,7 +217,7 @@ func (r *Reconciler) reconcileServiceAccountAndRoleBindings(ctx context.Context, _, err := utils.CopySecret(r.KubeClientSet.CoreV1(), system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name) if err != nil { r.Recorder.Event(ns, corev1.EventTypeWarning, secretCopyFailure, - fmt.Sprintf("Error copying secret %s/%s => %s/%s : %w", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err)) + fmt.Sprintf("Error copying secret %s/%s => %s/%s : %v", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err)) return fmt.Errorf("Error copying secret %s/%s => %s/%s : %w", system.Namespace(), r.brokerPullSecretName, ns.Name, sa.Name, err) } else { r.Recorder.Event(ns, corev1.EventTypeNormal, secretCopied, From 7c4766872cd05a76ac2816f6bd7e91cf5b377deb Mon Sep 17 00:00:00 2001 From: grac3gao Date: Mon, 6 Jan 2020 15:57:28 -0800 Subject: [PATCH 12/26] code reviews/conflicts --- Gopkg.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gopkg.lock b/Gopkg.lock index 48c4b569a6c..81ef7edd259 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1516,6 +1516,7 @@ "knative.dev/pkg/metrics/metricstest", "knative.dev/pkg/metrics/testing", "knative.dev/pkg/profiling", + "knative.dev/pkg/ptr", "knative.dev/pkg/reconciler/testing", "knative.dev/pkg/resolver", "knative.dev/pkg/signals", From 8e80aba036c76d2ec034ac27b64e064d85a519b4 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Tue, 14 Jan 2020 23:54:43 -0800 Subject: [PATCH 13/26] update status --- .../v1alpha1/configmappropagation_types.go | 2 +- .../configmappropagation.go | 21 ++++++++++++------- .../testing/configmappropagation.go | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 1d583138f0b..c759c79568b 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -89,7 +89,7 @@ type ConfigMapPropagationStatusCopyConfigMap struct { Ready string `json:"ready,omitempty"` // Reason indicates reasons if the operation is not ready - Reason string `json:"deadLetterSinkURI,omitempty"` + Reason string `json:"reason,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index 47ffc696dd6..da3ba92f8c8 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -121,6 +121,9 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { logging.FromContext(ctx).Debug("Reconciling", zap.Any("ConfigMapPropagation", cmp)) cmp.Status.InitializeConditions() + if cmp.Status.CopyConfigMaps == nil { + cmp.Status.CopyConfigMaps = map[string]v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + } // 1. Create/update ConfigMaps from original namespace to current namespace // 2. Track changes of original ConfigMaps as well as copy ConfigMaps @@ -248,7 +251,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: originalConfigMapName}.String() expectedStatus := r.newCopyConfigMapStatus(source, deleteConfigMap) - if err = r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { + if err, deleted := r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, fmt.Sprintf("Failed to propagate ConfigMap %v: %v", originalConfigMapName, err)) @@ -257,7 +260,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi } expectedStatus.Reason = err.Error() cmp.Status.CopyConfigMaps[source] = expectedStatus - } else { + } else if deleted { delete(cmp.Status.CopyConfigMaps, source) } } @@ -276,7 +279,7 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 logging.FromContext(ctx).Error("Unable to get ConfigMap: "+current.Name+" in current namespace", zap.Error(err)) return fmt.Errorf("error getting ConfigMap in current namespace: %w", err), "" } - + msg := "" // Only update ConfigMap with knative.dev/config-propagation:copy label. // If the ConfigMap does not have this label, the controller must not update the ConfigMap. if current != nil { @@ -285,12 +288,13 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 // OwnerReference will be removed when the propagation label is not set to copy // so that this copied configmap will not be deleted if cmp is deleted current.OwnerReferences = nil - return nil, `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagation for this ConfigMap` + expected = current + msg = `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagation for this ConfigMap` } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Update(expected); err != nil { return fmt.Errorf("error updating ConfigMap in current namespace: %w", err), "" } - return nil, "" + return nil, msg } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Create(expected); err != nil { @@ -300,7 +304,7 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 return nil, "" } -func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string, originalConfigMapList []*corev1.ConfigMap) error { +func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string, originalConfigMapList []*corev1.ConfigMap) (error, bool) { originalConfigMap, contains := r.contains(originalConfigMapName, originalConfigMapList) expectedSelector := resources.ExpectedOriginalSelector(cmp.Spec.Selector) //if !contains || !r.isSubset(originalConfigMap.GetLabels(), resources.OriginalLabels(cmp.Spec.Selector)) { @@ -310,10 +314,11 @@ func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.Co ` no longer exists/no longer has "knative.dev/eventing/config-propagation:original" label, delete corresponding copy ConfigMap ` + copyConfigMap.Name) if err := r.KubeClientSet.CoreV1().ConfigMaps(cmp.Namespace).Delete(copyConfigMap.Name, &metav1.DeleteOptions{}); err != nil { logging.FromContext(ctx).Error("error deleting ConfigMap in current namespace", zap.Error(err)) - return err + return err, false } + return nil, true } - return nil + return nil, false } // contains returns a configmap object if its name is in a configmaplist diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 6363a564000..3bbe3755b3a 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -55,7 +55,7 @@ func WithConfigMapPropagationDeletionTimestamp(cmp *v1alpha1.ConfigMapPropagatio func WithConfigMapPropagationSelector(selector map[string]string) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { - cmp.Spec.Selector = &selector + cmp.Spec.Selector = selector } } From 4a4f250c2e3c38277906744e3c145a579546a273 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 15 Jan 2020 22:02:03 -0800 Subject: [PATCH 14/26] update status --- .../v1alpha1/configmappropagation_defaults.go | 2 +- .../configmappropagation_defaults_test.go | 8 +- .../configmappropagation_lifecycle.go | 18 +++ .../v1alpha1/configmappropagation_types.go | 9 +- .../configmappropagation_validation.go | 42 ++---- .../configmappropagation_validation_test.go | 16 +-- .../configs/v1alpha1/zz_generated.deepcopy.go | 10 +- .../configs/v1alpha1/configmappropagation.go | 2 +- .../typed/configs/v1alpha1/configs_client.go | 2 +- .../versioned/typed/configs/v1alpha1/doc.go | 2 +- .../typed/configs/v1alpha1/fake/doc.go | 2 +- .../fake/fake_configmappropagation.go | 2 +- .../v1alpha1/fake/fake_configs_client.go | 2 +- .../configs/v1alpha1/generated_expansion.go | 2 +- .../externalversions/configs/interface.go | 2 +- .../configs/v1alpha1/configmappropagation.go | 2 +- .../configs/v1alpha1/interface.go | 2 +- .../configmappropagation.go | 2 +- .../configmappropagation/fake/fake.go | 2 +- .../configs/v1alpha1/configmappropagation.go | 2 +- .../configs/v1alpha1/expansion_generated.go | 2 +- .../configmappropagation.go | 125 ++++++++++-------- .../configmappropagation_test.go | 51 +++++-- pkg/reconciler/namespace/resources/labels.go | 4 +- .../testing/configmappropagation.go | 27 +++- 25 files changed, 202 insertions(+), 138 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go index 83ac2f28fc3..a6eeb086bc5 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go @@ -24,6 +24,6 @@ func (cmp *ConfigMapPropagation) SetDefaults(ctx context.Context) { // If we haven't configured the selector, // then set the default selector to be an empty map if cmp != nil && cmp.Spec.Selector == nil { - cmp.Spec.Selector = map[string]string{} + cmp.Spec.Selector = &map[string]string{} } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go index c12e44b1659..eba607ca08b 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -37,15 +37,15 @@ func TestConfigMapPropagationDefaults(t *testing.T) { }{ "nil spec": { initial: ConfigMapPropagation{}, - expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: defaultSelector}}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: &defaultSelector}}, }, "selector empty": { initial: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: namespace}}, - expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: namespace, Selector: defaultSelector}}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{OriginalNamespace: namespace, Selector: &defaultSelector}}, }, "with selector": { - initial: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: otherSelector}}, - expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: otherSelector}}, + initial: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: &otherSelector}}, + expected: ConfigMapPropagation{Spec: ConfigMapPropagationSpec{Selector: &otherSelector}}, }, } for n, tc := range testCases { diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index db7b46c30ae..d04dfeaf645 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -52,3 +52,21 @@ func (cmps *ConfigMapPropagationStatus) MarkNotPropagated() { configMapPropagationCondSet.Manage(cmps).MarkFalse(ConfigMapPropagationConditionPropagated, "PropagationFailed", "ConfigMapPropagation could not fully propagate ConfigMaps from original namespace to current namespace") } + +func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(source, operation, ready, reason string, sourceGeneration *int64) { + if source != "" { + cmpsc.Source = source + } + if operation != "" { + cmpsc.Operation = operation + } + if ready != "" { + cmpsc.Ready = ready + } + if reason != "" { + cmpsc.Reason = reason + } + if sourceGeneration != nil { + cmpsc.SourceGeneration = *sourceGeneration + } +} diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index c759c79568b..68bcba2bb39 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -63,7 +63,7 @@ type ConfigMapPropagationSpec struct { OriginalNamespace string `json:"originalNamespace,omitempty"` // Selector only selects original configMaps with corresponding labels // +optional - Selector map[string]string `json:"selector,omitempty"` + Selector *map[string]string `json:"selector,omitempty"` } // ConfigMapPropagationStatus represents the current state of a ConfigMapPropagation. @@ -74,7 +74,7 @@ type ConfigMapPropagationStatus struct { duckv1.Status `json:",inline"` //CopyConfigMaps is the status for each copied configmap. - CopyConfigMaps map[string]ConfigMapPropagationStatusCopyConfigMap `json:"CopyConfigMaps,omitempty"` + CopyConfigMaps map[string]ConfigMapPropagationStatusCopyConfigMap `json:"CopyConfigmaps,omitempty"` } // ConfigMapPropagationStatusCopyConfigMap represents the status of a copied configmap @@ -82,7 +82,7 @@ type ConfigMapPropagationStatusCopyConfigMap struct { // Source is "originalNamespace/originalConfigMapName" Source string `json:"source,omitempty"` - // Operation represents the operation CMP takes for this configmap. The operations are copy|delete, + // Operation represents the operation CMP takes for this configmap. The operations are copy|delete|stop, Operation string `json:"operation,omitempty"` // Ready represents the operation is ready or not @@ -90,6 +90,9 @@ type ConfigMapPropagationStatusCopyConfigMap struct { // Reason indicates reasons if the operation is not ready Reason string `json:"reason,omitempty"` + + // Generation represents the generation of source configmap + SourceGeneration int64 `json:"generation,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index 4df5f110d19..31b0fcc20f4 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -19,7 +19,6 @@ package v1alpha1 import ( "context" "fmt" - "regexp" "strings" "k8s.io/apimachinery/pkg/util/validation" @@ -28,11 +27,6 @@ import ( "knative.dev/pkg/kmp" ) -var ( - // Only allow lowercase alphanumeric, starting with letters. - validSelectorName = regexp.MustCompile(`^[a-z][a-z0-9./-]*$`) -) - // Validate the ConfigMapPropagation. func (cmp *ConfigMapPropagation) Validate(ctx context.Context) *apis.FieldError { return cmp.Spec.Validate(ctx).ViaField("spec") @@ -47,30 +41,22 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE } if cmps.Selector != nil { - if len(cmps.Selector) == 0 { - fe := &apis.FieldError{ - Message: "At least one selector must be specified", - Paths: []string{"selector"}, - } - errs = errs.Also(fe) - } else { - for key, value := range cmps.Selector { - if err := validation.IsQualifiedName(key); len(err) != 0 { - fe := &apis.FieldError{ - Message: fmt.Sprintf("Invalid selector key: %v", key), - Paths: []string{"selector"}, - Details: strings.Join(err, "; "), - } - errs = errs.Also(fe) + for key, value := range *cmps.Selector { + if err := validation.IsQualifiedName(key); len(err) != 0 { + fe := &apis.FieldError{ + Message: fmt.Sprintf("Invalid selector key: %v", key), + Paths: []string{"selector"}, + Details: strings.Join(err, "; "), } - if err := validation.IsValidLabelValue(value); len(err) != 0 { - fe := &apis.FieldError{ - Message: fmt.Sprintf("Invalid selector value: %v", value), - Paths: []string{"selector"}, - Details: strings.Join(err, "; "), - } - errs = errs.Also(fe) + errs = errs.Also(fe) + } + if err := validation.IsValidLabelValue(value); len(err) != 0 { + fe := &apis.FieldError{ + Message: fmt.Sprintf("Invalid selector value: %v", value), + Paths: []string{"selector"}, + Details: strings.Join(err, "; "), } + errs = errs.Also(fe) } } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index 4f2a9935af3..599ba24d51d 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -67,19 +67,9 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { fe := apis.ErrMissingField("originalNamespace") return fe }(), - }, { - name: "empty selector", - cmps: &ConfigMapPropagationSpec{ - Selector: map[string]string{}, - OriginalNamespace: originalNamespace, - }, - want: &apis.FieldError{ - Message: "At least one selector must be specified", - Paths: []string{"selector"}, - }, }, { name: "missing original namespace", - cmps: &ConfigMapPropagationSpec{Selector: validSelector}, + cmps: &ConfigMapPropagationSpec{Selector: &validSelector}, want: func() *apis.FieldError { fe := apis.ErrMissingField("originalNamespace") return fe @@ -88,7 +78,7 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { name: "invalid selector key", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, - Selector: map[string]string{ + Selector: &map[string]string{ "*nvalid": "testing", }}, want: &apis.FieldError{ @@ -100,7 +90,7 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { name: "invalid seletor value", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, - Selector: map[string]string{ + Selector: &map[string]string{ "invalid": "test/ing", }}, want: &apis.FieldError{ diff --git a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go index 147512fe8a6..40ab3f110b4 100644 --- a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go @@ -90,9 +90,13 @@ func (in *ConfigMapPropagationSpec) DeepCopyInto(out *ConfigMapPropagationSpec) *out = *in if in.Selector != nil { in, out := &in.Selector, &out.Selector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val + *out = new(map[string]string) + if **in != nil { + in, out := *in, *out + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } } return diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go index d8e29c04011..dc075deec55 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go index 234ae8e2ad3..53285edf25b 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go index a1c6bb9fe8f..41e872fe9a9 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go index a00e5d7b21a..c7f6e65cab8 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go index 8f37589d0aa..c829aa87ffc 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go index f557cf3e2c5..6b97fff7e5a 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configs_client.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go index 978ee9a77f8..ef016fddbd2 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/informers/externalversions/configs/interface.go b/pkg/client/informers/externalversions/configs/interface.go index 8110f0edbec..a545b2e0441 100644 --- a/pkg/client/informers/externalversions/configs/interface.go +++ b/pkg/client/informers/externalversions/configs/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go b/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go index e85aa1edcbf..c36690cbfe8 100644 --- a/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go +++ b/pkg/client/informers/externalversions/configs/v1alpha1/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/informers/externalversions/configs/v1alpha1/interface.go b/pkg/client/informers/externalversions/configs/v1alpha1/interface.go index 7f699aadd55..98c0cd06b85 100644 --- a/pkg/client/informers/externalversions/configs/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/configs/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go index 52776dd173f..585887158b6 100644 --- a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go +++ b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go index cd0b6324351..3d6047ce3b2 100644 --- a/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go +++ b/pkg/client/injection/informers/configs/v1alpha1/configmappropagation/fake/fake.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/listers/configs/v1alpha1/configmappropagation.go b/pkg/client/listers/configs/v1alpha1/configmappropagation.go index abdbecd0724..3274646b754 100644 --- a/pkg/client/listers/configs/v1alpha1/configmappropagation.go +++ b/pkg/client/listers/configs/v1alpha1/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/client/listers/configs/v1alpha1/expansion_generated.go b/pkg/client/listers/configs/v1alpha1/expansion_generated.go index 12e98d74c4c..bded4cdb67d 100644 --- a/pkg/client/listers/configs/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/configs/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index da3ba92f8c8..d1c6b189a32 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -42,16 +42,18 @@ import ( ) const ( - // Name of the corev1.Events emitted from the reconciliation process + // Name of the corev1.Events emitted from the reconciliation process. configMapPropagationReconcileError = "ConfigMapPropagationReconcileError" configMapPropagationUpdateStatusFailed = "ConfigMapPropagationStatusFailed" configMapPropagationReadinessChanged = "ConfigMapPropagationReadinessChanged" configMapPropagationPropagateSingleConfigMapFailed = "ConfigMapPropagationPropagateSingleConfigMapFailed" configMapPropagationPropagateSingleConfigMapSucceed = "ConfigMapPropagationPropagateSingleConfigMapSucceed" - // Name of operation to propagate single configmap + // Name of operation to propagate single configmap. copyConfigMap = "copy" deleteConfigMap = "delete" + // stopConfigMap indicates a configmap stop propagating. + stopConfigMap = "stop" ) type Reconciler struct { @@ -66,14 +68,14 @@ type Reconciler struct { var configMapGVK = corev1.SchemeGroupVersion.WithKind("ConfigMap") -// Check that our Reconciler implements controller.Reconciler +// Check that our Reconciler implements controller.Reconciler. var _ controller.Reconciler = (*Reconciler)(nil) // Reconcile compares the actual state with the desired, and attempts to // converge the two. It then updates the Status block of the ConfigMapPropagation resource // with the current status of the resource. func (r *Reconciler) Reconcile(ctx context.Context, key string) error { - // Convert the namespace/name string into a distinct namespace and name + // Convert the namespace/name string into a distinct namespace and name. namespace, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { logging.FromContext(ctx).Error("invalid resource key") @@ -90,7 +92,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { return err } - // Don't modify the informers copy + // Don't modify the informers copy. configMapPropagation := original.DeepCopy() // Reconcile this copy of the ConfigMapPropagation and then write back any status @@ -104,8 +106,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { logging.FromContext(ctx).Debug("ConfigMapPropagation reconciled") } - // Since the reconciler took a crack at this, make sure it's reflected - // in the status correctly. + // Since the reconciler took a crack at this, make sure it's reflected in the status correctly. configMapPropagation.Status.ObservedGeneration = original.Generation if _, updateStatusErr := r.updateStatus(ctx, configMapPropagation); updateStatusErr != nil { @@ -114,7 +115,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { fmt.Sprintf("Failed to update ConfigMapPropagation's status: %v", updateStatusErr)) return updateStatusErr } - // Requeue if the resource is not ready: + // Requeue if the resource is not ready. return reconcileErr } @@ -125,8 +126,8 @@ func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropa cmp.Status.CopyConfigMaps = map[string]v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} } - // 1. Create/update ConfigMaps from original namespace to current namespace - // 2. Track changes of original ConfigMaps as well as copy ConfigMaps + // 1. Create/update ConfigMaps from original namespace to current namespace. + // 2. Track changes of original ConfigMaps as well as copy ConfigMaps. // No need to reconcile if the ConfigMapPropagation has been marked for deletion. if cmp.DeletionTimestamp != nil { @@ -138,7 +139,7 @@ func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropa // If Selector is set to match specific labels (the required labels from ConfigMapPropagation), // the tracker can't track changes when an original ConfigMap no longer has required labels. // One alternative way is to track the name of every qualified original ConfigMap, - // but this requires to track specific Selector as well, in order to notice newly qualified original ConfigMaps + // but this requires to track specific Selector as well, in order to notice newly qualified original ConfigMaps. originalConfigMapObjRef := tracker.Reference{ Kind: configMapGVK.Kind, APIVersion: configMapGVK.GroupVersion().String(), @@ -207,36 +208,46 @@ func (r *Reconciler) updateStatus(ctx context.Context, desired *v1alpha1.ConfigM func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { // List ConfigMaps in original namespace and create/update copy ConfigMap in current namespace. var errs error - originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(resources.ExpectedOriginalSelector(cmp.Spec.Selector)) + originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(resources.ExpectedOriginalSelector(*cmp.Spec.Selector)) if err != nil { logging.FromContext(ctx).Error("Unable to get the ConfigMap list in original namespace", zap.Error(err)) return err } for _, configMap := range originalConfigMapList { + key := resources.MakeCopyConfigMapName(cmp.Name, configMap.Name) source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: configMap.Name}.String() - expectedStatus := r.newCopyConfigMapStatus(source, copyConfigMap) - if err, msg := r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { + // Take original configmap generation, in order to later update copy configmap status. + sourceGeneration := &configMap.Generation + expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + // Variable "succeed" represents whether a create/update action is successful or not. + if err, succeed := r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, fmt.Sprintf("Failed to propagate ConfigMap %v: %v", configMap.Name, err)) if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.Reason = err.Error() + expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "false", err.Error(), sourceGeneration) + } else if !succeed { + // If there is no error, but the create/update action is not successful, + // this indicates the copy configmap's copy label is removed. + logging.FromContext(ctx).Debug("Stop propagating ConfigMap " + configMap.Name) + r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, + fmt.Sprintf("Stop propagating ConfigMap: %s", configMap.Name)) + expectedStatus.SetCopyConfigMapStatus(source, stopConfigMap, "true", + `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, + sourceGeneration) } else { logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Propagate ConfigMap %v succeed", configMap.Name)) - if msg != "" { - expectedStatus.Reason = msg - } else { - expectedStatus.Ready = "true" - } + expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "true", "", sourceGeneration) } - cmp.Status.CopyConfigMaps[source] = expectedStatus + // Update current copy configmap's status. + cmp.Status.CopyConfigMaps[key] = expectedStatus } - // List ConfigMaps in current namespace and delete copy ConfigMap if the corresponding original ConfigMap no longer exists or no longer has the required label + // List ConfigMaps in current namespace and delete copy ConfigMap if the corresponding original ConfigMap no longer exists or no longer has the required label. copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) if err != nil { logging.FromContext(ctx).Error("Unable to get the ConfigMap list in current namespace", zap.Error(err)) @@ -244,24 +255,32 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi } for _, copyConfigMap := range copyConfigMapList { - // Select copy ConfigMap which is controlled by current ConfigMapPropagation + // Select copy ConfigMap which is controlled by current ConfigMapPropagation. if metav1.IsControlledBy(copyConfigMap, cmp) { - // Get the name of original ConfigMap - // The name of Copy ConfigMap is followed by - + // Get the name of original ConfigMap. + // The name of Copy ConfigMap is followed by -. originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: originalConfigMapName}.String() - expectedStatus := r.newCopyConfigMapStatus(source, deleteConfigMap) - if err, deleted := r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { + expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + var sourceGeneration *int64 + if value, ok := cmp.Status.CopyConfigMaps[copyConfigMap.Name]; ok { + // The current copy configmap status will keep the original configmap generation here, + // because the generation update is done when creating/updating copy configmap. + sourceGeneration = &value.DeepCopy().SourceGeneration + } + // Variable "succeed" represents whether a delete action is successful or not. + if err, succeed := r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) r.Recorder.Eventf(cmp, corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, fmt.Sprintf("Failed to propagate ConfigMap %v: %v", originalConfigMapName, err)) if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.Reason = err.Error() - cmp.Status.CopyConfigMaps[source] = expectedStatus - } else if deleted { - delete(cmp.Status.CopyConfigMaps, source) + expectedStatus.SetCopyConfigMapStatus(source, deleteConfigMap, "false", err.Error(), sourceGeneration) + cmp.Status.CopyConfigMaps[copyConfigMap.Name] = expectedStatus + } else if succeed { + // If copy configmap is deleted successfully, delete status. + delete(cmp.Status.CopyConfigMaps, copyConfigMap.Name) } } } @@ -269,7 +288,8 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi return errs } -func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, configMap *corev1.ConfigMap) (error, string) { +// createOrUpdateConfigMaps will return error and bool (represents whether a create/update action is successful or not). +func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, configMap *corev1.ConfigMap) (error, bool) { expected := resources.MakeConfigMap(resources.ConfigMapArgs{ Original: configMap, ConfigMapPropagation: cmp, @@ -277,37 +297,39 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 current, err := r.configMapLister.ConfigMaps(cmp.Namespace).Get(expected.Name) if err != nil && !apierrs.IsNotFound(err) { logging.FromContext(ctx).Error("Unable to get ConfigMap: "+current.Name+" in current namespace", zap.Error(err)) - return fmt.Errorf("error getting ConfigMap in current namespace: %w", err), "" + return fmt.Errorf("error getting ConfigMap in current namespace: %w", err), false } - msg := "" + // Only update ConfigMap with knative.dev/config-propagation:copy label. // If the ConfigMap does not have this label, the controller must not update the ConfigMap. if current != nil { label := current.GetLabels() + succeed := true if label[resources.PropagationLabelKey] != resources.PropagationLabelValueCopy { - // OwnerReference will be removed when the propagation label is not set to copy - // so that this copied configmap will not be deleted if cmp is deleted - current.OwnerReferences = nil - expected = current - msg = `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagation for this ConfigMap` + // OwnerReference will be removed when the knative.dev/config-propagation:copy label is not set in copy configmap + // so that this copy configmap will not be deleted if cmp is deleted. + expected = current.DeepCopy() + expected.OwnerReferences = nil + // It will return false for the create/update action is not successful, due to removed copy label. + // But it is not an error for ConfigMapPropagation for not propagating successfully. + succeed = false } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Update(expected); err != nil { - return fmt.Errorf("error updating ConfigMap in current namespace: %w", err), "" + return fmt.Errorf("error updating ConfigMap in current namespace: %w", err), false } - return nil, msg + return nil, succeed } if current, err = r.KubeClientSet.CoreV1().ConfigMaps(expected.Namespace).Create(expected); err != nil { - return fmt.Errorf("error creating ConfigMap in current namespace: %w", err), "" + return fmt.Errorf("error creating ConfigMap in current namespace: %w", err), false } - - return nil, "" + return nil, true } +// deleteOrKeepConfigMap will return error and bool (represents whether a delete action is successful or not). func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string, originalConfigMapList []*corev1.ConfigMap) (error, bool) { originalConfigMap, contains := r.contains(originalConfigMapName, originalConfigMapList) - expectedSelector := resources.ExpectedOriginalSelector(cmp.Spec.Selector) - //if !contains || !r.isSubset(originalConfigMap.GetLabels(), resources.OriginalLabels(cmp.Spec.Selector)) { + expectedSelector := resources.ExpectedOriginalSelector(*cmp.Spec.Selector) if !contains || !expectedSelector.Matches(labels.Set(originalConfigMap.Labels)) { // If Original ConfigMap no longer exists or no longer has the required label, delete copy ConfigMap. logging.FromContext(ctx).Info("Original ConfigMap " + originalConfigMapName + @@ -321,7 +343,7 @@ func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.Co return nil, false } -// contains returns a configmap object if its name is in a configmaplist +// contains returns a configmap object if its name is in a configmaplist. func (r *Reconciler) contains(name string, list []*corev1.ConfigMap) (*corev1.ConfigMap, bool) { for _, configMap := range list { if configMap.Name == name { @@ -330,12 +352,3 @@ func (r *Reconciler) contains(name string, list []*corev1.ConfigMap) (*corev1.Co } return nil, false } - -func (r *Reconciler) newCopyConfigMapStatus(source, operation string) v1alpha1.ConfigMapPropagationStatusCopyConfigMap { - return v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ - Source: source, - Operation: operation, - Ready: "false", - Reason: "", - } -} diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 01f4b7c0b6d..6e2699f415c 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -89,7 +89,9 @@ func TestAllCase(t *testing.T) { Objects: []runtime.Object{ NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, - WithConfigMapPropagationDeletionTimestamp), + WithConfigMapPropagationDeletionTimestamp, + WithInitConfigMapStatus(), + ), }, }, { Name: "Original ConfigMap no longer has required labels", @@ -130,6 +132,7 @@ func TestAllCase(t *testing.T) { NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -179,6 +182,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationNotPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "delete", "false", "inducing failure for delete configmaps"), ), }}, WantErr: true, @@ -189,12 +195,13 @@ func TestAllCase(t *testing.T) { "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), }, }, { - Name: "Original ConfigMap has changed, update copy ConfigMap succeeded", + Name: "Original ConfigMap has changed, update copy ConfigMap failed", Key: testKey, Objects: []runtime.Object{ NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), @@ -226,6 +233,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationNotPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps"), ), }}, WantErr: true, @@ -236,12 +246,13 @@ func TestAllCase(t *testing.T) { "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), }, }, { - Name: "Original ConfigMap has changed, update copy ConfigMap failed", + Name: "Original ConfigMap has changed, update copy ConfigMap succeeded", Key: testKey, Objects: []runtime.Object{ NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), @@ -270,6 +281,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "copy", "true", ""), ), }}, WantEvents: []string{ @@ -283,6 +297,7 @@ func TestAllCase(t *testing.T) { NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), @@ -312,6 +327,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "copy", "true", ""), ), }}, WantEvents: []string{ @@ -337,19 +355,26 @@ func TestAllCase(t *testing.T) { )), ), }, + WantUpdates: []clientgotesting.UpdateActionImpl{{ + Object: NewConfigMap(copyConfigMapName, currentNS, + WithConfigMapLabels(map[string]string{}), + ), + }}, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), - WithConfigMapPropagationNotPropagated, + WithConfigMapPropagationPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), ), }}, - WantErr: true, + WantErr: false, WantEvents: []string{ - Eventf(corev1.EventTypeWarning, configMapPropagationPropagateSingleConfigMapFailed, - `Failed to propagate ConfigMap %v: unable to update ConfigMap in current namespace, ConfigMap doesn't have "knative.dev/config-propagation:copy" label`, originalConfigMapName), - Eventf(corev1.EventTypeWarning, configMapPropagationReconcileError, - "ConfigMapPropagation reconcile error: one or more ConfigMap propagation failed"), + Eventf(corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, + `Stop propagating ConfigMap: test-original-cm`), + Eventf(corev1.EventTypeNormal, configMapPropagationReadinessChanged, "ConfigMapPropagation %q became ready", configMapPropagationName), }, }, { Name: "Create new ConfigMap failed", @@ -358,6 +383,7 @@ func TestAllCase(t *testing.T) { NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), @@ -380,6 +406,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationNotPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps"), ), }}, WantErr: true, @@ -397,6 +426,7 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationGeneration(configMapPropagationGeneration), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), @@ -418,6 +448,9 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithConfigMapPropagationGeneration(configMapPropagationGeneration), WithConfigMapPropagationStatusObservedGeneration(configMapPropagationGeneration), + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "copy", "true", ""), ), }}, WantEvents: []string{ diff --git a/pkg/reconciler/namespace/resources/labels.go b/pkg/reconciler/namespace/resources/labels.go index 4512b5e2b04..b9396ac1647 100644 --- a/pkg/reconciler/namespace/resources/labels.go +++ b/pkg/reconciler/namespace/resources/labels.go @@ -34,8 +34,8 @@ func OwnedLabels() map[string]string { } // ConfigMapPropagationOwnedLabels generates the labels present on injected broker resources. -func ConfigMapPropagationOwnedLabels() map[string]string { - return map[string]string{ +func ConfigMapPropagationOwnedLabels() *map[string]string { + return &map[string]string{ CmpDefaultLabelKey: CmpDefaultLabelValue, } } diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 3bbe3755b3a..a03d97e5a45 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -48,6 +48,23 @@ func WithInitConfigMapPropagationConditions(cmp *v1alpha1.ConfigMapPropagation) cmp.Status.InitializeConditions() } +func WithInitConfigMapStatus() ConfigMapPropagationOption { + return func(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.CopyConfigMaps = map[string]v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + } +} + +func WithCopyConfigMapStatus(key, source, operation, ready, reason string) ConfigMapPropagationOption { + return func(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.CopyConfigMaps[key] = v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ + Source: source, + Operation: operation, + Ready: ready, + Reason: reason, + } + } +} + func WithConfigMapPropagationDeletionTimestamp(cmp *v1alpha1.ConfigMapPropagation) { t := metav1.NewTime(time.Unix(1e9, 0)) cmp.ObjectMeta.SetDeletionTimestamp(&t) @@ -55,19 +72,19 @@ func WithConfigMapPropagationDeletionTimestamp(cmp *v1alpha1.ConfigMapPropagatio func WithConfigMapPropagationSelector(selector map[string]string) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { - cmp.Spec.Selector = selector + cmp.Spec.Selector = &selector } } func WithConfigMapPropagationGeneration(gen int64) ConfigMapPropagationOption { - return func(s *v1alpha1.ConfigMapPropagation) { - s.Generation = gen + return func(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Generation = gen } } func WithConfigMapPropagationStatusObservedGeneration(gen int64) ConfigMapPropagationOption { - return func(s *v1alpha1.ConfigMapPropagation) { - s.Status.ObservedGeneration = gen + return func(cmp *v1alpha1.ConfigMapPropagation) { + cmp.Status.ObservedGeneration = gen } } From de812771db478ff57cd8598072014c821b2ff753 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 15 Jan 2020 22:46:18 -0800 Subject: [PATCH 15/26] add unit test + update perf test --- .../configmappropagation_test.go | 21 +++++++---- pkg/reconciler/testing/configmap.go | 6 ++++ .../testing/configmappropagation.go | 11 +++--- .../broker-imc/100-broker-perf-setup.yaml | 36 +++++-------------- .../continuous/100-broker-imc-setup.yaml | 36 +++++-------------- 5 files changed, 42 insertions(+), 68 deletions(-) diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 6e2699f415c..b58a838c0a3 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -44,6 +44,7 @@ const ( originalConfigMapName = "test-original-cm" originalNS = "knative-eventing" + configMapGeneration = int64(9) configMapPropagationGeneration = 7 ) @@ -184,7 +185,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "delete", "false", "inducing failure for delete configmaps"), + "delete", "false", "inducing failure for delete configmaps", int64(0)), ), }}, WantErr: true, @@ -206,6 +207,7 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), + WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -235,7 +237,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps"), + "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps", configMapGeneration), ), }}, WantErr: true, @@ -257,6 +259,7 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), + WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -283,7 +286,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "copy", "true", "", configMapGeneration), ), }}, WantEvents: []string{ @@ -302,6 +305,7 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), + WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -329,7 +333,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "copy", "true", "", configMapGeneration), ), }}, WantEvents: []string{ @@ -346,6 +350,7 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), + WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(map[string]string{}), @@ -367,7 +372,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), + "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, configMapGeneration), ), }}, WantErr: false, @@ -387,6 +392,7 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), + WithConfigMapGeneration(configMapGeneration), ), }, WantCreates: []runtime.Object{ @@ -408,7 +414,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps"), + "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps", configMapGeneration), ), }}, WantErr: true, @@ -430,6 +436,7 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), + WithConfigMapGeneration(configMapGeneration), ), }, WantCreates: []runtime.Object{ @@ -450,7 +457,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationStatusObservedGeneration(configMapPropagationGeneration), WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "copy", "true", "", configMapGeneration), ), }}, WantEvents: []string{ diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go index 41c38bf61f1..9f7e35727f2 100644 --- a/pkg/reconciler/testing/configmap.go +++ b/pkg/reconciler/testing/configmap.go @@ -47,6 +47,12 @@ func WithConfigMapLabels(labels map[string]string) ConfigMapOption { } } +func WithConfigMapGeneration(generation int64) ConfigMapOption { + return func(cm *v1.ConfigMap) { + cm.Generation = generation + } +} + func WithConfigMapOwnerReference(ConfigMapPropagation *v1alpha1.ConfigMapPropagation) ConfigMapOption { return func(cm *v1.ConfigMap) { cm.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index a03d97e5a45..47cd38b9115 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -54,13 +54,14 @@ func WithInitConfigMapStatus() ConfigMapPropagationOption { } } -func WithCopyConfigMapStatus(key, source, operation, ready, reason string) ConfigMapPropagationOption { +func WithCopyConfigMapStatus(key, source, operation, ready, reason string, sourceGeneration int64) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { cmp.Status.CopyConfigMaps[key] = v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ - Source: source, - Operation: operation, - Ready: ready, - Reason: reason, + Source: source, + Operation: operation, + Ready: ready, + Reason: reason, + SourceGeneration: sourceGeneration, } } } diff --git a/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml b/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml index 7fb68b70f90..c7503681a77 100644 --- a/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml +++ b/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml @@ -128,35 +128,15 @@ roleRef: --- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding +apiVersion: configs.knative.dev/v1alpha1 +kind: ConfigMapPropagation metadata: - name: eventing-config-reader-default-eventing-broker-ingress - namespace: knative-eventing -subjects: - - kind: ServiceAccount - name: eventing-broker-ingress - namespace: perf-eventing -roleRef: - kind: ClusterRole - name: eventing-config-reader - apiGroup: rbac.authorization.k8s.io - ---- - -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: eventing-config-reader-default-eventing-broker-filter - namespace: knative-eventing -subjects: - - kind: ServiceAccount - name: eventing-broker-filter - namespace: perf-eventing -roleRef: - kind: ClusterRole - name: eventing-config-reader - apiGroup: rbac.authorization.k8s.io + name: perf-eventing-cmp + namespace: perf-eventing +spec: + originalNamespace: knative-eventing + selector: + knative.dev/config-category: eventing --- diff --git a/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml b/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml index 7ed5fe24e3b..0dd29793e67 100644 --- a/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml +++ b/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml @@ -121,35 +121,15 @@ roleRef: --- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding +apiVersion: configs.knative.dev/v1alpha1 +kind: ConfigMapPropagation metadata: - name: eventing-config-reader-default-eventing-broker-ingress - namespace: knative-eventing -subjects: - - kind: ServiceAccount - name: eventing-broker-ingress - namespace: default -roleRef: - kind: ClusterRole - name: eventing-config-reader - apiGroup: rbac.authorization.k8s.io - ---- - -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: eventing-config-reader-default-eventing-broker-filter - namespace: knative-eventing -subjects: - - kind: ServiceAccount - name: eventing-broker-filter - namespace: default -roleRef: - kind: ClusterRole - name: eventing-config-reader - apiGroup: rbac.authorization.k8s.io + name: perf-eventing-cmp + namespace: default +spec: + originalNamespace: knative-eventing + selector: + knative.dev/config-category: eventing --- From b370aa919854e873073e7b4343619c81da89913a Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 15 Jan 2020 22:56:57 -0800 Subject: [PATCH 16/26] copyright year --- pkg/apis/configs/register.go | 2 +- pkg/apis/configs/v1alpha1/configmappropagation_defaults.go | 2 +- .../configs/v1alpha1/configmappropagation_defaults_test.go | 2 +- pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go | 2 +- .../configs/v1alpha1/configmappropagation_lifecycle_test.go | 2 +- pkg/apis/configs/v1alpha1/configmappropagation_types.go | 2 +- .../configs/v1alpha1/configmappropagation_types_test.go | 6 +++--- .../configs/v1alpha1/configmappropagation_validation.go | 2 +- .../v1alpha1/configmappropagation_validation_test.go | 2 +- pkg/apis/configs/v1alpha1/doc.go | 2 +- pkg/apis/configs/v1alpha1/register.go | 2 +- pkg/apis/configs/v1alpha1/register_test.go | 2 +- pkg/reconciler/configmappropagation/configmappropagation.go | 2 +- .../configmappropagation/configmappropagation_test.go | 2 +- pkg/reconciler/configmappropagation/controller.go | 2 +- pkg/reconciler/configmappropagation/controller_test.go | 2 +- pkg/reconciler/configmappropagation/resources/configmap.go | 2 +- .../configmappropagation/resources/configmap_test.go | 2 +- pkg/reconciler/configmappropagation/resources/labels.go | 2 +- .../configmappropagation/resources/labels_test.go | 2 +- pkg/reconciler/namespace/resources/configmappropagation.go | 2 +- pkg/reconciler/testing/configmap.go | 2 +- pkg/reconciler/testing/configmappropagation.go | 2 +- 23 files changed, 25 insertions(+), 25 deletions(-) diff --git a/pkg/apis/configs/register.go b/pkg/apis/configs/register.go index 8e33b6faaeb..8a6241a546b 100644 --- a/pkg/apis/configs/register.go +++ b/pkg/apis/configs/register.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go index a6eeb086bc5..54e954ce2c5 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go index eba607ca08b..f391d509dc0 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index d04dfeaf645..becbdb3ec8c 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index 084a31a2ff5..b79bc654535 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 68bcba2bb39..52a84b39e9c 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go index ca9c8df5159..bd2d8285665 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types_test.go @@ -1,5 +1,5 @@ /* - * Copyright 2019 The Knative Authors + * 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. @@ -30,8 +30,8 @@ func TestConfigMapPropagation_GetGroupVersionKind(t *testing.T) { } func TestConfigMapPropagation_GetUntypedSpec(t *testing.T) { cmp := ConfigMapPropagation{} - int := cmp.GetUntypedSpec() - if !reflect.DeepEqual(int, cmp.Spec) { + in := cmp.GetUntypedSpec() + if !reflect.DeepEqual(in, cmp.Spec) { t.Errorf("Should be ConfigMapPropagationSpec.") } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index 31b0fcc20f4..c836c097543 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index 599ba24d51d..1f86e8a7807 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/doc.go b/pkg/apis/configs/v1alpha1/doc.go index 7417f460d83..787c633705d 100644 --- a/pkg/apis/configs/v1alpha1/doc.go +++ b/pkg/apis/configs/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/register.go b/pkg/apis/configs/v1alpha1/register.go index bb54a18d3b9..0d4dcca50f1 100644 --- a/pkg/apis/configs/v1alpha1/register.go +++ b/pkg/apis/configs/v1alpha1/register.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/apis/configs/v1alpha1/register_test.go b/pkg/apis/configs/v1alpha1/register_test.go index f384ea8b431..857dc9cb710 100644 --- a/pkg/apis/configs/v1alpha1/register_test.go +++ b/pkg/apis/configs/v1alpha1/register_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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 diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index d1c6b189a32..3b028c4f93c 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index b58a838c0a3..709a4766247 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/controller.go b/pkg/reconciler/configmappropagation/controller.go index a5c1955a290..7808253ac45 100644 --- a/pkg/reconciler/configmappropagation/controller.go +++ b/pkg/reconciler/configmappropagation/controller.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/controller_test.go b/pkg/reconciler/configmappropagation/controller_test.go index f0a53ddbce1..f74d38f89e1 100644 --- a/pkg/reconciler/configmappropagation/controller_test.go +++ b/pkg/reconciler/configmappropagation/controller_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/resources/configmap.go b/pkg/reconciler/configmappropagation/resources/configmap.go index 13bc6f90139..0eb47485a9f 100644 --- a/pkg/reconciler/configmappropagation/resources/configmap.go +++ b/pkg/reconciler/configmappropagation/resources/configmap.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/resources/configmap_test.go b/pkg/reconciler/configmappropagation/resources/configmap_test.go index 2021b8892cf..9cff2a3a72c 100644 --- a/pkg/reconciler/configmappropagation/resources/configmap_test.go +++ b/pkg/reconciler/configmappropagation/resources/configmap_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/resources/labels.go b/pkg/reconciler/configmappropagation/resources/labels.go index 9db40d36834..0f62f59545d 100644 --- a/pkg/reconciler/configmappropagation/resources/labels.go +++ b/pkg/reconciler/configmappropagation/resources/labels.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/configmappropagation/resources/labels_test.go b/pkg/reconciler/configmappropagation/resources/labels_test.go index 49bfd8a651f..3e898bbde2d 100644 --- a/pkg/reconciler/configmappropagation/resources/labels_test.go +++ b/pkg/reconciler/configmappropagation/resources/labels_test.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/namespace/resources/configmappropagation.go b/pkg/reconciler/namespace/resources/configmappropagation.go index a2b6a7762f2..3865318e7cc 100644 --- a/pkg/reconciler/namespace/resources/configmappropagation.go +++ b/pkg/reconciler/namespace/resources/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go index 9f7e35727f2..148714e12b7 100644 --- a/pkg/reconciler/testing/configmap.go +++ b/pkg/reconciler/testing/configmap.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 47cd38b9115..67b51331651 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -1,5 +1,5 @@ /* -Copyright 2019 The Knative Authors +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. From 005d94378f5c6387b0a2c784226488de16674138 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Wed, 15 Jan 2020 23:10:57 -0800 Subject: [PATCH 17/26] update unit test --- .../configmappropagation_lifecycle_test.go | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index b79bc654535..92c86482a7a 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + "reflect" "testing" "github.com/google/go-cmp/cmp" @@ -199,3 +200,28 @@ func TestConfigMapPropagationIsReady(t *testing.T) { }) } } + +func TestSetCopyConfigMapStatus(t *testing.T) { + sourceGeneration := int64(4) + tests := []struct { + name string + cmpsc *ConfigMapPropagationStatusCopyConfigMap + want *ConfigMapPropagationStatusCopyConfigMap + }{{ + name: "all happy", + cmpsc: &ConfigMapPropagationStatusCopyConfigMap{}, + want: &ConfigMapPropagationStatusCopyConfigMap{ + "source", "operation", + "ready", "reason", sourceGeneration, + }, + }} + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.cmpsc.SetCopyConfigMapStatus("source", "operation", + "ready", "reason", &sourceGeneration) + if got := test.cmpsc; !reflect.DeepEqual(test.want, got) { + t.Errorf("unexpected readiness: want %v, got %v", test.want, got) + } + }) + } +} From 92a3f4854ce2bff38fa9b50a91cf370269b84e2e Mon Sep 17 00:00:00 2001 From: grac3gao Date: Thu, 16 Jan 2020 11:02:50 -0800 Subject: [PATCH 18/26] remove generation --- .../configmappropagation_lifecycle.go | 5 +---- .../configmappropagation_lifecycle_test.go | 5 ++--- .../v1alpha1/configmappropagation_types.go | 3 --- .../configmappropagation.go | 17 ++++----------- .../configmappropagation_test.go | 21 +++++++------------ pkg/reconciler/testing/configmap.go | 6 ------ .../testing/configmappropagation.go | 11 +++++----- 7 files changed, 19 insertions(+), 49 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index becbdb3ec8c..bf9443c237c 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -53,7 +53,7 @@ func (cmps *ConfigMapPropagationStatus) MarkNotPropagated() { "ConfigMapPropagation could not fully propagate ConfigMaps from original namespace to current namespace") } -func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(source, operation, ready, reason string, sourceGeneration *int64) { +func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(source, operation, ready, reason string) { if source != "" { cmpsc.Source = source } @@ -66,7 +66,4 @@ func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(sou if reason != "" { cmpsc.Reason = reason } - if sourceGeneration != nil { - cmpsc.SourceGeneration = *sourceGeneration - } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index 92c86482a7a..0fb4c76abbe 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -202,7 +202,6 @@ func TestConfigMapPropagationIsReady(t *testing.T) { } func TestSetCopyConfigMapStatus(t *testing.T) { - sourceGeneration := int64(4) tests := []struct { name string cmpsc *ConfigMapPropagationStatusCopyConfigMap @@ -212,13 +211,13 @@ func TestSetCopyConfigMapStatus(t *testing.T) { cmpsc: &ConfigMapPropagationStatusCopyConfigMap{}, want: &ConfigMapPropagationStatusCopyConfigMap{ "source", "operation", - "ready", "reason", sourceGeneration, + "ready", "reason", }, }} for _, test := range tests { t.Run(test.name, func(t *testing.T) { test.cmpsc.SetCopyConfigMapStatus("source", "operation", - "ready", "reason", &sourceGeneration) + "ready", "reason") if got := test.cmpsc; !reflect.DeepEqual(test.want, got) { t.Errorf("unexpected readiness: want %v, got %v", test.want, got) } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 52a84b39e9c..4b00cbe9246 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -90,9 +90,6 @@ type ConfigMapPropagationStatusCopyConfigMap struct { // Reason indicates reasons if the operation is not ready Reason string `json:"reason,omitempty"` - - // Generation represents the generation of source configmap - SourceGeneration int64 `json:"generation,omitempty"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index 3b028c4f93c..bffe9d5b990 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -216,8 +216,6 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi for _, configMap := range originalConfigMapList { key := resources.MakeCopyConfigMapName(cmp.Name, configMap.Name) source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: configMap.Name}.String() - // Take original configmap generation, in order to later update copy configmap status. - sourceGeneration := &configMap.Generation expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} // Variable "succeed" represents whether a create/update action is successful or not. if err, succeed := r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { @@ -227,7 +225,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "false", err.Error(), sourceGeneration) + expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "false", err.Error()) } else if !succeed { // If there is no error, but the create/update action is not successful, // this indicates the copy configmap's copy label is removed. @@ -235,13 +233,12 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Stop propagating ConfigMap: %s", configMap.Name)) expectedStatus.SetCopyConfigMapStatus(source, stopConfigMap, "true", - `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, - sourceGeneration) + `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`) } else { logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Propagate ConfigMap %v succeed", configMap.Name)) - expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "true", "", sourceGeneration) + expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "true", "") } // Update current copy configmap's status. cmp.Status.CopyConfigMaps[key] = expectedStatus @@ -262,12 +259,6 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: originalConfigMapName}.String() expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} - var sourceGeneration *int64 - if value, ok := cmp.Status.CopyConfigMaps[copyConfigMap.Name]; ok { - // The current copy configmap status will keep the original configmap generation here, - // because the generation update is done when creating/updating copy configmap. - sourceGeneration = &value.DeepCopy().SourceGeneration - } // Variable "succeed" represents whether a delete action is successful or not. if err, succeed := r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) @@ -276,7 +267,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(source, deleteConfigMap, "false", err.Error(), sourceGeneration) + expectedStatus.SetCopyConfigMapStatus(source, deleteConfigMap, "false", err.Error()) cmp.Status.CopyConfigMaps[copyConfigMap.Name] = expectedStatus } else if succeed { // If copy configmap is deleted successfully, delete status. diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 709a4766247..39e8d016b36 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -44,7 +44,6 @@ const ( originalConfigMapName = "test-original-cm" originalNS = "knative-eventing" - configMapGeneration = int64(9) configMapPropagationGeneration = 7 ) @@ -185,7 +184,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "delete", "false", "inducing failure for delete configmaps", int64(0)), + "delete", "false", "inducing failure for delete configmaps"), ), }}, WantErr: true, @@ -207,7 +206,6 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), - WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -237,7 +235,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps", configMapGeneration), + "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps"), ), }}, WantErr: true, @@ -259,7 +257,6 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), - WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -286,7 +283,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", "", configMapGeneration), + "copy", "true", ""), ), }}, WantEvents: []string{ @@ -305,7 +302,6 @@ func TestAllCase(t *testing.T) { NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), WithConfigMapData(originalData), - WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -333,7 +329,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", "", configMapGeneration), + "copy", "true", ""), ), }}, WantEvents: []string{ @@ -350,7 +346,6 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), - WithConfigMapGeneration(configMapGeneration), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(map[string]string{}), @@ -372,7 +367,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, configMapGeneration), + "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), ), }}, WantErr: false, @@ -392,7 +387,6 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), - WithConfigMapGeneration(configMapGeneration), ), }, WantCreates: []runtime.Object{ @@ -414,7 +408,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps", configMapGeneration), + "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps"), ), }}, WantErr: true, @@ -436,7 +430,6 @@ func TestAllCase(t *testing.T) { ), NewConfigMap(originalConfigMapName, originalNS, WithConfigMapLabels(originalSelector), - WithConfigMapGeneration(configMapGeneration), ), }, WantCreates: []runtime.Object{ @@ -457,7 +450,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationStatusObservedGeneration(configMapPropagationGeneration), WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", "", configMapGeneration), + "copy", "true", ""), ), }}, WantEvents: []string{ diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go index 148714e12b7..e56ca9b6800 100644 --- a/pkg/reconciler/testing/configmap.go +++ b/pkg/reconciler/testing/configmap.go @@ -47,12 +47,6 @@ func WithConfigMapLabels(labels map[string]string) ConfigMapOption { } } -func WithConfigMapGeneration(generation int64) ConfigMapOption { - return func(cm *v1.ConfigMap) { - cm.Generation = generation - } -} - func WithConfigMapOwnerReference(ConfigMapPropagation *v1alpha1.ConfigMapPropagation) ConfigMapOption { return func(cm *v1.ConfigMap) { cm.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 67b51331651..1bbd607364f 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -54,14 +54,13 @@ func WithInitConfigMapStatus() ConfigMapPropagationOption { } } -func WithCopyConfigMapStatus(key, source, operation, ready, reason string, sourceGeneration int64) ConfigMapPropagationOption { +func WithCopyConfigMapStatus(key, source, operation, ready, reason string) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { cmp.Status.CopyConfigMaps[key] = v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ - Source: source, - Operation: operation, - Ready: ready, - Reason: reason, - SourceGeneration: sourceGeneration, + Source: source, + Operation: operation, + Ready: ready, + Reason: reason, } } } From f0af2c40a481ca0970c5f398ca383b9827437f1d Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 17 Jan 2020 10:28:51 -0800 Subject: [PATCH 19/26] labelSelector/status array/resourceVersion --- config/300-configmappropagation.yaml | 9 ---- .../v1alpha1/configmappropagation_defaults.go | 3 +- .../configmappropagation_defaults_test.go | 11 ++--- .../configmappropagation_lifecycle.go | 8 +++- .../configmappropagation_lifecycle_test.go | 6 +-- .../v1alpha1/configmappropagation_types.go | 21 ++++++++-- .../configmappropagation_validation.go | 2 +- .../configmappropagation_validation_test.go | 18 ++++---- .../configs/v1alpha1/zz_generated.deepcopy.go | 17 +++----- .../configmappropagation.go | 38 ++++++++--------- .../configmappropagation_test.go | 41 ++++++++++++++----- .../configmappropagation/resources/labels.go | 18 ++++---- .../resources/labels_test.go | 22 ++++++---- .../resources/configmappropagation.go | 2 +- pkg/reconciler/namespace/resources/labels.go | 4 +- pkg/reconciler/testing/configmap.go | 4 +- .../testing/configmappropagation.go | 11 ++--- test/lib/resources/eventing.go | 4 +- .../broker-imc/100-broker-perf-setup.yaml | 5 ++- .../continuous/100-broker-imc-setup.yaml | 5 ++- 20 files changed, 141 insertions(+), 108 deletions(-) diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index 77e0823e522..824b7385a38 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -49,23 +49,14 @@ spec: - name: OriginalNamespace type: string JSONPath: ".spec.originalNamespace" - - name: Selector - type: string - JSONPath: ".spec.selector" validation: openAPIV3Schema: properties: spec: required: - originalNamespace - - selector properties: originalNamespace: type: string description: "The namespace where original ConfigMaps exist in." - selector: - type: object - description: "Map of selectors used for select specific group of ConfigMaps." - additionalProperties: - type: string diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go index 54e954ce2c5..09942e9e4a1 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults.go @@ -18,12 +18,13 @@ package v1alpha1 import ( "context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func (cmp *ConfigMapPropagation) SetDefaults(ctx context.Context) { // If we haven't configured the selector, // then set the default selector to be an empty map if cmp != nil && cmp.Spec.Selector == nil { - cmp.Spec.Selector = &map[string]string{} + cmp.Spec.Selector = &metav1.LabelSelector{} } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go index f391d509dc0..cef3e1837ed 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_defaults_test.go @@ -18,16 +18,17 @@ package v1alpha1 import ( "context" - "github.com/google/go-cmp/cmp" "testing" + + "github.com/google/go-cmp/cmp" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( namespace = "testing-eventing" - defaultSelector = map[string]string{} - otherSelector = map[string]string{ - "knative.dev/testing": "eventing", - } + defaultSelector = metav1.LabelSelector{} + otherSelector = metav1.LabelSelector{MatchLabels: map[string]string{"testing": "testing"}} ) func TestConfigMapPropagationDefaults(t *testing.T) { diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index bf9443c237c..7e06f08df5a 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -53,7 +53,10 @@ func (cmps *ConfigMapPropagationStatus) MarkNotPropagated() { "ConfigMapPropagation could not fully propagate ConfigMaps from original namespace to current namespace") } -func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(source, operation, ready, reason string) { +func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(name, source, operation, ready, reason, resourceVersion string) { + if name != "" { + cmpsc.Name = name + } if source != "" { cmpsc.Source = source } @@ -66,4 +69,7 @@ func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(sou if reason != "" { cmpsc.Reason = reason } + if resourceVersion != "" { + cmpsc.ResourceVersion = resourceVersion + } } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go index 0fb4c76abbe..4c0ff73ca39 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle_test.go @@ -210,14 +210,12 @@ func TestSetCopyConfigMapStatus(t *testing.T) { name: "all happy", cmpsc: &ConfigMapPropagationStatusCopyConfigMap{}, want: &ConfigMapPropagationStatusCopyConfigMap{ - "source", "operation", - "ready", "reason", + "name", "source", "operation", "ready", "reason", "resourceVersion", }, }} for _, test := range tests { t.Run(test.name, func(t *testing.T) { - test.cmpsc.SetCopyConfigMapStatus("source", "operation", - "ready", "reason") + test.cmpsc.SetCopyConfigMapStatus("name", "source", "operation", "ready", "reason", "resourceVersion") if got := test.cmpsc; !reflect.DeepEqual(test.want, got) { t.Errorf("unexpected readiness: want %v, got %v", test.want, got) } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 4b00cbe9246..24df0ef61ab 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -63,7 +63,7 @@ type ConfigMapPropagationSpec struct { OriginalNamespace string `json:"originalNamespace,omitempty"` // Selector only selects original configMaps with corresponding labels // +optional - Selector *map[string]string `json:"selector,omitempty"` + Selector *metav1.LabelSelector `json:"selector,omitempty"` } // ConfigMapPropagationStatus represents the current state of a ConfigMapPropagation. @@ -74,22 +74,37 @@ type ConfigMapPropagationStatus struct { duckv1.Status `json:",inline"` //CopyConfigMaps is the status for each copied configmap. - CopyConfigMaps map[string]ConfigMapPropagationStatusCopyConfigMap `json:"CopyConfigmaps,omitempty"` + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + CopyConfigMaps []ConfigMapPropagationStatusCopyConfigMap `json:"copyConfigmaps" patchStrategy:"merge" patchMergeKey:"name"` } // ConfigMapPropagationStatusCopyConfigMap represents the status of a copied configmap type ConfigMapPropagationStatusCopyConfigMap struct { + // Name is copy configmap's name + // +required + Name string `json:"name,omitempty"` + // Source is "originalNamespace/originalConfigMapName" + // +required Source string `json:"source,omitempty"` - // Operation represents the operation CMP takes for this configmap. The operations are copy|delete|stop, + // Operation represents the operation CMP takes for this configmap. The operations are copy|delete|stop + // +required Operation string `json:"operation,omitempty"` // Ready represents the operation is ready or not + // +required Ready string `json:"ready,omitempty"` // Reason indicates reasons if the operation is not ready + // +optional Reason string `json:"reason,omitempty"` + + // ResourceVersion is the resourceVersion of original configmap + // +optional + ResourceVersion string `json:"resourceVersionFromSource,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index c836c097543..13fee9cb68f 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -41,7 +41,7 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE } if cmps.Selector != nil { - for key, value := range *cmps.Selector { + for key, value := range cmps.Selector.MatchLabels { if err := validation.IsQualifiedName(key); len(err) != 0 { fe := &apis.FieldError{ Message: fmt.Sprintf("Invalid selector key: %v", key), diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index 1f86e8a7807..abf0eb1f65f 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -18,17 +18,18 @@ package v1alpha1 import ( "context" + "testing" + "github.com/google/go-cmp/cmp" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" - "testing" ) var ( originalNamespace = "original" currentNamespace = "current" - validSelector = map[string]string{ - "testing": "testing", - } + validSelector = metav1.LabelSelector{MatchLabels: map[string]string{"testing": "testing"}} ) func TestConfigMapPropagationValidation(t *testing.T) { @@ -78,9 +79,8 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { name: "invalid selector key", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, - Selector: &map[string]string{ - "*nvalid": "testing", - }}, + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"*nvalid": "testing"}}, + }, want: &apis.FieldError{ Message: `Invalid selector key: *nvalid`, Paths: []string{"selector"}, @@ -90,9 +90,7 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { name: "invalid seletor value", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, - Selector: &map[string]string{ - "invalid": "test/ing", - }}, + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"invalid": "test/ing"}}}, want: &apis.FieldError{ Message: `Invalid selector value: test/ing`, Paths: []string{"selector"}, diff --git a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go index 40ab3f110b4..f8dc4793f85 100644 --- a/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/configs/v1alpha1/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha1 import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -90,14 +91,8 @@ func (in *ConfigMapPropagationSpec) DeepCopyInto(out *ConfigMapPropagationSpec) *out = *in if in.Selector != nil { in, out := &in.Selector, &out.Selector - *out = new(map[string]string) - if **in != nil { - in, out := *in, *out - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) } return } @@ -118,10 +113,8 @@ func (in *ConfigMapPropagationStatus) DeepCopyInto(out *ConfigMapPropagationStat in.Status.DeepCopyInto(&out.Status) if in.CopyConfigMaps != nil { in, out := &in.CopyConfigMaps, &out.CopyConfigMaps - *out = make(map[string]ConfigMapPropagationStatusCopyConfigMap, len(*in)) - for key, val := range *in { - (*out)[key] = val - } + *out = make([]ConfigMapPropagationStatusCopyConfigMap, len(*in)) + copy(*out, *in) } return } diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index bffe9d5b990..fcfa3a49e5e 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -81,7 +81,6 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { logging.FromContext(ctx).Error("invalid resource key") return nil } - // Get the ConfigMapPropagation resource with this namespace/name original, err := r.configMapPropagationLister.ConfigMapPropagations(namespace).Get(name) if apierrs.IsNotFound(err) { @@ -122,10 +121,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, key string) error { func (r *Reconciler) reconcile(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { logging.FromContext(ctx).Debug("Reconciling", zap.Any("ConfigMapPropagation", cmp)) cmp.Status.InitializeConditions() - if cmp.Status.CopyConfigMaps == nil { - cmp.Status.CopyConfigMaps = map[string]v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} - } - + cmp.Status.CopyConfigMaps = []v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} // 1. Create/update ConfigMaps from original namespace to current namespace. // 2. Track changes of original ConfigMaps as well as copy ConfigMaps. @@ -208,15 +204,16 @@ func (r *Reconciler) updateStatus(ctx context.Context, desired *v1alpha1.ConfigM func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation) error { // List ConfigMaps in original namespace and create/update copy ConfigMap in current namespace. var errs error - originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(resources.ExpectedOriginalSelector(*cmp.Spec.Selector)) + originalConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Spec.OriginalNamespace).List(resources.ExpectedOriginalSelector(cmp.Spec.Selector)) if err != nil { logging.FromContext(ctx).Error("Unable to get the ConfigMap list in original namespace", zap.Error(err)) return err } for _, configMap := range originalConfigMapList { - key := resources.MakeCopyConfigMapName(cmp.Name, configMap.Name) + name := resources.MakeCopyConfigMapName(cmp.Name, configMap.Name) source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: configMap.Name}.String() - expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + resourceVersion := configMap.ResourceVersion + var expectedStatus v1alpha1.ConfigMapPropagationStatusCopyConfigMap // Variable "succeed" represents whether a create/update action is successful or not. if err, succeed := r.createOrUpdateConfigMaps(ctx, cmp, configMap); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) @@ -225,25 +222,24 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "false", err.Error()) + expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "false", err.Error(), resourceVersion) } else if !succeed { // If there is no error, but the create/update action is not successful, // this indicates the copy configmap's copy label is removed. logging.FromContext(ctx).Debug("Stop propagating ConfigMap " + configMap.Name) r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Stop propagating ConfigMap: %s", configMap.Name)) - expectedStatus.SetCopyConfigMapStatus(source, stopConfigMap, "true", - `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`) + expectedStatus.SetCopyConfigMapStatus(name, source, stopConfigMap, "true", + `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, resourceVersion) } else { logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Propagate ConfigMap %v succeed", configMap.Name)) - expectedStatus.SetCopyConfigMapStatus(source, copyConfigMap, "true", "") + expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "true", "", resourceVersion) } // Update current copy configmap's status. - cmp.Status.CopyConfigMaps[key] = expectedStatus + cmp.Status.CopyConfigMaps = append(cmp.Status.CopyConfigMaps, expectedStatus) } - // List ConfigMaps in current namespace and delete copy ConfigMap if the corresponding original ConfigMap no longer exists or no longer has the required label. copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) if err != nil { @@ -258,7 +254,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi // The name of Copy ConfigMap is followed by -. originalConfigMapName := strings.TrimPrefix(copyConfigMap.Name, cmp.Name+"-") source := types.NamespacedName{Namespace: cmp.Spec.OriginalNamespace, Name: originalConfigMapName}.String() - expectedStatus := v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + var expectedStatus v1alpha1.ConfigMapPropagationStatusCopyConfigMap // Variable "succeed" represents whether a delete action is successful or not. if err, succeed := r.deleteOrKeepConfigMap(ctx, cmp, copyConfigMap, originalConfigMapName, originalConfigMapList); err != nil { logging.FromContext(ctx).Warn("Failed to propagate ConfigMap: ", zap.Error(err)) @@ -267,11 +263,13 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(source, deleteConfigMap, "false", err.Error()) - cmp.Status.CopyConfigMaps[copyConfigMap.Name] = expectedStatus + expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "false", err.Error(), "") } else if succeed { - // If copy configmap is deleted successfully, delete status. - delete(cmp.Status.CopyConfigMaps, copyConfigMap.Name) + expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "true", "", "") + } + if expectedStatus.Name != "" { + // expectedStatus with same name will be merged and updated. + cmp.Status.CopyConfigMaps = append(cmp.Status.CopyConfigMaps, expectedStatus) } } } @@ -320,7 +318,7 @@ func (r *Reconciler) createOrUpdateConfigMaps(ctx context.Context, cmp *v1alpha1 // deleteOrKeepConfigMap will return error and bool (represents whether a delete action is successful or not). func (r *Reconciler) deleteOrKeepConfigMap(ctx context.Context, cmp *v1alpha1.ConfigMapPropagation, copyConfigMap *corev1.ConfigMap, originalConfigMapName string, originalConfigMapList []*corev1.ConfigMap) (error, bool) { originalConfigMap, contains := r.contains(originalConfigMapName, originalConfigMapList) - expectedSelector := resources.ExpectedOriginalSelector(*cmp.Spec.Selector) + expectedSelector := resources.ExpectedOriginalSelector(cmp.Spec.Selector) if !contains || !expectedSelector.Matches(labels.Set(originalConfigMap.Labels)) { // If Original ConfigMap no longer exists or no longer has the required label, delete copy ConfigMap. logging.FromContext(ctx).Info("Original ConfigMap " + originalConfigMapName + diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 39e8d016b36..71f4a68b2b0 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/types" clientgotesting "k8s.io/client-go/testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/eventing/pkg/apis/configs/v1alpha1" "knative.dev/eventing/pkg/client/clientset/versioned/scheme" "knative.dev/eventing/pkg/reconciler" @@ -48,16 +49,20 @@ const ( ) var ( - selector = map[string]string{ - "testings": "testing", + selector = metav1.LabelSelector{ + MatchLabels: map[string]string{"testings": "testing"}, } - originalSelector = map[string]string{ - "testings": "testing", - resources.PropagationLabelKey: resources.PropagationLabelValueOriginal, + originalSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testings": "testing", + resources.PropagationLabelKey: resources.PropagationLabelValueOriginal, + }, } - copySelector = map[string]string{ - resources.PropagationLabelKey: resources.PropagationLabelValueCopy, - resources.CopyLabelKey: resources.MakeCopyConfigMapLabel(currentNS, originalConfigMapName), + copySelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + resources.PropagationLabelKey: resources.PropagationLabelValueCopy, + resources.CopyLabelKey: resources.MakeCopyConfigMapLabel(currentNS, originalConfigMapName), + }, } copyConfigMapName = resources.MakeCopyConfigMapName(configMapPropagationName, originalConfigMapName) originalData = map[string]string{"data": "original"} @@ -100,9 +105,12 @@ func TestAllCase(t *testing.T) { NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(originalConfigMapName, originalNS, - WithConfigMapLabels(map[string]string{}), + WithConfigMapLabels(metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -120,6 +128,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "delete", "true", ""), ), }}, WantEvents: []string{ @@ -150,6 +161,9 @@ func TestAllCase(t *testing.T) { WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), WithConfigMapPropagationPropagated, + WithInitConfigMapStatus(), + WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", + "delete", "true", ""), ), }}, WantEvents: []string{ @@ -162,6 +176,7 @@ func TestAllCase(t *testing.T) { NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), + WithInitConfigMapStatus(), ), NewConfigMap(copyConfigMapName, currentNS, WithConfigMapLabels(copySelector), @@ -348,7 +363,9 @@ func TestAllCase(t *testing.T) { WithConfigMapLabels(originalSelector), ), NewConfigMap(copyConfigMapName, currentNS, - WithConfigMapLabels(map[string]string{}), + WithConfigMapLabels(metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }), WithConfigMapOwnerReference(NewConfigMapPropagation(configMapPropagationName, currentNS, WithInitConfigMapPropagationConditions, WithConfigMapPropagationSelector(selector), @@ -357,7 +374,9 @@ func TestAllCase(t *testing.T) { }, WantUpdates: []clientgotesting.UpdateActionImpl{{ Object: NewConfigMap(copyConfigMapName, currentNS, - WithConfigMapLabels(map[string]string{}), + WithConfigMapLabels(metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }), ), }}, WantStatusUpdates: []clientgotesting.UpdateActionImpl{{ diff --git a/pkg/reconciler/configmappropagation/resources/labels.go b/pkg/reconciler/configmappropagation/resources/labels.go index 0f62f59545d..4f092750a63 100644 --- a/pkg/reconciler/configmappropagation/resources/labels.go +++ b/pkg/reconciler/configmappropagation/resources/labels.go @@ -16,7 +16,10 @@ limitations under the License. package resources -import "k8s.io/apimachinery/pkg/labels" +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) const ( PropagationLabelKey = "knative.dev/config-propagation" @@ -27,14 +30,11 @@ const ( // ExpectedOriginalSelector with return a selector which matches the input set with an additional label "knative.dev/config-propagation: original" // This is the expected selector to select original configmaps -func ExpectedOriginalSelector(selector map[string]string) labels.Selector { - expectedOriginalSelector := map[string]string{} - for index, element := range selector { - expectedOriginalSelector[index] = element - } +func ExpectedOriginalSelector(selector *metav1.LabelSelector) labels.Selector { + expectedOriginalSelector := selector.DeepCopy() // Add original label if it doesn't exist - if expectedOriginalSelector[PropagationLabelKey] == "" { - expectedOriginalSelector[PropagationLabelKey] = PropagationLabelValueOriginal + if expectedOriginalSelector.MatchLabels[PropagationLabelKey] == "" { + metav1.AddLabelToSelector(expectedOriginalSelector, PropagationLabelKey, PropagationLabelValueOriginal) } - return labels.SelectorFromSet(expectedOriginalSelector) + return labels.SelectorFromSet(expectedOriginalSelector.MatchLabels) } diff --git a/pkg/reconciler/configmappropagation/resources/labels_test.go b/pkg/reconciler/configmappropagation/resources/labels_test.go index 3e898bbde2d..0e561c0ee66 100644 --- a/pkg/reconciler/configmappropagation/resources/labels_test.go +++ b/pkg/reconciler/configmappropagation/resources/labels_test.go @@ -17,9 +17,11 @@ limitations under the License. package resources import ( - "k8s.io/apimachinery/pkg/labels" "reflect" "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" ) func TestOriginalLabels(t *testing.T) { @@ -30,7 +32,9 @@ func TestOriginalLabels(t *testing.T) { }{{ Name: "empty map", F: func() labels.Selector { - return ExpectedOriginalSelector(map[string]string{}) + return ExpectedOriginalSelector(&metav1.LabelSelector{ + MatchLabels: map[string]string{}, + }) }, Want: labels.SelectorFromSet(map[string]string{ PropagationLabelKey: PropagationLabelValueOriginal, @@ -38,8 +42,10 @@ func TestOriginalLabels(t *testing.T) { }, { Name: "map with existing keys", F: func() labels.Selector { - return ExpectedOriginalSelector(map[string]string{ - "testing": "testing", + return ExpectedOriginalSelector(&metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testing": "testing", + }, }) }, Want: labels.SelectorFromSet(map[string]string{ @@ -49,9 +55,11 @@ func TestOriginalLabels(t *testing.T) { }, { Name: "map with original key", F: func() labels.Selector { - return ExpectedOriginalSelector(map[string]string{ - "testing": "testing", - PropagationLabelKey: PropagationLabelValueOriginal, + return ExpectedOriginalSelector(&metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testing": "testing", + PropagationLabelKey: PropagationLabelValueOriginal, + }, }) }, Want: labels.SelectorFromSet(map[string]string{ diff --git a/pkg/reconciler/namespace/resources/configmappropagation.go b/pkg/reconciler/namespace/resources/configmappropagation.go index 3865318e7cc..a8bb0031c94 100644 --- a/pkg/reconciler/namespace/resources/configmappropagation.go +++ b/pkg/reconciler/namespace/resources/configmappropagation.go @@ -31,7 +31,7 @@ func MakeConfigMapPropagation(namespace string) *v1alpha1.ConfigMapPropagation { }, Spec: v1alpha1.ConfigMapPropagationSpec{ OriginalNamespace: system.Namespace(), - Selector: ConfigMapPropagationOwnedLabels(), + Selector: &metav1.LabelSelector{MatchLabels: ConfigMapPropagationOwnedLabels()}, }, } } diff --git a/pkg/reconciler/namespace/resources/labels.go b/pkg/reconciler/namespace/resources/labels.go index b9396ac1647..4512b5e2b04 100644 --- a/pkg/reconciler/namespace/resources/labels.go +++ b/pkg/reconciler/namespace/resources/labels.go @@ -34,8 +34,8 @@ func OwnedLabels() map[string]string { } // ConfigMapPropagationOwnedLabels generates the labels present on injected broker resources. -func ConfigMapPropagationOwnedLabels() *map[string]string { - return &map[string]string{ +func ConfigMapPropagationOwnedLabels() map[string]string { + return map[string]string{ CmpDefaultLabelKey: CmpDefaultLabelValue, } } diff --git a/pkg/reconciler/testing/configmap.go b/pkg/reconciler/testing/configmap.go index e56ca9b6800..8f412628a83 100644 --- a/pkg/reconciler/testing/configmap.go +++ b/pkg/reconciler/testing/configmap.go @@ -41,9 +41,9 @@ func NewConfigMap(name, namespace string, o ...ConfigMapOption) *v1.ConfigMap { return cm } -func WithConfigMapLabels(labels map[string]string) ConfigMapOption { +func WithConfigMapLabels(labels metav1.LabelSelector) ConfigMapOption { return func(cm *v1.ConfigMap) { - cm.ObjectMeta.Labels = labels + cm.ObjectMeta.Labels = labels.MatchLabels } } diff --git a/pkg/reconciler/testing/configmappropagation.go b/pkg/reconciler/testing/configmappropagation.go index 1bbd607364f..fa72f41cec5 100644 --- a/pkg/reconciler/testing/configmappropagation.go +++ b/pkg/reconciler/testing/configmappropagation.go @@ -50,18 +50,19 @@ func WithInitConfigMapPropagationConditions(cmp *v1alpha1.ConfigMapPropagation) func WithInitConfigMapStatus() ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { - cmp.Status.CopyConfigMaps = map[string]v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} + cmp.Status.CopyConfigMaps = []v1alpha1.ConfigMapPropagationStatusCopyConfigMap{} } } -func WithCopyConfigMapStatus(key, source, operation, ready, reason string) ConfigMapPropagationOption { +func WithCopyConfigMapStatus(name, source, operation, ready, reason string) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { - cmp.Status.CopyConfigMaps[key] = v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ + cmp.Status.CopyConfigMaps = append(cmp.Status.CopyConfigMaps, v1alpha1.ConfigMapPropagationStatusCopyConfigMap{ + Name: name, Source: source, Operation: operation, Ready: ready, Reason: reason, - } + }) } } @@ -70,7 +71,7 @@ func WithConfigMapPropagationDeletionTimestamp(cmp *v1alpha1.ConfigMapPropagatio cmp.ObjectMeta.SetDeletionTimestamp(&t) } -func WithConfigMapPropagationSelector(selector map[string]string) ConfigMapPropagationOption { +func WithConfigMapPropagationSelector(selector metav1.LabelSelector) ConfigMapPropagationOption { return func(cmp *v1alpha1.ConfigMapPropagation) { cmp.Spec.Selector = &selector } diff --git a/test/lib/resources/eventing.go b/test/lib/resources/eventing.go index 31f7fecae5a..498c9654f63 100644 --- a/test/lib/resources/eventing.go +++ b/test/lib/resources/eventing.go @@ -138,7 +138,9 @@ func ConfigMapPropagation(name, namespace string) *configsv1alpha1.ConfigMapProp }, Spec: configsv1alpha1.ConfigMapPropagationSpec{ OriginalNamespace: "knative-eventing", - Selector: resources.ConfigMapPropagationOwnedLabels(), + Selector: &metav1.LabelSelector{ + MatchLabels: resources.ConfigMapPropagationOwnedLabels(), + }, }, } } diff --git a/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml b/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml index c7503681a77..568c70e3178 100644 --- a/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml +++ b/test/performance/benchmarks/broker-imc/100-broker-perf-setup.yaml @@ -131,12 +131,13 @@ roleRef: apiVersion: configs.knative.dev/v1alpha1 kind: ConfigMapPropagation metadata: - name: perf-eventing-cmp + name: eventing namespace: perf-eventing spec: originalNamespace: knative-eventing selector: - knative.dev/config-category: eventing + matchlabels: + knative.dev/config-category: eventing --- diff --git a/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml b/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml index 0dd29793e67..f7cb1cc1cee 100644 --- a/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml +++ b/test/performance/benchmarks/broker-imc/continuous/100-broker-imc-setup.yaml @@ -124,12 +124,13 @@ roleRef: apiVersion: configs.knative.dev/v1alpha1 kind: ConfigMapPropagation metadata: - name: perf-eventing-cmp + name: eventing namespace: default spec: originalNamespace: knative-eventing selector: - knative.dev/config-category: eventing + matchlabels: + knative.dev/config-category: eventing --- From ce739651e97bf95f3344e31eec8e71199ad80443 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Fri, 17 Jan 2020 11:49:06 -0800 Subject: [PATCH 20/26] add validation/unit test --- .../v1alpha1/configmappropagation_validation.go | 11 +++++++++-- .../configmappropagation_validation_test.go | 17 +++++++++++++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index 13fee9cb68f..14986bd8c23 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -44,7 +44,7 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE for key, value := range cmps.Selector.MatchLabels { if err := validation.IsQualifiedName(key); len(err) != 0 { fe := &apis.FieldError{ - Message: fmt.Sprintf("Invalid selector key: %v", key), + Message: fmt.Sprintf("Invalid selector matchLabels key: %v", key), Paths: []string{"selector"}, Details: strings.Join(err, "; "), } @@ -52,13 +52,20 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE } if err := validation.IsValidLabelValue(value); len(err) != 0 { fe := &apis.FieldError{ - Message: fmt.Sprintf("Invalid selector value: %v", value), + Message: fmt.Sprintf("Invalid selector matchLabels value: %v", value), Paths: []string{"selector"}, Details: strings.Join(err, "; "), } errs = errs.Also(fe) } } + if cmps.Selector.MatchExpressions != nil { + fe := &apis.FieldError{ + Message: fmt.Sprintf("MatchExppressions isn't supported yet"), + Paths: []string{"selector"}, + } + errs = errs.Also(fe) + } } return errs } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index abf0eb1f65f..480a4caec3d 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -76,26 +76,35 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { return fe }(), }, { - name: "invalid selector key", + name: "invalid selector matchLabels key", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"*nvalid": "testing"}}, }, want: &apis.FieldError{ - Message: `Invalid selector key: *nvalid`, + Message: `Invalid selector matchLabels key: *nvalid`, Paths: []string{"selector"}, Details: "name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')", }, }, { - name: "invalid seletor value", + name: "invalid selector matchLabels value", cmps: &ConfigMapPropagationSpec{ OriginalNamespace: originalNamespace, Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"invalid": "test/ing"}}}, want: &apis.FieldError{ - Message: `Invalid selector value: test/ing`, + Message: `Invalid selector matchLabels value: test/ing`, Paths: []string{"selector"}, Details: "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')", }, + }, { + name: "additional selector matchExpressions", + cmps: &ConfigMapPropagationSpec{ + OriginalNamespace: originalNamespace, + Selector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{}}}, + want: &apis.FieldError{ + Message: `MatchExppressions isn't supported yet`, + Paths: []string{"selector"}, + }, }, } From 25c7167b7a349f13ba6ce6e2272115775ca99d47 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Tue, 21 Jan 2020 11:44:38 -0800 Subject: [PATCH 21/26] consistency --- .../configmappropagation.go | 16 ++++++++-------- .../configmappropagation_test.go | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index fcfa3a49e5e..dc813c23608 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -50,10 +50,10 @@ const ( configMapPropagationPropagateSingleConfigMapSucceed = "ConfigMapPropagationPropagateSingleConfigMapSucceed" // Name of operation to propagate single configmap. - copyConfigMap = "copy" - deleteConfigMap = "delete" + copyConfigMap = "Copy" + deleteConfigMap = "Delete" // stopConfigMap indicates a configmap stop propagating. - stopConfigMap = "stop" + stopConfigMap = "Stop" ) type Reconciler struct { @@ -222,20 +222,20 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "false", err.Error(), resourceVersion) + expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "False", err.Error(), resourceVersion) } else if !succeed { // If there is no error, but the create/update action is not successful, // this indicates the copy configmap's copy label is removed. logging.FromContext(ctx).Debug("Stop propagating ConfigMap " + configMap.Name) r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Stop propagating ConfigMap: %s", configMap.Name)) - expectedStatus.SetCopyConfigMapStatus(name, source, stopConfigMap, "true", + expectedStatus.SetCopyConfigMapStatus(name, source, stopConfigMap, "True", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, resourceVersion) } else { logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Propagate ConfigMap %v succeed", configMap.Name)) - expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "true", "", resourceVersion) + expectedStatus.SetCopyConfigMapStatus(name, source, copyConfigMap, "True", "", resourceVersion) } // Update current copy configmap's status. cmp.Status.CopyConfigMaps = append(cmp.Status.CopyConfigMaps, expectedStatus) @@ -263,9 +263,9 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi if errs == nil { errs = fmt.Errorf("one or more ConfigMap propagation failed") } - expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "false", err.Error(), "") + expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "False", err.Error(), "") } else if succeed { - expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "true", "", "") + expectedStatus.SetCopyConfigMapStatus(copyConfigMap.Name, source, deleteConfigMap, "True", "", "") } if expectedStatus.Name != "" { // expectedStatus with same name will be merged and updated. diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 71f4a68b2b0..4454845cb4a 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -130,7 +130,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "delete", "true", ""), + "Delete", "True", ""), ), }}, WantEvents: []string{ @@ -163,7 +163,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "delete", "true", ""), + "Delete", "True", ""), ), }}, WantEvents: []string{ @@ -199,7 +199,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "delete", "false", "inducing failure for delete configmaps"), + "Delete", "False", "inducing failure for delete configmaps"), ), }}, WantErr: true, @@ -250,7 +250,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error updating ConfigMap in current namespace: inducing failure for update configmaps"), + "Copy", "False", "error updating ConfigMap in current namespace: inducing failure for update configmaps"), ), }}, WantErr: true, @@ -298,7 +298,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "Copy", "True", ""), ), }}, WantEvents: []string{ @@ -344,7 +344,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "Copy", "True", ""), ), }}, WantEvents: []string{ @@ -386,7 +386,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "stop", "true", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), + "Stop", "True", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), ), }}, WantErr: false, @@ -427,7 +427,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationNotPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "false", "error creating ConfigMap in current namespace: inducing failure for create configmaps"), + "Copy", "False", "error creating ConfigMap in current namespace: inducing failure for create configmaps"), ), }}, WantErr: true, @@ -469,7 +469,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationStatusObservedGeneration(configMapPropagationGeneration), WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "copy", "true", ""), + "Copy", "True", ""), ), }}, WantEvents: []string{ From 12c2f4004d14b8c399887740ffbba562ed2d1dfc Mon Sep 17 00:00:00 2001 From: grac3gao Date: Mon, 27 Jan 2020 11:21:55 -0800 Subject: [PATCH 22/26] modification --- config/core/configmaps/logging.yaml | 2 ++ config/core/configmaps/observability.yaml | 2 ++ config/core/configmaps/tracing.yaml | 2 ++ .../core/roles/controller-clusterroles.yaml | 8 +++++++ .../configmappropagation_lifecycle.go | 24 +++++-------------- .../v1alpha1/configmappropagation_types.go | 5 ---- .../configmappropagation_validation.go | 2 +- .../configmappropagation.go | 4 ++-- 8 files changed, 23 insertions(+), 26 deletions(-) diff --git a/config/core/configmaps/logging.yaml b/config/core/configmaps/logging.yaml index c65449a6ebb..a43deb49e86 100644 --- a/config/core/configmaps/logging.yaml +++ b/config/core/configmaps/logging.yaml @@ -19,6 +19,8 @@ metadata: namespace: knative-eventing labels: eventing.knative.dev/release: devel + knative.dev/config-propagation: original + knative.dev/config-category: eventing data: # Common configuration for all Knative codebase zap-logger-config: | diff --git a/config/core/configmaps/observability.yaml b/config/core/configmaps/observability.yaml index 6f5b114afc8..df9f5d4a5e4 100644 --- a/config/core/configmaps/observability.yaml +++ b/config/core/configmaps/observability.yaml @@ -19,6 +19,8 @@ metadata: namespace: knative-eventing labels: eventing.knative.dev/release: devel + knative.dev/config-propagation: original + knative.dev/config-category: eventing data: _example: | ################################ diff --git a/config/core/configmaps/tracing.yaml b/config/core/configmaps/tracing.yaml index ac03d87cbd9..06fd6710b04 100644 --- a/config/core/configmaps/tracing.yaml +++ b/config/core/configmaps/tracing.yaml @@ -19,6 +19,8 @@ metadata: namespace: knative-eventing labels: eventing.knative.dev/release: devel + knative.dev/config-propagation: original + knative.dev/config-category: eventing data: _example: | ################################ diff --git a/config/core/roles/controller-clusterroles.yaml b/config/core/roles/controller-clusterroles.yaml index eb97da57e94..0690c42ffff 100644 --- a/config/core/roles/controller-clusterroles.yaml +++ b/config/core/roles/controller-clusterroles.yaml @@ -115,6 +115,14 @@ rules: verbs: - "update" + # Configs resources and status we care about. + - apiGroups: + - "configs.knative.dev" + resources: + - "configmappropagation" + - "configmappropagation/status" + verbs: *everything + # The subscription controller needs to retrieve and watch CustomResourceDefinitions. - apiGroups: - "apiextensions.k8s.io" diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go index 7e06f08df5a..b87cdbdd66a 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_lifecycle.go @@ -54,22 +54,10 @@ func (cmps *ConfigMapPropagationStatus) MarkNotPropagated() { } func (cmpsc *ConfigMapPropagationStatusCopyConfigMap) SetCopyConfigMapStatus(name, source, operation, ready, reason, resourceVersion string) { - if name != "" { - cmpsc.Name = name - } - if source != "" { - cmpsc.Source = source - } - if operation != "" { - cmpsc.Operation = operation - } - if ready != "" { - cmpsc.Ready = ready - } - if reason != "" { - cmpsc.Reason = reason - } - if resourceVersion != "" { - cmpsc.ResourceVersion = resourceVersion - } + cmpsc.Name = name + cmpsc.Source = source + cmpsc.Operation = operation + cmpsc.Ready = ready + cmpsc.Reason = reason + cmpsc.ResourceVersion = resourceVersion } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_types.go b/pkg/apis/configs/v1alpha1/configmappropagation_types.go index 24df0ef61ab..7df9db31825 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_types.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_types.go @@ -87,23 +87,18 @@ type ConfigMapPropagationStatusCopyConfigMap struct { Name string `json:"name,omitempty"` // Source is "originalNamespace/originalConfigMapName" - // +required Source string `json:"source,omitempty"` // Operation represents the operation CMP takes for this configmap. The operations are copy|delete|stop - // +required Operation string `json:"operation,omitempty"` // Ready represents the operation is ready or not - // +required Ready string `json:"ready,omitempty"` // Reason indicates reasons if the operation is not ready - // +optional Reason string `json:"reason,omitempty"` // ResourceVersion is the resourceVersion of original configmap - // +optional ResourceVersion string `json:"resourceVersionFromSource,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"` } diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index 14986bd8c23..8353d99e5f3 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -61,7 +61,7 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE } if cmps.Selector.MatchExpressions != nil { fe := &apis.FieldError{ - Message: fmt.Sprintf("MatchExppressions isn't supported yet"), + Message: fmt.Sprintf("matchExpressions isn't supported yet"), Paths: []string{"selector"}, } errs = errs.Also(fe) diff --git a/pkg/reconciler/configmappropagation/configmappropagation.go b/pkg/reconciler/configmappropagation/configmappropagation.go index dc813c23608..f762092554b 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation.go +++ b/pkg/reconciler/configmappropagation/configmappropagation.go @@ -230,7 +230,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, fmt.Sprintf("Stop propagating ConfigMap: %s", configMap.Name)) expectedStatus.SetCopyConfigMapStatus(name, source, stopConfigMap, "True", - `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`, resourceVersion) + `copy ConfigMap doesn't have copy label, stop propagating this ConfigMap`, resourceVersion) } else { logging.FromContext(ctx).Debug("Propagate ConfigMap " + configMap.Name + " succeed") r.Recorder.Eventf(cmp, corev1.EventTypeNormal, configMapPropagationPropagateSingleConfigMapSucceed, @@ -241,7 +241,7 @@ func (r *Reconciler) reconcileConfigMap(ctx context.Context, cmp *v1alpha1.Confi cmp.Status.CopyConfigMaps = append(cmp.Status.CopyConfigMaps, expectedStatus) } // List ConfigMaps in current namespace and delete copy ConfigMap if the corresponding original ConfigMap no longer exists or no longer has the required label. - copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.Everything()) + copyConfigMapList, err := r.configMapLister.ConfigMaps(cmp.Namespace).List(labels.SelectorFromSet(map[string]string{resources.PropagationLabelKey: resources.PropagationLabelValueCopy})) if err != nil { logging.FromContext(ctx).Error("Unable to get the ConfigMap list in current namespace", zap.Error(err)) return err From fc09fc6340b6daf8ab0afb6d4575fa672ce3c85b Mon Sep 17 00:00:00 2001 From: grac3gao Date: Mon, 27 Jan 2020 11:56:47 -0800 Subject: [PATCH 23/26] modification --- config/core/roles/controller-clusterroles.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/core/roles/controller-clusterroles.yaml b/config/core/roles/controller-clusterroles.yaml index 0690c42ffff..0ce75c5c29a 100644 --- a/config/core/roles/controller-clusterroles.yaml +++ b/config/core/roles/controller-clusterroles.yaml @@ -96,6 +96,14 @@ rules: - "parallels/status" verbs: *everything + # Configs resources and status we care about. + - apiGroups: + - "configs.knative.dev" + resources: + - "configmappropagations" + - "configmappropagations/status" + verbs: *everything + # Messaging resources and finalizers we care about. - apiGroups: - "messaging.knative.dev" @@ -115,14 +123,6 @@ rules: verbs: - "update" - # Configs resources and status we care about. - - apiGroups: - - "configs.knative.dev" - resources: - - "configmappropagation" - - "configmappropagation/status" - verbs: *everything - # The subscription controller needs to retrieve and watch CustomResourceDefinitions. - apiGroups: - "apiextensions.k8s.io" From bf279c170000c746be8c40064c5ec4c60d785476 Mon Sep 17 00:00:00 2001 From: grac3gao Date: Mon, 27 Jan 2020 13:19:42 -0800 Subject: [PATCH 24/26] update unit test --- pkg/apis/configs/v1alpha1/configmappropagation_validation.go | 2 +- .../configs/v1alpha1/configmappropagation_validation_test.go | 2 +- .../configmappropagation/configmappropagation_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go index 8353d99e5f3..aa08074b0c0 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation.go @@ -61,7 +61,7 @@ func (cmps *ConfigMapPropagationSpec) Validate(ctx context.Context) *apis.FieldE } if cmps.Selector.MatchExpressions != nil { fe := &apis.FieldError{ - Message: fmt.Sprintf("matchExpressions isn't supported yet"), + Message: fmt.Sprintf("MatchExpressions isn't supported yet"), Paths: []string{"selector"}, } errs = errs.Also(fe) diff --git a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go index 480a4caec3d..595e4fef725 100644 --- a/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go +++ b/pkg/apis/configs/v1alpha1/configmappropagation_validation_test.go @@ -102,7 +102,7 @@ func TestConfigMapPropagationSpecValidation(t *testing.T) { OriginalNamespace: originalNamespace, Selector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{}}}, want: &apis.FieldError{ - Message: `MatchExppressions isn't supported yet`, + Message: `MatchExpressions isn't supported yet`, Paths: []string{"selector"}, }, }, diff --git a/pkg/reconciler/configmappropagation/configmappropagation_test.go b/pkg/reconciler/configmappropagation/configmappropagation_test.go index 4454845cb4a..1ea31203caf 100644 --- a/pkg/reconciler/configmappropagation/configmappropagation_test.go +++ b/pkg/reconciler/configmappropagation/configmappropagation_test.go @@ -386,7 +386,7 @@ func TestAllCase(t *testing.T) { WithConfigMapPropagationPropagated, WithInitConfigMapStatus(), WithCopyConfigMapStatus("test-cmp-test-original-cm", "knative-eventing/test-original-cm", - "Stop", "True", `copy ConfigMap doesn't have "knative.dev/config-propagation:copy" label, stop propagating this ConfigMap`), + "Stop", "True", `copy ConfigMap doesn't have copy label, stop propagating this ConfigMap`), ), }}, WantErr: false, From 586f6f0144d8288feafa6a48afb8108cd8b4feea Mon Sep 17 00:00:00 2001 From: grac3gao Date: Mon, 27 Jan 2020 14:03:29 -0800 Subject: [PATCH 25/26] change api group name --- config/300-configmappropagation.yaml | 4 ++-- config/core/roles/controller-clusterroles.yaml | 2 +- pkg/apis/configs/register.go | 2 +- pkg/apis/configs/v1alpha1/doc.go | 2 +- pkg/apis/configs/v1alpha1/register_test.go | 4 ++-- .../versioned/typed/configs/v1alpha1/configs_client.go | 2 +- .../typed/configs/v1alpha1/fake/fake_configmappropagation.go | 4 ++-- pkg/client/informers/externalversions/generic.go | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml index 824b7385a38..f91b156247e 100644 --- a/config/300-configmappropagation.yaml +++ b/config/300-configmappropagation.yaml @@ -15,12 +15,12 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: configmappropagations.configs.knative.dev + name: configmappropagations.configs.internal.knative.dev labels: eventing.knative.dev/release: devel knative.dev/crd-install: "true" spec: - group: configs.knative.dev + group: configs.internal.knative.dev versions: - name: v1alpha1 served: true diff --git a/config/core/roles/controller-clusterroles.yaml b/config/core/roles/controller-clusterroles.yaml index 0ce75c5c29a..a8b3436bbcd 100644 --- a/config/core/roles/controller-clusterroles.yaml +++ b/config/core/roles/controller-clusterroles.yaml @@ -98,7 +98,7 @@ rules: # Configs resources and status we care about. - apiGroups: - - "configs.knative.dev" + - "configs.internal.knative.dev" resources: - "configmappropagations" - "configmappropagations/status" diff --git a/pkg/apis/configs/register.go b/pkg/apis/configs/register.go index 8a6241a546b..77becd24253 100644 --- a/pkg/apis/configs/register.go +++ b/pkg/apis/configs/register.go @@ -17,5 +17,5 @@ limitations under the License. package configs const ( - GroupName = "configs.knative.dev" + GroupName = "configs.internal.knative.dev" ) diff --git a/pkg/apis/configs/v1alpha1/doc.go b/pkg/apis/configs/v1alpha1/doc.go index 787c633705d..4db3f84709e 100644 --- a/pkg/apis/configs/v1alpha1/doc.go +++ b/pkg/apis/configs/v1alpha1/doc.go @@ -16,5 +16,5 @@ limitations under the License. // Package v1alpha1 is the v1alpha1 version of the API. // +k8s:deepcopy-gen=package -// +groupName=configs.knative.dev +// +groupName=configs.internal.knative.dev package v1alpha1 diff --git a/pkg/apis/configs/v1alpha1/register_test.go b/pkg/apis/configs/v1alpha1/register_test.go index 857dc9cb710..caf0af75ba7 100644 --- a/pkg/apis/configs/v1alpha1/register_test.go +++ b/pkg/apis/configs/v1alpha1/register_test.go @@ -23,7 +23,7 @@ import ( // Resource takes an unqualified resource and returns a Group qualified GroupResource func TestResource(t *testing.T) { want := schema.GroupResource{ - Group: "configs.knative.dev", + Group: "configs.internal.knative.dev", Resource: "foo", } @@ -37,7 +37,7 @@ func TestResource(t *testing.T) { // Kind takes an unqualified resource and returns a Group qualified GroupKind func TestKind(t *testing.T) { want := schema.GroupKind{ - Group: "configs.knative.dev", + Group: "configs.internal.knative.dev", Kind: "kind", } diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go index 53285edf25b..7efb4a582a2 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/configs_client.go @@ -29,7 +29,7 @@ type ConfigsV1alpha1Interface interface { ConfigMapPropagationsGetter } -// ConfigsV1alpha1Client is used to interact with features provided by the configs.knative.dev group. +// ConfigsV1alpha1Client is used to interact with features provided by the configs.internal.knative.dev group. type ConfigsV1alpha1Client struct { restClient rest.Interface } diff --git a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go index c829aa87ffc..65ce8935d53 100644 --- a/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go +++ b/pkg/client/clientset/versioned/typed/configs/v1alpha1/fake/fake_configmappropagation.go @@ -34,9 +34,9 @@ type FakeConfigMapPropagations struct { ns string } -var configmappropagationsResource = schema.GroupVersionResource{Group: "configs.knative.dev", Version: "v1alpha1", Resource: "configmappropagations"} +var configmappropagationsResource = schema.GroupVersionResource{Group: "configs.internal.knative.dev", Version: "v1alpha1", Resource: "configmappropagations"} -var configmappropagationsKind = schema.GroupVersionKind{Group: "configs.knative.dev", Version: "v1alpha1", Kind: "ConfigMapPropagation"} +var configmappropagationsKind = schema.GroupVersionKind{Group: "configs.internal.knative.dev", Version: "v1alpha1", Kind: "ConfigMapPropagation"} // Get takes name of the configMapPropagation, and returns the corresponding configMapPropagation object, and an error if there is any. func (c *FakeConfigMapPropagations) Get(name string, options v1.GetOptions) (result *v1alpha1.ConfigMapPropagation, err error) { diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index edd74d4af08..d242d8da8d7 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -59,7 +59,7 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=configs.knative.dev, Version=v1alpha1 + // Group=configs.internal.knative.dev, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("configmappropagations"): return &genericInformer{resource: resource.GroupResource(), informer: f.Configs().V1alpha1().ConfigMapPropagations().Informer()}, nil From 8ebc2c5557647a89a89cbbff141a0607a1e23eee Mon Sep 17 00:00:00 2001 From: grac3gao Date: Tue, 28 Jan 2020 00:08:25 -0800 Subject: [PATCH 26/26] add symlink --- config/300-configmappropagation.yaml | 63 +------------------ .../core/resources/configmappropagation.yaml | 61 ++++++++++++++++++ 2 files changed, 62 insertions(+), 62 deletions(-) mode change 100644 => 120000 config/300-configmappropagation.yaml create mode 100644 config/core/resources/configmappropagation.yaml diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml deleted file mode 100644 index f91b156247e..00000000000 --- a/config/300-configmappropagation.yaml +++ /dev/null @@ -1,62 +0,0 @@ -# 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. - -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: configmappropagations.configs.internal.knative.dev - labels: - eventing.knative.dev/release: devel - knative.dev/crd-install: "true" -spec: - group: configs.internal.knative.dev - versions: - - name: v1alpha1 - served: true - storage: true - names: - kind: ConfigMapPropagation - plural: configmappropagations - singular: configmappropagation - categories: - - all - - knative - - eventing - shortNames: - - kcmp - - cmp - scope: Namespaced - subresources: - status: {} - additionalPrinterColumns: - - name: Ready - type: string - JSONPath: ".status.conditions[?(@.type==\"Ready\")].status" - - name: Reason - type: string - JSONPath: ".status.conditions[?(@.type==\"Ready\")].reason" - - name: OriginalNamespace - type: string - JSONPath: ".spec.originalNamespace" - validation: - openAPIV3Schema: - properties: - spec: - required: - - originalNamespace - properties: - originalNamespace: - type: string - description: "The namespace where original ConfigMaps exist in." - diff --git a/config/300-configmappropagation.yaml b/config/300-configmappropagation.yaml new file mode 120000 index 00000000000..cba754c58ea --- /dev/null +++ b/config/300-configmappropagation.yaml @@ -0,0 +1 @@ +core/resources/configmappropagation.yaml \ No newline at end of file diff --git a/config/core/resources/configmappropagation.yaml b/config/core/resources/configmappropagation.yaml new file mode 100644 index 00000000000..714a2eed36e --- /dev/null +++ b/config/core/resources/configmappropagation.yaml @@ -0,0 +1,61 @@ +# 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. + +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: configmappropagations.configs.internal.knative.dev + labels: + eventing.knative.dev/release: devel + knative.dev/crd-install: "true" +spec: + group: configs.internal.knative.dev + versions: + - name: v1alpha1 + served: true + storage: true + names: + kind: ConfigMapPropagation + plural: configmappropagations + singular: configmappropagation + categories: + - all + - knative + - eventing + shortNames: + - kcmp + - cmp + scope: Namespaced + subresources: + status: {} + additionalPrinterColumns: + - name: Ready + type: string + JSONPath: ".status.conditions[?(@.type==\"Ready\")].status" + - name: Reason + type: string + JSONPath: ".status.conditions[?(@.type==\"Ready\")].reason" + - name: OriginalNamespace + type: string + JSONPath: ".spec.originalNamespace" + validation: + openAPIV3Schema: + properties: + spec: + required: + - originalNamespace + properties: + originalNamespace: + type: string + description: "The namespace where original ConfigMaps exist in."