Promote API to v1beta1

This commit is contained in:
stefanprodan 2020-09-30 15:25:08 +03:00
parent 3f2f4d5b04
commit f16e5f041a
52 changed files with 1244 additions and 131 deletions

View File

@ -22,7 +22,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2-beta
with:
go-version: 1.14.x
go-version: 1.15.x
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.3.0
- name: Setup Kustomize

View File

@ -1,5 +1,5 @@
# Docker buildkit multi-arch build requires golang alpine
FROM golang:1.14-alpine as builder
FROM golang:1.15-alpine as builder
WORKDIR /workspace

View File

@ -52,7 +52,7 @@ manifests: controller-gen
# Generate API reference documentation
api-docs: gen-crd-api-reference-docs
$(API_REF_GEN) -api-dir=./api/v1alpha1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/source.md
$(API_REF_GEN) -api-dir=./api/v1beta1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/source.md
# Run go fmt against code
fmt:

View File

@ -3,14 +3,14 @@ repo: github.com/fluxcd/source-controller
resources:
- group: source
kind: GitRepository
version: v1alpha1
version: v1beta1
- group: source
kind: HelmRepository
version: v1alpha1
version: v1beta1
- group: source
kind: HelmChart
version: v1alpha1
version: v1beta1
- group: source
kind: Bucket
version: v1alpha1
version: v1beta1
version: "2"

View File

