Repository: kubernetes/minikube (go)

Issue:
feature: add doc URL to the addon list table
while reviwing this PR:https://github.com/kubernetes/minikube/pull/7603

since the URL will be different based on driver, it would be nice that if we have add the URL of the addon to the list, so they dont have to dig into the documentaiton and pain to find the URL for the regsiry

```
medmac@~/Desktop/md1 $ ./minikube-darwin-amd64 addons list
|-----------------------------|----------|--------------|
|         ADDON NAME          | PROFILE  |    STATUS    |
|-----------------------------|----------|--------------|
| dashboard                   | minikube | disabled     |
| default-storageclass        | minikube | enabled ✅   |
| efk                         | minikube | disabled     |
| freshpod                    | minikube | disabled     |
| gvisor                      | minikube | disabled     |
| helm-tiller                 | minikube | disabled     |
| ingress                     | minikube | disabled     |
| ingress-dns                 | minikube | disabled     |
| istio                       | minikube | disabled     |
| istio-provisioner           | minikube | disabled     |
| logviewer                   | minikube | disabled     |
| metrics-server              | minikube | disabled     |
| nvidia-driver-installer     | minikube | disabled     |
| nvidia-gpu-device-plugin    | minikube | disabled     |
| registry                    | minikube | enabled ✅   |
| registry-aliases            | minikube | disabled     |
| registry-creds              | minikube | disabled     |
| storage-provisioner         | minikube | enabled ✅   |
| storage-provisioner-gluster | minikube | disabled     |
|-----------------------------|----------|--------------|
```

Pull request description:
Add doc URL to the addon list table
<!-- 🎉 Thank you for contributing to minikube! 🎉 Here are some hints to get your PR merged faster:

1. Your PR title will be included in the release notes, choose it carefully
2. If the PR fixes an issue, add "fixes #<issue number>" to the description.
3. If the PR is a user interface change, please include a "before" and "after" example.
4. If the PR is a large design change, please include an enhancement proposal:
https://github.com/kubernetes/minikube/tree/master/enhancements
-->

Fixes #7731

I'd like to address two open thoughts:

1. I was unable to find docs for all addons. This might result in a new backlog item to create those docs?
2. Do we have some sort of short URL to replace the bulky `https://minikube.sigs.k8s.io/docs/` in the output below?

I'm very open to any feedback. Cheers!

## Before:

```plaintext
$ minikube addons list
|-----------------------------|--------------------------------|
|         ADDON NAME          |           MAINTAINER           |
|-----------------------------|--------------------------------|
| ambassador                  | third-party (ambassador)       |
| auto-pause                  | google                         |
| csi-hostpath-driver         | kubernetes                     |
| dashboard                   | kubernetes                     |
| default-storageclass        | kubernetes                     |
| efk                         | third-party (elastic)          |
| freshpod                    | google                         |
| gcp-auth                    | google                         |
| gvisor                      | google                         |
| helm-tiller                 | third-party (helm)             |
| ingress                     | unknown (third-party)          |
| ingress-dns                 | google                         |
| istio                       | third-party (istio)            |
| istio-provisioner           | third-party (istio)            |
| kong                        | third-party (Kong HQ)          |
| kubevirt                    | third-party (kubevirt)         |
| logviewer                   | unknown (third-party)          |
| metallb                     | third-party (metallb)          |
| metrics-server              | kubernetes                     |
| nvidia-driver-installer     | google                         |
| nvidia-gpu-device-plugin    | third-party (nvidia)           |
| olm                         | third-party (operator          |
|                             | framework)                     |
| pod-security-policy         | unknown (third-party)          |
| portainer                   | portainer.io                   |
| registry                    | google                         |
| registry-aliases            | unknown (third-party)          |
| registry-creds              | third-party (upmc enterprises) |
| storage-provisioner         | google                         |
| storage-provisioner-gluster | unknown (third-party)          |
| volumesnapshots             | kubernetes                     |
|-----------------------------|--------------------------------|
```

## After:

