Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23912e4091 | ||
|
|
17468cb5f5 | ||
|
|
5ea7aa0a75 | ||
|
|
7792cd6a10 | ||
|
|
237d186207 | ||
|
|
c41487598e | ||
|
|
2c0aa3c3af | ||
|
|
cedb33b2b9 | ||
|
|
06a3aa2c60 | ||
|
|
3fadc94711 | ||
|
|
61d02bf5e4 | ||
|
|
a62976461e | ||
|
|
d7a893acf9 | ||
|
|
0c67e75fb6 | ||
|
|
e6b84c4cfc | ||
|
|
5d2e793386 | ||
|
|
f0517906b7 | ||
|
|
16fa167931 | ||
|
|
b036999b8c | ||
|
|
1911766b7b | ||
|
|
9f7835d818 | ||
|
|
1df45e4857 | ||
|
|
47a1743965 | ||
|
|
d5844bbdaa | ||
|
|
128c87ab33 | ||
|
|
f4adcae79a | ||
|
|
ba4df070cf | ||
|
|
ce4ecfb388 | ||
|
|
e6006e0833 |
@@ -57,6 +57,7 @@ var (
|
||||
bootstrapArch = flags.Arch(defaults.Arch)
|
||||
bootstrapLogLevel = flags.LogLevel(defaults.LogLevel)
|
||||
bootstrapRequiredComponents = []string{"source-controller", "kustomize-controller"}
|
||||
bootstrapTokenAuth bool
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -75,14 +76,16 @@ func init() {
|
||||
bootstrapCmd.PersistentFlags().Var(&bootstrapArch, "arch", bootstrapArch.Description())
|
||||
bootstrapCmd.PersistentFlags().StringVar(&bootstrapBranch, "branch", bootstrapDefaultBranch,
|
||||
"default branch (for GitHub this must match the default branch setting for the organization)")
|
||||
rootCmd.AddCommand(bootstrapCmd)
|
||||
bootstrapCmd.PersistentFlags().BoolVar(&bootstrapWatchAllNamespaces, "watch-all-namespaces", true,
|
||||
"watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed")
|
||||
bootstrapCmd.PersistentFlags().BoolVar(&bootstrapNetworkPolicy, "network-policy", true,
|
||||
"deny ingress access to the toolkit controllers from other namespaces using network policies")
|
||||
bootstrapCmd.PersistentFlags().BoolVar(&bootstrapTokenAuth, "token-auth", false,
|
||||
"when enabled, the personal access token will be used instead of SSH deploy key")
|
||||
bootstrapCmd.PersistentFlags().Var(&bootstrapLogLevel, "log-level", bootstrapLogLevel.Description())
|
||||
bootstrapCmd.PersistentFlags().StringVar(&bootstrapManifestsPath, "manifests", "", "path to the manifest directory")
|
||||
bootstrapCmd.PersistentFlags().MarkHidden("manifests")
|
||||
rootCmd.AddCommand(bootstrapCmd)
|
||||
}
|
||||
|
||||
func bootstrapValidate() error {
|
||||
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fluxcd/flux2/internal/utils"
|
||||
"github.com/fluxcd/pkg/git"
|
||||
@@ -35,7 +37,7 @@ var bootstrapGitHubCmd = &cobra.Command{
|
||||
Use: "github",
|
||||
Short: "Bootstrap toolkit components in a GitHub repository",
|
||||
Long: `The bootstrap github command creates the GitHub repository if it doesn't exists and
|
||||
commits the toolkit components manifests to the master branch.
|
||||
commits the toolkit components manifests to the main branch.
|
||||
Then it configures the target cluster to synchronize with the repository.
|
||||
If the toolkit components are present on the cluster,
|
||||
the bootstrap command will perform an upgrade if needed.`,
|
||||
@@ -54,8 +56,11 @@ the bootstrap command will perform an upgrade if needed.`,
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
flux bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise using SSH auth
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --ssh-hostname=<domain>
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise using HTTPS auth
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --token-auth
|
||||
|
||||
# Run bootstrap for a an existing repository with a branch named main
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --branch=main
|
||||
@@ -64,15 +69,16 @@ the bootstrap command will perform an upgrade if needed.`,
|
||||
}
|
||||
|
||||
var (
|
||||
ghOwner string
|
||||
ghRepository string
|
||||
ghInterval time.Duration
|
||||
ghPersonal bool
|
||||
ghPrivate bool
|
||||
ghHostname string
|
||||
ghPath string
|
||||
ghTeams []string
|
||||
ghDelete bool
|
||||
ghOwner string
|
||||
ghRepository string
|
||||
ghInterval time.Duration
|
||||
ghPersonal bool
|
||||
ghPrivate bool
|
||||
ghHostname string
|
||||
ghPath string
|
||||
ghTeams []string
|
||||
ghDelete bool
|
||||
ghSSHHostname string
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -87,6 +93,7 @@ func init() {
|
||||
bootstrapGitHubCmd.Flags().BoolVar(&ghPrivate, "private", true, "is private repository")
|
||||
bootstrapGitHubCmd.Flags().DurationVar(&ghInterval, "interval", time.Minute, "sync interval")
|
||||
bootstrapGitHubCmd.Flags().StringVar(&ghHostname, "hostname", git.GitHubDefaultHostname, "GitHub hostname")
|
||||
bootstrapGitHubCmd.Flags().StringVar(&ghSSHHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
||||
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)")
|
||||
@@ -110,6 +117,10 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if ghSSHHostname != "" {
|
||||
repository.SSHHost = ghSSHHostname
|
||||
}
|
||||
|
||||
provider := &git.GithubProvider{
|
||||
IsPrivate: ghPrivate,
|
||||
IsPersonal: ghPersonal,
|
||||
@@ -155,7 +166,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// clone repository and checkout the master branch
|
||||
// clone repository and checkout the main branch
|
||||
if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -201,28 +212,45 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
||||
logger.Successf("install completed")
|
||||
}
|
||||
|
||||
// setup SSH deploy key
|
||||
if shouldCreateDeployKey(ctx, kubeClient, namespace) {
|
||||
logger.Actionf("configuring deploy key")
|
||||
u, err := url.Parse(repository.GetSSH())
|
||||
if err != nil {
|
||||
return fmt.Errorf("git URL parse failed: %w", err)
|
||||
if bootstrapTokenAuth {
|
||||
// setup HTTPS token auth
|
||||
secret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
Namespace: namespace,
|
||||
},
|
||||
StringData: map[string]string{
|
||||
"username": "git",
|
||||
"password": ghToken,
|
||||
},
|
||||
}
|
||||
|
||||
key, err := generateDeployKey(ctx, kubeClient, u, namespace)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generating deploy key failed: %w", err)
|
||||
}
|
||||
|
||||
keyName := "flux"
|
||||
if ghPath != "" {
|
||||
keyName = fmt.Sprintf("flux-%s", ghPath)
|
||||
}
|
||||
|
||||
if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil {
|
||||
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
|
||||
return err
|
||||
} else if changed {
|
||||
logger.Successf("deploy key configured")
|
||||
}
|
||||
} else {
|
||||
// setup SSH deploy key
|
||||
if shouldCreateDeployKey(ctx, kubeClient, namespace) {
|
||||
logger.Actionf("configuring deploy key")
|
||||
u, err := url.Parse(repository.GetSSH())
|
||||
if err != nil {
|
||||
return fmt.Errorf("git URL parse failed: %w", err)
|
||||
}
|
||||
|
||||
key, err := generateDeployKey(ctx, kubeClient, u, namespace)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generating deploy key failed: %w", err)
|
||||
}
|
||||
|
||||
keyName := "flux"
|
||||
if ghPath != "" {
|
||||
keyName = fmt.Sprintf("flux-%s", ghPath)
|
||||
}
|
||||
|
||||
if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil {
|
||||
return err
|
||||
} else if changed {
|
||||
logger.Successf("deploy key configured")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,22 +45,22 @@ the bootstrap command will perform an upgrade if needed.`,
|
||||
export GITLAB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo using HTTPS token authentication
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --token-auth
|
||||
|
||||
# Run bootstrap for a private repo using SSH authentication
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --ssh-hostname=gitlab.com
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal --token-auth
|
||||
|
||||
# Run bootstrap for a private repo hosted on a GitLab server
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> --token-auth
|
||||
|
||||
# Run bootstrap for a an existing repository with a branch named main
|
||||
flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
|
||||
flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main --token-auth
|
||||
`,
|
||||
RunE: bootstrapGitLabCmdRun,
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func init() {
|
||||
bootstrapGitLabCmd.Flags().BoolVar(&glPrivate, "private", true, "is private repository")
|
||||
bootstrapGitLabCmd.Flags().DurationVar(&glInterval, "interval", time.Minute, "sync interval")
|
||||
bootstrapGitLabCmd.Flags().StringVar(&glHostname, "hostname", git.GitLabDefaultHostname, "GitLab hostname")
|
||||
bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, when specified a deploy key will be added to the repository")
|
||||
bootstrapGitLabCmd.Flags().StringVar(&glSSHHostname, "ssh-hostname", "", "GitLab SSH hostname, to be used when the SSH host differs from the HTTPS one")
|
||||
bootstrapGitLabCmd.Flags().StringVar(&glPath, "path", "", "repository path, when specified the cluster sync will be scoped to this path")
|
||||
|
||||
bootstrapCmd.AddCommand(bootstrapGitLabCmd)
|
||||
@@ -180,7 +180,22 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
||||
|
||||
repoURL := repository.GetURL()
|
||||
|
||||
if glSSHHostname != "" {
|
||||
if bootstrapTokenAuth {
|
||||
// setup HTTPS token auth
|
||||
secret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
Namespace: namespace,
|
||||
},
|
||||
StringData: map[string]string{
|
||||
"username": "git",
|
||||
"password": glToken,
|
||||
},
|
||||
}
|
||||
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// setup SSH deploy key
|
||||
repoURL = repository.GetSSH()
|
||||
if shouldCreateDeployKey(ctx, kubeClient, namespace) {
|
||||
@@ -206,21 +221,6 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
||||
logger.Successf("deploy key configured")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// setup HTTPS token auth
|
||||
secret := corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: namespace,
|
||||
Namespace: namespace,
|
||||
},
|
||||
StringData: map[string]string{
|
||||
"username": "git",
|
||||
"password": glToken,
|
||||
},
|
||||
}
|
||||
if err := upsertSecret(ctx, kubeClient, secret); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// configure repo synchronization
|
||||
|
||||
@@ -180,6 +180,10 @@ func componentsCheck() bool {
|
||||
} else {
|
||||
logger.Successf("%s is healthy", deployment)
|
||||
}
|
||||
kubectlArgs = []string{"-n", namespace, "get", "deployment", deployment, "-o", "jsonpath=\"{..image}\""}
|
||||
if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, kubectlArgs...); err == nil {
|
||||
logger.Actionf(strings.TrimPrefix(strings.TrimSuffix(output, "\""), "\""))
|
||||
}
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ var (
|
||||
ksSANamespace string
|
||||
ksDecryptionProvider flags.DecryptionProvider
|
||||
ksDecryptionSecret string
|
||||
ksTargetNamespace string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -97,6 +98,7 @@ func init() {
|
||||
createKsCmd.Flags().StringVar(&ksSANamespace, "sa-namespace", "", "service account namespace")
|
||||
createKsCmd.Flags().Var(&ksDecryptionProvider, "decryption-provider", ksDecryptionProvider.Description())
|
||||
createKsCmd.Flags().StringVar(&ksDecryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption")
|
||||
createKsCmd.Flags().StringVar(&ksTargetNamespace, "target-namespace", "", "overrides the namespace of all Kustomization objects reconciled by this Kustomization")
|
||||
createCmd.AddCommand(createKsCmd)
|
||||
}
|
||||
|
||||
@@ -139,8 +141,9 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
|
||||
Kind: ksSource.Kind,
|
||||
Name: ksSource.Name,
|
||||
},
|
||||
Suspend: false,
|
||||
Validation: ksValidation,
|
||||
Suspend: false,
|
||||
Validation: ksValidation,
|
||||
TargetNamespace: ksTargetNamespace,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if export {
|
||||
for i, _ := range tenantNamespaces {
|
||||
if err := exportTenant(namespaces[i], roleBindings[1]); err != nil {
|
||||
if err := exportTenant(namespaces[i], roleBindings[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
|
||||
--log-level logLevel log level, available options are: (debug, info, error) (default info)
|
||||
--network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true)
|
||||
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
|
||||
--token-auth when enabled, the personal access token will be used instead of SSH deploy key
|
||||
-v, --version string toolkit version (default "latest")
|
||||
--watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true)
|
||||
```
|
||||
|
||||
@@ -5,7 +5,7 @@ Bootstrap toolkit components in a GitHub repository
|
||||
### Synopsis
|
||||
|
||||
The bootstrap github command creates the GitHub repository if it doesn't exists and
|
||||
commits the toolkit components manifests to the master branch.
|
||||
commits the toolkit components manifests to the main branch.
|
||||
Then it configures the target cluster to synchronize with the repository.
|
||||
If the toolkit components are present on the cluster,
|
||||
the bootstrap command will perform an upgrade if needed.
|
||||
@@ -32,8 +32,11 @@ flux bootstrap github [flags]
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
flux bootstrap github --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain>
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise using SSH auth
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --ssh-hostname=<domain>
|
||||
|
||||
# Run bootstrap for a private repo hosted on GitHub Enterprise using HTTPS auth
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --hostname=<domain> --token-auth
|
||||
|
||||
# Run bootstrap for a an existing repository with a branch named main
|
||||
flux bootstrap github --owner=<organization> --repository=<repo name> --branch=main
|
||||
@@ -43,15 +46,16 @@ flux bootstrap github [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for github
|
||||
--hostname string GitHub hostname (default "github.com")
|
||||
--interval duration sync interval (default 1m0s)
|
||||
--owner string GitHub user or organization name
|
||||
--path string repository path, when specified the cluster sync will be scoped to this path
|
||||
--personal is personal repository
|
||||
--private is private repository (default true)
|
||||
--repository string GitHub repository name
|
||||
--team stringArray GitHub team to be given maintainer access
|
||||
-h, --help help for github
|
||||
--hostname string GitHub hostname (default "github.com")
|
||||
--interval duration sync interval (default 1m0s)
|
||||
--owner string GitHub user or organization name
|
||||
--path string repository path, when specified the cluster sync will be scoped to this path
|
||||
--personal is personal repository
|
||||
--private is private repository (default true)
|
||||
--repository string GitHub repository name
|
||||
--ssh-hostname string GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one
|
||||
--team stringArray GitHub team to be given maintainer access
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -68,6 +72,7 @@ flux bootstrap github [flags]
|
||||
--network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true)
|
||||
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--token-auth when enabled, the personal access token will be used instead of SSH deploy key
|
||||
--verbose print generated objects
|
||||
-v, --version string toolkit version (default "latest")
|
||||
--watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true)
|
||||
|
||||
@@ -21,22 +21,22 @@ flux bootstrap gitlab [flags]
|
||||
export GITLAB_TOKEN=<my-token>
|
||||
|
||||
# Run bootstrap for a private repo using HTTPS token authentication
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --token-auth
|
||||
|
||||
# Run bootstrap for a private repo using SSH authentication
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --ssh-hostname=gitlab.com
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name>
|
||||
|
||||
# Run bootstrap for a repository path
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --path=dev-cluster
|
||||
|
||||
# Run bootstrap for a public repository on a personal account
|
||||
flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal=true
|
||||
flux bootstrap gitlab --owner=<user> --repository=<repo name> --private=false --personal --token-auth
|
||||
|
||||
# Run bootstrap for a private repo hosted on a GitLab server
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain>
|
||||
flux bootstrap gitlab --owner=<group> --repository=<repo name> --hostname=<domain> --token-auth
|
||||
|
||||
# Run bootstrap for a an existing repository with a branch named main
|
||||
flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main
|
||||
flux bootstrap gitlab --owner=<organization> --repository=<repo name> --branch=main --token-auth
|
||||
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ flux bootstrap gitlab [flags]
|
||||
--personal is personal repository
|
||||
--private is private repository (default true)
|
||||
--repository string GitLab repository name
|
||||
--ssh-hostname string GitLab SSH hostname, when specified a deploy key will be added to the repository
|
||||
--ssh-hostname string GitLab SSH hostname, to be used when the SSH host differs from the HTTPS one
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -68,6 +68,7 @@ flux bootstrap gitlab [flags]
|
||||
--network-policy deny ingress access to the toolkit controllers from other namespaces using network policies (default true)
|
||||
--registry string container registry where the toolkit images are published (default "ghcr.io/fluxcd")
|
||||
--timeout duration timeout for this operation (default 5m0s)
|
||||
--token-auth when enabled, the personal access token will be used instead of SSH deploy key
|
||||
--verbose print generated objects
|
||||
-v, --version string toolkit version (default "latest")
|
||||
--watch-all-namespaces watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed (default true)
|
||||
|
||||
@@ -55,6 +55,7 @@ flux create kustomization [name] [flags]
|
||||
--sa-name string service account name
|
||||
--sa-namespace string service account namespace
|
||||
--source kustomizationSource source that contains the Kubernetes manifests in the format '[<kind>/]<name>',where kind can be one of: (GitRepository, Bucket), if kind is not specified it defaults to GitRepository
|
||||
--target-namespace string overrides the namespace of all Kustomization objects reconciled by this Kustomization
|
||||
--validation string validate the manifests before applying them on the cluster, can be 'client' or 'server'
|
||||
```
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ $ flux install \
|
||||
--arch=amd64 \
|
||||
--network-policy=true \
|
||||
--watch-all-namespaces=true \
|
||||
--namespace=flux-systen
|
||||
--namespace=flux-system
|
||||
✚ generating manifests
|
||||
✔ manifests build completed
|
||||
► installing components in flux-system namespace
|
||||
|
||||
@@ -710,7 +710,7 @@ The custom resources for the Helm Controller would be:
|
||||
---
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta1
|
||||
kind: HelmRepository
|
||||
metdata:
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: default
|
||||
spec:
|
||||
@@ -724,6 +724,7 @@ metadata:
|
||||
namespace: default
|
||||
spec:
|
||||
interval: 5m
|
||||
releaseName: default-podinfo
|
||||
chart:
|
||||
spec:
|
||||
chart: podinfo
|
||||
|
||||
@@ -257,6 +257,38 @@ The definition of the listed keys is as follows:
|
||||
You can read more about the available formats and limitations in
|
||||
the [Helm documentation](https://helm.sh/docs/intro/using_helm/#the-format-and-limitations-of---set).
|
||||
|
||||
## Refer to values inside the chart
|
||||
|
||||
It is possible to replace the `values.yaml` with a different file present inside the Helm chart.
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2beta1
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: mongodb
|
||||
namespace: mongodb
|
||||
spec:
|
||||
interval: 5m
|
||||
chart:
|
||||
spec:
|
||||
chart: mongodb
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: bitnami
|
||||
valuesFile: values-production.yaml
|
||||
values:
|
||||
replicaCount: 5
|
||||
```
|
||||
|
||||
If the `spec.chart.spec.valuesFile` doesn't exists inside the chart, helm-controller will not be able to
|
||||
fetch the chart. To determine why the `HelmChart` fails to produce an artifact, you can inspect the status with:
|
||||
|
||||
```console
|
||||
$ kubectl get helmcharts --all-namespaces
|
||||
NAME READY STATUS
|
||||
mongodb False failed to locate override values file: values-prod.yaml
|
||||
```
|
||||
|
||||
## Configure notifications
|
||||
|
||||
The default toolkit installation configures the helm-controller to
|
||||
|
||||
@@ -44,12 +44,12 @@ Kubernetes cluster and configure it to manage itself from a Git
|
||||
repository.
|
||||
|
||||
The bootstrap creates a Git repository if one doesn't exist and
|
||||
commits the Flux components manifests to the main branch. Then it
|
||||
commits the Flux components manifests to the main branch. Then it
|
||||
configures the target cluster to synchronize with that repository by
|
||||
setting up SSH deploy keys.
|
||||
|
||||
If the Flux components are present on the cluster, the bootstrap
|
||||
command will perform an upgrade if needed. The bootstrap is
|
||||
command will perform an upgrade if needed. The bootstrap is
|
||||
idempotent, it's safe to run the command as many times as you want.
|
||||
|
||||
You can choose what components to install and for which cluster with:
|
||||
@@ -57,7 +57,7 @@ You can choose what components to install and for which cluster with:
|
||||
```sh
|
||||
flux bootstrap <GIT-PROVIDER> \
|
||||
--components=source-controller,kustomize-controller,helm-controller,notification-controller \
|
||||
--path=my-cluster \
|
||||
--path=clusters/my-cluster \
|
||||
--version=latest
|
||||
```
|
||||
|
||||
@@ -71,15 +71,16 @@ If you wish to install a specific version, use the Flux
|
||||
|
||||
With `--path` you can configure the directory which will be used to reconcile the target cluster.
|
||||
To control multiple clusters from the same Git repository, you have to set a unique path per
|
||||
cluster e.g. `staging-cluster` and `production-cluster`:
|
||||
cluster e.g. `clusters/staging` and `clusters/production`:
|
||||
|
||||
```sh
|
||||
├── staging-cluster # <- path=staging-cluster
|
||||
./clusters/
|
||||
├── staging # <- path=clusters/staging
|
||||
│ └── flux-system # <- namespace dir generated by bootstrap
|
||||
│ ├── gotk-components.yaml
|
||||
│ ├── gotk-sync.yaml
|
||||
│ └── kustomization.yaml
|
||||
└── production-cluster # <- path=production-cluster
|
||||
└── production-cluster # <- path=clusters/production
|
||||
└── flux-system
|
||||
```
|
||||
|
||||
@@ -87,6 +88,9 @@ cluster e.g. `staging-cluster` and `production-cluster`:
|
||||
If you wish to change the branch to something else than main, create the repository manually,
|
||||
push a branch to origin and then use `flux bootstrap <GIT-PROVIDER> --branch=your-branch`.
|
||||
|
||||
For examples on how you can structure your Git repository see:
|
||||
* [flux2-kustomize-helm-example](https://github.com/fluxcd/flux2-kustomize-helm-example)
|
||||
|
||||
### 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)
|
||||
@@ -104,7 +108,7 @@ Run the bootstrap for a repository on your personal GitHub account:
|
||||
flux bootstrap github \
|
||||
--owner=my-github-username \
|
||||
--repository=my-repository \
|
||||
--path=my-cluster \
|
||||
--path=clusters/my-cluster \
|
||||
--personal
|
||||
```
|
||||
|
||||
@@ -116,7 +120,7 @@ flux bootstrap github \
|
||||
--repository=my-repository \
|
||||
--team=team1-slug \
|
||||
--team=team2-slug \
|
||||
--path=my-cluster
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
When you specify a list of teams, those teams will be granted maintainer access to the repository.
|
||||
@@ -126,10 +130,23 @@ To run the bootstrap for a repository hosted on GitHub Enterprise, you have to s
|
||||
```sh
|
||||
flux bootstrap github \
|
||||
--hostname=my-github-enterprise.com \
|
||||
--ssh-hostname=my-github-enterprise.com \
|
||||
--owner=my-github-organization \
|
||||
--repository=my-repository \
|
||||
--branch=main \
|
||||
--path=my-cluster
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
If your GitHub Enterprise has SSH access disabled, you can use HTTPS and token authentication with:
|
||||
|
||||
```sh
|
||||
flux bootstrap github \
|
||||
--token-auth \
|
||||
--hostname=my-github-enterprise.com \
|
||||
--owner=my-github-organization \
|
||||
--repository=my-repository \
|
||||
--branch=main \
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
### GitLab and GitLab Enterprise
|
||||
@@ -150,7 +167,8 @@ flux bootstrap gitlab \
|
||||
--owner=my-gitlab-username \
|
||||
--repository=my-repository \
|
||||
--branch=master \
|
||||
--path=my-cluster \
|
||||
--path=clusters/my-cluster \
|
||||
--token-auth \
|
||||
--personal
|
||||
```
|
||||
|
||||
@@ -162,7 +180,7 @@ flux bootstrap gitlab \
|
||||
--owner=my-gitlab-username \
|
||||
--repository=my-repository \
|
||||
--branch=master \
|
||||
--path=my-cluster
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
!!! hint "Authentication"
|
||||
@@ -177,7 +195,7 @@ flux bootstrap gitlab \
|
||||
--owner=my-gitlab-group \
|
||||
--repository=my-repository \
|
||||
--branch=master \
|
||||
--path=my-cluster
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
To run the bootstrap for a repository hosted on GitLab on-prem or enterprise, you have to specify your GitLab hostname:
|
||||
@@ -185,10 +203,11 @@ To run the bootstrap for a repository hosted on GitLab on-prem or enterprise, yo
|
||||
```sh
|
||||
flux bootstrap gitlab \
|
||||
--hostname=my-gitlab.com \
|
||||
--token-auth \
|
||||
--owner=my-gitlab-group \
|
||||
--repository=my-repository \
|
||||
--branch=master \
|
||||
--path=my-cluster
|
||||
--path=clusters/my-cluster
|
||||
```
|
||||
|
||||
### Generic Git Server
|
||||
@@ -205,15 +224,16 @@ cd my-repository
|
||||
Create a directory inside the repository:
|
||||
|
||||
```sh
|
||||
mkdir -p ./my-cluster/flux-system
|
||||
mkdir -p ./clusters/my-cluster/flux-system
|
||||
```
|
||||
|
||||
Generate the Flux manifests with:
|
||||
|
||||
```sh
|
||||
# on ARM64/AARCH64 clusters use --arch=arm64
|
||||
flux install --version=latest \
|
||||
--arch=amd64 \ # on ARM64/AARCH64 clusters use --arch=arm64
|
||||
--export > ./my-cluster/flux-system/gotk-components.yaml
|
||||
--arch=amd64 \
|
||||
--export > ./clusters/my-cluster/flux-system/gotk-components.yaml
|
||||
```
|
||||
|
||||
If your cluster must pull images from a private container registry, first you should pull
|
||||
@@ -241,7 +261,7 @@ Set your registry domain, and the pull secret when generating the manifests:
|
||||
flux install --version=latest \
|
||||
--registry=registry.internal/fluxcd \
|
||||
--image-pull-secret=regcred \
|
||||
--export > ./my-cluster/flux-system/gotk-components.yaml
|
||||
--export > ./clusters/my-cluster/flux-system/gotk-components.yaml
|
||||
```
|
||||
|
||||
Commit and push the manifest to the master branch:
|
||||
@@ -253,7 +273,7 @@ git add -A && git commit -m "add components" && git push
|
||||
Apply the manifests on your cluster:
|
||||
|
||||
```sh
|
||||
kubectl apply -f ./my-cluster/flux-system/gotk-components.yaml
|
||||
kubectl apply -f ./clusters/my-cluster/flux-system/gotk-components.yaml
|
||||
```
|
||||
|
||||
Verify that the controllers have started:
|
||||
@@ -301,12 +321,12 @@ Export both objects, generate a `kustomization.yaml`, commit and push the manife
|
||||
|
||||
```sh
|
||||
flux export source git flux-system \
|
||||
> ./my-cluster/flux-system/gotk-sync.yaml
|
||||
> ./clusters/my-cluster/flux-system/gotk-sync.yaml
|
||||
|
||||
flux export kustomization flux-system \
|
||||
>> ./my-cluster/flux-system/gotk-sync.yaml
|
||||
>> ./clusters/my-cluster/flux-system/gotk-sync.yaml
|
||||
|
||||
cd ./my-cluster/flux-system && kustomize create --autodetect
|
||||
cd ./clusters/my-cluster/flux-system && kustomize create --autodetect
|
||||
|
||||
git add -A && git commit -m "add sync manifests" && git push
|
||||
```
|
||||
@@ -315,7 +335,7 @@ To upgrade the Flux components to a newer version, run the install command and c
|
||||
|
||||
```sh
|
||||
flux install --version=latest \
|
||||
--export > ./my-cluster/flux-system/gotk-components.yaml
|
||||
--export > ./clusters/my-cluster/flux-system/gotk-components.yaml
|
||||
|
||||
git add -A && git commit -m "update flux" && git push
|
||||
```
|
||||
@@ -323,15 +343,100 @@ git add -A && git commit -m "update flux" && git push
|
||||
The source-controller will pull the changes on the cluster, then the kustomize-controller
|
||||
will perform a rolling update of all Flux components including itself.
|
||||
|
||||
## Dev install
|
||||
## Bootstrap with Terraform
|
||||
|
||||
For testing purposes you can install Flux without storing its manifests in a Git repository.
|
||||
The bootstrap procedure can be implemented with Terraform using the Flux provider published on
|
||||
[registry.terraform.io](https://registry.terraform.io/providers/fluxcd/flux).
|
||||
|
||||
Here is the equivalent to `fluxctl install`:
|
||||
The provider consists of two data sources (`flux_install` and `flux_sync`) for generating the
|
||||
Kubernetes manifests that can be used to install or upgrade Flux:
|
||||
|
||||
```hcl
|
||||
data "flux_install" "main" {
|
||||
target_path = "clusters/my-cluster"
|
||||
arch = "amd64"
|
||||
network_policy = false
|
||||
version = "latest"
|
||||
}
|
||||
|
||||
data "flux_sync" "main" {
|
||||
target_path = "clusters/my-cluster"
|
||||
url = "https://github.com/${var.github_owner}/${var.repository_name}"
|
||||
branch = "main"
|
||||
}
|
||||
```
|
||||
|
||||
For more details on how to use the Terraform provider
|
||||
please see [fluxcd/terraform-provider-flux](https://github.com/fluxcd/terraform-provider-flux).
|
||||
|
||||
## Customize Flux manifests
|
||||
|
||||
You can customize the Flux components in the Git repository where you've run bootstrap with Kustomize patches.
|
||||
|
||||
First clone the repository locally and generate a `kustomization.yaml` file with:
|
||||
|
||||
```sh
|
||||
flux install \
|
||||
--components=source-controller,kustomize-controller
|
||||
cd ./clusters/production && kustomize create --autodetect
|
||||
```
|
||||
|
||||
Assuming you want to add custom annotations and labels to the Flux controllers in `clusters/production`.
|
||||
Create a Kustomize patch and set the metadata for source-controller and kustomize-controller pods:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: source-controller
|
||||
namespace: flux-system
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
custom: annotation
|
||||
labels:
|
||||
custom: label
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: kustomize-controller
|
||||
namespace: flux-system
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
custom: annotation
|
||||
labels:
|
||||
custom: label
|
||||
```
|
||||
|
||||
Save the above file as `flux-system-patch.yaml` inside the `clusters/production` dir.
|
||||
|
||||
Edit `clusters/production/kustomization.yaml` and add the patch:
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- flux-system
|
||||
patchesStrategicMerge:
|
||||
- flux-system-patch.yaml
|
||||
```
|
||||
|
||||
Push the changes to main branch:
|
||||
|
||||
```sh
|
||||
git add -A && git commit -m "add production metadata" && git push
|
||||
```
|
||||
|
||||
Flux will detect the change and will update itself on the production cluster.
|
||||
|
||||
## Dev install
|
||||
|
||||
For testing purposes you can install Flux without storing its manifests in a Git repository:
|
||||
|
||||
```sh
|
||||
flux install --arch=amd64
|
||||
```
|
||||
|
||||
Then you can register Git repositories and reconcile them on your cluster:
|
||||
@@ -352,27 +457,20 @@ flux create kustomization podinfo-default \
|
||||
--health-check-timeout=2m
|
||||
```
|
||||
|
||||
Here is the equivalent to `helm install helm-operator`:
|
||||
You can register Helm repositories and create Helm releases:
|
||||
|
||||
```sh
|
||||
flux install \
|
||||
--components=source-controller,kustomize-controller,helm-controller
|
||||
```
|
||||
|
||||
Then you can register Helm repositories and create Helm releases:
|
||||
|
||||
```sh
|
||||
flux create source helm stable \
|
||||
flux create source helm bitnami \
|
||||
--interval=1h \
|
||||
--url=https://charts.helm.sh/stable
|
||||
--url=https://charts.bitnami.com/bitnami
|
||||
|
||||
flux create helmrelease sealed-secrets \
|
||||
flux create helmrelease nginx \
|
||||
--interval=1h \
|
||||
--release-name=sealed-secrets \
|
||||
--target-namespace=flux-system \
|
||||
--source=HelmRepository/stable \
|
||||
--chart=sealed-secrets \
|
||||
--chart-version="1.10.x"
|
||||
--release-name=nginx-ingress-controller \
|
||||
--target-namespace=kube-system \
|
||||
--source=HelmRepository/bitnami \
|
||||
--chart=nginx-ingress-controller \
|
||||
--chart-version="5.x.x"
|
||||
```
|
||||
|
||||
## Monitoring with Prometheus and Grafana
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Manage Kubernetes secrets with Mozilla SOPS
|
||||
|
||||
In order to store secrets safely in a public or private Git repository, you can use
|
||||
Mozilla's [SOPS](https://github.com/mozilla/sops) CLI to encrypt
|
||||
Mozilla's [SOPS](https://github.com/mozilla/sops) CLI to encrypt
|
||||
Kubernetes secrets with OpenPGP, AWS KMS, GCP KMS and Azure Key Vault.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
To follow this guide you'll need a Kubernetes cluster with the GitOps
|
||||
To follow this guide you'll need a Kubernetes cluster with the GitOps
|
||||
toolkit controllers installed on it.
|
||||
Please see the [get started guide](../get-started/index.md)
|
||||
or the [installation guide](installation.md).
|
||||
@@ -26,7 +26,7 @@ $ gpg --full-generate-key
|
||||
|
||||
Real name: stefanprodan
|
||||
Email address: stefanprodan@users.noreply.github.com
|
||||
Comment:
|
||||
Comment:
|
||||
You selected this USER-ID:
|
||||
"stefanprodan <stefanprodan@users.noreply.github.com>"
|
||||
```
|
||||
@@ -48,7 +48,7 @@ gpg --export-secret-keys \
|
||||
--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
|
||||
kubectl create secret generic sops-gpg \
|
||||
--namespace=flux-system \
|
||||
--from-file=sops.asc=/dev/stdin
|
||||
--from-file=sops.asc=/dev/stdin
|
||||
```
|
||||
|
||||
## Encrypt secrets
|
||||
@@ -102,10 +102,12 @@ Note that the `sops-gpg` can contain more than one key, sops will try to decrypt
|
||||
secrets by iterating over all the private keys until it finds one that works.
|
||||
|
||||
!!! hint KMS
|
||||
When using AWS/GCP KMS or Azure Key Vault, you'll have to bind an IAM Role
|
||||
When using AWS/GCP KMS, you'll have to bind an IAM Role
|
||||
with read access to the KMS keys to the `default` service account of the
|
||||
`flux-system` namespace for kustomize-controller to be able to fetch
|
||||
keys from KMS.
|
||||
keys from KMS. When using Azure Key Vault you need to authenticate the kustomize controller either by passing
|
||||
[Service Principal credentials as environment variables](https://github.com/mozilla/sops#encrypting-using-azure-key-vault)
|
||||
or with [add-pod-identity](https://github.com/Azure/aad-pod-identity).
|
||||
|
||||
## GitOps workflow
|
||||
|
||||
@@ -161,6 +163,6 @@ to a database using a username and password, they'll be doing the following:
|
||||
Once the manifests have been pushed to the Git repository, the following happens:
|
||||
|
||||
* source-controller pulls the changes from Git
|
||||
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
|
||||
* kustomize-controller loads the GPG keys from the `sops-pgp` secret
|
||||
* kustomize-controller decrypts the Kubernetes secrets with sops and applies them on the cluster
|
||||
* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container
|
||||
|
||||
@@ -92,4 +92,5 @@ Tasks
|
||||
- [x] <span style="color:grey">Implement support for Helm charts from Git</span>
|
||||
- [x] <span style="color:grey">Implement support for referring to an alternative chart values file</span>
|
||||
- [x] <span style="color:grey">Stabilize API</span>
|
||||
- [ ] Create a migration guide for Helm Operator users
|
||||
- [x] <span style="color:grey">[Create a migration guide for Helm Operator users](../guides/helm-operator-migration.md)</span>
|
||||
- [ ] [Gather feedback on the migration guide](https://github.com/fluxcd/flux2/discussions/413)
|
||||
2
go.mod
2
go.mod
@@ -6,7 +6,7 @@ require (
|
||||
github.com/blang/semver/v4 v4.0.0
|
||||
github.com/fluxcd/helm-controller/api v0.2.0
|
||||
github.com/fluxcd/kustomize-controller/api v0.2.1
|
||||
github.com/fluxcd/notification-controller/api v0.2.0
|
||||
github.com/fluxcd/notification-controller/api v0.2.1
|
||||
github.com/fluxcd/pkg/apis/meta v0.2.0
|
||||
github.com/fluxcd/pkg/git v0.0.7
|
||||
github.com/fluxcd/pkg/runtime v0.2.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -142,8 +142,8 @@ github.com/fluxcd/helm-controller/api v0.2.0 h1:HWfqy4rUlo4ck+YnTIMcwWBrfeK2sW7l
|
||||
github.com/fluxcd/helm-controller/api v0.2.0/go.mod h1:02vw8JOlzdOysJ8p5AMp7XhPqtH9DS12VIeN46yzHY0=
|
||||
github.com/fluxcd/kustomize-controller/api v0.2.1 h1:9qtOFdUXIF1j0PW+3c9c/VU+fA4EibnL4Ogz1qgazPw=
|
||||
github.com/fluxcd/kustomize-controller/api v0.2.1/go.mod h1:rNS7iETBnm3BvZmPtaLM1otIIyiu4SPeJEL2H2X0uAc=
|
||||
github.com/fluxcd/notification-controller/api v0.2.0 h1:8bToM5qayZHWdayxC+/xKgIWTqW1scc6hk86sCvspa0=
|
||||
github.com/fluxcd/notification-controller/api v0.2.0/go.mod h1:ygBRvQxylsFhYxcot2sbX29B3H2g9WYlWRX0DKtI/lQ=
|
||||
github.com/fluxcd/notification-controller/api v0.2.1 h1:G08+7BjsBLV62nvmGQ/uduozR3y3ldaet9y7dX1rN2E=
|
||||
github.com/fluxcd/notification-controller/api v0.2.1/go.mod h1:p0dP0a5iosNSdxQXIddx4E0TGOIxu5/Dp8UWAs535no=
|
||||
github.com/fluxcd/pkg/apis/meta v0.0.2 h1:kyA4Y0IzNjf1joBOnFqpWG7aNDHvtLExZcaHQM7qhRI=
|
||||
github.com/fluxcd/pkg/apis/meta v0.0.2/go.mod h1:nCNps5JJOcEQr3MNDmZqI4o0chjePSUYL6Q2ktDtotU=
|
||||
github.com/fluxcd/pkg/apis/meta v0.1.0 h1:CfOYHYaHslhcb3QlzgKCOXl4ziCbA5zG/fUa1qFlHis=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- https://github.com/fluxcd/notification-controller/archive/v0.2.0.zip//notification-controller-0.2.0/config/crd
|
||||
- https://github.com/fluxcd/notification-controller/archive/v0.2.0.zip//notification-controller-0.2.0/config/manager
|
||||
- https://github.com/fluxcd/notification-controller/archive/v0.2.1.zip//notification-controller-0.2.1/config/crd
|
||||
- https://github.com/fluxcd/notification-controller/archive/v0.2.1.zip//notification-controller-0.2.1/config/manager
|
||||
|
||||
@@ -52,9 +52,9 @@ nav:
|
||||
- Monitoring with Prometheus: guides/monitoring.md
|
||||
- Sealed Secrets: guides/sealed-secrets.md
|
||||
- Mozilla SOPS: guides/mozilla-sops.md
|
||||
- Migrate:
|
||||
- From Flux v1: guides/flux-v1-migration.md
|
||||
- From the Helm Operator: guides/helm-operator-migration.md
|
||||
- Migration:
|
||||
- Migrate from Flux v1: guides/flux-v1-migration.md
|
||||
- Migrate from the Helm Operator: guides/helm-operator-migration.md
|
||||
- Toolkit Components:
|
||||
- Overview: components/index.md
|
||||
- Source Controller:
|
||||
|
||||
Reference in New Issue
Block a user