From 26afc8f85cffb258572fe41dc386d4e84a65a1cf Mon Sep 17 00:00:00 2001 From: Santhosh Nagaraj S Date: Mon, 6 Jun 2022 12:47:55 +0530 Subject: [PATCH] Addon: add headlamp Signed-off-by: Santhosh Nagaraj S --- cmd/minikube/cmd/config/addons_list_test.go | 2 +- cmd/minikube/cmd/config/enable.go | 23 +++++++++ deploy/addons/assets.go | 4 ++ .../headlamp/headlamp-clusterrolebinding.yaml | 18 +++++++ .../headlamp/headlamp-deployment.yaml.tmpl | 42 +++++++++++++++ .../addons/headlamp/headlamp-namespace.yaml | 6 +++ deploy/addons/headlamp/headlamp-service.yaml | 21 ++++++++ .../headlamp/headlamp-serviceaccount.yaml | 10 ++++ pkg/addons/config.go | 5 ++ pkg/minikube/assets/addons.go | 13 +++++ .../en/docs/handbook/addons/headlamp.md | 51 +++++++++++++++++++ test/integration/addons_test.go | 14 +++++ 12 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 deploy/addons/headlamp/headlamp-clusterrolebinding.yaml create mode 100644 deploy/addons/headlamp/headlamp-deployment.yaml.tmpl create mode 100644 deploy/addons/headlamp/headlamp-namespace.yaml create mode 100644 deploy/addons/headlamp/headlamp-service.yaml create mode 100644 deploy/addons/headlamp/headlamp-serviceaccount.yaml create mode 100644 site/content/en/docs/handbook/addons/headlamp.md diff --git a/cmd/minikube/cmd/config/addons_list_test.go b/cmd/minikube/cmd/config/addons_list_test.go index ae4a53ca25..1398508c2d 100644 --- a/cmd/minikube/cmd/config/addons_list_test.go +++ b/cmd/minikube/cmd/config/addons_list_test.go @@ -77,7 +77,7 @@ func TestAddonsList(t *testing.T) { Ambassador *interface{} `json:"ambassador"` } - b := make([]byte, 557) + b := make([]byte, 571) r, w, err := os.Pipe() if err != nil { t.Fatalf("failed to create pipe: %v", err) diff --git a/cmd/minikube/cmd/config/enable.go b/cmd/minikube/cmd/config/enable.go index 28da1eb43f..36c38c1ed8 100644 --- a/cmd/minikube/cmd/config/enable.go +++ b/cmd/minikube/cmd/config/enable.go @@ -67,6 +67,29 @@ var addonsEnableCmd = &cobra.Command{ minikube{{.profileArg}} addons enable metrics-server +`, out.V{"profileArg": tipProfileArg}) + + } + if addon == "headlamp" { + out.Styled(style.Tip, `To access Headlamp, use the following command: +minikube service headlamp -n headlamp + +`) + out.Styled(style.Tip, `To authenticate in Headlamp, fetch the Authentication Token using the following command: + +export SECRET=$(kubectl get secrets --namespace headlamp -o custom-columns=":metadata.name" | grep "headlamp-token") +kubectl get secret $SECRET --namespace headlamp --template=\{\{.data.token\}\} | base64 --decode + +`) + + tipProfileArg := "" + if ClusterFlagValue() != constants.DefaultClusterName { + tipProfileArg = fmt.Sprintf(" -p %s", ClusterFlagValue()) + } + out.Styled(style.Tip, `Headlamp can display more detailed information when metrics-server is installed. To install it, run: + +minikube{{.profileArg}} addons enable metrics-server + `, out.V{"profileArg": tipProfileArg}) } diff --git a/deploy/addons/assets.go b/deploy/addons/assets.go index 84b6b644d5..209f0560d4 100644 --- a/deploy/addons/assets.go +++ b/deploy/addons/assets.go @@ -147,4 +147,8 @@ var ( // InAccelAssets assets for inaccel addon //go:embed inaccel/fpga-operator.yaml.tmpl InAccelAssets embed.FS + + // HeadlampAssets assets for headlamp addon + //go:embed headlamp/*.yaml headlamp/*.tmpl + HeadlampAssets embed.FS ) diff --git a/deploy/addons/headlamp/headlamp-clusterrolebinding.yaml b/deploy/addons/headlamp/headlamp-clusterrolebinding.yaml new file mode 100644 index 0000000000..1f516989ed --- /dev/null +++ b/deploy/addons/headlamp/headlamp-clusterrolebinding.yaml @@ -0,0 +1,18 @@ +--- +# ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: headlamp-admin + namespace: headlamp + labels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: headlamp + namespace: headlamp diff --git a/deploy/addons/headlamp/headlamp-deployment.yaml.tmpl b/deploy/addons/headlamp/headlamp-deployment.yaml.tmpl new file mode 100644 index 0000000000..63da3b3433 --- /dev/null +++ b/deploy/addons/headlamp/headlamp-deployment.yaml.tmpl @@ -0,0 +1,42 @@ +--- +# Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: headlamp + namespace: headlamp + labels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp + template: + metadata: + labels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp + spec: + serviceAccountName: headlamp + containers: + - name: headlamp + image: {{.CustomRegistries.Headlamp | default .ImageRepository | default .Registries.Headlamp }}{{.Images.Headlamp}} + imagePullPolicy: IfNotPresent + args: + - "-in-cluster" + - "-plugins-dir=/headlamp/plugins" + ports: + - name: http + containerPort: 4466 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http diff --git a/deploy/addons/headlamp/headlamp-namespace.yaml b/deploy/addons/headlamp/headlamp-namespace.yaml new file mode 100644 index 0000000000..85d4ae0a2e --- /dev/null +++ b/deploy/addons/headlamp/headlamp-namespace.yaml @@ -0,0 +1,6 @@ +--- +# Namespace +apiVersion: v1 +kind: Namespace +metadata: + name: headlamp diff --git a/deploy/addons/headlamp/headlamp-service.yaml b/deploy/addons/headlamp/headlamp-service.yaml new file mode 100644 index 0000000000..1eca749b82 --- /dev/null +++ b/deploy/addons/headlamp/headlamp-service.yaml @@ -0,0 +1,21 @@ +--- +# Service +apiVersion: v1 +kind: Service +metadata: + name: headlamp + namespace: headlamp + labels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp + kubernetes.io/minikube-addons-endpoint: headlamp +spec: + type: NodePort + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp diff --git a/deploy/addons/headlamp/headlamp-serviceaccount.yaml b/deploy/addons/headlamp/headlamp-serviceaccount.yaml new file mode 100644 index 0000000000..2dfba7fc61 --- /dev/null +++ b/deploy/addons/headlamp/headlamp-serviceaccount.yaml @@ -0,0 +1,10 @@ +--- +# ServiceAccount +apiVersion: v1 +kind: ServiceAccount +metadata: + name: headlamp + namespace: headlamp + labels: + app.kubernetes.io/name: headlamp + app.kubernetes.io/instance: headlamp diff --git a/pkg/addons/config.go b/pkg/addons/config.go index 81db657897..6aba241a00 100644 --- a/pkg/addons/config.go +++ b/pkg/addons/config.go @@ -202,4 +202,9 @@ var Addons = []*Addon{ set: SetBool, callbacks: []setFn{EnableOrDisableAddon}, }, + { + name: "headlamp", + set: SetBool, + callbacks: []setFn{EnableOrDisableAddon}, + }, } diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 5b3dec96bc..c7ed128430 100755 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -701,6 +701,19 @@ var Addons = map[string]*Addon{ }, map[string]string{ "Helm3": "docker.io", }), + "headlamp": NewAddon([]*BinAsset{ + MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-namespace.yaml", vmpath.GuestAddonsDir, "headlamp-namespace.yaml", "6040"), + MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-service.yaml", vmpath.GuestAddonsDir, "headlamp-service.yaml", "6040"), + MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-deployment.yaml.tmpl", vmpath.GuestAddonsDir, "headlamp-deployment.yaml", "6040"), + MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-serviceaccount.yaml", vmpath.GuestAddonsDir, "headlamp-serviceaccount.yaml", "6040"), + MustBinAsset(addons.HeadlampAssets, "headlamp/headlamp-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "headlamp-clusterrolebinding.yaml", "6040"), + }, false, "headlamp", "kinvolk.io", "https://minikube.sigs.k8s.io/docs/handbook/addons/headlamp/", + map[string]string{ + "Headlamp": "kinvolk/headlamp:v0.9.0@sha256:465aaee6518f3fdd032965eccd6a8f49e924d144b1c86115bad613872672ec02", + }, + map[string]string{ + "Headlamp": "ghcr.io", + }), } // parseMapString creates a map based on `str` which is encoded as =,=,... diff --git a/site/content/en/docs/handbook/addons/headlamp.md b/site/content/en/docs/handbook/addons/headlamp.md new file mode 100644 index 0000000000..f72e3aa2ad --- /dev/null +++ b/site/content/en/docs/handbook/addons/headlamp.md @@ -0,0 +1,51 @@ +--- +title: "Using Headlamp Addon" +linkTitle: "Headlamp" +weight: 1 +date: 2022-06-08 +--- + +## Headlamp Addon + +[Headlamp](https://kinvolk.github.io/headlamp) is an easy-to-use and extensible Kubernetes web UI. + +### Enable Headlamp on minikube + +To enable this addon, simply run: +```shell script +minikube addons enable headlamp +``` + +Once the addon is enabled, you can access the Headlamp's web UI using the following command. +```shell script +minikube service headlamp -n headlamp +``` + +To authenticate in Headlamp, fetch the Authentication Token using the following command: + +```shell script +export SECRET=$(kubectl get secrets --namespace headlamp -o custom-columns=":metadata.name" | grep "headlamp-token") +kubectl get secret $SECRET --namespace headlamp --template=\{\{.data.token\}\} | base64 --decode +``` + +Headlamp can display more detailed information when metrics-server is installed. To install it, run: + +```shell script +minikube addons enable metrics-server +``` + +### Testing installation + +```shell script +kubectl get pods -n headlamp +``` + +If everything went well, there should be no errors about Headlamp's installation in your minikube cluster. + +### Disable headlamp + +To disable this addon, simply run: + +```shell script +minikube addons disable headlamp +``` \ No newline at end of file diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go index 7b85db6b33..9071afee10 100644 --- a/test/integration/addons_test.go +++ b/test/integration/addons_test.go @@ -95,6 +95,7 @@ func TestAddons(t *testing.T) { {"HelmTiller", validateHelmTillerAddon}, {"Olm", validateOlmAddon}, {"CSI", validateCSIDriverAndSnapshots}, + {"Headlamp", validateHeadlampAddon}, } for _, tc := range tests { tc := tc @@ -708,3 +709,16 @@ func validateGCPAuthAddon(ctx context.Context, t *testing.T, profile string) { } } } + +func validateHeadlampAddon(ctx context.Context, t *testing.T, profile string) { + defer PostMortemLogs(t, profile) + + rr, err := Run(t, exec.CommandContext(ctx, Target(), "addons", "enable", "headlamp", "-p", profile, "--alsologtostderr", "-v=1")) + if err != nil { + t.Fatalf("failed to enable headlamp addon: args: %q: %v", rr.Command(), err) + } + + if _, err := PodWait(ctx, t, profile, "headlamp", "app.kubernetes.io/name=headlamp", Minutes(8)); err != nil { + t.Fatalf("failed waiting for headlamp pod: %v", err) + } +}