```text
|-----------------------------|--------------------------------|-----------------------------------------------------------------|
|         ADDON NAME          |           MAINTAINER           |                              DOCS                               |
|-----------------------------|--------------------------------|-----------------------------------------------------------------|
| ambassador                  | third-party (ambassador)       | n/a                                                             |
| auto-pause                  | google                         | n/a                                                             |
| csi-hostpath-driver         | kubernetes                     | n/a                                                             |
| dashboard                   | kubernetes                     | https://minikube.sigs.k8s.io/docs/handbook/dashboard/           |
| default-storageclass        | kubernetes                     | n/a                                                             |
| efk                         | third-party (elastic)          | n/a                                                             |
| freshpod                    | google                         | n/a                                                             |
| gcp-auth                    | google                         | https://minikube.sigs.k8s.io/docs/handbook/addons/gcp-auth/     |
| gvisor                      | google                         | n/a                                                             |
| helm-tiller                 | third-party (helm)             | n/a                                                             |
| ingress                     | unknown (third-party)          | n/a                                                             |
| ingress-dns                 | google                         | https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/  |
| istio                       | third-party (istio)            | n/a                                                             |
| istio-provisioner           | third-party (istio)            | n/a                                                             |
| kong                        | third-party (Kong HQ)          | https://minikube.sigs.k8s.io/docs/handbook/addons/kong-ingress/ |
| kubevirt                    | third-party (kubevirt)         | n/a                                                             |
| logviewer                   | unknown (third-party)          | n/a                                                             |
| metallb                     | third-party (metallb)          | n/a                                                             |
| metrics-server              | kubernetes                     | n/a                                                             |
| nvidia-driver-installer     | google                         | n/a                                                             |
| nvidia-gpu-device-plugin    | third-party (nvidia)           | n/a                                                             |
| olm                         | third-party (operator          | n/a                                                             |
|                             | framework)                     |                                                                 |
| pod-security-policy         | unknown (third-party)          | n/a                                                             |
| portainer                   | portainer.io                   | n/a                                                             |
| registry                    | google                         | n/a                                                             |
| registry-aliases            | unknown (third-party)          | n/a                                                             |
| registry-creds              | third-party (upmc enterprises) | n/a                                                             |
| storage-provisioner         | google                         | n/a                                                             |
| storage-provisioner-gluster | unknown (third-party)          | n/a                                                             |
| volumesnapshots             | kubernetes                     | n/a                                                             |
|-----------------------------|--------------------------------|-----------------------------------------------------------------|
```

Patch:
diff --git a/cmd/minikube/cmd/config/addons_list.go b/cmd/minikube/cmd/config/addons_list.go
index a76b9768c..d03dde177 100644
--- a/cmd/minikube/cmd/config/addons_list.go
+++ b/cmd/minikube/cmd/config/addons_list.go
@@ -36,6 +36,7 @@ import (
 )
 
 var addonListOutput string
