Skip to content
This repository was archived by the owner on Jun 29, 2022. It is now read-only.

Commit 863a7a9

Browse files
authored
Merge pull request #631 from kinvolk/invidian/kubeconfig-content-backup
Pass kubeconfig content around rather than file path
2 parents c164fa3 + b65cf5b commit 863a7a9

File tree

16 files changed

+627
-165
lines changed

16 files changed

+627
-165
lines changed

cli/cmd/cluster-apply.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package cmd
1616

1717
import (
1818
"fmt"
19-
"io/ioutil"
2019

2120
"github.com/pkg/errors"
2221
log "github.com/sirupsen/logrus"
@@ -80,8 +79,12 @@ func runClusterApply(cmd *cobra.Command, args []string) {
8079

8180
fmt.Printf("\nYour configurations are stored in %s\n", assetDir)
8281

83-
kubeconfigPath := assetsKubeconfig(assetDir)
84-
if err := verifyCluster(kubeconfigPath, p.Meta().ExpectedNodes); err != nil {
82+
kubeconfig, err := getKubeconfig()
83+
if err != nil {
84+
ctxLogger.Fatalf("Failed to get kubeconfig: %v", err)
85+
}
86+
87+
if err := verifyCluster(kubeconfig, p.Meta().ExpectedNodes); err != nil {
8588
ctxLogger.Fatalf("Verify cluster: %v", err)
8689
}
8790

@@ -90,10 +93,10 @@ func runClusterApply(cmd *cobra.Command, args []string) {
9093
fmt.Printf("\nEnsuring that cluster controlplane is up to date.\n")
9194

9295
cu := controlplaneUpdater{
93-
kubeconfigPath: kubeconfigPath,
94-
assetDir: assetDir,
95-
ctxLogger: *ctxLogger,
96-
ex: *ex,
96+
kubeconfig: kubeconfig,
97+
assetDir: assetDir,
98+
ctxLogger: *ctxLogger,
99+
ex: *ex,
97100
}
98101

99102
releases := []string{"pod-checkpointer", "kube-apiserver", "kubernetes", "calico"}
@@ -119,18 +122,13 @@ func runClusterApply(cmd *cobra.Command, args []string) {
119122
ctxLogger.Println("Applying component configuration")
120123

121124
if len(componentsToApply) > 0 {
122-
if err := applyComponents(lokoConfig, kubeconfigPath, componentsToApply...); err != nil {
125+
if err := applyComponents(lokoConfig, kubeconfig, componentsToApply...); err != nil {
123126
ctxLogger.Fatalf("Applying component configuration failed: %v", err)
124127
}
125128
}
126129
}
127130

128-
func verifyCluster(kubeconfigPath string, expectedNodes int) error {
129-
kubeconfig, err := ioutil.ReadFile(kubeconfigPath) // #nosec G304
130-
if err != nil {
131-
return errors.Wrapf(err, "failed to read kubeconfig file")
132-
}
133-
131+
func verifyCluster(kubeconfig []byte, expectedNodes int) error {
134132
cs, err := k8sutil.NewClientset(kubeconfig)
135133
if err != nil {
136134
return errors.Wrapf(err, "failed to set up clientset")

cli/cmd/cluster.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,10 @@ func clusterExists(ctxLogger *logrus.Entry, ex *terraform.Executor) bool {
148148
}
149149

150150
type controlplaneUpdater struct {
151-
kubeconfigPath string
152-
assetDir string
153-
ctxLogger logrus.Entry
154-
ex terraform.Executor
151+
kubeconfig []byte
152+
assetDir string
153+
ctxLogger logrus.Entry
154+
ex terraform.Executor
155155
}
156156

157157
func (c controlplaneUpdater) getControlplaneChart(name string) (*chart.Chart, error) {
@@ -187,7 +187,7 @@ func (c controlplaneUpdater) upgradeComponent(component string) {
187187
"component": component,
188188
})
189189

190-
actionConfig, err := util.HelmActionConfig("kube-system", c.kubeconfigPath)
190+
actionConfig, err := util.HelmActionConfig("kube-system", c.kubeconfig)
191191
if err != nil {
192192
ctxLogger.Fatalf("Failed initializing helm: %v", err)
193193
}

cli/cmd/component-apply.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func runApply(cmd *cobra.Command, args []string) {
6868
}
6969
}
7070

71-
func applyComponents(lokoConfig *config.Config, kubeconfig string, componentNames ...string) error {
71+
func applyComponents(lokoConfig *config.Config, kubeconfig []byte, componentNames ...string) error {
7272
for _, componentName := range componentNames {
7373
fmt.Printf("Applying component '%s'...\n", componentName)
7474

cli/cmd/component-delete.go

Lines changed: 2 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,14 @@
1515
package cmd
1616

1717
import (
18-
"context"
1918
"fmt"
20-
"io/ioutil"
2119
"strings"
2220

2321
log "github.com/sirupsen/logrus"
2422
"github.com/spf13/cobra"
25-
"helm.sh/helm/v3/pkg/action"
26-
"k8s.io/apimachinery/pkg/api/errors"
27-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2823

2924
"github.com/kinvolk/lokomotive/pkg/components"
3025
"github.com/kinvolk/lokomotive/pkg/components/util"
31-
"github.com/kinvolk/lokomotive/pkg/k8sutil"
3226
)
3327

3428
var componentDeleteCmd = &cobra.Command{
@@ -102,11 +96,11 @@ func runDelete(cmd *cobra.Command, args []string) {
10296
}
10397
}
10498

105-
func deleteComponents(kubeconfig string, componentObjects ...components.Component) error {
99+
func deleteComponents(kubeconfig []byte, componentObjects ...components.Component) error {
106100
for _, compObj := range componentObjects {
107101
fmt.Printf("Deleting component '%s'...\n", compObj.Metadata().Name)
108102

109-
if err := deleteHelmRelease(compObj, kubeconfig, deleteNamespace); err != nil {
103+
if err := util.UninstallComponent(compObj, kubeconfig, deleteNamespace); err != nil {
110104
return err
111105
}
112106

@@ -118,75 +112,3 @@ func deleteComponents(kubeconfig string, componentObjects ...components.Componen
118112

119113
return nil
120114
}
121-
122-
// deleteComponent deletes a component.
123-
func deleteHelmRelease(c components.Component, kubeconfig string, deleteNSBool bool) error {
124-
name := c.Metadata().Name
125-
if name == "" {
126-
// This should never fail in real user usage, if this does that means the component was not
127-
// created with all the needed information.
128-
panic(fmt.Errorf("component name is empty"))
129-
}
130-
131-
ns := c.Metadata().Namespace
132-
if ns == "" {
133-
// This should never fail in real user usage, if this does that means the component was not
134-
// created with all the needed information.
135-
panic(fmt.Errorf("component %s namespace is empty", name))
136-
}
137-
138-
cfg, err := util.HelmActionConfig(ns, kubeconfig)
139-
if err != nil {
140-
return fmt.Errorf("failed preparing helm client: %w", err)
141-
}
142-
143-
history := action.NewHistory(cfg)
144-
// Check if the component's release exists. If it does only then proceed to delete.
145-
//
146-
// Note: It is assumed that this call will return error only when the release does not exist.
147-
// The error check is ignored to make `lokoctl component delete ..` idempotent.
148-
// We rely on the fact that the 'component name' == 'release name'. Since component's name is
149-
// hardcoded and unlikely to change release name won't change as well. And they will be
150-
// consistent if installed by lokoctl. So it is highly unlikely that following call will return
151-
// any other error than "release not found".
152-
if _, err := history.Run(name); err == nil {
153-
uninstall := action.NewUninstall(cfg)
154-
155-
// Ignore the err when we have deleted the release already or it does not exist for some reason.
156-
if _, err := uninstall.Run(name); err != nil {
157-
return err
158-
}
159-
}
160-
161-
if deleteNSBool {
162-
if err := deleteNS(ns, kubeconfig); err != nil {
163-
return err
164-
}
165-
}
166-
167-
return nil
168-
}
169-
170-
func deleteNS(ns string, kubeconfig string) error {
171-
kubeconfigContent, err := ioutil.ReadFile(kubeconfig) // #nosec G304
172-
if err != nil {
173-
return fmt.Errorf("failed to read kubeconfig file: %v", err)
174-
}
175-
176-
cs, err := k8sutil.NewClientset(kubeconfigContent)
177-
if err != nil {
178-
return err
179-
}
180-
181-
// Delete the manually created namespace which was not created by helm.
182-
if err = cs.CoreV1().Namespaces().Delete(context.TODO(), ns, metav1.DeleteOptions{}); err != nil {
183-
// Ignore error when the namespace does not exist.
184-
if errors.IsNotFound(err) {
185-
return nil
186-
}
187-
188-
return err
189-
}
190-
191-
return nil
192-
}

cli/cmd/health.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package cmd
1616

1717
import (
1818
"fmt"
19-
"io/ioutil"
2019
"os"
2120
"text/tabwriter"
2221

@@ -28,10 +27,9 @@ import (
2827
)
2928

3029
var healthCmd = &cobra.Command{
31-
Use: "health",
32-
Short: "Get the health of a cluster",
33-
Run: runHealth,
34-
PersistentPreRunE: doesKubeconfigExist,
30+
Use: "health",
31+
Short: "Get the health of a cluster",
32+
Run: runHealth,
3533
}
3634

3735
func init() {
@@ -49,12 +47,7 @@ func runHealth(cmd *cobra.Command, args []string) {
4947
contextLogger.Fatalf("Error in finding kubeconfig file: %s", err)
5048
}
5149

52-
kubeconfigContent, err := ioutil.ReadFile(kubeconfig) // #nosec G304
53-
if err != nil {
54-
contextLogger.Fatalf("Failed to read kubeconfig file: %v", err)
55-
}
56-
57-
cs, err := k8sutil.NewClientset(kubeconfigContent)
50+
cs, err := k8sutil.NewClientset(kubeconfig)
5851
if err != nil {
5952
contextLogger.Fatalf("Error in creating setting up Kubernetes client: %q", err)
6053
}

cli/cmd/utils.go

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ package cmd
1616

1717
import (
1818
"fmt"
19+
"io/ioutil"
1920
"os"
2021
"path/filepath"
2122

2223
"github.com/hashicorp/hcl/v2"
2324
"github.com/mitchellh/go-homedir"
24-
"github.com/spf13/cobra"
2525
"github.com/spf13/viper"
2626

2727
"github.com/kinvolk/lokomotive/pkg/backend"
@@ -93,17 +93,20 @@ func getAssetDir() (string, error) {
9393
return cfg.Meta().AssetDir, nil
9494
}
9595

96-
// expandKubeconfigPath tries to expand ~ in the given kubeconfig path.
97-
// However, if that fails, it just returns original path as the best effort.
98-
func expandKubeconfigPath(path string) string {
96+
func getKubeconfig() ([]byte, error) {
97+
path, err := getKubeconfigPath()
98+
if err != nil {
99+
return nil, fmt.Errorf("failed getting kubeconfig path: %w", err)
100+
}
101+
99102
if expandedPath, err := homedir.Expand(path); err == nil {
100-
return expandedPath
103+
path = expandedPath
101104
}
102105

103106
// homedir.Expand is too restrictive for the ~ prefix,
104107
// i.e., it errors on "~somepath" which is a valid path,
105-
// so just return the original path.
106-
return path
108+
// so just read from the original path.
109+
return ioutil.ReadFile(path) // #nosec G304
107110
}
108111

109112
// getKubeconfig finds the kubeconfig to be used. The precedence is the following:
@@ -113,7 +116,7 @@ func expandKubeconfigPath(path string) string {
113116
// - Asset directory from cluster configuration.
114117
// - KUBECONFIG environment variable.
115118
// - ~/.kube/config path, which is the default for kubectl.
116-
func getKubeconfig() (string, error) {
119+
func getKubeconfigPath() (string, error) {
117120
assetKubeconfig, err := assetsKubeconfigPath()
118121
if err != nil {
119122
return "", fmt.Errorf("reading kubeconfig path from configuration failed: %w", err)
@@ -126,18 +129,13 @@ func getKubeconfig() (string, error) {
126129
defaultKubeconfigPath,
127130
}
128131

129-
return expandKubeconfigPath(pickString(paths...)), nil
130-
}
131-
132-
// pickString returns first non-empty string.
133-
func pickString(options ...string) string {
134-
for _, option := range options {
135-
if option != "" {
136-
return option
132+
for _, path := range paths {
133+
if path != "" {
134+
return path, nil
137135
}
138136
}
139137

140-
return ""
138+
return "", nil
141139
}
142140

143141
// assetsKubeconfigPath reads the lokocfg configuration and returns
@@ -161,19 +159,6 @@ func assetsKubeconfig(assetDir string) string {
161159
return filepath.Join(assetDir, "cluster-assets", "auth", "kubeconfig")
162160
}
163161

164-
// doesKubeconfigExist checks if the kubeconfig provided by user exists
165-
func doesKubeconfigExist(*cobra.Command, []string) error {
166-
var err error
167-
kubeconfig, err := getKubeconfig()
168-
if err != nil {
169-
return err
170-
}
171-
if _, err = os.Stat(kubeconfig); os.IsNotExist(err) {
172-
return fmt.Errorf("Kubeconfig %q not found", kubeconfig)
173-
}
174-
return err
175-
}
176-
177162
func getLokoConfig() (*config.Config, hcl.Diagnostics) {
178163
return config.LoadConfig(viper.GetString("lokocfg"), viper.GetString("lokocfg-vars"))
179164
}

0 commit comments

Comments
 (0)