Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1eb0270e9 | ||
|
|
03b6de1169 | ||
|
|
9d3f75d111 | ||
|
|
5c41924b2f | ||
|
|
7cf7cf2f1e | ||
|
|
2679731bde | ||
|
|
ad73370cd7 | ||
|
|
18acae57bd | ||
|
|
b427356eca | ||
|
|
2e6ca16a4a | ||
|
|
e98f1142a6 | ||
|
|
06fa8f75c9 | ||
|
|
8cbd4e8172 | ||
|
|
83c7994266 | ||
|
|
43843581b6 | ||
|
|
7e03d64e8a | ||
|
|
c6f4d71187 |
4
Makefile
4
Makefile
@@ -1,4 +1,4 @@
|
||||
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | tr -d '"')
|
||||
VERSION?=$(shell grep 'VERSION' cmd/flux/main.go | awk '{ print $$4 }' | head -n 1 | tr -d '"')
|
||||
EMBEDDED_MANIFESTS_TARGET=cmd/flux/manifests
|
||||
TEST_KUBECONFIG?=/tmp/flux-e2e-test-kubeconfig
|
||||
ENVTEST_BIN_VERSION?=latest
|
||||
@@ -48,7 +48,7 @@ $(EMBEDDED_MANIFESTS_TARGET): $(call rwildcard,manifests/,*.yaml *.json)
|
||||
./manifests/scripts/bundle.sh
|
||||
|
||||
build: $(EMBEDDED_MANIFESTS_TARGET)
|
||||
CGO_ENABLED=0 go build -o ./bin/flux ./cmd/flux
|
||||
CGO_ENABLED=0 go build -ldflags="-s -w -X main.VERSION=$(VERSION)" -o ./bin/flux ./cmd/flux
|
||||
|
||||
install:
|
||||
go install cmd/flux
|
||||
|
||||
56
README.md
56
README.md
@@ -20,59 +20,15 @@ Flux v2 is constructed with the [GitOps Toolkit](#gitops-toolkit), a
|
||||
set of composable APIs and specialized tools for building Continuous
|
||||
Delivery on top of Kubernetes.
|
||||
|
||||
## Flux installation
|
||||
Flux is a Cloud Native Computing Foundation ([CNCF](https://www.cncf.io/)) project.
|
||||
|
||||
With [Homebrew](https://brew.sh) for macOS and Linux:
|
||||
## Quickstart and documentation
|
||||
|
||||
```sh
|
||||
brew install fluxcd/tap/flux
|
||||
```
|
||||
To get started check out this [guide](https://fluxcd.io/docs/get-started/)
|
||||
on how to bootstrap Flux on Kubernetes and deploy a sample application in a GitOps manner.
|
||||
|
||||
With [GoFish](https://gofi.sh) for Windows, macOS and Linux:
|
||||
|
||||
```sh
|
||||
gofish install flux
|
||||
```
|
||||
|
||||
With Bash for macOS and Linux:
|
||||
|
||||
```sh
|
||||
curl -s https://fluxcd.io/install.sh | sudo bash
|
||||
|
||||
# enable completions in ~/.bash_profile
|
||||
. <(flux completion bash)
|
||||
```
|
||||
|
||||
Arch Linux (AUR) packages:
|
||||
|
||||
- [flux-bin](https://aur.archlinux.org/packages/flux-bin): install the latest
|
||||
stable version using a pre-build binary (recommended)
|
||||
- [flux-go](https://aur.archlinux.org/packages/flux-go): build the latest
|
||||
stable version from source code
|
||||
- [flux-scm](https://aur.archlinux.org/packages/flux-scm): build the latest
|
||||
(unstable) version from source code from our git `main` branch
|
||||
|
||||
Binaries for macOS AMD64/ARM64, Linux AMD64/ARM/ARM64 and Windows are available to
|
||||
download on the [release page](https://github.com/fluxcd/flux2/releases).
|
||||
|
||||
A multi-arch container image with `kubectl` and `flux` is available on Docker Hub and GitHub:
|
||||
|
||||
* `docker.io/fluxcd/flux-cli:<version>`
|
||||
* `ghcr.io/fluxcd/flux-cli:<version>`
|
||||
|
||||
Verify that your cluster satisfies the prerequisites with:
|
||||
|
||||
```sh
|
||||
flux check --pre
|
||||
```
|
||||
|
||||
## Get started
|
||||
|
||||
To get started with Flux, start [browsing the
|
||||
documentation](https://fluxcd.io/docs/) or get started with one of
|
||||
the following guides:
|
||||
|
||||
- [Get started with Flux](https://fluxcd.io/docs/get-started/)
|
||||
For more comprehensive documentation, see the following guides:
|
||||
- [Ways of structuring your repositories](https://fluxcd.io/docs/guides/repository-structure/)
|
||||
- [Manage Helm Releases](https://fluxcd.io/docs/guides/helmreleases/)
|
||||
- [Automate image updates to Git](https://fluxcd.io/docs/guides/image-update/)
|
||||
- [Manage Kubernetes secrets with Mozilla SOPS](https://fluxcd.io/docs/guides/mozilla-sops/)
|
||||
|
||||
@@ -199,6 +199,15 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
||||
}
|
||||
|
||||
var caBundle []byte
|
||||
if bootstrapArgs.caFile != "" {
|
||||
var err error
|
||||
caBundle, err = os.ReadFile(bootstrapArgs.caFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Bootstrap config
|
||||
bootstrapOpts := []bootstrap.GitOption{
|
||||
bootstrap.WithRepositoryURL(gitArgs.url),
|
||||
@@ -208,6 +217,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
|
||||
bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
|
||||
bootstrap.WithLogger(logger),
|
||||
bootstrap.WithCABundle(caBundle),
|
||||
}
|
||||
|
||||
// Setup bootstrapper with constructed configs
|
||||
|
||||
@@ -134,7 +134,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
|
||||
},
|
||||
},
|
||||
}
|
||||
if sourceHelmArgs.secretRef != "" {
|
||||
if sourceBucketArgs.secretRef != "" {
|
||||
bucket.Spec.SecretRef = &meta.LocalObjectReference{
|
||||
Name: sourceBucketArgs.secretRef,
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ type sourceGitFlags struct {
|
||||
caFile string
|
||||
privateKeyFile string
|
||||
recurseSubmodules bool
|
||||
silent bool
|
||||
}
|
||||
|
||||
var createSourceGitCmd = &cobra.Command{
|
||||
@@ -135,6 +136,7 @@ func init() {
|
||||
createSourceGitCmd.Flags().StringVar(&sourceGitArgs.privateKeyFile, "private-key-file", "", "path to a passwordless private key file used for authenticating to the Git SSH server")
|
||||
createSourceGitCmd.Flags().BoolVar(&sourceGitArgs.recurseSubmodules, "recurse-submodules", false,
|
||||
"when enabled, configures the GitRepository source to initialize and include Git submodules in the artifact it produces")
|
||||
createSourceGitCmd.Flags().BoolVarP(&sourceGitArgs.silent, "silent", "s", false, "assumes the deploy key is already setup, skips confirmation")
|
||||
|
||||
createSourceCmd.AddCommand(createSourceGitCmd)
|
||||
}
|
||||
@@ -272,12 +274,14 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
if ppk, ok := s.StringData[sourcesecret.PublicKeySecretKey]; ok {
|
||||
logger.Generatef("deploy key: %s", ppk)
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Have you added the deploy key to your repository",
|
||||
IsConfirm: true,
|
||||
}
|
||||
if _, err := prompt.Run(); err != nil {
|
||||
return fmt.Errorf("aborting")
|
||||
if !sourceGitArgs.silent {
|
||||
prompt := promptui.Prompt{
|
||||
Label: "Have you added the deploy key to your repository",
|
||||
IsConfirm: true,
|
||||
}
|
||||
if _, err := prompt.Run(); err != nil {
|
||||
return fmt.Errorf("aborting")
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.Actionf("applying secret with repository credentials")
|
||||
|
||||
131
cmd/flux/create_source_git_test.go
Normal file
131
cmd/flux/create_source_git_test.go
Normal file
@@ -0,0 +1,131 @@
|
||||
// +build unit
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
|
||||
"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"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var pollInterval = 50 * time.Millisecond
|
||||
var testTimeout = 10 * time.Second
|
||||
|
||||
// Update the GitRepository once created to exercise test specific behavior
|
||||
type reconcileFunc func(repo *sourcev1.GitRepository)
|
||||
|
||||
// reconciler waits for an object to be created, then invokes a test supplied
|
||||
// function to mutate that object, simulating a controller.
|
||||
// Test should invoke run() to run the background reconciler task which
|
||||
// polls to wait for the object to exist before applying the update function.
|
||||
// Any errors from the reconciler are asserted on test completion.
|
||||
type reconciler struct {
|
||||
client client.Client
|
||||
name types.NamespacedName
|
||||
reconcile reconcileFunc
|
||||
}
|
||||
|
||||
// Start the background task that waits for the object to exist then applies
|
||||
// the update function.
|
||||
func (r *reconciler) run(t *testing.T) {
|
||||
result := make(chan error)
|
||||
go func() {
|
||||
defer close(result)
|
||||
err := wait.PollImmediate(
|
||||
pollInterval,
|
||||
testTimeout,
|
||||
r.conditionFunc)
|
||||
result <- err
|
||||
}()
|
||||
t.Cleanup(func() {
|
||||
if err := <-result; err != nil {
|
||||
t.Errorf("Failure from test reconciler: '%v':", err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// A ConditionFunction that waits for the named GitRepository to be created,
|
||||
// then sets the ready condition to true.
|
||||
func (r *reconciler) conditionFunc() (bool, error) {
|
||||
var repo sourcev1.GitRepository
|
||||
if err := r.client.Get(context.Background(), r.name, &repo); err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return false, nil // Keep polling until object is created
|
||||
}
|
||||
return true, err
|
||||
}
|
||||
r.reconcile(&repo)
|
||||
err := r.client.Status().Update(context.Background(), &repo)
|
||||
return true, err
|
||||
}
|
||||
|
||||
func TestCreateSourceGit(t *testing.T) {
|
||||
// Default command used for multiple tests
|
||||
var command = "create source git podinfo --url=https://github.com/stefanprodan/podinfo --branch=master --timeout=" + testTimeout.String()
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
args string
|
||||
assert assertFunc
|
||||
reconcile reconcileFunc
|
||||
}{
|
||||
{
|
||||
"NoArgs",
|
||||
"create source git",
|
||||
assertError("GitRepository source name is required"),
|
||||
nil,
|
||||
}, {
|
||||
"Succeeded",
|
||||
command,
|
||||
assertGoldenFile("testdata/create_source_git/success.golden"),
|
||||
func(repo *sourcev1.GitRepository) {
|
||||
meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionTrue, sourcev1.GitOperationSucceedReason, "succeeded message")
|
||||
repo.Status.Artifact = &sourcev1.Artifact{
|
||||
Path: "some-path",
|
||||
Revision: "v1",
|
||||
}
|
||||
},
|
||||
}, {
|
||||
"Failed",
|
||||
command,
|
||||
assertError("failed message"),
|
||||
func(repo *sourcev1.GitRepository) {
|
||||
meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionFalse, sourcev1.URLInvalidReason, "failed message")
|
||||
},
|
||||
}, {
|
||||
"NoArtifact",
|
||||
command,
|
||||
assertError("GitRepository source reconciliation completed but no artifact was found"),
|
||||
func(repo *sourcev1.GitRepository) {
|
||||
// Updated with no artifact
|
||||
meta.SetResourceCondition(repo, meta.ReadyCondition, metav1.ConditionTrue, sourcev1.GitOperationSucceedReason, "succeeded message")
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ns := allocateNamespace("podinfo")
|
||||
setupTestNamespace(ns, t)
|
||||
if tc.reconcile != nil {
|
||||
r := reconciler{
|
||||
client: testEnv.client,
|
||||
name: types.NamespacedName{Namespace: ns, Name: "podinfo"},
|
||||
reconcile: tc.reconcile,
|
||||
}
|
||||
r.run(t)
|
||||
}
|
||||
cmd := cmdTestCase{
|
||||
args: tc.args + " -n=" + ns,
|
||||
assert: tc.assert,
|
||||
}
|
||||
cmd.runTestCmd(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/mattn/go-shellwords"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
@@ -132,7 +133,9 @@ func NewTestEnvKubeManager(testClusterMode TestClusterMode) (*testEnvKubeManager
|
||||
|
||||
tmpFilename := filepath.Join("/tmp", "kubeconfig-"+time.Nanosecond.String())
|
||||
os.WriteFile(tmpFilename, kubeConfig, 0644)
|
||||
k8sClient, err := client.NewWithWatch(cfg, client.Options{})
|
||||
k8sClient, err := client.NewWithWatch(cfg, client.Options{
|
||||
Scheme: utils.NewScheme(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -158,7 +161,9 @@ func NewTestEnvKubeManager(testClusterMode TestClusterMode) (*testEnvKubeManager
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k8sClient, err := client.NewWithWatch(cfg, client.Options{})
|
||||
k8sClient, err := client.NewWithWatch(cfg, client.Options{
|
||||
Scheme: utils.NewScheme(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
@@ -32,3 +35,14 @@ func TestMain(m *testing.M) {
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func setupTestNamespace(namespace string, t *testing.T) {
|
||||
ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}
|
||||
err := testEnv.client.Create(context.Background(), ns)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create namespace: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_ = testEnv.client.Delete(context.Background(), ns)
|
||||
})
|
||||
}
|
||||
|
||||
6
cmd/flux/testdata/create_source_git/success.golden
vendored
Normal file
6
cmd/flux/testdata/create_source_git/success.golden
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
✚ generating GitRepository source
|
||||
► applying GitRepository source
|
||||
✔ GitRepository source created
|
||||
◎ waiting for GitRepository source reconciliation
|
||||
✔ GitRepository source reconciliation completed
|
||||
✔ fetched revision: v1
|
||||
6
go.mod
6
go.mod
@@ -9,7 +9,7 @@ require (
|
||||
github.com/fluxcd/helm-controller/api v0.11.2
|
||||
github.com/fluxcd/image-automation-controller/api v0.14.1
|
||||
github.com/fluxcd/image-reflector-controller/api v0.11.1
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.0
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.1
|
||||
github.com/fluxcd/notification-controller/api v0.16.0
|
||||
github.com/fluxcd/pkg/apis/meta v0.10.0
|
||||
github.com/fluxcd/pkg/runtime v0.12.0
|
||||
@@ -36,3 +36,7 @@ require (
|
||||
sigs.k8s.io/kustomize/api v0.8.10
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
// drop LGPL dependency manifoldco/promptui -> juju/ansiterm
|
||||
// undo replacement when https://github.com/manifoldco/promptui/pull/181 is merged
|
||||
replace github.com/manifoldco/promptui => github.com/nguyer/promptui v0.8.1-0.20210517132806-70ccd4709797
|
||||
|
||||
13
go.sum
13
go.sum
@@ -211,8 +211,8 @@ github.com/fluxcd/image-automation-controller/api v0.14.1 h1:8EDUs61Gi5HgSA9ou0r
|
||||
github.com/fluxcd/image-automation-controller/api v0.14.1/go.mod h1:22GZblh0CmaZItQpvCBe40i5ql/oCZllpLqkGmoglEQ=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.11.1 h1:8pmUKL7Pise0JOBFgqw7eWtOK/rs3HNibXqCK9aJ8LE=
|
||||
github.com/fluxcd/image-reflector-controller/api v0.11.1/go.mod h1:lgQHGFz29OHmDU5Jwg689C/M+P/f9ujt6NS0zCLT0BQ=
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.0 h1:M2i7y8I3DZUlrNDzfxwVxVBrPkB+sQrPAyVtw6OTu9E=
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.0/go.mod h1:3RNiEd/XnYjSTGzMqDzDbQkOYpdPFrKuS+XdgWt9pds=
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.1 h1:OsErJQ3U3ReYTAtkeFo1t8UW4sjISF0a+6wsz942MT0=
|
||||
github.com/fluxcd/kustomize-controller/api v0.14.1/go.mod h1:3RNiEd/XnYjSTGzMqDzDbQkOYpdPFrKuS+XdgWt9pds=
|
||||
github.com/fluxcd/notification-controller/api v0.16.0 h1:3vaIj3AJRUA4dsfISuok8URV1RUmoe9NFpCAZ+tjOeU=
|
||||
github.com/fluxcd/notification-controller/api v0.16.0/go.mod h1:t28GMWMLiLqho+ikpZrldv22/vmCsFdQR8vdJluxknc=
|
||||
github.com/fluxcd/pkg/apis/kustomize v0.1.0/go.mod h1:gEl+W5cVykCC3RfrCaqe+Pz+j4lKl2aeR4dxsom/zII=
|
||||
@@ -489,8 +489,6 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
|
||||
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||
@@ -518,7 +516,6 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
|
||||
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
|
||||
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -530,15 +527,11 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
|
||||
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4=
|
||||
github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
|
||||
github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
@@ -585,6 +578,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nguyer/promptui v0.8.1-0.20210517132806-70ccd4709797 h1:unCiBzwNjcuVbP3bgM76z0ORyIuI4sspop1qhkQJ044=
|
||||
github.com/nguyer/promptui v0.8.1-0.20210517132806-70ccd4709797/go.mod h1:CBMXL3a2sC3Q8TjpLcQt8w/3aQ23VSy6r7UFeCG6phA=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
|
||||
@@ -47,7 +47,7 @@ type Reconciler interface {
|
||||
// manifests with the provided values, committing them to Git and
|
||||
// pushing to remote if there are any changes, and applying them
|
||||
// to the cluster.
|
||||
ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options) error
|
||||
ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options, secretOpts sourcesecret.Options) error
|
||||
|
||||
// ReconcileSourceSecret reconciles the source secret by generating
|
||||
// a new secret with the provided values if the secret does not
|
||||
@@ -87,7 +87,7 @@ func Run(ctx context.Context, reconciler Reconciler, manifestsBase string,
|
||||
}
|
||||
}
|
||||
|
||||
if err := reconciler.ReconcileComponents(ctx, manifestsBase, installOpts); err != nil {
|
||||
if err := reconciler.ReconcileComponents(ctx, manifestsBase, installOpts, secretOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := reconciler.ReconcileSourceSecret(ctx, secretOpts); err != nil {
|
||||
|
||||
@@ -46,8 +46,9 @@ import (
|
||||
)
|
||||
|
||||
type PlainGitBootstrapper struct {
|
||||
url string
|
||||
branch string
|
||||
url string
|
||||
branch string
|
||||
caBundle []byte
|
||||
|
||||
author git.Author
|
||||
commitMessageAppendix string
|
||||
@@ -70,6 +71,16 @@ func WithRepositoryURL(url string) GitOption {
|
||||
return repositoryURLOption(url)
|
||||
}
|
||||
|
||||
func WithCABundle(b []byte) GitOption {
|
||||
return caBundleOption(b)
|
||||
}
|
||||
|
||||
type caBundleOption []byte
|
||||
|
||||
func (o caBundleOption) applyGit(b *PlainGitBootstrapper) {
|
||||
b.caBundle = o
|
||||
}
|
||||
|
||||
type repositoryURLOption string
|
||||
|
||||
func (o repositoryURLOption) applyGit(b *PlainGitBootstrapper) {
|
||||
@@ -97,7 +108,7 @@ func NewPlainGitProvider(git git.Git, kube client.Client, opts ...GitOption) (*P
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options) error {
|
||||
func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifestsBase string, options install.Options, secretOpts sourcesecret.Options) error {
|
||||
// Clone if not already
|
||||
if _, err := b.git.Status(); err != nil {
|
||||
if err != git.ErrNoGitRepository {
|
||||
@@ -107,7 +118,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
|
||||
b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url)
|
||||
var cloned bool
|
||||
if err = retry(1, 2*time.Second, func() (err error) {
|
||||
cloned, err = b.git.Clone(ctx, b.url, b.branch)
|
||||
cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle)
|
||||
return
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to clone repository: %w", err)
|
||||
@@ -145,7 +156,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
|
||||
if err == nil {
|
||||
b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit)
|
||||
b.logger.Actionf("pushing component manifests to %q", b.url)
|
||||
if err = b.git.Push(ctx); err != nil {
|
||||
if err = b.git.Push(ctx, b.caBundle); err != nil {
|
||||
return fmt.Errorf("failed to push manifests: %w", err)
|
||||
}
|
||||
} else {
|
||||
@@ -260,7 +271,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
|
||||
b.logger.Actionf("cloning branch %q from Git repository %q", b.branch, b.url)
|
||||
var cloned bool
|
||||
if err = retry(1, 2*time.Second, func() (err error) {
|
||||
cloned, err = b.git.Clone(ctx, b.url, b.branch)
|
||||
cloned, err = b.git.Clone(ctx, b.url, b.branch, b.caBundle)
|
||||
return
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to clone repository: %w", err)
|
||||
@@ -309,7 +320,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
|
||||
if err == nil {
|
||||
b.logger.Successf("committed sync manifests to %q (%q)", b.branch, commit)
|
||||
b.logger.Actionf("pushing sync manifests to %q", b.url)
|
||||
if err = b.git.Push(ctx); err != nil {
|
||||
if err = b.git.Push(ctx, b.caBundle); err != nil {
|
||||
return fmt.Errorf("failed to push sync manifests: %w", err)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -42,10 +42,10 @@ type Commit struct {
|
||||
// remote repository.
|
||||
type Git interface {
|
||||
Init(url, branch string) (bool, error)
|
||||
Clone(ctx context.Context, url, branch string) (bool, error)
|
||||
Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error)
|
||||
Write(path string, reader io.Reader) error
|
||||
Commit(message Commit) (string, error)
|
||||
Push(ctx context.Context) error
|
||||
Push(ctx context.Context, caBundle []byte) error
|
||||
Status() (bool, error)
|
||||
Head() (string, error)
|
||||
Path() string
|
||||
|
||||
@@ -82,7 +82,7 @@ func (g *GoGit) Init(url, branch string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (g *GoGit) Clone(ctx context.Context, url, branch string) (bool, error) {
|
||||
func (g *GoGit) Clone(ctx context.Context, url, branch string, caBundle []byte) (bool, error) {
|
||||
branchRef := plumbing.NewBranchReferenceName(branch)
|
||||
r, err := gogit.PlainCloneContext(ctx, g.path, false, &gogit.CloneOptions{
|
||||
URL: url,
|
||||
@@ -94,6 +94,7 @@ func (g *GoGit) Clone(ctx context.Context, url, branch string) (bool, error) {
|
||||
NoCheckout: false,
|
||||
Progress: nil,
|
||||
Tags: gogit.NoTags,
|
||||
CABundle: caBundle,
|
||||
})
|
||||
if err != nil {
|
||||
if err == transport.ErrEmptyRemoteRepository || isRemoteBranchNotFoundErr(err, branchRef.String()) {
|
||||
@@ -185,7 +186,7 @@ func (g *GoGit) Commit(message git.Commit) (string, error) {
|
||||
return commit.String(), nil
|
||||
}
|
||||
|
||||
func (g *GoGit) Push(ctx context.Context) error {
|
||||
func (g *GoGit) Push(ctx context.Context, caBundle []byte) error {
|
||||
if g.repository == nil {
|
||||
return git.ErrNoGitRepository
|
||||
}
|
||||
@@ -194,6 +195,7 @@ func (g *GoGit) Push(ctx context.Context) error {
|
||||
RemoteName: gogit.DefaultRemoteName,
|
||||
Auth: g.auth,
|
||||
Progress: nil,
|
||||
CABundle: caBundle,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.0/kustomize-controller.crds.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.0/kustomize-controller.deployment.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.1/kustomize-controller.crds.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.1/kustomize-controller.deployment.yaml
|
||||
- account.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
|
||||
@@ -2,7 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/source-controller/releases/download/v0.15.4/source-controller.crds.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.0/kustomize-controller.crds.yaml
|
||||
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.14.1/kustomize-controller.crds.yaml
|
||||
- https://github.com/fluxcd/helm-controller/releases/download/v0.11.2/helm-controller.crds.yaml
|
||||
- https://github.com/fluxcd/notification-controller/releases/download/v0.16.0/notification-controller.crds.yaml
|
||||
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.11.1/image-reflector-controller.crds.yaml
|
||||
|
||||
Reference in New Issue
Block a user