+var addonPrintDocs bool
 
 // AddonListTemplate represents the addon list template
 type AddonListTemplate struct {
@@ -58,7 +59,7 @@ var addonsListCmd = &cobra.Command{
 		}
 		switch strings.ToLower(addonListOutput) {
 		case "list":
-			printAddonsList(cc)
+			printAddonsList(cc, addonPrintDocs)
 		case "json":
 			printAddonsJSON(cc)
 		default:
@@ -68,13 +69,8 @@ var addonsListCmd = &cobra.Command{
 }
 
 func init() {
-	addonsListCmd.Flags().StringVarP(
-		&addonListOutput,
-		"output",
-		"o",
-		"list",
-		`minikube addons list --output OUTPUT. json, list`)
-
+	addonsListCmd.Flags().StringVarP(&addonListOutput, "output", "o", "list", "minikube addons list --output OUTPUT. json, list")
+	addonsListCmd.Flags().BoolVarP(&addonPrintDocs, "docs", "d", false, "If true, print web links to addons' documentation if using --output=list (default).")
 	AddonsCmd.AddCommand(addonsListCmd)
 }
 
@@ -92,39 +88,56 @@ var stringFromStatus = func(addonStatus bool) string {
 	return "disabled"
 }
 
-var printAddonsList = func(cc *config.ClusterConfig) {
+var printAddonsList = func(cc *config.ClusterConfig, printDocs bool) {
 	addonNames := make([]string, 0, len(assets.Addons))
 	for addonName := range assets.Addons {
 		addonNames = append(addonNames, addonName)
 	}
 	sort.Strings(addonNames)
 
-	var tData [][]string
 	table := tablewriter.NewWriter(os.Stdout)
 	table.SetAutoFormatHeaders(true)
 	table.SetBorders(tablewriter.Border{Left: true, Top: true, Right: true, Bottom: true})
 	table.SetCenterSeparator("|")
+
+	// Create table header
+	var tHeader []string
 	if cc == nil {
-		table.SetHeader([]string{"Addon Name", "Maintainer"})
+		tHeader = []string{"Addon Name", "Maintainer"}
 	} else {
-		table.SetHeader([]string{"Addon Name", "Profile", "Status", "Maintainer"})
+		tHeader = []string{"Addon Name", "Profile", "Status", "Maintainer"}
 	}
+	if printDocs {
+		tHeader = append(tHeader, "Docs")
+	}
+	table.SetHeader(tHeader)
 
+	// Create table data
+	var tData [][]string
+	var temp []string
 	for _, addonName := range addonNames {
 		addonBundle := assets.Addons[addonName]
 		maintainer := addonBundle.Maintainer
 		if maintainer == "" {
-			maintainer = "unknown (third-party)"
+			maintainer = "3rd party (unknown)"
+		}
+		docs := addonBundle.Docs
+		if docs == "" {
+			docs = "n/a"
 		}
 		if cc == nil {
-			tData = append(tData, []string{addonName, maintainer})
-			continue
+			temp = []string{addonName, maintainer}
+		} else {
+			enabled := addonBundle.IsEnabled(cc)
+			temp = []string{addonName, cc.Name, fmt.Sprintf("%s %s", stringFromStatus(enabled), iconFromStatus(enabled)), maintainer}
 		}
-		enabled := addonBundle.IsEnabled(cc)
-		tData = append(tData, []string{addonName, cc.Name, fmt.Sprintf("%s %s", stringFromStatus(enabled), iconFromStatus(enabled)), maintainer})
+		if printDocs {
+			temp = append(temp, docs)
+		}
+		tData = append(tData, temp)
 	}
-
 	table.AppendBulk(tData)
+
 	table.Render()
 
 	v, _, err := config.ListProfiles()
diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go
index bc4b4a6cc..fe4b672cd 100755
--- a/pkg/minikube/assets/addons.go
+++ b/pkg/minikube/assets/addons.go
@@ -39,6 +39,7 @@ type Addon struct {
 	enabled    bool
 	addonName  string
 	Maintainer string
+	Docs       string
 	Images     map[string]string
 
 	// Registries currently only shows the default registry of images
@@ -52,12 +53,13 @@ type NetworkInfo struct {
 }
 
 // NewAddon creates a new Addon
-func NewAddon(assets []*BinAsset, enabled bool, addonName string, maintainer string, images map[string]string, registries map[string]string) *Addon {
+func NewAddon(assets []*BinAsset, enabled bool, addonName string, maintainer string, docs string, images map[string]string, registries map[string]string) *Addon {
 	a := &Addon{
 		Assets:     assets,
 		enabled:    enabled,
 		addonName:  addonName,
 		Maintainer: maintainer,
+		Docs:       docs,
 		Images:     images,
 		Registries: registries,
 	}
@@ -116,7 +118,7 @@ var Addons = map[string]*Addon{
 			"0640"),
 
 		// GuestPersistentDir
-	}, false, "auto-pause", "google", map[string]string{
+	}, false, "auto-pause", "Google", "", map[string]string{
 		"AutoPauseHook": "k8s-minikube/auto-pause-hook:v0.0.2@sha256:c76be418df5ca9c66d0d11c2c68461acbf4072c1cdfc17e64729c5ef4d5a4128",
 	}, map[string]string{
 		"AutoPauseHook": "gcr.io",
@@ -133,7 +135,7 @@ var Addons = map[string]*Addon{
 		MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640"),
 		MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640"),
 		MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640"),
-	}, false, "dashboard", "kubernetes", map[string]string{
+	}, false, "dashboard", "Kubernetes", "https://minikube.sigs.k8s.io/docs/handbook/dashboard/", map[string]string{
 		"Dashboard":      "kubernetesui/dashboard:v2.6.0@sha256:4af9580485920635d888efe1eddbd67e12f9d5d84dba87100e93feb4e46636b3",
 		"MetricsScraper": "kubernetesui/metrics-scraper:v1.0.8@sha256:76049887f07a0476dc93efc2d3569b9529bf982b22d29f356092ce206e98765c",
 	}, nil),
@@ -143,21 +145,21 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"storageclass.yaml",
 			"0640"),
-	}, true, "default-storageclass", "kubernetes", nil, nil),
+	}, true, "default-storageclass", "Kubernetes", "https://minikube.sigs.k8s.io/docs/handbook/persistent_volumes/", nil, nil),
 	"pod-security-policy": NewAddon([]*BinAsset{
 		MustBinAsset(addons.PodSecurityPolicyAssets,
 			"pod-security-policy/pod-security-policy.yaml.tmpl",
 			vmpath.GuestAddonsDir,
 			"pod-security-policy.yaml",
 			"0640"),
-	}, false, "pod-security-policy", "", nil, nil),
+	}, false, "pod-security-policy", "", "", nil, nil),
 	"storage-provisioner": NewAddon([]*BinAsset{
 		MustBinAsset(addons.StorageProvisionerAssets,
 			"storage-provisioner/storage-provisioner.yaml.tmpl",
 			vmpath.GuestAddonsDir,
 			"storage-provisioner.yaml",
 			"0640"),
-	}, true, "storage-provisioner", "google", map[string]string{
+	}, true, "storage-provisioner", "Google", "", map[string]string{
 		"StorageProvisioner": fmt.Sprintf("k8s-minikube/storage-provisioner:%s", version.GetStorageProvisionerVersion()),
 	}, map[string]string{
 		"StorageProvisioner": "gcr.io",
@@ -183,7 +185,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"storage-provisioner-glusterfile.yaml",
 			"0640"),
-	}, false, "storage-provisioner-gluster", "", map[string]string{
+	}, false, "storage-provisioner-gluster", "", "", map[string]string{
 		"Heketi":                 "heketi/heketi:10@sha256:76d5a6a3b7cf083d1e99efa1c15abedbc5c8b73bef3ade299ce9a4c16c9660f8",
 		"GlusterfileProvisioner": "gluster/glusterfile-provisioner:latest@sha256:9961a35cb3f06701958e202324141c30024b195579e5eb1704599659ddea5223",
 		"GlusterfsServer":        "nixpanic/glusterfs-server:pr_fake-disk@sha256:3c58ae9d4e2007758954879d3f4095533831eb757c64ca6a0e32d1fc53fb6034",
@@ -221,7 +223,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"kibana-svc.yaml",
 			"0640"),
