Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auto-detect gce and do not enable gcp auth addon #10730

Merged
merged 19 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/minikube/cmd/config/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var addonsEnableCmd = &cobra.Command{
addon := args[0]
// replace heapster as metrics-server because heapster is deprecated
if addon == "heapster" {
out.Styled(style.Waiting, "enable metrics-server addon instead of heapster addon because heapster is deprecated")
out.Styled(style.Waiting, "using metrics-server addon, heapster is deprecated")
addon = "metrics-server"
}
viper.Set(config.AddonImages, images)
Expand Down Expand Up @@ -76,5 +76,6 @@ var (
func init() {
addonsEnableCmd.Flags().StringVar(&images, "images", "", "Images used by this addon. Separated by commas.")
addonsEnableCmd.Flags().StringVar(&registries, "registries", "", "Registries used by this addon. Separated by commas.")
addonsEnableCmd.Flags().BoolVar(&addons.Force, "force", false, "If true, will perform potentially dangerous operations. Use with discretion.")
AddonsCmd.AddCommand(addonsEnableCmd)
}
103 changes: 101 additions & 2 deletions pkg/addons/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ limitations under the License.
package addons

import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"path"
"runtime"
"sort"
Expand All @@ -28,6 +32,7 @@ import (

"github.com/pkg/errors"
"github.com/spf13/viper"
"golang.org/x/oauth2/google"

"k8s.io/klog/v2"
"k8s.io/minikube/pkg/drivers/kic/oci"
Expand All @@ -47,11 +52,18 @@ import (
"k8s.io/minikube/pkg/minikube/storageclass"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/minikube/sysinit"
"k8s.io/minikube/pkg/util"
"k8s.io/minikube/pkg/util/retry"
)

// defaultStorageClassProvisioner is the name of the default storage class provisioner
const defaultStorageClassProvisioner = "standard"
const (
credentialsPath = "/var/lib/minikube/google_application_credentials.json"
projectPath = "/var/lib/minikube/google_cloud_project"
defaultStorageClassProvisioner = "standard"
)

// Force is used to override checks for addons
var Force bool = false

// RunCallbacks runs all actions associated to an addon, but does not set it (thread-safe)
func RunCallbacks(cc *config.ClusterConfig, name string, value string) error {
Expand Down Expand Up @@ -488,3 +500,90 @@ func enableOrDisableAutoPause(cc *config.ClusterConfig, name string, val string)

return nil
}

// enableOrDisableGCPAuth enables or disables the gcp-auth addon depending on the val parameter
func enableOrDisableGCPAuth(cfg *config.ClusterConfig, name string, val string) error {
sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
if enable {
return enableAddonGCPAuth(cfg)
}
return disableAddonGCPAuth(cfg)
}

func enableAddonGCPAuth(cfg *config.ClusterConfig) error {
if !Force && util.IsOnGCE() {
exit.Message(reason.InternalCredsNotFound, "It seems that you are running in GCE, which means authentication should work without the GCP Auth addon. If you would still like to authenticate using a credentials file, use the --force flag.")
}

// Grab command runner from running cluster
cc := mustload.Running(cfg.Name)
r := cc.CP.Runner

// Grab credentials from where GCP would normally look
ctx := context.Background()
creds, err := google.FindDefaultCredentials(ctx)
if err != nil {
exit.Message(reason.InternalCredsNotFound, "Could not find any GCP credentials. Either run `gcloud auth application-default login` or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the path of your credentials file.")
}

// Don't mount in empty credentials file
if creds.JSON == nil {
exit.Message(reason.InternalCredsNotFound, "Could not find any GCP credentials. Either run `gcloud auth application-default login` or set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the path of your credentials file.")
}

f := assets.NewMemoryAssetTarget(creds.JSON, credentialsPath, "0444")

err = r.Copy(f)
if err != nil {
return err
}

// First check if the project env var is explicitly set
projectEnv := os.Getenv("GOOGLE_CLOUD_PROJECT")
if projectEnv != "" {
f := assets.NewMemoryAssetTarget([]byte(projectEnv), projectPath, "0444")
return r.Copy(f)
}

// We're currently assuming gcloud is installed and in the user's path
project, err := exec.Command("gcloud", "config", "get-value", "project").Output()
if err == nil && len(project) > 0 {
f := assets.NewMemoryAssetTarget(bytes.TrimSpace(project), projectPath, "0444")
return r.Copy(f)
}

out.WarningT("Could not determine a Google Cloud project, which might be ok.")
out.Styled(style.Tip, `To set your Google Cloud project, run:

gcloud config set project <project name>

or set the GOOGLE_CLOUD_PROJECT environment variable.`)

// Copy an empty file in to avoid errors about missing files
emptyFile := assets.NewMemoryAssetTarget([]byte{}, projectPath, "0444")
return r.Copy(emptyFile)
}

func disableAddonGCPAuth(cfg *config.ClusterConfig) error {
// Grab command runner from running cluster
cc := mustload.Running(cfg.Name)
r := cc.CP.Runner

// Clean up the files generated when enabling the addon
creds := assets.NewMemoryAssetTarget([]byte{}, credentialsPath, "0444")
err := r.Remove(creds)
if err != nil {
return err
}

project := assets.NewMemoryAssetTarget([]byte{}, projectPath, "0444")
err = r.Remove(project)
if err != nil {
return err
}

return nil
}
3 changes: 1 addition & 2 deletions pkg/addons/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package addons

import (
"k8s.io/minikube/pkg/addons/gcpauth"
"k8s.io/minikube/pkg/minikube/config"
)

Expand Down Expand Up @@ -175,7 +174,7 @@ var Addons = []*Addon{
{
name: "gcp-auth",
set: SetBool,
callbacks: []setFn{gcpauth.EnableOrDisable, EnableOrDisableAddon, verifyGCPAuthAddon},
callbacks: []setFn{enableOrDisableGCPAuth, EnableOrDisableAddon, verifyGCPAuthAddon},
},
{
name: "volumesnapshots",
Expand Down
136 changes: 0 additions & 136 deletions pkg/addons/gcpauth/enable.go

This file was deleted.

3 changes: 3 additions & 0 deletions pkg/minikube/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ func Start(starter Starter, apiServer bool) (*kubeconfig.Settings, error) {

// enable addons, both old and new!
if starter.ExistingAddons != nil {
if viper.GetBool("force") {
addons.Force = true
}
wg.Add(1)
go addons.Start(&wg, starter.Cfg, starter.ExistingAddons, config.AddonList)
}
Expand Down
15 changes: 15 additions & 0 deletions pkg/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package util

import (
"fmt"
"net/http"
"os"
"os/user"
"path/filepath"
Expand Down Expand Up @@ -109,3 +110,17 @@ func MaybeChownDirRecursiveToMinikubeUser(dir string) error {
func ParseKubernetesVersion(version string) (semver.Version, error) {
return semver.Make(version[1:])
}

// IsOnGCE determines whether minikube is currently running on GCE.
func IsOnGCE() bool {
sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
resp, err := http.Get("http://metadata.google.internal")
if err != nil {
return false
}

if resp.Header.Get("Metadata-Flavor") == "Google" {
return true
}

return false
}
1 change: 1 addition & 0 deletions site/content/en/docs/commands/addons.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ minikube addons enable dashboard
### Options

```
--force If true, will perform potentially dangerous operations. Use with discretion.
sharifelgamal marked this conversation as resolved.
Show resolved Hide resolved
--images string Images used by this addon. Separated by commas.
--registries string Registries used by this addon. Separated by commas.
```
Expand Down
28 changes: 27 additions & 1 deletion test/integration/addons_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (

"github.com/hashicorp/go-retryablehttp"
"k8s.io/minikube/pkg/kapi"
"k8s.io/minikube/pkg/util"
"k8s.io/minikube/pkg/util/retry"
)

Expand All @@ -58,18 +59,43 @@ func TestAddons(t *testing.T) {
t.Fatalf("Failed setting GOOGLE_CLOUD_PROJECT env var: %v", err)
}

args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=olm", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, StartArgs()...)
args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=olm", "--addons=volumesnapshots", "--addons=csi-hostpath-driver"}, StartArgs()...)
if !(runtime.GOOS == "darwin" && KicDriver()) { // macos docker driver does not support ingress
args = append(args, "--addons=ingress")
}
if !arm64Platform() {
args = append(args, "--addons=helm-tiller")
}
if !util.IsOnGCE() {
args = append(args, "--addons=gcp-auth")
}
rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
if err != nil {
t.Fatalf("%s failed: %v", rr.Command(), err)
}

// If we're running the integration tests on GCE, which is frequently the case, first check to make sure we exit out properly,
// then use force to actually test using creds.
if util.IsOnGCE() {
args = append([]string{"addons", "enable", "gcp-auth"}, StartArgs()...)
rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
if err == nil {
t.Errorf("Expected error but didn't get one. command %v, output %v", rr.Command(), rr.Output())
} else {
if !strings.Contains(rr.Output(), "It seems that you are running in GCE") {
t.Errorf("Unexpected error message: %v", rr.Output())
} else {
// ok, use force here since we are in GCE
// do not use --force unless absolutely necessary
args = append(args, "--force")
rr, err := Run(t, exec.CommandContext(ctx, Target(), args...))
if err != nil {
t.Errorf("%s failed: %v", rr.Command(), err)
}
}
}
}

// Parallelized tests
t.Run("parallel", func(t *testing.T) {
tests := []struct {
Expand Down
Loading