1
0
mirror of synced 2026-03-01 19:26:55 +00:00

Compare commits

..

19 Commits

Author SHA1 Message Date
Stefan Prodan
3f98affd5a Merge pull request #223 from fluxcd/update-components
Update toolkit components
2020-09-12 12:11:32 +03:00
stefanprodan
531c2bcf00 Import fluxcd/pkg/runtime 2020-09-12 12:04:37 +03:00
fluxcdbot
dd5505918a Update toolkit components 2020-09-12 08:54:22 +00:00
Stefan Prodan
4a30a69eb4 Merge pull request #226 from fluxcd/bot-pr
Use fluxcdbot token in CI
2020-09-12 11:51:31 +03:00
stefanprodan
38b302e5a5 Use fluxcdbot token in CI 2020-09-12 11:44:41 +03:00
Hidde Beydals
ea010895a0 docs: update Helm roadmap 2020-09-11 15:31:15 +02:00
Stefan Prodan
7b88512698 Merge pull request #222 from fluxcd/rbac-patch-events
Add PATCH rule to crd-controller role for events
2020-09-11 09:21:50 +03:00
Hidde Beydals
1ff24d9285 Add PATCH rule to crd-controller role for events
During high custom resource count / low interval tests, I was greated
with a `cannot patch resource "events"` message. This happened due to
event compaction, where it will perform a patch instead of a create.
By giving the role the permission to do so this should no longer pose
a problem.
2020-09-10 20:57:59 +02:00
Stefan Prodan
ebf742d272 Merge pull request #219 from fluxcd/bootstrap-branch
Add branch flag to bootstrap cmd
2020-09-09 17:59:30 +03:00
stefanprodan
a7b1b04920 Add bootstrap reinstall e2e test 2020-09-09 17:27:56 +03:00
stefanprodan
1218d6abe8 Add branch flag to bootstrap cmd 2020-09-09 16:41:48 +03:00
Stefan Prodan
f9d546676b Merge pull request #218 from fluxcd/refac
Add GitHub bootstrap e2e test
2020-09-09 14:15:33 +03:00
stefanprodan
afef6960b9 Cleanup GitHub e2e repo 2020-09-09 14:03:26 +03:00
stefanprodan
f6626b8975 Add GitHub bootstrap e2e test 2020-09-09 08:56:55 +03:00
stefanprodan
b1e66f81ab Add label validation 2020-09-08 20:08:28 +03:00
Stefan Prodan
9cc018e618 Merge pull request #216 from fluxcd/labels
Add label arg to create commands
2020-09-08 18:14:31 +03:00
stefanprodan
797cd9bea2 Add label arg to create commands 2020-09-08 18:03:04 +03:00
Hidde Beydals
9dbfca3d7a Merge pull request #212 from fluxcd/refactor-hr-source-kind-validation
Refactor HelmRelease chart source kind validation
2020-09-07 12:02:34 +02:00
Hidde Beydals
f18d1efdcb Refactor HelmRelease chart source kind validation 2020-09-07 11:13:15 +02:00
37 changed files with 323 additions and 126 deletions

74
.github/workflows/bootstrap.yaml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: bootstrap
on:
push:
branches:
- '*'
jobs:
github:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Restore Go cache
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.14.x
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.4.0
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Build
run: sudo go build -o ./bin/gotk ./cmd/gotk
- name: bootstrap init
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: bootstrap no-op
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: uninstall
run: |
./bin/gotk suspend kustomization gitops-system
./bin/gotk uninstall --resources --crds -s
- name: bootstrap reinstall
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: delete repository
run: |
./bin/gotk bootstrap github \
--owner=fluxcd-testing \
--repository=gotk-test-${{ steps.vars.outputs.sha_short }} \
--path=test-cluster \
--delete
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: Debug failure
if: failure()
run: |
kubectl -n gitops-system get all
kubectl -n gitops-system logs deploy/source-controller
kubectl -n gitops-system logs deploy/kustomize-controller

View File