-	}, false, "efk", "third-party (elastic)", map[string]string{
+	}, false, "efk", "3rd party (Elastic)", "", map[string]string{
 		"Elasticsearch":        "elasticsearch:v5.6.2@sha256:7e95b32a7a2aad0c0db5c881e4a1ce8b7e53236144ae9d9cfb5fbe5608af4ab2",
 		"FluentdElasticsearch": "fluentd-elasticsearch:v2.0.2@sha256:d0480bbf2d0de2344036fa3f7034cf7b4b98025a89c71d7f1f1845ac0e7d5a97",
 		"Alpine":               "alpine:3.6@sha256:66790a2b79e1ea3e1dabac43990c54aca5d1ddf268d9a5a0285e4167c8b24475",
@@ -237,7 +239,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"ingress-deploy.yaml",
 			"0640"),
-	}, false, "ingress", "", map[string]string{
+	}, false, "ingress", "", "https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/", map[string]string{
 		// https://github.com/kubernetes/ingress-nginx/blob/6d9a39eda7b180f27b34726d7a7a96d73808ce75/deploy/static/provider/kind/deploy.yaml#L417
 		"IngressController": "ingress-nginx/controller:v1.2.0@sha256:d8196e3bc1e72547c5dec66d6556c0ff92a23f6d0919b206be170bc90d5f9185",
 		// https://github.com/kubernetes/ingress-nginx/blob/fc38b9f2aa2d68ee00c417cf97e727b77a00c175/deploy/static/provider/kind/deploy.yaml#L621
@@ -253,7 +255,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"istio-operator.yaml",
 			"0640"),
-	}, false, "istio-provisioner", "third-party (istio)", map[string]string{
+	}, false, "istio-provisioner", "3rd party (Istio)", "https://istio.io/latest/docs/setup/platform-setup/minikube/", map[string]string{
 		"IstioOperator": "istio/operator:1.12.2@sha256:42c7609872882cb88728a1592561b4046dac6d05b6002cbdc815b84c86a24f08",
 	}, nil),
 	"istio": NewAddon([]*BinAsset{
@@ -262,14 +264,14 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"istio-default-profile.yaml",
 			"0640"),
-	}, false, "istio", "third-party (istio)", nil, nil),
+	}, false, "istio", "3rd party (Istio)", "https://istio.io/latest/docs/setup/platform-setup/minikube/", nil, nil),
 	"kong": NewAddon([]*BinAsset{
 		MustBinAsset(addons.KongAssets,
 			"kong/kong-ingress-controller.yaml.tmpl",
 			vmpath.GuestAddonsDir,
 			"kong-ingress-controller.yaml",
 			"0640"),
-	}, false, "kong", "third-party (Kong HQ)", map[string]string{
+	}, false, "kong", "3rd party (Kong HQ)", "https://minikube.sigs.k8s.io/docs/handbook/addons/kong-ingress/", map[string]string{
 		"Kong":        "kong:2.7@sha256:4d3e93207305ace881fe9e95ac27717b6fbdd9e0ec1873c34e94908a4f4c9335",
 		"KongIngress": "kong/kubernetes-ingress-controller:2.1.1@sha256:60e4102ab2da7f61e9c478747f0762d06a6166b5f300526b237ed7354c3cb4c8",
 	}, nil),
@@ -279,7 +281,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"pod.yaml",
 			"0640"),
-	}, false, "kubevirt", "third-party (kubevirt)", map[string]string{
+	}, false, "kubevirt", "3rd party (KubeVirt)", "https://minikube.sigs.k8s.io/docs/tutorials/kubevirt/", map[string]string{
 		"Kubectl": "bitnami/kubectl:1.17@sha256:de642e973d3d0ef60e4d0a1f92286a9fdae245535c5990d4762bbe86fcf95887",
 	}, nil),
 	"metrics-server": NewAddon([]*BinAsset{
@@ -303,7 +305,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"metrics-server-service.yaml",
 			"0640"),
-	}, false, "metrics-server", "kubernetes", map[string]string{
+	}, false, "metrics-server", "Kubernetes", "", map[string]string{
 		"MetricsServer": "metrics-server/metrics-server:v0.6.1@sha256:5ddc6458eb95f5c70bd13fdab90cbd7d6ad1066e5b528ad1dcb28b76c5fb2f00",
 	}, map[string]string{
 		"MetricsServer": "k8s.gcr.io",
@@ -319,7 +321,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"olm.yaml",
 			"0640"),
-	}, false, "olm", "third-party (operator framework)", map[string]string{
+	}, false, "olm", "3rd party (Operator Framework)", "", map[string]string{
 		"OLM": "operator-framework/olm@sha256:e74b2ac57963c7f3ba19122a8c31c9f2a0deb3c0c5cac9e5323ccffd0ca198ed",
 		// operator-framework/community-operators was deprecated: https://github.com/operator-framework/community-operators#repository-is-obsolete; switching to OperatorHub.io instead
 		"UpstreamCommunityOperators": "operatorhubio/catalog@sha256:e08a1cd21fe72dd1be92be738b4bf1515298206dac5479c17a4b3ed119e30bd4",
@@ -343,7 +345,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"registry-proxy.yaml",
 			"0640"),
