1
0
mirror of synced 2026-03-01 11:16:56 +00:00

Compare commits

..

47 Commits

Author SHA1 Message Date
Stefan Prodan
4bc4aa1397 Merge pull request #2050 from fluxcd/do-not-edit-warn
Add `DO NOT EDIT` warn to bootstrap sync manifests
2021-11-04 18:47:50 +02:00
Stefan Prodan
04faba95cd Add DO NOT EDIT warn to bootstrap sync manifests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-04 18:03:40 +02:00
Sunny
f712dadab5 Merge pull request #2051 from fluxcd/update-components
Update toolkit components
2021-11-04 21:31:17 +05:30
fluxcdbot
58b3150ce3 Update toolkit components
- source-controller to v0.17.2
  https://github.com/fluxcd/source-controller/blob/v0.17.2/CHANGELOG.md
- image-automation-controller to v0.16.1
  https://github.com/fluxcd/image-automation-controller/blob/v0.16.1/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2021-11-04 14:07:27 +00:00
Stefan Prodan
e7225db397 Merge pull request #2046 from vespian/prozlach/support_http_proxy_envs
Use full domain name for notification-controller
2021-11-04 11:43:47 +02:00
Pawel Rozlach
8ec5492d87 fix: use full domain name for notification-controller
Signed-off-by: Pawel Rozlach <vespian@users.noreply.github.com>
2021-11-03 10:37:29 +01:00
Stefan Prodan
c2c64a70c4 Merge pull request #2042 from fluxcd/ecdsa-default
Set ECDSA as the default algorithm for `flux create source git`
2021-11-02 17:42:49 +02:00
Stefan Prodan
4621576f40 Set ECDSA as the default algorithm for flux create source git
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-02 17:21:10 +02:00
Stefan Prodan
3b609e9b03 Merge pull request #2041 from fluxcd/bootstrap-ecdsa-default
bootstrap: Set ECDSA as the default SSH key algorithm
2021-11-02 17:15:57 +02:00
Stefan Prodan
4f2ebd78be Set ECDSA as the default algorithm for flux create secret git
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-02 16:49:17 +02:00
Stefan Prodan
88dacebc94 bootstrap: Set ECDSA as the default SSH key algorithm
Motivation: RSA SHA-1 SSH keys are no longer accepted by GitHub https://github.blog/2021-09-01-improving-git-protocol-security-github/.
Given this we are switching the default from RSA to ECDSA for `git`, `github` and `gitlab` variants of `flux bootstrap`.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-02 16:22:16 +02:00
Stefan Prodan
92e7d1ad1e Merge pull request #2036 from fluxcd/part-of-selector
Switch to `app.kubernetes.io/part-of` label selector
2021-11-01 18:37:03 +02:00
Stefan Prodan
d5d8c340c8 Switch to app.kubernetes.io/part-of label selector
Use `app.kubernetes.io/part-of: flux` label instead of `app.kubernetes.io/instance` to select the in-cluster objects used in flux version, check, logs and uninstall commands.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-01 18:02:49 +02:00
Stefan Prodan
b8a85b809a Merge pull request #2035 from fluxcd/source-fetch-timeout
Add fetch timeout arg to create source commands
2021-11-01 16:06:12 +02:00
Stefan Prodan
61be0775af Add fetch timeout arg to create source commands
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-01 15:37:58 +02:00
Stefan Prodan
404ffa5a91 Merge pull request #2034 from fluxcd/default-namespace-from-env
Set default ns with `FLUX_SYSTEM_NAMESPACE` env var
2021-11-01 14:56:47 +02:00
Stefan Prodan
f2de7e04b8 Set default ns with FLUX_SYSTEM_NAMESPACE env var
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-01 14:21:44 +02:00
Stefan Prodan
8b3e3b1dd7 Merge pull request #2033 from fluxcd/update-issue-template
Add flux version to issue template
2021-11-01 13:07:35 +02:00
Stefan Prodan
81e91ac3f5 Add flux version to issue template
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-01 12:46:52 +02:00
Stefan Prodan
b9bde94d08 Merge pull request #2032 from fluxcd/tree-completion
Enable completion for flux tree cmd
2021-11-01 12:40:36 +02:00
Stefan Prodan
37746023c1 Enable completion for flux tree cmd
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-11-01 12:19:06 +02:00
Stefan Prodan
d3e529b8a4 Merge pull request #2015 from SomtochiAma/test-export-cmd
Add unit tests for export
2021-11-01 12:18:55 +02:00
Somtochi Onyekwere
eb69083ef5 Add unit tests for export
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
2021-11-01 10:46:07 +01:00
Hidde Beydals
96aac387c9 Merge pull request #2028 from fluxcd/update-components 2021-10-30 15:34:11 +02:00
fluxcdbot
870f18c621 Update toolkit components
- source-controller to v0.17.1
  https://github.com/fluxcd/source-controller/blob/v0.17.1/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2021-10-30 13:11:56 +00:00
Hidde Beydals
57b33e29f7 Merge pull request #2024 from kingdonb/fix-error-message-quoting 2021-10-29 18:11:39 +02:00
Kingdon Barrett
94b7917679 Fix quoting around reconciliation error message
While fixing an unrelated issue, I noticed:
    ✗ GitRepository reconciliation failed: ''PGP public keys secret error: expected pointer, but got nil

the single quote should surround the readyCond.Message

Signed-off-by: Kingdon Barrett <yebyen@gmail.com>
2021-10-29 11:21:56 -04:00
Hidde Beydals
98fa0c4271 Merge pull request #2023 from fluxcd/update-components-test 2021-10-28 17:30:10 +02:00
Hidde Beydals
8282907bce Update toolkit components tests
Signed-off-by: Hidde Beydals <hello@hidde.co>
2021-10-28 17:01:24 +02:00
Hidde Beydals
323f4f5e5f Merge pull request #2022 from fluxcd/update-components 2021-10-28 17:00:39 +02:00
fluxcdbot
744b3ebd0a Update toolkit components
- source-controller to v0.17.0
  https://github.com/fluxcd/source-controller/blob/v0.17.0/CHANGELOG.md
- image-automation-controller to v0.16.0
  https://github.com/fluxcd/image-automation-controller/blob/v0.16.0/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2021-10-28 14:46:49 +00:00
