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 all 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)
}
4 changes: 2 additions & 2 deletions cmd/minikube/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
"k8s.io/minikube/pkg/minikube/audit"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/detect"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/out"
Expand Down Expand Up @@ -80,7 +80,7 @@ func Execute() {
defer audit.Log(time.Now())

// Check whether this is a windows binary (.exe) running inisde WSL.
if runtime.GOOS == "windows" && driver.IsMicrosoftWSL() {
if runtime.GOOS == "windows" && detect.IsMicrosoftWSL() {
var found = false
for _, a := range os.Args {
if a == "--force" {
Expand Down
117 changes: 2 additions & 115 deletions pkg/addons/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,17 @@ import (
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/machine"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/out/register"
"k8s.io/minikube/pkg/minikube/reason"
"k8s.io/minikube/pkg/minikube/storageclass"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/minikube/sysinit"
"k8s.io/minikube/pkg/util/retry"
)

// defaultStorageClassProvisioner is the name of the default storage class provisioner
const 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 @@ -174,7 +171,6 @@ https://github.com/kubernetes/minikube/issues/7332`, out.V{"driver_name": cc.Dri
}
}

// TODO(r2d4): config package should not reference API, pull this out
api, err := machine.NewAPIClient()
if err != nil {
return errors.Wrap(err, "machine client")
Expand Down Expand Up @@ -279,75 +275,10 @@ func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon,
return retry.Expo(apply, 250*time.Millisecond, 2*time.Minute)
}

// enableOrDisableStorageClasses enables or disables storage classes
func enableOrDisableStorageClasses(cc *config.ClusterConfig, name string, val string) error {
klog.Infof("enableOrDisableStorageClasses %s=%v on %q", name, val, cc.Name)
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrap(err, "Error parsing boolean")
}

class := defaultStorageClassProvisioner
if name == "storage-provisioner-gluster" {
class = "glusterfile"
}

api, err := machine.NewAPIClient()
if err != nil {
return errors.Wrap(err, "machine client")
}
defer api.Close()

cp, err := config.PrimaryControlPlane(cc)
if err != nil {
return errors.Wrap(err, "getting control plane")
}
if !machine.IsRunning(api, config.MachineName(*cc, cp)) {
klog.Warningf("%q is not running, writing %s=%v to disk and skipping enablement", config.MachineName(*cc, cp), name, val)
return EnableOrDisableAddon(cc, name, val)
}

storagev1, err := storageclass.GetStoragev1(cc.Name)
if err != nil {
return errors.Wrapf(err, "Error getting storagev1 interface %v ", err)
}

if enable {
// Only StorageClass for 'name' should be marked as default
err = storageclass.SetDefaultStorageClass(storagev1, class)
if err != nil {
return errors.Wrapf(err, "Error making %s the default storage class", class)
}
} else {
// Unset the StorageClass as default
err := storageclass.DisableDefaultStorageClass(storagev1, class)
if err != nil {
return errors.Wrapf(err, "Error disabling %s as the default storage class", class)
}
}

return EnableOrDisableAddon(cc, name, val)
}

func verifyAddonStatus(cc *config.ClusterConfig, name string, val string) error {
return verifyAddonStatusInternal(cc, name, val, "kube-system")
}

func verifyGCPAuthAddon(cc *config.ClusterConfig, name string, val string) error {
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
err = verifyAddonStatusInternal(cc, name, val, "gcp-auth")

if enable && err == nil {
out.Styled(style.Notice, "Your GCP credentials will now be mounted into every pod created in the {{.name}} cluster.", out.V{"name": cc.Name})
out.Styled(style.Notice, "If you don't want your credentials mounted into a specific pod, add a label with the `gcp-auth-skip-secret` key to your pod configuration.")
}

return err
}

func verifyAddonStatusInternal(cc *config.ClusterConfig, name string, val string, ns string) error {
klog.Infof("Verifying addon %s=%s in %q", name, val, cc.Name)
enable, err := strconv.ParseBool(val)
Expand Down Expand Up @@ -444,47 +375,3 @@ func Start(wg *sync.WaitGroup, cc *config.ClusterConfig, toEnable map[string]boo
}
}
}

// enableOrDisableAutoPause enables the service after the config was copied by generic enble
func enableOrDisableAutoPause(cc *config.ClusterConfig, name string, val string) error {
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
out.Infof("auto-pause addon is an alpha feature and still in early development. Please file issues to help us make it better.")
out.Infof("https://github.com/kubernetes/minikube/labels/co%2Fauto-pause")

if !driver.IsKIC(cc.Driver) || runtime.GOARCH != "amd64" {
exit.Message(reason.Usage, `auto-pause currently is only supported on docker driver/docker runtime/amd64. Track progress of others here: https://github.com/kubernetes/minikube/issues/10601`)
}
co := mustload.Running(cc.Name)
if enable {
if err := sysinit.New(co.CP.Runner).EnableNow("auto-pause"); err != nil {
klog.ErrorS(err, "failed to enable", "service", "auto-pause")
}
}

port := co.CP.Port // api server port
if enable { // if enable then need to calculate the forwarded port
port = constants.AutoPauseProxyPort
if driver.NeedsPortForward(cc.Driver) {
port, err = oci.ForwardedPort(cc.Driver, cc.Name, port)
if err != nil {
klog.ErrorS(err, "failed to get forwarded port for", "auto-pause port", port)
}
}
}

updated, err := kubeconfig.UpdateEndpoint(cc.Name, co.CP.Hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
if err != nil {
klog.ErrorS(err, "failed to update kubeconfig", "auto-pause proxy endpoint")
return err
}
if updated {
klog.Infof("%s context has been updated to point to auto-pause proxy %s:%s", cc.Name, co.CP.Hostname, co.CP.Port)
} else {
klog.Info("no need to update kube-context for auto-pause proxy")
}

return nil
}
79 changes: 79 additions & 0 deletions pkg/addons/addons_autopause.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Copyright 2021 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package addons

import (
"runtime"
"strconv"

"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/constants"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/kubeconfig"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/reason"
"k8s.io/minikube/pkg/minikube/sysinit"
)

// enableOrDisableAutoPause enables the service after the config was copied by generic enble
func enableOrDisableAutoPause(cc *config.ClusterConfig, name string, val string) error {
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
out.Infof("auto-pause addon is an alpha feature and still in early development. Please file issues to help us make it better.")
out.Infof("https://github.com/kubernetes/minikube/labels/co%2Fauto-pause")

if !driver.IsKIC(cc.Driver) || runtime.GOARCH != "amd64" {
exit.Message(reason.Usage, `auto-pause currently is only supported on docker driver/docker runtime/amd64. Track progress of others here: https://github.com/kubernetes/minikube/issues/10601`)
}
co := mustload.Running(cc.Name)
if enable {
if err := sysinit.New(co.CP.Runner).EnableNow("auto-pause"); err != nil {
klog.ErrorS(err, "failed to enable", "service", "auto-pause")
}
}

port := co.CP.Port // api server port
if enable { // if enable then need to calculate the forwarded port
port = constants.AutoPauseProxyPort
if driver.NeedsPortForward(cc.Driver) {
port, err = oci.ForwardedPort(cc.Driver, cc.Name, port)
if err != nil {
klog.ErrorS(err, "failed to get forwarded port for", "auto-pause port", port)
}
}
}

updated, err := kubeconfig.UpdateEndpoint(cc.Name, co.CP.Hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
if err != nil {
klog.ErrorS(err, "failed to update kubeconfig", "auto-pause proxy endpoint")
return err
}
if updated {
klog.Infof("%s context has been updated to point to auto-pause proxy %s:%s", cc.Name, co.CP.Hostname, co.CP.Port)
} else {
klog.Info("no need to update kube-context for auto-pause proxy")
}

return nil
}
53 changes: 30 additions & 23 deletions pkg/addons/gcpauth/enable.go → pkg/addons/addons_gcpauth.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020 The Kubernetes Authors All rights reserved.
Copyright 2021 The Kubernetes Authors All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,21 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package gcpauth
package addons

import (
"bytes"
"context"
"io/ioutil"
"os"
"os/exec"
"path"
"strconv"

"github.com/pkg/errors"
"golang.org/x/oauth2/google"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/detect"
"k8s.io/minikube/pkg/minikube/exit"
"k8s.io/minikube/pkg/minikube/mustload"
"k8s.io/minikube/pkg/minikube/out"
Expand All @@ -41,19 +40,23 @@ const (
projectPath = "/var/lib/minikube/google_cloud_project"
)

// EnableOrDisable enables or disables the metadata addon depending on the val parameter
func EnableOrDisable(cfg *config.ClusterConfig, name string, val string) error {
// enableOrDisableGCPAuth enables or disables the gcp-auth addon depending on the val parameter
func enableOrDisableGCPAuth(cfg *config.ClusterConfig, name string, val string) error {
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
if enable {
return enableAddon(cfg)
return enableAddonGCPAuth(cfg)
}
return disableAddon(cfg)
return disableAddonGCPAuth(cfg)
}

func enableAddon(cfg *config.ClusterConfig) error {
func enableAddonGCPAuth(cfg *config.ClusterConfig) error {
if !Force && detect.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
Expand All @@ -65,20 +68,9 @@ func enableAddon(cfg *config.ClusterConfig) error {
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 {
// Cloud Shell sends credential files to an unusual location, let's check that location
// For example, CLOUDSDK_CONFIG=/tmp/tmp.cflmvysoQE
if e := os.Getenv("CLOUDSDK_CONFIG"); e != "" {
credFile := path.Join(e, "application_default_credentials.json")
b, err := ioutil.ReadFile(credFile)
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.")
}
creds.JSON = b
} else {
// We don't currently support authentication through the metadata server
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.")
}
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")
Expand Down Expand Up @@ -114,7 +106,7 @@ or set the GOOGLE_CLOUD_PROJECT environment variable.`)
return r.Copy(emptyFile)
}

func disableAddon(cfg *config.ClusterConfig) error {
func disableAddonGCPAuth(cfg *config.ClusterConfig) error {
// Grab command runner from running cluster
cc := mustload.Running(cfg.Name)
r := cc.CP.Runner
Expand All @@ -134,3 +126,18 @@ func disableAddon(cfg *config.ClusterConfig) error {

return nil
}

func verifyGCPAuthAddon(cc *config.ClusterConfig, name string, val string) error {
enable, err := strconv.ParseBool(val)
if err != nil {
return errors.Wrapf(err, "parsing bool: %s", name)
}
err = verifyAddonStatusInternal(cc, name, val, "gcp-auth")

if enable && err == nil {
out.Styled(style.Notice, "Your GCP credentials will now be mounted into every pod created in the {{.name}} cluster.", out.V{"name": cc.Name})
out.Styled(style.Notice, "If you don't want your credentials mounted into a specific pod, add a label with the `gcp-auth-skip-secret` key to your pod configuration.")
}

return err
}
Loading