Skip to content
This repository has been archived by the owner on Oct 12, 2023. It is now read-only.

Add item list CRD Spec #1

Merged
merged 5 commits into from
Jun 12, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin
vendor

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Kubernetes Generated files - skip generated files, except for vendored files

!vendor/**/zz_generated.*

# editor and IDE paraphernalia
.idea
*.swp
*.swo
*~
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Build the binary
FROM golang:1.14.1 as builder

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

# Copy the go source
COPY . .

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o applicationset-controller main.go

# Use distroless as minimal base image to package the manager binary
FROM debian:10-slim
WORKDIR /
COPY --from=builder /workspace/applicationset-controller /usr/local/bin/
27 changes: 27 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
VERSION?=$(shell cat VERSION)
IMAGE_TAG?=v$(VERSION)
IMAGE_PREFIX?=registry.cn-hangzhou.aliyuncs.com/appcenter
DOCKER_PUSH?=true

.PHONY: build
build:
CGO_ENABLED=0 go build -ldflags="-w -s" -o ./dist/argocd-aplicationset .

.PHONY: image
image:
docker build -t registry.cn-hangzhou.aliyuncs.com/appcenter/argocd-aplicationset:$(IMAGE_TAG) .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make the registry configurable as well, $IMAGE perhaps?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Can make it such that it builds a local image (without a registry), but will prepend IMAGE_PREFIX if it is defined?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@if [ "$(DOCKER_PUSH)" = "true" ] ; then docker push $(IMAGE_PREFIX)/argocd-aplicationset:$(IMAGE_TAG) ; fi

# Generate manifests e.g. CRD, RBAC etc.
.PHONY: manifests
manifests:
controller-gen paths=./api/... crd:trivialVersions=true output:dir=./manifests/crds/
controller-gen object paths=./api/...

# Run go fmt against code
fmt:
go fmt ./...

# Run go vet against code
vet:
go vet ./...
6 changes: 6 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
repo: github.com/argoproj-labs/applicationset
resources:
- group: argoproj.io
kind: ApplicationSet
version: v1alpha1
version: "1"
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
73 changes: 73 additions & 0 deletions api/v1alpha1/applicationset_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package v1alpha1

import (
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ApplicationSet is a set of Application resources
// +kubebuilder:object:root=true
// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type ApplicationSet struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec ApplicationSetSpec `json:"spec"`
}

// ApplicationSetSpec represents a class of application set state.
type ApplicationSetSpec struct {
Generators ApplicationSetGenerators `json:"generators"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per spec, it should be an array of ApplicationSetGenerator:

spec:
  generators:
  - clusters: {}
    Generators []ApplicationSetGenerator  `json:"generators"`

Template ApplicationSetTemplate `json:"template"`
Operation *v1alpha1.SyncOperation `json:"operation,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the operation field:

  1. Reusing the SyncOperation from the Applications APIs probably doesn't make sense here, since that object deals with a single git revision. But ApplicationSets may deal with many revisions, and even many repositories. If we do decide to have operation, we will need a new data structure.

  2. In fact, we're not sure what a sync operation even means for an AppSet. Currently, I think it would only be used as a convenience field which carries forward setting the operation field for all the Applications in the ApplicationSet. But this could be done as a convenience in the API server instead.

  3. We've had some regrets about introducing this operation field in Applications, since a better alternative might have been to introduce an SyncOperation CRD and controller to perform the logic. This CRD would act like a Job object and finish Successfully or Failed.

So with the above, I think we should leave out operation, until we think about how we want to do operations (if at all).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

SyncPolicy *ApplicationSetSyncPolicy `json:"syncPolicy,omitempty"`
}

// ApplicationSetSyncPolicy will provide a syncPolicy similar to Applications
type ApplicationSetSyncPolicy struct {
// Automated will keep an application synced to the target revision
Automated *SyncPolicyAutomated `json:"automated,omitempty"`
}

// SyncPolicyAutomated
type SyncPolicyAutomated struct {
// Prune will prune resources automatically as part of automated sync (default: false)
Prune bool `json:"prune,omitempty"`
InitialSync bool `json:"initialSync,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking the word sync is redundant in the initialSync, since it's already part of a syncPolicy. How about:

spec:
  syncPolicy:
    automated:
      prune: true
      initial: true

Let's also comment this to explain what this option is for:

// Initial will perform an initial sync for any newly created Applications which do not have automated sync turned on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

// ApplicationSetTemplate represents argocd ApplicationSpec
type ApplicationSetTemplate struct {
metav1.ObjectMeta `json:"metadata"`
TemplateSpec v1alpha1.ApplicationSpec `json:"spec"`
Copy link
Member

@jessesuen jessesuen Jun 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the field name needs to be named Spec, otherwise this may be an K8s API violation since the golang field name does not match the json field name.

}

// ApplicationSetGenerators include list item info
type ApplicationSetGenerators struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove s from ApplicationSetGenerators since this should be a single generator

type ApplicationSetGenerator struct {
	List *ListGenerator `json:"list, omitempty"`
}

Also, we should remove s from ListGenerators as well.

List GeneratorsList `json:"list, omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this should be *GeneratorsList as it is optional.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

}

// GeneratorsList include items info
type GeneratorsList struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GeneratorsList implies this is a list of all generators, what do you think about ListGenerator to more clearly indicate what this is?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Items GeneratorsItems `json:"items"`
}

// GeneratorsItems include cluster and url info
type GeneratorsItems struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest ListGeneratorItem

Cluster string `json:"cluster"`
Url string `json:"url"`
}

// +kubebuilder:object:root=true

// ApplicationSetList contains a list of ApplicationSet
type ApplicationSetList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ApplicationSet `json:"items"`
}

func init() {
SchemeBuilder.Register(&ApplicationSet{}, &ApplicationSetList{})
}
20 changes: 20 additions & 0 deletions api/v1alpha1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Package v1alpha1 contains API Schema definitions for the argoproj.io v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=argoproj.io
package v1alpha1

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: "argoproj.io", Version: "v1alpha1"}

// 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
)
194 changes: 194 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/list.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ spec:
url: https://9.8.7.6
template:
metadata:
name: '{{name}}-guestbook'
name: '{{cluster}}-guestbook'
spec:
source:
repoURL: https://github.com/infra-team/cluster-deployments.git
Expand Down