Stefan Prodan
3fdba35993 Merge pull request #2021 from fluxcd/e2e-retry-gh-get
e2e: Retry the GitHub API calls
2021-10-28 11:23:15 +03:00
Stefan Prodan
ebdf9ed379 e2e: Retry the GitHub API calls
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-10-28 10:56:52 +03:00
Stefan Prodan
a572274c5c Merge pull request #1932 from SomtochiAma/test-bootstrap
Add test for customizing bootstrap
2021-10-28 09:53:43 +03:00
Somtochi Onyekwere
6a6bba8669 Add test for customizing bootstrap
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
2021-10-27 15:45:23 +01:00
Stefan Prodan
1d1d4bbf4b Merge pull request #2008 from fluxcd/expand-hr-in-tree-ks
Expand Helm releases in flux tree cmd
2021-10-26 18:04:53 +03:00
Stefan Prodan
d9bb4c631e Add flux tree to e2e tests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-10-26 17:34:01 +03:00
Stefan Prodan
722962c138 Expand Helm releases in flux tree cmd
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-10-26 15:54:31 +03:00
Stefan Prodan
c98ff6ae87 Merge pull request #1988 from darkowlzz/update-maintainers
Add @darkowlzz to maintainers list
2021-10-25 19:36:16 +03:00
Sunny
cbef6a4cad Add @darkowlzz to maintainers list
Signed-off-by: Sunny <darkowlzz@protonmail.com>
2021-10-25 21:48:59 +05:30
Stefan Prodan
f887a2c029 Merge pull request #1998 from fluxcd/tree-cmd
Add flux tree command
2021-10-25 16:51:01 +03:00
Stefan Prodan
078cfe92c2 Add JSON and YAML output options to flux tree cmd
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-10-25 13:45:27 +03:00
Stefan Prodan
80ef184b60 Add flux tree command
The `flux tree kustomization` command prints the resources reconciled by the given Kustomization.

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2021-10-25 13:45:13 +03:00
Hidde Beydals
f2475988bd Merge pull request #2000 from wingkwong/refak/ioutil 2021-10-24 18:53:13 +02:00
WONG, Wing Kam
45526108e0 Remove use of deprecated io/ioutil
Signed-off-by: WONG, Wing Kam <wingkwong.code@gmail.com>
2021-10-24 22:17:20 +08:00
Stefan Prodan
414c0bbbdc Merge pull request #1997 from johngmyers/contrib-slack
Update Slack channel in CONTRIBUTING.md
2021-10-23 11:05:54 +03:00
John Gardiner Myers
6873a710d9 Update Slack channel in CONTRIBUTING.md
Signed-off-by: John Gardiner Myers <jgmyers@proofpoint.com>
2021-10-22 10:59:49 -07:00
53 changed files with 1254 additions and 46 deletions

View File

@@ -48,19 +48,18 @@ body:
required: true
attributes:
label: Flux version
description: Run `flux --version` to check. If not applicable, write `N/A`.
placeholder: e.g. 0.16.1
description: Run `flux version --client`. If not applicable, write `N/A`.
placeholder: e.g. v0.20.1
- type: textarea
validations:
required: true
attributes:
label: Flux check
description: Run `flux check` to check. If not applicable, write `N/A`.
description: Run `flux check`. If not applicable, write `N/A`.
placeholder: |
For example:
► checking prerequisites
kubectl 1.21.0 >=1.18.0-0
✔ Kubernetes 1.21.1 >=1.16.0-0
Kubernetes 1.21.1 >=1.19.0-0
► checking controllers
✔ all checks passed
- type: input

View File

@@ -64,6 +64,22 @@ jobs:
--team=team-z
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
- name: bootstrap customize
run: |
make setup-bootstrap-patch
/tmp/flux bootstrap github --manifests ./manifests/install/ \
--owner=fluxcd-testing \
--repository=${{ steps.vars.outputs.test_repo_name }} \
--branch=main \
--path=test-cluster \
--team=team-z
if [ $(kubectl get deployments.apps source-controller -o jsonpath='{.spec.template.spec.securityContext.runAsUser}') != "10000" ]; then
echo "Bootstrap not customized as controller is not running as user 10000" && exit 1
fi
env:
GITHUB_TOKEN: ${{ secrets.GITPROVIDER_BOT_TOKEN }}
GITHUB_REPO_NAME: ${{ steps.vars.outputs.test_repo_name }}
GITHUB_ORG_NAME: fluxcd-testing
- name: libgit2
run: |
/tmp/flux create source git test-libgit2 \

View File

@@ -191,7 +191,14 @@ jobs:
/tmp/flux create kustomization flux-system \
--source=flux-system \
--path=./clusters/staging
kubectl -n flux-system wait kustomization/infrastructure --for=condition=ready --timeout=5m
kubectl -n flux-system wait kustomization/apps --for=condition=ready --timeout=5m
kubectl -n nginx wait helmrelease/nginx --for=condition=ready --timeout=5m
kubectl -n redis wait helmrelease/redis --for=condition=ready --timeout=5m
kubectl -n podinfo wait helmrelease/podinfo --for=condition=ready --timeout=5m
- name: flux tree
run: |
/tmp/flux tree kustomization flux-system | grep Service/podinfo
- name: flux check
run: |
/tmp/flux check

View File