-	}, false, "registry", "google", map[string]string{
+	}, false, "registry", "Google", "", map[string]string{
 		"Registry":          "registry:2.7.1@sha256:d5459fcb27aecc752520df4b492b08358a1912fcdfa454f7d2101d4b09991daa",
 		"KubeRegistryProxy": "google_containers/kube-registry-proxy:0.4@sha256:1040f25a5273de0d72c54865a8efd47e3292de9fb8e5353e3fa76736b854f2da",
 	}, map[string]string{
@@ -355,7 +357,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"registry-creds-rc.yaml",
 			"0640"),
-	}, false, "registry-creds", "third-party (upmc enterprises)", map[string]string{
+	}, false, "registry-creds", "3rd party (UPMC Enterprises)", "https://minikube.sigs.k8s.io/docs/handbook/registry/", map[string]string{
 		"RegistryCreds": "upmcenterprises/registry-creds:1.10@sha256:93a633d4f2b76a1c66bf19c664dbddc56093a543de6d54320f19f585ccd7d605",
 	}, nil),
 	"registry-aliases": NewAddon([]*BinAsset{
@@ -384,7 +386,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"patch-coredns-job.yaml",
 			"0640"),
-	}, false, "registry-aliases", "", map[string]string{
+	}, false, "registry-aliases", "", "", map[string]string{
 		"CoreDNSPatcher": "rhdevelopers/core-dns-patcher@sha256:9220ff32f690c3d889a52afb59ca6fcbbdbd99e5370550cc6fd249adea8ed0a9",
 		"Alpine":         "alpine:3.11@sha256:0bd0e9e03a022c3b0226667621da84fc9bf562a9056130424b5bfbd8bcb0397f",
 		"Pause":          "google_containers/pause:3.1@sha256:f78411e19d84a252e53bff71a4407a5686c46983a2c2eeed83929b888179acea",
@@ -398,7 +400,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"freshpod-rc.yaml",
 			"0640"),
-	}, false, "freshpod", "google", map[string]string{
+	}, false, "freshpod", "Google", "https://github.com/GoogleCloudPlatform/freshpod", map[string]string{
 		"FreshPod": "google-samples/freshpod:v0.0.1@sha256:b9efde5b509da3fd2959519c4147b653d0c5cefe8a00314e2888e35ecbcb46f9",
 	}, map[string]string{
 		"FreshPod": "gcr.io",
@@ -409,7 +411,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"nvidia-driver-installer.yaml",
 			"0640"),
-	}, false, "nvidia-driver-installer", "google", map[string]string{
+	}, false, "nvidia-driver-installer", "Google", "https://minikube.sigs.k8s.io/docs/tutorials/nvidia_gpu/", map[string]string{
 		"NvidiaDriverInstaller": "minikube-nvidia-driver-installer:e2d9b43228decf5d6f7dce3f0a85d390f138fa01",
 		"Pause":                 "pause:2.0@sha256:9ce5316f9752b8347484ab0f6778573af15524124d52b93230b9a0dcc987e73e",
 	}, map[string]string{
@@ -422,7 +424,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"nvidia-gpu-device-plugin.yaml",
 			"0640"),
-	}, false, "nvidia-gpu-device-plugin", "third-party (nvidia)", map[string]string{
+	}, false, "nvidia-gpu-device-plugin", "3rd party (Nvidia)", "https://minikube.sigs.k8s.io/docs/tutorials/nvidia_gpu/", map[string]string{
 		"NvidiaDevicePlugin": "nvidia-gpu-device-plugin@sha256:4b036e8844920336fa48f36edeb7d4398f426d6a934ba022848deed2edbf09aa",
 	}, map[string]string{
 		"NvidiaDevicePlugin": "k8s.gcr.io",
@@ -438,7 +440,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"logviewer-rbac.yaml",
 			"0640"),
-	}, false, "logviewer", "", map[string]string{
+	}, false, "logviewer", "", "", map[string]string{
 		"LogViewer": "ivans3/minikube-log-viewer:latest@sha256:75854f45305cc47d17b04c6c588fa60777391761f951e3a34161ddf1f1b06405",
 	}, nil),
 	"gvisor": NewAddon([]*BinAsset{
@@ -457,7 +459,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestGvisorDir,
 			constants.GvisorConfigTomlTargetName,
 			"0640"),
-	}, false, "gvisor", "google", map[string]string{
+	}, false, "gvisor", "Google", "https://github.com/kubernetes/minikube/blob/master/deploy/addons/gvisor/README.md", map[string]string{
 		"GvisorAddon": "k8s-minikube/gvisor-addon:3@sha256:23eb17d48a66fc2b09c31454fb54ecae520c3e9c9197ef17fcb398b4f31d505a",
 	}, map[string]string{
 		"GvisorAddon": "gcr.io",
@@ -478,7 +480,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"helm-tiller-svc.yaml",
 			"0640"),
-	}, false, "helm-tiller", "third-party (helm)", map[string]string{
+	}, false, "helm-tiller", "3rd party (Helm)", "https://v2.helm.sh/docs/using_helm/", map[string]string{
 		"Tiller": "helm/tiller:v2.17.0@sha256:4c43eb385032945cad047d2350e4945d913b90b3ab43ee61cecb32a495c6df0f",
 	}, map[string]string{
 		// GCR is deprecated in helm
@@ -491,7 +493,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"ingress-dns-pod.yaml",
 			"0640"),
-	}, false, "ingress-dns", "google", map[string]string{
+	}, false, "ingress-dns", "Google", "https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/", map[string]string{
 		"IngressDNS": "k8s-minikube/minikube-ingress-dns:0.0.2@sha256:4abe27f9fc03fedab1d655e2020e6b165faf3bf6de1088ce6cf215a75b78f05f",
 	}, map[string]string{
 		"IngressDNS": "gcr.io",
@@ -507,7 +509,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"metallb-config.yaml",
 			"0640"),
-	}, false, "metallb", "third-party (metallb)", map[string]string{
+	}, false, "metallb", "3rd party (MetalLB)", "", map[string]string{
 		"Speaker":    "metallb/speaker:v0.9.6@sha256:c66585a805bed1a3b829d8fb4a4aab9d87233497244ebff96f1b88f1e7f8f991",
 		"Controller": "metallb/controller:v0.9.6@sha256:fbfdb9d3f55976b0ee38f3309d83a4ca703efcf15d6ca7889cd8189142286502",
 	}, nil),
@@ -527,7 +529,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"ambassadorinstallation.yaml",
 			"0640"),
-	}, false, "ambassador", "third-party (ambassador)", map[string]string{
+	}, false, "ambassador", "3rd party (Ambassador)", "https://minikube.sigs.k8s.io/docs/tutorials/ambassador_ingress_controller/", map[string]string{
 		"AmbassadorOperator": "datawire/ambassador-operator:v1.2.3@sha256:492f33e0828a371aa23331d75c11c251b21499e31287f026269e3f6ec6da34ed",
 	}, map[string]string{
 		"AmbassadorOperator": "quay.io",
@@ -548,7 +550,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"gcp-auth-webhook.yaml",
 			"0640"),
-	}, false, "gcp-auth", "google", map[string]string{
+	}, false, "gcp-auth", "Google", "https://minikube.sigs.k8s.io/docs/handbook/addons/gcp-auth/", map[string]string{
 		"KubeWebhookCertgen": "k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0@sha256:f3b6b39a6062328c095337b4cadcefd1612348fdd5190b1dcbcb9b9e90bd8068",
 		"GCPAuthWebhook":     "k8s-minikube/gcp-auth-webhook:v0.0.8@sha256:26c7b2454f1c946d7c80839251d939606620f37c2f275be2796c1ffd96c438f6",
 	}, map[string]string{
@@ -587,7 +589,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"volume-snapshot-controller-deployment.yaml",
 			"0640"),
-	}, false, "volumesnapshots", "kubernetes", map[string]string{
+	}, false, "volumesnapshots", "Kubernetes", "https://minikube.sigs.k8s.io/docs/tutorials/volume_snapshots_and_csi/", map[string]string{
 		"SnapshotController": "sig-storage/snapshot-controller:v4.0.0@sha256:00fcc441ea9f72899c25eed61d602272a2a58c5f0014332bdcb5ac24acef08e4",
 	}, map[string]string{
 		"SnapshotController": "k8s.gcr.io",
@@ -658,7 +660,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"csi-hostpath-storageclass.yaml",
 			"0640"),
-	}, false, "csi-hostpath-driver", "kubernetes", map[string]string{
+	}, false, "csi-hostpath-driver", "Kubernetes", "https://minikube.sigs.k8s.io/docs/tutorials/volume_snapshots_and_csi/", map[string]string{
 		"Attacher":              "sig-storage/csi-attacher:v3.1.0@sha256:50c3cfd458fc8e0bf3c8c521eac39172009382fc66dc5044a330d137c6ed0b09",
 		"HostMonitorAgent":      "sig-storage/csi-external-health-monitor-agent:v0.2.0@sha256:c20d4a4772599e68944452edfcecc944a1df28c19e94b942d526ca25a522ea02",
 		"HostMonitorController": "sig-storage/csi-external-health-monitor-controller:v0.2.0@sha256:14988b598a180cc0282f3f4bc982371baf9a9c9b80878fb385f8ae8bd04ecf16",
@@ -685,7 +687,7 @@ var Addons = map[string]*Addon{
 			vmpath.GuestAddonsDir,
 			"portainer.yaml",
 			"0640"),
-	}, false, "portainer", "portainer.io", map[string]string{
+	}, false, "portainer", "Portainer.io", "", map[string]string{
 		"Portainer": "portainer/portainer-ce:latest@sha256:4f126c5114b63e9d1bceb4b368944d14323329a9a0d4e7bb7eb53c9b7435d498",
 	}, nil),
 }