@ -6,9 +6,9 @@
[![release](https://img.shields.io/github/release/fluxcd/source-controller/all.svg)](https://github.com/fluxcd/source-controller/releases)
The source-controller is a Kubernetes operator, specialised in artifacts acquisition
from external sources such as Git and Helm repositories.
from external sources such as Git, Helm repositories and S3 buckets.
The source-controller implements the
[source.toolkit.fluxcd.io](https://github.com/fluxcd/source-controller/tree/master/docs/spec/v1alpha1) API
[source.toolkit.fluxcd.io](https://github.com/fluxcd/source-controller/tree/master/docs/spec/v1beta1) API
and is a core component of the [GitOps toolkit](https://toolkit.fluxcd.io).
![overview](docs/diagrams/source-controller-overview.png)

View File

@ -1,6 +1,6 @@
module github.com/fluxcd/source-controller/api
go 1.14
go 1.15
require (
github.com/fluxcd/pkg/apis/meta v0.0.2

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"path"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"time"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
const SourceFinalizer = "finalizers.fluxcd.io"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1alpha1 contains API Schema definitions for the source v1alpha1 API group
// Package v1beta1 contains API Schema definitions for the source v1beta1 API group
// +kubebuilder:object:generate=true
// +groupName=source.toolkit.fluxcd.io
package v1alpha1
package v1beta1

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"time"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
@ -23,7 +23,7 @@ import (
var (
// GroupVersion is group version used to register these objects.
GroupVersion = schema.GroupVersion{Group: "source.toolkit.fluxcd.io", Version: "v1alpha1"}
GroupVersion = schema.GroupVersion{Group: "source.toolkit.fluxcd.io", Version: "v1beta1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"github.com/fluxcd/pkg/apis/meta"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package v1beta1
import (
"time"

View File

@ -1,4 +1,4 @@
package v1alpha1
package v1beta1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -18,7 +18,7 @@ limitations under the License.
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha1
package v1beta1
import (
"github.com/fluxcd/pkg/apis/meta"

View File

@ -29,7 +29,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1beta1
schema:
openAPIV3Schema:
description: Bucket is the Schema for the buckets API

View File

@ -29,7 +29,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1beta1
schema:
openAPIV3Schema:
description: GitRepository is the Schema for the gitrepositories API

View File

@ -38,7 +38,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1beta1
schema:
openAPIV3Schema:
description: HelmChart is the Schema for the helmcharts API

View File

@ -29,7 +29,7 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
name: v1beta1
schema:
openAPIV3Schema:
description: HelmRepository is the Schema for the helmrepositories API

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: bucket-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: gitrepository-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: helmchart-git-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: helmchart-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: helmrepository-sample

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: podinfo

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: charts
@ -13,7 +13,7 @@ spec:
secretRef:
name: minio-credentials
---
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: helmchart-bucket

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: bitnami-charts

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: mariadb-git

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: mariadb

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1alpha1
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: bitnami-charts

View File

@ -42,7 +42,7 @@ import (
"github.com/fluxcd/pkg/recorder"
"github.com/fluxcd/pkg/runtime/predicates"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
// BucketReconciler reconciles a Bucket object
@ -315,7 +315,7 @@ func (r *BucketReconciler) checksum(root string) (string, error) {
return fmt.Sprintf("%x", sha1.Sum([]byte(checksum))), nil
}
// resetStatus returns a modified v1alpha1.Bucket and a boolean indicating
// resetStatus returns a modified v1beta1.Bucket and a boolean indicating
// if the status field has been reset.
func (r *BucketReconciler) resetStatus(bucket sourcev1.Bucket) (sourcev1.Bucket, bool) {
// We do not have an artifact, or it does no longer exist

View File

@ -40,7 +40,7 @@ import (
"github.com/fluxcd/pkg/recorder"
"github.com/fluxcd/pkg/runtime/predicates"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/fluxcd/source-controller/pkg/git"
)
@ -274,7 +274,7 @@ func (r *GitRepositoryReconciler) verify(ctx context.Context, publicKeySecret ty
return nil
}
// resetStatus returns a modified v1alpha1.GitRepository and a boolean indicating
// resetStatus returns a modified v1beta1.GitRepository and a boolean indicating
// if the status field has been reset.
func (r *GitRepositoryReconciler) resetStatus(repository sourcev1.GitRepository) (sourcev1.GitRepository, bool) {
// We do not have an artifact, or it does no longer exist

View File

@ -41,7 +41,7 @@ import (
"github.com/fluxcd/pkg/gittestserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
var _ = Describe("GitRepositoryReconciler", func() {

View File

@ -44,7 +44,7 @@ import (
"github.com/fluxcd/pkg/runtime/predicates"
"github.com/fluxcd/pkg/untar"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/fluxcd/source-controller/internal/helm"
)
@ -474,7 +474,7 @@ func (r *HelmChartReconciler) reconcileFromTarballArtifact(ctx context.Context,
return sourcev1.HelmChartReady(chart, newArtifact, cUrl, sourcev1.ChartPackageSucceededReason, message), nil
}
// resetStatus returns a modified v1alpha1.HelmChart and a boolean indicating
// resetStatus returns a modified v1beta1.HelmChart and a boolean indicating
// if the status field has been reset.
func (r *HelmChartReconciler) resetStatus(chart sourcev1.HelmChart) (sourcev1.HelmChart, bool) {
// We do not have an artifact, or it does no longer exist

View File

@ -45,7 +45,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
var _ = Describe("HelmChartReconciler", func() {

View File

@ -40,7 +40,7 @@ import (
"github.com/fluxcd/pkg/recorder"
"github.com/fluxcd/pkg/runtime/predicates"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/fluxcd/source-controller/internal/helm"
)
@ -248,7 +248,7 @@ func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, repository sou
return sourcev1.HelmRepositoryReady(repository, artifact, indexURL, sourcev1.IndexationSucceededReason, message), nil
}
// resetStatus returns a modified v1alpha1.HelmRepository and a boolean indicating
// resetStatus returns a modified v1beta1.HelmRepository and a boolean indicating
// if the status field has been reset.
func (r *HelmRepositoryReconciler) resetStatus(repository sourcev1.HelmRepository) (sourcev1.HelmRepository, bool) {
// We do not have an artifact, or it does no longer exist

View File

@ -32,7 +32,7 @@ import (
"github.com/fluxcd/pkg/helmtestserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
var _ = Describe("HelmRepositoryReconciler", func() {

View File

@ -37,7 +37,7 @@ import (
"github.com/fluxcd/pkg/lockedfile"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/fluxcd/source-controller/internal/fs"
)
@ -71,7 +71,7 @@ func NewStorage(basePath string, hostname string, timeout time.Duration) (*Stora
}, nil
}
// NewArtifactFor returns a new v1alpha1.Artifact.
// NewArtifactFor returns a new v1beta1.Artifact.
func (s *Storage) NewArtifactFor(kind string, metadata metav1.Object, revision, fileName string) sourcev1.Artifact {
path := sourcev1.ArtifactPath(kind, metadata.GetNamespace(), metadata.GetName(), fileName)
artifact := sourcev1.Artifact{
@ -82,7 +82,7 @@ func (s *Storage) NewArtifactFor(kind string, metadata metav1.Object, revision,
return artifact
}
// SetArtifactURL sets the URL on the given v1alpha1.Artifact.
// SetArtifactURL sets the URL on the given v1beta1.Artifact.
func (s Storage) SetArtifactURL(artifact *sourcev1.Artifact) {
if artifact.Path == "" {
return
@ -101,19 +101,19 @@ func (s Storage) SetHostname(URL string) string {
return u.String()
}
// MkdirAll calls os.MkdirAll for the given v1alpha1.Artifact base dir.
// MkdirAll calls os.MkdirAll for the given v1beta1.Artifact base dir.
func (s *Storage) MkdirAll(artifact sourcev1.Artifact) error {
dir := filepath.Dir(s.LocalPath(artifact))
return os.MkdirAll(dir, 0777)
}
// RemoveAll calls os.RemoveAll for the given v1alpha1.Artifact base dir.
// RemoveAll calls os.RemoveAll for the given v1beta1.Artifact base dir.
func (s *Storage) RemoveAll(artifact sourcev1.Artifact) error {
dir := filepath.Dir(s.LocalPath(artifact))
return os.RemoveAll(dir)
}
// RemoveAllButCurrent removes all files for the given v1alpha1.Artifact base dir,
// RemoveAllButCurrent removes all files for the given v1beta1.Artifact base dir,
// excluding the current one.
func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) error {
localPath := s.LocalPath(artifact)
@ -139,7 +139,7 @@ func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) error {
return nil
}
// ArtifactExist returns a boolean indicating whether the v1alpha1.Artifact exists in storage
// ArtifactExist returns a boolean indicating whether the v1beta1.Artifact exists in storage
// and is a regular file.
func (s *Storage) ArtifactExist(artifact sourcev1.Artifact) bool {
fi, err := os.Lstat(s.LocalPath(artifact))
@ -149,7 +149,7 @@ func (s *Storage) ArtifactExist(artifact sourcev1.Artifact) bool {
return fi.Mode().IsRegular()
}
// Archive atomically archives the given directory as a tarball to the given v1alpha1.Artifact
// Archive atomically archives the given directory as a tarball to the given v1beta1.Artifact
// path, excluding any VCS specific files and directories, or any of the excludes defined in
// the excludeFiles. If successful, it sets the checksum and last update time on the artifact.
func (s *Storage) Archive(artifact *sourcev1.Artifact, dir string, ignore *string) (err error) {
@ -265,7 +265,7 @@ func writeToArchiveExcludeMatches(dir string, matcher gitignore.Matcher, writer
return filepath.Walk(dir, fn)
}
// AtomicWriteFile atomically writes the io.Reader contents to the v1alpha1.Artifact path.
// AtomicWriteFile atomically writes the io.Reader contents to the v1beta1.Artifact path.
// If successful, it sets the checksum and last update time on the artifact.
func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader, mode os.FileMode) (err error) {
localPath := s.LocalPath(*artifact)
@ -304,7 +304,7 @@ func (s *Storage) AtomicWriteFile(artifact *sourcev1.Artifact, reader io.Reader,
return nil
}
// Copy atomically copies the io.Reader contents to the v1alpha1.Artifact path.
// Copy atomically copies the io.Reader contents to the v1beta1.Artifact path.
// If successful, it sets the checksum and last update time on the artifact.
func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error) {
localPath := s.LocalPath(*artifact)
@ -340,7 +340,7 @@ func (s *Storage) Copy(artifact *sourcev1.Artifact, reader io.Reader) (err error
}
// CopyFromPath atomically copies the contents of the given path to the path of
// the v1alpha1.Artifact. If successful, the checksum and last update time on the
// the v1beta1.Artifact. If successful, the checksum and last update time on the
// artifact is set.
func (s *Storage) CopyFromPath(artifact *sourcev1.Artifact, path string) (err error) {
f, err := os.Open(path)
@ -351,7 +351,7 @@ func (s *Storage) CopyFromPath(artifact *sourcev1.Artifact, path string) (err er
return s.Copy(artifact, f)
}
// Symlink creates or updates a symbolic link for the given v1alpha1.Artifact
// Symlink creates or updates a symbolic link for the given v1beta1.Artifact
// and returns the URL for the symlink.
func (s *Storage) Symlink(artifact sourcev1.Artifact, linkName string) (string, error) {
localPath := s.LocalPath(artifact)
@ -382,7 +382,7 @@ func (s *Storage) Checksum(reader io.Reader) string {
return fmt.Sprintf("%x", h.Sum(nil))
}
// Lock creates a file lock for the given v1alpha1.Artifact.
// Lock creates a file lock for the given v1beta1.Artifact.
func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) {
lockFile := s.LocalPath(artifact) + ".lock"
mutex := lockedfile.MutexAt(lockFile)

View File

@ -13,7 +13,7 @@ import (
"testing"
"time"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
type ignoreMap map[string]bool

View File

@ -36,7 +36,7 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
// +kubebuilder:scaffold:imports
)

View File

@ -2,22 +2,22 @@
<p>Packages:</p>
<ul class="simple">
<li>
<a href="#source.toolkit.fluxcd.io%2fv1alpha1">source.toolkit.fluxcd.io/v1alpha1</a>
<a href="#source.toolkit.fluxcd.io%2fv1beta1">source.toolkit.fluxcd.io/v1beta1</a>
</li>
</ul>
<h2 id="source.toolkit.fluxcd.io/v1alpha1">source.toolkit.fluxcd.io/v1alpha1</h2>
<p>Package v1alpha1 contains API Schema definitions for the source v1alpha1 API group</p>
<h2 id="source.toolkit.fluxcd.io/v1beta1">source.toolkit.fluxcd.io/v1beta1</h2>
<p>Package v1beta1 contains API Schema definitions for the source v1beta1 API group</p>
Resource Types:
<ul class="simple"><li>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Bucket">Bucket</a>
<a href="#source.toolkit.fluxcd.io/v1beta1.Bucket">Bucket</a>
</li><li>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepository">GitRepository</a>
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepository">GitRepository</a>
</li><li>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChart">HelmChart</a>
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChart">HelmChart</a>
</li><li>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepository">HelmRepository</a>
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepository">HelmRepository</a>
</li></ul>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.Bucket">Bucket
<h3 id="source.toolkit.fluxcd.io/v1beta1.Bucket">Bucket
</h3>
<p>Bucket is the Schema for the buckets API</p>
<div class="md-typeset__scrollwrap">
@ -35,7 +35,7 @@ Resource Types:
<code>apiVersion</code><br>
string</td>
<td>
<code>source.toolkit.fluxcd.io/v1alpha1</code>
<code>source.toolkit.fluxcd.io/v1beta1</code>
</td>
</tr>
<tr>
@ -65,7 +65,7 @@ Refer to the Kubernetes API documentation for the fields of the
<td>
<code>spec</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.BucketSpec">
<a href="#source.toolkit.fluxcd.io/v1beta1.BucketSpec">
BucketSpec
</a>
</em>
@ -194,7 +194,7 @@ string
<td>
<code>status</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.BucketStatus">
<a href="#source.toolkit.fluxcd.io/v1beta1.BucketStatus">
BucketStatus
</a>
</em>
@ -206,7 +206,7 @@ BucketStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.GitRepository">GitRepository
<h3 id="source.toolkit.fluxcd.io/v1beta1.GitRepository">GitRepository
</h3>
<p>GitRepository is the Schema for the gitrepositories API</p>
<div class="md-typeset__scrollwrap">
@ -224,7 +224,7 @@ BucketStatus
<code>apiVersion</code><br>
string</td>
<td>
<code>source.toolkit.fluxcd.io/v1alpha1</code>
<code>source.toolkit.fluxcd.io/v1beta1</code>
</td>
</tr>
<tr>
@ -254,7 +254,7 @@ Refer to the Kubernetes API documentation for the fields of the
<td>
<code>spec</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositorySpec">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositorySpec">
GitRepositorySpec
</a>
</em>
@ -323,7 +323,7 @@ Kubernetes meta/v1.Duration
<td>
<code>ref</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryRef">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryRef">
GitRepositoryRef
</a>
</em>
@ -338,7 +338,7 @@ master branch.</p>
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryVerification">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryVerification">
GitRepositoryVerification
</a>
</em>
@ -369,7 +369,7 @@ consult the documentation for your version to find out what those are.</p>
<td>
<code>status</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryStatus">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryStatus">
GitRepositoryStatus
</a>
</em>
@ -381,7 +381,7 @@ GitRepositoryStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmChart">HelmChart
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmChart">HelmChart
</h3>
<p>HelmChart is the Schema for the helmcharts API</p>
<div class="md-typeset__scrollwrap">
@ -399,7 +399,7 @@ GitRepositoryStatus
<code>apiVersion</code><br>
string</td>
<td>
<code>source.toolkit.fluxcd.io/v1alpha1</code>
<code>source.toolkit.fluxcd.io/v1beta1</code>
</td>
</tr>
<tr>
@ -429,7 +429,7 @@ Refer to the Kubernetes API documentation for the fields of the
<td>
<code>spec</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChartSpec">
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChartSpec">
HelmChartSpec
</a>
</em>
@ -466,7 +466,7 @@ and Bucket sources. Defaults to latest when omitted.</p>
<td>
<code>sourceRef</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.LocalHelmChartSourceReference">
<a href="#source.toolkit.fluxcd.io/v1beta1.LocalHelmChartSourceReference">
LocalHelmChartSourceReference
</a>
</em>
@ -508,7 +508,7 @@ relative path in the SourceRef. Ignored when omitted.</p>
<td>
<code>status</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChartStatus">
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChartStatus">
HelmChartStatus
</a>
</em>
@ -520,7 +520,7 @@ HelmChartStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmRepository">HelmRepository
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmRepository">HelmRepository
</h3>
<p>HelmRepository is the Schema for the helmrepositories API</p>
<div class="md-typeset__scrollwrap">
@ -538,7 +538,7 @@ HelmChartStatus
<code>apiVersion</code><br>
string</td>
<td>
<code>source.toolkit.fluxcd.io/v1alpha1</code>
<code>source.toolkit.fluxcd.io/v1beta1</code>
</td>
</tr>
<tr>
@ -568,7 +568,7 @@ Refer to the Kubernetes API documentation for the fields of the
<td>
<code>spec</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepositorySpec">
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepositorySpec">
HelmRepositorySpec
</a>
</em>
@ -641,7 +641,7 @@ Kubernetes meta/v1.Duration
<td>
<code>status</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepositoryStatus">
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepositoryStatus">
HelmRepositoryStatus
</a>
</em>
@ -653,14 +653,14 @@ HelmRepositoryStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.Artifact">Artifact
<h3 id="source.toolkit.fluxcd.io/v1beta1.Artifact">Artifact
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.BucketStatus">BucketStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryStatus">GitRepositoryStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChartStatus">HelmChartStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepositoryStatus">HelmRepositoryStatus</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.BucketStatus">BucketStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryStatus">GitRepositoryStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChartStatus">HelmChartStatus</a>,
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepositoryStatus">HelmRepositoryStatus</a>)
</p>
<p>Artifact represents the output of a source synchronisation.</p>
<div class="md-typeset__scrollwrap">
@ -739,11 +739,11 @@ artifact.</p>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.BucketSpec">BucketSpec
<h3 id="source.toolkit.fluxcd.io/v1beta1.BucketSpec">BucketSpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Bucket">Bucket</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.Bucket">Bucket</a>)
</p>
<p>BucketSpec defines the desired state of an S3 compatible bucket</p>
<div class="md-typeset__scrollwrap">
@ -873,11 +873,11 @@ string
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.BucketStatus">BucketStatus
<h3 id="source.toolkit.fluxcd.io/v1beta1.BucketStatus">BucketStatus
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Bucket">Bucket</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.Bucket">Bucket</a>)
</p>
<p>BucketStatus defines the observed state of a bucket</p>
<div class="md-typeset__scrollwrap">
@ -932,7 +932,7 @@ string
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Artifact">
<a href="#source.toolkit.fluxcd.io/v1beta1.Artifact">
Artifact
</a>
</em>
@ -946,11 +946,11 @@ Artifact
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.GitRepositoryRef">GitRepositoryRef
<h3 id="source.toolkit.fluxcd.io/v1beta1.GitRepositoryRef">GitRepositoryRef
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositorySpec">GitRepositorySpec</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositorySpec">GitRepositorySpec</a>)
</p>
<p>GitRepositoryRef defines the git ref used for pull and checkout operations.</p>
<div class="md-typeset__scrollwrap">
@ -1015,11 +1015,11 @@ string
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.GitRepositorySpec">GitRepositorySpec
<h3 id="source.toolkit.fluxcd.io/v1beta1.GitRepositorySpec">GitRepositorySpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepository">GitRepository</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepository">GitRepository</a>)
</p>
<p>GitRepositorySpec defines the desired state of a Git repository.</p>
<div class="md-typeset__scrollwrap">
@ -1092,7 +1092,7 @@ Kubernetes meta/v1.Duration
<td>
<code>ref</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryRef">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryRef">
GitRepositoryRef
</a>
</em>
@ -1107,7 +1107,7 @@ master branch.</p>
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositoryVerification">
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositoryVerification">
GitRepositoryVerification
</a>
</em>
@ -1135,11 +1135,11 @@ consult the documentation for your version to find out what those are.</p>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.GitRepositoryStatus">GitRepositoryStatus
<h3 id="source.toolkit.fluxcd.io/v1beta1.GitRepositoryStatus">GitRepositoryStatus
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepository">GitRepository</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepository">GitRepository</a>)
</p>
<p>GitRepositoryStatus defines the observed state of a Git repository.</p>
<div class="md-typeset__scrollwrap">
@ -1195,7 +1195,7 @@ sync.</p>
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Artifact">
<a href="#source.toolkit.fluxcd.io/v1beta1.Artifact">
Artifact
</a>
</em>
@ -1209,11 +1209,11 @@ Artifact
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.GitRepositoryVerification">GitRepositoryVerification
<h3 id="source.toolkit.fluxcd.io/v1beta1.GitRepositoryVerification">GitRepositoryVerification
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.GitRepositorySpec">GitRepositorySpec</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.GitRepositorySpec">GitRepositorySpec</a>)
</p>
<p>GitRepositoryVerification defines the OpenPGP signature verification process.</p>
<div class="md-typeset__scrollwrap">
@ -1254,11 +1254,11 @@ Kubernetes core/v1.LocalObjectReference
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmChartSpec">HelmChartSpec
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmChartSpec">HelmChartSpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChart">HelmChart</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChart">HelmChart</a>)
</p>
<p>HelmChartSpec defines the desired state of a Helm chart.</p>
<div class="md-typeset__scrollwrap">
@ -1299,7 +1299,7 @@ and Bucket sources. Defaults to latest when omitted.</p>
<td>
<code>sourceRef</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.LocalHelmChartSourceReference">
<a href="#source.toolkit.fluxcd.io/v1beta1.LocalHelmChartSourceReference">
LocalHelmChartSourceReference
</a>
</em>
@ -1338,11 +1338,11 @@ relative path in the SourceRef. Ignored when omitted.</p>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmChartStatus">HelmChartStatus
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmChartStatus">HelmChartStatus
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChart">HelmChart</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChart">HelmChart</a>)
</p>
<p>HelmChartStatus defines the observed state of the HelmChart.</p>
<div class="md-typeset__scrollwrap">
@ -1397,7 +1397,7 @@ string
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Artifact">
<a href="#source.toolkit.fluxcd.io/v1beta1.Artifact">
Artifact
</a>
</em>
@ -1411,11 +1411,11 @@ Artifact
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmRepositorySpec">HelmRepositorySpec
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmRepositorySpec">HelmRepositorySpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepository">HelmRepository</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepository">HelmRepository</a>)
</p>
<p>HelmRepositorySpec defines the reference to a Helm repository.</p>
<div class="md-typeset__scrollwrap">
@ -1489,11 +1489,11 @@ Kubernetes meta/v1.Duration
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.HelmRepositoryStatus">HelmRepositoryStatus
<h3 id="source.toolkit.fluxcd.io/v1beta1.HelmRepositoryStatus">HelmRepositoryStatus
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmRepository">HelmRepository</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmRepository">HelmRepository</a>)
</p>
<p>HelmRepositoryStatus defines the observed state of the HelmRepository.</p>
<div class="md-typeset__scrollwrap">
@ -1548,7 +1548,7 @@ string
<td>
<code>artifact</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.Artifact">
<a href="#source.toolkit.fluxcd.io/v1beta1.Artifact">
Artifact
</a>
</em>
@ -1562,11 +1562,11 @@ Artifact
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.LocalHelmChartSourceReference">LocalHelmChartSourceReference
<h3 id="source.toolkit.fluxcd.io/v1beta1.LocalHelmChartSourceReference">LocalHelmChartSourceReference
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1alpha1.HelmChartSpec">HelmChartSpec</a>)
<a href="#source.toolkit.fluxcd.io/v1beta1.HelmChartSpec">HelmChartSpec</a>)
</p>
<p>LocalHelmChartSourceReference contains enough information to let you locate
the typed referenced object at namespace level.</p>
@ -1619,7 +1619,7 @@ string
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1alpha1.Source">Source
<h3 id="source.toolkit.fluxcd.io/v1beta1.Source">Source
</h3>
<p>Source interface must be supported by all API types.</p>
<div class="admonition note">

View File

@ -20,7 +20,7 @@ of the components using them.
## API Specification
* [v1alpha1](v1alpha1/README.md)
* [v1beta1](v1beta1/README.md)
## Implementation

View File

@ -0,0 +1,21 @@
# source.toolkit.fluxcd.io/v1beta1
This is the v1beta1 API specification for defining the desired state sources of Kubernetes clusters.
## Specification
* [Common](common.md)
* Source kinds:
+ [GitRepository](gitrepositories.md)
+ [HelmRepository](helmrepositories.md)
+ [HelmChart](helmcharts.md)
+ [Bucket](buckets.md)
## Implementation
* [source-controller](https://github.com/fluxcd/source-controller/)
## Consumers
* [kustomize-controller](https://github.com/fluxcd/kustomize-controller/)
* [helm-controller](https://github.com/fluxcd/helm-controller/)

View File

@ -0,0 +1,234 @@
# Object storage buckets
The `Bucket` API defines a source for artifacts coming from S3 compatible storage
such as Minio, Amazon S3, Google Cloud Storage, Alibaba Cloud OSS and others.
## Specification
Bucket:
```go
// BucketSpec defines the desired state of an S3 compatible bucket
type BucketSpec struct {
// The S3 compatible storage provider name, default ('generic').
// +kubebuilder:validation:Enum=generic;aws
// +optional
Provider string `json:"provider,omitempty"`
// The bucket name.
// +required
BucketName string `json:"bucketName"`
// The bucket endpoint address.
// +required
Endpoint string `json:"endpoint"`
// Insecure allows connecting to a non-TLS S3 HTTP endpoint.
// +optional
Insecure bool `json:"insecure,omitempty"`
// The bucket region.
// +optional
Region string `json:"region,omitempty"`
// The name of the secret containing authentication credentials
// for the Bucket.
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
// The interval at which to check for bucket updates.
// +required
Interval metav1.Duration `json:"interval"`
// The timeout for download operations, default ('20s').
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Ignore overrides the set of excluded patterns in the .sourceignore format
// (which is the same as .gitignore).
// +optional
Ignore *string `json:"ignore,omitempty"`
}
```
Supported providers:
```go
const (
GenericBucketProvider string = "generic"
AmazonBucketProvider string = "aws"
)
```
### Status
```go
// BucketStatus defines the observed state of a bucket
type BucketStatus struct {
// ObservedGeneration is the last observed generation.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// Conditions holds the conditions for the Bucket.
// +optional
Conditions []meta.Condition `json:"conditions,omitempty"`
// URL is the download link for the artifact output of the last Bucket sync.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful Bucket sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
}
```
### Condition reasons
```go
const (
// BucketOperationSucceedReason represents the fact that the bucket listing and
// download operations succeeded.
BucketOperationSucceedReason string = "BucketOperationSucceed"
// BucketOperationFailedReason represents the fact that the bucket listing or
// download operations failed.
BucketOperationFailedReason string = "BucketOperationFailed"
)
```
## Artifact
The resource exposes the latest synchronized state from S3 as an artifact
in a gzip compressed TAR archive (`<bucket checksum>.tar.gz`).
### Excluding files
Git files (`.git/`, `.gitignore`, `.gitmodules`, and `.gitattributes`) are
excluded from the archive by default, as well as some extensions (`.jpg, .jpeg,
.gif, .png, .wmv, .flv, .tar.gz, .zip`)
Excluding additional files from the archive is possible by adding a
`.sourceignore` file in the root of the bucket. The `.sourceignore` file
follows [the `.gitignore` pattern
format](https://git-scm.com/docs/gitignore#_pattern_format), pattern
entries may overrule default exclusions.
Another option is to use the `spec.ignore` field, for example:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: podinfo
spec:
ignore: |
# exclude all
/*
# include deploy dir
!/deploy
# exclude file extensions from deploy dir
/deploy/**/*.md
/deploy/**/*.txt
```
When specified, `spec.ignore` overrides the default exclusion list.
## Spec examples
### Static authentication
Authentication credentials can be provided with a Kubernetes secret that contains
`accesskey` and `secretkey` fields:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: podinfo
namespace: gitops-system
spec:
interval: 1m
provider: generic
bucketName: podinfo
endpoint: minio.minio.svc.cluster.local:9000
insecure: true
secretRef:
name: minio-credentials
---
apiVersion: v1
kind: Secret
metadata:
name: minio-credentials
namespace: gitops-system
type: Opaque
data:
accesskey: <BASE64>
secretkey: <BASE64>
```
> **Note:** that for Google Cloud Storage you have to enable
> S3 compatible access in your GCP project.
### AWS IAM authentication
When the provider is `aws` and the `secretRef` is not specified,
the credentials are retrieve from the EC2 service:
```yaml
apiVersion: source.toolkit.fluccd.io/v1beta1
kind: Bucket
metadata:
name: podinfo
namespace: gitops-system
spec:
interval: 5m
provider: aws
bucketName: podinfo
endpoint: s3.amazonaws.com
region: us-east-1
timeout: 30s
```
> **Note:** that on EKS you have to create an IAM role for the source-controller
> service account that grants access to the bucket.
## Status examples
Successful download:
```yaml
status:
artifact:
checksum: b249024b8544521792a079c4037d0a06dd0497a9
lastUpdateTime: "2020-09-18T08:34:49Z"
path: bucket/gitops-system/podinfo/aeaba8b6dd51c53084f99b098cfae4f5148ad410.tar.gz
revision: aeaba8b6dd51c53084f99b098cfae4f5148ad410
url: http://localhost:9090/bucket/gitops-system/podinfo/aeaba8b6dd51c53084f99b098cfae4f5148ad410.tar.gz
conditions:
- lastTransitionTime: "2020-09-18T08:34:49Z"
message: 'Fetched revision: aeaba8b6dd51c53084f99b098cfae4f5148ad410'
reason: BucketOperationSucceed
status: "True"
type: Ready
observedGeneration: 2
url: http://localhost:9090/bucket/gitops-system/podinfo/latest.tar.gz
```
Failed download:
```yaml
status:
conditions:
- lastTransitionTime: "2020-09-18T08:34:49Z"
message: "bucket 'test' not found"
reason: BucketOperationFailed
status: "False"
type: Ready
```
Wait for ready condition:
```bash
kubectl -n gitios-system wait bucket/podinfo --for=condition=ready --timeout=1m
```

114
docs/spec/v1beta1/common.md Normal file
View File

@ -0,0 +1,114 @@
# Common
Common defines resources used across all source types.
## Specification
### Source interface
Source objects should adhere to the `Source` interface. This interface exposes the [interval](#source-synchronization)
and [artifact](#source-status) of the source to clients without the prerequisite of knowing the source kind:
````go
type Source interface {
// GetInterval returns the interval at which the source is updated.
GetInterval() metav1.Duration
// GetArtifact returns the latest artifact from the source, or nil.
GetArtifact() *Artifact
}
````
### Source reconciliation
Source objects should contain a `spec.interval` field that tells the controller at which interval to check for updates:
```go
type SourceSpec struct {
// The interval at which to check for source updates.
// +required
Interval metav1.Duration `json:"interval"`
}
```
Valid time units are `s`, `m` and `h` e.g. `interval: 5m`.
The controller can be told to check for updates right away by setting an annotation on source objects:
```bash
kubectl annotate --overwrite gitrepository/podinfo fluxcd.io/reconcileAt="$(date +%s)"
```
### Source status
Source objects should contain a status sub-resource that embeds an artifact object:
```go
// Artifact represents the output of a source synchronisation.
type Artifact struct {
// Path is the relative file path of this artifact.
// +required
Path string `json:"path"`
// URL is the HTTP address of this artifact.
// +required
URL string `json:"url"`
// Revision is a human readable identifier traceable in the origin
// source system. It can be a Git commit sha, Git tag, a Helm index
// timestamp, a Helm chart version, etc.
// +optional
Revision string `json:"revision"`
// Checksum is the SHA1 checksum of the artifact.
// +optional
Checksum string `json:"checksum"`
// LastUpdateTime is the timestamp corresponding to the last
// update of this artifact.
// +required
LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"`
}
```
### Source condition
> **Note:** to be replaced with <https://github.com/kubernetes/enhancements/pull/1624>
> once made available.
Source objects should implement the [`meta.Condition`](https://godoc.org/github.com/fluxcd/pkg/apis/meta#Condition).
#### Types
Source objects should implement the [`meta.ReadyCondition`](https://godoc.org/github.com/fluxcd/pkg/apis/meta#pkg-constants),
but may implement additional domain-specific types.
#### Reasons
Source objects may implement the [`meta` condition
reasons](https://godoc.org/github.com/fluxcd/pkg/apis/meta#pkg-constants), but
are allowed to use their own reasons if they provide a better explanation.
In addition, the following source specific reasons are available:
```go
const (
// URLInvalidReason represents the fact that a given source has an invalid URL.
URLInvalidReason string = "URLInvalid"
// StorageOperationFailedReason signals a failure caused by a storage operation.
StorageOperationFailedReason string = "StorageOperationFailed"
// AuthenticationFailedReason represents the fact that a given secret does not
// have the required fields or the provided credentials do not match.
AuthenticationFailedReason string = "AuthenticationFailed"
// VerificationFailedReason represents the fact that the cryptographic provenance
// verification for the source failed.
VerificationFailedReason string = "VerificationFailed"
)
```
## Examples
See the [`GitRepository`](gitrepositories.md) and [`HelmChart`](helmcharts.md) APIs.

View File

@ -0,0 +1,394 @@
# Git Repositories
The `GitRepository` API defines a source for artifacts coming from Git. The
resource exposes the latest synchronized state from Git as an artifact in a
[gzip compressed TAR archive](#artifact).
## Specification
Git repository:
```go
// GitRepositorySpec defines the desired state of a Git repository.
type GitRepositorySpec struct {
// The repository URL, can be a HTTP or SSH address.
// +kubebuilder:validation:Pattern="^(http|https|ssh)://"
// +required
URL string `json:"url"`
// The secret name containing the Git credentials.
// For HTTPS repositories the secret must contain username and password
// fields.
// For SSH repositories the secret must contain identity, identity.pub and
// known_hosts fields.
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
// The interval at which to check for repository updates.
// +required
Interval metav1.Duration `json:"interval"`
// The timeout for remote git operations like cloning, default to 20s.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// The git reference to checkout and monitor for changes, defaults to
// master branch.
// +optional
Reference *GitRepositoryRef `json:"ref,omitempty"`
// Verify OpenPGP signature for the commit that HEAD points to.
// +optional
Verification *GitRepositoryVerification `json:"verify,omitempty"`
// Ignore overrides the set of excluded patterns in the .sourceignore format
// (which is the same as .gitignore). If not provided, a default will be used,
// consult the documentation for your version to find out what those are.
// +optional
Ignore *string `json:"ignore,omitempty"`
}
```
Git repository reference:
```go
// 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,omitempty"`
// The git tag to checkout, takes precedence over branch.
// +optional
Tag string `json:"tag,omitempty"`
// The git tag semver expression, takes precedence over tag.
// +optional
SemVer string `json:"semver,omitempty"`
// The git commit sha to checkout, if specified tag filters will be ignored.
// +optional
Commit string `json:"commit,omitempty"`
}
```
Git repository cryptographic provenance verification:
```go
// GitRepositoryVerification defines the OpenPGP signature verification process.
type GitRepositoryVerification struct {
// Mode describes what git object should be verified, currently ('head').
// +kubebuilder:validation:Enum=head
Mode string `json:"mode"`
// The secret name containing the public keys of all trusted git authors.
SecretRef corev1.LocalObjectReference `json:"secretRef"`
}
```
### Status
```go
// GitRepositoryStatus defines the observed state of the GitRepository.
type GitRepositoryStatus struct {
// +optional
Conditions []meta.Condition `json:"conditions,omitempty"`
// URL is the download link for the artifact output of the last repository
// sync.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful repository sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
}
```
### Condition reasons
```go
const (
// GitOperationSucceedReason represents the fact that the git
// clone, pull and checkout operations succeeded.
GitOperationSucceedReason string = "GitOperationSucceed"
// GitOperationFailedReason represents the fact that the git
// clone, pull or checkout operations failed.
GitOperationFailedReason string = "GitOperationFailed"
)
```
## Artifact
The `GitRepository` API defines a source for artifacts coming from Git. The
resource exposes the latest synchronized state from Git as an artifact in a
gzip compressed TAR archive (`<commit hash>.tar.gz`).
### Excluding files
Git files (`.git/`, `.gitignore`, `.gitmodules`, and `.gitattributes`) are
excluded from the archive by default, as well as some extensions (`.jpg, .jpeg,
.gif, .png, .wmv, .flv, .tar.gz, .zip`)
Excluding additional files from the archive is possible by adding a
`.sourceignore` file in the root of the repository. The `.sourceignore` file
follows [the `.gitignore` pattern
format](https://git-scm.com/docs/gitignore#_pattern_format), pattern
entries may overrule default exclusions.
Another option is to use the `spec.ignore` field, for example:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ignore: |
# exclude all
/*
# include deploy dir
!/deploy
# exclude file extensions from deploy dir
/deploy/**/*.md
/deploy/**/*.txt
```
When specified, `spec.ignore` overrides the default exclusion list.
## Spec examples
### Checkout strategies
Pull the master branch of a public repository every minute:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
```
Pull a specific branch:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
branch: v3.x
```
Checkout a specific commit from a branch:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
commit: 363a6a8fe6a7f13e05d34c163b0ef02a777da20a
```
Pull a specific tag:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
tag: 3.2.0
```
Pull tag based on a [semver range](https://github.com/blang/semver#ranges):
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
semver: ">=3.1.0-rc.1 <3.2.0"
```
### HTTPS authentication
HTTPS authentication requires a Kubernetes secret with `username` and `password` fields:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
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>
```
> **Note:** that self-signed certificates are not supported.
### SSH authentication
SSH authentication requires a Kubernetes secret with `identity` and `known_hosts` fields:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
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>
known_hosts: <BASE64>
```
> **Note:** that the SSH address does not support SCP syntax. The URL format is
> `ssh://user@host:port/org/repository`.
Example of generating the SSH credentials secret:
```bash
ssh-keygen -q -N "" -f ./identity
ssh-keyscan github.com > ./known_hosts
kubectl create secret generic ssh-credentials \
--from-file=./identity \
--from-file=./identity.pub \
--from-file=./known_hosts
```
### GPG signature verification
Verify the OpenPGP signature for the commit that master branch HEAD points to:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
spec:
interval: 1m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
verify:
mode: head
secretRef:
name: pgp-public-keys
---
apiVersion: v1
kind: Secret
metadata:
name: pgp-public-keys
namespace: default
type: Opaque
data:
author1.asc: <BASE64>
author2.asc: <BASE64>
```
Example of generating the PGP public keys secret:
```bash
gpg --export --armor 3CB12BA185C47B67 > author1.asc
gpg --export --armor 6A7436E8790F8689 > author2.asc
kubectl create secret generic pgp-public-keys \
--from-file=author1.asc \
--from-file=author2.asc
```
## Status examples
Successful sync:
```yaml
status:
artifact:
lastUpdateTime: "2020-04-07T06:59:23Z"
path: /data/gitrepository/default/podinfo/363a6a8fe6a7f13e05d34c163b0ef02a777da20a.tar.gz
revision: master/363a6a8fe6a7f13e05d34c163b0ef02a777da20a
url: http://<host>/gitrepository/default/podinfo/363a6a8fe6a7f13e05d34c163b0ef02a777da20a.tar.gz
conditions:
- lastTransitionTime: "2020-04-07T06:59:23Z"
message: 'Git repoistory artifacts are available at:
/data/gitrepository/default/podinfo/363a6a8fe6a7f13e05d34c163b0ef02a777da20a.tar.gz'
reason: GitOperationSucceed
status: "True"
type: Ready
url: http://<host>/gitrepository/default/podinfo/latest.tar.gz
```
Failed authentication:
```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: AuthenticationFailed
status: "False"
type: Ready
```
Failed PGP signature verification:
```yaml
status:
conditions:
- lastTransitionTime: "2020-04-06T06:48:59Z"
message: 'PGP signature of {Stefan Prodan 2020-04-04 13:36:58 +0300 +0300} can not be verified'
reason: VerificationFailed
status: "False"
type: Ready
```
Wait for ready condition:
```bash
kubectl wait gitrepository/podinfo --for=condition=ready --timeout=1m
```

View File

@ -0,0 +1,197 @@
# Helm Charts
The `HelmChart` API defines a source for Helm chart artifacts coming
from [`HelmRepository` sources](helmrepositories.md). The resource
exposes the latest pulled or packaged chart as an artifact.
## Specification
Helm chart:
```go
// HelmChartSpec defines the desired state of a Helm chart.
type HelmChartSpec struct {
// The name or path the Helm chart is available at in the SourceRef.
// +required
Chart string `json:"chart"`
// The chart version semver expression, ignored for charts from GitRepository
// and Bucket sources. Defaults to latest when omitted.
// +optional
Version string `json:"version,omitempty"`
// The reference to the Source the chart is available at.
// +required
SourceRef LocalHelmChartSourceReference `json:"sourceRef"`
// The interval at which to check the Source for updates.
// +required
Interval metav1.Duration `json:"interval"`
// Alternative values file to use as the default chart values, expected to be a
// relative path in the SourceRef. Ignored when omitted.
// +optional
ValuesFile string `json:"valuesFile,omitempty"`
}
```
### Reference types
```go
// LocalHelmChartSourceReference contains enough information to let you locate
// the typed referenced object at namespace level.
type LocalHelmChartSourceReference struct {
// APIVersion of the referent.
// +optional
APIVersion string `json:"apiVersion,omitempty"`
// Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
// 'Bucket').
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket
// +required
Kind string `json:"kind"`
// Name of the referent.
// +required
Name string `json:"name"`
}
```
### Status
```go
// HelmChartStatus defines the observed state of the HelmChart.
type HelmChartStatus struct {
// +optional
Conditions []meta.Condition `json:"conditions,omitempty"`
// URL is the download link for the last chart fetched.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful chart sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
}
```
### Condition reasons
```go
const (
// ChartPullFailedReason represents the fact that the pull of the Helm chart
// failed.
ChartPullFailedReason string = "ChartPullFailed"
// ChartPullSucceededReason represents the fact that the pull of the Helm chart
// succeeded.
ChartPullSucceededReason string = "ChartPullSucceeded"
// ChartPackageFailedReason represent the fact that the package of the Helm
// chart failed.
ChartPackageFailedReason string = "ChartPackageFailed"
// ChartPackageSucceededReason represents the fact that the package of the Helm
// chart succeeded.
ChartPackageSucceededReason string = "ChartPackageSucceeded"
)
```
## Spec examples
Pull a specific chart version every five minutes:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: redis
spec:
chart: redis
version: 10.5.7
sourceRef:
name: stable
kind: HelmRepository
interval: 5m
```
Pull the latest chart version that matches the semver range every ten minutes:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: redis
spec:
chart: redis
version: 10.5.x
sourceRef:
name: stable
kind: HelmRepository
interval: 10m
```
Check a Git repository every ten minutes for a new `version` in the
`Chart.yaml`, and package a new chart if the revision differs:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: podinfo
spec:
chart: ./charts/podinfo
sourceRef:
name: podinfo
kind: GitRepository
interval: 10m
```
Check a S3 compatible bucket every ten minutes for a new `version` in the
`Chart.yaml`, and package a new chart if the revision differs:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmChart
metadata:
name: podinfo
spec:
chart: ./podinfo
sourceRef:
name: charts
kind: Bucket
interval: 10m
```
## Status examples
Successful chart pull:
```yaml
status:
url: http://<host>/helmchart/default/redis/redis-10.5.7.tgz
conditions:
- lastTransitionTime: "2020-04-10T09:34:45Z"
message: Helm chart is available at /data/helmchart/default/redis/redis-10.5.7.tgz
reason: ChartPullSucceeded
status: "True"
type: Ready
```
Failed chart pull:
```yaml
status:
conditions:
- lastTransitionTime: "2020-04-10T09:34:45Z"
message: 'invalid chart URL format'
reason: ChartPullFailed
status: "False"
type: Ready
```
Wait for ready condition:
```bash
kubectl wait helmchart/redis --for=condition=ready --timeout=1m
```

View File

@ -0,0 +1,153 @@
# Helm Repositories
The `HelmRepository` API defines a source for Helm repositories.
The resource exposes the latest synchronized repository index as
an artifact.
## Specification
Helm repository:
```go
// HelmRepositorySpec defines the reference to a Helm repository.
type HelmRepositorySpec struct {
// The Helm repository URL, a valid URL contains at least a protocol and host.
// +required
URL string `json:"url"`
// The name of the secret containing authentication credentials for the Helm
// repository.
// For HTTP/S basic auth the secret must contain username and
// password fields.
// For TLS the secret must contain caFile, keyFile and caCert
// fields.
// +optional
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
// The interval at which to check the upstream for updates.
// +required
Interval metav1.Duration `json:"interval"`
// The timeout of index downloading, defaults to 60s.
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
}
```
### Status
```go
// HelmRepositoryStatus defines the observed state of the HelmRepository.
type HelmRepositoryStatus struct {
// +optional
Conditions []meta.Condition `json:"conditions,omitempty"`
// URL is the download link for the last index fetched.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful repository sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
}
```
### Condition reasons
```go
const (
// IndexationFailedReason represents the fact that the indexation of the given
// Helm repository failed.
IndexationFailedReason string = "IndexationFailed"
// IndexationSucceededReason represents the fact that the indexation of the
// given Helm repository succeeded.
IndexationSucceededReason string = "IndexationSucceed"
)
```
## Spec examples
Pull the index of a public Helm repository every ten minutes:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: stable
spec:
url: https://kubernetes-charts.storage.googleapis.com/
interval: 10m
```
Pull the index of a private Helm repository every minute:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: private
spec:
url: https://charts.example.com
secretRef:
name: https-credentials
interval: 1m
---
apiVersion: v1
kind: Secret
metadata:
name: https-credentials
namespace: default
type: Opaque
data:
username: <BASE64>
password: <BASE64>
certFile: <BASE64>
keyFile: <BASE64>
caFile: <BASE64>
```
## Status examples
Successful indexation:
```yaml
status:
url: http://<host>/helmrepository/default/stable/index.yaml
conditions:
- lastTransitionTime: "2020-04-10T09:34:45Z"
message: Helm repository index is available at /data/helmrepository/default/stable/index-21c195d78e699e4b656e2885887d019627838993.yaml
reason: IndexationSucceeded
status: "True"
type: Ready
```
Failed indexation:
```yaml
status:
conditions:
- lastTransitionTime: "2020-04-10T09:27:21Z"
message: 'failed to fetch https://invalid.example.com/index.yaml : 404 Not Found'
reason: IndexationFailed
status: "False"
type: Ready
```
Invalid repository URL:
```yaml
status:
conditions:
- lastTransitionTime: "2020-04-10T09:27:21Z"
message: scheme "invalid" not supported
reason: URLInvalid
status: "False"
type: Ready
```
Wait for ready condition:
```bash
kubectl wait helmrepository/stable --for=condition=ready --timeout=1m
```

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/fluxcd/source-controller
go 1.14
go 1.15
replace github.com/fluxcd/source-controller/api => ./api

View File

@ -36,7 +36,7 @@ import (
"github.com/fluxcd/pkg/recorder"
"github.com/fluxcd/pkg/runtime/logger"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/fluxcd/source-controller/controllers"
// +kubebuilder:scaffold:imports
)
@ -239,11 +239,11 @@ func mustInitStorage(path string, storageAddr string, l logr.Logger) *controller
return storage
}
func envOrDefault(envName, dflt string) string {
func envOrDefault(envName, defaultValue string) string {
ret := os.Getenv(envName)
if ret != "" {
return ret
}
return dflt
return defaultValue
}

View File

@ -26,7 +26,7 @@ import (
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
)
const (