diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go index 0dc8bd11..e2683546 100644 --- a/cmd/flux/bootstrap.go +++ b/cmd/flux/bootstrap.go @@ -45,62 +45,71 @@ var bootstrapCmd = &cobra.Command{ Long: "The bootstrap sub-commands bootstrap the toolkit components on the targeted Git provider.", } -var ( - bootstrapVersion string - bootstrapDefaultComponents []string - bootstrapExtraComponents []string - bootstrapRegistry string - bootstrapImagePullSecret string - bootstrapBranch string - bootstrapWatchAllNamespaces bool - bootstrapNetworkPolicy bool - bootstrapManifestsPath string - bootstrapArch flags.Arch - bootstrapLogLevel = flags.LogLevel(defaults.LogLevel) - bootstrapRequiredComponents = []string{"source-controller", "kustomize-controller"} - bootstrapTokenAuth bool - bootstrapClusterDomain string -) +type bootstrapFlags struct { + version string + defaultComponents []string + extraComponents []string + registry string + imagePullSecret string + branch string + watchAllNamespaces bool + networkPolicy bool + manifestsPath string + arch flags.Arch + logLevel flags.LogLevel + requiredComponents []string + tokenAuth bool + clusterDomain string +} const ( bootstrapDefaultBranch = "main" ) +var bootstrapArgs = NewBootstrapFlags() + func init() { - bootstrapCmd.PersistentFlags().StringVarP(&bootstrapVersion, "version", "v", defaults.Version, + bootstrapCmd.PersistentFlags().StringVarP(&bootstrapArgs.version, "version", "v", rootArgs.defaults.Version, "toolkit version") - bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapDefaultComponents, "components", defaults.Components, + bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapArgs.defaultComponents, "components", rootArgs.defaults.Components, "list of components, accepts comma-separated values") - bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapExtraComponents, "components-extra", nil, + bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapArgs.extraComponents, "components-extra", nil, "list of components in addition to those supplied or defaulted, accepts comma-separated values") - bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "ghcr.io/fluxcd", + bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.registry, "registry", "ghcr.io/fluxcd", "container registry where the toolkit images are published") - bootstrapCmd.PersistentFlags().StringVar(&bootstrapImagePullSecret, "image-pull-secret", "", + bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.imagePullSecret, "image-pull-secret", "", "Kubernetes secret name used for pulling the toolkit images from a private registry") - bootstrapCmd.PersistentFlags().Var(&bootstrapArch, "arch", bootstrapArch.Description()) - bootstrapCmd.PersistentFlags().StringVar(&bootstrapBranch, "branch", bootstrapDefaultBranch, + bootstrapCmd.PersistentFlags().Var(&bootstrapArgs.arch, "arch", bootstrapArgs.arch.Description()) + bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.branch, "branch", bootstrapDefaultBranch, "default branch (for GitHub this must match the default branch setting for the organization)") - bootstrapCmd.PersistentFlags().BoolVar(&bootstrapWatchAllNamespaces, "watch-all-namespaces", true, + bootstrapCmd.PersistentFlags().BoolVar(&bootstrapArgs.watchAllNamespaces, "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, + bootstrapCmd.PersistentFlags().BoolVar(&bootstrapArgs.networkPolicy, "network-policy", true, "deny ingress access to the toolkit controllers from other namespaces using network policies") - bootstrapCmd.PersistentFlags().BoolVar(&bootstrapTokenAuth, "token-auth", false, + bootstrapCmd.PersistentFlags().BoolVar(&bootstrapArgs.tokenAuth, "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().StringVar(&bootstrapClusterDomain, "cluster-domain", defaults.ClusterDomain, "internal cluster domain") + bootstrapCmd.PersistentFlags().Var(&bootstrapArgs.logLevel, "log-level", bootstrapArgs.logLevel.Description()) + bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.manifestsPath, "manifests", "", "path to the manifest directory") + bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.clusterDomain, "cluster-domain", rootArgs.defaults.ClusterDomain, "internal cluster domain") bootstrapCmd.PersistentFlags().MarkHidden("manifests") bootstrapCmd.PersistentFlags().MarkDeprecated("arch", "multi-arch container image is now available for AMD64, ARMv7 and ARM64") rootCmd.AddCommand(bootstrapCmd) } +func NewBootstrapFlags() bootstrapFlags { + return bootstrapFlags{ + logLevel: flags.LogLevel(rootArgs.defaults.LogLevel), + requiredComponents: []string{"source-controller", "kustomize-controller"}, + } +} + func bootstrapComponents() []string { - return append(bootstrapDefaultComponents, bootstrapExtraComponents...) + return append(bootstrapArgs.defaultComponents, bootstrapArgs.extraComponents...) } func bootstrapValidate() error { components := bootstrapComponents() - for _, component := range bootstrapRequiredComponents { + for _, component := range bootstrapArgs.requiredComponents { if !utils.ContainsItemString(components, component) { return fmt.Errorf("component %s is required", component) } @@ -116,23 +125,23 @@ func bootstrapValidate() error { func generateInstallManifests(targetPath, namespace, tmpDir string, localManifests string) (string, error) { opts := install.Options{ BaseURL: localManifests, - Version: bootstrapVersion, - Namespace: namespace, + Version: bootstrapArgs.version, + Namespace: rootArgs.namespace, Components: bootstrapComponents(), - Registry: bootstrapRegistry, - ImagePullSecret: bootstrapImagePullSecret, - WatchAllNamespaces: bootstrapWatchAllNamespaces, - NetworkPolicy: bootstrapNetworkPolicy, - LogLevel: bootstrapLogLevel.String(), - NotificationController: defaults.NotificationController, - ManifestFile: defaults.ManifestFile, - Timeout: timeout, + Registry: bootstrapArgs.registry, + ImagePullSecret: bootstrapArgs.imagePullSecret, + WatchAllNamespaces: bootstrapArgs.watchAllNamespaces, + NetworkPolicy: bootstrapArgs.networkPolicy, + LogLevel: bootstrapArgs.logLevel.String(), + NotificationController: rootArgs.defaults.NotificationController, + ManifestFile: rootArgs.defaults.ManifestFile, + Timeout: rootArgs.timeout, TargetPath: targetPath, - ClusterDomain: bootstrapClusterDomain, + ClusterDomain: bootstrapArgs.clusterDomain, } if localManifests == "" { - opts.BaseURL = defaults.BaseURL + opts.BaseURL = rootArgs.defaults.BaseURL } output, err := install.Generate(opts) @@ -149,13 +158,13 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error { kubectlArgs := []string{"apply", "-f", manifestPath} - if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, kubeconfig, kubecontext, kubectlArgs...); err != nil { + if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return fmt.Errorf("install failed") } for _, deployment := range components { - kubectlArgs = []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()} - if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, kubeconfig, kubecontext, kubectlArgs...); err != nil { + kubectlArgs = []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()} + if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return fmt.Errorf("install failed") } } @@ -191,20 +200,20 @@ func generateSyncManifests(url, branch, name, namespace, targetPath, tmpDir stri func applySyncManifests(ctx context.Context, kubeClient client.Client, name, namespace, manifestsPath string) error { kubectlArgs := []string{"apply", "-k", manifestsPath} - if _, err := utils.ExecKubectlCommand(ctx, utils.ModeStderrOS, kubeconfig, kubecontext, kubectlArgs...); err != nil { + if _, err := utils.ExecKubectlCommand(ctx, utils.ModeStderrOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return err } logger.Waitingf("waiting for cluster sync") var gitRepository sourcev1.GitRepository - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isGitRepositoryReady(ctx, kubeClient, types.NamespacedName{Name: name, Namespace: namespace}, &gitRepository)); err != nil { return err } var kustomization kustomizev1.Kustomization - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isKustomizationReady(ctx, kubeClient, types.NamespacedName{Name: name, Namespace: namespace}, &kustomization)); err != nil { return err } @@ -239,7 +248,7 @@ func shouldCreateDeployKey(ctx context.Context, kubeClient client.Client, namesp } func generateDeployKey(ctx context.Context, kubeClient client.Client, url *url.URL, namespace string) (string, error) { - pair, err := generateKeyPair(ctx, sourceGitKeyAlgorithm, sourceGitRSABits, sourceGitECDSACurve) + pair, err := generateKeyPair(ctx, sourceArgs.GitKeyAlgorithm, sourceArgs.GitRSABits, sourceArgs.GitECDSACurve) if err != nil { return "", err } diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index 336423de..aeca46be 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -71,35 +71,37 @@ the bootstrap command will perform an upgrade if needed.`, RunE: bootstrapGitHubCmdRun, } -var ( - ghOwner string - ghRepository string - ghInterval time.Duration - ghPersonal bool - ghPrivate bool - ghHostname string - ghPath flags.SafeRelativePath - ghTeams []string - ghDelete bool - ghSSHHostname string -) +type githubFlags struct { + owner string + repository string + interval time.Duration + personal bool + private bool + hostname string + path flags.SafeRelativePath + teams []string + delete bool + sshHostname string +} const ( ghDefaultPermission = "maintain" ) +var githubArgs githubFlags + func init() { - bootstrapGitHubCmd.Flags().StringVar(&ghOwner, "owner", "", "GitHub user or organization name") - bootstrapGitHubCmd.Flags().StringVar(&ghRepository, "repository", "", "GitHub repository name") - bootstrapGitHubCmd.Flags().StringArrayVar(&ghTeams, "team", []string{}, "GitHub team to be given maintainer access") - bootstrapGitHubCmd.Flags().BoolVar(&ghPersonal, "personal", false, "is personal repository") - 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().Var(&ghPath, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") - - bootstrapGitHubCmd.Flags().BoolVar(&ghDelete, "delete", false, "delete repository (used for testing only)") + bootstrapGitHubCmd.Flags().StringVar(&githubArgs.owner, "owner", "", "GitHub user or organization name") + bootstrapGitHubCmd.Flags().StringVar(&githubArgs.repository, "repository", "", "GitHub repository name") + bootstrapGitHubCmd.Flags().StringArrayVar(&githubArgs.teams, "team", []string{}, "GitHub team to be given maintainer access") + bootstrapGitHubCmd.Flags().BoolVar(&githubArgs.personal, "personal", false, "is personal repository") + bootstrapGitHubCmd.Flags().BoolVar(&githubArgs.private, "private", true, "is private repository") + bootstrapGitHubCmd.Flags().DurationVar(&githubArgs.interval, "interval", time.Minute, "sync interval") + bootstrapGitHubCmd.Flags().StringVar(&githubArgs.hostname, "hostname", git.GitHubDefaultHostname, "GitHub hostname") + bootstrapGitHubCmd.Flags().StringVar(&githubArgs.sshHostname, "ssh-hostname", "", "GitHub SSH hostname, to be used when the SSH host differs from the HTTPS one") + bootstrapGitHubCmd.Flags().Var(&githubArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") + + bootstrapGitHubCmd.Flags().BoolVar(&githubArgs.delete, "delete", false, "delete repository (used for testing only)") bootstrapGitHubCmd.Flags().MarkHidden("delete") bootstrapCmd.AddCommand(bootstrapGitHubCmd) @@ -115,41 +117,41 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { return err } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers(ctx, kubeClient, namespace, filepath.ToSlash(ghPath.String())) + usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers(ctx, kubeClient, rootArgs.namespace, filepath.ToSlash(githubArgs.path.String())) if bootstrapPathDiffers { return fmt.Errorf("cluster already bootstrapped to %v path", usedPath) } - repository, err := git.NewRepository(ghRepository, ghOwner, ghHostname, ghToken, "flux", ghOwner+"@users.noreply.github.com") + repository, err := git.NewRepository(githubArgs.repository, githubArgs.owner, githubArgs.hostname, ghToken, "flux", githubArgs.owner+"@users.noreply.github.com") if err != nil { return err } - if ghSSHHostname != "" { - repository.SSHHost = ghSSHHostname + if githubArgs.sshHostname != "" { + repository.SSHHost = githubArgs.sshHostname } provider := &git.GithubProvider{ - IsPrivate: ghPrivate, - IsPersonal: ghPersonal, + IsPrivate: githubArgs.private, + IsPersonal: githubArgs.personal, } - tmpDir, err := ioutil.TempDir("", namespace) + tmpDir, err := ioutil.TempDir("", rootArgs.namespace) if err != nil { return err } defer os.RemoveAll(tmpDir) - if ghDelete { + if githubArgs.delete { if err := provider.DeleteRepository(ctx, repository); err != nil { return err } @@ -158,7 +160,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { } // create GitHub repository if doesn't exists - logger.Actionf("connecting to %s", ghHostname) + logger.Actionf("connecting to %s", githubArgs.hostname) changed, err := provider.CreateRepository(ctx, repository) if err != nil { return err @@ -169,8 +171,8 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { withErrors := false // add teams to org repository - if !ghPersonal { - for _, team := range ghTeams { + if !githubArgs.personal { + for _, team := range githubArgs.teams { if changed, err := provider.AddTeam(ctx, repository, team, ghDefaultPermission); err != nil { logger.Failuref(err.Error()) withErrors = true @@ -181,20 +183,20 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { } // clone repository and checkout the main branch - if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil { + if err := repository.Checkout(ctx, bootstrapArgs.branch, tmpDir); err != nil { return err } logger.Successf("repository cloned") // generate install manifests logger.Generatef("generating manifests") - installManifest, err := generateInstallManifests(ghPath.String(), namespace, tmpDir, bootstrapManifestsPath) + installManifest, err := generateInstallManifests(githubArgs.path.String(), rootArgs.namespace, tmpDir, bootstrapArgs.manifestsPath) if err != nil { return err } // stage install manifests - changed, err = repository.Commit(ctx, path.Join(ghPath.String(), namespace), "Add manifests") + changed, err = repository.Commit(ctx, path.Join(githubArgs.path.String(), rootArgs.namespace), "Add manifests") if err != nil { return err } @@ -210,11 +212,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { } // determine if repo synchronization is working - isInstall := shouldInstallManifests(ctx, kubeClient, namespace) + isInstall := shouldInstallManifests(ctx, kubeClient, rootArgs.namespace) if isInstall { // apply install manifests - logger.Actionf("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", rootArgs.namespace) if err := applyInstallManifests(ctx, installManifest, bootstrapComponents()); err != nil { return err } @@ -223,12 +225,12 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { repoURL := repository.GetURL() - if bootstrapTokenAuth { + if bootstrapArgs.tokenAuth { // setup HTTPS token auth secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - Namespace: namespace, + Name: rootArgs.namespace, + Namespace: rootArgs.namespace, }, StringData: map[string]string{ "username": "git", @@ -241,21 +243,21 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { } else { // setup SSH deploy key repoURL = repository.GetSSH() - if shouldCreateDeployKey(ctx, kubeClient, namespace) { + if shouldCreateDeployKey(ctx, kubeClient, rootArgs.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) + key, err := generateDeployKey(ctx, kubeClient, u, rootArgs.namespace) if err != nil { return fmt.Errorf("generating deploy key failed: %w", err) } keyName := "flux" - if ghPath != "" { - keyName = fmt.Sprintf("flux-%s", ghPath) + if githubArgs.path != "" { + keyName = fmt.Sprintf("flux-%s", githubArgs.path) } if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { @@ -268,13 +270,13 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // configure repo synchronization logger.Actionf("generating sync manifests") - syncManifests, err := generateSyncManifests(repoURL, bootstrapBranch, namespace, namespace, filepath.ToSlash(ghPath.String()), tmpDir, ghInterval) + syncManifests, err := generateSyncManifests(repoURL, bootstrapArgs.branch, rootArgs.namespace, rootArgs.namespace, filepath.ToSlash(githubArgs.path.String()), tmpDir, githubArgs.interval) if err != nil { return err } // commit and push manifests - if changed, err = repository.Commit(ctx, path.Join(ghPath.String(), namespace), "Add manifests"); err != nil { + if changed, err = repository.Commit(ctx, path.Join(githubArgs.path.String(), rootArgs.namespace), "Add manifests"); err != nil { return err } else if changed { if err := repository.Push(ctx); err != nil { @@ -285,7 +287,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // apply manifests and waiting for sync logger.Actionf("applying sync manifests") - if err := applySyncManifests(ctx, kubeClient, namespace, namespace, syncManifests); err != nil { + if err := applySyncManifests(ctx, kubeClient, rootArgs.namespace, rootArgs.namespace, syncManifests); err != nil { return err } diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index 5767a0e0..d5f99d91 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -73,26 +73,28 @@ const ( gitlabProjectRegex = `\A[[:alnum:]\x{00A9}-\x{1f9ff}_][[:alnum:]\p{Pd}\x{00A9}-\x{1f9ff}_\.]*\z` ) -var ( - glOwner string - glRepository string - glInterval time.Duration - glPersonal bool - glPrivate bool - glHostname string - glSSHHostname string - glPath flags.SafeRelativePath -) +type gitlabFlags struct { + owner string + repository string + interval time.Duration + personal bool + private bool + hostname string + sshHostname string + path flags.SafeRelativePath +} + +var gitlabArgs gitlabFlags func init() { - bootstrapGitLabCmd.Flags().StringVar(&glOwner, "owner", "", "GitLab user or group name") - bootstrapGitLabCmd.Flags().StringVar(&glRepository, "repository", "", "GitLab repository name") - bootstrapGitLabCmd.Flags().BoolVar(&glPersonal, "personal", false, "is personal repository") - 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, to be used when the SSH host differs from the HTTPS one") - bootstrapGitLabCmd.Flags().Var(&glPath, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") + bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.owner, "owner", "", "GitLab user or group name") + bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.repository, "repository", "", "GitLab repository name") + bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.personal, "personal", false, "is personal repository") + bootstrapGitLabCmd.Flags().BoolVar(&gitlabArgs.private, "private", true, "is private repository") + bootstrapGitLabCmd.Flags().DurationVar(&gitlabArgs.interval, "interval", time.Minute, "sync interval") + bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.hostname, "hostname", git.GitLabDefaultHostname, "GitLab hostname") + bootstrapGitLabCmd.Flags().StringVar(&gitlabArgs.sshHostname, "ssh-hostname", "", "GitLab SSH hostname, to be used when the SSH host differs from the HTTPS one") + bootstrapGitLabCmd.Flags().Var(&gitlabArgs.path, "path", "path relative to the repository root, when specified the cluster sync will be scoped to this path") bootstrapCmd.AddCommand(bootstrapGitLabCmd) } @@ -103,54 +105,54 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("%s environment variable not found", git.GitLabTokenName) } - projectNameIsValid, err := regexp.MatchString(gitlabProjectRegex, glRepository) + projectNameIsValid, err := regexp.MatchString(gitlabProjectRegex, gitlabArgs.repository) if err != nil { return err } if !projectNameIsValid { - return fmt.Errorf("%s is an invalid project name for gitlab.\nIt can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'.", glRepository) + return fmt.Errorf("%s is an invalid project name for gitlab.\nIt can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'.", gitlabArgs.repository) } if err := bootstrapValidate(); err != nil { return err } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers(ctx, kubeClient, namespace, filepath.ToSlash(glPath.String())) + usedPath, bootstrapPathDiffers := checkIfBootstrapPathDiffers(ctx, kubeClient, rootArgs.namespace, filepath.ToSlash(gitlabArgs.path.String())) if bootstrapPathDiffers { return fmt.Errorf("cluster already bootstrapped to %v path", usedPath) } - repository, err := git.NewRepository(glRepository, glOwner, glHostname, glToken, "flux", glOwner+"@users.noreply.gitlab.com") + repository, err := git.NewRepository(gitlabArgs.repository, gitlabArgs.owner, gitlabArgs.hostname, glToken, "flux", gitlabArgs.owner+"@users.noreply.gitlab.com") if err != nil { return err } - if glSSHHostname != "" { - repository.SSHHost = glSSHHostname + if gitlabArgs.sshHostname != "" { + repository.SSHHost = gitlabArgs.sshHostname } - tmpDir, err := ioutil.TempDir("", namespace) + tmpDir, err := ioutil.TempDir("", rootArgs.namespace) if err != nil { return err } defer os.RemoveAll(tmpDir) provider := &git.GitLabProvider{ - IsPrivate: glPrivate, - IsPersonal: glPersonal, + IsPrivate: gitlabArgs.private, + IsPersonal: gitlabArgs.personal, } // create GitLab project if doesn't exists - logger.Actionf("connecting to %s", glHostname) + logger.Actionf("connecting to %s", gitlabArgs.hostname) changed, err := provider.CreateRepository(ctx, repository) if err != nil { return err @@ -160,20 +162,20 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { } // clone repository and checkout the master branch - if err := repository.Checkout(ctx, bootstrapBranch, tmpDir); err != nil { + if err := repository.Checkout(ctx, bootstrapArgs.branch, tmpDir); err != nil { return err } logger.Successf("repository cloned") // generate install manifests logger.Generatef("generating manifests") - installManifest, err := generateInstallManifests(glPath.String(), namespace, tmpDir, bootstrapManifestsPath) + installManifest, err := generateInstallManifests(gitlabArgs.path.String(), rootArgs.namespace, tmpDir, bootstrapArgs.manifestsPath) if err != nil { return err } // stage install manifests - changed, err = repository.Commit(ctx, path.Join(glPath.String(), namespace), "Add manifests") + changed, err = repository.Commit(ctx, path.Join(gitlabArgs.path.String(), rootArgs.namespace), "Add manifests") if err != nil { return err } @@ -189,11 +191,11 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { } // determine if repo synchronization is working - isInstall := shouldInstallManifests(ctx, kubeClient, namespace) + isInstall := shouldInstallManifests(ctx, kubeClient, rootArgs.namespace) if isInstall { // apply install manifests - logger.Actionf("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", rootArgs.namespace) if err := applyInstallManifests(ctx, installManifest, bootstrapComponents()); err != nil { return err } @@ -202,12 +204,12 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { repoURL := repository.GetURL() - if bootstrapTokenAuth { + if bootstrapArgs.tokenAuth { // setup HTTPS token auth secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - Namespace: namespace, + Name: rootArgs.namespace, + Namespace: rootArgs.namespace, }, StringData: map[string]string{ "username": "git", @@ -220,21 +222,21 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { } else { // setup SSH deploy key repoURL = repository.GetSSH() - if shouldCreateDeployKey(ctx, kubeClient, namespace) { + if shouldCreateDeployKey(ctx, kubeClient, rootArgs.namespace) { logger.Actionf("configuring deploy key") u, err := url.Parse(repoURL) if err != nil { return fmt.Errorf("git URL parse failed: %w", err) } - key, err := generateDeployKey(ctx, kubeClient, u, namespace) + key, err := generateDeployKey(ctx, kubeClient, u, rootArgs.namespace) if err != nil { return fmt.Errorf("generating deploy key failed: %w", err) } keyName := "flux" - if glPath != "" { - keyName = fmt.Sprintf("flux-%s", glPath) + if gitlabArgs.path != "" { + keyName = fmt.Sprintf("flux-%s", gitlabArgs.path) } if changed, err := provider.AddDeployKey(ctx, repository, key, keyName); err != nil { @@ -247,13 +249,13 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // configure repo synchronization logger.Actionf("generating sync manifests") - syncManifests, err := generateSyncManifests(repoURL, bootstrapBranch, namespace, namespace, filepath.ToSlash(glPath.String()), tmpDir, glInterval) + syncManifests, err := generateSyncManifests(repoURL, bootstrapArgs.branch, rootArgs.namespace, rootArgs.namespace, filepath.ToSlash(gitlabArgs.path.String()), tmpDir, gitlabArgs.interval) if err != nil { return err } // commit and push manifests - if changed, err = repository.Commit(ctx, path.Join(glPath.String(), namespace), "Add manifests"); err != nil { + if changed, err = repository.Commit(ctx, path.Join(gitlabArgs.path.String(), rootArgs.namespace), "Add manifests"); err != nil { return err } else if changed { if err := repository.Push(ctx); err != nil { @@ -264,7 +266,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // apply manifests and waiting for sync logger.Actionf("applying sync manifests") - if err := applySyncManifests(ctx, kubeClient, namespace, namespace, syncManifests); err != nil { + if err := applySyncManifests(ctx, kubeClient, rootArgs.namespace, rootArgs.namespace, syncManifests); err != nil { return err } diff --git a/cmd/flux/check.go b/cmd/flux/check.go index 42a48247..b2037cb7 100644 --- a/cmd/flux/check.go +++ b/cmd/flux/check.go @@ -44,25 +44,27 @@ the local environment is configured correctly and if the installed components ar RunE: runCheckCmd, } -var ( - checkPre bool - checkComponents []string -) +type checkFlags struct { + pre bool + components []string +} type kubectlVersion struct { ClientVersion *apimachineryversion.Info `json:"clientVersion"` } +var checkArgs checkFlags + func init() { - checkCmd.Flags().BoolVarP(&checkPre, "pre", "", false, + checkCmd.Flags().BoolVarP(&checkArgs.pre, "pre", "", false, "only run pre-installation checks") - checkCmd.Flags().StringSliceVar(&checkComponents, "components", defaults.Components, + checkCmd.Flags().StringSliceVar(&checkArgs.components, "components", rootArgs.defaults.Components, "list of components, accepts comma-separated values") rootCmd.AddCommand(checkCmd) } func runCheckCmd(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() logger.Actionf("checking prerequisites") @@ -76,7 +78,7 @@ func runCheckCmd(cmd *cobra.Command, args []string) error { checkFailed = true } - if checkPre { + if checkArgs.pre { if checkFailed { os.Exit(1) } @@ -103,7 +105,7 @@ func kubectlCheck(ctx context.Context, version string) bool { } kubectlArgs := []string{"version", "--client", "--output", "json"} - output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, kubeconfig, kubecontext, kubectlArgs...) + output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...) if err != nil { logger.Failuref("kubectl version can't be determined") return false @@ -132,7 +134,7 @@ func kubectlCheck(ctx context.Context, version string) bool { } func kubernetesCheck(version string) bool { - cfg, err := utils.KubeConfig(kubeconfig, kubecontext) + cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { logger.Failuref("Kubernetes client initialization failed: %s", err.Error()) return false @@ -167,20 +169,20 @@ func kubernetesCheck(version string) bool { } func componentsCheck() bool { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() ok := true - for _, deployment := range checkComponents { - kubectlArgs := []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()} - if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, kubeconfig, kubecontext, kubectlArgs...); err != nil { + for _, deployment := range checkArgs.components { + kubectlArgs := []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()} + if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n")) ok = false } 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, kubeconfig, kubecontext, kubectlArgs...); err == nil { + kubectlArgs = []string{"-n", rootArgs.namespace, "get", "deployment", deployment, "-o", "jsonpath=\"{..image}\""} + if output, err := utils.ExecKubectlCommand(ctx, utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err == nil { logger.Actionf(strings.TrimPrefix(strings.TrimSuffix(output, "\""), "\"")) } } diff --git a/cmd/flux/create.go b/cmd/flux/create.go index 5cdf2f61..3010c99c 100644 --- a/cmd/flux/create.go +++ b/cmd/flux/create.go @@ -38,16 +38,18 @@ var createCmd = &cobra.Command{ Long: "The create sub-commands generate sources and resources.", } -var ( +type createFlags struct { interval time.Duration export bool labels []string -) +} + +var createArgs createFlags func init() { - createCmd.PersistentFlags().DurationVarP(&interval, "interval", "", time.Minute, "source sync interval") - createCmd.PersistentFlags().BoolVar(&export, "export", false, "export in YAML format to stdout") - createCmd.PersistentFlags().StringSliceVar(&labels, "label", nil, + createCmd.PersistentFlags().DurationVarP(&createArgs.interval, "interval", "", time.Minute, "source sync interval") + createCmd.PersistentFlags().BoolVar(&createArgs.export, "export", false, "export in YAML format to stdout") + createCmd.PersistentFlags().StringSliceVar(&createArgs.labels, "label", nil, "set labels on the resource (can specify multiple labels with commas: label1=value1,label2=value2)") rootCmd.AddCommand(createCmd) } @@ -99,10 +101,10 @@ type upsertWaitable interface { // resource, then waiting for it to reconcile. See the note on // `upsert` for how to work with the `mutate` argument. func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) // NB globals + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) // NB globals if err != nil { return err } @@ -116,7 +118,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e } logger.Waitingf("waiting for %s reconciliation", names.kind) - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isReady(ctx, kubeClient, namespacedName, object)); err != nil { return err } @@ -126,7 +128,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e func parseLabels() (map[string]string, error) { result := make(map[string]string) - for _, label := range labels { + for _, label := range createArgs.labels { // validate key value pair parts := strings.Split(label, "=") if len(parts) != 2 { diff --git a/cmd/flux/create_alert.go b/cmd/flux/create_alert.go index b471c0fb..fb3d234b 100644 --- a/cmd/flux/create_alert.go +++ b/cmd/flux/create_alert.go @@ -49,16 +49,18 @@ var createAlertCmd = &cobra.Command{ RunE: createAlertCmdRun, } -var ( - aProviderRef string - aEventSeverity string - aEventSources []string -) +type alertFlags struct { + providerRef string + eventSeverity string + eventSources []string +} + +var alertArgs alertFlags func init() { - createAlertCmd.Flags().StringVar(&aProviderRef, "provider-ref", "", "reference to provider") - createAlertCmd.Flags().StringVar(&aEventSeverity, "event-severity", "", "severity of events to send alerts for") - createAlertCmd.Flags().StringArrayVar(&aEventSources, "event-source", []string{}, "sources that should generate alerts (/)") + createAlertCmd.Flags().StringVar(&alertArgs.providerRef, "provider-ref", "", "reference to provider") + createAlertCmd.Flags().StringVar(&alertArgs.eventSeverity, "event-severity", "", "severity of events to send alerts for") + createAlertCmd.Flags().StringArrayVar(&alertArgs.eventSources, "event-source", []string{}, "sources that should generate alerts (/)") createCmd.AddCommand(createAlertCmd) } @@ -68,12 +70,12 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - if aProviderRef == "" { + if alertArgs.providerRef == "" { return fmt.Errorf("provider ref is required") } eventSources := []notificationv1.CrossNamespaceObjectReference{} - for _, eventSource := range aEventSources { + for _, eventSource := range alertArgs.eventSources { kind, name := utils.ParseObjectKindName(eventSource) if kind == "" { return fmt.Errorf("invalid event source '%s', must be in format /", eventSource) @@ -94,34 +96,34 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { return err } - if !export { + if !createArgs.export { logger.Generatef("generating Alert") } alert := notificationv1.Alert{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: notificationv1.AlertSpec{ ProviderRef: corev1.LocalObjectReference{ - Name: aProviderRef, + Name: alertArgs.providerRef, }, - EventSeverity: aEventSeverity, + EventSeverity: alertArgs.eventSeverity, EventSources: eventSources, Suspend: false, }, } - if export { + if createArgs.export { return exportAlert(alert) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -133,7 +135,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for Alert reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isAlertReady(ctx, kubeClient, namespacedName, &alert)); err != nil { return err } diff --git a/cmd/flux/create_alertprovider.go b/cmd/flux/create_alertprovider.go index 3c06534c..d5b79d8c 100644 --- a/cmd/flux/create_alertprovider.go +++ b/cmd/flux/create_alertprovider.go @@ -54,20 +54,22 @@ var createAlertProviderCmd = &cobra.Command{ RunE: createAlertProviderCmdRun, } -var ( - apType string - apChannel string - apUsername string - apAddress string - apSecretRef string -) +type alertProviderFlags struct { + alertType string + channel string + username string + address string + secretRef string +} + +var alertProviderArgs alertProviderFlags func init() { - createAlertProviderCmd.Flags().StringVar(&apType, "type", "", "type of provider") - createAlertProviderCmd.Flags().StringVar(&apChannel, "channel", "", "channel to send messages to in the case of a chat provider") - createAlertProviderCmd.Flags().StringVar(&apUsername, "username", "", "bot username used by the provider") - createAlertProviderCmd.Flags().StringVar(&apAddress, "address", "", "path to either the git repository, chat provider or webhook") - createAlertProviderCmd.Flags().StringVar(&apSecretRef, "secret-ref", "", "name of secret containing authentication token") + createAlertProviderCmd.Flags().StringVar(&alertProviderArgs.alertType, "type", "", "type of provider") + createAlertProviderCmd.Flags().StringVar(&alertProviderArgs.channel, "channel", "", "channel to send messages to in the case of a chat provider") + createAlertProviderCmd.Flags().StringVar(&alertProviderArgs.username, "username", "", "bot username used by the provider") + createAlertProviderCmd.Flags().StringVar(&alertProviderArgs.address, "address", "", "path to either the git repository, chat provider or webhook") + createAlertProviderCmd.Flags().StringVar(&alertProviderArgs.secretRef, "secret-ref", "", "name of secret containing authentication token") createCmd.AddCommand(createAlertProviderCmd) } @@ -77,7 +79,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - if apType == "" { + if alertProviderArgs.alertType == "" { return fmt.Errorf("Provider type is required") } @@ -86,38 +88,38 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { return err } - if !export { + if !createArgs.export { logger.Generatef("generating Provider") } provider := notificationv1.Provider{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: notificationv1.ProviderSpec{ - Type: apType, - Channel: apChannel, - Username: apUsername, - Address: apAddress, + Type: alertProviderArgs.alertType, + Channel: alertProviderArgs.channel, + Username: alertProviderArgs.username, + Address: alertProviderArgs.address, }, } - if apSecretRef != "" { + if alertProviderArgs.secretRef != "" { provider.Spec.SecretRef = &corev1.LocalObjectReference{ - Name: apSecretRef, + Name: alertProviderArgs.secretRef, } } - if export { + if createArgs.export { return exportAlertProvider(provider) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -129,7 +131,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for Provider reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isAlertProviderReady(ctx, kubeClient, namespacedName, &provider)); err != nil { return err } diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index 3abb3da7..8174f63a 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -98,28 +98,30 @@ var createHelmReleaseCmd = &cobra.Command{ RunE: createHelmReleaseCmdRun, } -var ( - hrName string - hrSource flags.HelmChartSource - hrDependsOn []string - hrChart string - hrChartVersion string - hrTargetNamespace string - hrValuesFile string - hrValuesFrom flags.HelmReleaseValuesFrom - hrSAName string -) +type helmReleaseFlags struct { + name string + source flags.HelmChartSource + dependsOn []string + chart string + chartVersion string + targetNamespace string + valuesFile string + valuesFrom flags.HelmReleaseValuesFrom + saName string +} + +var helmReleaseArgs helmReleaseFlags func init() { - createHelmReleaseCmd.Flags().StringVar(&hrName, "release-name", "", "name used for the Helm release, defaults to a composition of '[-]'") - createHelmReleaseCmd.Flags().Var(&hrSource, "source", hrSource.Description()) - createHelmReleaseCmd.Flags().StringVar(&hrChart, "chart", "", "Helm chart name or path") - createHelmReleaseCmd.Flags().StringVar(&hrChartVersion, "chart-version", "", "Helm chart version, accepts a semver range (ignored for charts from GitRepository sources)") - createHelmReleaseCmd.Flags().StringArrayVar(&hrDependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed, supported formats '' and '/'") - createHelmReleaseCmd.Flags().StringVar(&hrTargetNamespace, "target-namespace", "", "namespace to install this release, defaults to the HelmRelease namespace") - createHelmReleaseCmd.Flags().StringVar(&hrSAName, "service-account", "", "the name of the service account to impersonate when reconciling this HelmRelease") - createHelmReleaseCmd.Flags().StringVar(&hrValuesFile, "values", "", "local path to the values.yaml file") - createHelmReleaseCmd.Flags().Var(&hrValuesFrom, "values-from", hrValuesFrom.Description()) + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.name, "release-name", "", "name used for the Helm release, defaults to a composition of '[-]'") + createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.source, "source", helmReleaseArgs.source.Description()) + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.chart, "chart", "", "Helm chart name or path") + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.chartVersion, "chart-version", "", "Helm chart version, accepts a semver range (ignored for charts from GitRepository sources)") + createHelmReleaseCmd.Flags().StringArrayVar(&helmReleaseArgs.dependsOn, "depends-on", nil, "HelmReleases that must be ready before this release can be installed, supported formats '' and '/'") + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.targetNamespace, "target-namespace", "", "namespace to install this release, defaults to the HelmRelease namespace") + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.saName, "service-account", "", "the name of the service account to impersonate when reconciling this HelmRelease") + createHelmReleaseCmd.Flags().StringVar(&helmReleaseArgs.valuesFile, "values", "", "local path to the values.yaml file") + createHelmReleaseCmd.Flags().Var(&helmReleaseArgs.valuesFrom, "values-from", helmReleaseArgs.valuesFrom.Description()) createCmd.AddCommand(createHelmReleaseCmd) } @@ -129,7 +131,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - if hrChart == "" { + if helmReleaseArgs.chart == "" { return fmt.Errorf("chart name or path is required") } @@ -138,30 +140,30 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { return err } - if !export { + if !createArgs.export { logger.Generatef("generating HelmRelease") } helmRelease := helmv2.HelmRelease{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: helmv2.HelmReleaseSpec{ - ReleaseName: hrName, - DependsOn: utils.MakeDependsOn(hrDependsOn), + ReleaseName: helmReleaseArgs.name, + DependsOn: utils.MakeDependsOn(helmReleaseArgs.dependsOn), Interval: metav1.Duration{ - Duration: interval, + Duration: createArgs.interval, }, - TargetNamespace: hrTargetNamespace, + TargetNamespace: helmReleaseArgs.targetNamespace, Chart: helmv2.HelmChartTemplate{ Spec: helmv2.HelmChartTemplateSpec{ - Chart: hrChart, - Version: hrChartVersion, + Chart: helmReleaseArgs.chart, + Version: helmReleaseArgs.chartVersion, SourceRef: helmv2.CrossNamespaceObjectReference{ - Kind: hrSource.Kind, - Name: hrSource.Name, + Kind: helmReleaseArgs.source.Kind, + Name: helmReleaseArgs.source.Name, }, }, }, @@ -169,39 +171,39 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { }, } - if hrSAName != "" { - helmRelease.Spec.ServiceAccountName = hrSAName + if helmReleaseArgs.saName != "" { + helmRelease.Spec.ServiceAccountName = helmReleaseArgs.saName } - if hrValuesFile != "" { - data, err := ioutil.ReadFile(hrValuesFile) + if helmReleaseArgs.valuesFile != "" { + data, err := ioutil.ReadFile(helmReleaseArgs.valuesFile) if err != nil { - return fmt.Errorf("reading values from %s failed: %w", hrValuesFile, err) + return fmt.Errorf("reading values from %s failed: %w", helmReleaseArgs.valuesFile, err) } json, err := yaml.YAMLToJSON(data) if err != nil { - return fmt.Errorf("converting values to JSON from %s failed: %w", hrValuesFile, err) + return fmt.Errorf("converting values to JSON from %s failed: %w", helmReleaseArgs.valuesFile, err) } helmRelease.Spec.Values = &apiextensionsv1.JSON{Raw: json} } - if hrValuesFrom.String() != "" { + if helmReleaseArgs.valuesFrom.String() != "" { helmRelease.Spec.ValuesFrom = []helmv2.ValuesReference{{ - Kind: hrValuesFrom.Kind, - Name: hrValuesFrom.Name, + Kind: helmReleaseArgs.valuesFrom.Kind, + Name: helmReleaseArgs.valuesFrom.Name, }} } - if export { + if createArgs.export { return exportHelmRelease(helmRelease) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -213,7 +215,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for HelmRelease reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isHelmReleaseReady(ctx, kubeClient, namespacedName, &helmRelease)); err != nil { return err } diff --git a/cmd/flux/create_image_policy.go b/cmd/flux/create_image_policy.go index 287e3dcd..3262c1e9 100644 --- a/cmd/flux/create_image_policy.go +++ b/cmd/flux/create_image_policy.go @@ -78,7 +78,7 @@ func createImagePolicyRun(cmd *cobra.Command, args []string) error { var policy = imagev1.ImagePolicy{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: labels, }, Spec: imagev1.ImagePolicySpec{ @@ -103,7 +103,7 @@ func createImagePolicyRun(cmd *cobra.Command, args []string) error { } } - if export { + if createArgs.export { return printExport(exportImagePolicy(&policy)) } diff --git a/cmd/flux/create_image_repository.go b/cmd/flux/create_image_repository.go index 03daf0ec..e82aeb49 100644 --- a/cmd/flux/create_image_repository.go +++ b/cmd/flux/create_image_repository.go @@ -77,12 +77,12 @@ func createImageRepositoryRun(cmd *cobra.Command, args []string) error { var repo = imagev1.ImageRepository{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: labels, }, Spec: imagev1.ImageRepositorySpec{ Image: imageRepoArgs.image, - Interval: metav1.Duration{Duration: interval}, + Interval: metav1.Duration{Duration: createArgs.interval}, }, } if imageRepoArgs.timeout != 0 { @@ -94,7 +94,7 @@ func createImageRepositoryRun(cmd *cobra.Command, args []string) error { } } - if export { + if createArgs.export { return printExport(exportImageRepository(&repo)) } diff --git a/cmd/flux/create_image_updateauto.go b/cmd/flux/create_image_updateauto.go index 4379ed4d..871b64f2 100644 --- a/cmd/flux/create_image_updateauto.go +++ b/cmd/flux/create_image_updateauto.go @@ -80,7 +80,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error { var update = autov1.ImageUpdateAutomation{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: labels, }, Spec: autov1.ImageUpdateAutomationSpec{ @@ -90,7 +90,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error { }, Branch: imageUpdateArgs.branch, }, - Interval: metav1.Duration{Duration: interval}, + Interval: metav1.Duration{Duration: createArgs.interval}, Update: autov1.UpdateStrategy{ Setters: &autov1.SettersStrategy{}, }, @@ -102,7 +102,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error { }, } - if export { + if createArgs.export { return printExport(exportImageUpdate(&update)) } diff --git a/cmd/flux/create_kustomization.go b/cmd/flux/create_kustomization.go index e355ed0e..a16d3787 100644 --- a/cmd/flux/create_kustomization.go +++ b/cmd/flux/create_kustomization.go @@ -72,53 +72,61 @@ var createKsCmd = &cobra.Command{ RunE: createKsCmdRun, } -var ( - ksSource flags.KustomizationSource - ksPath flags.SafeRelativePath = "./" - ksPrune bool - ksDependsOn []string - ksValidation string - ksHealthCheck []string - ksHealthTimeout time.Duration - ksSAName string - ksDecryptionProvider flags.DecryptionProvider - ksDecryptionSecret string - ksTargetNamespace string -) +type kustomizationFlags struct { + source flags.KustomizationSource + path flags.SafeRelativePath + prune bool + dependsOn []string + validation string + healthCheck []string + healthTimeout time.Duration + saName string + decryptionProvider flags.DecryptionProvider + decryptionSecret string + targetNamespace string +} + +var kustomizationArgs = NewKustomizationFlags() func init() { - createKsCmd.Flags().Var(&ksSource, "source", ksSource.Description()) - createKsCmd.Flags().Var(&ksPath, "path", "path to the directory containing a kustomization.yaml file") - createKsCmd.Flags().BoolVar(&ksPrune, "prune", false, "enable garbage collection") - createKsCmd.Flags().StringArrayVar(&ksHealthCheck, "health-check", nil, "workload to be included in the health assessment, in the format '/.'") - createKsCmd.Flags().DurationVar(&ksHealthTimeout, "health-check-timeout", 2*time.Minute, "timeout of health checking operations") - createKsCmd.Flags().StringVar(&ksValidation, "validation", "", "validate the manifests before applying them on the cluster, can be 'client' or 'server'") - createKsCmd.Flags().StringArrayVar(&ksDependsOn, "depends-on", nil, "Kustomization that must be ready before this Kustomization can be applied, supported formats '' and '/'") - createKsCmd.Flags().StringVar(&ksSAName, "service-account", "", "the name of the service account to impersonate when reconciling this Kustomization") - 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") + createKsCmd.Flags().Var(&kustomizationArgs.source, "source", kustomizationArgs.source.Description()) + createKsCmd.Flags().Var(&kustomizationArgs.path, "path", "path to the directory containing a kustomization.yaml file") + createKsCmd.Flags().BoolVar(&kustomizationArgs.prune, "prune", false, "enable garbage collection") + createKsCmd.Flags().StringArrayVar(&kustomizationArgs.healthCheck, "health-check", nil, "workload to be included in the health assessment, in the format '/.'") + createKsCmd.Flags().DurationVar(&kustomizationArgs.healthTimeout, "health-check-timeout", 2*time.Minute, "timeout of health checking operations") + createKsCmd.Flags().StringVar(&kustomizationArgs.validation, "validation", "", "validate the manifests before applying them on the cluster, can be 'client' or 'server'") + createKsCmd.Flags().StringArrayVar(&kustomizationArgs.dependsOn, "depends-on", nil, "Kustomization that must be ready before this Kustomization can be applied, supported formats '' and '/'") + createKsCmd.Flags().StringVar(&kustomizationArgs.saName, "service-account", "", "the name of the service account to impersonate when reconciling this Kustomization") + createKsCmd.Flags().Var(&kustomizationArgs.decryptionProvider, "decryption-provider", kustomizationArgs.decryptionProvider.Description()) + createKsCmd.Flags().StringVar(&kustomizationArgs.decryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption") + createKsCmd.Flags().StringVar(&kustomizationArgs.targetNamespace, "target-namespace", "", "overrides the namespace of all Kustomization objects reconciled by this Kustomization") createCmd.AddCommand(createKsCmd) } +func NewKustomizationFlags() kustomizationFlags { + return kustomizationFlags{ + path: "./", + } +} + func createKsCmdRun(cmd *cobra.Command, args []string) error { if len(args) < 1 { return fmt.Errorf("Kustomization name is required") } name := args[0] - if ksPath == "" { + if kustomizationArgs.path == "" { return fmt.Errorf("path is required") } - if !strings.HasPrefix(ksPath.String(), "./") { + if !strings.HasPrefix(kustomizationArgs.path.String(), "./") { return fmt.Errorf("path must begin with ./") } - if !export { + if !createArgs.export { logger.Generatef("generating Kustomization") } - ksLabels, err := parseLabels() + kslabels, err := parseLabels() if err != nil { return err } @@ -126,29 +134,29 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { kustomization := kustomizev1.Kustomization{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, - Labels: ksLabels, + Namespace: rootArgs.namespace, + Labels: kslabels, }, Spec: kustomizev1.KustomizationSpec{ - DependsOn: utils.MakeDependsOn(ksDependsOn), + DependsOn: utils.MakeDependsOn(kustomizationArgs.dependsOn), Interval: metav1.Duration{ - Duration: interval, + Duration: createArgs.interval, }, - Path: ksPath.String(), - Prune: ksPrune, + Path: kustomizationArgs.path.String(), + Prune: kustomizationArgs.prune, SourceRef: kustomizev1.CrossNamespaceSourceReference{ - Kind: ksSource.Kind, - Name: ksSource.Name, + Kind: kustomizationArgs.source.Kind, + Name: kustomizationArgs.source.Name, }, Suspend: false, - Validation: ksValidation, - TargetNamespace: ksTargetNamespace, + Validation: kustomizationArgs.validation, + TargetNamespace: kustomizationArgs.targetNamespace, }, } - if len(ksHealthCheck) > 0 { + if len(kustomizationArgs.healthCheck) > 0 { healthChecks := make([]kustomizev1.CrossNamespaceObjectReference, 0) - for _, w := range ksHealthCheck { + for _, w := range kustomizationArgs.healthCheck { kindObj := strings.Split(w, "/") if len(kindObj) != 2 { return fmt.Errorf("invalid health check '%s' must be in the format 'kind/name.namespace' %v", w, kindObj) @@ -183,32 +191,32 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { } kustomization.Spec.HealthChecks = healthChecks kustomization.Spec.Timeout = &metav1.Duration{ - Duration: ksHealthTimeout, + Duration: kustomizationArgs.healthTimeout, } } - if ksSAName != "" { - kustomization.Spec.ServiceAccountName = ksSAName + if kustomizationArgs.saName != "" { + kustomization.Spec.ServiceAccountName = kustomizationArgs.saName } - if ksDecryptionProvider != "" { + if kustomizationArgs.decryptionProvider != "" { kustomization.Spec.Decryption = &kustomizev1.Decryption{ - Provider: ksDecryptionProvider.String(), + Provider: kustomizationArgs.decryptionProvider.String(), } - if ksDecryptionSecret != "" { - kustomization.Spec.Decryption.SecretRef = &corev1.LocalObjectReference{Name: ksDecryptionSecret} + if kustomizationArgs.decryptionSecret != "" { + kustomization.Spec.Decryption.SecretRef = &corev1.LocalObjectReference{Name: kustomizationArgs.decryptionSecret} } } - if export { + if createArgs.export { return exportKs(kustomization) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -220,7 +228,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for Kustomization reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isKustomizationReady(ctx, kubeClient, namespacedName, &kustomization)); err != nil { return err } diff --git a/cmd/flux/create_receiver.go b/cmd/flux/create_receiver.go index 30bc4aa9..62bba90c 100644 --- a/cmd/flux/create_receiver.go +++ b/cmd/flux/create_receiver.go @@ -50,18 +50,20 @@ var createReceiverCmd = &cobra.Command{ RunE: createReceiverCmdRun, } -var ( - rcvType string - rcvSecretRef string - rcvEvents []string - rcvResources []string -) +type receiverFlags struct { + receiverType string + secretRef string + events []string + resources []string +} + +var receiverArgs receiverFlags func init() { - createReceiverCmd.Flags().StringVar(&rcvType, "type", "", "") - createReceiverCmd.Flags().StringVar(&rcvSecretRef, "secret-ref", "", "") - createReceiverCmd.Flags().StringArrayVar(&rcvEvents, "event", []string{}, "") - createReceiverCmd.Flags().StringArrayVar(&rcvResources, "resource", []string{}, "") + createReceiverCmd.Flags().StringVar(&receiverArgs.receiverType, "type", "", "") + createReceiverCmd.Flags().StringVar(&receiverArgs.secretRef, "secret-ref", "", "") + createReceiverCmd.Flags().StringArrayVar(&receiverArgs.events, "event", []string{}, "") + createReceiverCmd.Flags().StringArrayVar(&receiverArgs.resources, "resource", []string{}, "") createCmd.AddCommand(createReceiverCmd) } @@ -71,16 +73,16 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - if rcvType == "" { + if receiverArgs.receiverType == "" { return fmt.Errorf("Receiver type is required") } - if rcvSecretRef == "" { + if receiverArgs.secretRef == "" { return fmt.Errorf("secret ref is required") } resources := []notificationv1.CrossNamespaceObjectReference{} - for _, resource := range rcvResources { + for _, resource := range receiverArgs.resources { kind, name := utils.ParseObjectKindName(resource) if kind == "" { return fmt.Errorf("invalid event source '%s', must be in format /", resource) @@ -101,35 +103,35 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { return err } - if !export { + if !createArgs.export { logger.Generatef("generating Receiver") } receiver := notificationv1.Receiver{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: notificationv1.ReceiverSpec{ - Type: rcvType, - Events: rcvEvents, + Type: receiverArgs.receiverType, + Events: receiverArgs.events, Resources: resources, SecretRef: corev1.LocalObjectReference{ - Name: rcvSecretRef, + Name: receiverArgs.secretRef, }, Suspend: false, }, } - if export { + if createArgs.export { return exportReceiver(receiver) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -141,7 +143,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for Receiver reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isReceiverReady(ctx, kubeClient, namespacedName, &receiver)); err != nil { return err } diff --git a/cmd/flux/create_secret_git.go b/cmd/flux/create_secret_git.go index 693008ab..0178fa3e 100644 --- a/cmd/flux/create_secret_git.go +++ b/cmd/flux/create_secret_git.go @@ -71,37 +71,47 @@ For Git over HTTP/S, the provided basic authentication credentials are stored in RunE: createSecretGitCmdRun, } -var ( - secretGitURL string - secretGitUsername string - secretGitPassword string - secretGitKeyAlgorithm flags.PublicKeyAlgorithm = "rsa" - secretGitRSABits flags.RSAKeyBits = 2048 - secretGitECDSACurve = flags.ECDSACurve{Curve: elliptic.P384()} -) +type secretGitFlags struct { + url string + username string + password string + keyAlgorithm flags.PublicKeyAlgorithm + rsaBits flags.RSAKeyBits + ecdsaCurve flags.ECDSACurve +} + +var secretGitArgs = NewSecretGitFlags() func init() { - createSecretGitCmd.Flags().StringVar(&secretGitURL, "url", "", "git address, e.g. ssh://git@host/org/repository") - createSecretGitCmd.Flags().StringVarP(&secretGitUsername, "username", "u", "", "basic authentication username") - createSecretGitCmd.Flags().StringVarP(&secretGitPassword, "password", "p", "", "basic authentication password") - createSecretGitCmd.Flags().Var(&secretGitKeyAlgorithm, "ssh-key-algorithm", secretGitKeyAlgorithm.Description()) - createSecretGitCmd.Flags().Var(&secretGitRSABits, "ssh-rsa-bits", secretGitRSABits.Description()) - createSecretGitCmd.Flags().Var(&secretGitECDSACurve, "ssh-ecdsa-curve", secretGitECDSACurve.Description()) + createSecretGitCmd.Flags().StringVar(&secretGitArgs.url, "url", "", "git address, e.g. ssh://git@host/org/repository") + createSecretGitCmd.Flags().StringVarP(&secretGitArgs.username, "username", "u", "", "basic authentication username") + createSecretGitCmd.Flags().StringVarP(&secretGitArgs.password, "password", "p", "", "basic authentication password") + createSecretGitCmd.Flags().Var(&secretGitArgs.keyAlgorithm, "ssh-key-algorithm", secretGitArgs.keyAlgorithm.Description()) + createSecretGitCmd.Flags().Var(&secretGitArgs.rsaBits, "ssh-rsa-bits", secretGitArgs.rsaBits.Description()) + createSecretGitCmd.Flags().Var(&secretGitArgs.ecdsaCurve, "ssh-ecdsa-curve", secretGitArgs.ecdsaCurve.Description()) createSecretCmd.AddCommand(createSecretGitCmd) } +func NewSecretGitFlags() secretGitFlags { + return secretGitFlags{ + keyAlgorithm: "rsa", + rsaBits: 2048, + ecdsaCurve: flags.ECDSACurve{Curve: elliptic.P384()}, + } +} + func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { if len(args) < 1 { return fmt.Errorf("secret name is required") } name := args[0] - if secretGitURL == "" { + if secretGitArgs.url == "" { return fmt.Errorf("url is required") } - u, err := url.Parse(secretGitURL) + u, err := url.Parse(secretGitArgs.url) if err != nil { return fmt.Errorf("git URL parse failed: %w", err) } @@ -111,20 +121,20 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { return err } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: secretLabels, }, } switch u.Scheme { case "ssh": - pair, err := generateKeyPair(ctx, secretGitKeyAlgorithm, secretGitRSABits, secretGitECDSACurve) + pair, err := generateKeyPair(ctx, secretGitArgs.keyAlgorithm, secretGitArgs.rsaBits, secretGitArgs.ecdsaCurve) if err != nil { return err } @@ -140,28 +150,28 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { "known_hosts": hostKey, } - if !export { + if !createArgs.export { logger.Generatef("deploy key: %s", string(pair.PublicKey)) } case "http", "https": - if secretGitUsername == "" || secretGitPassword == "" { + if secretGitArgs.username == "" || secretGitArgs.password == "" { return fmt.Errorf("for Git over HTTP/S the username and password are required") } // TODO: add cert data when it's implemented in source-controller secret.Data = map[string][]byte{ - "username": []byte(secretGitUsername), - "password": []byte(secretGitPassword), + "username": []byte(secretGitArgs.username), + "password": []byte(secretGitArgs.password), } default: return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme) } - if export { + if createArgs.export { return exportSecret(secret) } - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -169,7 +179,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { if err := upsertSecret(ctx, kubeClient, secret); err != nil { return err } - logger.Actionf("secret '%s' created in '%s' namespace", name, namespace) + logger.Actionf("secret '%s' created in '%s' namespace", name, rootArgs.namespace) return nil } diff --git a/cmd/flux/create_secret_helm.go b/cmd/flux/create_secret_helm.go index e0b22ac6..e137c12a 100644 --- a/cmd/flux/create_secret_helm.go +++ b/cmd/flux/create_secret_helm.go @@ -55,20 +55,22 @@ The create secret helm command generates a Kubernetes secret with basic authenti RunE: createSecretHelmCmdRun, } -var ( - secretHelmUsername string - secretHelmPassword string - secretHelmCertFile string - secretHelmKeyFile string - secretHelmCAFile string -) +type secretHelmFlags struct { + username string + password string + certFile string + keyFile string + caFile string +} + +var secretHelmArgs secretHelmFlags func init() { - createSecretHelmCmd.Flags().StringVarP(&secretHelmUsername, "username", "u", "", "basic authentication username") - createSecretHelmCmd.Flags().StringVarP(&secretHelmPassword, "password", "p", "", "basic authentication password") - createSecretHelmCmd.Flags().StringVar(&secretHelmCertFile, "cert-file", "", "TLS authentication cert file path") - createSecretHelmCmd.Flags().StringVar(&secretHelmKeyFile, "key-file", "", "TLS authentication key file path") - createSecretHelmCmd.Flags().StringVar(&secretHelmCAFile, "ca-file", "", "TLS authentication CA file path") + createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.username, "username", "u", "", "basic authentication username") + createSecretHelmCmd.Flags().StringVarP(&secretHelmArgs.password, "password", "p", "", "basic authentication password") + createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.certFile, "cert-file", "", "TLS authentication cert file path") + createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.keyFile, "key-file", "", "TLS authentication key file path") + createSecretHelmCmd.Flags().StringVar(&secretHelmArgs.caFile, "ca-file", "", "TLS authentication CA file path") createSecretCmd.AddCommand(createSecretHelmCmd) } @@ -87,47 +89,47 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error { secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: secretLabels, }, StringData: map[string]string{}, } - if secretHelmUsername != "" && secretHelmPassword != "" { - secret.StringData["username"] = secretHelmUsername - secret.StringData["password"] = secretHelmPassword + if secretHelmArgs.username != "" && secretHelmArgs.password != "" { + secret.StringData["username"] = secretHelmArgs.username + secret.StringData["password"] = secretHelmArgs.password } - if secretHelmCertFile != "" && secretHelmKeyFile != "" { - cert, err := ioutil.ReadFile(secretHelmCertFile) + if secretHelmArgs.certFile != "" && secretHelmArgs.keyFile != "" { + cert, err := ioutil.ReadFile(secretHelmArgs.certFile) if err != nil { - return fmt.Errorf("failed to read repository cert file '%s': %w", secretHelmCertFile, err) + return fmt.Errorf("failed to read repository cert file '%s': %w", secretHelmArgs.certFile, err) } secret.StringData["certFile"] = string(cert) - key, err := ioutil.ReadFile(secretHelmKeyFile) + key, err := ioutil.ReadFile(secretHelmArgs.keyFile) if err != nil { - return fmt.Errorf("failed to read repository key file '%s': %w", secretHelmKeyFile, err) + return fmt.Errorf("failed to read repository key file '%s': %w", secretHelmArgs.keyFile, err) } secret.StringData["keyFile"] = string(key) } - if secretHelmCAFile != "" { - ca, err := ioutil.ReadFile(secretHelmCAFile) + if secretHelmArgs.caFile != "" { + ca, err := ioutil.ReadFile(secretHelmArgs.caFile) if err != nil { - return fmt.Errorf("failed to read repository CA file '%s': %w", secretHelmCAFile, err) + return fmt.Errorf("failed to read repository CA file '%s': %w", secretHelmArgs.caFile, err) } secret.StringData["caFile"] = string(ca) } - if export { + if createArgs.export { return exportSecret(secret) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } @@ -135,7 +137,7 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error { if err := upsertSecret(ctx, kubeClient, secret); err != nil { return err } - logger.Actionf("secret '%s' created in '%s' namespace", name, namespace) + logger.Actionf("secret '%s' created in '%s' namespace", name, rootArgs.namespace) return nil } diff --git a/cmd/flux/create_source_bucket.go b/cmd/flux/create_source_bucket.go index 1cebb798..f6bae667 100644 --- a/cmd/flux/create_source_bucket.go +++ b/cmd/flux/create_source_bucket.go @@ -61,41 +61,49 @@ For Buckets with static authentication, the credentials are stored in a Kubernet RunE: createSourceBucketCmdRun, } -var ( - sourceBucketName string - sourceBucketProvider = flags.SourceBucketProvider(sourcev1.GenericBucketProvider) - sourceBucketEndpoint string - sourceBucketAccessKey string - sourceBucketSecretKey string - sourceBucketRegion string - sourceBucketInsecure bool - sourceBucketSecretRef string -) +type sourceBucketFlags struct { + name string + provider flags.SourceBucketProvider + endpoint string + accessKey string + secretKey string + region string + insecure bool + secretRef string +} + +var sourceBucketArgs = NewSourceBucketFlags() func init() { - createSourceBucketCmd.Flags().Var(&sourceBucketProvider, "provider", sourceBucketProvider.Description()) - createSourceBucketCmd.Flags().StringVar(&sourceBucketName, "bucket-name", "", "the bucket name") - createSourceBucketCmd.Flags().StringVar(&sourceBucketEndpoint, "endpoint", "", "the bucket endpoint address") - createSourceBucketCmd.Flags().StringVar(&sourceBucketAccessKey, "access-key", "", "the bucket access key") - createSourceBucketCmd.Flags().StringVar(&sourceBucketSecretKey, "secret-key", "", "the bucket secret key") - createSourceBucketCmd.Flags().StringVar(&sourceBucketRegion, "region", "", "the bucket region") - createSourceBucketCmd.Flags().BoolVar(&sourceBucketInsecure, "insecure", false, "for when connecting to a non-TLS S3 HTTP endpoint") - createSourceBucketCmd.Flags().StringVar(&sourceBucketSecretRef, "secret-ref", "", "the name of an existing secret containing credentials") + createSourceBucketCmd.Flags().Var(&sourceBucketArgs.provider, "provider", sourceBucketArgs.provider.Description()) + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.name, "bucket-name", "", "the bucket name") + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.endpoint, "endpoint", "", "the bucket endpoint address") + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.accessKey, "access-key", "", "the bucket access key") + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.secretKey, "secret-key", "", "the bucket secret key") + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.region, "region", "", "the bucket region") + createSourceBucketCmd.Flags().BoolVar(&sourceBucketArgs.insecure, "insecure", false, "for when connecting to a non-TLS S3 HTTP endpoint") + createSourceBucketCmd.Flags().StringVar(&sourceBucketArgs.secretRef, "secret-ref", "", "the name of an existing secret containing credentials") createSourceCmd.AddCommand(createSourceBucketCmd) } +func NewSourceBucketFlags() sourceBucketFlags { + return sourceBucketFlags{ + provider: flags.SourceBucketProvider(sourcev1.GenericBucketProvider), + } +} + func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { if len(args) < 1 { return fmt.Errorf("Bucket source name is required") } name := args[0] - if sourceBucketName == "" { + if sourceBucketArgs.name == "" { return fmt.Errorf("bucket-name is required") } - if sourceBucketEndpoint == "" { + if sourceBucketArgs.endpoint == "" { return fmt.Errorf("endpoint is required") } @@ -113,55 +121,55 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { bucket := &sourcev1.Bucket{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: sourcev1.BucketSpec{ - BucketName: sourceBucketName, - Provider: sourceBucketProvider.String(), - Insecure: sourceBucketInsecure, - Endpoint: sourceBucketEndpoint, - Region: sourceBucketRegion, + BucketName: sourceBucketArgs.name, + Provider: sourceBucketArgs.provider.String(), + Insecure: sourceBucketArgs.insecure, + Endpoint: sourceBucketArgs.endpoint, + Region: sourceBucketArgs.region, Interval: metav1.Duration{ - Duration: interval, + Duration: createArgs.interval, }, }, } - if sourceHelmSecretRef != "" { + if sourceHelmArgs.secretRef != "" { bucket.Spec.SecretRef = &corev1.LocalObjectReference{ - Name: sourceBucketSecretRef, + Name: sourceBucketArgs.secretRef, } } - if export { + if createArgs.export { return exportBucket(*bucket) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } logger.Generatef("generating Bucket source") - if sourceBucketSecretRef == "" { + if sourceBucketArgs.secretRef == "" { secretName := fmt.Sprintf("bucket-%s", name) secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, StringData: map[string]string{}, } - if sourceBucketAccessKey != "" && sourceBucketSecretKey != "" { - secret.StringData["accesskey"] = sourceBucketAccessKey - secret.StringData["secretkey"] = sourceBucketSecretKey + if sourceBucketArgs.accessKey != "" && sourceBucketArgs.secretKey != "" { + secret.StringData["accesskey"] = sourceBucketArgs.accessKey + secret.StringData["secretkey"] = sourceBucketArgs.secretKey } if len(secret.StringData) > 0 { @@ -183,7 +191,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for Bucket source reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isBucketReady(ctx, kubeClient, namespacedName, bucket)); err != nil { return err } diff --git a/cmd/flux/create_source_git.go b/cmd/flux/create_source_git.go index 4ca684bc..0243e206 100644 --- a/cmd/flux/create_source_git.go +++ b/cmd/flux/create_source_git.go @@ -40,6 +40,21 @@ import ( sourcev1 "github.com/fluxcd/source-controller/api/v1beta1" ) +type SourceGitFlags struct { + GitURL string + GitBranch string + GitTag string + GitSemver string + GitUsername string + GitPassword string + + GitKeyAlgorithm flags.PublicKeyAlgorithm + GitRSABits flags.RSAKeyBits + GitECDSACurve flags.ECDSACurve + GitSecretRef string + GitImplementation flags.GitImplementation +} + var createSourceGitCmd = &cobra.Command{ Use: "git [name]", Short: "Create or update a GitRepository source", @@ -84,44 +99,39 @@ For private Git repositories, the basic authentication credentials are stored in RunE: createSourceGitCmdRun, } -var ( - sourceGitURL string - sourceGitBranch string - sourceGitTag string - sourceGitSemver string - sourceGitUsername string - sourceGitPassword string - - sourceGitKeyAlgorithm flags.PublicKeyAlgorithm = "rsa" - sourceGitRSABits flags.RSAKeyBits = 2048 - sourceGitECDSACurve = flags.ECDSACurve{Curve: elliptic.P384()} - sourceGitSecretRef string - sourceGitImplementation flags.GitImplementation -) +var sourceArgs = NewSourceGitFlags() func init() { - createSourceGitCmd.Flags().StringVar(&sourceGitURL, "url", "", "git address, e.g. ssh://git@host/org/repository") - createSourceGitCmd.Flags().StringVar(&sourceGitBranch, "branch", "master", "git branch") - createSourceGitCmd.Flags().StringVar(&sourceGitTag, "tag", "", "git tag") - createSourceGitCmd.Flags().StringVar(&sourceGitSemver, "tag-semver", "", "git tag semver range") - createSourceGitCmd.Flags().StringVarP(&sourceGitUsername, "username", "u", "", "basic authentication username") - createSourceGitCmd.Flags().StringVarP(&sourceGitPassword, "password", "p", "", "basic authentication password") - createSourceGitCmd.Flags().Var(&sourceGitKeyAlgorithm, "ssh-key-algorithm", sourceGitKeyAlgorithm.Description()) - createSourceGitCmd.Flags().Var(&sourceGitRSABits, "ssh-rsa-bits", sourceGitRSABits.Description()) - createSourceGitCmd.Flags().Var(&sourceGitECDSACurve, "ssh-ecdsa-curve", sourceGitECDSACurve.Description()) - createSourceGitCmd.Flags().StringVarP(&sourceGitSecretRef, "secret-ref", "", "", "the name of an existing secret containing SSH or basic credentials") - createSourceGitCmd.Flags().Var(&sourceGitImplementation, "git-implementation", sourceGitImplementation.Description()) + createSourceGitCmd.Flags().StringVar(&sourceArgs.GitURL, "url", "", "git address, e.g. ssh://git@host/org/repository") + createSourceGitCmd.Flags().StringVar(&sourceArgs.GitBranch, "branch", "master", "git branch") + createSourceGitCmd.Flags().StringVar(&sourceArgs.GitTag, "tag", "", "git tag") + createSourceGitCmd.Flags().StringVar(&sourceArgs.GitSemver, "tag-semver", "", "git tag semver range") + createSourceGitCmd.Flags().StringVarP(&sourceArgs.GitUsername, "username", "u", "", "basic authentication username") + createSourceGitCmd.Flags().StringVarP(&sourceArgs.GitPassword, "password", "p", "", "basic authentication password") + createSourceGitCmd.Flags().Var(&sourceArgs.GitKeyAlgorithm, "ssh-key-algorithm", sourceArgs.GitKeyAlgorithm.Description()) + createSourceGitCmd.Flags().Var(&sourceArgs.GitRSABits, "ssh-rsa-bits", sourceArgs.GitRSABits.Description()) + createSourceGitCmd.Flags().Var(&sourceArgs.GitECDSACurve, "ssh-ecdsa-curve", sourceArgs.GitECDSACurve.Description()) + createSourceGitCmd.Flags().StringVarP(&sourceArgs.GitSecretRef, "secret-ref", "", "", "the name of an existing secret containing SSH or basic credentials") + createSourceGitCmd.Flags().Var(&sourceArgs.GitImplementation, "git-implementation", sourceArgs.GitImplementation.Description()) createSourceCmd.AddCommand(createSourceGitCmd) } +func NewSourceGitFlags() SourceGitFlags { + return SourceGitFlags{ + GitKeyAlgorithm: "rsa", + GitRSABits: 2048, + GitECDSACurve: flags.ECDSACurve{Curve: elliptic.P384()}, + } +} + func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { if len(args) < 1 { return fmt.Errorf("GitRepository source name is required") } name := args[0] - if sourceGitURL == "" { + if sourceArgs.GitURL == "" { return fmt.Errorf("url is required") } @@ -131,7 +141,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } defer os.RemoveAll(tmpDir) - u, err := url.Parse(sourceGitURL) + u, err := url.Parse(sourceArgs.GitURL) if err != nil { return fmt.Errorf("git URL parse failed: %w", err) } @@ -144,54 +154,54 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { gitRepository := sourcev1.GitRepository{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: sourcev1.GitRepositorySpec{ - URL: sourceGitURL, + URL: sourceArgs.GitURL, Interval: metav1.Duration{ - Duration: interval, + Duration: createArgs.interval, }, Reference: &sourcev1.GitRepositoryRef{}, }, } - if sourceGitImplementation != "" { - gitRepository.Spec.GitImplementation = sourceGitImplementation.String() + if sourceArgs.GitImplementation != "" { + gitRepository.Spec.GitImplementation = sourceArgs.GitImplementation.String() } - if sourceGitSemver != "" { - gitRepository.Spec.Reference.SemVer = sourceGitSemver - } else if sourceGitTag != "" { - gitRepository.Spec.Reference.Tag = sourceGitTag + if sourceArgs.GitSemver != "" { + gitRepository.Spec.Reference.SemVer = sourceArgs.GitSemver + } else if sourceArgs.GitTag != "" { + gitRepository.Spec.Reference.Tag = sourceArgs.GitTag } else { - gitRepository.Spec.Reference.Branch = sourceGitBranch + gitRepository.Spec.Reference.Branch = sourceArgs.GitBranch } - if export { - if sourceGitSecretRef != "" { + if createArgs.export { + if sourceArgs.GitSecretRef != "" { gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{ - Name: sourceGitSecretRef, + Name: sourceArgs.GitSecretRef, } } return exportGit(gitRepository) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } withAuth := false // TODO(hidde): move all auth prep to separate func? - if sourceGitSecretRef != "" { + if sourceArgs.GitSecretRef != "" { withAuth = true } else if u.Scheme == "ssh" { logger.Generatef("generating deploy key pair") - pair, err := generateKeyPair(ctx, sourceGitKeyAlgorithm, sourceGitRSABits, sourceGitECDSACurve) + pair, err := generateKeyPair(ctx, sourceArgs.GitKeyAlgorithm, sourceArgs.GitRSABits, sourceArgs.GitECDSACurve) if err != nil { return err } @@ -216,7 +226,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, StringData: map[string]string{ @@ -229,17 +239,17 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { return err } withAuth = true - } else if sourceGitUsername != "" && sourceGitPassword != "" { + } else if sourceArgs.GitUsername != "" && sourceArgs.GitPassword != "" { logger.Actionf("applying secret with basic auth credentials") secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, StringData: map[string]string{ - "username": sourceGitUsername, - "password": sourceGitPassword, + "username": sourceArgs.GitUsername, + "password": sourceArgs.GitPassword, }, } if err := upsertSecret(ctx, kubeClient, secret); err != nil { @@ -256,8 +266,8 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { if withAuth { secretName := name - if sourceGitSecretRef != "" { - secretName = sourceGitSecretRef + if sourceArgs.GitSecretRef != "" { + secretName = sourceArgs.GitSecretRef } gitRepository.Spec.SecretRef = &corev1.LocalObjectReference{ Name: secretName, @@ -271,7 +281,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for GitRepository source reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isGitRepositoryReady(ctx, kubeClient, namespacedName, &gitRepository)); err != nil { return err } diff --git a/cmd/flux/create_source_helm.go b/cmd/flux/create_source_helm.go index 78f85f8d..0570604d 100644 --- a/cmd/flux/create_source_helm.go +++ b/cmd/flux/create_source_helm.go @@ -64,24 +64,26 @@ For private Helm repositories, the basic authentication credentials are stored i RunE: createSourceHelmCmdRun, } -var ( - sourceHelmURL string - sourceHelmUsername string - sourceHelmPassword string - sourceHelmCertFile string - sourceHelmKeyFile string - sourceHelmCAFile string - sourceHelmSecretRef string -) +type sourceHelmFlags struct { + url string + username string + password string + certFile string + keyFile string + caFile string + secretRef string +} + +var sourceHelmArgs sourceHelmFlags func init() { - createSourceHelmCmd.Flags().StringVar(&sourceHelmURL, "url", "", "Helm repository address") - createSourceHelmCmd.Flags().StringVarP(&sourceHelmUsername, "username", "u", "", "basic authentication username") - createSourceHelmCmd.Flags().StringVarP(&sourceHelmPassword, "password", "p", "", "basic authentication password") - createSourceHelmCmd.Flags().StringVar(&sourceHelmCertFile, "cert-file", "", "TLS authentication cert file path") - createSourceHelmCmd.Flags().StringVar(&sourceHelmKeyFile, "key-file", "", "TLS authentication key file path") - createSourceHelmCmd.Flags().StringVar(&sourceHelmCAFile, "ca-file", "", "TLS authentication CA file path") - createSourceHelmCmd.Flags().StringVarP(&sourceHelmSecretRef, "secret-ref", "", "", "the name of an existing secret containing TLS or basic auth credentials") + createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.url, "url", "", "Helm repository address") + createSourceHelmCmd.Flags().StringVarP(&sourceHelmArgs.username, "username", "u", "", "basic authentication username") + createSourceHelmCmd.Flags().StringVarP(&sourceHelmArgs.password, "password", "p", "", "basic authentication password") + createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.certFile, "cert-file", "", "TLS authentication cert file path") + createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.keyFile, "key-file", "", "TLS authentication key file path") + createSourceHelmCmd.Flags().StringVar(&sourceHelmArgs.caFile, "ca-file", "", "TLS authentication CA file path") + createSourceHelmCmd.Flags().StringVarP(&sourceHelmArgs.secretRef, "secret-ref", "", "", "the name of an existing secret containing TLS or basic auth credentials") createSourceCmd.AddCommand(createSourceHelmCmd) } @@ -92,7 +94,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - if sourceHelmURL == "" { + if sourceHelmArgs.url == "" { return fmt.Errorf("url is required") } @@ -107,78 +109,78 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } defer os.RemoveAll(tmpDir) - if _, err := url.Parse(sourceHelmURL); err != nil { + if _, err := url.Parse(sourceHelmArgs.url); err != nil { return fmt.Errorf("url parse failed: %w", err) } helmRepository := &sourcev1.HelmRepository{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, Spec: sourcev1.HelmRepositorySpec{ - URL: sourceHelmURL, + URL: sourceHelmArgs.url, Interval: metav1.Duration{ - Duration: interval, + Duration: createArgs.interval, }, }, } - if sourceHelmSecretRef != "" { + if sourceHelmArgs.secretRef != "" { helmRepository.Spec.SecretRef = &corev1.LocalObjectReference{ - Name: sourceHelmSecretRef, + Name: sourceHelmArgs.secretRef, } } - if export { + if createArgs.export { return exportHelmRepository(*helmRepository) } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } logger.Generatef("generating HelmRepository source") - if sourceHelmSecretRef == "" { + if sourceHelmArgs.secretRef == "" { secretName := fmt.Sprintf("helm-%s", name) secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, - Namespace: namespace, + Namespace: rootArgs.namespace, Labels: sourceLabels, }, StringData: map[string]string{}, } - if sourceHelmUsername != "" && sourceHelmPassword != "" { - secret.StringData["username"] = sourceHelmUsername - secret.StringData["password"] = sourceHelmPassword + if sourceHelmArgs.username != "" && sourceHelmArgs.password != "" { + secret.StringData["username"] = sourceHelmArgs.username + secret.StringData["password"] = sourceHelmArgs.password } - if sourceHelmCertFile != "" && sourceHelmKeyFile != "" { - cert, err := ioutil.ReadFile(sourceHelmCertFile) + if sourceHelmArgs.certFile != "" && sourceHelmArgs.keyFile != "" { + cert, err := ioutil.ReadFile(sourceHelmArgs.certFile) if err != nil { - return fmt.Errorf("failed to read repository cert file '%s': %w", sourceHelmCertFile, err) + return fmt.Errorf("failed to read repository cert file '%s': %w", sourceHelmArgs.certFile, err) } secret.StringData["certFile"] = string(cert) - key, err := ioutil.ReadFile(sourceHelmKeyFile) + key, err := ioutil.ReadFile(sourceHelmArgs.keyFile) if err != nil { - return fmt.Errorf("failed to read repository key file '%s': %w", sourceHelmKeyFile, err) + return fmt.Errorf("failed to read repository key file '%s': %w", sourceHelmArgs.keyFile, err) } secret.StringData["keyFile"] = string(key) } - if sourceHelmCAFile != "" { - ca, err := ioutil.ReadFile(sourceHelmCAFile) + if sourceHelmArgs.caFile != "" { + ca, err := ioutil.ReadFile(sourceHelmArgs.caFile) if err != nil { - return fmt.Errorf("failed to read repository CA file '%s': %w", sourceHelmCAFile, err) + return fmt.Errorf("failed to read repository CA file '%s': %w", sourceHelmArgs.caFile, err) } secret.StringData["caFile"] = string(ca) } @@ -202,7 +204,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } logger.Waitingf("waiting for HelmRepository source reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isHelmRepositoryReady(ctx, kubeClient, namespacedName, helmRepository)); err != nil { return err } diff --git a/cmd/flux/create_tenant.go b/cmd/flux/create_tenant.go index 185b45a0..3af59ca0 100644 --- a/cmd/flux/create_tenant.go +++ b/cmd/flux/create_tenant.go @@ -58,14 +58,16 @@ const ( tenantLabel = "toolkit.fluxcd.io/tenant" ) -var ( - tenantNamespaces []string - tenantClusterRole string -) +type tenantFlags struct { + namespaces []string + clusterRole string +} + +var tenantArgs tenantFlags func init() { - createTenantCmd.Flags().StringSliceVar(&tenantNamespaces, "with-namespace", nil, "namespace belonging to this tenant") - createTenantCmd.Flags().StringVar(&tenantClusterRole, "cluster-role", "cluster-admin", "cluster role of the tenant role binding") + createTenantCmd.Flags().StringSliceVar(&tenantArgs.namespaces, "with-namespace", nil, "namespace belonging to this tenant") + createTenantCmd.Flags().StringVar(&tenantArgs.clusterRole, "cluster-role", "cluster-admin", "cluster role of the tenant role binding") createCmd.AddCommand(createTenantCmd) } @@ -78,11 +80,11 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid tenant name '%s': %v", tenant, err) } - if tenantClusterRole == "" { + if tenantArgs.clusterRole == "" { return fmt.Errorf("cluster-role is required") } - if tenantNamespaces == nil { + if tenantArgs.namespaces == nil { return fmt.Errorf("with-namespace is required") } @@ -90,7 +92,7 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { var accounts []corev1.ServiceAccount var roleBindings []rbacv1.RoleBinding - for _, ns := range tenantNamespaces { + for _, ns := range tenantArgs.namespaces { if err := validation.IsQualifiedName(ns); len(err) > 0 { return fmt.Errorf("invalid namespace '%s': %v", ns, err) } @@ -141,14 +143,14 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { RoleRef: rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", - Name: tenantClusterRole, + Name: tenantArgs.clusterRole, }, } roleBindings = append(roleBindings, roleBinding) } - if export { - for i, _ := range tenantNamespaces { + if createArgs.export { + for i, _ := range tenantArgs.namespaces { if err := exportTenant(namespaces[i], accounts[i], roleBindings[i]); err != nil { return err } @@ -156,15 +158,15 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { return nil } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - for i, _ := range tenantNamespaces { + for i, _ := range tenantArgs.namespaces { logger.Actionf("applying namespace %s", namespaces[i].Name) if err := upsertNamespace(ctx, kubeClient, namespaces[i]); err != nil { return err diff --git a/cmd/flux/delete.go b/cmd/flux/delete.go index d03ea43a..966f8800 100644 --- a/cmd/flux/delete.go +++ b/cmd/flux/delete.go @@ -33,12 +33,14 @@ var deleteCmd = &cobra.Command{ Long: "The delete sub-commands delete sources and resources.", } -var ( - deleteSilent bool -) +type deleteFlags struct { + silent bool +} + +var deleteArgs deleteFlags func init() { - deleteCmd.PersistentFlags().BoolVarP(&deleteSilent, "silent", "s", false, + deleteCmd.PersistentFlags().BoolVarP(&deleteArgs.silent, "silent", "s", false, "delete resource without asking for confirmation") rootCmd.AddCommand(deleteCmd) @@ -55,16 +57,16 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -73,7 +75,7 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this " + del.humanKind, IsConfirm: true, @@ -83,7 +85,7 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, namespace) + logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, rootArgs.namespace) err = kubeClient.Delete(ctx, del.object.asClientObject()) if err != nil { return err diff --git a/cmd/flux/delete_alert.go b/cmd/flux/delete_alert.go index bb8cb0bc..0f9ce12e 100644 --- a/cmd/flux/delete_alert.go +++ b/cmd/flux/delete_alert.go @@ -48,16 +48,16 @@ func deleteAlertCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -67,7 +67,7 @@ func deleteAlertCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this Alert", IsConfirm: true, @@ -77,7 +77,7 @@ func deleteAlertCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting alert %s in %s namespace", name, namespace) + logger.Actionf("deleting alert %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &alert) if err != nil { return err diff --git a/cmd/flux/delete_alertprovider.go b/cmd/flux/delete_alertprovider.go index c3ebc908..3e58e963 100644 --- a/cmd/flux/delete_alertprovider.go +++ b/cmd/flux/delete_alertprovider.go @@ -48,16 +48,16 @@ func deleteAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -67,7 +67,7 @@ func deleteAlertProviderCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this Provider", IsConfirm: true, @@ -77,7 +77,7 @@ func deleteAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting provider %s in %s namespace", name, namespace) + logger.Actionf("deleting provider %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &alertProvider) if err != nil { return err diff --git a/cmd/flux/delete_helmrelease.go b/cmd/flux/delete_helmrelease.go index 47249bda..a527b6c2 100644 --- a/cmd/flux/delete_helmrelease.go +++ b/cmd/flux/delete_helmrelease.go @@ -49,16 +49,16 @@ func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -68,7 +68,7 @@ func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { if !helmRelease.Spec.Suspend { logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s Helm release!", name) } @@ -81,7 +81,7 @@ func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting release %s in %s namespace", name, namespace) + logger.Actionf("deleting release %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &helmRelease) if err != nil { return err diff --git a/cmd/flux/delete_kustomization.go b/cmd/flux/delete_kustomization.go index 0d1fef3d..06a407cf 100644 --- a/cmd/flux/delete_kustomization.go +++ b/cmd/flux/delete_kustomization.go @@ -48,16 +48,16 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -67,7 +67,7 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { if !kustomization.Spec.Suspend { logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name) } @@ -80,7 +80,7 @@ func deleteKsCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting kustomization %s in %s namespace", name, namespace) + logger.Actionf("deleting kustomization %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &kustomization) if err != nil { return err diff --git a/cmd/flux/delete_receiver.go b/cmd/flux/delete_receiver.go index b92fe83f..deef850e 100644 --- a/cmd/flux/delete_receiver.go +++ b/cmd/flux/delete_receiver.go @@ -48,16 +48,16 @@ func deleteReceiverCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -67,7 +67,7 @@ func deleteReceiverCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this Receiver", IsConfirm: true, @@ -77,7 +77,7 @@ func deleteReceiverCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting receiver %s in %s namespace", name, namespace) + logger.Actionf("deleting receiver %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &receiver) if err != nil { return err diff --git a/cmd/flux/delete_source_bucket.go b/cmd/flux/delete_source_bucket.go index ccdcf3f1..09130e4f 100644 --- a/cmd/flux/delete_source_bucket.go +++ b/cmd/flux/delete_source_bucket.go @@ -47,16 +47,16 @@ func deleteSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -66,7 +66,7 @@ func deleteSourceBucketCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this source", IsConfirm: true, @@ -76,7 +76,7 @@ func deleteSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting source %s in %s namespace", name, namespace) + logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &bucket) if err != nil { return err diff --git a/cmd/flux/delete_source_git.go b/cmd/flux/delete_source_git.go index 7173c3a1..72c91852 100644 --- a/cmd/flux/delete_source_git.go +++ b/cmd/flux/delete_source_git.go @@ -47,16 +47,16 @@ func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -66,7 +66,7 @@ func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this source", IsConfirm: true, @@ -76,7 +76,7 @@ func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting source %s in %s namespace", name, namespace) + logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &git) if err != nil { return err diff --git a/cmd/flux/delete_source_helm.go b/cmd/flux/delete_source_helm.go index 5eb10d51..20b48b46 100644 --- a/cmd/flux/delete_source_helm.go +++ b/cmd/flux/delete_source_helm.go @@ -47,16 +47,16 @@ func deleteSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -66,7 +66,7 @@ func deleteSourceHelmCmdRun(cmd *cobra.Command, args []string) error { return err } - if !deleteSilent { + if !deleteArgs.silent { prompt := promptui.Prompt{ Label: "Are you sure you want to delete this source", IsConfirm: true, @@ -76,7 +76,7 @@ func deleteSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting source %s in %s namespace", name, namespace) + logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace) err = kubeClient.Delete(ctx, &helmRepository) if err != nil { return err diff --git a/cmd/flux/export.go b/cmd/flux/export.go index ec475306..0b60fba9 100644 --- a/cmd/flux/export.go +++ b/cmd/flux/export.go @@ -35,12 +35,14 @@ var exportCmd = &cobra.Command{ Long: "The export sub-commands export resources in YAML format.", } -var ( - exportAll bool -) +type exportFlags struct { + all bool +} + +var exportArgs exportFlags func init() { - exportCmd.PersistentFlags().BoolVar(&exportAll, "all", false, "select all resources") + exportCmd.PersistentFlags().BoolVar(&exportArgs.all, "all", false, "select all resources") rootCmd.AddCommand(exportCmd) } @@ -65,26 +67,26 @@ type exportCommand struct { } func (export exportCommand) run(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { - err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(namespace)) + if exportArgs.all { + err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(rootArgs.namespace)) if err != nil { return err } if export.list.len() == 0 { - logger.Failuref("no objects found in %s namespace", namespace) + logger.Failuref("no objects found in %s namespace", rootArgs.namespace) return nil } @@ -96,7 +98,7 @@ func (export exportCommand) run(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } err = kubeClient.Get(ctx, namespacedName, export.object.asClientObject()) diff --git a/cmd/flux/export_alert.go b/cmd/flux/export_alert.go index 8fa7ba42..b6c7cf80 100644 --- a/cmd/flux/export_alert.go +++ b/cmd/flux/export_alert.go @@ -48,27 +48,27 @@ func init() { } func exportAlertCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list notificationv1.AlertList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no alerts found in %s namespace", namespace) + logger.Failuref("no alerts found in %s namespace", rootArgs.namespace) return nil } @@ -80,7 +80,7 @@ func exportAlertCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var alert notificationv1.Alert diff --git a/cmd/flux/export_alertprovider.go b/cmd/flux/export_alertprovider.go index 2d805e40..f3404e03 100644 --- a/cmd/flux/export_alertprovider.go +++ b/cmd/flux/export_alertprovider.go @@ -48,27 +48,27 @@ func init() { } func exportAlertProviderCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list notificationv1.ProviderList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no alertproviders found in %s namespace", namespace) + logger.Failuref("no alertproviders found in %s namespace", rootArgs.namespace) return nil } @@ -80,7 +80,7 @@ func exportAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var alertProvider notificationv1.Provider diff --git a/cmd/flux/export_helmrelease.go b/cmd/flux/export_helmrelease.go index dff04b61..8266ddc8 100644 --- a/cmd/flux/export_helmrelease.go +++ b/cmd/flux/export_helmrelease.go @@ -49,27 +49,27 @@ func init() { } func exportHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list helmv2.HelmReleaseList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no helmrelease found in %s namespace", namespace) + logger.Failuref("no helmrelease found in %s namespace", rootArgs.namespace) return nil } @@ -81,7 +81,7 @@ func exportHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var helmRelease helmv2.HelmRelease diff --git a/cmd/flux/export_kustomization.go b/cmd/flux/export_kustomization.go index 86c33aca..e90002e6 100644 --- a/cmd/flux/export_kustomization.go +++ b/cmd/flux/export_kustomization.go @@ -49,27 +49,27 @@ func init() { } func exportKsCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("kustomization name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list kustomizev1.KustomizationList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no kustomizations found in %s namespace", namespace) + logger.Failuref("no kustomizations found in %s namespace", rootArgs.namespace) return nil } @@ -81,7 +81,7 @@ func exportKsCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var kustomization kustomizev1.Kustomization diff --git a/cmd/flux/export_receiver.go b/cmd/flux/export_receiver.go index ebecabef..700d8756 100644 --- a/cmd/flux/export_receiver.go +++ b/cmd/flux/export_receiver.go @@ -48,27 +48,27 @@ func init() { } func exportReceiverCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list notificationv1.ReceiverList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no receivers found in %s namespace", namespace) + logger.Failuref("no receivers found in %s namespace", rootArgs.namespace) return nil } @@ -80,7 +80,7 @@ func exportReceiverCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var receiver notificationv1.Receiver diff --git a/cmd/flux/export_source_bucket.go b/cmd/flux/export_source_bucket.go index 32e20322..7aaa7e14 100644 --- a/cmd/flux/export_source_bucket.go +++ b/cmd/flux/export_source_bucket.go @@ -49,27 +49,27 @@ func init() { } func exportSourceBucketCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list sourcev1.BucketList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no source found in %s namespace", namespace) + logger.Failuref("no source found in %s namespace", rootArgs.namespace) return nil } @@ -86,7 +86,7 @@ func exportSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var bucket sourcev1.Bucket diff --git a/cmd/flux/export_source_git.go b/cmd/flux/export_source_git.go index 6a422d78..12d033d2 100644 --- a/cmd/flux/export_source_git.go +++ b/cmd/flux/export_source_git.go @@ -49,27 +49,27 @@ func init() { } func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list sourcev1.GitRepositoryList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no source found in %s namespace", namespace) + logger.Failuref("no source found in %s namespace", rootArgs.namespace) return nil } @@ -86,7 +86,7 @@ func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.GitRepository diff --git a/cmd/flux/export_source_helm.go b/cmd/flux/export_source_helm.go index 756bf7fa..d3de5305 100644 --- a/cmd/flux/export_source_helm.go +++ b/cmd/flux/export_source_helm.go @@ -49,27 +49,27 @@ func init() { } func exportSourceHelmCmdRun(cmd *cobra.Command, args []string) error { - if !exportAll && len(args) < 1 { + if !exportArgs.all && len(args) < 1 { return fmt.Errorf("name is required") } - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if exportAll { + if exportArgs.all { var list sourcev1.HelmRepositoryList - err = kubeClient.List(ctx, &list, client.InNamespace(namespace)) + err = kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)) if err != nil { return err } if len(list.Items) == 0 { - logger.Failuref("no source found in %s namespace", namespace) + logger.Failuref("no source found in %s namespace", rootArgs.namespace) return nil } @@ -86,7 +86,7 @@ func exportSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.HelmRepository diff --git a/cmd/flux/get.go b/cmd/flux/get.go index 580d807b..5a60b2b8 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -36,10 +36,14 @@ var getCmd = &cobra.Command{ Long: "The get sub-commands print the statuses of sources and resources.", } -var allNamespaces bool +type GetFlags struct { + allNamespaces bool +} + +var getArgs GetFlags func init() { - getCmd.PersistentFlags().BoolVarP(&allNamespaces, "all-namespaces", "A", false, + getCmd.PersistentFlags().BoolVarP(&getArgs.allNamespaces, "all-namespaces", "A", false, "list the requested object(s) across all namespaces") rootCmd.AddCommand(getCmd) } @@ -74,17 +78,17 @@ type getCommand struct { } func (get getCommand) run(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } err = kubeClient.List(ctx, get.list.asClientList(), listOpts...) if err != nil { @@ -92,14 +96,14 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { } if get.list.len() == 0 { - logger.Failuref("no %s objects found in %s namespace", get.kind, namespace) + logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace) return nil } - header := get.list.headers(allNamespaces) + header := get.list.headers(getArgs.allNamespaces) var rows [][]string for i := 0; i < get.list.len(); i++ { - row := get.list.summariseItem(i, allNamespaces) + row := get.list.summariseItem(i, getArgs.allNamespaces) rows = append(rows, row) } utils.PrintTable(os.Stdout, header, rows) diff --git a/cmd/flux/get_alert.go b/cmd/flux/get_alert.go index 63c6c8ff..2219cdd8 100644 --- a/cmd/flux/get_alert.go +++ b/cmd/flux/get_alert.go @@ -47,17 +47,17 @@ func init() { } func getAlertCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list notificationv1.AlertList err = kubeClient.List(ctx, &list, listOpts...) @@ -66,12 +66,12 @@ func getAlertCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no alerts found in %s namespace", namespace) + logger.Failuref("no alerts found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -92,7 +92,7 @@ func getAlertCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(alert.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{alert.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_alertprovider.go b/cmd/flux/get_alertprovider.go index a60203c0..72f76df1 100644 --- a/cmd/flux/get_alertprovider.go +++ b/cmd/flux/get_alertprovider.go @@ -45,17 +45,17 @@ func init() { } func getAlertProviderCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list notificationv1.ProviderList err = kubeClient.List(ctx, &list, listOpts...) @@ -64,12 +64,12 @@ func getAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no providers found in %s namespace", namespace) + logger.Failuref("no providers found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -88,7 +88,7 @@ func getAlertProviderCmdRun(cmd *cobra.Command, args []string) error { "waiting to be reconciled", } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{provider.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_helmrelease.go b/cmd/flux/get_helmrelease.go index ecf84db3..6577105f 100644 --- a/cmd/flux/get_helmrelease.go +++ b/cmd/flux/get_helmrelease.go @@ -49,17 +49,17 @@ func init() { } func getHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list helmv2.HelmReleaseList err = kubeClient.List(ctx, &list, listOpts...) @@ -68,12 +68,12 @@ func getHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no releases found in %s namespace", namespace) + logger.Failuref("no releases found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -96,7 +96,7 @@ func getHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(helmRelease.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{helmRelease.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_kustomization.go b/cmd/flux/get_kustomization.go index 4e4de5de..d0c6553d 100644 --- a/cmd/flux/get_kustomization.go +++ b/cmd/flux/get_kustomization.go @@ -48,17 +48,17 @@ func init() { } func getKsCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list kustomizev1.KustomizationList err = kubeClient.List(ctx, &list, listOpts...) @@ -67,12 +67,12 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no kustomizations found in %s namespace", namespace) + logger.Failuref("no kustomizations found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -95,7 +95,7 @@ func getKsCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(kustomization.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{kustomization.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_receiver.go b/cmd/flux/get_receiver.go index b760b7d6..41232d53 100644 --- a/cmd/flux/get_receiver.go +++ b/cmd/flux/get_receiver.go @@ -47,17 +47,17 @@ func init() { } func getReceiverCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list notificationv1.ReceiverList err = kubeClient.List(ctx, &list, listOpts...) @@ -66,12 +66,12 @@ func getReceiverCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no receivers found in %s namespace", namespace) + logger.Failuref("no receivers found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string diff --git a/cmd/flux/get_source_bucket.go b/cmd/flux/get_source_bucket.go index 0d9b698e..8c39c221 100644 --- a/cmd/flux/get_source_bucket.go +++ b/cmd/flux/get_source_bucket.go @@ -50,17 +50,17 @@ func init() { } func getSourceBucketCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list sourcev1.BucketList err = kubeClient.List(ctx, &list, listOpts...) @@ -69,12 +69,12 @@ func getSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no bucket sources found in %s namespace", namespace) + logger.Failuref("no bucket sources found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -101,7 +101,7 @@ func getSourceBucketCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(source.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{source.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_source_chart.go b/cmd/flux/get_source_chart.go index db012061..8f56fdc8 100644 --- a/cmd/flux/get_source_chart.go +++ b/cmd/flux/get_source_chart.go @@ -50,17 +50,17 @@ func init() { } func getSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list sourcev1.HelmChartList err = kubeClient.List(ctx, &list, listOpts...) @@ -69,12 +69,12 @@ func getSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no chart sources found in %s namespace", namespace) + logger.Failuref("no chart sources found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -101,7 +101,7 @@ func getSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(source.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{source.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_source_git.go b/cmd/flux/get_source_git.go index 8f8fb811..9d629671 100644 --- a/cmd/flux/get_source_git.go +++ b/cmd/flux/get_source_git.go @@ -50,17 +50,17 @@ func init() { } func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list sourcev1.GitRepositoryList err = kubeClient.List(ctx, &list, listOpts...) @@ -69,12 +69,12 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no git sources found in %s namespace", namespace) + logger.Failuref("no git sources found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -101,7 +101,7 @@ func getSourceGitCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(source.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{source.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/get_source_helm.go b/cmd/flux/get_source_helm.go index 5f36cf5a..9deaa271 100644 --- a/cmd/flux/get_source_helm.go +++ b/cmd/flux/get_source_helm.go @@ -50,17 +50,17 @@ func init() { } func getSourceHelmCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } var listOpts []client.ListOption - if !allNamespaces { - listOpts = append(listOpts, client.InNamespace(namespace)) + if !getArgs.allNamespaces { + listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) } var list sourcev1.HelmRepositoryList err = kubeClient.List(ctx, &list, listOpts...) @@ -69,12 +69,12 @@ func getSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } if len(list.Items) == 0 { - logger.Failuref("no helm sources found in %s namespace", namespace) + logger.Failuref("no helm sources found in %s namespace", rootArgs.namespace) return nil } header := []string{"Name", "Ready", "Message", "Revision", "Suspended"} - if allNamespaces { + if getArgs.allNamespaces { header = append([]string{"Namespace"}, header...) } var rows [][]string @@ -101,7 +101,7 @@ func getSourceHelmCmdRun(cmd *cobra.Command, args []string) error { strings.Title(strconv.FormatBool(source.Spec.Suspend)), } } - if allNamespaces { + if getArgs.allNamespaces { row = append([]string{source.Namespace}, row...) } rows = append(rows, row) diff --git a/cmd/flux/install.go b/cmd/flux/install.go index 89ec0795..819aab9d 100644 --- a/cmd/flux/install.go +++ b/cmd/flux/install.go @@ -63,7 +63,7 @@ var ( installWatchAllNamespaces bool installNetworkPolicy bool installArch flags.Arch - installLogLevel = flags.LogLevel(defaults.LogLevel) + installLogLevel = flags.LogLevel(rootArgs.defaults.LogLevel) installClusterDomain string ) @@ -72,34 +72,34 @@ func init() { "write the install manifests to stdout and exit") installCmd.Flags().BoolVarP(&installDryRun, "dry-run", "", false, "only print the object that would be applied") - installCmd.Flags().StringVarP(&installVersion, "version", "v", defaults.Version, + installCmd.Flags().StringVarP(&installVersion, "version", "v", rootArgs.defaults.Version, "toolkit version") - installCmd.Flags().StringSliceVar(&installDefaultComponents, "components", defaults.Components, + installCmd.Flags().StringSliceVar(&installDefaultComponents, "components", rootArgs.defaults.Components, "list of components, accepts comma-separated values") installCmd.Flags().StringSliceVar(&installExtraComponents, "components-extra", nil, "list of components in addition to those supplied or defaulted, accepts comma-separated values") installCmd.Flags().StringVar(&installManifestsPath, "manifests", "", "path to the manifest directory") - installCmd.Flags().StringVar(&installRegistry, "registry", defaults.Registry, + installCmd.Flags().StringVar(&installRegistry, "registry", rootArgs.defaults.Registry, "container registry where the toolkit images are published") installCmd.Flags().StringVar(&installImagePullSecret, "image-pull-secret", "", "Kubernetes secret name used for pulling the toolkit images from a private registry") installCmd.Flags().Var(&installArch, "arch", installArch.Description()) - installCmd.Flags().BoolVar(&installWatchAllNamespaces, "watch-all-namespaces", defaults.WatchAllNamespaces, + installCmd.Flags().BoolVar(&installWatchAllNamespaces, "watch-all-namespaces", rootArgs.defaults.WatchAllNamespaces, "watch for custom resources in all namespaces, if set to false it will only watch the namespace where the toolkit is installed") installCmd.Flags().Var(&installLogLevel, "log-level", installLogLevel.Description()) - installCmd.Flags().BoolVar(&installNetworkPolicy, "network-policy", defaults.NetworkPolicy, + installCmd.Flags().BoolVar(&installNetworkPolicy, "network-policy", rootArgs.defaults.NetworkPolicy, "deny ingress access to the toolkit controllers from other namespaces using network policies") - installCmd.Flags().StringVar(&installClusterDomain, "cluster-domain", defaults.ClusterDomain, "internal cluster domain") + installCmd.Flags().StringVar(&installClusterDomain, "cluster-domain", rootArgs.defaults.ClusterDomain, "internal cluster domain") installCmd.Flags().MarkHidden("manifests") installCmd.Flags().MarkDeprecated("arch", "multi-arch container image is now available for AMD64, ARMv7 and ARM64") rootCmd.AddCommand(installCmd) } func installCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - tmpDir, err := ioutil.TempDir("", namespace) + tmpDir, err := ioutil.TempDir("", rootArgs.namespace) if err != nil { return err } @@ -118,16 +118,16 @@ func installCmdRun(cmd *cobra.Command, args []string) error { opts := install.Options{ BaseURL: installManifestsPath, Version: installVersion, - Namespace: namespace, + Namespace: rootArgs.namespace, Components: components, Registry: installRegistry, ImagePullSecret: installImagePullSecret, WatchAllNamespaces: installWatchAllNamespaces, NetworkPolicy: installNetworkPolicy, LogLevel: installLogLevel.String(), - NotificationController: defaults.NotificationController, - ManifestFile: fmt.Sprintf("%s.yaml", namespace), - Timeout: timeout, + NotificationController: rootArgs.defaults.NotificationController, + ManifestFile: fmt.Sprintf("%s.yaml", rootArgs.namespace), + Timeout: rootArgs.timeout, ClusterDomain: installClusterDomain, } @@ -144,7 +144,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("install failed: %w", err) } - if verbose { + if rootArgs.verbose { fmt.Print(manifest.Content) } else if installExport { fmt.Println("---") @@ -156,9 +156,9 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } logger.Successf("manifests build completed") - logger.Actionf("installing components in %s namespace", namespace) + logger.Actionf("installing components in %s namespace", rootArgs.namespace) applyOutput := utils.ModeStderrOS - if verbose { + if rootArgs.verbose { applyOutput = utils.ModeOS } @@ -167,7 +167,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { kubectlArgs = append(kubectlArgs, "--dry-run=client") applyOutput = utils.ModeOS } - if _, err := utils.ExecKubectlCommand(ctx, applyOutput, kubeconfig, kubecontext, kubectlArgs...); err != nil { + if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return fmt.Errorf("install failed") } @@ -180,8 +180,8 @@ func installCmdRun(cmd *cobra.Command, args []string) error { logger.Waitingf("verifying installation") for _, deployment := range components { - kubectlArgs = []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()} - if _, err := utils.ExecKubectlCommand(ctx, applyOutput, kubeconfig, kubecontext, kubectlArgs...); err != nil { + kubectlArgs = []string{"-n", rootArgs.namespace, "rollout", "status", "deployment", deployment, "--timeout", rootArgs.timeout.String()} + if _, err := utils.ExecKubectlCommand(ctx, applyOutput, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return fmt.Errorf("install failed") } else { logger.Successf("%s ready", deployment) diff --git a/cmd/flux/main.go b/cmd/flux/main.go index 234f48e0..215a3525 100644 --- a/cmd/flux/main.go +++ b/cmd/flux/main.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/cobra/doc" _ "k8s.io/client-go/plugin/pkg/client/auth" - fluxlog "github.com/fluxcd/flux2/pkg/log" "github.com/fluxcd/flux2/pkg/manifestgen/install" ) @@ -94,22 +93,32 @@ var rootCmd = &cobra.Command{ `, } -var ( +var logger = stderrLogger{stderr: os.Stderr} + +type rootFlags struct { kubeconfig string kubecontext string namespace string timeout time.Duration verbose bool - pollInterval = 2 * time.Second - logger fluxlog.Logger = stderrLogger{stderr: os.Stderr} - defaults = install.MakeDefaultOptions() -) + pollInterval time.Duration + defaults install.Options +} + +var rootArgs = NewRootFlags() func init() { - rootCmd.PersistentFlags().StringVarP(&namespace, "namespace", "n", defaults.Namespace, "the namespace scope for this operation") - rootCmd.PersistentFlags().DurationVar(&timeout, "timeout", 5*time.Minute, "timeout for this operation") - rootCmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "print generated objects") - rootCmd.PersistentFlags().StringVarP(&kubecontext, "context", "", "", "kubernetes context to use") + rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace, "the namespace scope for this operation") + rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation") + rootCmd.PersistentFlags().BoolVar(&rootArgs.verbose, "verbose", false, "print generated objects") + rootCmd.PersistentFlags().StringVarP(&rootArgs.kubecontext, "context", "", "", "kubernetes context to use") +} + +func NewRootFlags() rootFlags { + return rootFlags{ + pollInterval: 2 * time.Second, + defaults: install.MakeDefaultOptions(), + } } func main() { @@ -124,22 +133,22 @@ func main() { func kubeconfigFlag() { if home := homeDir(); home != "" { - rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "", filepath.Join(home, ".kube", "config"), + rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", filepath.Join(home, ".kube", "config"), "path to the kubeconfig file") } else { - rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "", "", + rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "", "absolute path to the kubeconfig file") } if len(os.Getenv("KUBECONFIG")) > 0 { - kubeconfig = os.Getenv("KUBECONFIG") + rootArgs.kubeconfig = os.Getenv("KUBECONFIG") } } func generateDocs() { args := os.Args[1:] if len(args) > 0 && args[0] == "docgen" { - rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "", "~/.kube/config", + rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "~/.kube/config", "path to the kubeconfig file") rootCmd.DisableAutoGenTag = true err := doc.GenMarkdownTree(rootCmd, "./docs/cmd") diff --git a/cmd/flux/reconcile.go b/cmd/flux/reconcile.go index 25a5e0cf..8b7be0ad 100644 --- a/cmd/flux/reconcile.go +++ b/cmd/flux/reconcile.go @@ -69,16 +69,16 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -91,7 +91,7 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, namespace) + logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, rootArgs.namespace) if err := requestReconciliation(ctx, kubeClient, namespacedName, reconcile.object); err != nil { return err } @@ -99,7 +99,7 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error { lastHandledReconcileAt := reconcile.object.lastHandledReconcileRequest() logger.Waitingf("waiting for %s reconciliation", reconcile.kind) - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, reconciliationHandled(ctx, kubeClient, namespacedName, reconcile.object, lastHandledReconcileAt)); err != nil { return err } diff --git a/cmd/flux/reconcile_alert.go b/cmd/flux/reconcile_alert.go index f37ed870..d210685a 100644 --- a/cmd/flux/reconcile_alert.go +++ b/cmd/flux/reconcile_alert.go @@ -51,16 +51,16 @@ func reconcileAlertCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -74,7 +74,7 @@ func reconcileAlertCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - logger.Actionf("annotating Alert %s in %s namespace", name, namespace) + logger.Actionf("annotating Alert %s in %s namespace", name, rootArgs.namespace) if alert.Annotations == nil { alert.Annotations = map[string]string{ meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano), @@ -89,7 +89,7 @@ func reconcileAlertCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Alert annotated") logger.Waitingf("waiting for reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isAlertReady(ctx, kubeClient, namespacedName, &alert)); err != nil { return err } diff --git a/cmd/flux/reconcile_alertprovider.go b/cmd/flux/reconcile_alertprovider.go index 67f12cd0..70644db4 100644 --- a/cmd/flux/reconcile_alertprovider.go +++ b/cmd/flux/reconcile_alertprovider.go @@ -51,20 +51,20 @@ func reconcileAlertProviderCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } - logger.Actionf("annotating Provider %s in %s namespace", name, namespace) + logger.Actionf("annotating Provider %s in %s namespace", name, rootArgs.namespace) var alertProvider notificationv1.Provider err = kubeClient.Get(ctx, namespacedName, &alertProvider) if err != nil { @@ -84,7 +84,7 @@ func reconcileAlertProviderCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Provider annotated") logger.Waitingf("waiting for reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isAlertProviderReady(ctx, kubeClient, namespacedName, &alertProvider)); err != nil { return err } diff --git a/cmd/flux/reconcile_helmrelease.go b/cmd/flux/reconcile_helmrelease.go index edbb3671..1e08d829 100644 --- a/cmd/flux/reconcile_helmrelease.go +++ b/cmd/flux/reconcile_helmrelease.go @@ -51,12 +51,14 @@ The reconcile kustomization command triggers a reconciliation of a HelmRelease r RunE: reconcileHrCmdRun, } -var ( +type reconcileHelmReleaseFlags struct { syncHrWithSource bool -) +} + +var rhrArgs reconcileHelmReleaseFlags func init() { - reconcileHrCmd.Flags().BoolVar(&syncHrWithSource, "with-source", false, "reconcile HelmRelease source") + reconcileHrCmd.Flags().BoolVar(&rhrArgs.syncHrWithSource, "with-source", false, "reconcile HelmRelease source") reconcileCmd.AddCommand(reconcileHrCmd) } @@ -67,16 +69,16 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -90,7 +92,7 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - if syncHrWithSource { + if rhrArgs.syncHrWithSource { switch helmRelease.Spec.Chart.Spec.SourceRef.Kind { case sourcev1.HelmRepositoryKind: err = reconcileSourceHelmCmdRun(nil, []string{helmRelease.Spec.Chart.Spec.SourceRef.Name}) @@ -105,14 +107,14 @@ func reconcileHrCmdRun(cmd *cobra.Command, args []string) error { } lastHandledReconcileAt := helmRelease.Status.LastHandledReconcileAt - logger.Actionf("annotating HelmRelease %s in %s namespace", name, namespace) + logger.Actionf("annotating HelmRelease %s in %s namespace", name, rootArgs.namespace) if err := requestHelmReleaseReconciliation(ctx, kubeClient, namespacedName, &helmRelease); err != nil { return err } logger.Successf("HelmRelease annotated") logger.Waitingf("waiting for HelmRelease reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, helmReleaseReconciliationHandled(ctx, kubeClient, namespacedName, &helmRelease, lastHandledReconcileAt), ); err != nil { return err diff --git a/cmd/flux/reconcile_kustomization.go b/cmd/flux/reconcile_kustomization.go index b543ed4d..9f788b92 100644 --- a/cmd/flux/reconcile_kustomization.go +++ b/cmd/flux/reconcile_kustomization.go @@ -50,12 +50,14 @@ The reconcile kustomization command triggers a reconciliation of a Kustomization RunE: reconcileKsCmdRun, } -var ( +type reconcileKsFlags struct { syncKsWithSource bool -) +} + +var rksArgs reconcileKsFlags func init() { - reconcileKsCmd.Flags().BoolVar(&syncKsWithSource, "with-source", false, "reconcile Kustomization source") + reconcileKsCmd.Flags().BoolVar(&rksArgs.syncKsWithSource, "with-source", false, "reconcile Kustomization source") reconcileCmd.AddCommand(reconcileKsCmd) } @@ -66,16 +68,16 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var kustomization kustomizev1.Kustomization @@ -88,7 +90,7 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - if syncKsWithSource { + if rksArgs.syncKsWithSource { switch kustomization.Spec.SourceRef.Kind { case sourcev1.GitRepositoryKind: err = reconcileSourceGitCmdRun(nil, []string{kustomization.Spec.SourceRef.Name}) @@ -101,7 +103,7 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error { } lastHandledReconcileAt := kustomization.Status.LastHandledReconcileAt - logger.Actionf("annotating Kustomization %s in %s namespace", name, namespace) + logger.Actionf("annotating Kustomization %s in %s namespace", name, rootArgs.namespace) if err := requestKustomizeReconciliation(ctx, kubeClient, namespacedName, &kustomization); err != nil { return err } @@ -109,7 +111,7 @@ func reconcileKsCmdRun(cmd *cobra.Command, args []string) error { logger.Waitingf("waiting for Kustomization reconciliation") if err := wait.PollImmediate( - pollInterval, timeout, + rootArgs.pollInterval, rootArgs.timeout, kustomizeReconciliationHandled(ctx, kubeClient, namespacedName, &kustomization, lastHandledReconcileAt), ); err != nil { return err diff --git a/cmd/flux/reconcile_receiver.go b/cmd/flux/reconcile_receiver.go index b26b55f2..25cdeb99 100644 --- a/cmd/flux/reconcile_receiver.go +++ b/cmd/flux/reconcile_receiver.go @@ -51,16 +51,16 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -74,7 +74,7 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - logger.Actionf("annotating Receiver %s in %s namespace", name, namespace) + logger.Actionf("annotating Receiver %s in %s namespace", name, rootArgs.namespace) if receiver.Annotations == nil { receiver.Annotations = map[string]string{ meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano), @@ -88,7 +88,7 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Receiver annotated") logger.Waitingf("waiting for Receiver reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isReceiverReady(ctx, kubeClient, namespacedName, &receiver)); err != nil { return err } diff --git a/cmd/flux/reconcile_source_bucket.go b/cmd/flux/reconcile_source_bucket.go index 22928927..3fe8e017 100644 --- a/cmd/flux/reconcile_source_bucket.go +++ b/cmd/flux/reconcile_source_bucket.go @@ -56,16 +56,16 @@ func reconcileSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var bucket sourcev1.Bucket @@ -79,7 +79,7 @@ func reconcileSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } lastHandledReconcileAt := bucket.Status.LastHandledReconcileAt - logger.Actionf("annotating Bucket source %s in %s namespace", name, namespace) + logger.Actionf("annotating Bucket source %s in %s namespace", name, rootArgs.namespace) if err := requestBucketReconciliation(ctx, kubeClient, namespacedName, &bucket); err != nil { return err } @@ -87,7 +87,7 @@ func reconcileSourceBucketCmdRun(cmd *cobra.Command, args []string) error { logger.Waitingf("waiting for Bucket source reconciliation") if err := wait.PollImmediate( - pollInterval, timeout, + rootArgs.pollInterval, rootArgs.timeout, bucketReconciliationHandled(ctx, kubeClient, namespacedName, &bucket, lastHandledReconcileAt), ); err != nil { return err diff --git a/cmd/flux/reconcile_source_git.go b/cmd/flux/reconcile_source_git.go index b5e54e75..d3185970 100644 --- a/cmd/flux/reconcile_source_git.go +++ b/cmd/flux/reconcile_source_git.go @@ -54,16 +54,16 @@ func reconcileSourceGitCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.GitRepository @@ -76,7 +76,7 @@ func reconcileSourceGitCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - logger.Actionf("annotating GitRepository source %s in %s namespace", name, namespace) + logger.Actionf("annotating GitRepository source %s in %s namespace", name, rootArgs.namespace) if err := requestGitRepositoryReconciliation(ctx, kubeClient, namespacedName, &repository); err != nil { return err } @@ -84,7 +84,7 @@ func reconcileSourceGitCmdRun(cmd *cobra.Command, args []string) error { lastHandledReconcileAt := repository.Status.LastHandledReconcileAt logger.Waitingf("waiting for GitRepository source reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, gitRepositoryReconciliationHandled(ctx, kubeClient, namespacedName, &repository, lastHandledReconcileAt)); err != nil { return err } diff --git a/cmd/flux/reconcile_source_helm.go b/cmd/flux/reconcile_source_helm.go index 4e52d172..97c9a168 100644 --- a/cmd/flux/reconcile_source_helm.go +++ b/cmd/flux/reconcile_source_helm.go @@ -55,16 +55,16 @@ func reconcileSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.HelmRepository @@ -77,7 +77,7 @@ func reconcileSourceHelmCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("resource is suspended") } - logger.Actionf("annotating HelmRepository source %s in %s namespace", name, namespace) + logger.Actionf("annotating HelmRepository source %s in %s namespace", name, rootArgs.namespace) if err := requestHelmRepositoryReconciliation(ctx, kubeClient, namespacedName, &repository); err != nil { return err } @@ -85,7 +85,7 @@ func reconcileSourceHelmCmdRun(cmd *cobra.Command, args []string) error { lastHandledReconcileAt := repository.Status.LastHandledReconcileAt logger.Waitingf("waiting for HelmRepository source reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, helmRepositoryReconciliationHandled(ctx, kubeClient, namespacedName, &repository, lastHandledReconcileAt)); err != nil { return err } diff --git a/cmd/flux/resume.go b/cmd/flux/resume.go index 35522456..f7bc74af 100644 --- a/cmd/flux/resume.go +++ b/cmd/flux/resume.go @@ -55,16 +55,16 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } @@ -73,7 +73,7 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, name, namespace) + logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, name, rootArgs.namespace) resume.object.setUnsuspended() if err := kubeClient.Update(ctx, resume.object.asClientObject()); err != nil { return err @@ -81,7 +81,7 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { logger.Successf("%s resumed", resume.humanKind) logger.Waitingf("waiting for %s reconciliation", resume.kind) - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isReady(ctx, kubeClient, namespacedName, resume.object)); err != nil { return err } diff --git a/cmd/flux/resume_alert.go b/cmd/flux/resume_alert.go index 3b43d2aa..329c32dd 100644 --- a/cmd/flux/resume_alert.go +++ b/cmd/flux/resume_alert.go @@ -54,16 +54,16 @@ func resumeAlertCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var alert notificationv1.Alert @@ -72,7 +72,7 @@ func resumeAlertCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming Alert %s in %s namespace", name, namespace) + logger.Actionf("resuming Alert %s in %s namespace", name, rootArgs.namespace) alert.Spec.Suspend = false if err := kubeClient.Update(ctx, &alert); err != nil { return err @@ -80,7 +80,7 @@ func resumeAlertCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Alert resumed") logger.Waitingf("waiting for Alert reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isAlertResumed(ctx, kubeClient, namespacedName, &alert)); err != nil { return err } diff --git a/cmd/flux/resume_helmrelease.go b/cmd/flux/resume_helmrelease.go index 4e5eebb0..c9538af3 100644 --- a/cmd/flux/resume_helmrelease.go +++ b/cmd/flux/resume_helmrelease.go @@ -55,16 +55,16 @@ func resumeHrCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var helmRelease helmv2.HelmRelease @@ -73,7 +73,7 @@ func resumeHrCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming HelmRelease %s in %s namespace", name, namespace) + logger.Actionf("resuming HelmRelease %s in %s namespace", name, rootArgs.namespace) helmRelease.Spec.Suspend = false if err := kubeClient.Update(ctx, &helmRelease); err != nil { return err @@ -81,7 +81,7 @@ func resumeHrCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("HelmRelease resumed") logger.Waitingf("waiting for HelmRelease reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isHelmReleaseResumed(ctx, kubeClient, namespacedName, &helmRelease)); err != nil { return err } diff --git a/cmd/flux/resume_kustomization.go b/cmd/flux/resume_kustomization.go index 58d41cdc..286a8be6 100644 --- a/cmd/flux/resume_kustomization.go +++ b/cmd/flux/resume_kustomization.go @@ -54,16 +54,16 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var kustomization kustomizev1.Kustomization @@ -72,7 +72,7 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming Kustomization %s in %s namespace", name, namespace) + logger.Actionf("resuming Kustomization %s in %s namespace", name, rootArgs.namespace) kustomization.Spec.Suspend = false if err := kubeClient.Update(ctx, &kustomization); err != nil { return err @@ -80,7 +80,7 @@ func resumeKsCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Kustomization resumed") logger.Waitingf("waiting for Kustomization reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isKustomizationResumed(ctx, kubeClient, namespacedName, &kustomization)); err != nil { return err } diff --git a/cmd/flux/resume_receiver.go b/cmd/flux/resume_receiver.go index a94982a5..8302edf6 100644 --- a/cmd/flux/resume_receiver.go +++ b/cmd/flux/resume_receiver.go @@ -54,16 +54,16 @@ func resumeReceiverCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var receiver notificationv1.Receiver @@ -72,7 +72,7 @@ func resumeReceiverCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming Receiver %s in %s namespace", name, namespace) + logger.Actionf("resuming Receiver %s in %s namespace", name, rootArgs.namespace) receiver.Spec.Suspend = false if err := kubeClient.Update(ctx, &receiver); err != nil { return err @@ -80,7 +80,7 @@ func resumeReceiverCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("Receiver resumed") logger.Waitingf("waiting for Receiver reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isReceiverResumed(ctx, kubeClient, namespacedName, &receiver)); err != nil { return err } diff --git a/cmd/flux/resume_source_bucket.go b/cmd/flux/resume_source_bucket.go index 895d1c69..deba5916 100644 --- a/cmd/flux/resume_source_bucket.go +++ b/cmd/flux/resume_source_bucket.go @@ -53,16 +53,16 @@ func resumeSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var bucket sourcev1.Bucket @@ -71,7 +71,7 @@ func resumeSourceBucketCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming source %s in %s namespace", name, namespace) + logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace) bucket.Spec.Suspend = false if err := kubeClient.Update(ctx, &bucket); err != nil { return err @@ -79,7 +79,7 @@ func resumeSourceBucketCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("source resumed") logger.Waitingf("waiting for Bucket reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isBucketResumed(ctx, kubeClient, namespacedName, &bucket)); err != nil { return err } diff --git a/cmd/flux/resume_source_chart.go b/cmd/flux/resume_source_chart.go index 8f3d1bfe..bcfa465f 100644 --- a/cmd/flux/resume_source_chart.go +++ b/cmd/flux/resume_source_chart.go @@ -53,16 +53,16 @@ func resumeSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.HelmChart @@ -71,7 +71,7 @@ func resumeSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming source %s in %s namespace", name, namespace) + logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace) repository.Spec.Suspend = false if err := kubeClient.Update(ctx, &repository); err != nil { return err @@ -79,7 +79,7 @@ func resumeSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("source resumed") logger.Waitingf("waiting for HelmChart reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isHelmChartResumed(ctx, kubeClient, namespacedName, &repository)); err != nil { return err } diff --git a/cmd/flux/resume_source_git.go b/cmd/flux/resume_source_git.go index 53b386c5..56c7c47f 100644 --- a/cmd/flux/resume_source_git.go +++ b/cmd/flux/resume_source_git.go @@ -53,16 +53,16 @@ func resumeSourceGitCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.GitRepository @@ -71,7 +71,7 @@ func resumeSourceGitCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming source %s in %s namespace", name, namespace) + logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace) repository.Spec.Suspend = false if err := kubeClient.Update(ctx, &repository); err != nil { return err @@ -79,7 +79,7 @@ func resumeSourceGitCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("source resumed") logger.Waitingf("waiting for GitRepository reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isGitRepositoryResumed(ctx, kubeClient, namespacedName, &repository)); err != nil { return err } diff --git a/cmd/flux/resume_source_helm.go b/cmd/flux/resume_source_helm.go index 59d01b5d..97a7a7b1 100644 --- a/cmd/flux/resume_source_helm.go +++ b/cmd/flux/resume_source_helm.go @@ -53,16 +53,16 @@ func resumeSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.HelmRepository @@ -71,7 +71,7 @@ func resumeSourceHelmCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("resuming source %s in %s namespace", name, namespace) + logger.Actionf("resuming source %s in %s namespace", name, rootArgs.namespace) repository.Spec.Suspend = false if err := kubeClient.Update(ctx, &repository); err != nil { return err @@ -79,7 +79,7 @@ func resumeSourceHelmCmdRun(cmd *cobra.Command, args []string) error { logger.Successf("source resumed") logger.Waitingf("waiting for HelmRepository reconciliation") - if err := wait.PollImmediate(pollInterval, timeout, + if err := wait.PollImmediate(rootArgs.pollInterval, rootArgs.timeout, isHelmRepositoryResumed(ctx, kubeClient, namespacedName, &repository)); err != nil { return err } diff --git a/cmd/flux/suspend.go b/cmd/flux/suspend.go index 89a661bf..6f2eac88 100644 --- a/cmd/flux/suspend.go +++ b/cmd/flux/suspend.go @@ -53,16 +53,16 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } err = kubeClient.Get(ctx, namespacedName, suspend.object.asClientObject()) @@ -70,7 +70,7 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, name, namespace) + logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, name, rootArgs.namespace) suspend.object.setSuspended() if err := kubeClient.Update(ctx, suspend.object.asClientObject()); err != nil { return err diff --git a/cmd/flux/suspend_alert.go b/cmd/flux/suspend_alert.go index 6d2b11d9..3c215658 100644 --- a/cmd/flux/suspend_alert.go +++ b/cmd/flux/suspend_alert.go @@ -47,16 +47,16 @@ func suspendAlertCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var alert notificationv1.Alert @@ -65,7 +65,7 @@ func suspendAlertCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending Alert %s in %s namespace", name, namespace) + logger.Actionf("suspending Alert %s in %s namespace", name, rootArgs.namespace) alert.Spec.Suspend = true if err := kubeClient.Update(ctx, &alert); err != nil { return err diff --git a/cmd/flux/suspend_helmrelease.go b/cmd/flux/suspend_helmrelease.go index eef5c05b..6536f15f 100644 --- a/cmd/flux/suspend_helmrelease.go +++ b/cmd/flux/suspend_helmrelease.go @@ -48,16 +48,16 @@ func suspendHrCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var helmRelease helmv2.HelmRelease @@ -66,7 +66,7 @@ func suspendHrCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending HelmRelease %s in %s namespace", name, namespace) + logger.Actionf("suspending HelmRelease %s in %s namespace", name, rootArgs.namespace) helmRelease.Spec.Suspend = true if err := kubeClient.Update(ctx, &helmRelease); err != nil { return err diff --git a/cmd/flux/suspend_kustomization.go b/cmd/flux/suspend_kustomization.go index 39dc9167..dd2a808e 100644 --- a/cmd/flux/suspend_kustomization.go +++ b/cmd/flux/suspend_kustomization.go @@ -47,16 +47,16 @@ func suspendKsCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var kustomization kustomizev1.Kustomization @@ -65,7 +65,7 @@ func suspendKsCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending kustomization %s in %s namespace", name, namespace) + logger.Actionf("suspending kustomization %s in %s namespace", name, rootArgs.namespace) kustomization.Spec.Suspend = true if err := kubeClient.Update(ctx, &kustomization); err != nil { return err diff --git a/cmd/flux/suspend_receiver.go b/cmd/flux/suspend_receiver.go index e8877e77..1558b97d 100644 --- a/cmd/flux/suspend_receiver.go +++ b/cmd/flux/suspend_receiver.go @@ -47,16 +47,16 @@ func suspendReceiverCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var receiver notificationv1.Receiver @@ -65,7 +65,7 @@ func suspendReceiverCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending Receiver %s in %s namespace", name, namespace) + logger.Actionf("suspending Receiver %s in %s namespace", name, rootArgs.namespace) receiver.Spec.Suspend = true if err := kubeClient.Update(ctx, &receiver); err != nil { return err diff --git a/cmd/flux/suspend_source_bucket.go b/cmd/flux/suspend_source_bucket.go index e2f82673..dd0b9f36 100644 --- a/cmd/flux/suspend_source_bucket.go +++ b/cmd/flux/suspend_source_bucket.go @@ -46,16 +46,16 @@ func suspendSourceBucketCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var bucket sourcev1.Bucket @@ -64,7 +64,7 @@ func suspendSourceBucketCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending source %s in %s namespace", name, namespace) + logger.Actionf("suspending source %s in %s namespace", name, rootArgs.namespace) bucket.Spec.Suspend = true if err := kubeClient.Update(ctx, &bucket); err != nil { return err diff --git a/cmd/flux/suspend_source_chart.go b/cmd/flux/suspend_source_chart.go index 5498a745..28d2c0d9 100644 --- a/cmd/flux/suspend_source_chart.go +++ b/cmd/flux/suspend_source_chart.go @@ -46,16 +46,16 @@ func suspendSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var chart sourcev1.HelmChart @@ -64,7 +64,7 @@ func suspendSourceHelmChartCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending source %s in %s namespace", name, namespace) + logger.Actionf("suspending source %s in %s namespace", name, rootArgs.namespace) chart.Spec.Suspend = true if err := kubeClient.Update(ctx, &chart); err != nil { return err diff --git a/cmd/flux/suspend_source_git.go b/cmd/flux/suspend_source_git.go index e96f3fc5..4d20cc26 100644 --- a/cmd/flux/suspend_source_git.go +++ b/cmd/flux/suspend_source_git.go @@ -46,16 +46,16 @@ func suspendSourceGitCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.GitRepository @@ -64,7 +64,7 @@ func suspendSourceGitCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending source %s in %s namespace", name, namespace) + logger.Actionf("suspending source %s in %s namespace", name, rootArgs.namespace) repository.Spec.Suspend = true if err := kubeClient.Update(ctx, &repository); err != nil { return err diff --git a/cmd/flux/suspend_source_helm.go b/cmd/flux/suspend_source_helm.go index fd132962..2b4d00b5 100644 --- a/cmd/flux/suspend_source_helm.go +++ b/cmd/flux/suspend_source_helm.go @@ -46,16 +46,16 @@ func suspendSourceHelmCmdRun(cmd *cobra.Command, args []string) error { } name := args[0] - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: namespace, + Namespace: rootArgs.namespace, Name: name, } var repository sourcev1.HelmRepository @@ -64,7 +64,7 @@ func suspendSourceHelmCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("suspending source %s in %s namespace", name, namespace) + logger.Actionf("suspending source %s in %s namespace", name, rootArgs.namespace) repository.Spec.Suspend = true if err := kubeClient.Update(ctx, &repository); err != nil { return err diff --git a/cmd/flux/uninstall.go b/cmd/flux/uninstall.go index bbe6a90c..8d6027f6 100644 --- a/cmd/flux/uninstall.go +++ b/cmd/flux/uninstall.go @@ -45,38 +45,40 @@ var uninstallCmd = &cobra.Command{ RunE: uninstallCmdRun, } -var ( - uninstallCRDs bool - uninstallResources bool - uninstallDryRun bool - uninstallSilent bool -) +type uninstallFlags struct { + crds bool + resources bool + dryRun bool + silent bool +} + +var uninstallArgs uninstallFlags func init() { - uninstallCmd.Flags().BoolVar(&uninstallResources, "resources", true, + uninstallCmd.Flags().BoolVar(&uninstallArgs.resources, "resources", true, "removes custom resources such as Kustomizations, GitRepositories and HelmRepositories") - uninstallCmd.Flags().BoolVar(&uninstallCRDs, "crds", false, + uninstallCmd.Flags().BoolVar(&uninstallArgs.crds, "crds", false, "removes all CRDs previously installed") - uninstallCmd.Flags().BoolVar(&uninstallDryRun, "dry-run", false, + uninstallCmd.Flags().BoolVar(&uninstallArgs.dryRun, "dry-run", false, "only print the object that would be deleted") - uninstallCmd.Flags().BoolVarP(&uninstallSilent, "silent", "s", false, + uninstallCmd.Flags().BoolVarP(&uninstallArgs.silent, "silent", "s", false, "delete components without asking for confirmation") rootCmd.AddCommand(uninstallCmd) } func uninstallCmdRun(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(kubeconfig, kubecontext) + kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) if err != nil { return err } - if !uninstallDryRun && !uninstallSilent { + if !uninstallArgs.dryRun && !uninstallArgs.silent { prompt := promptui.Prompt{ - Label: fmt.Sprintf("Are you sure you want to delete the %s namespace", namespace), + Label: fmt.Sprintf("Are you sure you want to delete the %s namespace", rootArgs.namespace), IsConfirm: true, } if _, err := prompt.Run(); err != nil { @@ -85,7 +87,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { } dryRun := "--dry-run=server" - deleteResources := uninstallResources || uninstallCRDs + deleteResources := uninstallArgs.resources || uninstallArgs.crds // known kinds with finalizers namespacedKinds := []string{ @@ -96,8 +98,8 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { // suspend bootstrap kustomization to avoid finalizers deadlock kustomizationName := types.NamespacedName{ - Namespace: namespace, - Name: namespace, + Namespace: rootArgs.namespace, + Name: rootArgs.namespace, } var kustomization kustomizev1.Kustomization err = kubeClient.Get(ctx, kustomizationName, &kustomization) @@ -113,21 +115,21 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { // add HelmRelease kind to deletion list if exists var list helmv2.HelmReleaseList - if err := kubeClient.List(ctx, &list, client.InNamespace(namespace)); err == nil { + if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace)); err == nil { namespacedKinds = append(namespacedKinds, helmv2.HelmReleaseKind) } if deleteResources { logger.Actionf("uninstalling custom resources") for _, kind := range namespacedKinds { - if err := deleteAll(ctx, kind, uninstallDryRun); err != nil { + if err := deleteAll(ctx, kind, uninstallArgs.dryRun); err != nil { logger.Failuref("kubectl: %s", err.Error()) } } } var kinds []string - if uninstallCRDs { + if uninstallArgs.crds { kinds = append(kinds, "crds") } @@ -138,13 +140,13 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { for _, kind := range kinds { kubectlArgs := []string{ "delete", kind, - "-l", fmt.Sprintf("app.kubernetes.io/instance=%s", namespace), - "--ignore-not-found", "--timeout", timeout.String(), + "-l", fmt.Sprintf("app.kubernetes.io/instance=%s", rootArgs.namespace), + "--ignore-not-found", "--timeout", rootArgs.timeout.String(), } - if uninstallDryRun { + if uninstallArgs.dryRun { kubectlArgs = append(kubectlArgs, dryRun) } - if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, kubeconfig, kubecontext, kubectlArgs...); err != nil { + if _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...); err != nil { return fmt.Errorf("uninstall failed: %w", err) } } @@ -157,13 +159,13 @@ func deleteAll(ctx context.Context, kind string, dryRun bool) error { kubectlArgs := []string{ "delete", kind, "--ignore-not-found", "--all", "--all-namespaces", - "--timeout", timeout.String(), + "--timeout", rootArgs.timeout.String(), } if dryRun { kubectlArgs = append(kubectlArgs, "--dry-run=server") } - _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, kubeconfig, kubecontext, kubectlArgs...) + _, err := utils.ExecKubectlCommand(ctx, utils.ModeOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...) return err }