diff --git a/site/content/en/docs/commands/addons.md b/site/content/en/docs/commands/addons.md
index d7e2377f8..1b4ebaac5 100644
--- a/site/content/en/docs/commands/addons.md
+++ b/site/content/en/docs/commands/addons.md
@@ -252,6 +252,7 @@ minikube addons list [flags]
 ### Options
 
 ```
+  -d, --docs            If true, print web links to addons' documentation if using --output=list (default).
   -o, --output string   minikube addons list --output OUTPUT. json, list (default "list")
 ```
 
diff --git a/translations/de.json b/translations/de.json
index 86b706c7e..ba591e10a 100644
--- a/translations/de.json
+++ b/translations/de.json
@@ -345,6 +345,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.": "Wenn true, speichern Sie Docker-Images für den aktuellen Bootstrapper zwischen und laden Sie sie auf den Computer. Immer falsch mit --vm-driver = none.",
 	"If true, only download and cache files for later use - don't install or start anything.": "Wenn true, laden Sie nur Dateien für die spätere Verwendung herunter und speichern Sie sie – installieren oder starten Sie nichts.",
 	"If true, pods might get deleted and restarted on addon enable": "Falls gesetzt, könnten Pods gelöscht und neugestartet werden, wenn ein Addon aktiviert wird",
+	"If true, print web links to addons' documentation if using --output=list (default).": "Falls gesetzt, gibt Links zu den Dokumentationen der Addons aus. Funktioniert nur, wenn --output=list (default).",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "Falls gesetzt, gibt die Liste der Profile schneller aus, indem das Validieren des Status des Clusters ausgelassen wird.",
 	"If true, the added node will be marked for work. Defaults to true.": "Falls gesetzt, wird der hinzugefügte Node als Arbeitsnode markiert. Default: true",
 	"If true, the node added will also be a control plane in addition to a worker.": "Falls gesetzt, wird der Knoten auch als Control Plane hinzugefügt, zusätzlich zu als Worker.",
diff --git a/translations/es.json b/translations/es.json
index 057331157..0040fab95 100644
--- a/translations/es.json
+++ b/translations/es.json
@@ -354,6 +354,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.": "Si el valor es \"true\", las imágenes de Docker del programa previo actual se almacenan en caché y se cargan en la máquina. Siempre es \"false\" si se especifica --vm-driver=none.",
 	"If true, only download and cache files for later use - don't install or start anything.": "Si el valor es \"true\", los archivos solo se descargan y almacenan en caché (no se instala ni inicia nada).",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",
diff --git a/translations/fr.json b/translations/fr.json
index 06bcd73a0..30e1aa91f 100644
--- a/translations/fr.json
+++ b/translations/fr.json
@@ -337,6 +337,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.": "Si vrai, met en cache les images Docker pour le programme d'amorçage actuel et les charge dans la machine. Toujours faux avec --driver=none.",
 	"If true, only download and cache files for later use - don't install or start anything.": "Si la valeur est \"true\", téléchargez les fichiers et mettez-les en cache uniquement pour une utilisation future. Ne lancez pas d'installation et ne commencez aucun processus.",
 	"If true, pods might get deleted and restarted on addon enable": "Si vrai, les pods peuvent être supprimés et redémarrés lors addon enable",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "Si vrai, renvoie la liste des profils plus rapidement en ignorant la validation de l'état du cluster.",
 	"If true, the added node will be marked for work. Defaults to true.": "Si vrai, le nœud ajouté sera marqué pour le travail. La valeur par défaut est true.",
 	"If true, the node added will also be a control plane in addition to a worker.": "Si vrai, le nœud ajouté sera également un plan de contrôle en plus d'un travailleur.",
diff --git a/translations/ja.json b/translations/ja.json
index dbd5d0d62..9c4f9c56a 100644
--- a/translations/ja.json
+++ b/translations/ja.json
@@ -345,6 +345,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.": "true の場合、現在のブートストラッパーの Docker イメージをキャッシュに保存して、マシンに読み込みます。--vm-driver=none の場合は常に false です。",
 	"If true, only download and cache files for later use - don't install or start anything.": "true の場合、後の使用のためのファイルのダウンロードとキャッシュ保存のみ行われます。インストールも起動も行いません",
 	"If true, pods might get deleted and restarted on addon enable": "true の場合、有効なアドオンの Pod は削除され、再起動されます",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "true の場合、クラスター状態の検証を省略することにより高速にプロファイル一覧を返します。",
 	"If true, the added node will be marked for work. Defaults to true.": "true の場合、追加されたノードはワーカー用としてマークされます。デフォルトは true です。",
 	"If true, the node added will also be a control plane in addition to a worker.": "true の場合、追加されたノードはワーカーに加えてコントロールプレーンにもなります。",
diff --git a/translations/ko.json b/translations/ko.json
index 4d4536ec9..a32d205c1 100644
--- a/translations/ko.json
+++ b/translations/ko.json
@@ -371,6 +371,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.": "",
 	"If true, only download and cache files for later use - don't install or start anything.": "",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",