@@ -54,10 +54,10 @@ jobs:
id: cpr
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ secrets.BOT_GITHUB_TOKEN }}
commit-message: Update toolkit components
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
author: fluxcdbot <fluxcdbot@users.noreply.github.com>
title: Update toolkit components
body: |
${{ steps.update.outputs.pr_body }}

View File

@@ -50,10 +50,11 @@ var (
bootstrapRegistry string
bootstrapImagePullSecret string
bootstrapArch string
bootstrapBranch string
)
const (
bootstrapBranch = "master"
bootstrapDefaultBranch = "master"
bootstrapInstallManifest = "toolkit-components.yaml"
bootstrapSourceManifest = "toolkit-source.yaml"
bootstrapKustomizationManifest = "toolkit-kustomization.yaml"
@@ -70,6 +71,8 @@ func init() {
"Kubernetes secret name used for pulling the toolkit images from a private registry")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapArch, "arch", "amd64",
"arch can be amd64 or arm64")
bootstrapCmd.PersistentFlags().StringVar(&bootstrapBranch, "branch", bootstrapDefaultBranch,
"default branch (for GitHub this must match the default branch setting for the organization)")
rootCmd.AddCommand(bootstrapCmd)
}
@@ -114,8 +117,8 @@ func applyInstallManifests(ctx context.Context, manifestPath string, components
return nil
}
func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, interval time.Duration) error {
gvk := sourcev1.GroupVersion.WithKind("GitRepository")
func generateSyncManifests(url, branch, name, namespace, targetPath, tmpDir string, interval time.Duration) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.GitRepositoryKind)
gitRepository := sourcev1.GitRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
@@ -131,7 +134,7 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
Duration: interval,
},
Reference: &sourcev1.GitRepositoryRef{
Branch: "master",
Branch: branch,
},
SecretRef: &corev1.LocalObjectReference{
Name: name,
@@ -148,7 +151,7 @@ func generateSyncManifests(url, name, namespace, targetPath, tmpDir string, inte
return err
}
gvk = kustomizev1.GroupVersion.WithKind("Kustomization")
gvk = kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)
kustomization := kustomizev1.Kustomization{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,

View File

@@ -55,6 +55,9 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a private repo hosted on GitHub Enterprise
gotk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap github --owner=<organization> --repository=<repo name> --branch=main
`,
RunE: bootstrapGitHubCmdRun,
}
@@ -68,6 +71,7 @@ var (
ghHostname string
ghPath string
ghTeams []string
ghDelete bool
)
const (
@@ -84,6 +88,9 @@ func init() {
bootstrapGitHubCmd.Flags().StringVar(&ghHostname, "hostname", git.GitHubDefaultHostname, "GitHub hostname")
bootstrapGitHubCmd.Flags().StringVar(&ghPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path")
bootstrapGitHubCmd.Flags().BoolVar(&ghDelete, "delete", false, "delete repository (used for testing only)")
bootstrapGitHubCmd.Flags().MarkHidden("delete")
bootstrapCmd.AddCommand(bootstrapGitHubCmd)
}
@@ -107,11 +114,6 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
IsPersonal: ghPersonal,
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", namespace)
if err != nil {
return err
@@ -121,6 +123,14 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
if ghDelete {
if err := provider.DeleteRepository(ctx, repository); err != nil {
return err
}
logger.Successf("repository deleted")
return nil
}
// create GitHub repository if doesn't exists
logger.Actionf("connecting to %s", ghHostname)
changed, err := provider.CreateRepository(ctx, repository)
@@ -173,6 +183,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
logger.Successf("components are up to date")
}
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
// determine if repo synchronization is working
isInstall := shouldInstallManifests(ctx, kubeClient, namespace)
@@ -211,22 +226,19 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, namespace, namespace, ghPath, tmpDir, ghInterval); err != nil {
return err
}
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(ghPath, namespace), "Add manifests"); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
logger.Successf("sync manifests pushed")
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")

View File

@@ -52,6 +52,9 @@ the bootstrap command will perform an upgrade if needed.`,
# Run bootstrap for a private repo hosted on a GitLab server
gotk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
`,
RunE: bootstrapGitLabCmdRun,
}
@@ -195,22 +198,19 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
}
// configure repo synchronization
if isInstall {
// generate source and kustomization manifests
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), namespace, namespace, glPath, tmpDir, glInterval); err != nil {
return err
}
logger.Actionf("generating sync manifests")
if err := generateSyncManifests(repository.GetSSH(), bootstrapBranch, namespace, namespace, glPath, tmpDir, glInterval); err != nil {
return err
}
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(glPath, namespace), "Add manifests"); err != nil {
// commit and push manifests
if changed, err = repository.Commit(ctx, path.Join(glPath, namespace), "Add manifests"); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
} else if changed {
if err := repository.Push(ctx); err != nil {
return err
}
logger.Successf("sync manifests pushed")
}
logger.Successf("sync manifests pushed")
// apply manifests and waiting for sync
logger.Actionf("applying sync manifests")

View File

@@ -17,8 +17,12 @@ limitations under the License.
package main
import (
"fmt"
"strings"
"time"
"k8s.io/apimachinery/pkg/util/validation"
"github.com/spf13/cobra"
)
@@ -31,10 +35,38 @@ var createCmd = &cobra.Command{
var (
interval time.Duration
export bool
labels []string
)
func init() {
createCmd.PersistentFlags().DurationVarP(&interval, "interval", "", time.Minute, "source sync interval")
createCmd.PersistentFlags().BoolVar(&export, "export", false, "export in YAML format to stdout")
createCmd.PersistentFlags().StringSliceVar(&labels, "label", nil,
"set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)")
rootCmd.AddCommand(createCmd)
}
func parseLabels() (map[string]string, error) {
result := make(map[string]string)
for _, label := range labels {
// validate key value pair
parts := strings.Split(label, "=")
if len(parts) != 2 {
return nil, fmt.Errorf("invalid label format '%s', must be key=value", label)
}
// validate label name
if errors := validation.IsQualifiedName(parts[0]); len(errors) > 0 {
return nil, fmt.Errorf("invalid label '%s': %v", parts[0], errors)
}
// validate label value
if errors := validation.IsValidLabelValue(parts[1]); len(errors) > 0 {
return nil, fmt.Errorf("invalid label value '%s': %v", parts[1], errors)
}
result[parts[0]] = parts[1]
}
return result, nil
}

View File

@@ -115,20 +115,18 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
}
hrSourceElements := strings.Split(hrSource, "/")
if len(hrSourceElements) != 2 {
return fmt.Errorf("source must be in format <kind>/<name>")
return fmt.Errorf("invalid source '%s', must be in format <kind>/<name>", hrSource)
}
hrSourceKind, hrSourceName := hrSourceElements[0], hrSourceElements[1]
if hrSourceKind != sourcev1.HelmRepositoryKind && hrSourceKind != sourcev1.GitRepositoryKind {
return fmt.Errorf("source kind must be one of: %s", []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind})
if !utils.containsItemString(supportedHelmChartSourceKinds, hrSourceKind) {
return fmt.Errorf("source kind %s is not supported, can be %v",
hrSourceKind, supportedHelmChartSourceKinds)
}
if hrChart == "" {
return fmt.Errorf("chart name or path is required")
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
kubeClient, err := utils.kubeClient(kubeconfig)
sourceLabels, err := parseLabels()
if err != nil {
return err
}
@@ -141,6 +139,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: helmv2.HelmReleaseSpec{
ReleaseName: hrName,
@@ -181,6 +180,14 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
return exportHelmRelease(helmRelease)
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
kubeClient, err := utils.kubeClient(kubeconfig)
if err != nil {
return err
}
logger.Actionf("applying release")
if err := upsertHelmRelease(ctx, kubeClient, helmRelease); err != nil {
return err
@@ -237,6 +244,7 @@ func upsertHelmRelease(ctx context.Context, kubeClient client.Client, helmReleas
return err
}
existing.Labels = helmRelease.Labels
existing.Spec = helmRelease.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -121,10 +121,16 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
logger.Generatef("generating kustomization")
}
ksLabels, err := parseLabels()
if err != nil {
return err
}
kustomization := kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: ksLabels,
},
Spec: kustomizev1.KustomizationSpec{
DependsOn: ksDependsOn,
@@ -260,6 +266,7 @@ func upsertKustomization(ctx context.Context, kubeClient client.Client, kustomiz
return err
}
existing.Labels = kustomization.Labels
existing.Spec = kustomization.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -129,10 +129,16 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("git URL parse failed: %w", err)
}
sourceLabels, err := parseLabels()
if err != nil {
return err
}
gitRepository := sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: sourcev1.GitRepositorySpec{
URL: sourceGitURL,
@@ -343,6 +349,7 @@ func upsertGitRepository(ctx context.Context, kubeClient client.Client, gitRepos
return err
}
existing.Labels = gitRepository.Labels
existing.Spec = gitRepository.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err

View File

@@ -19,18 +19,19 @@ package main
import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
"io/ioutil"
"net/url"
"os"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"net/url"
"os"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var createSourceHelmCmd = &cobra.Command{
@@ -91,6 +92,11 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("url is required")
}
sourceLabels, err := parseLabels()
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", name)
if err != nil {
return err
@@ -105,6 +111,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: sourceLabels,
},
Spec: sourcev1.HelmRepositorySpec{
URL: sourceHelmURL,
@@ -225,6 +232,7 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client, helmRep
return err
}
existing.Labels = helmRepository.Labels
existing.Spec = helmRepository.Spec
if err := kubeClient.Update(ctx, &existing); err != nil {
return err
@@ -233,27 +241,3 @@ func upsertHelmRepository(ctx context.Context, kubeClient client.Client, helmRep
logger.Successf("source updated")
return nil
}
func exportHelmRepository(source sourcev1.HelmRepository) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)
export := sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
},
Spec: source.Spec,
}
data, err := yaml.Marshal(export)
if err != nil {
return err
}
fmt.Println("---")
fmt.Println(string(data))
return nil
}

View File

@@ -68,7 +68,7 @@ func exportHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
}
if len(list.Items) == 0 {
logger.Failuref("no kustomizations found in %s namespace", namespace)
logger.Failuref("no helmrelease found in %s namespace", namespace)
return nil
}
@@ -101,8 +101,10 @@ func exportHelmRelease(helmRelease helmv2.HelmRelease) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: helmRelease.Name,
Namespace: helmRelease.Namespace,
Name: helmRelease.Name,
Namespace: helmRelease.Namespace,
Labels: helmRelease.Labels,
Annotations: helmRelease.Annotations,
},
Spec: helmRelease.Spec,
}

View File

@@ -20,12 +20,13 @@ import (
"context"
"fmt"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
)
var exportKsCmd = &cobra.Command{
@@ -100,8 +101,10 @@ func exportKs(kustomization kustomizev1.Kustomization) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: kustomization.Name,
Namespace: kustomization.Namespace,
Name: kustomization.Name,
Namespace: kustomization.Namespace,
Labels: kustomization.Labels,
Annotations: kustomization.Annotations,
},
Spec: kustomization.Spec,
}

View File

@@ -20,13 +20,14 @@ import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var exportSourceGitCmd = &cobra.Command{
@@ -110,8 +111,10 @@ func exportGit(source sourcev1.GitRepository) error {
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
Name: source.Name,
Namespace: source.Namespace,
Labels: source.Labels,
Annotations: source.Annotations,
},
Spec: source.Spec,
}

View File

@@ -20,13 +20,14 @@ import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var exportSourceHelmCmd = &cobra.Command{
@@ -102,6 +103,32 @@ func exportSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
return nil
}
func exportHelmRepository(source sourcev1.HelmRepository) error {
gvk := sourcev1.GroupVersion.WithKind(sourcev1.HelmRepositoryKind)
export := sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: gvk.Kind,
APIVersion: gvk.GroupVersion().String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: source.Name,
Namespace: source.Namespace,
Labels: source.Labels,
Annotations: source.Annotations,
},
Spec: source.Spec,
}
data, err := yaml.Marshal(export)
if err != nil {
return err
}
fmt.Println("---")
fmt.Println(string(data))
return nil
}
func exportHelmCredentials(ctx context.Context, kubeClient client.Client, source sourcev1.HelmRepository) error {
if source.Spec.SecretRef != nil {
namespacedName := types.NamespacedName{

View File

@@ -26,6 +26,8 @@ import (
"github.com/spf13/cobra/doc"
_ "k8s.io/client-go/plugin/pkg/client/auth"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
gotklog "github.com/fluxcd/toolkit/pkg/log"
)
@@ -104,12 +106,13 @@ var (
)
var (
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
defaultVersion = "latest"
defaultNamespace = "gitops-system"
defaultNotification = "notification-controller"
supportedArch = []string{"arm64", "amd64"}
supportedDecryptionProviders = []string{"sops"}
defaultComponents = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
defaultVersion = "latest"
defaultNamespace = "gitops-system"
defaultNotification = "notification-controller"
supportedArch = []string{"arm64", "amd64"}
supportedDecryptionProviders = []string{"sops"}
supportedHelmChartSourceKinds = []string{sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind}
)
func init() {

View File

@@ -21,7 +21,6 @@ import (
"fmt"
"time"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
@@ -29,6 +28,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
helmv2 "github.com/fluxcd/helm-controller/api/v2alpha1"
consts "github.com/fluxcd/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var reconcileHrCmd = &cobra.Command{
@@ -95,10 +96,10 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error {
logger.Actionf("annotating HelmRelease %s in %s namespace", name, namespace)
if helmRelease.Annotations == nil {
helmRelease.Annotations = map[string]string{
helmv2.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
consts.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
helmRelease.Annotations[helmv2.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
helmRelease.Annotations[consts.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &helmRelease); err != nil {
return err

View File

@@ -21,10 +21,12 @@ import (
"fmt"
"time"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
consts "github.com/fluxcd/pkg/runtime"
)
var reconcileKsCmd = &cobra.Command{
@@ -86,10 +88,10 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error {
logger.Actionf("annotating kustomization %s in %s namespace", name, namespace)
if kustomization.Annotations == nil {
kustomization.Annotations = map[string]string{
kustomizev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
consts.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
kustomization.Annotations[kustomizev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
kustomization.Annotations[consts.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &kustomization); err != nil {
return err

View File

@@ -19,11 +19,15 @@ package main
import (
"context"
"fmt"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
"time"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"time"
consts "github.com/fluxcd/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var reconcileSourceGitCmd = &cobra.Command{
@@ -68,10 +72,10 @@ func syncSourceGitCmdRun(cmd *cobra.Command, args []string) error {
if gitRepository.Annotations == nil {
gitRepository.Annotations = map[string]string{
sourcev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
consts.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
gitRepository.Annotations[sourcev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
gitRepository.Annotations[consts.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &gitRepository); err != nil {
return err

View File

@@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
consts "github.com/fluxcd/pkg/runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
@@ -72,10 +73,10 @@ func syncSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
if helmRepository.Annotations == nil {
helmRepository.Annotations = map[string]string{
sourcev1.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
consts.ReconcileAtAnnotation: time.Now().Format(time.RFC3339Nano),
}
} else {
helmRepository.Annotations[sourcev1.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
helmRepository.Annotations[consts.ReconcileAtAnnotation] = time.Now().Format(time.RFC3339Nano)
}
if err := kubeClient.Update(ctx, &helmRepository); err != nil {
return err

View File

@@ -10,6 +10,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
-h, --help help for bootstrap
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry

View File

@@ -35,6 +35,9 @@ gotk bootstrap github [flags]
# Run bootstrap for a private repo hosted on GitHub Enterprise
gotk bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap github --owner=<organization> --repository=<repo name> --branch=main
```
### Options
@@ -55,6 +58,7 @@ gotk bootstrap github [flags]
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")

View File

@@ -32,6 +32,9 @@ gotk bootstrap gitlab [flags]
# Run bootstrap for a private repo hosted on a GitLab server
gotk bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
# Run bootstrap for a an existing repository with a branch named main
gotk bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
```
### Options
@@ -52,6 +55,7 @@ gotk bootstrap gitlab [flags]
```
--arch string arch can be amd64 or arm64 (default "amd64")
--branch string default branch (for GitHub this must match the default branch setting for the organization) (default "master")
--components strings list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
--image-pull-secret string Kubernetes secret name used for pulling the toolkit images from a private registry
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")

View File

@@ -12,6 +12,7 @@ The create sub-commands generate sources and resources.
--export export in YAML format to stdout
-h, --help help for create
--interval duration source sync interval (default 1m0s)
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
```
### Options inherited from parent commands

View File

@@ -72,6 +72,7 @@ gotk create helmrelease [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -68,6 +68,7 @@ gotk create kustomization [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -18,6 +18,7 @@ The create source sub-commands generate sources.
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -73,6 +73,7 @@ gotk create source git [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -53,6 +53,7 @@ gotk create source helm [name] [flags]
--export export in YAML format to stdout
--interval duration source sync interval (default 1m0s)
--kubeconfig string path to the kubeconfig file (default "~/.kube/config")
--label strings set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)
--namespace string the namespace scope for this operation (default "gitops-system")
--timeout duration timeout for this operation (default 5m0s)
--verbose print generated objects

View File

@@ -79,6 +79,10 @@ cluster e.g. `staging-cluster` and `production-cluster`:
└── gitops-system
```
!!! hint "Change the default branch"
If you wish to change the branch to something else than master, create the repository manually,
push a branch to origin and then use `gotk bootstrap <GIT-PROVIDER> --branch=your-branch`.
### GitHub and GitHub Enterprise
Generate a [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line)

View File

@@ -67,7 +67,7 @@ Tasks
### Helm v3 feature parity
[= 90% "90%"]
[= 100% "100%"]
Goals
@@ -91,5 +91,6 @@ Tasks
- [x] <span style="color:grey">Implement support for values from `Secret` and `ConfigMap` resources</span>
- [x] <span style="color:grey">Implement conditional remediation on (failed) Helm actions</span>
- [x] <span style="color:grey">Implement support for Helm charts from Git</span>
- [ ] [Implement support for referring to an alternative chart values file](https://github.com/fluxcd/helm-controller/issues/4)
- [x] <span style="color:grey">Implement support for referring to an alternative chart values file</span>\
- [ ] Stabilize API
- [ ] Create a migration guide for Helm Operator users

9
go.mod
View File

@@ -4,12 +4,13 @@ go 1.14
require (
github.com/blang/semver v3.5.1+incompatible
github.com/fluxcd/helm-controller/api v0.0.7
github.com/fluxcd/kustomize-controller/api v0.0.10
github.com/fluxcd/pkg/git v0.0.6
github.com/fluxcd/helm-controller/api v0.0.8
github.com/fluxcd/kustomize-controller/api v0.0.11
github.com/fluxcd/pkg/git v0.0.7
github.com/fluxcd/pkg/runtime v0.0.1
github.com/fluxcd/pkg/ssh v0.0.5
github.com/fluxcd/pkg/untar v0.0.5
github.com/fluxcd/source-controller/api v0.0.14
github.com/fluxcd/source-controller/api v0.0.16
github.com/manifoldco/promptui v0.7.0
github.com/spf13/cobra v1.0.0
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect

22
go.sum
View File

@@ -111,18 +111,20 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fluxcd/helm-controller/api v0.0.7 h1:aidjXvcklClH8omhYqiKswZ+MS6t8knOpUacsuESue8=
github.com/fluxcd/helm-controller/api v0.0.7/go.mod h1:KlzwTkpphQxulgWBwCl/uxfBU0QxK/X+w4YcJqGy/1c=
github.com/fluxcd/kustomize-controller/api v0.0.10 h1:dhkTOg3LzNQwRL+lO0YlzOP7AhdpZdghUQNXYhvfiYU=
github.com/fluxcd/kustomize-controller/api v0.0.10/go.mod h1:88m3p6xY3J2pjh5OsL3ANy7PkyA93KiqAJE58JMQyoc=
github.com/fluxcd/pkg/git v0.0.6 h1:4qktw8M3zj98MAs4ny6qSi36sYvTiI1czif5FqlQl4o=
github.com/fluxcd/pkg/git v0.0.6/go.mod h1:9AI9yPkb2ruIcE70moVG3WhunA2/RAMJPc3rtoH8QFE=
github.com/fluxcd/helm-controller/api v0.0.8 h1:Pf+hZjsUpRmoQJeCe178bGWOOm2/Bvg8/s0aafRa1wQ=
github.com/fluxcd/helm-controller/api v0.0.8/go.mod h1:KlzwTkpphQxulgWBwCl/uxfBU0QxK/X+w4YcJqGy/1c=
github.com/fluxcd/kustomize-controller/api v0.0.11 h1:uFL0FT0AP+NmHR8upy+Y7AhBqcWQh2Lvp1F9FXL22iQ=
github.com/fluxcd/kustomize-controller/api v0.0.11/go.mod h1:88m3p6xY3J2pjh5OsL3ANy7PkyA93KiqAJE58JMQyoc=
github.com/fluxcd/pkg/git v0.0.7 h1:tFSYPy7tcIYfOt8H5EUERXIRz7fk0id302oQZde1NtU=
github.com/fluxcd/pkg/git v0.0.7/go.mod h1:5Vu92x6Q3CpxDUllmB69kAkVY5jAtPpXcY2TSZ/oCJI=
github.com/fluxcd/pkg/runtime v0.0.1 h1:h8jztHVF9UMGD7XBQSfXDdw80bpT6BOkd0xe4kknPL0=
github.com/fluxcd/pkg/runtime v0.0.1/go.mod h1:cU1t0+Ld39pZjMyrrHukw1E++OZFNHxG2qAExfDWQ34=
github.com/fluxcd/pkg/ssh v0.0.5 h1:rnbFZ7voy2JBlUfMbfyqArX2FYaLNpDhccGFC3qW83A=
github.com/fluxcd/pkg/ssh v0.0.5/go.mod h1:7jXPdXZpc0ttMNz2kD9QuMi3RNn/e0DOFbj0Tij/+Hs=
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
github.com/fluxcd/source-controller/api v0.0.14 h1:iNG6AGnr44z4T6F0JC2M82ekyxzJ29c3m+DVC7FwSHQ=
github.com/fluxcd/source-controller/api v0.0.14/go.mod h1:PUe+EYQ/s+KPnz2iOCgdf+L6clM0SWkyvdXIpbfpkQE=
github.com/fluxcd/source-controller/api v0.0.16 h1:Mk+X2H+5CX7vfmrVhGT/TR8EnZ8UmZ20TpPyP3e8ZBs=
github.com/fluxcd/source-controller/api v0.0.16/go.mod h1:PUe+EYQ/s+KPnz2iOCgdf+L6clM0SWkyvdXIpbfpkQE=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -265,8 +267,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v32 v32.0.0 h1:q74KVb22spUq0U5HqZ9VCYqQz8YRuOtL/39ZnfwO+NM=
github.com/google/go-github/v32 v32.0.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/helm-controller/config//crd?ref=v0.0.7
- github.com/fluxcd/helm-controller/config//manager?ref=v0.0.7
- github.com/fluxcd/helm-controller/config//crd?ref=v0.0.8
- github.com/fluxcd/helm-controller/config//manager?ref=v0.0.8
patchesJson6902:
- target:
group: apps

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.10
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.10
- github.com/fluxcd/kustomize-controller/config//crd?ref=v0.0.11
- github.com/fluxcd/kustomize-controller/config//manager?ref=v0.0.11
patchesJson6902:
- target:
group: apps

View File

@@ -1,5 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/notification-controller/config//crd?ref=v0.0.8
- github.com/fluxcd/notification-controller/config//manager?ref=v0.0.8
- github.com/fluxcd/notification-controller/config//crd?ref=v0.0.10
- github.com/fluxcd/notification-controller/config//manager?ref=v0.0.10

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.14
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.14
- github.com/fluxcd/source-controller/config//crd?ref=v0.0.16
- github.com/fluxcd/source-controller/config//manager?ref=v0.0.16
patchesJson6902:
- target:
group: apps

View File

@@ -27,6 +27,7 @@ rules:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding