diff --git a/README.md b/README.md index 67b6555..2fef2cc 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,15 @@ The kustomize-controller is a Kubernetes operator that applies kustomizations in Features: * watches for `Kustomization` objects -* fetches artifacts produced by `GitRepository` objects -* watches `GitRepository` objects for revision changes +* fetches artifacts produced by [source-controller](https://github.com/fluxcd/source-controller) from `Source` objects +* watches `Source` objects for revision changes * builds the kustomization using the latest fetched artifact * applies the resulting Kubernetes manifests on the cluster -* prunes the Kubernetes objects removed from git based on a label selector +* prunes the Kubernetes objects removed from source based on a label selector ## Kustomization API -A kustomization object defines the source of Kubernetes manifests by referencing a Git repository +A kustomization object defines the source of Kubernetes manifests by referencing a source (managed by [source-controller](https://github.com/fluxcd/source-controller)), the path to the kustomization file, and a label selector used for garbage collection of resources removed from the Git source. @@ -34,9 +34,9 @@ type KustomizationSpec struct { // +optional Prune string `json:"prune,omitempty"` - // Reference of the Git repository where the kustomization source is. + // Reference of the source where the kustomization file is. // +required - GitRepositoryRef corev1.LocalObjectReference `json:"gitRepositoryRef"` + SourceRef corev1.TypedLocalObjectReference `json:"sourceRef"` // The interval at which to apply the kustomization. // +required @@ -44,6 +44,9 @@ type KustomizationSpec struct { } ``` +Supported source kinds: +* [GitRepository](https://github.com/fluxcd/source-controller/blob/master/docs/spec/v1alpha1/gitrepositories.md) + ## Usage Build prerequisites: @@ -57,9 +60,8 @@ Build prerequisites: Install source-controller with: ```bash -git clone https://github.com/fluxcd/source-controller -cd source-controller -make docker-build docker-push dev-deploy IMG=your-docker-hub-username/source-controller:test +kustomize build https://github.com/fluxcd/source-controller//config/default?ref=v0.0.1-alpha.1 \ +kubectl apply -f- ``` Install kustomize-controller with: @@ -111,7 +113,8 @@ spec: interval: 5m path: "./overlays/dev/" prune: "env=dev" - gitRepositoryRef: + sourceRef: + kind: GitRepository name: podinfo ``` @@ -190,7 +193,8 @@ spec: interval: 10m path: "./overlays/production/" prune: "env=production" - gitRepositoryRef: + sourceRef: + kind: GitRepository name: podinfo-releases ``` diff --git a/api/v1alpha1/kustomization_types.go b/api/v1alpha1/kustomization_types.go index 2be6eae..8b869ec 100644 --- a/api/v1alpha1/kustomization_types.go +++ b/api/v1alpha1/kustomization_types.go @@ -35,7 +35,7 @@ type KustomizationSpec struct { // Reference of the Git repository where the kustomization source is. // +required - GitRepositoryRef corev1.LocalObjectReference `json:"gitRepositoryRef"` + SourceRef corev1.TypedLocalObjectReference `json:"sourceRef"` // The interval at which to apply the kustomization. // +required diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 2591d04..68ff722 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -45,7 +45,7 @@ func (in *Kustomization) DeepCopyInto(out *Kustomization) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } @@ -102,7 +102,7 @@ func (in *KustomizationList) DeepCopyObject() runtime.Object { // 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 - out.GitRepositoryRef = in.GitRepositoryRef + in.SourceRef.DeepCopyInto(&out.SourceRef) out.Interval = in.Interval } diff --git a/config/crd/bases/kustomize.fluxcd.io_kustomizations.yaml b/config/crd/bases/kustomize.fluxcd.io_kustomizations.yaml index 29b74a2..d459add 100644 --- a/config/crd/bases/kustomize.fluxcd.io_kustomizations.yaml +++ b/config/crd/bases/kustomize.fluxcd.io_kustomizations.yaml @@ -46,15 +46,6 @@ spec: spec: description: KustomizationSpec defines the desired state of a kustomization. properties: - gitRepositoryRef: - description: Reference of the Git repository where the kustomization - source is. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object interval: description: The interval at which to apply the kustomization. type: string @@ -66,10 +57,29 @@ spec: description: Label selector used for prune operations, e.g. env=staging. pattern: ^.*=.*$ type: string + sourceRef: + description: Reference of the Git repository where the kustomization + source is. + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the + core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object required: - - gitRepositoryRef - interval - path + - sourceRef type: object status: description: KustomizationStatus defines the observed state of a kustomization. diff --git a/config/samples/kustomize_v1alpha1_kustomization.yaml b/config/samples/kustomize_v1alpha1_kustomization.yaml index ab2626c..511c969 100644 --- a/config/samples/kustomize_v1alpha1_kustomization.yaml +++ b/config/samples/kustomize_v1alpha1_kustomization.yaml @@ -6,7 +6,8 @@ spec: interval: 5m path: "./overlays/dev/" prune: "env=dev" - gitRepositoryRef: + sourceRef: + kind: GitRepository name: podinfo --- apiVersion: kustomize.fluxcd.io/v1alpha1 @@ -17,7 +18,8 @@ spec: interval: 5m path: "./overlays/staging/" prune: "env=staging" - gitRepositoryRef: + sourceRef: + kind: GitRepository name: podinfo --- apiVersion: kustomize.fluxcd.io/v1alpha1 @@ -28,5 +30,6 @@ spec: interval: 5m path: "./overlays/production/" prune: "env=production" - gitRepositoryRef: + sourceRef: + kind: GitRepository name: podinfo-releases diff --git a/controllers/gitrepository_controller.go b/controllers/gitrepository_controller.go index d6f9d1b..a842404 100644 --- a/controllers/gitrepository_controller.go +++ b/controllers/gitrepository_controller.go @@ -63,6 +63,10 @@ func (r *GitRepositoryWatcher) Reconcile(req ctrl.Request) (ctrl.Result, error) // trigger apply for each kustomization using this Git repository for _, kustomization := range list.Items { kustomization.Annotations[kustomizev1.SyncAtAnnotation] = metav1.Now().String() + if kustomization.Spec.SourceRef.APIGroup == nil { + emptyAPIGroup := "" + kustomization.Spec.SourceRef.APIGroup = &emptyAPIGroup + } if err := r.Update(ctx, &kustomization); err != nil { log.Error(err, "unable to annotate kustomization", "kustomization", kustomization.GetName()) } @@ -77,7 +81,10 @@ func (r *GitRepositoryWatcher) SetupWithManager(mgr ctrl.Manager) error { err := mgr.GetFieldIndexer().IndexField(&kustomizev1.Kustomization{}, kustomizev1.SourceIndexKey, func(rawObj runtime.Object) []string { k := rawObj.(*kustomizev1.Kustomization) - return []string{k.Spec.GitRepositoryRef.Name} + if k.Spec.SourceRef.Kind == "GitRepository" { + return []string{k.Spec.SourceRef.Name} + } + return nil }, ) if err != nil { diff --git a/controllers/kustomization_controller.go b/controllers/kustomization_controller.go index be19c6d..35343fe 100644 --- a/controllers/kustomization_controller.go +++ b/controllers/kustomization_controller.go @@ -55,20 +55,31 @@ func (r *KustomizationReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro log := r.Log.WithValues(kustomization.Kind, req.NamespacedName) - // get artifact source - var repository sourcev1.GitRepository - repositoryName := types.NamespacedName{ - Namespace: kustomization.GetNamespace(), - Name: kustomization.Spec.GitRepositoryRef.Name, + var source sourcev1.Source + + // get artifact source from Git repository + if kustomization.Spec.SourceRef.Kind == "GitRepository" { + var repository sourcev1.GitRepository + repositoryName := types.NamespacedName{ + Namespace: kustomization.GetNamespace(), + Name: kustomization.Spec.SourceRef.Name, + } + err := r.Client.Get(ctx, repositoryName, &repository) + if err != nil { + log.Error(err, "GitRepository not found", "gitrepository", repositoryName) + return ctrl.Result{Requeue: true}, err + } + source = &repository } - err := r.Client.Get(ctx, repositoryName, &repository) - if err != nil { - log.Error(err, "GitRepository not found", "gitrepository", repositoryName) - return ctrl.Result{Requeue: true}, err + + if source == nil { + err := fmt.Errorf("source `%s` kind '%s' not supported", + kustomization.Spec.SourceRef.Name, kustomization.Spec.SourceRef.Kind) + return ctrl.Result{}, err } // try git sync - syncedKustomization, err := r.sync(ctx, *kustomization.DeepCopy(), repository) + syncedKustomization, err := r.sync(ctx, *kustomization.DeepCopy(), source) if err != nil { log.Error(err, "Kustomization sync failed") } @@ -95,14 +106,14 @@ func (r *KustomizationReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *KustomizationReconciler) sync( ctx context.Context, kustomization kustomizev1.Kustomization, - repository sourcev1.GitRepository) (kustomizev1.Kustomization, error) { - if repository.Status.Artifact == nil || repository.Status.Artifact.URL == "" { - err := fmt.Errorf("artifact not found in %s", repository.GetName()) + source sourcev1.Source) (kustomizev1.Kustomization, error) { + if source.GetArtifact() == nil || source.GetArtifact().URL == "" { + err := fmt.Errorf("artifact not found in %s", kustomization.Spec.SourceRef.Name) return kustomizev1.KustomizationNotReady(kustomization, kustomizev1.ArtifactFailedReason, err.Error()), err } // create tmp dir - tmpDir, err := ioutil.TempDir("", repository.Name) + tmpDir, err := ioutil.TempDir("", kustomization.Name) if err != nil { err = fmt.Errorf("tmp dir error: %w", err) return kustomizev1.KustomizationNotReady(kustomization, sourcev1.StorageOperationFailedReason, err.Error()), err @@ -110,7 +121,7 @@ func (r *KustomizationReconciler) sync( defer os.RemoveAll(tmpDir) // download artifact and extract files - url := repository.Status.Artifact.URL + url := source.GetArtifact().URL cmd := fmt.Sprintf("cd %s && curl -sL %s | tar -xz --strip-components=1 -C .", tmpDir, url) command := exec.CommandContext(ctx, "/bin/sh", "-c", cmd) output, err := command.CombinedOutput() diff --git a/go.mod b/go.mod index e62b350..f48c17a 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/fluxcd/kustomize-controller go 1.13 require ( - github.com/fluxcd/source-controller v0.0.0-20200414154724-1e3bc471d5a8 + github.com/fluxcd/source-controller v0.0.1-alpha.1 github.com/go-logr/logr v0.1.0 github.com/onsi/ginkgo v1.11.0 github.com/onsi/gomega v1.8.1 diff --git a/go.sum b/go.sum index 47e9bf3..c18c5f0 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fluxcd/source-controller v0.0.0-20200414154724-1e3bc471d5a8 h1:5c5rSkmLKf/7N9Ec7F/JqM8BWCijIhz7MtQ8l0htSmI= -github.com/fluxcd/source-controller v0.0.0-20200414154724-1e3bc471d5a8/go.mod h1:11wGvvFvaae1wW4ZyZfanCUfFj8qcowW2Z8hx//Q8To= +github.com/fluxcd/source-controller v0.0.1-alpha.1 h1:UgQ9xnTZdhJN2UMrOfxa6QUan/7ckScpInvy6C24mqQ= +github.com/fluxcd/source-controller v0.0.1-alpha.1/go.mod h1:11wGvvFvaae1wW4ZyZfanCUfFj8qcowW2Z8hx//Q8To= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=