@@ -30,7 +30,7 @@ you can sign your commit automatically with `git commit -s`.
For realtime communications we use Slack: To join the conversation, simply
join the [CNCF](https://slack.cncf.io/) Slack workspace and use the
[#flux-dev](https://cloud-native.slack.com/messages/flux-dev/) channel.
[#flux-contributors](https://cloud-native.slack.com/messages/flux-contributors/) channel.
To discuss ideas and specifications we use [Github
Discussions](https://github.com/fluxcd/flux2/discussions).

View File

@@ -17,3 +17,4 @@ Hidde Beydals, Weaveworks <hidde@weave.works> (github: @hiddeco, slack: hidde)
Max Jonas Werner, D2iQ <mwerner@d2iq.com> (github: @makkes, slack: max)
Philip Laine, Xenit <philip.laine@xenit.se> (github: @phillebaba, slack: phillebaba)
Stefan Prodan, Weaveworks <stefan@weave.works> (github: @stefanprodan, slack: stefanprodan)
Sunny, Weaveworks <sunny@weave.works> (github: @darkowlzz, slack: darkowlzz)

View File

@@ -58,10 +58,12 @@ install:
install-dev:
CGO_ENABLED=0 go build -o /usr/local/bin ./cmd/flux
install-envtest: setup-envtest
$(SETUP_ENVTEST) use $(ENVTEST_BIN_VERSION)
setup-bootstrap-patch:
go run ./tests/bootstrap/main.go
# Find or download setup-envtest
setup-envtest:
ifeq (, $(shell which setup-envtest))

View File

@@ -140,7 +140,7 @@ func NewBootstrapFlags() bootstrapFlags {
return bootstrapFlags{
logLevel: flags.LogLevel(rootArgs.defaults.LogLevel),
requiredComponents: []string{"source-controller", "kustomize-controller"},
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.RSAPrivateKeyAlgorithm),
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.ECDSAPrivateKeyAlgorithm),
keyRSABits: 2048,
keyECDSACurve: flags.ECDSACurve{Curve: elliptic.P384()},
}

View File

@@ -30,6 +30,7 @@ import (
"github.com/fluxcd/pkg/version"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen"
"github.com/fluxcd/flux2/pkg/manifestgen/install"
"github.com/fluxcd/flux2/pkg/status"
)
@@ -191,7 +192,7 @@ func componentsCheck() bool {
}
ok := true
selector := client.MatchingLabels{"app.kubernetes.io/instance": rootArgs.namespace}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil {
for _, d := range list.Items {

View File

@@ -105,7 +105,7 @@ func init() {
func NewSecretGitFlags() secretGitFlags {
return secretGitFlags{
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.RSAPrivateKeyAlgorithm),
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.ECDSAPrivateKeyAlgorithm),
rsaBits: 2048,
ecdsaCurve: flags.ECDSACurve{Curve: elliptic.P384()},
}

View File

@@ -17,6 +17,8 @@ limitations under the License.
package main
import (
"time"
"github.com/spf13/cobra"
)
@@ -26,6 +28,14 @@ var createSourceCmd = &cobra.Command{
Long: "The create source sub-commands generate sources.",
}
type createSourceFlags struct {
fetchTimeout time.Duration
}
var createSourceArgs createSourceFlags
func init() {
createSourceCmd.PersistentFlags().DurationVar(&createSourceArgs.fetchTimeout, "fetch-timeout", createSourceArgs.fetchTimeout,
"set a timeout for fetch operations performed by source-controller (e.g. 'git clone' or 'helm repo update')")
createCmd.AddCommand(createSourceCmd)
}

View File

@@ -134,6 +134,11 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
},
},
}
if createSourceArgs.fetchTimeout > 0 {
bucket.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout}
}
if sourceBucketArgs.secretRef != "" {
bucket.Spec.SecretRef = &meta.LocalObjectReference{
Name: sourceBucketArgs.secretRef,

View File

@@ -143,7 +143,7 @@ func init() {
func newSourceGitFlags() sourceGitFlags {
return sourceGitFlags{
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.RSAPrivateKeyAlgorithm),
keyAlgorithm: flags.PublicKeyAlgorithm(sourcesecret.ECDSAPrivateKeyAlgorithm),
keyRSABits: 2048,
keyECDSACurve: flags.ECDSACurve{Curve: elliptic.P384()},
}
@@ -206,6 +206,10 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
},
}
if createSourceArgs.fetchTimeout > 0 {
gitRepository.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout}
}
if sourceGitArgs.gitImplementation != "" {
gitRepository.Spec.GitImplementation = sourceGitArgs.gitImplementation.String()
}

View File

@@ -129,6 +129,10 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
},
}
if createSourceArgs.fetchTimeout > 0 {
helmRepository.Spec.Timeout = &metav1.Duration{Duration: createSourceArgs.fetchTimeout}
}
if sourceHelmArgs.secretRef != "" {
helmRepository.Spec.SecretRef = &meta.LocalObjectReference{
Name: sourceHelmArgs.secretRef,

View File

@@ -113,8 +113,8 @@ func printExport(export interface{}) error {
if err != nil {
return err
}
fmt.Println("---")
fmt.Println(resourceToString(data))
rootCmd.Println("---")
rootCmd.Println(resourceToString(data))
return nil
}

88
cmd/flux/export_test.go Normal file
View File

@@ -0,0 +1,88 @@
// +build unit
package main
import (
"testing"
)
func TestExport(t *testing.T) {
cases := []struct {
name string
arg string
goldenFile string
}{
{
"alert-provider",
"export alert-provider slack",
"testdata/export/provider.yaml",
},
{
"alert",
"export alert flux-system",
"testdata/export/alert.yaml",
},
{
"image policy",
"export image policy flux-system",
"testdata/export/image-policy.yaml",
},
{
"image repository",
"export image repository flux-system",
"testdata/export/image-repo.yaml",
},
{
"image update",
"export image update flux-system",
"testdata/export/image-update.yaml",
},
{
"source git",
"export source git flux-system",
"testdata/export/git-repo.yaml",
},
{
"source helm",
"export source helm flux-system",
"testdata/export/helm-repo.yaml",
},
{
"receiver",
"export receiver flux-system",
"testdata/export/receiver.yaml",
},
{
"kustomization",
"export kustomization flux-system",
"testdata/export/ks.yaml",
},
{
"helmrelease",
"export helmrelease flux-system",
"testdata/export/helm-release.yaml",
},
{
"bucket",
"export source bucket flux-system",
"testdata/export/bucket.yaml",
},
}
objectFile := "testdata/export/objects.yaml"
tmpl := map[string]string{
"fluxns": allocateNamespace("flux-system"),
}
testEnv.CreateObjectFile(objectFile, tmpl, t)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
cmd := cmdTestCase{
args: tt.arg + " -n=" + tmpl["fluxns"],
assert: assertGoldenTemplateFile(tt.goldenFile, tmpl),
}
cmd.runTestCmd(t)
})
}
}

View File

