diff --git a/cmd/flux/bootstrap_bitbucket_server.go b/cmd/flux/bootstrap_bitbucket_server.go index 07fb04c7..56e1a906 100644 --- a/cmd/flux/bootstrap_bitbucket_server.go +++ b/cmd/flux/bootstrap_bitbucket_server.go @@ -121,7 +121,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -179,7 +179,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { installOptions := install.Options{ BaseURL: rootArgs.defaults.BaseURL, Version: bootstrapArgs.version, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Components: bootstrapComponents(), Registry: bootstrapArgs.registry, ImagePullSecret: bootstrapArgs.imagePullSecret, @@ -200,7 +200,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { // Source generation and secret config secretOpts := sourcesecret.Options{ Name: bootstrapArgs.secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, TargetPath: bServerArgs.path.String(), ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } @@ -232,8 +232,8 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { // Sync manifest config syncOpts := sync.Options{ Interval: bServerArgs.interval, - Name: rootArgs.namespace, - Namespace: rootArgs.namespace, + Name: *kubeconfigArgs.Namespace, + Namespace: *kubeconfigArgs.Namespace, Branch: bootstrapArgs.branch, Secret: bootstrapArgs.secretName, TargetPath: bServerArgs.path.ToSlash(), @@ -251,7 +251,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(bServerArgs.teams, bServerDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(bServerArgs.readWriteKey), - bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext), + bootstrap.WithKubeconfig(kubeconfigArgs), bootstrap.WithLogger(logger), bootstrap.WithCABundle(caBundle), } diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go index 786a2692..4a754764 100644 --- a/cmd/flux/bootstrap_git.go +++ b/cmd/flux/bootstrap_git.go @@ -101,7 +101,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -128,7 +128,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { installOptions := install.Options{ BaseURL: rootArgs.defaults.BaseURL, Version: bootstrapArgs.version, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Components: bootstrapComponents(), Registry: bootstrapArgs.registry, ImagePullSecret: bootstrapArgs.imagePullSecret, @@ -149,7 +149,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { // Source generation and secret config secretOpts := sourcesecret.Options{ Name: bootstrapArgs.secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, TargetPath: gitArgs.path.String(), ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } @@ -194,8 +194,8 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { // Sync manifest config syncOpts := sync.Options{ Interval: gitArgs.interval, - Name: rootArgs.namespace, - Namespace: rootArgs.namespace, + Name: *kubeconfigArgs.Namespace, + Namespace: *kubeconfigArgs.Namespace, URL: repositoryURL.String(), Branch: bootstrapArgs.branch, Secret: bootstrapArgs.secretName, @@ -220,7 +220,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithBranch(bootstrapArgs.branch), bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail), bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), - bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext), + bootstrap.WithKubeconfig(kubeconfigArgs), bootstrap.WithPostGenerateSecretFunc(promptPublicKey), bootstrap.WithLogger(logger), bootstrap.WithCABundle(caBundle), diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go index f2775da9..fd04ac6f 100644 --- a/cmd/flux/bootstrap_github.go +++ b/cmd/flux/bootstrap_github.go @@ -125,7 +125,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -175,7 +175,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { installOptions := install.Options{ BaseURL: rootArgs.defaults.BaseURL, Version: bootstrapArgs.version, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Components: bootstrapComponents(), Registry: bootstrapArgs.registry, ImagePullSecret: bootstrapArgs.imagePullSecret, @@ -196,7 +196,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // Source generation and secret config secretOpts := sourcesecret.Options{ Name: bootstrapArgs.secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, TargetPath: githubArgs.path.ToSlash(), ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } @@ -221,8 +221,8 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { // Sync manifest config syncOpts := sync.Options{ Interval: githubArgs.interval, - Name: rootArgs.namespace, - Namespace: rootArgs.namespace, + Name: *kubeconfigArgs.Namespace, + Namespace: *kubeconfigArgs.Namespace, Branch: bootstrapArgs.branch, Secret: bootstrapArgs.secretName, TargetPath: githubArgs.path.ToSlash(), @@ -240,7 +240,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(githubArgs.teams, ghDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(githubArgs.readWriteKey), - bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext), + bootstrap.WithKubeconfig(kubeconfigArgs), bootstrap.WithLogger(logger), bootstrap.WithCABundle(caBundle), } diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go index 88b85aeb..6906a2a7 100644 --- a/cmd/flux/bootstrap_gitlab.go +++ b/cmd/flux/bootstrap_gitlab.go @@ -129,7 +129,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -186,7 +186,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { installOptions := install.Options{ BaseURL: rootArgs.defaults.BaseURL, Version: bootstrapArgs.version, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Components: bootstrapComponents(), Registry: bootstrapArgs.registry, ImagePullSecret: bootstrapArgs.imagePullSecret, @@ -207,7 +207,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // Source generation and secret config secretOpts := sourcesecret.Options{ Name: bootstrapArgs.secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, TargetPath: gitlabArgs.path.String(), ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } @@ -235,8 +235,8 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { // Sync manifest config syncOpts := sync.Options{ Interval: gitlabArgs.interval, - Name: rootArgs.namespace, - Namespace: rootArgs.namespace, + Name: *kubeconfigArgs.Namespace, + Namespace: *kubeconfigArgs.Namespace, Branch: bootstrapArgs.branch, Secret: bootstrapArgs.secretName, TargetPath: gitlabArgs.path.ToSlash(), @@ -254,7 +254,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error { bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix), bootstrap.WithProviderTeamPermissions(mapTeamSlice(gitlabArgs.teams, glDefaultPermission)), bootstrap.WithReadWriteKeyPermissions(gitlabArgs.readWriteKey), - bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext), + bootstrap.WithKubeconfig(kubeconfigArgs), bootstrap.WithLogger(logger), bootstrap.WithCABundle(caBundle), } diff --git a/cmd/flux/check.go b/cmd/flux/check.go index 42c6891e..a36159d0 100644 --- a/cmd/flux/check.go +++ b/cmd/flux/check.go @@ -128,7 +128,7 @@ func fluxCheck() { } func kubernetesCheck(constraints []string) bool { - cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + cfg, err := utils.KubeConfig(kubeconfigArgs) if err != nil { logger.Failuref("Kubernetes client initialization failed: %s", err.Error()) return false @@ -176,7 +176,7 @@ func componentsCheck() bool { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeConfig, err := utils.KubeConfig(kubeconfigArgs) if err != nil { return false } @@ -186,7 +186,7 @@ func componentsCheck() bool { return false } - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return false } @@ -194,7 +194,7 @@ func componentsCheck() bool { ok := true selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue} var list v1.DeploymentList - if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err == nil { + if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err == nil { for _, d := range list.Items { if ref, err := buildComponentObjectRefs(d.Name); err == nil { if err := statusChecker.Assess(ref...); err != nil { diff --git a/cmd/flux/check_test.go b/cmd/flux/check_test.go index c70d6b09..8ae39b1b 100644 --- a/cmd/flux/check_test.go +++ b/cmd/flux/check_test.go @@ -29,7 +29,7 @@ import ( ) func TestCheckPre(t *testing.T) { - jsonOutput, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, "version", "--output", "json") + jsonOutput, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, "version", "--output", "json") if err != nil { t.Fatalf("Error running utils.ExecKubectlCommand: %v", err.Error()) } diff --git a/cmd/flux/completion.go b/cmd/flux/completion.go index 077d768e..06beac2a 100644 --- a/cmd/flux/completion.go +++ b/cmd/flux/completion.go @@ -25,10 +25,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - memory "k8s.io/client-go/discovery/cached" "k8s.io/client-go/dynamic" - "k8s.io/client-go/restmapper" ) var completionCmd = &cobra.Command{ @@ -42,7 +39,7 @@ func init() { } func contextsCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - rawConfig, err := utils.ClientConfig(rootArgs.kubeconfig, rootArgs.kubecontext).RawConfig() + rawConfig, err := kubeconfigArgs.ToRawKubeConfigLoader().RawConfig() if err != nil { return completionError(err) } @@ -63,16 +60,15 @@ func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Co ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + cfg, err := utils.KubeConfig(kubeconfigArgs) if err != nil { return completionError(err) } - dc, err := discovery.NewDiscoveryClientForConfig(cfg) + mapper, err := kubeconfigArgs.ToRESTMapper() if err != nil { return completionError(err) } - mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc)) mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { @@ -86,7 +82,7 @@ func resourceNamesCompletionFunc(gvk schema.GroupVersionKind) func(cmd *cobra.Co var dr dynamic.ResourceInterface if mapping.Scope.Name() == meta.RESTScopeNameNamespace { - dr = client.Resource(mapping.Resource).Namespace(rootArgs.namespace) + dr = client.Resource(mapping.Resource).Namespace(*kubeconfigArgs.Namespace) } else { dr = client.Resource(mapping.Resource) } diff --git a/cmd/flux/create.go b/cmd/flux/create.go index 3010c99c..758a2f54 100644 --- a/cmd/flux/create.go +++ b/cmd/flux/create.go @@ -104,7 +104,7 @@ func (names apiType) upsertAndWait(object upsertWaitable, mutate func() error) e ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) // NB globals + kubeClient, err := utils.KubeClient(kubeconfigArgs) // NB globals if err != nil { return err } diff --git a/cmd/flux/create_alert.go b/cmd/flux/create_alert.go index e260ae64..0a5ea93a 100644 --- a/cmd/flux/create_alert.go +++ b/cmd/flux/create_alert.go @@ -102,7 +102,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { alert := notificationv1.Alert{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: notificationv1.AlertSpec{ @@ -122,7 +122,7 @@ func createAlertCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/create_alertprovider.go b/cmd/flux/create_alertprovider.go index 93ac7e89..7d5bf640 100644 --- a/cmd/flux/create_alertprovider.go +++ b/cmd/flux/create_alertprovider.go @@ -94,7 +94,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { provider := notificationv1.Provider{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: notificationv1.ProviderSpec{ @@ -118,7 +118,7 @@ func createAlertProviderCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/create_helmrelease.go b/cmd/flux/create_helmrelease.go index 6a035858..2072c720 100644 --- a/cmd/flux/create_helmrelease.go +++ b/cmd/flux/create_helmrelease.go @@ -160,7 +160,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { helmRelease := helmv2.HelmRelease{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: helmv2.HelmReleaseSpec{ @@ -250,7 +250,7 @@ func createHelmReleaseCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/create_image_policy.go b/cmd/flux/create_image_policy.go index 0cebd321..05cb5c14 100644 --- a/cmd/flux/create_image_policy.go +++ b/cmd/flux/create_image_policy.go @@ -101,7 +101,7 @@ func createImagePolicyRun(cmd *cobra.Command, args []string) error { var policy = imagev1.ImagePolicy{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, }, Spec: imagev1.ImagePolicySpec{ diff --git a/cmd/flux/create_image_repository.go b/cmd/flux/create_image_repository.go index 7619c8a6..b5ffdcb8 100644 --- a/cmd/flux/create_image_repository.go +++ b/cmd/flux/create_image_repository.go @@ -104,7 +104,7 @@ func createImageRepositoryRun(cmd *cobra.Command, args []string) error { var repo = imagev1.ImageRepository{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, }, Spec: imagev1.ImageRepositorySpec{ diff --git a/cmd/flux/create_image_update.go b/cmd/flux/create_image_update.go index 6ef81a28..2adb562c 100644 --- a/cmd/flux/create_image_update.go +++ b/cmd/flux/create_image_update.go @@ -108,7 +108,7 @@ func createImageUpdateRun(cmd *cobra.Command, args []string) error { var update = autov1.ImageUpdateAutomation{ ObjectMeta: metav1.ObjectMeta{ Name: objectName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, }, Spec: autov1.ImageUpdateAutomationSpec{ diff --git a/cmd/flux/create_kustomization.go b/cmd/flux/create_kustomization.go index eb898e7b..d523374d 100644 --- a/cmd/flux/create_kustomization.go +++ b/cmd/flux/create_kustomization.go @@ -143,7 +143,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { kustomization := kustomizev1.Kustomization{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: kslabels, }, Spec: kustomizev1.KustomizationSpec{ @@ -232,7 +232,7 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/create_receiver.go b/cmd/flux/create_receiver.go index c2d33a15..d6004dc1 100644 --- a/cmd/flux/create_receiver.go +++ b/cmd/flux/create_receiver.go @@ -109,7 +109,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { receiver := notificationv1.Receiver{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: notificationv1.ReceiverSpec{ @@ -130,7 +130,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/create_secret_git.go b/cmd/flux/create_secret_git.go index 0e6d7106..769c2526 100644 --- a/cmd/flux/create_secret_git.go +++ b/cmd/flux/create_secret_git.go @@ -132,7 +132,7 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { opts := sourcesecret.Options{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } @@ -176,14 +176,14 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } if err := upsertSecret(ctx, kubeClient, s); err != nil { return err } - logger.Actionf("git secret '%s' created in '%s' namespace", name, rootArgs.namespace) + logger.Actionf("git secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace) return nil } diff --git a/cmd/flux/create_secret_helm.go b/cmd/flux/create_secret_helm.go index 0fe8df8b..8f9df1b5 100644 --- a/cmd/flux/create_secret_helm.go +++ b/cmd/flux/create_secret_helm.go @@ -80,7 +80,7 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error { opts := sourcesecret.Options{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, Username: secretHelmArgs.username, Password: secretHelmArgs.password, @@ -100,7 +100,7 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -112,6 +112,6 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("helm secret '%s' created in '%s' namespace", name, rootArgs.namespace) + logger.Actionf("helm secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace) return nil } diff --git a/cmd/flux/create_secret_tls.go b/cmd/flux/create_secret_tls.go index 2b8c40d9..a308066e 100644 --- a/cmd/flux/create_secret_tls.go +++ b/cmd/flux/create_secret_tls.go @@ -79,7 +79,7 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error { opts := sourcesecret.Options{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: labels, CAFilePath: secretTLSArgs.caFile, CertFilePath: secretTLSArgs.certFile, @@ -97,7 +97,7 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -109,6 +109,6 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error { return err } - logger.Actionf("tls secret '%s' created in '%s' namespace", name, rootArgs.namespace) + logger.Actionf("tls secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace) return nil } diff --git a/cmd/flux/create_source_bucket.go b/cmd/flux/create_source_bucket.go index 4ec6aaea..50858c5b 100644 --- a/cmd/flux/create_source_bucket.go +++ b/cmd/flux/create_source_bucket.go @@ -120,7 +120,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { bucket := &sourcev1.Bucket{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: sourcev1.BucketSpec{ @@ -152,7 +152,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -165,7 +165,7 @@ func createSourceBucketCmdRun(cmd *cobra.Command, args []string) error { secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, StringData: map[string]string{}, diff --git a/cmd/flux/create_source_git.go b/cmd/flux/create_source_git.go index f2c6b918..17a928b6 100644 --- a/cmd/flux/create_source_git.go +++ b/cmd/flux/create_source_git.go @@ -193,7 +193,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { gitRepository := sourcev1.GitRepository{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: sourcev1.GitRepositorySpec{ @@ -235,7 +235,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -244,7 +244,7 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error { if sourceGitArgs.secretRef == "" { secretOpts := sourcesecret.Options{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile, } switch u.Scheme { diff --git a/cmd/flux/create_source_helm.go b/cmd/flux/create_source_helm.go index a1edd409..81b5a05f 100644 --- a/cmd/flux/create_source_helm.go +++ b/cmd/flux/create_source_helm.go @@ -118,7 +118,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { helmRepository := &sourcev1.HelmRepository{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Labels: sourceLabels, }, Spec: sourcev1.HelmRepositorySpec{ @@ -147,7 +147,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -157,7 +157,7 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error { secretName := fmt.Sprintf("helm-%s", name) secretOpts := sourcesecret.Options{ Name: secretName, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Username: sourceHelmArgs.username, Password: sourceHelmArgs.password, CertFilePath: sourceHelmArgs.certFile, diff --git a/cmd/flux/create_tenant.go b/cmd/flux/create_tenant.go index 22bb978f..88b8eda6 100644 --- a/cmd/flux/create_tenant.go +++ b/cmd/flux/create_tenant.go @@ -159,7 +159,7 @@ func createTenantCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } diff --git a/cmd/flux/delete.go b/cmd/flux/delete.go index 966f8800..7facf933 100644 --- a/cmd/flux/delete.go +++ b/cmd/flux/delete.go @@ -60,13 +60,13 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } @@ -85,7 +85,7 @@ func (del deleteCommand) run(cmd *cobra.Command, args []string) error { } } - logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, rootArgs.namespace) + logger.Actionf("deleting %s %s in %s namespace", del.humanKind, name, *kubeconfigArgs.Namespace) err = kubeClient.Delete(ctx, del.object.asClientObject()) if err != nil { return err diff --git a/cmd/flux/export.go b/cmd/flux/export.go index 173bb763..e9b3be11 100644 --- a/cmd/flux/export.go +++ b/cmd/flux/export.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "fmt" + "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" @@ -73,19 +74,19 @@ func (export exportCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } if exportArgs.all { - err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(rootArgs.namespace)) + err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(*kubeconfigArgs.Namespace)) if err != nil { return err } if export.list.len() == 0 { - return fmt.Errorf("no objects found in %s namespace", rootArgs.namespace) + return fmt.Errorf("no objects found in %s namespace", *kubeconfigArgs.Namespace) } for i := 0; i < export.list.len(); i++ { @@ -96,7 +97,7 @@ func (export exportCommand) run(cmd *cobra.Command, args []string) error { } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } err = kubeClient.Get(ctx, namespacedName, export.object.asClientObject()) diff --git a/cmd/flux/export_secret.go b/cmd/flux/export_secret.go index 74d018b2..eb7dfb05 100644 --- a/cmd/flux/export_secret.go +++ b/cmd/flux/export_secret.go @@ -19,6 +19,7 @@ package main import ( "context" "fmt" + "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -58,19 +59,19 @@ func (export exportWithSecretCommand) run(cmd *cobra.Command, args []string) err ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } if exportArgs.all { - err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(rootArgs.namespace)) + err = kubeClient.List(ctx, export.list.asClientList(), client.InNamespace(*kubeconfigArgs.Namespace)) if err != nil { return err } if export.list.len() == 0 { - return fmt.Errorf("no objects found in %s namespace", rootArgs.namespace) + return fmt.Errorf("no objects found in %s namespace", *kubeconfigArgs.Namespace) } for i := 0; i < export.list.len(); i++ { @@ -88,7 +89,7 @@ func (export exportWithSecretCommand) run(cmd *cobra.Command, args []string) err } else { name := args[0] namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } err = kubeClient.Get(ctx, namespacedName, export.object.asClientObject()) diff --git a/cmd/flux/get.go b/cmd/flux/get.go index db3d34dd..f52fd496 100644 --- a/cmd/flux/get.go +++ b/cmd/flux/get.go @@ -135,14 +135,14 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } var listOpts []client.ListOption if !getArgs.allNamespaces { - listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) + listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace)) } if len(args) > 0 { @@ -162,7 +162,7 @@ func (get getCommand) run(cmd *cobra.Command, args []string) error { if get.list.len() == 0 { if !getAll { - logger.Failuref("no %s objects found in %s namespace", get.kind, rootArgs.namespace) + logger.Failuref("no %s objects found in %s namespace", get.kind, *kubeconfigArgs.Namespace) } return nil } diff --git a/cmd/flux/install.go b/cmd/flux/install.go index 36937b16..9032929b 100644 --- a/cmd/flux/install.go +++ b/cmd/flux/install.go @@ -131,7 +131,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { logger.Generatef("generating manifests") } - tmpDir, err := os.MkdirTemp("", rootArgs.namespace) + tmpDir, err := os.MkdirTemp("", *kubeconfigArgs.Namespace) if err != nil { return err } @@ -148,7 +148,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { opts := install.Options{ BaseURL: installArgs.manifestsPath, Version: installArgs.version, - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Components: components, Registry: installArgs.registry, ImagePullSecret: installArgs.imagePullSecret, @@ -156,7 +156,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error { NetworkPolicy: installArgs.networkPolicy, LogLevel: installArgs.logLevel.String(), NotificationController: rootArgs.defaults.NotificationController, - ManifestFile: fmt.Sprintf("%s.yaml", rootArgs.namespace), + ManifestFile: fmt.Sprintf("%s.yaml", *kubeconfigArgs.Namespace), Timeout: rootArgs.timeout, ClusterDomain: installArgs.clusterDomain, TolerationKeys: installArgs.tolerationKeys, @@ -183,21 +183,21 @@ func installCmdRun(cmd *cobra.Command, args []string) error { } logger.Successf("manifests build completed") - logger.Actionf("installing components in %s namespace", rootArgs.namespace) + logger.Actionf("installing components in %s namespace", *kubeconfigArgs.Namespace) if installArgs.dryRun { logger.Successf("install dry-run finished") return nil } - applyOutput, err := utils.Apply(ctx, rootArgs.kubeconfig, rootArgs.kubecontext, filepath.Join(tmpDir, manifest.Path)) + applyOutput, err := utils.Apply(ctx, kubeconfigArgs, filepath.Join(tmpDir, manifest.Path)) if err != nil { return fmt.Errorf("install failed: %w", err) } fmt.Fprintln(os.Stderr, applyOutput) - kubeConfig, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeConfig, err := utils.KubeConfig(kubeconfigArgs) if err != nil { return fmt.Errorf("install failed: %w", err) } diff --git a/cmd/flux/logs.go b/cmd/flux/logs.go index 23197363..3dc0f903 100644 --- a/cmd/flux/logs.go +++ b/cmd/flux/logs.go @@ -99,7 +99,7 @@ func logsCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - cfg, err := utils.KubeConfig(rootArgs.kubeconfig, rootArgs.kubecontext) + cfg, err := utils.KubeConfig(kubeconfigArgs) if err != nil { return err } @@ -278,7 +278,7 @@ func filterPrintLog(t *template.Template, l *ControllerLogEntry) { if logsArgs.logLevel != "" && logsArgs.logLevel != l.Level || logsArgs.kind != "" && strings.ToLower(logsArgs.kind) != strings.ToLower(l.Kind) || logsArgs.name != "" && strings.ToLower(logsArgs.name) != strings.ToLower(l.Name) || - !logsArgs.allNamespaces && strings.ToLower(rootArgs.namespace) != strings.ToLower(l.Namespace) { + !logsArgs.allNamespaces && strings.ToLower(*kubeconfigArgs.Namespace) != strings.ToLower(l.Namespace) { return } diff --git a/cmd/flux/main.go b/cmd/flux/main.go index 6b00e4b0..d61bcda9 100644 --- a/cmd/flux/main.go +++ b/cmd/flux/main.go @@ -21,13 +21,13 @@ import ( "fmt" "log" "os" - "path/filepath" "strings" "time" "github.com/spf13/cobra" "golang.org/x/term" corev1 "k8s.io/api/core/v1" + "k8s.io/cli-runtime/pkg/genericclioptions" _ "k8s.io/client-go/plugin/pkg/client/auth" "github.com/fluxcd/flux2/pkg/manifestgen/install" @@ -99,9 +99,6 @@ Command line utility for assembling Kubernetes CD pipelines the GitOps way.`, var logger = stderrLogger{stderr: os.Stderr} type rootFlags struct { - kubeconfig string - kubecontext string - namespace string timeout time.Duration verbose bool pollInterval time.Duration @@ -109,19 +106,26 @@ type rootFlags struct { } var rootArgs = NewRootFlags() +var kubeconfigArgs = genericclioptions.NewConfigFlags(false) func init() { - rootCmd.PersistentFlags().StringVarP(&rootArgs.namespace, "namespace", "n", rootArgs.defaults.Namespace, - "the namespace scope for this operation, can be set with FLUX_SYSTEM_NAMESPACE env var") - rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace"))) - rootCmd.PersistentFlags().DurationVar(&rootArgs.timeout, "timeout", 5*time.Minute, "timeout for this operation") rootCmd.PersistentFlags().BoolVar(&rootArgs.verbose, "verbose", false, "print generated objects") - rootCmd.PersistentFlags().StringVarP(&rootArgs.kubeconfig, "kubeconfig", "", "", - "absolute path to the kubeconfig file") - rootCmd.PersistentFlags().StringVarP(&rootArgs.kubecontext, "context", "", "", "kubernetes context to use") + configureDefaultNamespace() + kubeconfigArgs.APIServer = nil // prevent AddFlags from configuring --server flag + kubeconfigArgs.Timeout = nil // prevent AddFlags from configuring --request-timeout flag, we have --timeout instead + kubeconfigArgs.AddFlags(rootCmd.PersistentFlags()) + + // Since some subcommands use the `-s` flag as a short version for `--silent`, we manually configure the server flag + // without the `-s` short version. While we're no longer on par with kubectl's flags, we maintain backwards compatibility + // on the CLI interface. + apiServer := "" + kubeconfigArgs.APIServer = &apiServer + rootCmd.PersistentFlags().StringVar(kubeconfigArgs.APIServer, "server", *kubeconfigArgs.APIServer, "The address and port of the Kubernetes API server") + rootCmd.RegisterFlagCompletionFunc("context", contextsCompletionFunc) + rootCmd.RegisterFlagCompletionFunc("namespace", resourceNamesCompletionFunc(corev1.SchemeGroupVersion.WithKind("Namespace"))) rootCmd.DisableAutoGenTag = true rootCmd.SetOut(os.Stdout) @@ -138,30 +142,17 @@ func NewRootFlags() rootFlags { func main() { log.SetFlags(0) - configureKubeconfig() - configureDefaultNamespace() if err := rootCmd.Execute(); err != nil { logger.Failuref("%v", err) os.Exit(1) } } -func configureKubeconfig() { - switch { - case len(rootArgs.kubeconfig) > 0: - case len(os.Getenv("KUBECONFIG")) > 0: - rootArgs.kubeconfig = os.Getenv("KUBECONFIG") - default: - if home := homeDir(); len(home) > 0 { - rootArgs.kubeconfig = filepath.Join(home, ".kube", "config") - } - } -} - func configureDefaultNamespace() { + *kubeconfigArgs.Namespace = rootArgs.defaults.Namespace fromEnv := os.Getenv("FLUX_SYSTEM_NAMESPACE") - if fromEnv != "" && rootArgs.namespace == rootArgs.defaults.Namespace { - rootArgs.namespace = fromEnv + if fromEnv != "" { + kubeconfigArgs.Namespace = &fromEnv } } diff --git a/cmd/flux/main_e2e_test.go b/cmd/flux/main_e2e_test.go index 1e2c775e..7cd6bfa2 100644 --- a/cmd/flux/main_e2e_test.go +++ b/cmd/flux/main_e2e_test.go @@ -35,7 +35,7 @@ func TestMain(m *testing.M) { if err != nil { panic(fmt.Errorf("error creating kube manager: '%w'", err)) } - rootArgs.kubeconfig = testEnv.kubeConfigPath + kubeconfigArgs.KubeConfig = &testEnv.kubeConfigPath // Install Flux. output, err := executeCommand("install --components-extra=image-reflector-controller,image-automation-controller") @@ -54,7 +54,7 @@ func TestMain(m *testing.M) { // Delete namespace and wait for finalisation kubectlArgs := []string{"delete", "namespace", "flux-system"} - _, err = utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...) + _, err = utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...) if err != nil { panic(fmt.Errorf("delete namespace error:'%w'", err)) } @@ -66,13 +66,13 @@ func TestMain(m *testing.M) { func setupTestNamespace(namespace string) (func(), error) { kubectlArgs := []string{"create", "namespace", namespace} - _, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...) + _, err := utils.ExecKubectlCommand(context.TODO(), utils.ModeStderrOS, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...) if err != nil { return nil, err } return func() { kubectlArgs := []string{"delete", "namespace", namespace} - utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, rootArgs.kubeconfig, rootArgs.kubecontext, kubectlArgs...) + utils.ExecKubectlCommand(context.TODO(), utils.ModeCapture, *kubeconfigArgs.KubeConfig, *kubeconfigArgs.Context, kubectlArgs...) }, nil } diff --git a/cmd/flux/main_unit_test.go b/cmd/flux/main_unit_test.go index 2b992cce..605b204c 100644 --- a/cmd/flux/main_unit_test.go +++ b/cmd/flux/main_unit_test.go @@ -42,7 +42,8 @@ func TestMain(m *testing.M) { panic(fmt.Errorf("error creating kube manager: '%w'", err)) } testEnv = km - rootArgs.kubeconfig = testEnv.kubeConfigPath + // rootArgs.kubeconfig = testEnv.kubeConfigPath + kubeconfigArgs.KubeConfig = &testEnv.kubeConfigPath // Run tests code := m.Run() diff --git a/cmd/flux/reconcile.go b/cmd/flux/reconcile.go index c0c609d8..c3e53a73 100644 --- a/cmd/flux/reconcile.go +++ b/cmd/flux/reconcile.go @@ -75,13 +75,13 @@ func (reconcile reconcileCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } @@ -94,7 +94,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, rootArgs.namespace) + logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, *kubeconfigArgs.Namespace) if err := requestReconciliation(ctx, kubeClient, namespacedName, reconcile.object); err != nil { return err } diff --git a/cmd/flux/reconcile_alertprovider.go b/cmd/flux/reconcile_alertprovider.go index 092e8ac9..df24a68e 100644 --- a/cmd/flux/reconcile_alertprovider.go +++ b/cmd/flux/reconcile_alertprovider.go @@ -54,17 +54,17 @@ func reconcileAlertProviderCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } - logger.Actionf("annotating Provider %s in %s namespace", name, rootArgs.namespace) + logger.Actionf("annotating Provider %s in %s namespace", name, *kubeconfigArgs.Namespace) var alertProvider notificationv1.Provider err = kubeClient.Get(ctx, namespacedName, &alertProvider) if err != nil { diff --git a/cmd/flux/reconcile_receiver.go b/cmd/flux/reconcile_receiver.go index 9b7e7fd0..676aa30a 100644 --- a/cmd/flux/reconcile_receiver.go +++ b/cmd/flux/reconcile_receiver.go @@ -54,13 +54,13 @@ func reconcileReceiverCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.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, rootArgs.namespace) + logger.Actionf("annotating Receiver %s in %s namespace", name, *kubeconfigArgs.Namespace) if receiver.Annotations == nil { receiver.Annotations = map[string]string{ meta.ReconcileRequestAnnotation: time.Now().Format(time.RFC3339Nano), diff --git a/cmd/flux/reconcile_with_source.go b/cmd/flux/reconcile_with_source.go index 7052b879..4eff1ee8 100644 --- a/cmd/flux/reconcile_with_source.go +++ b/cmd/flux/reconcile_with_source.go @@ -36,13 +36,13 @@ func (reconcile reconcileWithSourceCommand) run(cmd *cobra.Command, args []strin ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } namespacedName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } @@ -57,20 +57,20 @@ func (reconcile reconcileWithSourceCommand) run(cmd *cobra.Command, args []strin if reconcile.object.reconcileSource() { reconcileCmd, nsName := reconcile.object.getSource() - nsCopy := rootArgs.namespace + nsCopy := *kubeconfigArgs.Namespace if nsName.Namespace != "" { - rootArgs.namespace = nsName.Namespace + *kubeconfigArgs.Namespace = nsName.Namespace } err := reconcileCmd.run(nil, []string{nsName.Name}) if err != nil { return err } - rootArgs.namespace = nsCopy + *kubeconfigArgs.Namespace = nsCopy } lastHandledReconcileAt := reconcile.object.lastHandledReconcileRequest() - logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, rootArgs.namespace) + logger.Actionf("annotating %s %s in %s namespace", reconcile.kind, name, *kubeconfigArgs.Namespace) if err := requestReconciliation(ctx, kubeClient, namespacedName, reconcile.object); err != nil { return err } diff --git a/cmd/flux/resume.go b/cmd/flux/resume.go index 004bcfb6..163fbb90 100644 --- a/cmd/flux/resume.go +++ b/cmd/flux/resume.go @@ -72,13 +72,13 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } var listOpts []client.ListOption - listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) + listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace)) if len(args) > 0 { listOpts = append(listOpts, client.MatchingFields{ "metadata.name": args[0], @@ -91,12 +91,12 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { } if resume.list.len() == 0 { - logger.Failuref("no %s objects found in %s namespace", resume.kind, rootArgs.namespace) + logger.Failuref("no %s objects found in %s namespace", resume.kind, *kubeconfigArgs.Namespace) return nil } for i := 0; i < resume.list.len(); i++ { - logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, resume.list.resumeItem(i).asClientObject().GetName(), rootArgs.namespace) + logger.Actionf("resuming %s %s in %s namespace", resume.humanKind, resume.list.resumeItem(i).asClientObject().GetName(), *kubeconfigArgs.Namespace) resume.list.resumeItem(i).setUnsuspended() if err := kubeClient.Update(ctx, resume.list.resumeItem(i).asClientObject()); err != nil { return err @@ -105,7 +105,7 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { namespacedName := types.NamespacedName{ Name: resume.list.resumeItem(i).asClientObject().GetName(), - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, } logger.Waitingf("waiting for %s reconciliation", resume.kind) diff --git a/cmd/flux/status.go b/cmd/flux/status.go index 631a3e2f..d39071e2 100644 --- a/cmd/flux/status.go +++ b/cmd/flux/status.go @@ -69,7 +69,7 @@ func isReady(ctx context.Context, kubeClient client.Client, func buildComponentObjectRefs(components ...string) ([]object.ObjMetadata, error) { var objRefs []object.ObjMetadata for _, deployment := range components { - objMeta, err := object.CreateObjMetadata(rootArgs.namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"}) + objMeta, err := object.CreateObjMetadata(*kubeconfigArgs.Namespace, deployment, schema.GroupKind{Group: "apps", Kind: "Deployment"}) if err != nil { return nil, err } diff --git a/cmd/flux/suspend.go b/cmd/flux/suspend.go index 101f29bb..02a44bd1 100644 --- a/cmd/flux/suspend.go +++ b/cmd/flux/suspend.go @@ -69,13 +69,13 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } var listOpts []client.ListOption - listOpts = append(listOpts, client.InNamespace(rootArgs.namespace)) + listOpts = append(listOpts, client.InNamespace(*kubeconfigArgs.Namespace)) if len(args) > 0 { listOpts = append(listOpts, client.MatchingFields{ "metadata.name": args[0], @@ -88,12 +88,12 @@ func (suspend suspendCommand) run(cmd *cobra.Command, args []string) error { } if suspend.list.len() == 0 { - logger.Failuref("no %s objects found in %s namespace", suspend.kind, rootArgs.namespace) + logger.Failuref("no %s objects found in %s namespace", suspend.kind, *kubeconfigArgs.Namespace) return nil } for i := 0; i < suspend.list.len(); i++ { - logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, suspend.list.item(i).asClientObject().GetName(), rootArgs.namespace) + logger.Actionf("suspending %s %s in %s namespace", suspend.humanKind, suspend.list.item(i).asClientObject().GetName(), *kubeconfigArgs.Namespace) suspend.list.item(i).setSuspended() if err := kubeClient.Update(ctx, suspend.list.item(i).asClientObject()); err != nil { return err diff --git a/cmd/flux/trace.go b/cmd/flux/trace.go index a5af188e..910c9d43 100644 --- a/cmd/flux/trace.go +++ b/cmd/flux/trace.go @@ -89,7 +89,7 @@ func traceCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } @@ -107,7 +107,7 @@ func traceCmdRun(cmd *cobra.Command, args []string) error { }) objName := types.NamespacedName{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, } diff --git a/cmd/flux/tree_kustomization.go b/cmd/flux/tree_kustomization.go index 25d4142d..ed19f685 100644 --- a/cmd/flux/tree_kustomization.go +++ b/cmd/flux/tree_kustomization.go @@ -77,14 +77,14 @@ func treeKsCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } k := &kustomizev1.Kustomization{} err = kubeClient.Get(ctx, client.ObjectKey{ - Namespace: rootArgs.namespace, + Namespace: *kubeconfigArgs.Namespace, Name: name, }, k) if err != nil { diff --git a/cmd/flux/uninstall.go b/cmd/flux/uninstall.go index 448137a1..15d271b8 100644 --- a/cmd/flux/uninstall.go +++ b/cmd/flux/uninstall.go @@ -82,13 +82,13 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) defer cancel() - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } - logger.Actionf("deleting components in %s namespace", rootArgs.namespace) - uninstallComponents(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun) + logger.Actionf("deleting components in %s namespace", *kubeconfigArgs.Namespace) + uninstallComponents(ctx, kubeClient, *kubeconfigArgs.Namespace, uninstallArgs.dryRun) logger.Actionf("deleting toolkit.fluxcd.io finalizers in all namespaces") uninstallFinalizers(ctx, kubeClient, uninstallArgs.dryRun) @@ -97,7 +97,7 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error { uninstallCustomResourceDefinitions(ctx, kubeClient, uninstallArgs.dryRun) if !uninstallArgs.keepNamespace { - uninstallNamespace(ctx, kubeClient, rootArgs.namespace, uninstallArgs.dryRun) + uninstallNamespace(ctx, kubeClient, *kubeconfigArgs.Namespace, uninstallArgs.dryRun) } logger.Successf("uninstall finished") diff --git a/cmd/flux/version.go b/cmd/flux/version.go index 93ee3f90..f5da9e29 100644 --- a/cmd/flux/version.go +++ b/cmd/flux/version.go @@ -74,19 +74,19 @@ func versionCmdRun(cmd *cobra.Command, args []string) error { info["flux"] = rootArgs.defaults.Version if !versionArgs.client { - kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext) + kubeClient, err := utils.KubeClient(kubeconfigArgs) if err != nil { return err } selector := client.MatchingLabels{manifestgen.PartOfLabelKey: manifestgen.PartOfLabelValue} var list v1.DeploymentList - if err := kubeClient.List(ctx, &list, client.InNamespace(rootArgs.namespace), selector); err != nil { + if err := kubeClient.List(ctx, &list, client.InNamespace(*kubeconfigArgs.Namespace), selector); err != nil { return err } if len(list.Items) == 0 { - return fmt.Errorf("no deployments found in %s namespace", rootArgs.namespace) + return fmt.Errorf("no deployments found in %s namespace", *kubeconfigArgs.Namespace) } for _, d := range list.Items { diff --git a/go.mod b/go.mod index 1cdfd738..a48b2954 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( k8s.io/api v0.22.2 k8s.io/apiextensions-apiserver v0.22.2 k8s.io/apimachinery v0.22.2 + k8s.io/cli-runtime v0.21.1 k8s.io/client-go v0.22.2 k8s.io/kubectl v0.21.1 sigs.k8s.io/cli-utils v0.26.0 diff --git a/internal/bootstrap/bootstrap_plain_git.go b/internal/bootstrap/bootstrap_plain_git.go index 16d66ed7..f661e936 100644 --- a/internal/bootstrap/bootstrap_plain_git.go +++ b/internal/bootstrap/bootstrap_plain_git.go @@ -27,6 +27,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/cli-runtime/pkg/genericclioptions" "sigs.k8s.io/cli-utils/pkg/object" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/kustomize/api/filesys" @@ -57,8 +58,7 @@ type PlainGitBootstrapper struct { gpgPassphrase string gpgKeyID string - kubeconfig string - kubecontext string + restClientGetter genericclioptions.RESTClientGetter postGenerateSecret []PostGenerateSecretFunc @@ -167,12 +167,12 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest if _, err := os.Stat(kfile); err == nil { // Apply the components and their patches b.logger.Actionf("installing components in %q namespace", options.Namespace) - if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, kfile); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, kfile); err != nil { return err } } else { // Apply the CRDs and controllers - if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, componentsYAML); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, componentsYAML); err != nil { return err } } @@ -299,7 +299,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options // Apply to cluster b.logger.Actionf("applying sync manifests") - if _, err := utils.Apply(ctx, b.kubeconfig, b.kubecontext, filepath.Join(b.git.Path(), kusManifests.Path)); err != nil { + if _, err := utils.Apply(ctx, b.restClientGetter, filepath.Join(b.git.Path(), kusManifests.Path)); err != nil { return err } @@ -332,7 +332,7 @@ func (b *PlainGitBootstrapper) ReportKustomizationHealth(ctx context.Context, op } func (b *PlainGitBootstrapper) ReportComponentsHealth(ctx context.Context, install install.Options, timeout time.Duration) error { - cfg, err := utils.KubeConfig(b.kubeconfig, b.kubecontext) + cfg, err := utils.KubeConfig(b.restClientGetter) if err != nil { return err } diff --git a/internal/bootstrap/options.go b/internal/bootstrap/options.go index 2deb67db..6d79055c 100644 --- a/internal/bootstrap/options.go +++ b/internal/bootstrap/options.go @@ -19,6 +19,7 @@ package bootstrap import ( "github.com/fluxcd/flux2/internal/bootstrap/git" "github.com/fluxcd/flux2/pkg/log" + "k8s.io/cli-runtime/pkg/genericclioptions" ) type Option interface { @@ -90,21 +91,18 @@ func (o commitMessageAppendixOption) applyGitProvider(b *GitProviderBootstrapper o.applyGit(b.PlainGitBootstrapper) } -func WithKubeconfig(kubeconfig, kubecontext string) Option { +func WithKubeconfig(rcg genericclioptions.RESTClientGetter) Option { return kubeconfigOption{ - kubeconfig: kubeconfig, - kubecontext: kubecontext, + rcg: rcg, } } type kubeconfigOption struct { - kubeconfig string - kubecontext string + rcg genericclioptions.RESTClientGetter } func (o kubeconfigOption) applyGit(b *PlainGitBootstrapper) { - b.kubeconfig = o.kubeconfig - b.kubecontext = o.kubecontext + b.restClientGetter = o.rcg } func (o kubeconfigOption) applyGitProvider(b *GitProviderBootstrapper) { diff --git a/internal/utils/apply.go b/internal/utils/apply.go index cf87123d..7865d0f2 100644 --- a/internal/utils/apply.go +++ b/internal/utils/apply.go @@ -26,9 +26,9 @@ import ( "github.com/fluxcd/pkg/ssa" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/cli-runtime/pkg/genericclioptions" "sigs.k8s.io/cli-utils/pkg/kstatus/polling" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/apiutil" "sigs.k8s.io/kustomize/api/konfig" "github.com/fluxcd/flux2/pkg/manifestgen/kustomization" @@ -36,12 +36,12 @@ import ( // Apply is the equivalent of 'kubectl apply --server-side -f'. // If the given manifest is a kustomization.yaml, then apply performs the equivalent of 'kubectl apply --server-side -k'. -func Apply(ctx context.Context, kubeConfigPath string, kubeContext string, manifestPath string) (string, error) { - cfg, err := KubeConfig(kubeConfigPath, kubeContext) +func Apply(ctx context.Context, rcg genericclioptions.RESTClientGetter, manifestPath string) (string, error) { + cfg, err := KubeConfig(rcg) if err != nil { return "", err } - restMapper, err := apiutil.NewDynamicRESTMapper(cfg) + restMapper, err := rcg.ToRESTMapper() if err != nil { return "", err } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 963b88e2..361b9448 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -37,8 +37,8 @@ import ( apiruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" sigyaml "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" @@ -107,22 +107,8 @@ func ExecKubectlCommand(ctx context.Context, mode ExecMode, kubeConfigPath strin return "", nil } -func ClientConfig(kubeConfigPath string, kubeContext string) clientcmd.ClientConfig { - configFiles := SplitKubeConfigPath(kubeConfigPath) - configOverrides := clientcmd.ConfigOverrides{} - - if len(kubeContext) > 0 { - configOverrides.CurrentContext = kubeContext - } - - return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - &clientcmd.ClientConfigLoadingRules{Precedence: configFiles}, - &configOverrides, - ) -} - -func KubeConfig(kubeConfigPath string, kubeContext string) (*rest.Config, error) { - cfg, err := ClientConfig(kubeConfigPath, kubeContext).ClientConfig() +func KubeConfig(rcg genericclioptions.RESTClientGetter) (*rest.Config, error) { + cfg, err := rcg.ToRESTConfig() if err != nil { return nil, fmt.Errorf("kubernetes configuration load failed: %w", err) } @@ -152,10 +138,10 @@ func NewScheme() *apiruntime.Scheme { return scheme } -func KubeClient(kubeConfigPath string, kubeContext string) (client.WithWatch, error) { - cfg, err := KubeConfig(kubeConfigPath, kubeContext) +func KubeClient(rcg genericclioptions.RESTClientGetter) (client.WithWatch, error) { + cfg, err := rcg.ToRESTConfig() if err != nil { - return nil, fmt.Errorf("kubernetes client initialization failed: %w", err) + return nil, err } scheme := NewScheme()