Skip to content

Commit

Permalink
Make sure gcp-auth addon can be enabled on startup (#9318)
Browse files Browse the repository at this point in the history
* fix documentation for gcp-auth addon

* make sure kube-system pods are up before enabling gcp-auth

* fix lint

* add failurePolicy for webhook

* only install addons if asked

* better comment

* slightly less hacky code

* defer addons properly

* simplify code for performance
  • Loading branch information
sharifelgamal committed Sep 29, 2020
1 parent 09dd4b7 commit ff051f9
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 20 deletions.
7 changes: 7 additions & 0 deletions deploy/addons/gcp-auth/gcp-auth-webhook.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,17 @@ metadata:
app: gcp-auth
webhooks:
- name: gcp-auth-mutate.k8s.io
failurePolicy: Fail
objectSelector:
matchExpressions:
- key: gcp-auth-skip-secret
operator: DoesNotExist
namespaceSelector:
matchExpressions:
- key: name
operator: NotIn
values:
- kube-system
sideEffects: None
admissionReviewVersions: ["v1","v1beta1"]
clientConfig:
Expand Down
40 changes: 36 additions & 4 deletions pkg/addons/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,18 @@ func verifyAddonStatus(cc *config.ClusterConfig, name string, val string) error
}

func verifyGCPAuthAddon(cc *config.ClusterConfig, name string, val string) error {
return verifyAddonStatusInternal(cc, name, val, "gcp-auth")
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.T(style.Notice, "Your GCP credentials will now be mounted into every pod created in the {{.name}} cluster.", out.V{"name": cc.Name})
out.T(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 {
Expand Down Expand Up @@ -394,24 +405,45 @@ func Start(wg *sync.WaitGroup, cc *config.ClusterConfig, toEnable map[string]boo

var awg sync.WaitGroup

defer func() { // making it show after verifications( not perfect till #7613 is closed)
enabledAddons := []string{}
deferredAddons := []string{}

defer func() { // making it show after verifications (see #7613)
register.Reg.SetStep(register.EnablingAddons)
out.T(style.AddonEnable, "Enabled addons: {{.addons}}", out.V{"addons": strings.Join(toEnableList, ", ")})
out.T(style.AddonEnable, "Enabled addons: {{.addons}}", out.V{"addons": strings.Join(enabledAddons, ", ")})
}()
for _, a := range toEnableList {
if a == "gcp-auth" {
deferredAddons = append(deferredAddons, a)
continue
}

awg.Add(1)
go func(name string) {
err := RunCallbacks(cc, name, "true")
if err != nil {
out.WarningT("Enabling '{{.name}}' returned an error: {{.error}}", out.V{"name": name, "error": err})
} else {
enabledAddons = append(enabledAddons, name)
}
awg.Done()
}(a)
}

// Wait until all of the addons are enabled before updating the config (not thread safe)
awg.Wait()
for _, a := range toEnableList {

// Now run the deferred addons
for _, a := range deferredAddons {
err := RunCallbacks(cc, a, "true")
if err != nil {
out.WarningT("Enabling '{{.name}}' returned an error: {{.error}}", out.V{"name": a, "error": err})
} else {
enabledAddons = append(enabledAddons, a)
}
}

for _, a := range enabledAddons {
if err := Set(cc, a, "true"); err != nil {
glog.Errorf("store failed: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/addons/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ var Addons = []*Addon{
{
name: "gcp-auth",
set: SetBool,
callbacks: []setFn{gcpauth.EnableOrDisable, enableOrDisableAddon, verifyGCPAuthAddon, gcpauth.DisplayAddonMessage},
callbacks: []setFn{gcpauth.EnableOrDisable, enableOrDisableAddon, verifyGCPAuthAddon},
},
{
name: "volumesnapshots",
Expand Down
15 changes: 1 addition & 14 deletions pkg/addons/gcpauth/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func enableAddon(cfg *config.ClusterConfig) error {
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 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 @@ -116,16 +116,3 @@ func disableAddon(cfg *config.ClusterConfig) error {

return nil
}

// DisplayAddonMessage display an gcp auth addon specific message to the user
func DisplayAddonMessage(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 {
out.T(style.Notice, "Your GCP credentials will now be mounted into every pod created in the {{.name}} cluster.", out.V{"name": cfg.Name})
out.T(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 nil
}
2 changes: 1 addition & 1 deletion site/content/en/docs/handbook/addons/gcp-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ weight: 1
date: 2020-07-15
---

If you have a containerized GCP app with a Kubernetes yaml, you can automatically add your credentials to all your deployed pods dynamically with this minikube addon. You just need to have a credentials file, which can be generated with `gcloud auth login`. If you already have a json credentials file you want specify, use the GOOGLE_APPLICATION_CREDENTIALS environment variable.
If you have a containerized GCP app with a Kubernetes yaml, you can automatically add your credentials to all your deployed pods dynamically with this minikube addon. You just need to have a credentials file, which can be generated with `gcloud auth application-default login`. If you already have a json credentials file you want specify, use the GOOGLE_APPLICATION_CREDENTIALS environment variable.

- Start a cluster:
```
Expand Down

0 comments on commit ff051f9

Please sign in to comment.