From 29d25a4dbebd9a77a1b6e7d45b70e5b59c55f873 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Wed, 29 Mar 2023 16:29:05 +0300 Subject: [PATCH 01/11] Promote Kustomization API to v1 Signed-off-by: Stefan Prodan --- Makefile | 2 +- PROJECT | 3 + api/v1/condition_types.go | 55 ++ api/v1/doc.go | 20 + api/v1/groupversion_info.go | 33 ++ api/v1/inventory_types.go | 33 ++ api/v1/kustomization_types.go | 321 ++++++++++++ api/v1/reference_types.go | 47 ++ api/v1/zz_generated.deepcopy.go | 331 ++++++++++++ api/v1beta1/kustomization_types.go | 1 + api/v1beta1/zz_generated.deepcopy.go | 2 +- api/v1beta2/kustomization_types.go | 2 +- api/v1beta2/zz_generated.deepcopy.go | 2 +- ...mize.toolkit.fluxcd.io_kustomizations.yaml | 488 +++++++++++++++++- ...n.yaml => kustomize_v1_kustomization.yaml} | 4 +- ...yaml => source_v1beta2_gitrepository.yaml} | 4 +- config/testdata/crds-crs/cert-manager.yaml | 2 +- config/testdata/impersonation/test.yaml | 2 +- config/testdata/managed-fields/podinfo.yaml | 2 +- config/testdata/oci/podinfo.yaml | 2 +- docs/api/kustomize.md | 158 ++---- go.mod | 2 +- hack/boilerplate.go.txt | 2 +- .../controllers/kustomization_acl_test.go | 2 +- .../controllers/kustomization_controller.go | 2 +- .../kustomization_decryptor_test.go | 2 +- .../kustomization_dependson_test.go | 2 +- .../controllers/kustomization_fetcher_test.go | 2 +- .../controllers/kustomization_force_test.go | 2 +- .../controllers/kustomization_fuzzer_test.go | 2 +- .../kustomization_impersonation_test.go | 2 +- .../controllers/kustomization_indexers.go | 2 +- .../kustomization_inventory_test.go | 2 +- .../controllers/kustomization_prune_test.go | 2 +- .../kustomization_transformer_test.go | 25 +- .../kustomization_validation_test.go | 2 +- .../controllers/kustomization_varsub_test.go | 2 +- .../controllers/kustomization_wait_test.go | 2 +- internal/controllers/suite_test.go | 2 +- internal/decryptor/decryptor.go | 2 +- internal/decryptor/decryptor_test.go | 5 +- internal/inventory/inventory.go | 2 +- main.go | 2 +- 43 files changed, 1404 insertions(+), 180 deletions(-) create mode 100644 api/v1/condition_types.go create mode 100644 api/v1/doc.go create mode 100644 api/v1/groupversion_info.go create mode 100644 api/v1/inventory_types.go create mode 100644 api/v1/kustomization_types.go create mode 100644 api/v1/reference_types.go create mode 100644 api/v1/zz_generated.deepcopy.go rename config/samples/{kustomize_v1beta1_kustomization.yaml => kustomize_v1_kustomization.yaml} (85%) rename config/samples/{source_v1beta1_gitrepository.yaml => source_v1beta2_gitrepository.yaml} (76%) diff --git a/Makefile b/Makefile index bc20eb54..2731a18c 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ manifests: controller-gen # Generate API reference documentation api-docs: gen-crd-api-reference-docs - $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/kustomize.md + $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/kustomize.md # Run go mod tidy tidy: diff --git a/PROJECT b/PROJECT index 97afa1d1..4d16c7e8 100644 --- a/PROJECT +++ b/PROJECT @@ -1,6 +1,9 @@ domain: toolkit.fluxcd.io repo: github.com/fluxcd/kustomize-controller resources: +- group: kustomize + kind: Kustomization + version: v1 - group: kustomize kind: Kustomization version: v1beta2 diff --git a/api/v1/condition_types.go b/api/v1/condition_types.go new file mode 100644 index 00000000..8a177d56 --- /dev/null +++ b/api/v1/condition_types.go @@ -0,0 +1,55 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +const ( + // HealthyCondition represents the last recorded + // health assessment result. + HealthyCondition string = "Healthy" + + // PruneFailedReason represents the fact that the + // pruning of the Kustomization failed. + PruneFailedReason string = "PruneFailed" + + // ArtifactFailedReason represents the fact that the + // source artifact download failed. + ArtifactFailedReason string = "ArtifactFailed" + + // BuildFailedReason represents the fact that the + // kustomize build failed. + BuildFailedReason string = "BuildFailed" + + // HealthCheckFailedReason represents the fact that + // one of the health checks failed. + HealthCheckFailedReason string = "HealthCheckFailed" + + // DependencyNotReadyReason represents the fact that + // one of the dependencies is not ready. + DependencyNotReadyReason string = "DependencyNotReady" + + // ReconciliationSucceededReason represents the fact that + // the reconciliation succeeded. + ReconciliationSucceededReason string = "ReconciliationSucceeded" + + // ReconciliationFailedReason represents the fact that + // the reconciliation failed. + ReconciliationFailedReason string = "ReconciliationFailed" + + // ProgressingWithRetryReason represents the fact that + // the reconciliation encountered an error that will be retried. + ProgressingWithRetryReason string = "ProgressingWithRetry" +) diff --git a/api/v1/doc.go b/api/v1/doc.go new file mode 100644 index 00000000..d96907b1 --- /dev/null +++ b/api/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1 API group. +// +kubebuilder:object:generate=true +// +groupName=kustomize.toolkit.fluxcd.io +package v1 diff --git a/api/v1/groupversion_info.go b/api/v1/groupversion_info.go new file mode 100644 index 00000000..6639b83b --- /dev/null +++ b/api/v1/groupversion_info.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "kustomize.toolkit.fluxcd.io", Version: "v1beta2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1/inventory_types.go b/api/v1/inventory_types.go new file mode 100644 index 00000000..83fc9e71 --- /dev/null +++ b/api/v1/inventory_types.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +// ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization. +type ResourceInventory struct { + // Entries of Kubernetes resource object references. + Entries []ResourceRef `json:"entries"` +} + +// ResourceRef contains the information necessary to locate a resource within a cluster. +type ResourceRef struct { + // ID is the string representation of the Kubernetes resource object's metadata, + // in the format '___'. + ID string `json:"id"` + + // Version is the API version of the Kubernetes resource object's kind. + Version string `json:"v"` +} diff --git a/api/v1/kustomization_types.go b/api/v1/kustomization_types.go new file mode 100644 index 00000000..ac5258ec --- /dev/null +++ b/api/v1/kustomization_types.go @@ -0,0 +1,321 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import ( + "time" + + "github.com/fluxcd/pkg/apis/kustomize" + "github.com/fluxcd/pkg/apis/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + KustomizationKind = "Kustomization" + KustomizationFinalizer = "finalizers.fluxcd.io" + MaxConditionMessageLength = 20000 + EnabledValue = "enabled" + DisabledValue = "disabled" + MergeValue = "merge" +) + +// KustomizationSpec defines the configuration to calculate the desired state from a Source using Kustomize. +type KustomizationSpec struct { + // CommonMetadata specifies the common labels and annotations that are applied to all resources. + // Any existing label or annotation will be overridden if its key matches a common one. + // +optional + CommonMetadata *CommonMetadata `json:"commonMetadata,omitempty"` + + // DependsOn may contain a meta.NamespacedObjectReference slice + // with references to Kustomization resources that must be ready before this + // Kustomization can be reconciled. + // +optional + DependsOn []meta.NamespacedObjectReference `json:"dependsOn,omitempty"` + + // Decrypt Kubernetes secrets before applying them on the cluster. + // +optional + Decryption *Decryption `json:"decryption,omitempty"` + + // The interval at which to reconcile the Kustomization. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + // +required + Interval metav1.Duration `json:"interval"` + + // The interval at which to retry a previously failed reconciliation. + // When not specified, the controller uses the KustomizationSpec.Interval + // value to retry failures. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + // +optional + RetryInterval *metav1.Duration `json:"retryInterval,omitempty"` + + // The KubeConfig for reconciling the Kustomization on a remote cluster. + // When used in combination with KustomizationSpec.ServiceAccountName, + // forces the controller to act on behalf of that Service Account at the + // target cluster. + // If the --default-service-account flag is set, its value will be used as + // a controller level fallback for when KustomizationSpec.ServiceAccountName + // is empty. + // +optional + KubeConfig *meta.KubeConfigReference `json:"kubeConfig,omitempty"` + + // Path to the directory containing the kustomization.yaml file, or the + // set of plain YAMLs a kustomization.yaml should be generated for. + // Defaults to 'None', which translates to the root path of the SourceRef. + // +optional + Path string `json:"path,omitempty"` + + // PostBuild describes which actions to perform on the YAML manifest + // generated by building the kustomize overlay. + // +optional + PostBuild *PostBuild `json:"postBuild,omitempty"` + + // Prune enables garbage collection. + // +required + Prune bool `json:"prune"` + + // A list of resources to be included in the health assessment. + // +optional + HealthChecks []meta.NamespacedObjectKindReference `json:"healthChecks,omitempty"` + + // Strategic merge and JSON patches, defined as inline YAML objects, + // capable of targeting objects based on kind, label and annotation selectors. + // +optional + Patches []kustomize.Patch `json:"patches,omitempty"` + + // Images is a list of (image name, new name, new tag or digest) + // for changing image names, tags or digests. This can also be achieved with a + // patch, but this operator is simpler to specify. + // +optional + Images []kustomize.Image `json:"images,omitempty"` + + // The name of the Kubernetes service account to impersonate + // when reconciling this Kustomization. + // +optional + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // Reference of the source where the kustomization file is. + // +required + SourceRef CrossNamespaceSourceReference `json:"sourceRef"` + + // This flag tells the controller to suspend subsequent kustomize executions, + // it does not apply to already started executions. Defaults to false. + // +optional + Suspend bool `json:"suspend,omitempty"` + + // TargetNamespace sets or overrides the namespace in the + // kustomization.yaml file. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Optional + // +optional + TargetNamespace string `json:"targetNamespace,omitempty"` + + // Timeout for validation, apply and health checking operations. + // Defaults to 'Interval' duration. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" + // +optional + Timeout *metav1.Duration `json:"timeout,omitempty"` + + // Force instructs the controller to recreate resources + // when patching fails due to an immutable field change. + // +kubebuilder:default:=false + // +optional + Force bool `json:"force,omitempty"` + + // Wait instructs the controller to check the health of all the reconciled resources. + // When enabled, the HealthChecks are ignored. Defaults to false. + // +optional + Wait bool `json:"wait,omitempty"` + + // Components specifies relative paths to specifications of other Components. + // +optional + Components []string `json:"components,omitempty"` +} + +// CommonMetadata defines the common labels and annotations. +type CommonMetadata struct { + // Annotations to be added to the object's metadata. + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // Labels to be added to the object's metadata. + // +optional + Labels map[string]string `json:"labels,omitempty"` +} + +// Decryption defines how decryption is handled for Kubernetes manifests. +type Decryption struct { + // Provider is the name of the decryption engine. + // +kubebuilder:validation:Enum=sops + // +required + Provider string `json:"provider"` + + // The secret name containing the private OpenPGP keys used for decryption. + // +optional + SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"` +} + +// PostBuild describes which actions to perform on the YAML manifest +// generated by building the kustomize overlay. +type PostBuild struct { + // Substitute holds a map of key/value pairs. + // The variables defined in your YAML manifests + // that match any of the keys defined in the map + // will be substituted with the set value. + // Includes support for bash string replacement functions + // e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. + // +optional + Substitute map[string]string `json:"substitute,omitempty"` + + // SubstituteFrom holds references to ConfigMaps and Secrets containing + // the variables and their values to be substituted in the YAML manifests. + // The ConfigMap and the Secret data keys represent the var names and they + // must match the vars declared in the manifests for the substitution to happen. + // +optional + SubstituteFrom []SubstituteReference `json:"substituteFrom,omitempty"` +} + +// SubstituteReference contains a reference to a resource containing +// the variables name and value. +type SubstituteReference struct { + // Kind of the values referent, valid values are ('Secret', 'ConfigMap'). + // +kubebuilder:validation:Enum=Secret;ConfigMap + // +required + Kind string `json:"kind"` + + // Name of the values referent. Should reside in the same namespace as the + // referring resource. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +required + Name string `json:"name"` + + // Optional indicates whether the referenced resource must exist, or whether to + // tolerate its absence. If true and the referenced resource is absent, proceed + // as if the resource was present but empty, without any variables defined. + // +kubebuilder:default:=false + // +optional + Optional bool `json:"optional,omitempty"` +} + +// KustomizationStatus defines the observed state of a kustomization. +type KustomizationStatus struct { + meta.ReconcileRequestStatus `json:",inline"` + + // ObservedGeneration is the last reconciled generation. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` + + // The last successfully applied revision. + // Equals the Revision of the applied Artifact from the referenced Source. + // +optional + LastAppliedRevision string `json:"lastAppliedRevision,omitempty"` + + // LastAttemptedRevision is the revision of the last reconciliation attempt. + // +optional + LastAttemptedRevision string `json:"lastAttemptedRevision,omitempty"` + + // Inventory contains the list of Kubernetes resource object references that have been successfully applied. + // +optional + Inventory *ResourceInventory `json:"inventory,omitempty"` +} + +// GetTimeout returns the timeout with default. +func (in Kustomization) GetTimeout() time.Duration { + duration := in.Spec.Interval.Duration - 30*time.Second + if in.Spec.Timeout != nil { + duration = in.Spec.Timeout.Duration + } + if duration < 30*time.Second { + return 30 * time.Second + } + return duration +} + +// GetRetryInterval returns the retry interval +func (in Kustomization) GetRetryInterval() time.Duration { + if in.Spec.RetryInterval != nil { + return in.Spec.RetryInterval.Duration + } + return in.GetRequeueAfter() +} + +// GetRequeueAfter returns the duration after which the Kustomization must be +// reconciled again. +func (in Kustomization) GetRequeueAfter() time.Duration { + return in.Spec.Interval.Duration +} + +// GetDependsOn returns the list of dependencies across-namespaces. +func (in Kustomization) GetDependsOn() []meta.NamespacedObjectReference { + return in.Spec.DependsOn +} + +// GetConditions returns the status conditions of the object. +func (in Kustomization) GetConditions() []metav1.Condition { + return in.Status.Conditions +} + +// SetConditions sets the status conditions on the object. +func (in *Kustomization) SetConditions(conditions []metav1.Condition) { + in.Status.Conditions = conditions +} + +// GetStatusConditions returns a pointer to the Status.Conditions slice. +// Deprecated: use GetConditions instead. +func (in *Kustomization) GetStatusConditions() *[]metav1.Condition { + return &in.Status.Conditions +} + +// +genclient +// +genclient:Namespaced +// +kubebuilder:storageversion +// +kubebuilder:object:root=true +// +kubebuilder:resource:shortName=ks +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" + +// Kustomization is the Schema for the kustomizations API. +type Kustomization struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KustomizationSpec `json:"spec,omitempty"` + // +kubebuilder:default:={"observedGeneration":-1} + Status KustomizationStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// KustomizationList contains a list of kustomizations. +type KustomizationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Kustomization `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Kustomization{}, &KustomizationList{}) +} diff --git a/api/v1/reference_types.go b/api/v1/reference_types.go new file mode 100644 index 00000000..e466cbd0 --- /dev/null +++ b/api/v1/reference_types.go @@ -0,0 +1,47 @@ +/* +Copyright 2023 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1 + +import "fmt" + +// CrossNamespaceSourceReference contains enough information to let you locate the +// typed Kubernetes resource object at cluster level. +type CrossNamespaceSourceReference struct { + // API version of the referent. + // +optional + APIVersion string `json:"apiVersion,omitempty"` + + // Kind of the referent. + // +kubebuilder:validation:Enum=OCIRepository;GitRepository;Bucket + // +required + Kind string `json:"kind"` + + // Name of the referent. + // +required + Name string `json:"name"` + + // Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference. + // +optional + Namespace string `json:"namespace,omitempty"` +} + +func (s *CrossNamespaceSourceReference) String() string { + if s.Namespace != "" { + return fmt.Sprintf("%s/%s/%s", s.Kind, s.Namespace, s.Name) + } + return fmt.Sprintf("%s/%s", s.Kind, s.Name) +} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000..5731df8a --- /dev/null +++ b/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,331 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2023 The Flux 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 controller-gen. DO NOT EDIT. + +package v1 + +import ( + "github.com/fluxcd/pkg/apis/kustomize" + "github.com/fluxcd/pkg/apis/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + 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 *CommonMetadata) DeepCopyInto(out *CommonMetadata) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonMetadata. +func (in *CommonMetadata) DeepCopy() *CommonMetadata { + if in == nil { + return nil + } + out := new(CommonMetadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CrossNamespaceSourceReference) DeepCopyInto(out *CrossNamespaceSourceReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceSourceReference. +func (in *CrossNamespaceSourceReference) DeepCopy() *CrossNamespaceSourceReference { + if in == nil { + return nil + } + out := new(CrossNamespaceSourceReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Decryption) DeepCopyInto(out *Decryption) { + *out = *in + if in.SecretRef != nil { + in, out := &in.SecretRef, &out.SecretRef + *out = new(meta.LocalObjectReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Decryption. +func (in *Decryption) DeepCopy() *Decryption { + if in == nil { + return nil + } + out := new(Decryption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Kustomization) DeepCopyInto(out *Kustomization) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kustomization. +func (in *Kustomization) DeepCopy() *Kustomization { + if in == nil { + return nil + } + out := new(Kustomization) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Kustomization) 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 *KustomizationList) DeepCopyInto(out *KustomizationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Kustomization, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationList. +func (in *KustomizationList) DeepCopy() *KustomizationList { + if in == nil { + return nil + } + out := new(KustomizationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KustomizationList) 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 *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) { + *out = *in + if in.CommonMetadata != nil { + in, out := &in.CommonMetadata, &out.CommonMetadata + *out = new(CommonMetadata) + (*in).DeepCopyInto(*out) + } + if in.DependsOn != nil { + in, out := &in.DependsOn, &out.DependsOn + *out = make([]meta.NamespacedObjectReference, len(*in)) + copy(*out, *in) + } + if in.Decryption != nil { + in, out := &in.Decryption, &out.Decryption + *out = new(Decryption) + (*in).DeepCopyInto(*out) + } + out.Interval = in.Interval + if in.RetryInterval != nil { + in, out := &in.RetryInterval, &out.RetryInterval + *out = new(metav1.Duration) + **out = **in + } + if in.KubeConfig != nil { + in, out := &in.KubeConfig, &out.KubeConfig + *out = new(meta.KubeConfigReference) + **out = **in + } + if in.PostBuild != nil { + in, out := &in.PostBuild, &out.PostBuild + *out = new(PostBuild) + (*in).DeepCopyInto(*out) + } + if in.HealthChecks != nil { + in, out := &in.HealthChecks, &out.HealthChecks + *out = make([]meta.NamespacedObjectKindReference, len(*in)) + copy(*out, *in) + } + if in.Patches != nil { + in, out := &in.Patches, &out.Patches + *out = make([]kustomize.Patch, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Images != nil { + in, out := &in.Images, &out.Images + *out = make([]kustomize.Image, len(*in)) + copy(*out, *in) + } + out.SourceRef = in.SourceRef + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(metav1.Duration) + **out = **in + } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationSpec. +func (in *KustomizationSpec) DeepCopy() *KustomizationSpec { + if in == nil { + return nil + } + out := new(KustomizationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KustomizationStatus) DeepCopyInto(out *KustomizationStatus) { + *out = *in + out.ReconcileRequestStatus = in.ReconcileRequestStatus + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Inventory != nil { + in, out := &in.Inventory, &out.Inventory + *out = new(ResourceInventory) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationStatus. +func (in *KustomizationStatus) DeepCopy() *KustomizationStatus { + if in == nil { + return nil + } + out := new(KustomizationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PostBuild) DeepCopyInto(out *PostBuild) { + *out = *in + if in.Substitute != nil { + in, out := &in.Substitute, &out.Substitute + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.SubstituteFrom != nil { + in, out := &in.SubstituteFrom, &out.SubstituteFrom + *out = make([]SubstituteReference, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostBuild. +func (in *PostBuild) DeepCopy() *PostBuild { + if in == nil { + return nil + } + out := new(PostBuild) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceInventory) DeepCopyInto(out *ResourceInventory) { + *out = *in + if in.Entries != nil { + in, out := &in.Entries, &out.Entries + *out = make([]ResourceRef, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceInventory. +func (in *ResourceInventory) DeepCopy() *ResourceInventory { + if in == nil { + return nil + } + out := new(ResourceInventory) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRef) DeepCopyInto(out *ResourceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRef. +func (in *ResourceRef) DeepCopy() *ResourceRef { + if in == nil { + return nil + } + out := new(ResourceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SubstituteReference) DeepCopyInto(out *SubstituteReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubstituteReference. +func (in *SubstituteReference) DeepCopy() *SubstituteReference { + if in == nil { + return nil + } + out := new(SubstituteReference) + in.DeepCopyInto(out) + return out +} diff --git a/api/v1beta1/kustomization_types.go b/api/v1beta1/kustomization_types.go index 49160a89..84fc52e1 100644 --- a/api/v1beta1/kustomization_types.go +++ b/api/v1beta1/kustomization_types.go @@ -278,6 +278,7 @@ const ( // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" +// +kubebuilder:deprecatedversion:warning="v1beta1 Kustomization is deprecated, upgrade to v1" // Kustomization is the Schema for the kustomizations API. type Kustomization struct { diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index f48e1530..d325cf3f 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2021 The Flux authors +Copyright 2023 The Flux 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/api/v1beta2/kustomization_types.go b/api/v1beta2/kustomization_types.go index 582fe009..e529704d 100644 --- a/api/v1beta2/kustomization_types.go +++ b/api/v1beta2/kustomization_types.go @@ -305,13 +305,13 @@ func (in *Kustomization) GetStatusConditions() *[]metav1.Condition { // +genclient // +genclient:Namespaced -// +kubebuilder:storageversion // +kubebuilder:object:root=true // +kubebuilder:resource:shortName=ks // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="" +// +kubebuilder:deprecatedversion:warning="v1beta2 Kustomization is deprecated, upgrade to v1" // Kustomization is the Schema for the kustomizations API. type Kustomization struct { diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 5d153cd3..7a148980 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2021 The Flux authors +Copyright 2023 The Flux 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/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml index e8f2a0cc..730c375a 100644 --- a/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml +++ b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml @@ -17,6 +17,488 @@ spec: singular: kustomization scope: Namespaced versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Kustomization is the Schema for the kustomizations API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: KustomizationSpec defines the configuration to calculate + the desired state from a Source using Kustomize. + properties: + commonMetadata: + description: CommonMetadata specifies the common labels and annotations + that are applied to all resources. Any existing label or annotation + will be overridden if its key matches a common one. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to be added to the object's metadata. + type: object + labels: + additionalProperties: + type: string + description: Labels to be added to the object's metadata. + type: object + type: object + components: + description: Components specifies relative paths to specifications + of other Components. + items: + type: string + type: array + decryption: + description: Decrypt Kubernetes secrets before applying them on the + cluster. + properties: + provider: + description: Provider is the name of the decryption engine. + enum: + - sops + type: string + secretRef: + description: The secret name containing the private OpenPGP keys + used for decryption. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + dependsOn: + description: DependsOn may contain a meta.NamespacedObjectReference + slice with references to Kustomization resources that must be ready + before this Kustomization can be reconciled. + items: + description: NamespacedObjectReference contains enough information + to locate the referenced Kubernetes resource object in any namespace. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - name + type: object + type: array + force: + default: false + description: Force instructs the controller to recreate resources + when patching fails due to an immutable field change. + type: boolean + healthChecks: + description: A list of resources to be included in the health assessment. + items: + description: NamespacedObjectKindReference contains enough information + to locate the typed referenced Kubernetes resource object in any + namespace. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: array + images: + description: Images is a list of (image name, new name, new tag or + digest) for changing image names, tags or digests. This can also + be achieved with a patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, a new tag + or digest, which will replace the original name and tag. + properties: + digest: + description: Digest is the value used to replace the original + image tag. If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace the original + name. + type: string + newTag: + description: NewTag is the value used to replace the original + tag. + type: string + required: + - name + type: object + type: array + interval: + description: The interval at which to reconcile the Kustomization. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: The KubeConfig for reconciling the Kustomization on a + remote cluster. When used in combination with KustomizationSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at + the target cluster. If the --default-service-account flag is set, + its value will be used as a controller level fallback for when KustomizationSpec.ServiceAccountName + is empty. + properties: + secretRef: + description: SecretRef holds the name of a secret that contains + a key with the kubeconfig file as the value. If no key is set, + the key will default to 'value'. It is recommended that the + kubeconfig is self-contained, and the secret is regularly updated + if credentials such as a cloud-access-token expire. Cloud specific + `cmd-path` auth helpers will not function without adding binaries + and credentials to the Pod that is responsible for reconciling + Kubernetes resources. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + required: + - secretRef + type: object + patches: + description: Strategic merge and JSON patches, defined as inline YAML + objects, capable of targeting objects based on kind, label and annotation + selectors. + items: + description: Patch contains an inline StrategicMerge or JSON6902 + patch, and the target the patch should be applied to. + properties: + patch: + description: Patch contains an inline StrategicMerge patch or + an inline JSON6902 patch with an array of operation objects. + type: string + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: AnnotationSelector is a string that follows + the label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: Group is the API group to select resources + from. Together with Version and Kind it is capable of + unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: LabelSelector is a string that follows the + label selection expression https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: Version of the API Group to select resources + from. Together with Group and Kind it is capable of unambiguously + identifying and/or selecting resources. https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + path: + description: Path to the directory containing the kustomization.yaml + file, or the set of plain YAMLs a kustomization.yaml should be generated + for. Defaults to 'None', which translates to the root path of the + SourceRef. + type: string + postBuild: + description: PostBuild describes which actions to perform on the YAML + manifest generated by building the kustomize overlay. + properties: + substitute: + additionalProperties: + type: string + description: Substitute holds a map of key/value pairs. The variables + defined in your YAML manifests that match any of the keys defined + in the map will be substituted with the set value. Includes + support for bash string replacement functions e.g. ${var:=default}, + ${var:position} and ${var/substring/replacement}. + type: object + substituteFrom: + description: SubstituteFrom holds references to ConfigMaps and + Secrets containing the variables and their values to be substituted + in the YAML manifests. The ConfigMap and the Secret data keys + represent the var names and they must match the vars declared + in the manifests for the substitution to happen. + items: + description: SubstituteReference contains a reference to a resource + containing the variables name and value. + properties: + kind: + description: Kind of the values referent, valid values are + ('Secret', 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the values referent. Should reside + in the same namespace as the referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + default: false + description: Optional indicates whether the referenced resource + must exist, or whether to tolerate its absence. If true + and the referenced resource is absent, proceed as if the + resource was present but empty, without any variables + defined. + type: boolean + required: + - kind + - name + type: object + type: array + type: object + prune: + description: Prune enables garbage collection. + type: boolean + retryInterval: + description: The interval at which to retry a previously failed reconciliation. + When not specified, the controller uses the KustomizationSpec.Interval + value to retry failures. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + serviceAccountName: + description: The name of the Kubernetes service account to impersonate + when reconciling this Kustomization. + type: string + sourceRef: + description: Reference of the source where the kustomization file + is. + properties: + apiVersion: + description: API version of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, defaults to the namespace + of the Kubernetes resource object that contains the reference. + type: string + required: + - kind + - name + type: object + suspend: + description: This flag tells the controller to suspend subsequent + kustomize executions, it does not apply to already started executions. + Defaults to false. + type: boolean + targetNamespace: + description: TargetNamespace sets or overrides the namespace in the + kustomization.yaml file. + maxLength: 63 + minLength: 1 + type: string + timeout: + description: Timeout for validation, apply and health checking operations. + Defaults to 'Interval' duration. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + wait: + description: Wait instructs the controller to check the health of + all the reconciled resources. When enabled, the HealthChecks are + ignored. Defaults to false. + type: boolean + required: + - interval + - prune + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: KustomizationStatus defines the observed state of a kustomization. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + inventory: + description: Inventory contains the list of Kubernetes resource object + references that have been successfully applied. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary + to locate a resource within a cluster. + properties: + id: + description: ID is the string representation of the Kubernetes + resource object's metadata, in the format '___'. + type: string + v: + description: Version is the API version of the Kubernetes + resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object + lastAppliedRevision: + description: The last successfully applied revision. Equals the Revision + of the applied Artifact from the referenced Source. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastHandledReconcileAt: + description: LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value can + be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} - additionalPrinterColumns: - jsonPath: .status.conditions[?(@.type=="Ready")].status name: Ready @@ -27,6 +509,8 @@ spec: - jsonPath: .metadata.creationTimestamp name: Age type: date + deprecated: true + deprecationWarning: v1beta1 Kustomization is deprecated, upgrade to v1 name: v1beta1 schema: openAPIV3Schema: @@ -566,6 +1050,8 @@ spec: - jsonPath: .status.conditions[?(@.type=="Ready")].message name: Status type: string + deprecated: true + deprecationWarning: v1beta2 Kustomization is deprecated, upgrade to v1 name: v1beta2 schema: openAPIV3Schema: @@ -1137,6 +1623,6 @@ spec: type: object type: object served: true - storage: true + storage: false subresources: status: {} diff --git a/config/samples/kustomize_v1beta1_kustomization.yaml b/config/samples/kustomize_v1_kustomization.yaml similarity index 85% rename from config/samples/kustomize_v1beta1_kustomization.yaml rename to config/samples/kustomize_v1_kustomization.yaml index 35164984..d296984b 100644 --- a/config/samples/kustomize_v1beta1_kustomization.yaml +++ b/config/samples/kustomize_v1_kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: webapp-dev @@ -12,7 +12,7 @@ spec: wait: true timeout: 2m --- -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: webapp-production diff --git a/config/samples/source_v1beta1_gitrepository.yaml b/config/samples/source_v1beta2_gitrepository.yaml similarity index 76% rename from config/samples/source_v1beta1_gitrepository.yaml rename to config/samples/source_v1beta2_gitrepository.yaml index 60b5a4d4..d9eed924 100644 --- a/config/samples/source_v1beta1_gitrepository.yaml +++ b/config/samples/source_v1beta2_gitrepository.yaml @@ -1,4 +1,4 @@ -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: GitRepository metadata: name: webapp-latest @@ -8,7 +8,7 @@ spec: ref: branch: master --- -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: GitRepository metadata: name: webapp-releases diff --git a/config/testdata/crds-crs/cert-manager.yaml b/config/testdata/crds-crs/cert-manager.yaml index 1cec3dc5..f5f1bb2e 100644 --- a/config/testdata/crds-crs/cert-manager.yaml +++ b/config/testdata/crds-crs/cert-manager.yaml @@ -8,7 +8,7 @@ spec: ref: tag: "v1.1.0" --- -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: certs diff --git a/config/testdata/impersonation/test.yaml b/config/testdata/impersonation/test.yaml index 0aa96029..21edc705 100644 --- a/config/testdata/impersonation/test.yaml +++ b/config/testdata/impersonation/test.yaml @@ -44,7 +44,7 @@ spec: ref: tag: "6.3.0" --- -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: podinfo diff --git a/config/testdata/managed-fields/podinfo.yaml b/config/testdata/managed-fields/podinfo.yaml index 1f065fc0..857b26c4 100644 --- a/config/testdata/managed-fields/podinfo.yaml +++ b/config/testdata/managed-fields/podinfo.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: podinfo diff --git a/config/testdata/oci/podinfo.yaml b/config/testdata/oci/podinfo.yaml index fc80f79f..fb475093 100644 --- a/config/testdata/oci/podinfo.yaml +++ b/config/testdata/oci/podinfo.yaml @@ -9,7 +9,7 @@ spec: ref: tag: "6.3.0" --- -apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: oci diff --git a/docs/api/kustomize.md b/docs/api/kustomize.md index d5b0ec9d..9c2ad55a 100644 --- a/docs/api/kustomize.md +++ b/docs/api/kustomize.md @@ -2,16 +2,16 @@

