Add source API spec proposal
This commit is contained in:
parent
96c7ad502c
commit
b4b85029fb
|
@ -0,0 +1,52 @@
|
|||
# Source Controller Proposal
|
||||
|
||||
## Context
|
||||
|
||||
The desired state of a cluster is made out of Kubernetes objects, these objects are expressed in `.yaml` format and
|
||||
are applied on the cluster by operators running inside the cluster. An operator's role is to fetch the Kubernetes
|
||||
objects, run transformations on them and reconcile the cluster state with the resulting manifest.
|
||||
|
||||
For an operator to acquire the resources that make up the desired state it needs to understand the communication
|
||||
protocol and the authentication scheme, verify the authenticity of a source and deal with rate limits and retries.
|
||||
In the FluxCD organization there are currently two operators that perform such operations. Both Flux and
|
||||
Helm Operator connect to Git repositories to fetch Kubernetes objects, they need to maintain an up-to-date mirror
|
||||
of one or several repos. Besides Git, Helm Operator needs to connect to Helm repositories hosted on public or
|
||||
private HTTPS servers.
|
||||
|
||||
## Motivation
|
||||
|
||||
Each Flux or Helm Operator instance maintains its own Git repository mirror even if all of them
|
||||
point to the same source. If the Git repository host becomes unavailable, the cluster state will diverge from the last
|
||||
know desired state since the operators will stop the reconciliation due to pull errors.
|
||||
|
||||
Decoupling the Kubernetes objects acquisition from the reconciliation process with an in-cluster
|
||||
source manager would make Flux and Helm Operator resilient to outbound connectivity issues and would
|
||||
simplify the state machine(s) that these controllers operate.
|
||||
|
||||
Managing the source operations in a dedicated controller could allow Flux to compose the desire state of a cluster
|
||||
from multiple source.
|
||||
Further more the manifests transformation process could be performed by 3rd party tools
|
||||
(e.g. kustomize, jk, tanka, cue run by Tekton pipelines or Kubernetes Jobs)
|
||||
that would output the final state of the Kubernetes objects into an artifacts repository maintained by the source controller.
|
||||
|
||||
## Goals
|
||||
|
||||
The main goal is to define a set of Kubernetes objects that cluster admins and various automated operators
|
||||
can interact with to offload the sources (e.g. Git and Helm repositories)
|
||||
registration, authentication and resource fetching to a dedicated controller.
|
||||
|
||||
The controller implementation will watch for source objects in a cluster and act on them.
|
||||
The actions performed by the source controller could be:
|
||||
* validate source definitions
|
||||
* authenticate to sources and validate authenticity
|
||||
* detect source changes based on update policies (semver)
|
||||
* fetch resources on-demand and on-a-schedule
|
||||
* package the fetched resources into a well known format (tar.gz)
|
||||
* store the artifacts locally
|
||||
* make the artifacts addressable by their source identifier (sha, version, ts)
|
||||
* make the artifacts available in-cluster to interested 3rd parties
|
||||
* notify interested 3rd parties of source changes and availability (status conditions, events, hooks)
|
||||
|
||||
## API Specification
|
||||
|
||||
* [v1alpha1](v1alpha1/README.md)
|
|
@ -0,0 +1,10 @@
|
|||
# source.fluxcd.io/v1alpha1
|
||||
|
||||
The is the v1alpha1 API specification for defining the desired state sources of Kubernetes clusters.
|
||||
|
||||
Source kinds:
|
||||
* [GitRepository](gitrepositories.md)
|
||||
* [HelmRepository](helmrepositories.md)
|
||||
|
||||
Implementations:
|
||||
* source-controller [v0.0.1-alpha.1](https://github.com/fluxcd/source-controller/releases)
|
|
@ -0,0 +1,212 @@
|
|||
# Git Repositories
|
||||
|
||||
The `GitReposiory` API defines a source for artifacts coming from Git.
|
||||
|
||||
## Specification
|
||||
|
||||
Git repository spec:
|
||||
|
||||
```go
|
||||
// GitRepositorySpec defines the desired state of GitRepository
|
||||
type GitRepositorySpec struct {
|
||||
// +kubebuilder:validation:Pattern="^(http|https|ssh)://"
|
||||
|
||||
// The repository URL, can be a HTTP or SSH address.
|
||||
Url string `json:"url"`
|
||||
|
||||
// The secret name containing the Git credentials
|
||||
// +optional
|
||||
SecretRef *v1.LocalObjectReference `json:"secretRef,omitempty"`
|
||||
|
||||
// The git reference to checkout and monitor for changes.
|
||||
// +optional
|
||||
Reference *GitRepositoryRef `json:"ref,omitempty"`
|
||||
|
||||
// The interval at which to check for repository updates.
|
||||
Interval metav1.Duration `json:"interval"`
|
||||
}
|
||||
|
||||
// GitRepositoryRef defines the git ref used for pull and checkout operations
|
||||
type GitRepositoryRef struct {
|
||||
// The git branch to checkout, defaults to ('master').
|
||||
// +optional
|
||||
Branch string `json:"branch"`
|
||||
|
||||
// The git tag to checkout, takes precedence over branch.
|
||||
// +optional
|
||||
Tag string `json:"tag"`
|
||||
|
||||
// The git tag semver expression, takes precedence over tag.
|
||||
// +optional
|
||||
SemVer string `json:"semver"`
|
||||
}
|
||||
```
|
||||
|
||||
Git repository status:
|
||||
|
||||
```go
|
||||
// GitRepositoryStatus defines the observed state of GitRepository
|
||||
type GitRepositoryStatus struct {
|
||||
// +optional
|
||||
Conditions []RepositoryCondition `json:"conditions,omitempty"`
|
||||
|
||||
// LastUpdateTime is the timestamp corresponding to the last status
|
||||
// change of this repository.
|
||||
// +optional
|
||||
LastUpdateTime *metav1.Time `json:"lastUpdateTime,omitempty"`
|
||||
|
||||
// URI for the artifacts of the last successful repository sync.
|
||||
// +optional
|
||||
Artifacts string `json:"artifacts,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
Git repository status conditions:
|
||||
|
||||
```go
|
||||
// RepositoryCondition contains condition information for a repository
|
||||
type RepositoryCondition struct {
|
||||
// Type of the condition, currently ('Ready').
|
||||
Type RepositoryConditionType `json:"type"`
|
||||
|
||||
// Status of the condition, one of ('True', 'False', 'Unknown').
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
|
||||
// LastTransitionTime is the timestamp corresponding to the last status
|
||||
// change of this condition.
|
||||
// +optional
|
||||
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
|
||||
// Reason is a brief machine readable explanation for the condition's last
|
||||
// transition.
|
||||
// +optional
|
||||
Reason string `json:"reason,omitempty"`
|
||||
|
||||
// Message is a human readable description of the details of the last
|
||||
// transition, complementing reason.
|
||||
// +optional
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// RepositoryConditionType represents an repository condition value
|
||||
type RepositoryConditionType string
|
||||
|
||||
const (
|
||||
// RepositoryConditionReady represents the fact that a given repository condition
|
||||
// is in ready state.
|
||||
RepositoryConditionReady RepositoryConditionType = "Ready"
|
||||
)
|
||||
```
|
||||
|
||||
## Spec examples
|
||||
|
||||
Public repository:
|
||||
|
||||
```yaml
|
||||
apiVersion: source.fluxcd.io/v1alpha1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
annotations:
|
||||
# force sync trigger
|
||||
source.fluxcd.io/syncAt: "2020-04-06T15:39:52+03:00"
|
||||
spec:
|
||||
interval: 1m
|
||||
url: https://github.com/stefanprodan/podinfo
|
||||
ref:
|
||||
branch: master
|
||||
tag: "3.2.0"
|
||||
semver: ">= 3.2.0 <3.3.0"
|
||||
```
|
||||
|
||||
HTTPS authentication:
|
||||
|
||||
```yaml
|
||||
apiVersion: source.fluxcd.io/v1alpha1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
spec:
|
||||
url: https://github.com/stefanprodan/podinfo
|
||||
secretRef:
|
||||
name: https-credentials
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: https-credentials
|
||||
namespace: default
|
||||
type: Opaque
|
||||
data:
|
||||
username: <BASE64>
|
||||
password: <BASE64>
|
||||
```
|
||||
|
||||
SSH authentication:
|
||||
|
||||
```yaml
|
||||
apiVersion: source.fluxcd.io/v1alpha1
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
spec:
|
||||
url: ssh://git@github.com:stefanprodan/podinfo
|
||||
secretRef:
|
||||
name: ssh-credentials
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ssh-credentials
|
||||
namespace: default
|
||||
type: Opaque
|
||||
data:
|
||||
identity: <BASE64>
|
||||
identity.pub: <BASE64>
|
||||
know_hosts: <BASE64>
|
||||
```
|
||||
|
||||
Example of generating the SSH credentials secret:
|
||||
|
||||
```bash
|
||||
ssh-keygen -q -N "" -f ./identity
|
||||
ssh-keyscan github.com > ./know_hosts
|
||||
|
||||
kubectl create secret generic ssh-credentials \
|
||||
--from-file=./identity \
|
||||
--from-file=./identity.pub \
|
||||
--from-file=./know_hosts
|
||||
```
|
||||
|
||||
## Status examples
|
||||
|
||||
Successful sync:
|
||||
|
||||
```yaml
|
||||
status:
|
||||
artifacts: http://source-controller.source-system/repositories/podinfo-default/5e747d3e088cd7a34ace4abc8cf7f3c3696e402f.tar.gz
|
||||
conditions:
|
||||
- lastTransitionTime: "2020-04-07T06:59:23Z"
|
||||
message: 'Fetched artifacts are available at
|
||||
/data/repositories/podinfo-default/5e747d3e088cd7a34ace4abc8cf7f3c3696e402f.tar.gz'
|
||||
reason: GitCloneSucceed
|
||||
status: "True"
|
||||
type: Ready
|
||||
lastUpdateTime: "2020-04-07T06:59:23Z"
|
||||
```
|
||||
|
||||
Failed sync:
|
||||
|
||||
```yaml
|
||||
status:
|
||||
conditions:
|
||||
- lastTransitionTime: "2020-04-06T06:48:59Z"
|
||||
message: 'git clone error ssh: handshake failed: ssh: unable to authenticate,
|
||||
attempted methods [none publickey], no supported methods remain'
|
||||
reason: GitCloneFailed
|
||||
status: "False"
|
||||
type: Ready
|
||||
```
|
|
@ -0,0 +1,15 @@
|
|||
# Helm Repositories
|
||||
|
||||
The `HelmReposiory` and `HelmChart` API defines a source for artifacts coming from Helm repositories.
|
||||
|
||||
## Specification
|
||||
|
||||
TODO
|
||||
|
||||
## Spec examples
|
||||
|
||||
TODO
|
||||
|
||||
## Status examples
|
||||
|
||||
TODO
|
Loading…
Reference in New Issue