@@ -39,6 +39,7 @@ import (
"github.com/fluxcd/flux2/internal/flags"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen"
)
var logsCmd = &cobra.Command{
@@ -93,7 +94,7 @@ func init() {
}
func logsCmdRun(cmd *cobra.Command, args []string) error {
fluxSelector := fmt.Sprintf("app.kubernetes.io/instance=%s", logsArgs.fluxNamespace)
fluxSelector := fmt.Sprintf("%s=%s", manifestgen.PartOfLabelKey, manifestgen.PartOfLabelValue)
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()

View File

@@ -107,7 +107,8 @@ type rootFlags struct {
var rootArgs = NewRootFlags()
func init() {
rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace, "the namespace scope for this operation")
rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace,
"the namespace scope for this operation, can be set with FLUX_SYSTEM_NAMESPACE env var")
rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace")))
rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation")
@@ -134,6 +135,7 @@ func NewRootFlags() rootFlags {
func main() {
log.SetFlags(0)
configureKubeconfig()
configureDefaultNamespace()
if err := rootCmd.Execute(); err != nil {
logger.Failuref("%v", err)
os.Exit(1)
@@ -152,6 +154,13 @@ func configureKubeconfig() {
}
}
func configureDefaultNamespace() {
fromEnv := os.Getenv("FLUX_SYSTEM_NAMESPACE")
if fromEnv != "" && rootArgs.namespace == rootArgs.defaults.Namespace {
rootArgs.namespace = fromEnv
}
}
func homeDir() string {
if h := os.Getenv("HOME"); h != "" {
return h

View File

@@ -122,7 +122,7 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error {
}
if readyCond.Status != metav1.ConditionTrue {
return fmt.Errorf("%s reconciliation failed: ''%s", reconcile.kind, readyCond.Message)
return fmt.Errorf("%s reconciliation failed: '%s'", reconcile.kind, readyCond.Message)
}
logger.Successf(reconcile.object.successMessage())
return nil

17
cmd/flux/testdata/export/alert.yaml vendored Normal file
View File

@@ -0,0 +1,17 @@
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Alert
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
eventSeverity: info
eventSources:
- kind: GitRepository
name: '*'
- kind: Kustomization
name: '*'
providerRef:
name: slack
summary: Slacktest Notification

14
cmd/flux/testdata/export/bucket.yaml vendored Normal file
View File

@@ -0,0 +1,14 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
bucketName: podinfo
endpoint: s3.amazonaws.com
interval: 5m0s
provider: aws
region: us-east-1
timeout: 30s

16
cmd/flux/testdata/export/git-repo.yaml vendored Normal file
View File

@@ -0,0 +1,16 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
gitImplementation: go-git
interval: 5m0s
ref:
branch: main
secretRef:
name: flux-system
timeout: 20s
url: ssh://git@github.com/example/repo

View File

@@ -0,0 +1,18 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
chart:
spec:
chart: podinfo
reconcileStrategy: ChartVersion
sourceRef:
kind: HelmRepository
name: flux-systen
namespace: {{ .fluxns }}
version: '*'
interval: 5m0s

11
cmd/flux/testdata/export/helm-repo.yaml vendored Normal file
View File

@@ -0,0 +1,11 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 5m0s
timeout: 1m0s
url: https://stefanprodan.github.io/podinfo

View File

@@ -0,0 +1,13 @@
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImagePolicy
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
imageRepositoryRef:
name: flux-system
policy:
semver:
range: 5.0.x

View File

@@ -0,0 +1,10 @@
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
image: ghcr.io/test/podinfo
interval: 1m0s

View File

@@ -0,0 +1,20 @@
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
git:
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
interval: 1m0s
sourceRef:
kind: GitRepository
name: flux-system
update:
path: ./clusters/my-cluster
strategy: Setters

14
cmd/flux/testdata/export/ks.yaml vendored Normal file
View File

@@ -0,0 +1,14 @@
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 5m0s
path: ./infrastructure/
prune: true
sourceRef:
kind: GitRepository
name: flux-system

153
cmd/flux/testdata/export/objects.yaml vendored Normal file
View File

@@ -0,0 +1,153 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
name: slack
namespace: {{ .fluxns }}
spec:
type: slack
channel: 'A channel with spacess'
address: https://hooks.slack.com/services/mock
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Alert
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
summary: "Slacktest Notification"
providerRef:
name: slack
eventSeverity: info
eventSources:
- kind: "GitRepository"
name: "*"
- kind: "Kustomization"
name: "*"
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
image: ghcr.io/test/podinfo
interval: 1m0s
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImagePolicy
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
imageRepositoryRef:
name: flux-system
policy:
semver:
range: 5.0.x
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 1m0s
sourceRef:
kind: GitRepository
name: flux-system
git:
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
update:
path: ./clusters/my-cluster
strategy: Setters
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
ref:
branch: main
secretRef:
name: flux-system
interval: 5m
url: ssh://git@github.com/example/repo
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
path: ./infrastructure/
sourceRef:
kind: GitRepository
name: flux-system
interval: 5m
prune: true
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Receiver
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
type: github
events:
- "ping"
- "push"
secretRef:
name: webhook-token
resources:
- kind: GitRepository
name: flux-system
namespace: flux-system
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 5m
timeout: 1m0s
url: https://stefanprodan.github.io/podinfo
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 5m
chart:
spec:
chart: podinfo
sourceRef:
kind: HelmRepository
name: flux-systen
namespace: {{ .fluxns }}
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: Bucket
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
interval: 5m
provider: aws
bucketName: podinfo
endpoint: s3.amazonaws.com
region: us-east-1
timeout: 30s

11
cmd/flux/testdata/export/provider.yaml vendored Normal file
View File

@@ -0,0 +1,11 @@
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
name: slack
namespace: {{ .fluxns }}
spec:
address: https://hooks.slack.com/services/mock
channel: A channel with spacess
type: slack

18
cmd/flux/testdata/export/receiver.yaml vendored Normal file
View File

@@ -0,0 +1,18 @@
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Receiver
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
events:
- ping
- push
resources:
- kind: GitRepository
name: flux-system
namespace: flux-system
secretRef:
name: webhook-token
type: github

View File

@@ -0,0 +1,88 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .fluxns }}
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: flux-system
namespace: {{ .fluxns }}
spec:
path: ./clusters/production
sourceRef:
kind: GitRepository
name: flux-system
interval: 5m
prune: true
status:
conditions:
- lastTransitionTime: "2021-08-01T04:52:56Z"
message: 'Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
reason: ReconciliationSucceeded
status: "True"
type: Ready
inventory:
entries:
- id: _{{ .fluxns }}__Namespace
v: v1
- id: {{ .fluxns }}_helm-controller_apps_Deployment
v: v1
- id: {{ .fluxns }}_kustomize-controller_apps_Deployment
v: v1
- id: {{ .fluxns }}_notification-controller_apps_Deployment
v: v1
- id: {{ .fluxns }}_source-controller_apps_Deployment
v: v1
- id: {{ .fluxns }}_infrastructure_kustomize.toolkit.fluxcd.io_Kustomization
v: v1beta2
- id: {{ .fluxns }}_flux-system_source.toolkit.fluxcd.io_GitRepository
v: v1beta1
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: infrastructure
namespace: {{ .fluxns }}
spec:
path: ./infrastructure/production
sourceRef:
kind: GitRepository
name: flux-system
interval: 5m
prune: true
status:
conditions:
- lastTransitionTime: "2021-08-01T04:52:56Z"
message: 'Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
reason: ReconciliationSucceeded
status: "True"
type: Ready
inventory:
entries:
- id: _cert-manager__Namespace
v: v1
- id: cert-manager_cert-manager_source.toolkit.fluxcd.io_HelmRepository
v: v1beta1
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: empty
namespace: {{ .fluxns }}
spec:
path: ./apps/todo
sourceRef:
kind: GitRepository
name: flux-system
interval: 5m
prune: true
status:
conditions:
- lastTransitionTime: "2021-08-01T04:52:56Z"
message: 'Applied revision: main/696f056df216eea4f9401adbee0ff744d4df390f'
reason: ReconciliationSucceeded
status: "True"
type: Ready
---

View File

@@ -0,0 +1,5 @@
Kustomization/{{ .fluxns }}/flux-system
├── Kustomization/{{ .fluxns }}/infrastructure
│ └── HelmRepository/cert-manager/cert-manager
└── GitRepository/{{ .fluxns }}/flux-system

View File

@@ -0,0 +1,2 @@
Kustomization/{{ .fluxns }}/empty

11
cmd/flux/testdata/tree/tree.golden vendored Normal file
View File

@@ -0,0 +1,11 @@
Kustomization/{{ .fluxns }}/flux-system
├── Namespace/{{ .fluxns }}
├── Deployment/{{ .fluxns }}/helm-controller
├── Deployment/{{ .fluxns }}/kustomize-controller
├── Deployment/{{ .fluxns }}/notification-controller
├── Deployment/{{ .fluxns }}/source-controller
├── Kustomization/{{ .fluxns }}/infrastructure
│ ├── Namespace/cert-manager
│ └── HelmRepository/cert-manager/cert-manager
└── GitRepository/{{ .fluxns }}/flux-system

31
cmd/flux/tree.go Normal file
View File

@@ -0,0 +1,31 @@
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"github.com/spf13/cobra"
)
var treeCmd = &cobra.Command{
Use: "tree",
Short: "Print the resources reconciled by Flux",
Long: `The tree command shows the list of resources reconciled by a Flux object.'`,
}
func init() {
rootCmd.AddCommand(treeCmd)
}

View File

@@ -0,0 +1,270 @@
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bytes"
"compress/gzip"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/fluxcd/flux2/internal/tree"
"github.com/fluxcd/flux2/internal/utils"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
"github.com/fluxcd/pkg/ssa"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/cli-utils/pkg/object"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
)
var treeKsCmd = &cobra.Command{
Use: "kustomization [name]",
Aliases: []string{"ks", "kustomization"},
Short: "Print the resource inventory of a Kustomization",
Long: `The tree command prints the resource list reconciled by a Kustomization.'`,
Example: ` # Print the resources managed by the root Kustomization
flux tree kustomization flux-system
# Print the Flux resources managed by the root Kustomization
flux tree kustomization flux-system --compact`,
RunE: treeKsCmdRun,
ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)),
}
type TreeKsFlags struct {
compact bool
output string
}
var treeKsArgs TreeKsFlags
func init() {
treeKsCmd.Flags().BoolVar(&treeKsArgs.compact, "compact", false, "list Flux resources only.")
treeKsCmd.Flags().StringVarP(&treeKsArgs.output, "output", "o", "",
"the format in which the tree should be printed. can be 'json' or 'yaml'")
treeCmd.AddCommand(treeKsCmd)
}
func treeKsCmdRun(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("kustomization name is required")
}
name := args[0]
ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
defer cancel()
kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
if err != nil {
return err
}
k := &kustomizev1.Kustomization{}
err = kubeClient.Get(ctx, client.ObjectKey{
Namespace: rootArgs.namespace,
Name: name,
}, k)
if err != nil {
return err
}
kMeta, err := object.CreateObjMetadata(k.Namespace, k.Name,
schema.GroupKind{Group: kustomizev1.GroupVersion.Group, Kind: kustomizev1.KustomizationKind})
if err != nil {
return err
}
kTree := tree.New(kMeta)
err = treeKustomization(ctx, kTree, k, kubeClient, treeKsArgs.compact)
if err != nil {
return err
}
switch treeKsArgs.output {
case "json":
data, err := json.MarshalIndent(kTree, "", " ")
if err != nil {
return err
}
rootCmd.Println(string(data))
case "yaml":
data, err := yaml.Marshal(kTree)
if err != nil {
return err
}
rootCmd.Println(string(data))
default:
rootCmd.Println(kTree.Print())
}
return nil
}
func treeKustomization(ctx context.Context, tree tree.ObjMetadataTree, item *kustomizev1.Kustomization, kubeClient client.Client, compact bool) error {
if item.Status.Inventory == nil || len(item.Status.Inventory.Entries) == 0 {
return nil
}
compactGroup := "toolkit.fluxcd.io"
for _, entry := range item.Status.Inventory.Entries {
objMetadata, err := object.ParseObjMetadata(entry.ID)
if err != nil {
return err
}
if compact && !strings.Contains(objMetadata.GroupKind.Group, compactGroup) {
continue
}
if objMetadata.GroupKind.Group == kustomizev1.GroupVersion.Group &&
objMetadata.GroupKind.Kind == kustomizev1.KustomizationKind &&
objMetadata.Namespace == item.Namespace &&
objMetadata.Name == item.Name {
continue
}
ks := tree.Add(objMetadata)
if objMetadata.GroupKind.Group == helmv2.GroupVersion.Group &&
objMetadata.GroupKind.Kind == helmv2.HelmReleaseKind {
objects, err := getHelmReleaseInventory(
ctx, client.ObjectKey{
Namespace: objMetadata.Namespace,
Name: objMetadata.Name,
}, kubeClient)
if err != nil {
return err
}
for _, obj := range objects {
if compact && !strings.Contains(obj.GroupKind.Group, compactGroup) {
continue
}
ks.Add(obj)
}
}
if objMetadata.GroupKind.Group == kustomizev1.GroupVersion.Group &&
objMetadata.GroupKind.Kind == kustomizev1.KustomizationKind {
k := &kustomizev1.Kustomization{}
err = kubeClient.Get(ctx, client.ObjectKey{
Namespace: objMetadata.Namespace,
Name: objMetadata.Name,
}, k)
if err != nil {
return fmt.Errorf("failed to find object: %w", err)
}
err := treeKustomization(ctx, ks, k, kubeClient, compact)
if err != nil {
return err
}
}
}
return nil
}
type hrStorage struct {
Name string `json:"name,omitempty"`
Manifest string `json:"manifest,omitempty"`
}
func getHelmReleaseInventory(ctx context.Context, objectKey client.ObjectKey, kubeClient client.Client) ([]object.ObjMetadata, error) {
hr := &helmv2.HelmRelease{}
if err := kubeClient.Get(ctx, objectKey, hr); err != nil {
return nil, err
}
storageNamespace := hr.GetNamespace()
if hr.Spec.StorageNamespace != "" {
storageNamespace = hr.Spec.StorageNamespace
}
storageName := hr.GetName()
if hr.Spec.ReleaseName != "" {
storageName = hr.Spec.ReleaseName
} else if hr.Spec.TargetNamespace != "" {
storageName = strings.Join([]string{hr.Spec.TargetNamespace, hr.Name}, "-")
}
storageVersion := hr.Status.LastReleaseRevision
// skip release if it failed to install
if storageVersion < 1 {
return nil, nil
}
storageKey := client.ObjectKey{
Namespace: storageNamespace,
Name: fmt.Sprintf("sh.helm.release.v1.%s.v%v", storageName, storageVersion),
}
storageSecret := &corev1.Secret{}
if err := kubeClient.Get(ctx, storageKey, storageSecret); err != nil {
// skip release if it has no storage
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, fmt.Errorf("failed to find the Helm storage object for HelmRelease '%s': %w", objectKey.String(), err)
}
releaseData, releaseFound := storageSecret.Data["release"]
if !releaseFound {
return nil, fmt.Errorf("failed to decode the Helm storage object for HelmRelease '%s'", objectKey.String())
}
// adapted from https://github.com/helm/helm/blob/02685e94bd3862afcb44f6cd7716dbeb69743567/pkg/storage/driver/util.go
var b64 = base64.StdEncoding
b, err := b64.DecodeString(string(releaseData))
if err != nil {
return nil, err
}
var magicGzip = []byte{0x1f, 0x8b, 0x08}
if bytes.Equal(b[0:3], magicGzip) {
r, err := gzip.NewReader(bytes.NewReader(b))
if err != nil {
return nil, err
}
defer r.Close()
b2, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
b = b2
}
var rls hrStorage
if err := json.Unmarshal(b, &rls); err != nil {
return nil, fmt.Errorf("failed to decode the Helm storage object for HelmRelease '%s': %w", objectKey.String(), err)
}
objects, err := ssa.ReadObjects(strings.NewReader(rls.Manifest))
if err != nil {
return nil, fmt.Errorf("failed to read the Helm storage object for HelmRelease '%s': %w", objectKey.String(), err)
}
return object.UnstructuredsToObjMetas(objects)
}