diff --git a/translations/pl.json b/translations/pl.json
index 17f838b48..3433a1542 100644
--- a/translations/pl.json
+++ b/translations/pl.json
@@ -357,6 +357,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.": "",
 	"If true, only download and cache files for later use - don't install or start anything.": "",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",
diff --git a/translations/ru.json b/translations/ru.json
index 8c8bdef38..d8bbe4aea 100644
--- a/translations/ru.json
+++ b/translations/ru.json
@@ -324,6 +324,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.": "",
 	"If true, only download and cache files for later use - don't install or start anything.": "",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",
diff --git a/translations/strings.txt b/translations/strings.txt
index dbf487fa6..843de236c 100644
--- a/translations/strings.txt
+++ b/translations/strings.txt
@@ -324,6 +324,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none.": "",
 	"If true, only download and cache files for later use - don't install or start anything.": "",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",
diff --git a/translations/zh-CN.json b/translations/zh-CN.json
index b4fa54927..3241051e8 100644
--- a/translations/zh-CN.json
+++ b/translations/zh-CN.json
@@ -429,6 +429,7 @@
 	"If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --vm-driver=none.": "如果为 true，请缓存当前引导程序的 docker 镜像并将其加载到机器中。在 --vm-driver=none 情况下始终为 false。",
 	"If true, only download and cache files for later use - don't install or start anything.": "如果为 true，仅会下载和缓存文件以备后用 - 不会安装或启动任何项。",
 	"If true, pods might get deleted and restarted on addon enable": "",
+	"If true, print web links to addons' documentation if using --output=list (default).": "",
 	"If true, returns list of profiles faster by skipping validating the status of the cluster.": "",
 	"If true, the added node will be marked for work. Defaults to true.": "",
 	"If true, the node added will also be a control plane in addition to a worker.": "",


Test patch:
diff --git a/cmd/minikube/cmd/config/addons_list_test.go b/cmd/minikube/cmd/config/addons_list_test.go
index 52afb8e37..5aca69e34 100644
--- a/cmd/minikube/cmd/config/addons_list_test.go
+++ b/cmd/minikube/cmd/config/addons_list_test.go
@@ -27,39 +27,50 @@ import (
 )
 
 func TestAddonsList(t *testing.T) {
-	t.Run("NonExistingClusterTable", func(t *testing.T) {
-		r, w, err := os.Pipe()
-		if err != nil {
-			t.Fatalf("failed to create pipe: %v", err)
-		}
-		old := os.Stdout
-		defer func() { os.Stdout = old }()
-		os.Stdout = w
-		printAddonsList(nil)
-		if err := w.Close(); err != nil {
-			t.Fatalf("failed to close pipe: %v", err)
-		}
-		buf := bufio.NewScanner(r)
-		pipeCount := 0
-		got := ""
-		// Pull the first 3 lines from stdout
-		for i := 0; i < 3; i++ {
-			if !buf.Scan() {
-				t.Fatalf("failed to read stdout")
+	tests := []struct {
+		name      string
+		printDocs bool
+		want      int
+	}{
+		{"DisabledDocs", false, 9},
+		{"EnabledDocs", true, 12},
+	}
+
+	for _, tt := range tests {
+		t.Run("NonExistingClusterTable"+tt.name, func(t *testing.T) {
+			r, w, err := os.Pipe()
+			if err != nil {
+				t.Fatalf("failed to create pipe: %v", err)
 			}
-			pipeCount += strings.Count(buf.Text(), "|")
-			got += buf.Text()
-		}
-		// The lines we pull should look something like
-		// |-----------------------------|-----------------------|
-		// |         ADDON NAME          |      MAINTAINER       |
-		// |-----------------------------|-----------------------|
-		// which has 9 pipes
-		expected := 9
-		if pipeCount != expected {
-			t.Errorf("Expected header to have %d pipes; got = %d: %q", expected, pipeCount, got)
-		}
-	})
+			old := os.Stdout
+			defer func() { os.Stdout = old }()
+			os.Stdout = w
+			printAddonsList(nil, tt.printDocs)
+			if err := w.Close(); err != nil {
+				t.Fatalf("failed to close pipe: %v", err)
+			}
+			buf := bufio.NewScanner(r)
+			pipeCount := 0
+			got := ""
+			// Pull the first 3 lines from stdout
+			for i := 0; i < 3; i++ {
+				if !buf.Scan() {
+					t.Fatalf("failed to read stdout")
+				}
+				pipeCount += strings.Count(buf.Text(), "|")
+				got += buf.Text()
+			}
+			// The lines we pull should look something like
+			// |------------|------------|(------|)
+			// | ADDON NAME | MAINTAINER |( DOCS |)
+			// |------------|------------|(------|)
+			// which has 9 or 12 pipes
+			expected := tt.want
+			if pipeCount != expected {
+				t.Errorf("Expected header to have %d pipes; got = %d: %q", expected, pipeCount, got)
+			}
+		})
+	}
 
 	t.Run("NonExistingClusterJSON", func(t *testing.T) {
 		type addons struct {