Packages:

-

kustomize.toolkit.fluxcd.io/v1beta2

-

Package v1beta2 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1beta2 API group.

+

kustomize.toolkit.fluxcd.io/v1

+

Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1 API group.

Resource Types: -

Kustomization +

Kustomization

Kustomization is the Schema for the kustomizations API.

@@ -29,7 +29,7 @@ Resource Types: apiVersion
string -kustomize.toolkit.fluxcd.io/v1beta2 +kustomize.toolkit.fluxcd.io/v1 @@ -59,7 +59,7 @@ Refer to the Kubernetes API documentation for the fields of the spec
- + KustomizationSpec @@ -72,7 +72,7 @@ KustomizationSpec commonMetadata
- + CommonMetadata @@ -103,7 +103,7 @@ Kustomization can be reconciled.

decryption
- + Decryption @@ -180,7 +180,7 @@ Defaults to ‘None’, which translates to the root path of the SourceR postBuild
- + PostBuild @@ -233,36 +233,6 @@ capable of targeting objects based on kind, label and annotation selectors.

-patchesStrategicMerge
- - -[]Kubernetes pkg/apis/apiextensions/v1.JSON - - - - -(Optional) -

Strategic merge patches, defined as inline YAML objects. -Deprecated: Use Patches instead.

- - - - -patchesJson6902
- - -[]github.com/fluxcd/pkg/apis/kustomize.JSON6902Patch - - - - -(Optional) -

JSON 6902 patches, defined as inline YAML objects. -Deprecated: Use Patches instead.

- - - - images
@@ -294,7 +264,7 @@ when reconciling this Kustomization.

sourceRef
-
+ CrossNamespaceSourceReference @@ -382,18 +352,6 @@ When enabled, the HealthChecks are ignored. Defaults to false.

Components specifies relative paths to specifications of other Components.

- - -validation
- -string - - - -(Optional) -

Deprecated: Not used in v1beta2.

- - @@ -401,7 +359,7 @@ string status
- + KustomizationStatus @@ -413,11 +371,11 @@ KustomizationStatus
-

CommonMetadata +

CommonMetadata

(Appears on: -KustomizationSpec) +KustomizationSpec)

CommonMetadata defines the common labels and annotations.

@@ -458,11 +416,11 @@ map[string]string
-

CrossNamespaceSourceReference +

CrossNamespaceSourceReference

(Appears on: -KustomizationSpec) +KustomizationSpec)

CrossNamespaceSourceReference contains enough information to let you locate the typed Kubernetes resource object at cluster level.

@@ -526,11 +484,11 @@ string -

Decryption +

Decryption

(Appears on: -KustomizationSpec) +KustomizationSpec)

Decryption defines how decryption is handled for Kubernetes manifests.

@@ -572,11 +530,11 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
-

KustomizationSpec +

KustomizationSpec

(Appears on: -Kustomization) +Kustomization)

KustomizationSpec defines the configuration to calculate the desired state from a Source using Kustomize.

@@ -593,7 +551,7 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference commonMetadata
- + CommonMetadata @@ -624,7 +582,7 @@ Kustomization can be reconciled.

decryption
- + Decryption @@ -701,7 +659,7 @@ Defaults to ‘None’, which translates to the root path of the SourceR postBuild
- + PostBuild @@ -754,36 +712,6 @@ capable of targeting objects based on kind, label and annotation selectors.

-patchesStrategicMerge
- - -[]Kubernetes pkg/apis/apiextensions/v1.JSON - - - - -(Optional) -

Strategic merge patches, defined as inline YAML objects. -Deprecated: Use Patches instead.

- - - - -patchesJson6902
- - -[]github.com/fluxcd/pkg/apis/kustomize.JSON6902Patch - - - - -(Optional) -

JSON 6902 patches, defined as inline YAML objects. -Deprecated: Use Patches instead.

- - - - images
@@ -815,7 +743,7 @@ when reconciling this Kustomization.

sourceRef
-
+ CrossNamespaceSourceReference @@ -903,27 +831,15 @@ When enabled, the HealthChecks are ignored. Defaults to false.

Components specifies relative paths to specifications of other Components.

- - -validation
- -string - - - -(Optional) -

Deprecated: Not used in v1beta2.

- -
-

KustomizationStatus +

KustomizationStatus

(Appears on: -Kustomization) +Kustomization)

KustomizationStatus defines the observed state of a kustomization.

@@ -1005,7 +921,7 @@ string inventory
- + ResourceInventory @@ -1019,11 +935,11 @@ ResourceInventory
-

PostBuild +

PostBuild

(Appears on: -KustomizationSpec) +KustomizationSpec)

PostBuild describes which actions to perform on the YAML manifest generated by building the kustomize overlay.

@@ -1058,7 +974,7 @@ e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}.

substituteFrom
- + []SubstituteReference @@ -1075,11 +991,11 @@ must match the vars declared in the manifests for the substitution to happen.

-

ResourceInventory +

ResourceInventory

(Appears on: -KustomizationStatus) +KustomizationStatus)

ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization.

@@ -1096,7 +1012,7 @@ must match the vars declared in the manifests for the substitution to happen.

entries
- + []ResourceRef @@ -1109,11 +1025,11 @@ must match the vars declared in the manifests for the substitution to happen.

-

ResourceRef +

ResourceRef

(Appears on: -ResourceInventory) +ResourceInventory)

ResourceRef contains the information necessary to locate a resource within a cluster.

@@ -1153,11 +1069,11 @@ string
-

SubstituteReference +

SubstituteReference

(Appears on: -PostBuild) +PostBuild)

SubstituteReference contains a reference to a resource containing the variables name and value.

