Use Source interface instead of Git concrete type
- use TypedLocalObjectReference instead of LocalObjectReference for referencing a source - update docs for GitRepository kind - update source API to 0.0.1-alpha.1
This commit is contained in:
parent
21309c3bf5
commit
c564555eb0
26
README.md
26
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
|
||||
```
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
2
go.mod
2
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
Loading…
Reference in New Issue