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/Makefile b/Makefile
index bc20eb54..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/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/v1/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/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/condition_types.go b/api/v1/condition_types.go
new file mode 100644
index 00000000..39bbf116
--- /dev/null
+++ b/api/v1/condition_types.go
@@ -0,0 +1,51 @@
+/*
+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"
+)
diff --git a/api/v1/doc.go b/api/v1/doc.go
new file mode 100644
index 00000000..fa70fe1d
--- /dev/null
+++ b/api/v1/doc.go
@@ -0,0 +1,21 @@
+/*
+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..e8f6b39f
--- /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: "v1"}
+
+ // 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..69e52146
--- /dev/null
+++ b/api/v1/inventory_types.go
@@ -0,0 +1,34 @@
+/*
+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..15e86bca
--- /dev/null
+++ b/api/v1/kustomization_types.go
@@ -0,0 +1,318 @@
+/*
+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
+}
+
+// +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..cf0d9abd
--- /dev/null
+++ b/api/v1/reference_types.go
@@ -0,0 +1,48 @@
+/*
+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..f5b6ec48 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/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/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_v1_gitrepository.yaml
similarity index 76%
rename from config/samples/source_v1beta1_gitrepository.yaml
rename to config/samples/source_v1_gitrepository.yaml
index 60b5a4d4..431f8382 100644
--- a/config/samples/source_v1beta1_gitrepository.yaml
+++ b/config/samples/source_v1_gitrepository.yaml
@@ -1,4 +1,4 @@
-apiVersion: source.toolkit.fluxcd.io/v1beta1
+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/v1beta1
+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 1cec3dc5..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
@@ -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/dependencies/backend.yaml b/config/testdata/dependencies/backend.yaml
index 15ceba5e..820cb29b 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
@@ -11,9 +11,8 @@ spec:
sourceRef:
kind: GitRepository
name: webapp
- validation: server
healthChecks:
- 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..f605aa8c 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
@@ -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 b26f6709..38d0bfeb 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
@@ -12,9 +12,8 @@ spec:
sourceRef:
kind: GitRepository
name: webapp
- validation: server
healthChecks:
- kind: Deployment
name: frontend
namespace: webapp
- timeout: 2m
\ No newline at end of file
+ timeout: 2m
diff --git a/config/testdata/dependencies/source.yaml b/config/testdata/dependencies/source.yaml
index b6dd9a63..5d1e3a54 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
@@ -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 0aa96029..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
@@ -42,9 +42,9 @@ spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
- tag: "6.3.0"
+ tag: "6.3.5"
---
-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..7e3c5a8c 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
@@ -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 fc80f79f..da480a80 100644
--- a/config/testdata/oci/podinfo.yaml
+++ b/config/testdata/oci/podinfo.yaml
@@ -7,9 +7,9 @@ spec:
interval: 10m
url: oci://ghcr.io/stefanprodan/manifests/podinfo
ref:
- tag: "6.3.0"
+ tag: "6.3.5"
---
-apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
+apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: oci
@@ -17,7 +17,7 @@ metadata:
spec:
targetNamespace: oci
interval: 10m
- path: "./kustomize"
+ path: "./"
prune: true
sourceRef:
kind: OCIRepository
diff --git a/config/testdata/overlays/production.yaml b/config/testdata/overlays/production.yaml
index 96381c72..d051cd76 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
@@ -9,7 +9,6 @@ spec:
sourceRef:
kind: GitRepository
name: webapp-releases
- validation: client
healthChecks:
- kind: Deployment
name: backend
@@ -19,7 +18,7 @@ spec:
namespace: production
timeout: 2m
---
-apiVersion: source.toolkit.fluxcd.io/v1beta1
+apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: webapp-releases
@@ -27,4 +26,4 @@ spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
- semver: ">=3.2.3"
+ semver: ">=6.3.5"
diff --git a/config/testdata/overlays/staging.yaml b/config/testdata/overlays/staging.yaml
index 81dc44e2..70aa176c 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
@@ -9,7 +9,6 @@ spec:
sourceRef:
kind: GitRepository
name: webapp-releases
- validation: client
healthChecks:
- kind: Deployment
name: backend
@@ -19,7 +18,7 @@ spec:
namespace: staging
timeout: 2m
---
-apiVersion: source.toolkit.fluxcd.io/v1beta1
+apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: webapp-latest
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/docs/api/kustomize.md b/docs/api/v1/kustomize.md
similarity index 78%
rename from docs/api/kustomize.md
rename to docs/api/v1/kustomize.md
index d5b0ec9d..76c1804b 100644
--- a/docs/api/kustomize.md
+++ b/docs/api/v1/kustomize.md
@@ -1,17 +1,18 @@
-Kustomize API reference
+Kustomize API reference v1
Packages:
-
-Package v1beta2 contains API Schema definitions for the kustomize.toolkit.fluxcd.io v1beta2 API group.
+
+Package v1 contains API Schema definitions for the kustomize.toolkit.fluxcd.io
+v1 API group.
Resource Types:
-Kustomization is the Schema for the kustomizations API.
@@ -29,7 +30,7 @@ Resource Types:
apiVersion
string
-kustomize.toolkit.fluxcd.io/v1beta2
+kustomize.toolkit.fluxcd.io/v1
|
@@ -59,7 +60,7 @@ Refer to the Kubernetes API documentation for the fields of the
spec
-
+
KustomizationSpec
@@ -72,15 +73,16 @@ KustomizationSpec
|
commonMetadata
-
+
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.
|
@@ -103,7 +105,7 @@ Kustomization can be reconciled.
decryption
-
+
Decryption
@@ -180,7 +182,7 @@ Defaults to ‘None’, which translates to the root path of the SourceR
|
postBuild
-
+
PostBuild
@@ -233,36 +235,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 +266,7 @@ when reconciling this Kustomization.
sourceRef
-
+
CrossNamespaceSourceReference
@@ -366,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.
|
|
@@ -382,18 +354,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 +361,7 @@ string
status
-
+
KustomizationStatus
@@ -413,11 +373,11 @@ KustomizationStatus
-CommonMetadata
+CommonMetadata
(Appears on:
-KustomizationSpec)
+KustomizationSpec)
CommonMetadata defines the common labels and annotations.
@@ -458,11 +418,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.
@@ -519,18 +479,19 @@ 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.
|
-Decryption
+Decryption
(Appears on:
-KustomizationSpec)
+KustomizationSpec)
Decryption defines how decryption is handled for Kubernetes manifests.
@@ -572,13 +533,14 @@ 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.
+KustomizationSpec defines the configuration to calculate the desired state
+from a Source using Kustomize.
-KustomizationStatus
+KustomizationStatus
(Appears on:
-Kustomization)
+Kustomization)
KustomizationStatus defines the observed state of a kustomization.
-PostBuild
+PostBuild
(Appears on:
-KustomizationSpec)
+KustomizationSpec)
PostBuild describes which actions to perform on the YAML manifest
generated by building the kustomize overlay.
@@ -1047,9 +969,8 @@ map[string]string
(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}.
|
@@ -1058,7 +979,7 @@ e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}.
substituteFrom
-
+
[]SubstituteReference
@@ -1067,21 +988,23 @@ 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.
|
-ResourceInventory
+ResourceInventory
(Appears on:
-KustomizationStatus)
+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.
-SubstituteReference
+SubstituteReference
(Appears on:
-PostBuild)
+PostBuild)
SubstituteReference contains a reference to a resource containing
the variables name and value.
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..8c64134d
--- /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)
+ + [Working with Kustomizations](kustomization.md#working-with-kustomizations)
+ * [Recommended settings](kustomization.md#recommended-settings)
+ + [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..d8ccb109
--- /dev/null
+++ b/docs/spec/v1/kustomization.md
@@ -0,0 +1,1782 @@
+# 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: 2023-03-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 namespace, 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 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
+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 60
+seconds.
+
+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.
+
+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.
+
+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
+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 information, 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 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.
+
+For example, assuming we have 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` by defining a `dependsOn` relationship between the two:
+
+```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 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
+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 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/)
+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.
+
+### Post build 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 variable 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` ― 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
+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 variable names using this regular
+expression: `^[_[:alpha:]][_[:alpha:][:digit:]]*$`.
+
+For example, assuming we 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 field. If set to `true`, the controller
+will replace the resources in-cluster if the patching fails due to immutable
+field changes.
+
+It can also be enabled 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
+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,
+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-clusterscluster-api).
+
+### Decryption
+
+`.spec.decryption` is an optional field to specify the configuration to decrypt
+Secrets that are a part of the Kustomization.
+
+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
+ 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 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
+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:
+ # Exemplary 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:
+```
+
+## 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:
+
+```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"
+```
+
+### Generating a `kustomization.yaml` file
+
+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).
+
+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](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 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
+the `webapp` namespace.
+
+#### 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)
+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.
+For example:
+
+```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 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
+ 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
+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
+```
+
+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 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, refer
+to [`.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 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).
+
+#### 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 Kustomization
+
+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 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`
+namespace 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 Kustomization, 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 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 `____`.
+
+```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
diff --git a/go.mod b/go.mod
index 7208b391..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
@@ -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/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/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:
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..7e780909 100644
--- a/internal/controllers/kustomization_acl_test.go
+++ b/internal/controllers/kustomization_acl_test.go
@@ -25,14 +25,14 @@ 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"
"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..48e5891a 100644
--- a/internal/controllers/kustomization_controller.go
+++ b/internal/controllers/kustomization_controller.go
@@ -60,9 +60,10 @@ 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/v1beta2"
+ kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
"github.com/fluxcd/kustomize-controller/internal/decryptor"
"github.com/fluxcd/kustomize-controller/internal/inventory"
)
@@ -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) {
@@ -1018,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_decryptor_test.go b/internal/controllers/kustomization_decryptor_test.go
index d082d0ed..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"
@@ -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..06180528 100644
--- a/internal/controllers/kustomization_dependson_test.go
+++ b/internal/controllers/kustomization_dependson_test.go
@@ -24,14 +24,14 @@ 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"
"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..451f66c3 100644
--- a/internal/controllers/kustomization_fetcher_test.go
+++ b/internal/controllers/kustomization_fetcher_test.go
@@ -25,14 +25,14 @@ 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"
"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..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"
@@ -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..bc3eaabb 100644
--- a/internal/controllers/kustomization_fuzzer_test.go
+++ b/internal/controllers/kustomization_fuzzer_test.go
@@ -57,11 +57,11 @@ 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"
- 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..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"
@@ -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..5212f031 100644
--- a/internal/controllers/kustomization_indexers.go
+++ b/internal/controllers/kustomization_indexers.go
@@ -24,9 +24,9 @@ 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/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..11a62a11 100644
--- a/internal/controllers/kustomization_inventory_test.go
+++ b/internal/controllers/kustomization_inventory_test.go
@@ -29,14 +29,14 @@ 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"
"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..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"
@@ -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..9c8972a5 100644
--- a/internal/controllers/kustomization_transformer_test.go
+++ b/internal/controllers/kustomization_transformer_test.go
@@ -26,16 +26,15 @@ 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"
- 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..414d6f4c 100644
--- a/internal/controllers/kustomization_validation_test.go
+++ b/internal/controllers/kustomization_validation_test.go
@@ -23,13 +23,13 @@ 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"
"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..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"
@@ -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..7efc8f0f 100644
--- a/internal/controllers/kustomization_wait_test.go
+++ b/internal/controllers/kustomization_wait_test.go
@@ -32,9 +32,9 @@ 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/v1beta2"
+ kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
)
func TestKustomizationReconciler_WaitConditions(t *testing.T) {
@@ -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")
@@ -181,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/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 ab2879c3..a0d9a41b 100644
--- a/internal/controllers/suite_test.go
+++ b/internal/controllers/suite_test.go
@@ -45,9 +45,10 @@ 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/v1beta2"
+ kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
)
func init() {
@@ -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)))
@@ -205,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 {
@@ -228,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) {
diff --git a/internal/decryptor/decryptor.go b/internal/decryptor/decryptor.go
index 45a95125..70b61375 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"
@@ -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(),
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..4e0a9a7a 100644
--- a/main.go
+++ b/main.go
@@ -43,9 +43,10 @@ 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"
+ sourcev1b2 "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"
@@ -63,6 +64,7 @@ func init() {
_ = clientgoscheme.AddToScheme(scheme)
_ = sourcev1.AddToScheme(scheme)
+ _ = sourcev1b2.AddToScheme(scheme)
_ = kustomizev1.AddToScheme(scheme)
// +kubebuilder:scaffold:scheme
}