diff --git a/go.mod b/go.mod index 7208b391..5b3f41d3 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,6 @@ require ( google.golang.org/grpc v1.54.0 google.golang.org/protobuf v1.30.0 k8s.io/api v0.26.3 - k8s.io/apiextensions-apiserver v0.26.3 k8s.io/apimachinery v0.26.3 k8s.io/client-go v0.26.3 sigs.k8s.io/cli-utils v0.34.0 @@ -205,6 +204,7 @@ require ( gopkg.in/urfave/cli.v1 v1.20.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.26.3 // indirect k8s.io/cli-runtime v0.25.4 // indirect k8s.io/component-base v0.26.3 // indirect k8s.io/klog/v2 v2.90.1 // indirect diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt index 923f609e..e4b53a5f 100644 --- a/hack/boilerplate.go.txt +++ b/hack/boilerplate.go.txt @@ -1,5 +1,5 @@ /* -Copyright 2021 The Flux authors +Copyright 2023 The Flux 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/internal/controllers/kustomization_acl_test.go b/internal/controllers/kustomization_acl_test.go index 3c02229f..05c2eb4c 100644 --- a/internal/controllers/kustomization_acl_test.go +++ b/internal/controllers/kustomization_acl_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_NoCrossNamespaceRefs(t *testing.T) { diff --git a/internal/controllers/kustomization_controller.go b/internal/controllers/kustomization_controller.go index 4247874f..fd565042 100644 --- a/internal/controllers/kustomization_controller.go +++ b/internal/controllers/kustomization_controller.go @@ -62,7 +62,7 @@ import ( "github.com/fluxcd/pkg/tar" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/decryptor" "github.com/fluxcd/kustomize-controller/internal/inventory" ) diff --git a/internal/controllers/kustomization_decryptor_test.go b/internal/controllers/kustomization_decryptor_test.go index d082d0ed..c3a7a79e 100644 --- a/internal/controllers/kustomization_decryptor_test.go +++ b/internal/controllers/kustomization_decryptor_test.go @@ -33,7 +33,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Decryptor(t *testing.T) { diff --git a/internal/controllers/kustomization_dependson_test.go b/internal/controllers/kustomization_dependson_test.go index de40ed50..7a29fcc8 100644 --- a/internal/controllers/kustomization_dependson_test.go +++ b/internal/controllers/kustomization_dependson_test.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_DependsOn(t *testing.T) { diff --git a/internal/controllers/kustomization_fetcher_test.go b/internal/controllers/kustomization_fetcher_test.go index 3bf0794a..f8fa7561 100644 --- a/internal/controllers/kustomization_fetcher_test.go +++ b/internal/controllers/kustomization_fetcher_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_ArtifactDownload(t *testing.T) { diff --git a/internal/controllers/kustomization_force_test.go b/internal/controllers/kustomization_force_test.go index 0644037c..d5bddf2e 100644 --- a/internal/controllers/kustomization_force_test.go +++ b/internal/controllers/kustomization_force_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Force(t *testing.T) { diff --git a/internal/controllers/kustomization_fuzzer_test.go b/internal/controllers/kustomization_fuzzer_test.go index 6160deff..215a5f30 100644 --- a/internal/controllers/kustomization_fuzzer_test.go +++ b/internal/controllers/kustomization_fuzzer_test.go @@ -61,7 +61,7 @@ import ( fuzz "github.com/AdaLogics/go-fuzz-headers" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) var ( diff --git a/internal/controllers/kustomization_impersonation_test.go b/internal/controllers/kustomization_impersonation_test.go index 56d14961..df9a7903 100644 --- a/internal/controllers/kustomization_impersonation_test.go +++ b/internal/controllers/kustomization_impersonation_test.go @@ -34,7 +34,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Impersonation(t *testing.T) { diff --git a/internal/controllers/kustomization_indexers.go b/internal/controllers/kustomization_indexers.go index f4524400..d7d89542 100644 --- a/internal/controllers/kustomization_indexers.go +++ b/internal/controllers/kustomization_indexers.go @@ -26,7 +26,7 @@ import ( "github.com/fluxcd/pkg/runtime/dependency" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func (r *KustomizationReconciler) requestsForRevisionChangeOf(indexKey string) func(obj client.Object) []reconcile.Request { diff --git a/internal/controllers/kustomization_inventory_test.go b/internal/controllers/kustomization_inventory_test.go index 1dc0438c..c447e654 100644 --- a/internal/controllers/kustomization_inventory_test.go +++ b/internal/controllers/kustomization_inventory_test.go @@ -36,7 +36,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Inventory(t *testing.T) { diff --git a/internal/controllers/kustomization_prune_test.go b/internal/controllers/kustomization_prune_test.go index 1a5b0b72..7a90827e 100644 --- a/internal/controllers/kustomization_prune_test.go +++ b/internal/controllers/kustomization_prune_test.go @@ -32,7 +32,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Prune(t *testing.T) { diff --git a/internal/controllers/kustomization_transformer_test.go b/internal/controllers/kustomization_transformer_test.go index 284c03ed..024c540d 100644 --- a/internal/controllers/kustomization_transformer_test.go +++ b/internal/controllers/kustomization_transformer_test.go @@ -30,12 +30,11 @@ import ( . "github.com/onsi/gomega" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_CommonMetadata(t *testing.T) { @@ -471,25 +470,6 @@ metadata: `, }, }, - PatchesJSON6902: []kustomize.JSON6902Patch{ - { - Patch: []kustomize.JSON6902{ - {Op: "add", Path: "/metadata/labels/patch3", Value: &apiextensionsv1.JSON{Raw: []byte(`"json6902"`)}}, - {Op: "replace", Path: "/spec/replicas", Value: &apiextensionsv1.JSON{Raw: []byte("2")}}, - }, - Target: kustomize.Selector{ - Group: "apps", - Version: "v1", - Kind: "Deployment", - Name: "podinfo", - }, - }, - }, - PatchesStrategicMerge: []apiextensionsv1.JSON{ - { - Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"patch4":"strategic-merge"}}}`), - }, - }, }, } @@ -507,9 +487,6 @@ metadata: t.Run("applies patches", func(t *testing.T) { g.Expect(deployment.ObjectMeta.Labels["patch1"]).To(Equal("inline-json")) g.Expect(deployment.ObjectMeta.Labels["patch2"]).To(Equal("inline-yaml")) - g.Expect(deployment.ObjectMeta.Labels["patch3"]).To(Equal("json6902")) - g.Expect(deployment.ObjectMeta.Labels["patch4"]).To(Equal("strategic-merge")) - g.Expect(*deployment.Spec.Replicas).To(Equal(int32(2))) g.Expect(deployment.Spec.Template.Spec.Containers[0].Image).To(ContainSubstring("5.2.0")) g.Expect(deployment.Spec.Template.Spec.Containers[1].Image).To(ContainSubstring("sha256:2832f53c577d44753e97b0ed5f00e7e3a06979c9fab77d0e78bdac4b612b14fb")) }) diff --git a/internal/controllers/kustomization_validation_test.go b/internal/controllers/kustomization_validation_test.go index 42fd1b09..f686c603 100644 --- a/internal/controllers/kustomization_validation_test.go +++ b/internal/controllers/kustomization_validation_test.go @@ -29,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Validation(t *testing.T) { diff --git a/internal/controllers/kustomization_varsub_test.go b/internal/controllers/kustomization_varsub_test.go index 2c92cd36..3d8414eb 100644 --- a/internal/controllers/kustomization_varsub_test.go +++ b/internal/controllers/kustomization_varsub_test.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_Varsub(t *testing.T) { diff --git a/internal/controllers/kustomization_wait_test.go b/internal/controllers/kustomization_wait_test.go index 3f0da707..94efcc60 100644 --- a/internal/controllers/kustomization_wait_test.go +++ b/internal/controllers/kustomization_wait_test.go @@ -34,7 +34,7 @@ import ( "github.com/fluxcd/pkg/testserver" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func TestKustomizationReconciler_WaitConditions(t *testing.T) { diff --git a/internal/controllers/suite_test.go b/internal/controllers/suite_test.go index ab2879c3..806c1255 100644 --- a/internal/controllers/suite_test.go +++ b/internal/controllers/suite_test.go @@ -47,7 +47,7 @@ import ( "github.com/fluxcd/pkg/testserver" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func init() { diff --git a/internal/decryptor/decryptor.go b/internal/decryptor/decryptor.go index 45a95125..30d58d45 100644 --- a/internal/decryptor/decryptor.go +++ b/internal/decryptor/decryptor.go @@ -46,7 +46,7 @@ import ( kustypes "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/yaml" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/sops/age" "github.com/fluxcd/kustomize-controller/internal/sops/awskms" "github.com/fluxcd/kustomize-controller/internal/sops/azkv" diff --git a/internal/decryptor/decryptor_test.go b/internal/decryptor/decryptor_test.go index 83fa2596..322b856a 100644 --- a/internal/decryptor/decryptor_test.go +++ b/internal/decryptor/decryptor_test.go @@ -45,9 +45,10 @@ import ( kustypes "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/yaml" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" - "github.com/fluxcd/kustomize-controller/internal/sops/age" "github.com/fluxcd/pkg/apis/meta" + + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" + "github.com/fluxcd/kustomize-controller/internal/sops/age" ) func TestIsEncryptedSecret(t *testing.T) { diff --git a/internal/inventory/inventory.go b/internal/inventory/inventory.go index 2a01820e..0845fbde 100644 --- a/internal/inventory/inventory.go +++ b/internal/inventory/inventory.go @@ -26,7 +26,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/ssa" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) func New() *kustomizev1.ResourceInventory { diff --git a/main.go b/main.go index a88876da..2f95ab3b 100644 --- a/main.go +++ b/main.go @@ -45,7 +45,7 @@ import ( "github.com/fluxcd/pkg/runtime/probes" sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" - kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2" + kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/controllers" "github.com/fluxcd/kustomize-controller/internal/features" "github.com/fluxcd/kustomize-controller/internal/statusreaders" From 793450fe5df19ed54d3be183a74c772de1d5ff02 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Wed, 29 Mar 2023 21:48:06 +0530 Subject: [PATCH 02/11] docs: add Kustomization v1 docs Signed-off-by: Sanskar Jaiswal --- docs/spec/README.md | 54 +- docs/spec/v1/README.md | 17 + docs/spec/v1/kustomization.md | 1753 +++++++++++++++++++++++++++++++++ 3 files changed, 1774 insertions(+), 50 deletions(-) create mode 100644 docs/spec/v1/README.md create mode 100644 docs/spec/v1/kustomization.md diff --git a/docs/spec/README.md b/docs/spec/README.md index c980280b..166d7311 100644 --- a/docs/spec/README.md +++ b/docs/spec/README.md @@ -1,53 +1,7 @@ # Kustomize Controller -The kustomize-controller is a Kubernetes operator, specialized in running -continuous delivery pipelines for infrastructure and workloads -defined with Kubernetes manifests and assembled with Kustomize. +## API Specification -## Motivation - -The main goal is to provide an automated operator that can -bootstrap and continuously reconcile the cluster state -from multiple sources (e.g. infrastructure and application repositories). - -When provisioning a new cluster, one may wish to install workloads in a specific order, -for example a validation controller such as OPA Gatekeeper should be up and running before -applying other manifests on the cluster. Another example is a service mesh admission controller, -the proxy injector must be functional before deploying applications into the mesh. - -When a cluster is shared with multiple teams, a cluster admin may wish to assign roles and service -accounts to each team. The manifests owned by a team will be applied on the cluster using -the team's account thus ensuring isolation between teams. For example, an admin can -restrict the operations performed on the cluster by a team to a single namespace. - -When dealing with an incident, one may wish to suspend the reconciliation of some workloads and -pin the reconciliation of others to a specific Git revision, without having to stop the reconciler -and affect the whole cluster. - -When operating a cluster, different teams may wish to receive notification about the status -of their CD pipelines. For example, the on-call team would receive alerts about all -failures in the prod namespace, while the frontend team may wish to be alerted when a new version -of the frontend app was deployed and if the deployment is healthy, no matter the namespace. - -## Design - -The reconciliation process can be defined with a Kubernetes custom resource -that describes a pipeline such as: -- **check** if depends-on conditions are meet -- **fetch** manifests from source-controller -- **generate** `kustomization.yaml` if needed -- **build** the manifests using the Kustomize SDK -- **decrypt** Kubernetes secrets using Mozilla SOPS SDK -- **impersonate** the tenant's Kubernetes account -- **validate** the resulting objects using server-side apply dry-run -- **detect drift** between the desired and state and cluster state -- **correct drift** by applying the objects using server-side apply -- **prune** the objects removed from source -- **wait** for the applied changes to rollout using Kubernetes kstatus library -- **report** the reconciliation result in the `status` sub-resource -- **alert** if something went wrong by sending events to Kubernetes API and notification-controller -- **notify** if the cluster state changed by sending events to Kubernetes API and notification-controller - -## Specifications - -The latest API specifications can be found [here](v1beta2/README.md). +[v1beta1](v1beta2/README.md). +[v1beta2](v1beta2/README.md). +[v1](v1/README.md). diff --git a/docs/spec/v1/README.md b/docs/spec/v1/README.md new file mode 100644 index 00000000..f0ae66f2 --- /dev/null +++ b/docs/spec/v1/README.md @@ -0,0 +1,17 @@ +# kustomize.toolkit.fluxcd.io/v1 + +This is the v1 API specification for defining continuous delivery pipelines +of Kubernetes objects generated with Kustomize. + +## Specification + +- [Kustomization CRD](kustomization.md) + + [Example](kustomization.md#example) + + [Writing a Kustomization spec](kustomization.md#writing-a-kustomization-spec) + + [Recommended settings](kustomization.md#recommended-settings) + + [Working with Kustomizations](kustomization.md#working-with-kustomizations) + + [Kustomization Status](kustomization.md#kustomization-status) + +## Implementation + +* [kustomize-controller](https://github.com/fluxcd/kustomize-controller/) diff --git a/docs/spec/v1/kustomization.md b/docs/spec/v1/kustomization.md new file mode 100644 index 00000000..2b94c732 --- /dev/null +++ b/docs/spec/v1/kustomization.md @@ -0,0 +1,1753 @@ +# Kustomization + +The `Kustomization` API defines a pipeline for fetching, decrypting, building, +validating and applying Kustomize overlays or plain Kubernetes manifests. +The `Kustomization` Custom Resource Definition is the +counterpart of Kustomize's `kustomization.yaml` config file. + +## Example + +The following is an example of a Flux Kustomization that reconciles the +Kubernetes manifests stored in a Git repository. + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ref: + branch: master +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: default +spec: + interval: 10m + targetNamespace: default + sourceRef: + kind: GitRepository + name: podinfo + path: "./kustomize" + prune: true + timeout: 1m +``` + +In the above example: + +- A Flux GitRepository named `podinfo` is created that clones the `master` + branch and makes the repository content available as an Artifact inside the cluster. +- A Flux Kustomization named `podinfo` is created that watches the + GitRepository for artifact changes. +- The Kustomization builds the YAML manifests located at the specified `spec.path`, + sets the namespace of all objects to the `spec.targetNamespace`, + validates the objects against the Kubernetes API and finally applies them on + the cluster. +- As specified by `spec.interval`, every ten minutes, the Kustomization runs a + server-side apply dry-run to detect and correct drift inside the cluster. +- When the Git revision changes, the manifests are reconciled automatically. If + previously applied objects are missing from the current revision, these + objects are deleted from the cluster when `spec.prune` is enabled. + +You can run this example by saving the manifest into `podinfo.yaml`. + +1. Apply the resource on the cluster: + + ```sh + kubectl apply -f podinfo.yaml + ``` + +2. Run `kubectl get gitrepositories` to see the source status: + + ```console + NAME URL READY STATUS + podinfo https://github.com/stefanprodan/podinfo True stored artifact for revision 'master@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0' + ``` + +3. Run `kubectl get kustomizations` to see the reconciliation status: + + ```console + NAME READY STATUS + podinfo True Applied revision: master@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0 + ``` + +4. Run `kubectl describe kustomization podinfo` to see the reconciliation status conditions and events: + + ```console + ... + Status: + Conditions: + Last Transition Time: 2022-06-07T11:14:41Z + Message: Applied revision: master@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0 + Reason: ReconciliationSucceeded + Status: True + Type: Ready + Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Progressing 1m48s kustomize-controller Service/default/podinfo created + Deployment/default/podinfo created + HorizontalPodAutoscaler/default/podinfo created + Normal ReconciliationSucceeded 1m48s kustomize-controller Reconciliation finished in 176.163666ms, next run in 10m0s + ``` + +## Writing a Kustomization spec + +As with all other Kubernetes config, a Kustomization needs `apiVersion`, +`kind`, and `metadata` fields. The name of a Kustomization object must be a +valid [DNS subdomain name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names#dns-subdomain-names). + +A Kustomization also needs a +[`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status). + +### Source reference + +`spec.sourceRef` is used to refer to the Source object which has the required +Artifact containing the YAML manifests. It has two required fields: + +* `kind`: The Kind of the referred Source object. Supported Source types: + * [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md) + * [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/ocirepositories.md) + * [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/buckets.md) +* `name`: The Name of the referred Source object. + +#### Cross-namespace references +By default, the Source object is assumed to be in the same namespace as the +Kustomization. To refer to a Source object in a different namesapce, specify +the namespace using `spec.sourceRef.namespace`. + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: webapp + namespace: apps +spec: + interval: 5m + path: "./deploy" + sourceRef: + kind: GitRepository + name: webapp + namespace: shared +``` + +On multi-tenant clusters, platform admins can disable cross-namespace references +by starting kustomize-controller with the `--no-cross-namespace-refs=true` flag. + +### Prune + +`spec.prune` is a required boolean field to enable/disable garbage collection +for a Kustomization. + +Garbage collection means that the Kubernetes objects that were previously +applied on the cluster but are missing from the current source revision, are +removed from the cluster automatically. Garbage collection is also performed +when a Kustomization object is deleted, triggering a removal of all Kubernetes +objects previously applied on the cluster. The removal of the Kubernetes objects +is done in the background, i.e it doesn't block the reconciliation of the Kustomization. + +To enable garbage collection for a Kustomization, set this field to `true`. + +You can disable pruning for certain resources by either labelling or +annotating them with: + +```yaml +kustomize.toolkit.fluxcd.io/prune: disabled +``` + +For info on how the controller tracks Kubernetes objects and determines what to +garbage collect, see [`.status.inventory`](#inventory). + +### Interval + +`spec.interval` is a required field that specifies the interval at which the +Kustomization is reconciled, i.e. the controller fetches the source with the +Kubernetes manifests, builds the Kustomization and applies it on the cluster, +correcting any existing drift in the process. The minimum value should be over 60 seconds. + +After successfully reconciling the object, kustomize-controller requeues it for +inspection after the specified interval. The value must be in a +[Go recognized duration string format](https://pkg.go.dev/time#ParseDuration), +e.g. `10m0s` to reconcile the object every 10 minutes. + +If the `.metadata.generation` of a resource changes (due to e.g. a change to +the spec) or the Source revision changes (which generates a Kubernetes event), +this is handled instantly outside the interval window. + +### Retry interval + +`spec.retryInterval` is an optional field to specify the interval at which to +retry a failed reconciliation. Unlike `spec.interval`, this field is +exclusively meant for failure retries. If not specified, it defaults to `spec.interval`. + +### Path + +`spec.path` is an optional field to specify the path to the directory in the +Source Artifact containing the kustomization.yaml file, or the set of plain +YAMLs for which a kustomization.yaml should be generated. +It defaults to blank, which translates to the root of the Source Artifact. + +Further reading: [Generate kustomization.yaml](#generate-kustomizationyaml) + +### Target namespace + +`spec.targetNamespace` is an optional field to specify the target namespace for +all the objects that are part of the Kustomization. It either configures or +overrides the [Kustomize `namespace`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/namespace/). + +While `spec.targetNamespace` is optional, if this field is non-empty then the +Kubernetes namespace being pointed to must exist prior to the Kustomization +being applied, kustomize-controller will not create the namespace. + +### Suspend + +`spec.suspend` is an optional boolean field to suspend the reconciliation of the +Kustomization. When a Kustomization is suspended, new Source revisions are not +applied to the cluster and drift detection/correction is paused. +To resume normal reconciliation, set it back to `false` or remove the field. + +For more info, see [Suspending and resuming](#suspending-and-resuming). + +### Health checks + +`spec.healthChecks` is an optional list used to refer to resources for which the +controller will perform health checks used to determine the rollout status of +[deployed workloads](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#deployment-status) +and the `Ready` status of custom resources. + +A health check entry can reference one of the following types: + +- Kubernetes built-in kinds: Deployment, DaemonSet, StatefulSet, + PersistentVolumeClaim, Pod, PodDisruptionBudget, Job, CronJob, Service, + Secret, ConfigMap, CustomResourceDefinition +- Flux kinds: HelmRelease, HelmRepository, GitRepository, etc. +- Custom resources that are compatible with [kstatus](https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus) + +Assuming the Kustomization source contains a Kubernetes Deployment named +`backend`, a health check can be defined as follows: +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: backend + namespace: default +spec: + interval: 5m + prune: true + sourceRef: + kind: GitRepository + name: webapp + healthChecks: + - apiVersion: apps/v1 + kind: Deployment + name: backend + namespace: dev +``` + +After applying the kustomize build output, the controller verifies if the +rollout was completed successfully. If the deployment was successful, the +Kustomization `Ready` condition is marked as `true`, if the rollout failed, or if +it takes more than the specified timeout to complete, then the Kustomization +`Ready` condition is set to false. If the deployment becomes healthy on the +next execution, then the Kustomization is marked as ready. + +When a Kustomization contains HelmRelease objects, instead of checking the +underlying Deployments, you can define a health check that waits for the +HelmReleases to be reconciled with: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: webapp + namespace: default +spec: + interval: 15m + path: "./releases/" + prune: true + sourceRef: + kind: GitRepository + name: webapp + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2beta1 + kind: HelmRelease + name: frontend + namespace: dev + - apiVersion: helm.toolkit.fluxcd.io/v2beta1 + kind: HelmRelease + name: backend + namespace: dev + timeout: 5m +``` + +If all the HelmRelease objects are successfully installed or upgraded, then +the Kustomization will be marked as ready. + +### Wait + +`spec.wait` is an optional boolean field to perform health checks for __all__ +reconciled resources as part of the Kustomization. If set to `true`, +`spec.healthChecks` is ignored. + +### Timeout + +`spec.timeout` is an optional field to specify a timeout duration for any +operation like building, applying, health checking, etc. performed during the +reconciliation process. + +### Dependencies + +`spec.dependsOn` is an optional list used to refer to other Kustomization +objects that the Kustomization depends on. If specified, then the Kustomization +is only applied after the referred Kustomizations are ready, i.e. have the +`Ready` condition marked as `true`. The readiness state of a Kustomization is +determined by its last applied status condition. + +This is helpful when need to make sure other resources exist before the +workloads defined in a Kustomization are deployed. For example, before +installing objects of a certain custom resource kind, the CRDs and the related +controller must exist in the cluster. + +Assuming two Kustomizations: +* cert-manager - reconciles the cert-manager CRDs and controller +* certs - reconciles the cert-manager custom resources + +You can instruct the controller to apply the cert-manager Kustomization before certs: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cert-manager + namespace: flux-system +spec: + interval: 5m + path: "./cert-manager/controller" + prune: true + sourceRef: + kind: GitRepository + name: flux-system + healthChecks: + - apiVersion: apps/v1 + kind: Deployment + name: cert-manager + namespace: cert-manager +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: certs + namespace: flux-system +spec: + dependsOn: + - name: cert-manager + interval: 5m + path: "./cert-manager/certs" + prune: true + sourceRef: + kind: GitRepository + name: flux-system +``` + +If `spec.healthChecks` is non-empty or `spec.wait` is set to `true`, a +Kustomization will be applied after all its dependencies' health checks are +passing. For example, a service mesh proxy injector should be running before +deploying applications inside the mesh. + +**Note:** Circular dependencies between Kustomizations must be avoided, +otherwise the interdependent Kustomizations will never be applied on the cluster. + +### Service Account reference + +`spec.serviceAccountName` is an optional field used to specify the +ServiceAccount to be impersonated while reconciling the Kustomization. For more +details, see [Role-based Access Control](#role-based-access-control). + +### Common metadata + +`spec.commonMetadata` is an optional field used to specify any metadata that +should be applied to all the Kustomization's resources. It has two optional fields: + +* `labels`: A map used for setting [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) + on an object. Any existing label will be overriden if it matches a key in + this map. +* `annotations`: A map used for setting [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) + on an object. Any existing annotation will be overriden if it matches a key + in this map. + +### Patches + +`spec.patches` is an optional list used to specify [Kustomize `patches`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/) +as inline YAML objects. This enables patching resources using either a +[strategic merge](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchstrategicmerge) +patch or a [JSON6902](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchjson6902) +patch. A patch can target a single resource or multiple resources. Each item in +the list must have the two fields mentioned below: + +* `patch`: Patch contains an inline strategic merge patch or an inline JSON6902 patch with an array of operation objects. +* `target`: Target points to the resources that the patch document should be applied to. + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: flux-system +spec: + # ...omitted for brevity + patches: + - patch: |- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: not-used + spec: + template: + metadata: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + target: + kind: Deployment + labelSelector: "app.kubernetes.io/part-of=my-app" + - patch: | + - op: add + path: /spec/template/spec/securityContext + value: + runAsUser: 10000 + fsGroup: 1337 + - op: add + path: /spec/template/spec/containers/0/securityContext + value: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: + - ALL + target: + kind: Deployment + name: podinfo + namespace: apps +``` + +### Images +`spec.images` is an optional list used to specify +[Kustomize `images`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/). +This allows overwriting the name, tag or digest of container images without creating patches. + +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: flux-system +spec: + # ...omitted for brevity + images: + - name: podinfo + newName: my-registry/podinfo + newTag: v1 + - name: podinfo + newTag: 1.8.0 + - name: podinfo + newName: my-podinfo + - name: podinfo + digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 +``` + +### Components +`spec.components` is an optional list used to specify +[Kustomize `components`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/components/). +This allows using reusable pieces of configuration logic that can be included +from multiple overlays. + +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: podinfo + namespace: flux-system +spec: + # ...omitted for brevity + components: + - ingress + - tls +``` + +**Note:** The component paths must be local and relative to the source root. + +**Warning:** Components are an alpha feature in Kustomize and are therefore +considered experimental in Flux. No guarantees are provided as the feature may +be modified in backwards incompatible ways or removed without warning. + +### Postbuild Variable Substitution + +With `spec.postBuild.substitute` you can provide a map of key/value pairs +holding the variables to be substituted in the final YAML manifest, after +kustomize build. + +With `spec.postBuild.substituteFrom` you can provide a list of ConfigMaps and +Secrets from which the variables are loaded. +The ConfigMap and Secret data keys are used as the var names. + +The `spec.postBuild.substituteFrom.optional` field indicates how the +controller should handle a referenced ConfigMap or Secret being absent +at reconciliation time. The controller's default behavior ― with +`optional` unspecified or set to `false` ― has it fail reconciliation if +the referenced object is missing. By setting the `optional` field to +`true`, you can indicate that the controller should use the referenced +object if it's there, but also tolerate its absence, treating that +absence as if the object had been present but empty, defining no +variables. + +This offers basic templating for your manifests including support +for [bash string replacement functions](https://github.com/drone/envsubst) e.g.: + +- `${var:=default}` +- `${var:position}` +- `${var:position:length}` +- `${var/substring/replacement}` + +**Note:** The name of a variable can contain only alphanumeric and underscore +characters. The controller validates the var names using this regular expression: +`^[_[:alpha:]][_[:alpha:][:digit:]]*$`. + +Assuming you have manifests with the following variables: + +```yaml +--- +apiVersion: v1 +kind: Namespace +metadata: + name: apps + labels: + environment: ${cluster_env:=dev} + region: "${cluster_region}" +``` + +You can specify the variables and their values in the Kustomization definition using +`spec.postBuild.substitute` and/or `spec.postBuild.substituteFrom`: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: apps +spec: + interval: 5m + path: "./apps/" + postBuild: + substitute: + cluster_env: "prod" + cluster_region: "eu-central-1" + substituteFrom: + - kind: ConfigMap + name: cluster-vars + # Use this ConfigMap if it exists, but proceed if it doesn't. + optional: true + - kind: Secret + name: cluster-secret-vars + # Fail if this Secret does not exist. +``` + +**Note:** For substituting variables in a secret, `spec.stringData` field must be used i.e + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: secret + namespace: flux-system +type: Opaque +stringData: + token: ${token} +``` + +The var values which are specified in-line with `substitute` +take precedence over the ones derived from `substituteFrom`. + +**Note:** If you want to avoid var substitutions in scripts embedded in +ConfigMaps or container commands, you must use the format `$var` instead of +`${var}`. If you want to keep the curly braces you can use `$${var}` which +will print out `${var}`. + +All the undefined variables in the format `${var}` will be substituted with an +empty string unless a default value is provided e.g. `${var:=default}`. + +You can disable the variable substitution for certain resources by either +labelling or annotating them with: + +```yaml +kustomize.toolkit.fluxcd.io/substitute: disabled +``` + +Substitution of variables only happens if at least a single variable or resource +to substitute from is defined. This may cause issues if you rely on expressions +which should evaluate to a default value, even if no other variables are +configured. To work around this, one can set an arbitrary key/value pair to +enable the substitution of variables. For example: + +```yaml +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: apps +spec: + ... + postBuild: + substitute: + var_substitution_enabled: "true" +``` + +You can replicate the controller post-build substitutions locally using +[kustomize](https://github.com/kubernetes-sigs/kustomize) +and Drone's [envsubst](https://github.com/drone/envsubst): + +```console +$ go install github.com/drone/envsubst/cmd/envsubst + +$ export cluster_region=eu-central-1 +$ kustomize build ./apps/ | $GOPATH/bin/envsubst +--- +apiVersion: v1 +kind: Namespace +metadata: + name: apps + labels: + environment: dev + region: eu-central-1 +``` + +### Force + +`spec.force` is an optional boolean. If set to `true`, the controller will +replace the resources in-cluster if the patching fails due to immutable field +changes. + +You can enable force apply for specific resources by labelling or annotating them with: + +```yaml +kustomize.toolkit.fluxcd.io/force: enabled +``` + +### KubeConfig reference + +`spec.kubeConfig.secretRef.Name` is an optional field to specify the name of +the secret containing a KubeConfig. If specified, objects will be applied, +health-checked, pruned, and deleted for the default cluster specified in that +KubeConfig instead of using the in-cluster ServiceAccount. + +The secret defined in the `kubeConfig.SecretRef` must exist in the same +namespace as the Kustomization. On every reconciliation, the KubeConfig bytes +will be loaded from the `.secretRef.key` key (default: `value` or `value.yaml`) +of the Secret’s data , and the Secret can thus be regularly updated if +cluster-access-tokens have to rotate due to expiration. + +```yaml +apiVersion: v1 +stringData: + value.yaml: | + apiVersion: v1 + kind: Config + # ...omitted for brevity +kind: Secret +metadata: + name: prod-kubeconfig +type: Opaque + +``` + +**Note:** The KubeConfig should be self-contained and not rely on binaries, +environment, or credential files from the kustomize-controller Pod. +This matches the constraints of KubeConfigs from current Cluster API providers. +KubeConfigs with `cmd-path` in them likely won't work without a custom, +per-provider installation of kustomize-controller. + +When both `spec.kubeConfig` and `spec.ServiceAccountName` are specified, +the controller will impersonate the service account on the target cluster. + +For more information, see [Remote Clusters/Cluster-API](#remote-clusters--cluster-api). + +### Decryption + +`spec.decryption` holds the decryption configuration to decrypt Secrets that +are a part of the Kustomization. Since, Secrets are either plain text or +`base64` encoded, its extremely unsafe to store them as it is in a public or +private Git repository. In order to store them safely, you can use +[Mozilla SOPS](https://github.com/mozilla/sops) and encrypt your Kubernetes +Secrets data with [age](https://age-encryption.org/v1/) and [OpenPGP](https://www.openpgp.org) +keys, or with provider implementations like Azure Key Vault, GCP KMS or Hashicorp Vault. + +**Note:** You should encrypt only the `data` section of the Kubernetes Secret, +encrypting the `metadata`, `kind` or `apiVersion` fields is not supported. +An easy way to do this is by appending `--encrypted-regex '^(data|stringData)$'` +to your `sops --encrypt` command. + +It has two required fields: +* `secretRef.name`: The name of the secret that contains the keys to be used for decryption. +* `provider`: The secrets decryption provider to be used. The only supported + value at the moment is `sops`. + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: sops-encrypted + namespace: default +spec: + interval: 5m + path: "./" + sourceRef: + kind: GitRepository + name: repository-with-secrets + decryption: + provider: sops + secretRef: + name: sops-keys +``` + +**Note:** For info on Secrets decryption at a controller level, please see +[Controller global decryption](#controller-global-decryption). + +The Secret's `.data` section is expected to contain entries with decryption +keys (for age and OpenPGP), or credentials (for any of the supported provider +implementations). The controller identifies the type of the entry by the suffix +of the key (e.g. `.agekey`), or a fixed key (e.g. `sops.vault-token`). + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary age private key + identity.agekey: + # Examplary Hashicorp Vault token + sops.vault-token: +``` + +#### age Secret entry + +To specify an age private key in a Kubernetes Secret, suffix the key of the +`.data` entry with `.agekey`. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary age private key + identity.agekey: +``` + +#### OpenPGP Secret entry + +To specify an OpenPGP (passwordless) keyring in armor format in a Kubernetes +Secret, suffix the key of the `.data` entry with `.asc`. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary OpenPGP keyring + identity.asc: +``` + +#### AWS KMS Secret Entry + +To specify credentials for an AWS user account linked to the IAM role with access +to KMS, append a `.data` entry with a fixed `sops.aws-kms` key. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + sops.aws-kms: | + aws_access_key_id: some-access-key-id + aws_secret_access_key: some-aws-secret-access-key + aws_session_token: some-aws-session-token # this field is optional +``` + +#### Azure Key Vault Secret entry + +To specify credentials for Azure Key Vault in a Secret, append a `.data` entry +with a fixed `sops.azure-kv` key. The value can contain a variety of JSON or +YAML formats depending on the authentication method you want to utilize. + +##### Service Principal with Secret + +To configure a Service Principal with Secret credentials to access the Azure +Key Vault, a JSON or YAML object with `tenantId`, `clientId` and `clientSecret` +fields must be configured as the `sops.azure-kv` value. It +optionally supports `authorityHost` to configure an authority host other than +the Azure Public Cloud endpoint. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Service Principal with Secret + sops.azure-kv: | + tenantId: some-tenant-id + clientId: some-client-id + clientSecret: some-client-secret +``` + +##### Service Principal with Certificate + +To configure a Service Principal with Certificate credentials to access the +Azure Key Vault, a JSON or YAML object with `tenantId`, `clientId` and +`clientCertificate` fields must be configured as the `sops.azure-kv` value. +It optionally supports `clientCertificateSendChain` and `authorityHost` to +control the sending of the certificate chain, or to specify an authority host +other than the Azure Public Cloud endpoint. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Service Principal with Certificate + sops.azure-kv: | + tenantId: some-tenant-id + clientId: some-client-id + clientCertificate: +``` + +##### `az` generated Service Principal + +To configure a Service Principal [generated using +`az`](https://docs.microsoft.com/en-us/azure/aks/kubernetes-service-principal?tabs=azure-cli#manually-create-a-service-principal), +the output of the command can be directly used as a `sops.azure-kv` value. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Service Principal generated with `az` + sops.azure-kv: | + { + "appId": "559513bd-0c19-4c1a-87cd-851a26afd5fc", + "displayName": "myAKSClusterServicePrincipal", + "name": "http://myAKSClusterServicePrincipal", + "password": "e763725a-5eee-40e8-a466-dc88d980f415", + "tenant": "72f988bf-86f1-41af-91ab-2d7cd011db48" + } +``` + +##### Managed Identity with Client ID + +To configure a Managed Identity making use of a Client ID, a JSON or YAML +object with a `clientId` must be configured as the `sops.azure-kv` value. It +optionally supports `authorityHost` to configure an authority host other than +the Azure Public Cloud endpoint. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary Azure Managed Identity with Client ID + sops.azure-kv: | + clientId: some-client-id +``` + +#### GCP KMS Secret entry + +To specify credentials for GCP KMS in a Kubernetes Secret, append a `.data` +entry with a fixed `sops.gcp-kms` key and the service account keys as its value. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +stringData: + # Exemplary GCP Service Account credentials file + sops.gcp-kms: | + { + "type": "service_account", + "project_id": "", + "private_key_id": "", + "private_key": "" + } +``` + +#### Hashicorp Vault Secret entry + +To specify credentials for Hashicorp Vault in a Kubernetes Secret, append a +`.data` entry with a fixed `sops.vault-token` key and the token as value. + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: sops-keys + namespace: default +data: + # Exemplary Hashicorp Vault Secret token + sops.vault-token: +``` + +## Recommended settings + +When deploying applications to production environments, it is recommended +to configure the following fields, while adjusting them to your desires for responsiveness: + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: webapp + namespace: apps +spec: + interval: 1m0s # check for new commits every minute and apply changes + url: https://github.com/org/webapp # clone over HTTPS + secretRef: # use token auth + name: webapp-git-token # Flux user PAT (read-only access) + ref: + branch: main + ignore: | + # exclude all + /* + # include deploy dir + !/deploy +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: webapp + namespace: apps +spec: + interval: 60m0s # detect drift and undo kubectl edits every hour + wait: true # wait for all applied resources to become ready + timeout: 3m0s # give up waiting after three minutes + retryInterval: 2m0s # retry every two minutes on apply or waiting failures + prune: true # remove stale resources from cluster + force: false # enable this to recreate resources on immutable fields changes + targetNamespace: apps # set the namespace for all resources + sourceRef: + kind: GitRepository + name: webapp + namespace: apps + path: "./deploy/production" +``` + +## Working with Kustomizations + +### Generate kustomization.yaml + +If your repository contains plain Kubernetes manifests, the +`kustomization.yaml` file is automatically generated (if it doesn't already exist) +for all the Kubernetes manifests in the directory tree specified in [`spec.path`](#path). +All YAML files present under that path must be valid Kubernetes manifests, +unless they're excluded either by way of the [`.sourceignore`](https://fluxcd.io/flux/components/source/gitrepositories/#sourceignore-file) +file or the [`spec.ignore`](https://fluxcd.io/flux/components/source/gitrepositories/#ignore) field on the corresponding Source object. + +Example of excluding CI workflows and SOPS config files: + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: podinfo + namespace: default +spec: + interval: 5m + url: https://github.com/stefanprodan/podinfo + ignore: | + .github/ + .sops.yaml + .gitlab-ci.yml +``` + +It is recommended to generate the `kustomization.yaml` on your own and store it +in Git, this way you can validate your manifests in CI +(example script [here](https://github.com/fluxcd/flux2-multi-tenancy/blob/main/scripts/validate.sh)). +Assuming your manifests are inside `apps/my-app`, you can generate a +`kustomization.yaml` with: + +```sh +cd apps/my-app + +# create kustomization.yaml +kustomize create --autodetect --recursive +``` + +### Role-based access control + +By default, a Kustomization apply runs under the cluster admin account and can +create, modify and delete cluster level objects (namespaces, CRDs, etc) and +namespaced objects (deployments, ingresses, etc). For certain Kustomizations a +cluster admin may wish to control what types of Kubernetes objects can be +reconciled and under which namespaces. +To restrict a Kustomization, one can assign a service account under which the +reconciliation is performed using [`spec.serviceAccountName`](#service-account-reference). + +Assuming you want to restrict a group of Kustomizations to a single namespace, +you can create an account with a role binding that grants access only to that namespace: + +```yaml +--- +apiVersion: v1 +kind: Namespace +metadata: + name: webapp +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: flux + namespace: webapp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: webapp-reconciler + namespace: webapp +rules: + - apiGroups: ['*'] + resources: ['*'] + verbs: ['*'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: webapp-reconciler + namespace: webapp +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: webapp-reconciler +subjects: +- kind: ServiceAccount + name: flux + namespace: webapp +``` + +**Note:** The namespace, RBAC and service account manifests should be +placed in a Git source and applied with a Kustomization. The Kustomizations that +are running under that service account should depend on the one that contains the account. + +Create a Kustomization that prevents altering the cluster state outside of the +`webapp` namespace: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: backend + namespace: webapp +spec: + serviceAccountName: flux + dependsOn: + - name: rbac + interval: 5m + path: "./webapp/backend/" + prune: true + sourceRef: + kind: GitRepository + name: webapp +``` + +When the controller reconciles the `backend` Kustomization, it will impersonate +the `flux` ServiceAccount. If the Kustomization contains cluster level objects +like CRDs or objects belonging to a different namespace, the reconciliation will +fail since the account it runs under has no permissions to alter objects outside +of the `webapp` namespace. + +#### Enforce impersonation + +On multi-tenant clusters, platform admins can enforce impersonation with the +`--default-service-account` flag. + +When the flag is set, all Kustomizations which don't have [`spec.serviceAccountName`](#service-account-reference) +specified will use the service account name provided by +`--default-service-account=` in the namespace of the object. + +### Remote clusters/Cluster-API + +With the [`spec.kubeConfig` field](#kubeconfig-reference) a Kustomization can be fully +reconciled on a remote cluster. This composes well with Cluster API bootstrap +providers such as CAPBK (kubeadm), CAPA (AWS) and others. + +To reconcile a Kustomization to a CAPI controlled cluster, put the +`Kustomization` in the same namespace as your `Cluster` object, and set the +`kubeConfig.secretRef.name` to `-kubeconfig`: + +```yaml +apiVersion: cluster.x-k8s.io/v1alpha3 +kind: Cluster +metadata: + name: stage # the kubeconfig Secret will contain the Cluster name + namespace: capi-stage +spec: + clusterNetwork: + pods: + cidrBlocks: + - 10.100.0.0/16 + serviceDomain: stage-cluster.local + services: + cidrBlocks: + - 10.200.0.0/12 + controlPlaneRef: + apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 + kind: KubeadmControlPlane + name: stage-control-plane + namespace: capi-stage + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 + kind: DockerCluster + name: stage + namespace: capi-stage +--- +# ... unrelated Cluster API objects omitted for brevity ... +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cluster-addons + namespace: capi-stage +spec: + interval: 5m + path: "./config/addons/" + prune: true + sourceRef: + kind: GitRepository + name: cluster-addons + kubeConfig: + secretRef: + name: stage-kubeconfig # Cluster API creates this for the matching Cluster +``` + +The Cluster and Kustomization can be created at the same time. +The Kustomization will eventually reconcile once the cluster is available. + +If you wish to target clusters created by other means than CAPI, you can create +a ServiceAccount on the remote cluster, generate a KubeConfig for that account +and then create a secret on the cluster where kustomize-controller is running e.g.: + +```sh +kubectl create secret generic prod-kubeconfig \ + --from-file=value.yaml=./kubeconfig +``` + +### Controller global decryption + +Other than [authentication using a Secret reference](#decryption), +it is possible to specify global decryption settings on the +kustomize-controller Pod. When the controller fails to find credentials on the +Kustomization object itself, it will fall back to these defaults. + +#### AWS KMS + +While making use of the [IAM OIDC provider](https://eksctl.io/usage/iamserviceaccounts/) +on your EKS cluster, you can create an IAM Role and Service Account with access +to AWS KMS (using at least `kms:Decrypt` and `kms:DescribeKey`). Once these are +created, you can annotate the kustomize-controller Service Account with the +Role ARN, granting the controller permission to decrypt the Secrets. Please refer +to the [SOPS guide](https://fluxcd.io/flux/guides/mozilla-sops/#aws) for detailed steps. + +```sh +kubectl -n flux-system annotate serviceaccount kustomize-controller \ + --field-manager=flux-client-side-apply \ + eks.amazonaws.com/role-arn='arn:aws:iam:::role/' +``` + +Furthermore, you can also use the usual [environment variables used for specifying AWS +credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-list) +, by patching the kustomize-controller deployment: + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + spec: + containers: + - name: manager + env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: awsAccessKeyID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: awsSecretAccessKey + - name: AWS_SESSION_TOKEN + valueFrom: + secretKeyRef: + name: aws-creds + key: awsSessionToken +``` + +In addition to this, the +[general SOPS documentation around KMS AWS applies](https://github.com/mozilla/sops#27kms-aws-profiles), +allowing you to specify e.g. a `SOPS_KMS_ARN` environment variable. + +**Note:**: If you're mounting a secret containing the AWS credentials as a file in the `kustomize-controller` pod, +you'd need to specify an environment variable `$HOME`, since the AWS credentials file is expected to be present +at `~/.aws`, like so: +```yaml +env: + - name: HOME + value: /home/{$USER} +``` + +#### Azure Key Vault + +While making use of [AAD Pod Identity](https://github.com/Azure/aad-pod-identity), +you can bind a Managed Identity to Flux's kustomize-controller. Once the +`AzureIdentity` and `AzureIdentityBinding` for this are created, you can patch +the controller's Deployment with the `aadpodidbinding` label set to the +selector of the binding, and the `AZURE_AUTH_METHOD` environment variable set +to `msi`. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + metadata: + labels: + aadpodidbinding: sops-akv-decryptor # match the AzureIdentityBinding selector + spec: + containers: + - name: manager + env: + - name: AZURE_AUTH_METHOD + value: msi +``` + +In addition to this, the [default SOPS Azure Key Vault flow is +followed](https://github.com/mozilla/sops#encrypting-using-azure-key-vault), +allowing you to specify a variety of other environment variables. + +#### GCP KMS + +While making use of Google Cloud Platform, the [`GOOGLE_APPLICATION_CREDENTIALS` +environment variable](https://cloud.google.com/docs/authentication/production) +is automatically taken into account. +[Granting permissions](https://cloud.google.com/kms/docs/reference/permissions-and-roles) +to the Service Account attached to this will therefore be sufficient to decrypt +data. When running outside GCP, it is possible to manually patch the +kustomize-controller Deployment with a valid set of (mounted) credentials. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + spec: + containers: + - name: manager + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/gcp/credentials.json + volumeMounts: + - name: gcp-credentials + mountPath: /var/gcp/ + readOnly: true + volumes: + - name: gcp-credentials + secret: + secretName: mysecret + items: + - key: credentials + path: credentials.json +``` + +#### Hashicorp Vault + +To configure a global default for Hashicorp Vault, patch the controller's +Deployment with a `VAULT_TOKEN` environment variable. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kustomize-controller + namespace: flux-system +spec: + template: + spec: + containers: + - name: manager + env: + - name: VAULT_TOKEN + value: +``` + +### Kustomize secretGenerator + +SOPS encrypted data can be stored as a base64 encoded Secret, which enables the +use of [Kustomize `secretGenerator`](https://github.com/kubernetes-sigs/kustomize/tree/main/examples/secretGeneratorPlugin.md) +as follows: + +```console +$ echo "my-secret-token" | sops -e /dev/stdin > token.encrypted +$ cat < kustomization.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +secretGenerator: + - name: token + files: + - token=token.encrypted +EOF +``` + +Commit and push `token.encrypted` and `kustomization.yaml` to Git. + +The kustomize-controller scans the values of Kubernetes Secrets, and when it +detects that the values are SOPS encrypted, it decrypts them before applying +them on the cluster. + +For secrets in `.json`, `.yaml` `.ini` and `.env` format, make sure you specify +the input type when encrypting them with SOPS: + +```sh +sops -e --input-type=json config.json > config.json.encrypted +sops -e --input-type=yaml config.yaml > config.yaml.encrypted +sops -e --input-type=env config.env > config.env.encrypted +``` + +For kustomize-controller to be able to decrypt a JSON config, you need to set +the file extension to `.json`: + +```yaml +kind: Kustomization +secretGenerator: + - name: config + files: + - config.json=config.json.encrypted +``` + +For dotenv files, use the `envs` directive: + +```yaml +kind: Kustomization +secretGenerator: + - name: config + envs: + - config.env.encrypted +``` + +For Docker config files, you need to specify both input and output type as JSON: + +```sh +sops -e --input-type=json --output-type=json ghcr.dockerconfigjson > ghcr.dockerconfigjson.encrypted +``` + +To generate an image pull secret, use the `.dockerconfigjson` as the secret key: + +```yaml +kind: Kustomization +secretGenerator: + - name: ghcr-auth + type: kubernetes.io/dockerconfigjson + files: + - .dockerconfigjson=ghcr.dockerconfigjson.encrypted +``` + +### Triggering a reconcile + +To manually tell the kustomize-controller to reconcile a Kustomization outside +the [specified interval window](#interval), it can be annotated with +`reconcile.fluxcd.io/requestedAt: `. Annotating the resource +queues the Kustomization for reconciliation if the `` differs +from the last value the controller acted on, as reported in +[`.status.lastHandledReconcileAt`](#last-handled-reconcile-at). + +Using `kubectl`: + +```sh +kubectl annotate --field-manager=flux-client-side-apply --overwrite kustomization/ reconcile.fluxcd.io/requestedAt="$(date +%s)" +``` + +Using `flux`: + +```sh +flux reconcile kustomization +``` + +### Customizing reconciliation + +You can configure the controller to ignore in-cluster resources by labelling or annotating them with: + +```yaml +kustomize.toolkit.fluxcd.io/reconcile: disabled +``` + +**Note:** When the `kustomize.toolkit.fluxcd.io/reconcile` annotation is set to `disabled`, +the controller will no longer apply changes from the source, nor will it prune the resource. +To resume reconciliation, set the annotation to `enabled` in the source +or remove it from the in-cluster object. + +If you use kubectl to edit an object managed by Flux, all changes will be undone when +the controller reconciles a Flux Kustomization containing that object. +In order to preserve fields added with kubectl, you have to specify a field manager +named `flux-client-side-apply` e.g.: + +```sh +kubectl apply --field-manager=flux-client-side-apply +``` + +Another option is to annotate or label objects with: + +```yaml +kustomize.toolkit.fluxcd.io/ssa: merge +``` + +**Note:** The fields defined in manifests will always be overridden, +the above procedure works only for adding new fields that don’t overlap with the desired state. + +For lists fields which are atomic (e.g `spec.tolerations` in PodSpec), Kubernetes doesn't allow different managers +for such fields, therefore any changes to these fields will be undone, even if you specify a manager. +For more context, please see the Kubernetes enhancement doc: +[555-server-side-apply](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/555-server-side-apply/README.md#lists). + +To learn how to handle patching failures due to immutable field changes, see [`spec.force`](#force). + +### Waiting for `Ready` + +When a change is applied, it is possible to wait for the Kustomization to reach +a `Ready` state using `kubectl`: + +```sh +kubectl wait gitrepository/ --for=condition=ready --timeout=1m +``` + +### Suspending and resuming + +When you find yourself in a situation where you temporarily want to pause the +reconciliation of a Kustomization, you can suspend it using [`spec.suspend`](#suspend). + +#### Suspend a Kustomization + +In your YAML declaration: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: +spec: + suspend: true +``` + +Using `kubectl`: + +```sh +kubectl patch kustomization --field-manager=flux-client-side-apply -p '{\"spec\": {\"suspend\" : true }}' +``` + +Using `flux`: + +```sh +flux suspend kustomization +``` + +#### Resume a GitRepository + +In your YAML declaration, comment out (or remove) the field: + +```yaml +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: +spec: + # suspend: true +``` + +**Note:** Setting the field value to `false` has the same effect as removing +it, but does not allow for "hot patching" using e.g. `kubectl` while practicing +GitOps; as the manually applied patch would be overwritten by the declared +state in Git. + +Using `kubectl`: + +```sh +kubectl patch kustomization --field-manager=flux-client-side-apply -p '{\"spec\" : {\"suspend\" : false }}' +``` + +Using `flux`: + +```sh +flux resume kustomization +``` + + +### Debugging a Kustomization + +There are several ways to gather information about a Kustomization for +debugging purposes. + +#### Describe the Kustomization + +Describing a Kustomization using +`kubectl describe kustomization ` +displays the latest recorded information for the resource in the `Status` and +`Events` sections: + +```console +... +Status: +... + Conditions: + Last Transition Time: 2023-03-29T06:09:32Z + Message: Fetching manifests for revision master/67e2c98a60dc92283531412a9e604dd4bae005a9 with a timeout of 4m30s + Observed Generation: 3 + Reason: ProgressingWithRetry + Status: True + Type: Reconciling + Last Transition Time: 2023-03-29T06:09:32Z + Message: kustomization path not found: stat /tmp/kustomization-1464362706/invalid: no such file or directory + Observed Generation: 3 + Reason: ArtifactFailed + Status: False + Type: Ready + Last Applied Revision: master/67e2c98a60dc92283531412a9e604dd4bae005a9 + Last Attempted Revision: master/67e2c98a60dc92283531412a9e604dd4bae005a9 + Observed Generation: 2 +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning ArtifactFailed 2s kustomize-controller kustomization path not found: stat /tmp/kustomization-1464362706/invalid: no such file or directory + +``` + +#### Trace emitted Events + +To view events for specific Kustomization(s), `kubectl events` can be used +to list the Events for specific objects. For example, running + +```sh +kubectl events -n flux-system --for kustomization/podinfo +``` + +lists + +```console +LAST SEEN TYPE REASON OBJECT MESSAGE +31s Warning ArtifactFailed kustomization/podinfo kustomization path not found: stat /tmp/kustomization-3011588360/invalid: no such file or directory +26s Normal ArtifactFailed kustomization/podinfo HorizontalPodAutoscaler/default/podinfo deleted... +18s Warning ArtifactFailed kustomization/podinfo kustomization path not found: stat /tmp/kustomization-3336282420/invalid: no such file or directory +9s Normal Progressing kustomization/podinfo Service/default/podinfo created... +9s Normal ReconciliationSucceeded kustomization/podinfo Reconciliation finished in 75.190237ms, next run in 5m0s +``` + +You can also use use the `flux events` command to view all events for a Kustomization and its related Source. For example, + +```sh +flux events --for Kustomization/podinfo +``` + +will list all events for the `podinfo` Kustomization in the `flux-system` namesapce and its related Source object, the `podinfo` GitRepository. + +```console +LAST SEEN TYPE REASON OBJECT MESSAGE +3m2s Warning ArtifactFailed Kustomization/podinfo kustomization path not found: stat /tmp/kustomization-3336282420/invalid: no such file or directory + +2m53s Normal ReconciliationSucceeded Kustomization/podinfo Reconciliation finished in 75.190237ms, next run in 5m0s + +2m53s Normal Progressing Kustomization/podinfo Service/default/podinfo created + Deployment/default/podinfo created + HorizontalPodAutoscaler/default/podinfo created + +19s (x17 over 8m24s) Normal GitOperationSucceeded GitRepository/podinfo no changes since last reconcilation: observed revision 'master/67e2c98a60dc92283531412a9e604dd4bae005a9' +``` + +Besides being reported in Events, the reconciliation errors are also logged by +the controller. The Flux CLI offer commands for filtering the logs for a +specific GitRepository, e.g. +`flux logs --level=error --kind=Kustomization --name=`. + +## Kustomization Status + +### Conditions + +A Kustomization enters various states during its lifecycle, reflected as +[Kubernetes Conditions][typical-status-properties]. +It can be [reconciling](#reconciling-kustomization) while applying the Kustomization on the cluster, it can be [ready](#ready-kustomization), or it can [fail during +reconciliation](#failed-kustomization). + +The Kustomization API is compatible with the [kstatus specification][kstatus-spec], +and reports `Reconciling` and `Stalled` conditions where applicable to +provide better (timeout) support to solutions polling the Kustomization to +become `Ready`. + +#### Reconciling Kustomization + +The kustomize-controller marks a Kustomization as _reconciling_ when it starts +the reconciliation of the same. The Condition added to the Kustomization's +`.status.conditions` has the following attributes: + +- `type: Reconciling` +- `status: "True"` +- `reason: Progressing` | `reason: ProgressingWithRetry` + +The Condition `message` is updated during the course of the reconciliation to +report the action being performed at any particular moment such as +building manifests, detecting drift, etc. + +The `Ready` Condition's `status` is also marked as `Unkown`. + +#### Ready Kustomization + +The kustomize-controller marks a Kustomization as _ready_ when a Kustomization +is successfully reconciled, i.e. the source was fetched, the kustomization was +built and applied on the cluster and all health checks are observed to be passing. + +When the Kustomization is "ready", the controller sets a Condition with the +following attributes in the Kustomization’s `.status.conditions`: + +- `type: Ready` +- `status: "True"` +- `reason: ReconciliationSucceeded` + +#### Failed Kustomization + +The kustomize-controller may get stuck trying to reconcile and apply a +Kustomization without completing. This can occur due to some of the following factors: + +* The Source object does not exist on the cluster. +* The Source has not produced an Artifact yet. +* The Kustomization's dependencies aren't ready yet. +* The specified path does not exist in the Artifact. +* Building the kustomization fails. +* Garbage collection fails. +* Running a health check failed. + +When this happens, the controller sets the `Ready` Condition status to False +and adds a Condition with the following attributes to the `Kustomization`’s +`.status.conditions`: + +- `type: Ready | HealthyCondition` +- `status: "False"` +- `reason: PruneFailed | ArtifactFailed | BuildFailed | HealthCheckFailed | DependencyNotReady | ReconciliationFailed ` + +The `message` field of the Condition will contain more information about why +the reconciliation failed. + +While the Kustomization has one or more of these Conditions, the controller +will continue to attempt a reconciliation of the Kustomization with an +exponential backoff, until it succeeds and the Kustomization marked as [ready](#ready-kustomization). + +Note that a Kustomization can be [reconciling](#reconciling-kustomization) +while failing at the same time, for example, due to a newly introduced +configuration issue in the Kustomization spec. When a reconciliation fails, the +`Reconciling` Condition `reason` would be `ProgressingWithRetry`. When the +reconciliation is performed again after the failure, the `reason` is updated to `Progressing`. + +### Inventory + +In order to perform operations such as drift detection, garbage collection, etc. +kustomize-controller needs to keep track of all Kubernetes objects that are +reconciled as part of a Kustomziation. To do this, it maintains an inventory +containing the list of Kubernetes resource object references that have been +successfully applied and records it in `.status.inventory`. The inventory +records are in the format `____`. + +```console +Status: + Inventory: + Entries: + Id: default_podinfo__Service + V: v1 + Id: default_podinfo_apps_Deployment + V: v1 + Id: default_podinfo_autoscaling_HorizontalPodAutoscaler + V: v2 +``` + +### Last applied revision + +`.status.lastAppliedRevision` is the last revision of the Artifact from the +referred Source object that was successfully applied to the cluster. + +### Last attempted revision + +`.status.lastAttemptedRevision` is the last revision of the Artifact from the +referred Source object that was attempted to be applied to the cluster. + +### Observed Generation + +The kustomize-controller reports an [observed generation][typical-status-properties] +in the Kustomization's `.status.observedGeneration`. The observed generation is +the latest `.metadata.generation` which resulted in either a [ready state](#ready-kustomization), +or stalled due to an error it can not recover from without human +intervention. + +### Last Handled Reconcile At + +The kustomize-controller reports the last `reconcile.fluxcd.io/requestedAt` +annotation value it acted on in the `.status.lastHandledReconcileAt` field. + +For practical information about this field, see [triggering a reconcile](#triggering-a-reconcile). + +[typical-status-properties]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties +[kstatus-spec]: https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus From 172adf6ee08c06a2dcff79ff119dce77b98a5c19 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Thu, 30 Mar 2023 16:35:25 +0300 Subject: [PATCH 03/11] Version API generated docs Signed-off-by: Stefan Prodan --- Makefile | 2 +- docs/api/{ => v1}/kustomize.md | 2 +- docs/spec/v1/kustomization.md | 22 ++++++++++++++-------- hack/api-docs/template/pkg.tpl | 7 ++++++- 4 files changed, 22 insertions(+), 11 deletions(-) rename docs/api/{ => v1}/kustomize.md (99%) diff --git a/Makefile b/Makefile index 2731a18c..263638bd 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ manifests: controller-gen # Generate API reference documentation api-docs: gen-crd-api-reference-docs - $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/kustomize.md + $(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1/kustomize.md # Run go mod tidy tidy: diff --git a/docs/api/kustomize.md b/docs/api/v1/kustomize.md similarity index 99% rename from docs/api/kustomize.md rename to docs/api/v1/kustomize.md index 9c2ad55a..da5b640f 100644 --- a/docs/api/kustomize.md +++ b/docs/api/v1/kustomize.md @@ -1,4 +1,4 @@ -

Kustomize API reference

+

Kustomize API reference v1

Packages:

  • diff --git a/docs/spec/v1/kustomization.md b/docs/spec/v1/kustomization.md index 2b94c732..61b7efd7 100644 --- a/docs/spec/v1/kustomization.md +++ b/docs/spec/v1/kustomization.md @@ -1,5 +1,7 @@ # Kustomization + + The `Kustomization` API defines a pipeline for fetching, decrypting, building, validating and applying Kustomize overlays or plain Kubernetes manifests. The `Kustomization` Custom Resource Definition is the @@ -82,7 +84,7 @@ You can run this example by saving the manifest into `podinfo.yaml`. ... Status: Conditions: - Last Transition Time: 2022-06-07T11:14:41Z + Last Transition Time: 2023-03-07T11:14:41Z Message: Applied revision: master@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0 Reason: ReconciliationSucceeded Status: True @@ -117,8 +119,9 @@ Artifact containing the YAML manifests. It has two required fields: * `name`: The Name of the referred Source object. #### Cross-namespace references + By default, the Source object is assumed to be in the same namespace as the -Kustomization. To refer to a Source object in a different namesapce, specify +Kustomization. To refer to a Source object in a different namespace, specify the namespace using `spec.sourceRef.namespace`. ```yaml @@ -231,6 +234,7 @@ A health check entry can reference one of the following types: Assuming the Kustomization source contains a Kubernetes Deployment named `backend`, a health check can be defined as follows: + ```yaml --- apiVersion: kustomize.toolkit.fluxcd.io/v1 @@ -317,6 +321,7 @@ installing objects of a certain custom resource kind, the CRDs and the related controller must exist in the cluster. Assuming two Kustomizations: + * cert-manager - reconciles the cert-manager CRDs and controller * certs - reconciles the cert-manager custom resources @@ -381,7 +386,7 @@ should be applied to all the Kustomization's resources. It has two optional fiel on an object. Any existing label will be overriden if it matches a key in this map. * `annotations`: A map used for setting [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) - on an object. Any existing annotation will be overriden if it matches a key + on an object. Any existing annotation will be overridden if it matches a key in this map. ### Patches @@ -441,6 +446,7 @@ spec: ``` ### Images + `spec.images` is an optional list used to specify [Kustomize `images`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/). This allows overwriting the name, tag or digest of container images without creating patches. @@ -466,6 +472,7 @@ spec: ``` ### Components + `spec.components` is an optional list used to specify [Kustomize `components`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/components/). This allows using reusable pieces of configuration logic that can be included @@ -561,7 +568,7 @@ spec: # Fail if this Secret does not exist. ``` -**Note:** For substituting variables in a secret, `spec.stringData` field must be used i.e +**Note:** For substituting variables in a secret, `spec.stringData` field must be used i.e: ```yaml --- @@ -678,7 +685,7 @@ per-provider installation of kustomize-controller. When both `spec.kubeConfig` and `spec.ServiceAccountName` are specified, the controller will impersonate the service account on the target cluster. -For more information, see [Remote Clusters/Cluster-API](#remote-clusters--cluster-api). +For more information, see [Remote Clusters/Cluster-API](#remote-clusterscluster-api). ### Decryption @@ -690,7 +697,7 @@ private Git repository. In order to store them safely, you can use Secrets data with [age](https://age-encryption.org/v1/) and [OpenPGP](https://www.openpgp.org) keys, or with provider implementations like Azure Key Vault, GCP KMS or Hashicorp Vault. -**Note:** You should encrypt only the `data` section of the Kubernetes Secret, +**Note:** You should encrypt only the `data/stringData` section of the Kubernetes Secret, encrypting the `metadata`, `kind` or `apiVersion` fields is not supported. An easy way to do this is by appending `--encrypted-regex '^(data|stringData)$'` to your `sops --encrypt` command. @@ -1540,7 +1547,6 @@ Using `flux`: flux resume kustomization ``` - ### Debugging a Kustomization There are several ways to gather information about a Kustomization for @@ -1683,7 +1689,7 @@ Kustomization without completing. This can occur due to some of the following fa * Running a health check failed. When this happens, the controller sets the `Ready` Condition status to False -and adds a Condition with the following attributes to the `Kustomization`’s +and adds a Condition with the following attributes to the Kustomization’s `.status.conditions`: - `type: Ready | HealthyCondition` diff --git a/hack/api-docs/template/pkg.tpl b/hack/api-docs/template/pkg.tpl index 61d05f77..d3c3d073 100644 --- a/hack/api-docs/template/pkg.tpl +++ b/hack/api-docs/template/pkg.tpl @@ -1,5 +1,10 @@ {{ define "packages" }} -

    Kustomize API reference

    +

    Kustomize API reference + {{- with (index .packages 0) -}} + {{ with (index .GoPackages 0 ) -}} + {{ printf " %s" .Name -}} + {{ end -}} + {{ end }}

    {{ with .packages}}

    Packages:

    From 4ed5082946c1d4f4b58b99e07c4f8c6036f44aeb Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Thu, 30 Mar 2023 17:10:47 +0300 Subject: [PATCH 04/11] Update Source APIs to v1.0.0-rc.1 Signed-off-by: Stefan Prodan --- config/default/kustomization.yaml | 4 ++-- ...tory.yaml => source_v1_gitrepository.yaml} | 4 ++-- config/testdata/crds-crs/cert-manager.yaml | 2 +- config/testdata/dependencies/source.yaml | 2 +- .../status-defaults/empty-kustomization.yaml | 2 +- go.mod | 2 +- go.sum | 4 ++-- .../controllers/kustomization_acl_test.go | 2 +- .../controllers/kustomization_controller.go | 19 ++++++++++--------- .../kustomization_decryptor_test.go | 2 +- .../kustomization_dependson_test.go | 2 +- .../controllers/kustomization_fetcher_test.go | 2 +- .../controllers/kustomization_force_test.go | 2 +- .../controllers/kustomization_fuzzer_test.go | 2 +- .../kustomization_impersonation_test.go | 2 +- .../controllers/kustomization_indexers.go | 2 +- .../kustomization_inventory_test.go | 2 +- .../controllers/kustomization_prune_test.go | 2 +- .../kustomization_transformer_test.go | 2 +- .../kustomization_validation_test.go | 2 +- .../controllers/kustomization_varsub_test.go | 2 +- .../controllers/kustomization_wait_test.go | 3 ++- internal/controllers/source_predicate.go | 2 +- internal/controllers/suite_test.go | 6 ++++-- main.go | 2 +- 25 files changed, 41 insertions(+), 37 deletions(-) rename config/samples/{source_v1beta2_gitrepository.yaml => source_v1_gitrepository.yaml} (76%) diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index faba8968..151ee30c 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: kustomize-system resources: -- https://github.com/fluxcd/source-controller/releases/download/v0.36.0/source-controller.crds.yaml -- https://github.com/fluxcd/source-controller/releases/download/v0.36.0/source-controller.deployment.yaml +- https://github.com/fluxcd/source-controller/releases/download/v1.0.0-rc.1/source-controller.crds.yaml +- https://github.com/fluxcd/source-controller/releases/download/v1.0.0-rc.1/source-controller.deployment.yaml - ../crd - ../rbac - ../manager diff --git a/config/samples/source_v1beta2_gitrepository.yaml b/config/samples/source_v1_gitrepository.yaml similarity index 76% rename from config/samples/source_v1beta2_gitrepository.yaml rename to config/samples/source_v1_gitrepository.yaml index d9eed924..431f8382 100644 --- a/config/samples/source_v1beta2_gitrepository.yaml +++ b/config/samples/source_v1_gitrepository.yaml @@ -1,4 +1,4 @@ -apiVersion: source.toolkit.fluxcd.io/v1beta2 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: webapp-latest @@ -8,7 +8,7 @@ spec: ref: branch: master --- -apiVersion: source.toolkit.fluxcd.io/v1beta2 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: webapp-releases diff --git a/config/testdata/crds-crs/cert-manager.yaml b/config/testdata/crds-crs/cert-manager.yaml index f5f1bb2e..0f43c6f7 100644 --- a/config/testdata/crds-crs/cert-manager.yaml +++ b/config/testdata/crds-crs/cert-manager.yaml @@ -1,4 +1,4 @@ -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: certs diff --git a/config/testdata/dependencies/source.yaml b/config/testdata/dependencies/source.yaml index b6dd9a63..f24c81fb 100644 --- a/config/testdata/dependencies/source.yaml +++ b/config/testdata/dependencies/source.yaml @@ -1,4 +1,4 @@ -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: webapp diff --git a/config/testdata/status-defaults/empty-kustomization.yaml b/config/testdata/status-defaults/empty-kustomization.yaml index 80620f12..d4fd9197 100644 --- a/config/testdata/status-defaults/empty-kustomization.yaml +++ b/config/testdata/status-defaults/empty-kustomization.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: status-defaults diff --git a/go.mod b/go.mod index 5b3f41d3..ed93e285 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/fluxcd/pkg/ssa v0.27.0 github.com/fluxcd/pkg/tar v0.2.0 github.com/fluxcd/pkg/testserver v0.4.0 - github.com/fluxcd/source-controller/api v0.36.1 + github.com/fluxcd/source-controller/api v1.0.0-rc.1 github.com/hashicorp/vault/api v1.9.0 github.com/onsi/gomega v1.27.5 github.com/opencontainers/go-digest v1.0.0 diff --git a/go.sum b/go.sum index 3663f087..a4411267 100644 --- a/go.sum +++ b/go.sum @@ -232,8 +232,8 @@ github.com/fluxcd/pkg/tar v0.2.0 h1:HEUHgONQYsJGeZZ4x6h5nQU9Aox1I4T3bOp1faWTqf8= github.com/fluxcd/pkg/tar v0.2.0/go.mod h1:w0/TOC7kwBJhnSJn7TCABkc/I7ib1f2Yz6vOsbLBnhw= github.com/fluxcd/pkg/testserver v0.4.0 h1:pDZ3gistqYhwlf3sAjn1Q8NzN4Qe6I1BEmHMHi46lMg= github.com/fluxcd/pkg/testserver v0.4.0/go.mod h1:gjOKX41okmrGYOa4oOF2fiLedDAfPo1XaG/EzrUUGBI= -github.com/fluxcd/source-controller/api v0.36.1 h1:/ul69kJNEwrFG1Cwk2P/GwgraIxOETCL+tP+zMtxTu8= -github.com/fluxcd/source-controller/api v0.36.1/go.mod h1:GktZmd5Dfxo84vPFBdLDl0bBtiJRODfd47uugK0romU= +github.com/fluxcd/source-controller/api v1.0.0-rc.1 h1:MZaP5utClMG95Aw/AVu1l05WEfmpEw/RIlCLnkCQl14= +github.com/fluxcd/source-controller/api v1.0.0-rc.1/go.mod h1:CvGNdS8g/MqwpERUK6aJp4lndsrm+JBzGpoyyZ4u0c8= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= diff --git a/internal/controllers/kustomization_acl_test.go b/internal/controllers/kustomization_acl_test.go index 05c2eb4c..7e780909 100644 --- a/internal/controllers/kustomization_acl_test.go +++ b/internal/controllers/kustomization_acl_test.go @@ -25,7 +25,7 @@ import ( apiacl "github.com/fluxcd/pkg/apis/acl" "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/controllers/kustomization_controller.go b/internal/controllers/kustomization_controller.go index fd565042..77002af2 100644 --- a/internal/controllers/kustomization_controller.go +++ b/internal/controllers/kustomization_controller.go @@ -60,7 +60,8 @@ import ( "github.com/fluxcd/pkg/runtime/predicates" "github.com/fluxcd/pkg/ssa" "github.com/fluxcd/pkg/tar" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" + sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/decryptor" @@ -110,7 +111,7 @@ func (r *KustomizationReconciler) SetupWithManager(mgr ctrl.Manager, opts Kustom // Index the Kustomizations by the OCIRepository references they (may) point at. if err := mgr.GetCache().IndexField(context.TODO(), &kustomizev1.Kustomization{}, ociRepositoryIndexKey, - r.indexBy(sourcev1.OCIRepositoryKind)); err != nil { + r.indexBy(sourcev1b2.OCIRepositoryKind)); err != nil { return fmt.Errorf("failed setting index fields: %w", err) } @@ -122,7 +123,7 @@ func (r *KustomizationReconciler) SetupWithManager(mgr ctrl.Manager, opts Kustom // Index the Kustomizations by the Bucket references they (may) point at. if err := mgr.GetCache().IndexField(context.TODO(), &kustomizev1.Kustomization{}, bucketIndexKey, - r.indexBy(sourcev1.BucketKind)); err != nil { + r.indexBy(sourcev1b2.BucketKind)); err != nil { return fmt.Errorf("failed setting index fields: %w", err) } @@ -141,7 +142,7 @@ func (r *KustomizationReconciler) SetupWithManager(mgr ctrl.Manager, opts Kustom predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}), )). Watches( - &source.Kind{Type: &sourcev1.OCIRepository{}}, + &source.Kind{Type: &sourcev1b2.OCIRepository{}}, handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(ociRepositoryIndexKey)), builder.WithPredicates(SourceRevisionChangePredicate{}), ). @@ -151,7 +152,7 @@ func (r *KustomizationReconciler) SetupWithManager(mgr ctrl.Manager, opts Kustom builder.WithPredicates(SourceRevisionChangePredicate{}), ). Watches( - &source.Kind{Type: &sourcev1.Bucket{}}, + &source.Kind{Type: &sourcev1b2.Bucket{}}, handler.EnqueueRequestsFromMapFunc(r.requestsForRevisionChangeOf(bucketIndexKey)), builder.WithPredicates(SourceRevisionChangePredicate{}), ). @@ -517,8 +518,8 @@ func (r *KustomizationReconciler) getSource(ctx context.Context, } switch obj.Spec.SourceRef.Kind { - case sourcev1.OCIRepositoryKind: - var repository sourcev1.OCIRepository + case sourcev1b2.OCIRepositoryKind: + var repository sourcev1b2.OCIRepository err := r.Client.Get(ctx, namespacedName, &repository) if err != nil { if apierrors.IsNotFound(err) { @@ -537,8 +538,8 @@ func (r *KustomizationReconciler) getSource(ctx context.Context, return src, fmt.Errorf("unable to get source '%s': %w", namespacedName, err) } src = &repository - case sourcev1.BucketKind: - var bucket sourcev1.Bucket + case sourcev1b2.BucketKind: + var bucket sourcev1b2.Bucket err := r.Client.Get(ctx, namespacedName, &bucket) if err != nil { if apierrors.IsNotFound(err) { diff --git a/internal/controllers/kustomization_decryptor_test.go b/internal/controllers/kustomization_decryptor_test.go index c3a7a79e..aee2c3aa 100644 --- a/internal/controllers/kustomization_decryptor_test.go +++ b/internal/controllers/kustomization_decryptor_test.go @@ -25,7 +25,7 @@ import ( "time" "github.com/fluxcd/pkg/apis/meta" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" "github.com/hashicorp/vault/api" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" diff --git a/internal/controllers/kustomization_dependson_test.go b/internal/controllers/kustomization_dependson_test.go index 7a29fcc8..06180528 100644 --- a/internal/controllers/kustomization_dependson_test.go +++ b/internal/controllers/kustomization_dependson_test.go @@ -24,7 +24,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/controllers/kustomization_fetcher_test.go b/internal/controllers/kustomization_fetcher_test.go index f8fa7561..451f66c3 100644 --- a/internal/controllers/kustomization_fetcher_test.go +++ b/internal/controllers/kustomization_fetcher_test.go @@ -25,7 +25,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/controllers/kustomization_force_test.go b/internal/controllers/kustomization_force_test.go index d5bddf2e..f1eada91 100644 --- a/internal/controllers/kustomization_force_test.go +++ b/internal/controllers/kustomization_force_test.go @@ -24,7 +24,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" apimeta "k8s.io/apimachinery/pkg/api/meta" diff --git a/internal/controllers/kustomization_fuzzer_test.go b/internal/controllers/kustomization_fuzzer_test.go index 215a5f30..bc3eaabb 100644 --- a/internal/controllers/kustomization_fuzzer_test.go +++ b/internal/controllers/kustomization_fuzzer_test.go @@ -57,7 +57,7 @@ import ( "github.com/fluxcd/pkg/runtime/controller" "github.com/fluxcd/pkg/runtime/testenv" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" fuzz "github.com/AdaLogics/go-fuzz-headers" diff --git a/internal/controllers/kustomization_impersonation_test.go b/internal/controllers/kustomization_impersonation_test.go index df9a7903..0de24e95 100644 --- a/internal/controllers/kustomization_impersonation_test.go +++ b/internal/controllers/kustomization_impersonation_test.go @@ -24,7 +24,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" diff --git a/internal/controllers/kustomization_indexers.go b/internal/controllers/kustomization_indexers.go index d7d89542..5212f031 100644 --- a/internal/controllers/kustomization_indexers.go +++ b/internal/controllers/kustomization_indexers.go @@ -24,7 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/fluxcd/pkg/runtime/dependency" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) diff --git a/internal/controllers/kustomization_inventory_test.go b/internal/controllers/kustomization_inventory_test.go index c447e654..11a62a11 100644 --- a/internal/controllers/kustomization_inventory_test.go +++ b/internal/controllers/kustomization_inventory_test.go @@ -29,7 +29,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/internal/controllers/kustomization_prune_test.go b/internal/controllers/kustomization_prune_test.go index 7a90827e..2d8ee81a 100644 --- a/internal/controllers/kustomization_prune_test.go +++ b/internal/controllers/kustomization_prune_test.go @@ -24,7 +24,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/internal/controllers/kustomization_transformer_test.go b/internal/controllers/kustomization_transformer_test.go index 024c540d..9c8972a5 100644 --- a/internal/controllers/kustomization_transformer_test.go +++ b/internal/controllers/kustomization_transformer_test.go @@ -26,7 +26,7 @@ import ( "github.com/fluxcd/pkg/apis/kustomize" "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" diff --git a/internal/controllers/kustomization_validation_test.go b/internal/controllers/kustomization_validation_test.go index f686c603..414d6f4c 100644 --- a/internal/controllers/kustomization_validation_test.go +++ b/internal/controllers/kustomization_validation_test.go @@ -23,7 +23,7 @@ import ( "time" "github.com/fluxcd/pkg/apis/meta" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/internal/controllers/kustomization_varsub_test.go b/internal/controllers/kustomization_varsub_test.go index 3d8414eb..2e562d84 100644 --- a/internal/controllers/kustomization_varsub_test.go +++ b/internal/controllers/kustomization_varsub_test.go @@ -23,7 +23,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" apimeta "k8s.io/apimachinery/pkg/api/meta" diff --git a/internal/controllers/kustomization_wait_test.go b/internal/controllers/kustomization_wait_test.go index 94efcc60..ebc9fcf3 100644 --- a/internal/controllers/kustomization_wait_test.go +++ b/internal/controllers/kustomization_wait_test.go @@ -32,7 +32,7 @@ import ( "github.com/fluxcd/pkg/apis/meta" "github.com/fluxcd/pkg/runtime/conditions" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) @@ -43,6 +43,7 @@ func TestKustomizationReconciler_WaitConditions(t *testing.T) { revision := "v1.0.0" resultK := &kustomizev1.Kustomization{} reconcileRequestAt := metav1.Now().String() + timeout := 60 * time.Second err := createNamespace(id) g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace") diff --git a/internal/controllers/source_predicate.go b/internal/controllers/source_predicate.go index 3d27cf2f..314eb634 100644 --- a/internal/controllers/source_predicate.go +++ b/internal/controllers/source_predicate.go @@ -20,7 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/predicate" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" ) type SourceRevisionChangePredicate struct { diff --git a/internal/controllers/suite_test.go b/internal/controllers/suite_test.go index 806c1255..661bacec 100644 --- a/internal/controllers/suite_test.go +++ b/internal/controllers/suite_test.go @@ -45,7 +45,8 @@ import ( "github.com/fluxcd/pkg/runtime/controller" "github.com/fluxcd/pkg/runtime/testenv" "github.com/fluxcd/pkg/testserver" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" + sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" ) @@ -77,8 +78,9 @@ var ( func runInContext(registerControllers func(*testenv.Environment), run func() error, crdPath string) error { var err error - utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme)) utilruntime.Must(kustomizev1.AddToScheme(scheme.Scheme)) + utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme)) + utilruntime.Must(sourcev1b2.AddToScheme(scheme.Scheme)) if debugMode { controllerLog.SetLogger(zap.New(zap.WriteTo(os.Stderr), zap.UseDevMode(false))) diff --git a/main.go b/main.go index 2f95ab3b..af6f5a8a 100644 --- a/main.go +++ b/main.go @@ -43,7 +43,7 @@ import ( "github.com/fluxcd/pkg/runtime/logger" "github.com/fluxcd/pkg/runtime/pprof" "github.com/fluxcd/pkg/runtime/probes" - sourcev1 "github.com/fluxcd/source-controller/api/v1beta2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/controllers" From d6c69d4253164a08cef9e105b31fbb4b71fd8cae Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Thu, 30 Mar 2023 18:45:23 +0300 Subject: [PATCH 05/11] Use conditions from fluxcd/pkg/apis/meta@v1.0.0 Signed-off-by: Stefan Prodan --- api/v1/condition_types.go | 4 ---- api/v1/groupversion_info.go | 2 +- api/v1/kustomization_types.go | 6 ------ internal/controllers/kustomization_controller.go | 2 +- internal/controllers/kustomization_wait_test.go | 2 +- internal/controllers/suite_test.go | 4 ++-- 6 files changed, 5 insertions(+), 15 deletions(-) diff --git a/api/v1/condition_types.go b/api/v1/condition_types.go index 8a177d56..39bbf116 100644 --- a/api/v1/condition_types.go +++ b/api/v1/condition_types.go @@ -48,8 +48,4 @@ const ( // ReconciliationFailedReason represents the fact that // the reconciliation failed. ReconciliationFailedReason string = "ReconciliationFailed" - - // ProgressingWithRetryReason represents the fact that - // the reconciliation encountered an error that will be retried. - ProgressingWithRetryReason string = "ProgressingWithRetry" ) diff --git a/api/v1/groupversion_info.go b/api/v1/groupversion_info.go index 6639b83b..e8f6b39f 100644 --- a/api/v1/groupversion_info.go +++ b/api/v1/groupversion_info.go @@ -23,7 +23,7 @@ import ( var ( // GroupVersion is group version used to register these objects. - GroupVersion = schema.GroupVersion{Group: "kustomize.toolkit.fluxcd.io", Version: "v1beta2"} + GroupVersion = schema.GroupVersion{Group: "kustomize.toolkit.fluxcd.io", Version: "v1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme. SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} diff --git a/api/v1/kustomization_types.go b/api/v1/kustomization_types.go index ac5258ec..19ac5197 100644 --- a/api/v1/kustomization_types.go +++ b/api/v1/kustomization_types.go @@ -281,12 +281,6 @@ func (in *Kustomization) SetConditions(conditions []metav1.Condition) { in.Status.Conditions = conditions } -// GetStatusConditions returns a pointer to the Status.Conditions slice. -// Deprecated: use GetConditions instead. -func (in *Kustomization) GetStatusConditions() *[]metav1.Condition { - return &in.Status.Conditions -} - // +genclient // +genclient:Namespaced // +kubebuilder:storageversion diff --git a/internal/controllers/kustomization_controller.go b/internal/controllers/kustomization_controller.go index 77002af2..48e5891a 100644 --- a/internal/controllers/kustomization_controller.go +++ b/internal/controllers/kustomization_controller.go @@ -1019,7 +1019,7 @@ func (r *KustomizationReconciler) finalizeStatus(ctx context.Context, if conditions.IsFalse(obj, meta.ReadyCondition) && conditions.Has(obj, meta.ReconcilingCondition) { rc := conditions.Get(obj, meta.ReconcilingCondition) - rc.Reason = kustomizev1.ProgressingWithRetryReason + rc.Reason = meta.ProgressingWithRetryReason conditions.Set(obj, rc) } diff --git a/internal/controllers/kustomization_wait_test.go b/internal/controllers/kustomization_wait_test.go index ebc9fcf3..7efc8f0f 100644 --- a/internal/controllers/kustomization_wait_test.go +++ b/internal/controllers/kustomization_wait_test.go @@ -182,7 +182,7 @@ parameters: } expectedMessage := "Running health checks" - g.Expect(conditions.GetReason(resultK, meta.ReconcilingCondition)).To(BeIdenticalTo(kustomizev1.ProgressingWithRetryReason)) + g.Expect(conditions.GetReason(resultK, meta.ReconcilingCondition)).To(BeIdenticalTo(meta.ProgressingWithRetryReason)) g.Expect(conditions.GetMessage(resultK, meta.ReconcilingCondition)).To(ContainSubstring(expectedMessage)) g.Expect(resultK.Status.LastHandledReconcileAt).To(BeIdenticalTo(reconcileRequestAt)) diff --git a/internal/controllers/suite_test.go b/internal/controllers/suite_test.go index 661bacec..a0d9a41b 100644 --- a/internal/controllers/suite_test.go +++ b/internal/controllers/suite_test.go @@ -207,7 +207,7 @@ func randStringRunes(n int) string { func isReconcileRunning(k *kustomizev1.Kustomization) bool { return conditions.IsReconciling(k) && - conditions.GetReason(k, meta.ReconcilingCondition) != kustomizev1.ProgressingWithRetryReason + conditions.GetReason(k, meta.ReconcilingCondition) != meta.ProgressingWithRetryReason } func isReconcileSuccess(k *kustomizev1.Kustomization) bool { @@ -230,7 +230,7 @@ func isReconcileFailure(k *kustomizev1.Kustomization) bool { return isHandled && conditions.IsReconciling(k) && conditions.IsFalse(k, meta.ReadyCondition) && conditions.GetObservedGeneration(k, meta.ReadyCondition) == k.Generation && - conditions.GetReason(k, meta.ReconcilingCondition) == kustomizev1.ProgressingWithRetryReason + conditions.GetReason(k, meta.ReconcilingCondition) == meta.ProgressingWithRetryReason } func logStatus(t *testing.T, k *kustomizev1.Kustomization) { From d456f3156d7635974a418910152035ab98cc7a7d Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Thu, 30 Mar 2023 18:48:05 +0300 Subject: [PATCH 06/11] Update e2e tests to v1 APIs Signed-off-by: Stefan Prodan --- .github/workflows/e2e.yaml | 2 +- config/testdata/dependencies/source.yaml | 2 +- config/testdata/impersonation/test.yaml | 2 +- config/testdata/managed-fields/podinfo.yaml | 4 ++-- config/testdata/oci/podinfo.yaml | 2 +- config/testdata/overlays/production.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 0c06fbc5..2bc112c9 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -103,7 +103,7 @@ jobs: - name: Run tests for removing kubectl managed fields run: | kubectl create ns managed-fields - kustomize build github.com/stefanprodan/podinfo//kustomize?ref=6.0.0 > /tmp/podinfo.yaml + kustomize build github.com/stefanprodan/podinfo//kustomize?ref=6.3.5 > /tmp/podinfo.yaml kubectl -n managed-fields apply -f /tmp/podinfo.yaml kubectl -n managed-fields apply -f ./config/testdata/managed-fields kubectl -n managed-fields wait kustomization/podinfo --for=condition=ready --timeout=4m diff --git a/config/testdata/dependencies/source.yaml b/config/testdata/dependencies/source.yaml index f24c81fb..5d1e3a54 100644 --- a/config/testdata/dependencies/source.yaml +++ b/config/testdata/dependencies/source.yaml @@ -6,4 +6,4 @@ spec: interval: 10m url: https://github.com/stefanprodan/podinfo ref: - semver: ">=3.2.3" + semver: ">=6.3.5" diff --git a/config/testdata/impersonation/test.yaml b/config/testdata/impersonation/test.yaml index 21edc705..706b792e 100644 --- a/config/testdata/impersonation/test.yaml +++ b/config/testdata/impersonation/test.yaml @@ -42,7 +42,7 @@ spec: interval: 5m url: https://github.com/stefanprodan/podinfo ref: - tag: "6.3.0" + tag: "6.3.5" --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization diff --git a/config/testdata/managed-fields/podinfo.yaml b/config/testdata/managed-fields/podinfo.yaml index 857b26c4..7e3c5a8c 100644 --- a/config/testdata/managed-fields/podinfo.yaml +++ b/config/testdata/managed-fields/podinfo.yaml @@ -12,7 +12,7 @@ spec: timeout: 1m targetNamespace: managed-fields --- -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: podinfo @@ -20,4 +20,4 @@ spec: interval: 5m url: https://github.com/stefanprodan/podinfo ref: - semver: "6.0.0" + semver: "6.3.5" diff --git a/config/testdata/oci/podinfo.yaml b/config/testdata/oci/podinfo.yaml index fb475093..65c9a469 100644 --- a/config/testdata/oci/podinfo.yaml +++ b/config/testdata/oci/podinfo.yaml @@ -7,7 +7,7 @@ spec: interval: 10m url: oci://ghcr.io/stefanprodan/manifests/podinfo ref: - tag: "6.3.0" + tag: "6.3.5" --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization diff --git a/config/testdata/overlays/production.yaml b/config/testdata/overlays/production.yaml index 96381c72..2d515e30 100644 --- a/config/testdata/overlays/production.yaml +++ b/config/testdata/overlays/production.yaml @@ -27,4 +27,4 @@ spec: interval: 5m url: https://github.com/stefanprodan/podinfo ref: - semver: ">=3.2.3" + semver: ">=6.3.5" From 7df47e6dc84d71c074d6db92d8ff4893646e722c Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Fri, 31 Mar 2023 13:14:41 +0530 Subject: [PATCH 07/11] update config/testdata to use source v1 and kustomize v1 Signed-off-by: Sanskar Jaiswal --- config/testdata/dependencies/backend.yaml | 4 ++-- config/testdata/dependencies/common.yaml | 2 +- config/testdata/dependencies/frontend.yaml | 4 ++-- config/testdata/impersonation/test.yaml | 2 +- config/testdata/overlays/production.yaml | 4 ++-- config/testdata/overlays/staging.yaml | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/testdata/dependencies/backend.yaml b/config/testdata/dependencies/backend.yaml index 15ceba5e..d637d704 100644 --- a/config/testdata/dependencies/backend.yaml +++ b/config/testdata/dependencies/backend.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: backend @@ -16,4 +16,4 @@ spec: - kind: Deployment name: backend namespace: webapp - timeout: 2m \ No newline at end of file + timeout: 2m diff --git a/config/testdata/dependencies/common.yaml b/config/testdata/dependencies/common.yaml index 5c5ac249..99067744 100644 --- a/config/testdata/dependencies/common.yaml +++ b/config/testdata/dependencies/common.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: common diff --git a/config/testdata/dependencies/frontend.yaml b/config/testdata/dependencies/frontend.yaml index b26f6709..80466d2d 100644 --- a/config/testdata/dependencies/frontend.yaml +++ b/config/testdata/dependencies/frontend.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: frontend @@ -17,4 +17,4 @@ spec: - kind: Deployment name: frontend namespace: webapp - timeout: 2m \ No newline at end of file + timeout: 2m diff --git a/config/testdata/impersonation/test.yaml b/config/testdata/impersonation/test.yaml index 706b792e..3c3c6465 100644 --- a/config/testdata/impersonation/test.yaml +++ b/config/testdata/impersonation/test.yaml @@ -33,7 +33,7 @@ subjects: name: gotk-reconciler namespace: impersonation --- -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: podinfo diff --git a/config/testdata/overlays/production.yaml b/config/testdata/overlays/production.yaml index 2d515e30..7e369030 100644 --- a/config/testdata/overlays/production.yaml +++ b/config/testdata/overlays/production.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: webapp-production @@ -19,7 +19,7 @@ spec: namespace: production timeout: 2m --- -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: webapp-releases diff --git a/config/testdata/overlays/staging.yaml b/config/testdata/overlays/staging.yaml index 81dc44e2..470c4d82 100644 --- a/config/testdata/overlays/staging.yaml +++ b/config/testdata/overlays/staging.yaml @@ -1,4 +1,4 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 +apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: webapp-staging @@ -19,7 +19,7 @@ spec: namespace: staging timeout: 2m --- -apiVersion: source.toolkit.fluxcd.io/v1beta1 +apiVersion: source.toolkit.fluxcd.io/v1 kind: GitRepository metadata: name: webapp-latest From acead1667a301278c58b05fd180443f207df5b99 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Fri, 31 Mar 2023 13:15:06 +0530 Subject: [PATCH 08/11] register source v1beta2 scheme Signed-off-by: Sanskar Jaiswal --- main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.go b/main.go index af6f5a8a..4e0a9a7a 100644 --- a/main.go +++ b/main.go @@ -44,6 +44,7 @@ import ( "github.com/fluxcd/pkg/runtime/pprof" "github.com/fluxcd/pkg/runtime/probes" sourcev1 "github.com/fluxcd/source-controller/api/v1" + sourcev1b2 "github.com/fluxcd/source-controller/api/v1beta2" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/kustomize-controller/internal/controllers" @@ -63,6 +64,7 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = sourcev1.AddToScheme(scheme) + _ = sourcev1b2.AddToScheme(scheme) _ = kustomizev1.AddToScheme(scheme) // +kubebuilder:scaffold:scheme } From 794558e3ec9eaa18b30e78d6ed61934548964262 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Fri, 31 Mar 2023 13:31:53 +0530 Subject: [PATCH 09/11] remove deprecated field validation from test data Signed-off-by: Sanskar Jaiswal --- config/testdata/dependencies/backend.yaml | 1 - config/testdata/dependencies/common.yaml | 1 - config/testdata/dependencies/frontend.yaml | 1 - config/testdata/overlays/production.yaml | 1 - config/testdata/overlays/staging.yaml | 1 - 5 files changed, 5 deletions(-) diff --git a/config/testdata/dependencies/backend.yaml b/config/testdata/dependencies/backend.yaml index d637d704..820cb29b 100644 --- a/config/testdata/dependencies/backend.yaml +++ b/config/testdata/dependencies/backend.yaml @@ -11,7 +11,6 @@ spec: sourceRef: kind: GitRepository name: webapp - validation: server healthChecks: - kind: Deployment name: backend diff --git a/config/testdata/dependencies/common.yaml b/config/testdata/dependencies/common.yaml index 99067744..f605aa8c 100644 --- a/config/testdata/dependencies/common.yaml +++ b/config/testdata/dependencies/common.yaml @@ -9,4 +9,3 @@ spec: sourceRef: kind: GitRepository name: webapp - validation: client diff --git a/config/testdata/dependencies/frontend.yaml b/config/testdata/dependencies/frontend.yaml index 80466d2d..38d0bfeb 100644 --- a/config/testdata/dependencies/frontend.yaml +++ b/config/testdata/dependencies/frontend.yaml @@ -12,7 +12,6 @@ spec: sourceRef: kind: GitRepository name: webapp - validation: server healthChecks: - kind: Deployment name: frontend diff --git a/config/testdata/overlays/production.yaml b/config/testdata/overlays/production.yaml index 7e369030..d051cd76 100644 --- a/config/testdata/overlays/production.yaml +++ b/config/testdata/overlays/production.yaml @@ -9,7 +9,6 @@ spec: sourceRef: kind: GitRepository name: webapp-releases - validation: client healthChecks: - kind: Deployment name: backend diff --git a/config/testdata/overlays/staging.yaml b/config/testdata/overlays/staging.yaml index 470c4d82..70aa176c 100644 --- a/config/testdata/overlays/staging.yaml +++ b/config/testdata/overlays/staging.yaml @@ -9,7 +9,6 @@ spec: sourceRef: kind: GitRepository name: webapp-releases - validation: client healthChecks: - kind: Deployment name: backend From f8711dcf4e7ac3d3dce3ae9e6bdf2554b3602f57 Mon Sep 17 00:00:00 2001 From: Sanskar Jaiswal Date: Fri, 31 Mar 2023 14:27:01 +0530 Subject: [PATCH 10/11] change path to root for e2e oci test Signed-off-by: Sanskar Jaiswal --- config/testdata/oci/podinfo.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/testdata/oci/podinfo.yaml b/config/testdata/oci/podinfo.yaml index 65c9a469..da480a80 100644 --- a/config/testdata/oci/podinfo.yaml +++ b/config/testdata/oci/podinfo.yaml @@ -17,7 +17,7 @@ metadata: spec: targetNamespace: oci interval: 10m - path: "./kustomize" + path: "./" prune: true sourceRef: kind: OCIRepository From ae00400d1269fc166266b32ed5d45c8b204cc85b Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Fri, 31 Mar 2023 13:05:20 +0200 Subject: [PATCH 11/11] api/docs: various nits and typos Signed-off-by: Hidde Beydals --- README.md | 2 +- api/v1/doc.go | 3 +- api/v1/inventory_types.go | 3 +- api/v1/kustomization_types.go | 25 +- api/v1/reference_types.go | 3 +- ...mize.toolkit.fluxcd.io_kustomizations.yaml | 2 +- docs/api/v1/kustomize.md | 43 ++- docs/spec/v1/README.md | 2 +- docs/spec/v1/kustomization.md | 339 ++++++++++-------- internal/decryptor/decryptor.go | 9 +- 10 files changed, 233 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index d79a193a..2f7eb07f 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ the controller performs actions to reconcile the cluster current state with the ## Specifications -* [API](docs/spec/v1beta2/README.md) +* [API](docs/spec/v1/README.md) * [Controller](docs/spec/README.md) ## Guides diff --git a/api/v1/doc.go b/api/v1/doc.go index d96907b1..fa70fe1d 100644 --- a/api/v1/doc.go +++ b/api/v1/doc.go @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1 API group. +// Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io +// v1 API group. // +kubebuilder:object:generate=true // +groupName=kustomize.toolkit.fluxcd.io package v1 diff --git a/api/v1/inventory_types.go b/api/v1/inventory_types.go index 83fc9e71..69e52146 100644 --- a/api/v1/inventory_types.go +++ b/api/v1/inventory_types.go @@ -16,7 +16,8 @@ limitations under the License. package v1 -// ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization. +// ResourceInventory contains a list of Kubernetes resource object references +// that have been applied by a Kustomization. type ResourceInventory struct { // Entries of Kubernetes resource object references. Entries []ResourceRef `json:"entries"` diff --git a/api/v1/kustomization_types.go b/api/v1/kustomization_types.go index 19ac5197..15e86bca 100644 --- a/api/v1/kustomization_types.go +++ b/api/v1/kustomization_types.go @@ -33,10 +33,12 @@ const ( MergeValue = "merge" ) -// KustomizationSpec defines the configuration to calculate the desired state from a Source using Kustomize. +// KustomizationSpec defines the configuration to calculate the desired state +// from a Source using Kustomize. type KustomizationSpec struct { - // CommonMetadata specifies the common labels and annotations that are applied to all resources. - // Any existing label or annotation will be overridden if its key matches a common one. + // CommonMetadata specifies the common labels and annotations that are + // applied to all resources. Any existing label or annotation will be + // overridden if its key matches a common one. // +optional CommonMetadata *CommonMetadata `json:"commonMetadata,omitempty"` @@ -139,8 +141,8 @@ type KustomizationSpec struct { // +optional Force bool `json:"force,omitempty"` - // Wait instructs the controller to check the health of all the reconciled resources. - // When enabled, the HealthChecks are ignored. Defaults to false. + // Wait instructs the controller to check the health of all the reconciled + // resources. When enabled, the HealthChecks are ignored. Defaults to false. // +optional Wait bool `json:"wait,omitempty"` @@ -176,9 +178,8 @@ type Decryption struct { // generated by building the kustomize overlay. type PostBuild struct { // Substitute holds a map of key/value pairs. - // The variables defined in your YAML manifests - // that match any of the keys defined in the map - // will be substituted with the set value. + // The variables defined in your YAML manifests that match any of the keys + // defined in the map will be substituted with the set value. // Includes support for bash string replacement functions // e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. // +optional @@ -186,8 +187,9 @@ type PostBuild struct { // SubstituteFrom holds references to ConfigMaps and Secrets containing // the variables and their values to be substituted in the YAML manifests. - // The ConfigMap and the Secret data keys represent the var names and they - // must match the vars declared in the manifests for the substitution to happen. + // The ConfigMap and the Secret data keys represent the var names, and they + // must match the vars declared in the manifests for the substitution to + // happen. // +optional SubstituteFrom []SubstituteReference `json:"substituteFrom,omitempty"` } @@ -235,7 +237,8 @@ type KustomizationStatus struct { // +optional LastAttemptedRevision string `json:"lastAttemptedRevision,omitempty"` - // Inventory contains the list of Kubernetes resource object references that have been successfully applied. + // Inventory contains the list of Kubernetes resource object references that + // have been successfully applied. // +optional Inventory *ResourceInventory `json:"inventory,omitempty"` } diff --git a/api/v1/reference_types.go b/api/v1/reference_types.go index e466cbd0..cf0d9abd 100644 --- a/api/v1/reference_types.go +++ b/api/v1/reference_types.go @@ -34,7 +34,8 @@ type CrossNamespaceSourceReference struct { // +required Name string `json:"name"` - // Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference. + // Namespace of the referent, defaults to the namespace of the Kubernetes + // resource object that contains the reference. // +optional Namespace string `json:"namespace,omitempty"` } diff --git a/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml index 730c375a..f5b6ec48 100644 --- a/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml +++ b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml @@ -280,7 +280,7 @@ spec: description: SubstituteFrom holds references to ConfigMaps and Secrets containing the variables and their values to be substituted in the YAML manifests. The ConfigMap and the Secret data keys - represent the var names and they must match the vars declared + represent the var names, and they must match the vars declared in the manifests for the substitution to happen. items: description: SubstituteReference contains a reference to a resource diff --git a/docs/api/v1/kustomize.md b/docs/api/v1/kustomize.md index da5b640f..76c1804b 100644 --- a/docs/api/v1/kustomize.md +++ b/docs/api/v1/kustomize.md @@ -6,7 +6,8 @@

kustomize.toolkit.fluxcd.io/v1

-

Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1 API group.

+

Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io +v1 API group.

Resource Types:
  • Kustomization @@ -79,8 +80,9 @@ CommonMetadata (Optional) -

    CommonMetadata specifies the common labels and annotations that are applied to all resources. -Any existing label or annotation will be overridden if its key matches a common one.

    +

    CommonMetadata specifies the common labels and annotations that are +applied to all resources. Any existing label or annotation will be +overridden if its key matches a common one.

    @@ -336,8 +338,8 @@ bool (Optional) -

    Wait instructs the controller to check the health of all the reconciled resources. -When enabled, the HealthChecks are ignored. Defaults to false.

    +

    Wait instructs the controller to check the health of all the reconciled +resources. When enabled, the HealthChecks are ignored. Defaults to false.

    @@ -477,7 +479,8 @@ string (Optional) -

    Namespace of the referent, defaults to the namespace of the Kubernetes resource object that contains the reference.

    +

    Namespace of the referent, defaults to the namespace of the Kubernetes +resource object that contains the reference.

    @@ -536,7 +539,8 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference (Appears on: Kustomization)

    -

    KustomizationSpec defines the configuration to calculate the desired state from a Source using Kustomize.

    +

    KustomizationSpec defines the configuration to calculate the desired state +from a Source using Kustomize.

    @@ -558,8 +562,9 @@ CommonMetadata @@ -815,8 +820,8 @@ bool @@ -928,7 +933,8 @@ ResourceInventory @@ -963,9 +969,8 @@ map[string]string @@ -983,8 +988,9 @@ e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}.

    (Optional)

    SubstituteFrom holds references to ConfigMaps and Secrets containing the variables and their values to be substituted in the YAML manifests. -The ConfigMap and the Secret data keys represent the var names and they -must match the vars declared in the manifests for the substitution to happen.

    +The ConfigMap and the Secret data keys represent the var names, and they +must match the vars declared in the manifests for the substitution to +happen.

    @@ -997,7 +1003,8 @@ must match the vars declared in the manifests for the substitution to happen.

    Appears on:KustomizationStatus)

    -

    ResourceInventory contains a list of Kubernetes resource object references that have been applied by a Kustomization.

    +

    ResourceInventory contains a list of Kubernetes resource object references +that have been applied by a Kustomization.

    (Optional) -

    CommonMetadata specifies the common labels and annotations that are applied to all resources. -Any existing label or annotation will be overridden if its key matches a common one.

    +

    CommonMetadata specifies the common labels and annotations that are +applied to all resources. Any existing label or annotation will be +overridden if its key matches a common one.

    (Optional) -

    Wait instructs the controller to check the health of all the reconciled resources. -When enabled, the HealthChecks are ignored. Defaults to false.

    +

    Wait instructs the controller to check the health of all the reconciled +resources. When enabled, the HealthChecks are ignored. Defaults to false.

    (Optional) -

    Inventory contains the list of Kubernetes resource object references that have been successfully applied.

    +

    Inventory contains the list of Kubernetes resource object references that +have been successfully applied.

    (Optional)

    Substitute holds a map of key/value pairs. -The variables defined in your YAML manifests -that match any of the keys defined in the map -will be substituted with the set value. +The variables defined in your YAML manifests that match any of the keys +defined in the map will be substituted with the set value. Includes support for bash string replacement functions e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}.

    diff --git a/docs/spec/v1/README.md b/docs/spec/v1/README.md index f0ae66f2..8c64134d 100644 --- a/docs/spec/v1/README.md +++ b/docs/spec/v1/README.md @@ -8,8 +8,8 @@ of Kubernetes objects generated with Kustomize. - [Kustomization CRD](kustomization.md) + [Example](kustomization.md#example) + [Writing a Kustomization spec](kustomization.md#writing-a-kustomization-spec) - + [Recommended settings](kustomization.md#recommended-settings) + [Working with Kustomizations](kustomization.md#working-with-kustomizations) + * [Recommended settings](kustomization.md#recommended-settings) + [Kustomization Status](kustomization.md#kustomization-status) ## Implementation diff --git a/docs/spec/v1/kustomization.md b/docs/spec/v1/kustomization.md index 61b7efd7..d8ccb109 100644 --- a/docs/spec/v1/kustomization.md +++ b/docs/spec/v1/kustomization.md @@ -45,16 +45,16 @@ In the above example: - A Flux GitRepository named `podinfo` is created that clones the `master` branch and makes the repository content available as an Artifact inside the cluster. - A Flux Kustomization named `podinfo` is created that watches the - GitRepository for artifact changes. -- The Kustomization builds the YAML manifests located at the specified `spec.path`, - sets the namespace of all objects to the `spec.targetNamespace`, + GitRepository for Artifact changes. +- The Kustomization builds the YAML manifests located at the specified `.spec.path`, + sets the namespace of all objects to the `.spec.targetNamespace`, validates the objects against the Kubernetes API and finally applies them on the cluster. -- As specified by `spec.interval`, every ten minutes, the Kustomization runs a +- As specified by `.spec.interval`, every ten minutes, the Kustomization runs a server-side apply dry-run to detect and correct drift inside the cluster. - When the Git revision changes, the manifests are reconciled automatically. If previously applied objects are missing from the current revision, these - objects are deleted from the cluster when `spec.prune` is enabled. + objects are deleted from the cluster when `.spec.prune` is enabled. You can run this example by saving the manifest into `podinfo.yaml`. @@ -78,7 +78,8 @@ You can run this example by saving the manifest into `podinfo.yaml`. podinfo True Applied revision: master@sha1:450796ddb2ab6724ee1cc32a4be56da032d1cca0 ``` -4. Run `kubectl describe kustomization podinfo` to see the reconciliation status conditions and events: +4. Run `kubectl describe kustomization podinfo` to see the reconciliation status + conditions and events: ```console ... @@ -109,20 +110,20 @@ A Kustomization also needs a ### Source reference -`spec.sourceRef` is used to refer to the Source object which has the required +`.spec.sourceRef` is used to refer to the Source object which has the required Artifact containing the YAML manifests. It has two required fields: -* `kind`: The Kind of the referred Source object. Supported Source types: - * [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md) - * [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/ocirepositories.md) - * [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/buckets.md) -* `name`: The Name of the referred Source object. +- `kind`: The Kind of the referred Source object. Supported Source types: + + [GitRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1/gitrepositories.md) + + [OCIRepository](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/ocirepositories.md) + + [Bucket](https://github.com/fluxcd/source-controller/blob/main/docs/spec/v1beta2/buckets.md) +- `name`: The Name of the referred Source object. #### Cross-namespace references By default, the Source object is assumed to be in the same namespace as the Kustomization. To refer to a Source object in a different namespace, specify -the namespace using `spec.sourceRef.namespace`. +the namespace using `.spec.sourceRef.namespace`. ```yaml --- @@ -145,15 +146,16 @@ by starting kustomize-controller with the `--no-cross-namespace-refs=true` flag. ### Prune -`spec.prune` is a required boolean field to enable/disable garbage collection +`.spec.prune` is a required boolean field to enable/disable garbage collection for a Kustomization. Garbage collection means that the Kubernetes objects that were previously applied on the cluster but are missing from the current source revision, are removed from the cluster automatically. Garbage collection is also performed when a Kustomization object is deleted, triggering a removal of all Kubernetes -objects previously applied on the cluster. The removal of the Kubernetes objects -is done in the background, i.e it doesn't block the reconciliation of the Kustomization. +objects previously applied on the cluster. The removal of the Kubernetes +objects is done in the background, i.e. it doesn't block the reconciliation of +the Kustomization. To enable garbage collection for a Kustomization, set this field to `true`. @@ -164,17 +166,18 @@ annotating them with: kustomize.toolkit.fluxcd.io/prune: disabled ``` -For info on how the controller tracks Kubernetes objects and determines what to -garbage collect, see [`.status.inventory`](#inventory). +For details on how the controller tracks Kubernetes objects and determines what +to garbage collect, see [`.status.inventory`](#inventory). ### Interval -`spec.interval` is a required field that specifies the interval at which the +`.spec.interval` is a required field that specifies the interval at which the Kustomization is reconciled, i.e. the controller fetches the source with the Kubernetes manifests, builds the Kustomization and applies it on the cluster, -correcting any existing drift in the process. The minimum value should be over 60 seconds. +correcting any existing drift in the process. The minimum value should be 60 +seconds. -After successfully reconciling the object, kustomize-controller requeues it for +After successfully reconciling the object, the controller requeues it for inspection after the specified interval. The value must be in a [Go recognized duration string format](https://pkg.go.dev/time#ParseDuration), e.g. `10m0s` to reconcile the object every 10 minutes. @@ -185,41 +188,43 @@ this is handled instantly outside the interval window. ### Retry interval -`spec.retryInterval` is an optional field to specify the interval at which to -retry a failed reconciliation. Unlike `spec.interval`, this field is -exclusively meant for failure retries. If not specified, it defaults to `spec.interval`. +`.spec.retryInterval` is an optional field to specify the interval at which to +retry a failed reconciliation. Unlike `.spec.interval`, this field is +exclusively meant for failure retries. If not specified, it defaults to +`.spec.interval`. ### Path -`spec.path` is an optional field to specify the path to the directory in the -Source Artifact containing the kustomization.yaml file, or the set of plain -YAMLs for which a kustomization.yaml should be generated. +`.spec.path` is an optional field to specify the path to the directory in the +Source Artifact containing the `kustomization.yaml` file, or the set of plain +YAMLs for which a `kustomization.yaml` should be generated. It defaults to blank, which translates to the root of the Source Artifact. -Further reading: [Generate kustomization.yaml](#generate-kustomizationyaml) +For more details on the generation of the file, see [generating a +`kustomization.yaml` file](#generating-a-kustomizationyaml-file). ### Target namespace -`spec.targetNamespace` is an optional field to specify the target namespace for +`.spec.targetNamespace` is an optional field to specify the target namespace for all the objects that are part of the Kustomization. It either configures or overrides the [Kustomize `namespace`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/namespace/). -While `spec.targetNamespace` is optional, if this field is non-empty then the +While `.spec.targetNamespace` is optional, if this field is non-empty then the Kubernetes namespace being pointed to must exist prior to the Kustomization being applied, kustomize-controller will not create the namespace. ### Suspend -`spec.suspend` is an optional boolean field to suspend the reconciliation of the +`.spec.suspend` is an optional boolean field to suspend the reconciliation of the Kustomization. When a Kustomization is suspended, new Source revisions are not applied to the cluster and drift detection/correction is paused. To resume normal reconciliation, set it back to `false` or remove the field. -For more info, see [Suspending and resuming](#suspending-and-resuming). +For more information, see [suspending and resuming](#suspending-and-resuming). ### Health checks -`spec.healthChecks` is an optional list used to refer to resources for which the +`.spec.healthChecks` is an optional list used to refer to resources for which the controller will perform health checks used to determine the rollout status of [deployed workloads](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#deployment-status) and the `Ready` status of custom resources. @@ -257,10 +262,10 @@ spec: After applying the kustomize build output, the controller verifies if the rollout was completed successfully. If the deployment was successful, the -Kustomization `Ready` condition is marked as `true`, if the rollout failed, or if -it takes more than the specified timeout to complete, then the Kustomization -`Ready` condition is set to false. If the deployment becomes healthy on the -next execution, then the Kustomization is marked as ready. +Kustomization `Ready` condition is marked as `True`, if the rollout failed, +or if it takes more than the specified timeout to complete, then the +Kustomization `Ready` condition is set to `False`. If the deployment becomes +healthy on the next execution, then the Kustomization is marked as ready. When a Kustomization contains HelmRelease objects, instead of checking the underlying Deployments, you can define a health check that waits for the @@ -297,35 +302,36 @@ the Kustomization will be marked as ready. ### Wait -`spec.wait` is an optional boolean field to perform health checks for __all__ +`.spec.wait` is an optional boolean field to perform health checks for __all__ reconciled resources as part of the Kustomization. If set to `true`, -`spec.healthChecks` is ignored. +`.spec.healthChecks` is ignored. ### Timeout -`spec.timeout` is an optional field to specify a timeout duration for any +`.spec.timeout` is an optional field to specify a timeout duration for any operation like building, applying, health checking, etc. performed during the reconciliation process. ### Dependencies -`spec.dependsOn` is an optional list used to refer to other Kustomization +`.spec.dependsOn` is an optional list used to refer to other Kustomization objects that the Kustomization depends on. If specified, then the Kustomization is only applied after the referred Kustomizations are ready, i.e. have the -`Ready` condition marked as `true`. The readiness state of a Kustomization is +`Ready` condition marked as `True`. The readiness state of a Kustomization is determined by its last applied status condition. -This is helpful when need to make sure other resources exist before the -workloads defined in a Kustomization are deployed. For example, before +This is helpful when there is a need to make sure other resources exist before +the workloads defined in a Kustomization are deployed. For example, before installing objects of a certain custom resource kind, the CRDs and the related controller must exist in the cluster. -Assuming two Kustomizations: +For example, assuming we have two Kustomizations: -* cert-manager - reconciles the cert-manager CRDs and controller -* certs - reconciles the cert-manager custom resources +- cert-manager: reconciles the cert-manager CRDs and controller +- certs: reconciles the cert-manager custom resources -You can instruct the controller to apply the cert-manager Kustomization before certs: +You can instruct the controller to apply the `cert-manager` Kustomization before +`certs` by defining a `dependsOn` relationship between the two: ```yaml --- @@ -363,43 +369,43 @@ spec: name: flux-system ``` -If `spec.healthChecks` is non-empty or `spec.wait` is set to `true`, a -Kustomization will be applied after all its dependencies' health checks are -passing. For example, a service mesh proxy injector should be running before -deploying applications inside the mesh. +If `.spec.healthChecks` is non-empty or `.spec.wait` is set to `true`, a +Kustomization will be applied after all its dependencies' health checks have +passed. For example, this can be used to ensure a service mesh proxy injector +is running before deploying applications inside the mesh. **Note:** Circular dependencies between Kustomizations must be avoided, otherwise the interdependent Kustomizations will never be applied on the cluster. ### Service Account reference -`spec.serviceAccountName` is an optional field used to specify the +`.spec.serviceAccountName` is an optional field used to specify the ServiceAccount to be impersonated while reconciling the Kustomization. For more details, see [Role-based Access Control](#role-based-access-control). ### Common metadata -`spec.commonMetadata` is an optional field used to specify any metadata that +`.spec.commonMetadata` is an optional field used to specify any metadata that should be applied to all the Kustomization's resources. It has two optional fields: -* `labels`: A map used for setting [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) - on an object. Any existing label will be overriden if it matches a key in - this map. -* `annotations`: A map used for setting [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) - on an object. Any existing annotation will be overridden if it matches a key - in this map. +- `labels`: A map used for setting [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) + on an object. Any existing label will be overridden if it matches with a key in + this map. +- `annotations`: A map used for setting [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) + on an object. Any existing annotation will be overridden if it matches with a key + in this map. ### Patches -`spec.patches` is an optional list used to specify [Kustomize `patches`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/) +`.spec.patches` is an optional list used to specify [Kustomize `patches`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/) as inline YAML objects. This enables patching resources using either a [strategic merge](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchstrategicmerge) patch or a [JSON6902](https://kubectl.docs.kubernetes.io/references/kustomize/glossary#patchjson6902) patch. A patch can target a single resource or multiple resources. Each item in the list must have the two fields mentioned below: -* `patch`: Patch contains an inline strategic merge patch or an inline JSON6902 patch with an array of operation objects. -* `target`: Target points to the resources that the patch document should be applied to. +- `patch`: Patch contains an inline strategic merge patch or an inline JSON6902 patch with an array of operation objects. +- `target`: Target points to the resources that the patch document should be applied to. ```yaml --- @@ -447,7 +453,7 @@ spec: ### Images -`spec.images` is an optional list used to specify +`.spec.images` is an optional list used to specify [Kustomize `images`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/). This allows overwriting the name, tag or digest of container images without creating patches. @@ -473,7 +479,7 @@ spec: ### Components -`spec.components` is an optional list used to specify +`.spec.components` is an optional list used to specify [Kustomize `components`](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/components/). This allows using reusable pieces of configuration logic that can be included from multiple overlays. @@ -497,20 +503,20 @@ spec: considered experimental in Flux. No guarantees are provided as the feature may be modified in backwards incompatible ways or removed without warning. -### Postbuild Variable Substitution +### Post build variable substitution -With `spec.postBuild.substitute` you can provide a map of key/value pairs +With `.spec.postBuild.substitute` you can provide a map of key-value pairs holding the variables to be substituted in the final YAML manifest, after kustomize build. -With `spec.postBuild.substituteFrom` you can provide a list of ConfigMaps and -Secrets from which the variables are loaded. -The ConfigMap and Secret data keys are used as the var names. +With `.spec.postBuild.substituteFrom` you can provide a list of ConfigMaps and +Secrets from which the variables are loaded. The ConfigMap and Secret data keys +are used as the variable names. -The `spec.postBuild.substituteFrom.optional` field indicates how the +The `.spec.postBuild.substituteFrom.optional` field indicates how the controller should handle a referenced ConfigMap or Secret being absent at reconciliation time. The controller's default behavior ― with -`optional` unspecified or set to `false` ― has it fail reconciliation if +`optional` unspecified or set to `false` ― it has failed reconciliation if the referenced object is missing. By setting the `optional` field to `true`, you can indicate that the controller should use the referenced object if it's there, but also tolerate its absence, treating that @@ -526,10 +532,10 @@ for [bash string replacement functions](https://github.com/drone/envsubst) e.g.: - `${var/substring/replacement}` **Note:** The name of a variable can contain only alphanumeric and underscore -characters. The controller validates the var names using this regular expression: -`^[_[:alpha:]][_[:alpha:][:digit:]]*$`. +characters. The controller validates the variable names using this regular +expression: `^[_[:alpha:]][_[:alpha:][:digit:]]*$`. -Assuming you have manifests with the following variables: +For example, assuming we have manifests with the following variables: ```yaml --- @@ -543,7 +549,7 @@ metadata: ``` You can specify the variables and their values in the Kustomization definition using -`spec.postBuild.substitute` and/or `spec.postBuild.substituteFrom`: +`.spec.postBuild.substitute` and/or `.spec.postBuild.substituteFrom`: ```yaml --- @@ -568,7 +574,7 @@ spec: # Fail if this Secret does not exist. ``` -**Note:** For substituting variables in a secret, `spec.stringData` field must be used i.e: +**Note:** For substituting variables in a secret, `.spec.stringData` field must be used i.e: ```yaml --- @@ -639,11 +645,12 @@ metadata: ### Force -`spec.force` is an optional boolean. If set to `true`, the controller will -replace the resources in-cluster if the patching fails due to immutable field -changes. +`.spec.force` is an optional boolean field. If set to `true`, the controller +will replace the resources in-cluster if the patching fails due to immutable +field changes. -You can enable force apply for specific resources by labelling or annotating them with: +It can also be enabled for specific resources by labelling or annotating them +with: ```yaml kustomize.toolkit.fluxcd.io/force: enabled @@ -651,7 +658,7 @@ kustomize.toolkit.fluxcd.io/force: enabled ### KubeConfig reference -`spec.kubeConfig.secretRef.Name` is an optional field to specify the name of +`.spec.kubeConfig.secretRef.Name` is an optional field to specify the name of the secret containing a KubeConfig. If specified, objects will be applied, health-checked, pruned, and deleted for the default cluster specified in that KubeConfig instead of using the in-cluster ServiceAccount. @@ -663,17 +670,17 @@ of the Secret’s data , and the Secret can thus be regularly updated if cluster-access-tokens have to rotate due to expiration. ```yaml +--- apiVersion: v1 -stringData: - value.yaml: | - apiVersion: v1 - kind: Config - # ...omitted for brevity kind: Secret metadata: name: prod-kubeconfig type: Opaque - +stringData: + value.yaml: | + apiVersion: v1 + kind: Config + # ...omitted for brevity ``` **Note:** The KubeConfig should be self-contained and not rely on binaries, @@ -682,29 +689,33 @@ This matches the constraints of KubeConfigs from current Cluster API providers. KubeConfigs with `cmd-path` in them likely won't work without a custom, per-provider installation of kustomize-controller. -When both `spec.kubeConfig` and `spec.ServiceAccountName` are specified, +When both `.spec.kubeConfig` and `.spec.ServiceAccountName` are specified, the controller will impersonate the service account on the target cluster. -For more information, see [Remote Clusters/Cluster-API](#remote-clusterscluster-api). +For more information, see [remote clusters/Cluster-API](#remote-clusterscluster-api). ### Decryption -`spec.decryption` holds the decryption configuration to decrypt Secrets that -are a part of the Kustomization. Since, Secrets are either plain text or -`base64` encoded, its extremely unsafe to store them as it is in a public or -private Git repository. In order to store them safely, you can use -[Mozilla SOPS](https://github.com/mozilla/sops) and encrypt your Kubernetes -Secrets data with [age](https://age-encryption.org/v1/) and [OpenPGP](https://www.openpgp.org) -keys, or with provider implementations like Azure Key Vault, GCP KMS or Hashicorp Vault. +`.spec.decryption` is an optional field to specify the configuration to decrypt +Secrets that are a part of the Kustomization. -**Note:** You should encrypt only the `data/stringData` section of the Kubernetes Secret, -encrypting the `metadata`, `kind` or `apiVersion` fields is not supported. +Since Secrets are either plain text or `base64` encoded, it's unsafe to store +them in plain text in a public or private Git repository. In order to store +them safely, you can use [Mozilla SOPS](https://github.com/mozilla/sops) and +encrypt your Kubernetes Secret data with [age](https://age-encryption.org/v1/) +and/or [OpenPGP](https://www.openpgp.org) keys, or with provider implementations +like Azure Key Vault, GCP KMS or Hashicorp Vault. + +**Note:** You should encrypt only the `data/stringData` section of the Kubernetes +Secret, encrypting the `metadata`, `kind` or `apiVersion` fields is not supported. An easy way to do this is by appending `--encrypted-regex '^(data|stringData)$'` to your `sops --encrypt` command. It has two required fields: -* `secretRef.name`: The name of the secret that contains the keys to be used for decryption. -* `provider`: The secrets decryption provider to be used. The only supported + +- `.secretRef.name`: The name of the secret that contains the keys to be used for + decryption. +- `.provider`: The secrets decryption provider to be used. The only supported value at the moment is `sops`. ```yaml @@ -726,8 +737,8 @@ spec: name: sops-keys ``` -**Note:** For info on Secrets decryption at a controller level, please see -[Controller global decryption](#controller-global-decryption). +**Note:** For information on Secrets decryption at a controller level, please +refer to [controller global decryption](#controller-global-decryption). The Secret's `.data` section is expected to contain entries with decryption keys (for age and OpenPGP), or credentials (for any of the supported provider @@ -744,7 +755,7 @@ metadata: data: # Exemplary age private key identity.agekey: - # Examplary Hashicorp Vault token + # Exemplary Hashicorp Vault token sops.vault-token: ``` @@ -782,7 +793,7 @@ data: identity.asc: ``` -#### AWS KMS Secret Entry +#### AWS KMS Secret entry To specify credentials for an AWS user account linked to the IAM role with access to KMS, append a `.data` entry with a fixed `sops.aws-kms` key. @@ -811,9 +822,9 @@ YAML formats depending on the authentication method you want to utilize. To configure a Service Principal with Secret credentials to access the Azure Key Vault, a JSON or YAML object with `tenantId`, `clientId` and `clientSecret` -fields must be configured as the `sops.azure-kv` value. It -optionally supports `authorityHost` to configure an authority host other than -the Azure Public Cloud endpoint. +fields must be configured as the `sops.azure-kv` value. It optionally supports +`authorityHost` to configure an authority host other than the Azure Public Cloud +endpoint. ```yaml --- @@ -939,10 +950,13 @@ data: sops.vault-token: ``` -## Recommended settings +## Working with Kustomizations + +### Recommended settings When deploying applications to production environments, it is recommended -to configure the following fields, while adjusting them to your desires for responsiveness: +to configure the following fields, while adjusting them to your desires for +responsiveness: ```yaml apiVersion: source.toolkit.fluxcd.io/v1 @@ -983,16 +997,16 @@ spec: path: "./deploy/production" ``` -## Working with Kustomizations +### Generating a `kustomization.yaml` file -### Generate kustomization.yaml +If your repository contains plain Kubernetes manifests without a +`kustomization.yaml`, the file is automatically generated for all the +Kubernetes manifests in the directory tree specified in [`.spec.path`](#path). -If your repository contains plain Kubernetes manifests, the -`kustomization.yaml` file is automatically generated (if it doesn't already exist) -for all the Kubernetes manifests in the directory tree specified in [`spec.path`](#path). All YAML files present under that path must be valid Kubernetes manifests, unless they're excluded either by way of the [`.sourceignore`](https://fluxcd.io/flux/components/source/gitrepositories/#sourceignore-file) -file or the [`spec.ignore`](https://fluxcd.io/flux/components/source/gitrepositories/#ignore) field on the corresponding Source object. +file or the [`.spec.ignore`](https://fluxcd.io/flux/components/source/gitrepositories/#ignore) +field on the corresponding Source object. Example of excluding CI workflows and SOPS config files: @@ -1013,7 +1027,7 @@ spec: It is recommended to generate the `kustomization.yaml` on your own and store it in Git, this way you can validate your manifests in CI -(example script [here](https://github.com/fluxcd/flux2-multi-tenancy/blob/main/scripts/validate.sh)). +([example script](https://github.com/fluxcd/flux2-multi-tenancy/blob/main/scripts/validate.sh)). Assuming your manifests are inside `apps/my-app`, you can generate a `kustomization.yaml` with: @@ -1032,7 +1046,7 @@ namespaced objects (deployments, ingresses, etc). For certain Kustomizations a cluster admin may wish to control what types of Kubernetes objects can be reconciled and under which namespaces. To restrict a Kustomization, one can assign a service account under which the -reconciliation is performed using [`spec.serviceAccountName`](#service-account-reference). +reconciliation is performed using [`.spec.serviceAccountName`](#service-account-reference). Assuming you want to restrict a group of Kustomizations to a single namespace, you can create an account with a role binding that grants access only to that namespace: @@ -1079,7 +1093,7 @@ subjects: placed in a Git source and applied with a Kustomization. The Kustomizations that are running under that service account should depend on the one that contains the account. -Create a Kustomization that prevents altering the cluster state outside of the +Create a Kustomization that prevents altering the cluster state outside the `webapp` namespace: ```yaml @@ -1105,20 +1119,20 @@ When the controller reconciles the `backend` Kustomization, it will impersonate the `flux` ServiceAccount. If the Kustomization contains cluster level objects like CRDs or objects belonging to a different namespace, the reconciliation will fail since the account it runs under has no permissions to alter objects outside -of the `webapp` namespace. +the `webapp` namespace. -#### Enforce impersonation +#### Enforcing impersonation On multi-tenant clusters, platform admins can enforce impersonation with the `--default-service-account` flag. -When the flag is set, all Kustomizations which don't have [`spec.serviceAccountName`](#service-account-reference) +When the flag is set, all Kustomizations which don't have [`.spec.serviceAccountName`](#service-account-reference) specified will use the service account name provided by `--default-service-account=` in the namespace of the object. ### Remote clusters/Cluster-API -With the [`spec.kubeConfig` field](#kubeconfig-reference) a Kustomization can be fully +With the [`.spec.kubeConfig` field](#kubeconfig-reference) a Kustomization can be fully reconciled on a remote cluster. This composes well with Cluster API bootstrap providers such as CAPBK (kubeadm), CAPA (AWS) and others. @@ -1176,7 +1190,8 @@ The Kustomization will eventually reconcile once the cluster is available. If you wish to target clusters created by other means than CAPI, you can create a ServiceAccount on the remote cluster, generate a KubeConfig for that account -and then create a secret on the cluster where kustomize-controller is running e.g.: +and then create a secret on the cluster where kustomize-controller is running. +For example: ```sh kubectl create secret generic prod-kubeconfig \ @@ -1206,8 +1221,8 @@ kubectl -n flux-system annotate serviceaccount kustomize-controller \ ``` Furthermore, you can also use the usual [environment variables used for specifying AWS -credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-list) -, by patching the kustomize-controller deployment: +credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html#envvars-list), +by patching the kustomize-controller Deployment: ```yaml --- @@ -1243,9 +1258,11 @@ In addition to this, the [general SOPS documentation around KMS AWS applies](https://github.com/mozilla/sops#27kms-aws-profiles), allowing you to specify e.g. a `SOPS_KMS_ARN` environment variable. -**Note:**: If you're mounting a secret containing the AWS credentials as a file in the `kustomize-controller` pod, -you'd need to specify an environment variable `$HOME`, since the AWS credentials file is expected to be present -at `~/.aws`, like so: +**Note:**: If you are mounting a secret containing the AWS credentials as a +file in the `kustomize-controller` Pod, you need to specify an environment +variable `$HOME`, since the AWS credentials file is expected to be present at +`~/.aws`. For example: + ```yaml env: - name: HOME @@ -1440,21 +1457,22 @@ flux reconcile kustomization ### Customizing reconciliation -You can configure the controller to ignore in-cluster resources by labelling or annotating them with: +You can configure the controller to ignore in-cluster resources by labelling or +annotating them with: ```yaml kustomize.toolkit.fluxcd.io/reconcile: disabled ``` -**Note:** When the `kustomize.toolkit.fluxcd.io/reconcile` annotation is set to `disabled`, -the controller will no longer apply changes from the source, nor will it prune the resource. -To resume reconciliation, set the annotation to `enabled` in the source -or remove it from the in-cluster object. +**Note:** When the `kustomize.toolkit.fluxcd.io/reconcile` annotation is set to +`disabled`, the controller will no longer apply changes from the source, nor +will it prune the resource. To resume reconciliation, set the annotation to +`enabled` in the source or remove it from the in-cluster object. -If you use kubectl to edit an object managed by Flux, all changes will be undone when -the controller reconciles a Flux Kustomization containing that object. -In order to preserve fields added with kubectl, you have to specify a field manager -named `flux-client-side-apply` e.g.: +If you use `kubectl` to edit an object managed by Flux, all changes will be +reverted when the controller reconciles a Flux Kustomization containing that +object. In order to preserve fields added with `kubectl`, you have to specify +a field manager named `flux-client-side-apply` e.g.: ```sh kubectl apply --field-manager=flux-client-side-apply @@ -1466,15 +1484,18 @@ Another option is to annotate or label objects with: kustomize.toolkit.fluxcd.io/ssa: merge ``` -**Note:** The fields defined in manifests will always be overridden, -the above procedure works only for adding new fields that don’t overlap with the desired state. +**Note:** The fields defined in manifests will always be overridden, the above +procedure works only for adding new fields that don’t overlap with the desired +state. -For lists fields which are atomic (e.g `spec.tolerations` in PodSpec), Kubernetes doesn't allow different managers -for such fields, therefore any changes to these fields will be undone, even if you specify a manager. -For more context, please see the Kubernetes enhancement doc: +For lists fields which are atomic (e.g. `.spec.tolerations` in PodSpec), Kubernetes +doesn't allow different managers for such fields, therefore any changes to these +fields will be undone, even if you specify a manager. For more context, please +see the Kubernetes enhancement document: [555-server-side-apply](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/555-server-side-apply/README.md#lists). -To learn how to handle patching failures due to immutable field changes, see [`spec.force`](#force). +To learn how to handle patching failures due to immutable field changes, refer +to [`.spec.force`](#force). ### Waiting for `Ready` @@ -1482,13 +1503,13 @@ When a change is applied, it is possible to wait for the Kustomization to reach a `Ready` state using `kubectl`: ```sh -kubectl wait gitrepository/ --for=condition=ready --timeout=1m +kubectl wait kustomization/ --for=condition=ready --timeout=1m ``` ### Suspending and resuming When you find yourself in a situation where you temporarily want to pause the -reconciliation of a Kustomization, you can suspend it using [`spec.suspend`](#suspend). +reconciliation of a Kustomization, you can suspend it using [`.spec.suspend`](#suspend). #### Suspend a Kustomization @@ -1516,7 +1537,7 @@ Using `flux`: flux suspend kustomization ``` -#### Resume a GitRepository +#### Resume a Kustomization In your YAML declaration, comment out (or remove) the field: @@ -1606,13 +1627,15 @@ LAST SEEN TYPE REASON OBJECT MESSAGE 9s Normal ReconciliationSucceeded kustomization/podinfo Reconciliation finished in 75.190237ms, next run in 5m0s ``` -You can also use use the `flux events` command to view all events for a Kustomization and its related Source. For example, +You can also use the `flux events` command to view all events for a +Kustomization and its related Source. For example, ```sh flux events --for Kustomization/podinfo ``` -will list all events for the `podinfo` Kustomization in the `flux-system` namesapce and its related Source object, the `podinfo` GitRepository. +will list all events for the `podinfo` Kustomization in the `flux-system` +namespace and its related Source object, the `podinfo` GitRepository. ```console LAST SEEN TYPE REASON OBJECT MESSAGE @@ -1629,7 +1652,7 @@ LAST SEEN TYPE REASON OBJECT Besides being reported in Events, the reconciliation errors are also logged by the controller. The Flux CLI offer commands for filtering the logs for a -specific GitRepository, e.g. +specific Kustomization, e.g. `flux logs --level=error --kind=Kustomization --name=`. ## Kustomization Status @@ -1680,13 +1703,13 @@ following attributes in the Kustomization’s `.status.conditions`: The kustomize-controller may get stuck trying to reconcile and apply a Kustomization without completing. This can occur due to some of the following factors: -* The Source object does not exist on the cluster. -* The Source has not produced an Artifact yet. -* The Kustomization's dependencies aren't ready yet. -* The specified path does not exist in the Artifact. -* Building the kustomization fails. -* Garbage collection fails. -* Running a health check failed. +- The Source object does not exist on the cluster. +- The Source has not produced an Artifact yet. +- The Kustomization's dependencies aren't ready yet. +- The specified path does not exist in the Artifact. +- Building the kustomization fails. +- Garbage collection fails. +- Running a health check failed. When this happens, the controller sets the `Ready` Condition status to False and adds a Condition with the following attributes to the Kustomization’s @@ -1713,7 +1736,7 @@ reconciliation is performed again after the failure, the `reason` is updated to In order to perform operations such as drift detection, garbage collection, etc. kustomize-controller needs to keep track of all Kubernetes objects that are -reconciled as part of a Kustomziation. To do this, it maintains an inventory +reconciled as part of a Kustomization. To do this, it maintains an inventory containing the list of Kubernetes resource object references that have been successfully applied and records it in `.status.inventory`. The inventory records are in the format `____`. diff --git a/internal/decryptor/decryptor.go b/internal/decryptor/decryptor.go index 30d58d45..70b61375 100644 --- a/internal/decryptor/decryptor.go +++ b/internal/decryptor/decryptor.go @@ -105,8 +105,7 @@ var ( } ) -// Decryptor performs decryption operations for a -// v1beta2.Kustomization. +// Decryptor performs decryption operations for a v1.Kustomization. // The only supported decryption provider at present is // DecryptionProviderSOPS. type Decryptor struct { @@ -115,8 +114,8 @@ type Decryptor struct { root string // client is the Kubernetes client used to e.g. retrieve Secrets with. client client.Client - // kustomization is the v1beta2.Kustomization we are decrypting for. - // The v1beta2.Decryption of the object is used to ImportKeys(). + // kustomization is the v1.Kustomization we are decrypting for. + // The v1.Decryption of the object is used to ImportKeys(). kustomization *kustomizev1.Kustomization // maxFileSize is the max size in bytes a file is allowed to have to be // decrypted. Defaults to maxEncryptedFileSize. @@ -187,7 +186,7 @@ func IsEncryptedSecret(object *unstructured.Unstructured) bool { } // ImportKeys imports the DecryptionProviderSOPS keys from the data values of -// the Secret referenced in the Kustomization's v1beta2.Decryption spec. +// the Secret referenced in the Kustomization's v1.Decryption spec. // It returns an error if the Secret cannot be retrieved, or if one of the // imports fails. // Imports do not have an effect after the first call to SopsDecryptWithFormat(),