View File

@@ -0,0 +1,64 @@
// +build unit
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"testing"
)
func TestTree(t *testing.T) {
cases := []struct {
name string
args string
objectFile string
goldenFile string
}{
{
"tree kustomization",
"tree kustomization flux-system",
"testdata/tree/kustomizations.yaml",
"testdata/tree/tree.golden",
},
{
"tree kustomization compact",
"tree kustomization flux-system --compact",
"testdata/tree/kustomizations.yaml",
"testdata/tree/tree-compact.golden",
},
{
"tree kustomization empty",
"tree kustomization empty",
"testdata/tree/kustomizations.yaml",
"testdata/tree/tree-empty.golden",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
tmpl := map[string]string{
"fluxns": allocateNamespace("flux-system"),
}
testEnv.CreateObjectFile(tc.objectFile, tmpl, t)
cmd := cmdTestCase{
args: tc.args + " -n=" + tmpl["fluxns"],
assert: assertGoldenTemplateFile(tc.goldenFile, tmpl),
}
cmd.runTestCmd(t)
})
}
}

View File

@@ -31,6 +31,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen"
helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
@@ -93,7 +94,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
uninstallFinalizers(ctx, kubeClient, uninstallArgs.dryRun)
logger.Actionf("deleting toolkit.fluxcd.io custom resource definitions")
uninstallCustomResourceDefinitions(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun)
uninstallCustomResourceDefinitions(ctx, kubeClient, uninstallArgs.dryRun)
if !uninstallArgs.keepNamespace {
uninstallNamespace(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun)
@@ -105,7 +106,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
func uninstallComponents(ctx context.Context, kubeClient client.Client, namespace string, dryRun bool) {
opts, dryRunStr := getDeleteOptions(dryRun)
selector := client.MatchingLabels{"app.kubernetes.io/instance": namespace}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
{
var list appsv1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(namespace), selector); err == nil {
@@ -262,9 +263,9 @@ func uninstallFinalizers(ctx context.Context, kubeClient client.Client, dryRun b
}
}
func uninstallCustomResourceDefinitions(ctx context.Context, kubeClient client.Client, namespace string, dryRun bool) {
func uninstallCustomResourceDefinitions(ctx context.Context, kubeClient client.Client, dryRun bool) {
opts, dryRunStr := getDeleteOptions(dryRun)
selector := client.MatchingLabels{"app.kubernetes.io/instance": namespace}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
{
var list apiextensionsv1.CustomResourceDefinitionList
if err := kubeClient.List(ctx, &list, selector); err == nil {

View File

@@ -28,6 +28,7 @@ import (
"sigs.k8s.io/yaml"
"github.com/fluxcd/flux2/internal/utils"
"github.com/fluxcd/flux2/pkg/manifestgen"
)
var versionCmd = &cobra.Command{
@@ -78,7 +79,7 @@ func versionCmdRun(cmd *cobra.Command, args []string) error {
return err
}
selector := client.MatchingLabels{"app.kubernetes.io/instance": rootArgs.namespace}
selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue}
var list v1.DeploymentList
if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err != nil {
return err

4
go.mod
View File

@@ -8,7 +8,7 @@ require (
github.com/cyphar/filepath-securejoin v0.2.2
github.com/fluxcd/go-git-providers v0.1.1
github.com/fluxcd/helm-controller/api v0.12.1
github.com/fluxcd/image-automation-controller/api v0.15.0
github.com/fluxcd/image-automation-controller/api v0.16.1
github.com/fluxcd/image-reflector-controller/api v0.13.0
github.com/fluxcd/kustomize-controller/api v0.16.0
github.com/fluxcd/notification-controller/api v0.18.1
@@ -18,7 +18,7 @@ require (
github.com/fluxcd/pkg/ssh v0.0.5
github.com/fluxcd/pkg/untar v0.0.5
github.com/fluxcd/pkg/version v0.0.1
github.com/fluxcd/source-controller/api v0.16.1
github.com/fluxcd/source-controller/api v0.17.2
github.com/go-errors/errors v1.4.0 // indirect
github.com/go-git/go-git/v5 v5.4.2
github.com/google/go-cmp v0.5.6

9
go.sum
View File

@@ -227,8 +227,8 @@ github.com/fluxcd/go-git-providers v0.1.1 h1:R4VafMOo1IlfEZcImApCeElge/HajhFvRzD
github.com/fluxcd/go-git-providers v0.1.1/go.mod h1:nRgNpHZmZhrsyNSma1JcAhjUG9xrqMGJcIUr9K7M7vk=
github.com/fluxcd/helm-controller/api v0.12.1 h1:rDyhMPvbhCxslqiNNG4nlfDCeYgrk6D+1ZKLsBS/Irs=
github.com/fluxcd/helm-controller/api v0.12.1/go.mod h1:zWmzV0s2SU4rEIGLPTt+dsaMs40OsNQgSgOATgJmxB0=
github.com/fluxcd/image-automation-controller/api v0.15.0 h1:KI350vt5JahE43D17VyLZFH4ZxtbnyHrekAd8AJsT5E=
github.com/fluxcd/image-automation-controller/api v0.15.0/go.mod h1:XvrEEpM1rVU+x1gQeXB/dj56w1dmOJRraTxQWOiuNME=
github.com/fluxcd/image-automation-controller/api v0.16.1 h1:EUiqALeUQY9zeOZNnviGZgKvbfmmhlMbaEuDath6/fc=
github.com/fluxcd/image-automation-controller/api v0.16.1/go.mod h1:wn6XjTpUnrQ2bakHhgJNAUj53snw50J0/+36pY4zXSE=
github.com/fluxcd/image-reflector-controller/api v0.13.0 h1:5kq0Jqh+ndZIye+4csfEbuos5GaXIiK77Gpx+ojo+f8=
github.com/fluxcd/image-reflector-controller/api v0.13.0/go.mod h1:lgQHGFz29OHmDU5Jwg689C/M+P/f9ujt6NS0zCLT0BQ=
github.com/fluxcd/kustomize-controller/api v0.16.0 h1:L/LRxS6oroGZe1AdElP3k1mnNIKGCpi0ntgHwJzdNYY=
@@ -250,9 +250,8 @@ github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7g
github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7RpQJ/nfw=
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
github.com/fluxcd/source-controller/api v0.16.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/fluxcd/source-controller/api v0.16.1 h1:3K0OueH0UA4iwIjKAXS72NaPBMO9OFx0xnB5S2am/AM=
github.com/fluxcd/source-controller/api v0.16.1/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/fluxcd/source-controller/api v0.17.2 h1:noePJGsevuvxWols6ErbowujuAHGWb/ZO8irtRHcVAc=
github.com/fluxcd/source-controller/api v0.17.2/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=

141
internal/tree/tree.go Normal file
View File

@@ -0,0 +1,141 @@
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Derived work from https://github.com/d6o/GoTree
Copyright (c) 2017 Diego Siqueira
*/
package tree
import (
"strings"
"github.com/fluxcd/pkg/ssa"
"sigs.k8s.io/cli-utils/pkg/object"
)
const (
newLine = "\n"
emptySpace = " "
middleItem = "├── "
continueItem = "│ "
lastItem = "└── "
)
type (
objMetadataTree struct {
Resource object.ObjMetadata `json:"resource"`
ResourceTree []ObjMetadataTree `json:"resources,omitempty"`
}
ObjMetadataTree interface {
Add(objMetadata object.ObjMetadata) ObjMetadataTree
AddTree(tree ObjMetadataTree)
Items() []ObjMetadataTree
Text() string
Print() string
}
printer struct {
}
Printer interface {
Print(ObjMetadataTree) string
}
)
func New(objMetadata object.ObjMetadata) ObjMetadataTree {
return &objMetadataTree{
Resource: objMetadata,
ResourceTree: []ObjMetadataTree{},
}
}
func (t *objMetadataTree) Add(objMetadata object.ObjMetadata) ObjMetadataTree {
n := New(objMetadata)
t.ResourceTree = append(t.ResourceTree, n)
return n
}
func (t *objMetadataTree) AddTree(tree ObjMetadataTree) {
t.ResourceTree = append(t.ResourceTree, tree)
}
func (t *objMetadataTree) Text() string {
return ssa.FmtObjMetadata(t.Resource)
}
func (t *objMetadataTree) Items() []ObjMetadataTree {
return t.ResourceTree
}
func (t *objMetadataTree) Print() string {
return newPrinter().Print(t)
}
func newPrinter() Printer {
return &printer{}
}
func (p *printer) Print(t ObjMetadataTree) string {
return t.Text() + newLine + p.printItems(t.Items(), []bool{})
}
func (p *printer) printText(text string, spaces []bool, last bool) string {
var result string
for _, space := range spaces {
if space {
result += emptySpace
} else {
result += continueItem
}
}
indicator := middleItem
if last {
indicator = lastItem
}
var out string
lines := strings.Split(text, "\n")
for i := range lines {
text := lines[i]
if i == 0 {
out += result + indicator + text + newLine
continue
}
if last {
indicator = emptySpace
} else {
indicator = continueItem
}
out += result + indicator + text + newLine
}
return out
}
func (p *printer) printItems(t []ObjMetadataTree, spaces []bool) string {
var result string
for i, f := range t {
last := i == len(t)-1
result += p.printText(f.Text(), spaces, last)
if len(f.Items()) > 0 {
spacesChild := append(spaces, last)
result += p.printItems(f.Items(), spacesChild)
}
}
return result
}

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.15.0/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.15.0/image-automation-controller.deployment.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.16.1/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.16.1/image-automation-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.16.1/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.16.1/source-controller.deployment.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.17.2/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.17.2/source-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,9 +1,9 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.16.1/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.17.2/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.16.0/kustomize-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.12.1/helm-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.18.1/notification-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.13.0/image-reflector-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.15.0/image-automation-controller.crds.yaml
- https://github.com/fluxcd/image-automation-controller/releases/download/v0.16.1/image-automation-controller.crds.yaml

View File

@@ -65,7 +65,15 @@ func fetch(ctx context.Context, url, version, dir string) error {
func generate(base string, options Options) error {
if containsItemString(options.Components, options.NotificationController) {
options.EventsAddr = fmt.Sprintf("http://%s/", options.NotificationController)
// We need to use full domain name here, as some users may deploy flux
// in environments that use http proxy.
//
// In such environments they normally add `.cluster.local` and `.local`
// suffixes to `no_proxy` variable in order to prevent cluster-local
// traffic from going through http proxy. Without fully specified
// domain they need to mention `notifications-controller` explicity in
// `no_proxy` variable after debugging http proxy logs.
options.EventsAddr = fmt.Sprintf("http://%s.%s.svc.%s/", options.NotificationController, options.Namespace, options.ClusterDomain)
}
if err := execTemplate(options, namespaceTmpl, path.Join(base, "namespace.yaml")); err != nil {

26
pkg/manifestgen/labels.go Normal file
View File

@@ -0,0 +1,26 @@
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package manifestgen
// These labels can be used to track down the namespace, custom resource definitions, deployments,
// services, network policies, service accounts, cluster roles and cluster role bindings belonging to Flux.
const (
PartOfLabelKey = "app.kubernetes.io/part-of"
PartOfLabelValue = "flux"
InstanceLabelKey = "app.kubernetes.io/instance"
VersionLabelKey = "app.kubernetes.io/version"
)

View File

@@ -24,6 +24,8 @@ import (
securejoin "github.com/cyphar/filepath-securejoin"
)
const GenWarning = "# This manifest was generated by flux bootstrap. DO NOT EDIT."
// Manifest holds the data of a multi-doc YAML
type Manifest struct {
// Relative path to the YAML file

View File

@@ -107,7 +107,7 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
return &manifestgen.Manifest{
Path: path.Join(options.TargetPath, options.Namespace, options.ManifestFile),
Content: fmt.Sprintf("---\n%s---\n%s", resourceToString(gitData), resourceToString(ksData)),
Content: fmt.Sprintf("%s\n---\n%s---\n%s", manifestgen.GenWarning, resourceToString(gitData), resourceToString(ksData)),
}, nil
}

View File

@@ -5,13 +5,13 @@ go 1.16
require (
github.com/Azure/azure-event-hubs-go/v3 v3.3.13
github.com/fluxcd/helm-controller/api v0.12.1
github.com/fluxcd/image-automation-controller/api v0.15.0
github.com/fluxcd/image-automation-controller/api v0.16.0
github.com/fluxcd/image-reflector-controller/api v0.13.0
github.com/fluxcd/kustomize-controller/api v0.16.0
github.com/fluxcd/notification-controller/api v0.18.1
github.com/fluxcd/pkg/apis/meta v0.10.1
github.com/fluxcd/pkg/runtime v0.12.1
github.com/fluxcd/source-controller/api v0.16.1
github.com/fluxcd/source-controller/api v0.17.0
github.com/hashicorp/terraform-exec v0.14.0
github.com/libgit2/git2go/v31 v31.6.1
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5

View File

@@ -193,8 +193,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxcd/helm-controller/api v0.12.1 h1:rDyhMPvbhCxslqiNNG4nlfDCeYgrk6D+1ZKLsBS/Irs=
github.com/fluxcd/helm-controller/api v0.12.1/go.mod h1:zWmzV0s2SU4rEIGLPTt+dsaMs40OsNQgSgOATgJmxB0=
github.com/fluxcd/image-automation-controller/api v0.15.0 h1:KI350vt5JahE43D17VyLZFH4ZxtbnyHrekAd8AJsT5E=
github.com/fluxcd/image-automation-controller/api v0.15.0/go.mod h1:XvrEEpM1rVU+x1gQeXB/dj56w1dmOJRraTxQWOiuNME=
github.com/fluxcd/image-automation-controller/api v0.16.0 h1:pPvEdb8Q7LgNVfugF3+/z2JQdUZ4ecYWrXiezLPov0w=
github.com/fluxcd/image-automation-controller/api v0.16.0/go.mod h1:tEQCFKGgxii7zfXti2MxixwFbxhEXnVJqLGM2x9zlGw=
github.com/fluxcd/image-reflector-controller/api v0.13.0 h1:5kq0Jqh+ndZIye+4csfEbuos5GaXIiK77Gpx+ojo+f8=
github.com/fluxcd/image-reflector-controller/api v0.13.0/go.mod h1:lgQHGFz29OHmDU5Jwg689C/M+P/f9ujt6NS0zCLT0BQ=
github.com/fluxcd/kustomize-controller/api v0.16.0 h1:L/LRxS6oroGZe1AdElP3k1mnNIKGCpi0ntgHwJzdNYY=
@@ -210,9 +210,8 @@ github.com/fluxcd/pkg/apis/meta v0.10.1/go.mod h1:yUblM2vg+X8TE3A2VvJfdhkGmg+uqB
github.com/fluxcd/pkg/runtime v0.12.0/go.mod h1:EyaTR2TOYcjL5U//C4yH3bt2tvTgIOSXpVRbWxUn/C4=
github.com/fluxcd/pkg/runtime v0.12.1 h1:r0KQG80gKY1NMp62FggSEdFBV60ZfbnA2RHL9y06DOY=
github.com/fluxcd/pkg/runtime v0.12.1/go.mod h1:9czAjokV0w22eYGR9/SQKUHXhvh7ISNVgc/6a6YMBE8=
github.com/fluxcd/source-controller/api v0.16.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/fluxcd/source-controller/api v0.16.1 h1:3K0OueH0UA4iwIjKAXS72NaPBMO9OFx0xnB5S2am/AM=
github.com/fluxcd/source-controller/api v0.16.1/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/fluxcd/source-controller/api v0.17.0 h1:skXx2H5SeziUTwJrp9MPJNwTtYTctJMQ7ZIJfLmg9b0=
github.com/fluxcd/source-controller/api v0.17.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=

View File

@@ -19,7 +19,6 @@ package test
import (
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -49,7 +48,7 @@ const defaultBranch = "main"
// getKubernetesCredentials returns a path to a kubeconfig file and a kube client instance.
func getKubernetesCredentials(kubeconfig, aksHost, aksCert, aksKey, aksCa string) (string, client.Client, error) {
tmpDir, err := ioutil.TempDir("", "*-azure-e2e")
tmpDir, err := os.MkdirTemp("", "*-azure-e2e")
if err != nil {
return "", nil, err
}
@@ -309,7 +308,7 @@ func getRepository(url, branchName string, overrideBranch bool, password string)
checkoutBranch = branchName
}
tmpDir, err := ioutil.TempDir("", "*-repository")
tmpDir, err := os.MkdirTemp("", "*-repository")
if err != nil {
return nil, "", err
}

99
tests/bootstrap/main.go Normal file
View File

@@ -0,0 +1,99 @@
package main
import (
"context"
"log"
"os"
"github.com/fluxcd/go-git-providers/github"
"github.com/fluxcd/go-git-providers/gitprovider"
"k8s.io/client-go/util/retry"
)
func main() {
ks := "test-cluster/flux-system/kustomization.yaml"
patchName := "test-cluster/flux-system/gotk-patches.yaml"
ksContent := `apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- path: gotk-patches.yaml
target:
kind: Deployment`
patchContent := `apiVersion: apps/v1
kind: Deployment
metadata:
name: all-flux-components
spec:
template:
metadata:
annotations:
# Required by Kubernetes node autoscaler
cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
spec:
securityContext:
runAsUser: 10000
fsGroup: 1337
containers:
- name: manager
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
runAsNonRoot: true
capabilities:
drop:
- ALL
`
commitFiles := []gitprovider.CommitFile{
{
Path: &ks,
Content: &ksContent,
},
{
Path: &patchName,
Content: &patchContent,
},
}
orgName := os.Getenv("GITHUB_ORG_NAME")
repoName := os.Getenv("GITHUB_REPO_NAME")
githubToken := os.Getenv(github.TokenVariable)
client, err := github.NewClient(github.WithOAuth2Token(githubToken))
if err != nil {
log.Fatalf("error initializing github client: %s", err)
}
repoRef := gitprovider.OrgRepositoryRef{
OrganizationRef: gitprovider.OrganizationRef{
Organization: orgName,
Domain: github.DefaultDomain,
},
RepositoryName: repoName,
}
if ok, err := client.HasTokenPermission(context.Background(), gitprovider.TokenPermissionRWRepository); err != nil {
log.Fatalf("error getting token permission: %s", err)
} else {
if !ok {
log.Fatal("token has no write permissions")
}
}
var repo gitprovider.OrgRepository
err = retry.OnError(retry.DefaultRetry, func(err error) bool {
return err != nil
}, func() error {
repo, err = client.OrgRepositories().Get(context.Background(), repoRef)
return err
})
if err != nil {
log.Fatalf("error getting %s repository in org %s: %s", repoRef.RepositoryName, repoRef.Organization, err)
}
_, err = repo.Commits().Create(context.Background(), "main", "add patch manifest 3", commitFiles)
if err != nil {
log.Fatalf("error making commit: %s", err)
}
}