Skip to content

backend: Add TLS Support for Headlamp Server#3523

Closed
shahvrushali22 wants to merge 2 commits intokubernetes-sigs:mainfrom
oracle-cne:add-tls-support
Closed

backend: Add TLS Support for Headlamp Server#3523
shahvrushali22 wants to merge 2 commits intokubernetes-sigs:mainfrom
oracle-cne:add-tls-support

Conversation

@shahvrushali22
Copy link
Contributor

@shahvrushali22 shahvrushali22 commented Jun 25, 2025

Summary

This PR adds TLS/HTTPS support for the Headlamp server by introducing new configuration options (tlsCert and tlsKey) and updating the Helm chart to allow serving Headlamp over HTTPS when deployed in-cluster.

Changes

  • Added tlsCert and tlsKey fields to HeadlampConfig in headlamp.go
  • Updated StartHeadlampServer to support ListenAndServeTLS conditionally
  • Added new TLS CLI flags and config options in config.go
  • Mounted TLS cert and key in the Helm chart via Kubernetes secrets
  • Added test TLS cert/key under headlamp_testdata for local development

Steps to Test

  1. Deploy Headlamp using Helm with a valid TLS secret (ui-tls) and set config.tlsCert and config.tlsKey in values.yaml
  2. Port-forward the Headlamp service
  3. Access the Headlamp UI via https://: and ensure it loads securely

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jun 25, 2025
@k8s-ci-robot k8s-ci-robot requested a review from illume June 25, 2025 18:00
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: shahvrushali22
Once this PR has been reviewed and has the lgtm label, please assign joaquimrocha for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot requested a review from skoeva June 25, 2025 18:00
@k8s-ci-robot
Copy link
Contributor

Welcome @shahvrushali22!

It looks like this is your first PR to kubernetes-sigs/headlamp 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-sigs/headlamp has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 25, 2025
@illume illume requested a review from Copilot June 28, 2025 07:33
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Adds optional TLS support for the Headlamp server by introducing certificate/key configuration, updating server startup logic, and extending the Helm chart to mount TLS secrets.

  • Introduce tlsCert and tlsKey fields and flags in Go config
  • Conditionally start HTTPS (ListenAndServeTLS) when in-cluster
  • Update Helm values, schema, and deployment template to mount and pass TLS secrets
  • Add end-to-end TLS startup test with self-signed cert

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
charts/headlamp/values.yaml Added default tlsCert/tlsKey and TLS volume mounts
charts/headlamp/values.schema.json Defined JSON schema entries for tlsCert/tlsKey
charts/headlamp/templates/deployment.yaml Injected -tls-cert/-tls-key args into container
backend/pkg/config/config.go Added TLSCert/TLSKey fields and CLI flags
backend/cmd/server.go Passed TLS config into Headlamp setup
backend/cmd/headlamp.go Use ListenAndServeTLS when useInCluster is true
backend/cmd/headlamp_test.go Added TestStartHeadlampServerTLS
backend/cmd/headlamp_testdata/headlamp.crt Test certificate
backend/cmd/headlamp_testdata/headlamp.key Test private key
Comments suppressed due to low confidence (3)

charts/headlamp/values.yaml:95

  • Helm values keys use camelCase but the Go config tag is tls-cert (kebab-case). Rename this key to tls-cert to match the Koanf tag and ensure the certificate path is loaded.
  tlsCert: "/headlamp-cert/headlamp-ca.crt"

charts/headlamp/templates/deployment.yaml:259

  • Wrap the TLS volumeMounts and CLI flag blocks in a conditional on both tlsCert and tlsKey to avoid mounting unused volumes when TLS is not configured.
            {{- with .Values.config.tlsCert }}

charts/headlamp/values.schema.json:226

  • Indentation of the new tlsCert and tlsKey schema entries is inconsistent with surrounding keys. Align them with existing definitions to keep the JSON schema clear and valid.
         "tlsCert": {

TLSKey string `koanf:"tls-key"`
}

func (c *Config) Validate() error {
Copy link

Copilot AI Jun 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation to ensure that if either tls-cert or tls-key is set, both must be provided (and optionally check file existence), otherwise startup may fail with a cryptic error.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a valid point. Would you mind adding this validation?

Comment on lines +1119 to +1121
// Give the server a moment to start
time.Sleep(100 * time.Millisecond)

Copy link

Copilot AI Jun 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on a fixed sleep can lead to flaky tests. Consider synchronizing on server readiness (e.g., pre-listen signal or using httptest.Server) instead of time.Sleep.

Suggested change
// Give the server a moment to start
time.Sleep(100 * time.Millisecond)
// Wait for the server to be ready by checking its readiness
timeout := time.After(5 * time.Second)
tick := time.Tick(100 * time.Millisecond)
for {
select {
case <-timeout:
t.Fatalf("Server did not become ready in time")
case <-tick:
resp, err := http.Get("https://localhost:8081/config")
if err == nil && resp.StatusCode == http.StatusOK {
resp.Body.Close()
break
}
}
}

Copilot uses AI. Check for mistakes.
@illume
Copy link
Contributor

illume commented Jun 28, 2025

This is great. Much appreciated.

The github check failure is because the helm tests need updating to account for the changes.

You can run make backend-lint and make backend-lint-fix to see the backend lint issues locally. https://github.com/kubernetes-sigs/headlamp/actions/runs/15903351760/job/44970970626?pr=3523

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How was this generated?

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How was this generated?

"type": "string",
"description": "Directory to load plugins from"
},
"tlsCert": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please document these in the charts/headlamp/README.md file?

# -- directory to look for plugins
pluginsDir: "/headlamp/plugins"
watchPlugins: false
tlsCert: "/headlamp-cert/headlamp-ca.crt"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does having these set by default mean the files are required?

I don't think we'd want to require these files (or volume mounts) by default, especially if it breaks existing users.

@illume
Copy link
Contributor

illume commented Jul 2, 2025

@shahvrushali22 I wonder, do you know how I can generate a certificate for testing locally?

I found this command, but haven't tried it yet.

mkdir -p tls-secret
cd tls-secret

openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout tls.key \
  -out tls.crt \
  -subj "/C=US/ST=Local/L=Localhost/O=Test Org/CN=localhost"

@shahvrushali22
Copy link
Contributor Author

@shahvrushali22 I wonder, do you know how I can generate a certificate for testing locally?

I found this command, but haven't tried it yet.

mkdir -p tls-secret
cd tls-secret

openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout tls.key \
  -out tls.crt \
  -subj "/C=US/ST=Local/L=Localhost/O=Test Org/CN=localhost"

Yes, that’s a valid way to generate a self-signed certificate for local testing.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 27, 2025
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@illume
Copy link
Contributor

illume commented Sep 2, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants