Skip to content

Commit ecc2c62

Browse files
authored
Merge pull request #3 from fluxcd/spec-v1alpha1
Add source API spec v1
2 parents 96c7ad5 + 000bf41 commit ecc2c62

File tree

6 files changed

+859
-0
lines changed

6 files changed

+859
-0
lines changed

docs/spec/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Source Controller Proposal
2+
3+
The main goal is to define a set of Kubernetes objects that cluster
4+
admins and various automated operators can interact with to offload
5+
the sources (e.g. Git and Helm repositories) registration, authentication,
6+
verification and resource fetching to a dedicated controller.
7+
8+
## Motivation
9+
10+
Each Flux and each Helm operator mirrors the Git repositories they are
11+
using, in the same way, using the same code. But other components
12+
might benefit from access to the source mirrors, and Flux and the Helm
13+
operator could work more in sympathy with Kubernetes by factoring it out.
14+
15+
If "sources" (usually git repos, but also Helm charts and potentially
16+
other things) existed in their own right as Kubernetes resources,
17+
components like Flux and Helm operator could use standard Kubernetes
18+
mechanisms to build on them; and, they could be managed independently
19+
of the components using them.
20+
21+
## API Specification
22+
23+
* [v1alpha1](v1alpha1/README.md)
24+
25+
## Implementation
26+
27+
The controller implementation will watch for source objects in a cluster and act on them.
28+
The actions performed by the source controller could be:
29+
30+
* validate source definitions
31+
* authenticate to sources and validate authenticity
32+
* detect source changes based on update policies (semver)
33+
* fetch resources on-demand and on-a-schedule
34+
* package the fetched resources into a well known format (tar.gz, yaml)
35+
* store the artifacts locally
36+
* make the artifacts addressable by their source identifier (sha, version, ts)
37+
* make the artifacts available in-cluster to interested 3rd parties
38+
* notify interested 3rd parties of source changes and availability (status conditions, events, hooks)
39+
40+
## Impact to Flux
41+
42+
Having a dedicated controller that manages Git repositories defined with Kubernetes custom resources would:
43+
44+
* simplify Flux configuration as fluxd could subscribe to Git sources in-cluster and pull the artifacts
45+
automatically without manual intervention from users to reconfigure and redeploy FLux
46+
* improve the installation experience as users will not have to patch fluxd's deployment to inject
47+
the HTTPS basic auth credentials, change the source URL or other Git and PGP related settings
48+
* enable fluxd to compose the desired state of a cluster from multiple sources by applying all artifacts present in flux namespace
49+
* enable fluxd to apply manifests coming from other sources than Git, e.g. S3 buckets
50+
* allow fluxd to run under a non-root user as it wouldn't need to shell out to ssh-keygen, git or pgp
51+
* enable fluxd to apply manifests coming from the most recent semver tag of a Git repository
52+
* allow user to pin the cluster desired state to a specific Git commit or Git tag
53+
54+
## Impact to Helm Operator
55+
56+
Having a dedicated controller that manages Helm repositories and charts defined with Kubernetes custom
57+
resources would:
58+
59+
* simplify the Helm Operator configuration as repository and chart definitions can be re-used across
60+
`HelmRelease` resources (see [fluxcd/helm-operator#142](https://github.com/fluxcd/helm-operator/issues/142))
61+
* improve the user experience as repositories requiring authentication will no longer require a
62+
`repositories.yaml` import / file mount
63+
* simplify the architecture of the Helm Operator as it allows the operator to work with a single
64+
source type (`HelmChart`) and way of preparing and executing installations and/or upgrades
65+
* allow the Helm Operator to run under a non-root user as it wouldn't need to shell out to git

docs/spec/v1alpha1/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# source.fluxcd.io/v1alpha1
2+
3+
The is the v1alpha1 API specification for defining the desired state sources of Kubernetes clusters.
4+
5+
## Specification
6+
7+
* [Common](common.md)
8+
* Source kinds:
9+
+ [GitRepository](gitrepositories.md)
10+
+ [HelmRepository](helmrepositories.md)
11+
+ [HelmChart](helmcharts.md)
12+
13+
## Implementation
14+
15+
* source-controller [v0.0.1-alpha.1](https://github.com/fluxcd/source-controller/releases)

docs/spec/v1alpha1/common.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Common
2+
3+
Common defines resources used across all source types.
4+
5+
## Specification
6+
7+
### Source interface
8+
9+
Source objects should adhere to the `Source` interface. This interface exposes the [interval](#source-synchronization)
10+
and [artifact](#source-status) of the source to clients without the prerequisite of knowing the source kind:
11+
12+
````go
13+
type Source interface {
14+
// GetInterval returns the interval at which the source is updated.
15+
GetInterval() metav1.Duration
16+
17+
// GetArtifact returns the latest artifact from the source, or nil.
18+
GetArtifact() *Artifact
19+
}
20+
````
21+
22+
### Source synchronization
23+
24+
Source objects should contain a `spec.interval` field that tells the controller at which interval to check for updates:
25+
26+
```go
27+
type SourceSpec struct {
28+
// The interval at which to check for source updates.
29+
// +required
30+
Interval metav1.Duration `json:"interval"`
31+
}
32+
```
33+
34+
Valid time units are `s`, `m` and `h` e.g. `interval: 5m`.
35+
36+
The controller can be told to check for updates right away by setting an annotation on source objects:
37+
38+
```go
39+
const (
40+
// ForceSyncAnnotation is the timestamp corresponding to an on-demand source sync.
41+
ForceSyncAnnotation string = "source.fluxcd.io/syncAt"
42+
)
43+
```
44+
45+
Force sync example:
46+
47+
```bash
48+
kubectl annotate --overwrite gitrepository/podinfo source.fluxcd.io/syncAt="$(date +%s)"
49+
```
50+
51+
### Source status
52+
53+
Source objects should contain a status sub-resource that embeds an artifact object:
54+
55+
```go
56+
// Artifact represents the output of a source synchronisation
57+
type Artifact struct {
58+
// Path is the local file path of this artifact.
59+
// +required
60+
Path string `json:"path"`
61+
62+
// URL is the HTTP address of this artifact.
63+
// +required
64+
URL string `json:"url"`
65+
66+
// Revision is a human readable identifier traceable in the origin source system.
67+
// It can be a commit sha, git tag, a helm index timestamp,
68+
// a helm chart version, a checksum, etc.
69+
// +optional
70+
Revision string `json:"revision"`
71+
72+
// LastUpdateTime is the timestamp corresponding to the last
73+
// update of this artifact.
74+
// +required
75+
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
76+
}
77+
```
78+
79+
### Source condition
80+
81+
> **Note:** to be replaced with <https://github.com/kubernetes/enhancements/pull/1624>
82+
> once made available.
83+
84+
```go
85+
// SourceCondition contains condition information for a source.
86+
type SourceCondition struct {
87+
// Type of the condition, currently ('Ready').
88+
// +required
89+
Type string `json:"type"`
90+
91+
// Status of the condition, one of ('True', 'False', 'Unknown').
92+
// +required
93+
Status corev1.ConditionStatus `json:"status"`
94+
95+
// LastTransitionTime is the timestamp corresponding to the last status
96+
// change of this condition.
97+
// +required
98+
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
99+
100+
// Reason is a brief machine readable explanation for the condition's last
101+
// transition.
102+
// +required
103+
Reason string `json:"reason,omitempty"`
104+
105+
// Message is a human readable description of the details of the last
106+
// transition, complementing reason.
107+
// +optional
108+
Message string `json:"message,omitempty"`
109+
}
110+
```
111+
112+
#### Types
113+
114+
```go
115+
const (
116+
// ReadyCondition represents the fact that a given source is in ready state.
117+
ReadyCondition string = "Ready"
118+
)
119+
```
120+
121+
#### Reasons
122+
123+
```go
124+
const (
125+
// InitializingReason represents the fact that a given source is being initialized.
126+
InitializingReason string = "Initializing"
127+
128+
// URLInvalidReason represents the fact that a given source has an invalid URL.
129+
URLInvalidReason string = "URLInvalid"
130+
131+
// StorageOperationFailedReason signals a failure caused by a storage operation.
132+
StorageOperationFailedReason string = "StorageOperationFailed"
133+
134+
// AuthenticationFailedReason represents the fact that a given secret does not
135+
// have the required fields or the provided credentials do not match.
136+
AuthenticationFailedReason string = "AuthenticationFailed"
137+
138+
// VerificationFailedReason represents the fact that the cryptographic provenance
139+
// verification for the source failed.
140+
VerificationFailedReason string = "VerificationFailed"
141+
)
142+
```
143+
144+
## Examples
145+
146+
See the [Git repository](gitrepositories.md) and [Helm chart](helmrepositories.md) APIs.

0 commit comments

Comments
 (0)