Skip to content

tls: enable tls.ca setting in client/exporter config files#177

Merged
mangelajo merged 4 commits intomainfrom
config-ca-certs
Feb 3, 2026
Merged

tls: enable tls.ca setting in client/exporter config files#177
mangelajo merged 4 commits intomainfrom
config-ca-certs

Conversation

@mangelajo
Copy link
Member

@mangelajo mangelajo commented Jan 30, 2026

This PR adds the following elements:

  • Exposing of the certificate authority bundle as a configmap for the jmp admin tool, the CA can be either auto-generated when a self signed CA is enabled, or an external authority / or certificate issuer in the language of cert-manager, in that case, when using an external issuer, the administrator needs to provide the new CABundle field, which could be empty for a public CA (i.e. ACME+letsencrypt or equivalent)
  • Adding support in the jmp admin tool to insert the CA bundle in the client/exporter config files when doing a jmp admin create [exporter|client]
  • E2E testing the above.

There is a follow up PR that enables OIDC logins "easy-login" where the server provides the CA to the jmp login (as well as some extra details like: endpoint, namespace, etc.

Summary by CodeRabbit

  • New Features

    • Support for supplying a custom base64-encoded CA bundle for external certificate issuers
    • CA bundle published to a ConfigMap (jumpstarter-service-ca-cert) so clients can verify TLS
    • Clients and exporters now include TLS config that uses the CA bundle when present
  • Tests

    • New end-to-end and unit tests validating CA ConfigMap behavior and client/exporter TLS handling

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Adds an optional base64-encoded PEM caBundle to IssuerReference, reconciles a CA ConfigMap (jumpstarter-service-ca-cert) from issuer CABundle or self-signed secret, and propagates the CA bundle to Python clients/exporters with tests and CRD/schema updates.

Changes

Cohort / File(s) Summary
API & CRD
controller/deploy/operator/api/v1alpha1/jumpstarter_types.go, controller/deploy/operator/api/v1alpha1/zz_generated.deepcopy.go, controller/deploy/operator/config/crd/bases/operator.jumpstarter.dev_jumpstarters.yaml, controller/deploy/operator/bundle/manifests/operator.jumpstarter.dev_jumpstarters.yaml
Added optional CABundle []byte (json:"caBundle,omitempty") to IssuerReference, updated deepcopy to deep-copy the slice, and extended CRD/CSV manifests with caBundle schema property.
Operator CA ConfigMap Reconciliation
controller/deploy/operator/internal/controller/jumpstarter/certificates.go
Added CA ConfigMap reconciliation (create/update) named jumpstarter-service-ca-cert, deriving ca.crt from Issuer.CABundle, self-signed CA secret, or leaving empty; introduced GetCAConfigMapName, reconcileCAConfigMap, and related constant.
End-to-end & BATS tests
controller/deploy/operator/test/e2e/e2e_test.go, e2e/tests.bats
Added e2e tests validating CA ConfigMap contents for self-signed and external issuer modes and a BATS test validating legacy client TLS CA usage.
Python client/exporter integration
python/packages/jumpstarter-kubernetes/jumpstarter_kubernetes/util/async_custom_object_api.py, python/packages/jumpstarter-kubernetes/jumpstarter_kubernetes/clients.py, python/packages/jumpstarter-kubernetes/jumpstarter_kubernetes/exporters.py, python/packages/jumpstarter-kubernetes/jumpstarter_kubernetes/clients_test.py, python/packages/jumpstarter-kubernetes/jumpstarter_kubernetes/exporters_test.py
Added get_ca_bundle() to fetch base64 CA from ConfigMap jumpstarter-service-ca-cert, wired CA into client/exporter configs as TLSConfigV1Alpha1(ca=...), and expanded tests covering presence/absence and encoding scenarios.
CSV timestamp-only change
controller/deploy/operator/bundle/manifests/jumpstarter-operator.clusterserviceversion.yaml
Updated createdAt timestamp only.

Sequence Diagram(s)

sequenceDiagram
    participant Operator as Operator (controller)
    participant K8sAPI as Kubernetes API
    participant CM as ConfigMap (jumpstarter-service-ca-cert)
    participant Client as Python Client/Exporter
    participant TLS as TLS stack

    Operator->>K8sAPI: reconcileCAConfigMap(js) — ensure ConfigMap exists
    K8sAPI-->>CM: create/update ca.crt (from Issuer.CABundle or CA secret)
    Client->>K8sAPI: read ConfigMap jumpstarter-service-ca-cert
    K8sAPI-->>Client: return ConfigMap (ca.crt or empty)
    Client->>Client: base64-decode/encode ca.crt -> TLSConfigV1Alpha1(ca=...)
    Client->>TLS: establish TLS connection using provided CA bundle
    TLS->>TLS: verify server cert against CA bundle
    TLS-->>Client: connection result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • Operator cert manager #139 — Prior cert-manager/IssuerReference work that introduced IssuerReference and is extended here by adding caBundle and CA ConfigMap orchestration.

Suggested labels

administration, operator

Suggested reviewers

  • evakhoni
  • bennyz

Poem

🐰 I hop with joy to guard the crt,
tucked in a ConfigMap, tiny and neat.
From issuer or secret it finds its place,
clients sip TLS with a confident face.
A carrot for secure connections, oh sweet! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main objective of the pull request: enabling TLS CA certificate support in client and exporter configuration files.
Docstring Coverage ✅ Passed Docstring coverage is 96.88% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch config-ca-certs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mangelajo
Copy link
Member Author

Hmm, this isn't running some of the CI jobs, why?

@mangelajo
Copy link
Member Author

ah, this is not over the base branch main...

@mangelajo mangelajo changed the title Config ca certs tls: enable tls.ca setting in client/exporter config files Feb 2, 2026
@mangelajo mangelajo changed the base branch from e2e-with-operator to main February 2, 2026 17:02
@mangelajo mangelajo requested a review from evakhoni February 2, 2026 17:05
}, caSecret)
if err != nil {
// CA secret doesn't exist yet - this is expected during initial setup
// The ConfigMap will be updated once the CA certificate is ready
Copy link
Member Author

Choose a reason for hiding this comment

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

In the follow up PR we wait until this is really ready before creating the configmap to avoid the service from having a "blank" CA bundle injected. In this PR we still don't use it from jumpstarter-controller, only jmp admin, so it's not a problem really, but on the later patch we start using this from jumpstarter-controller and we can't populate empty so you will see this change.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for clarifying this part!

@mangelajo
Copy link
Member Author

hmm CI is not running because this was first on top of another branch, let me update last commit message to trigger it

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@controller/deploy/operator/internal/controller/jumpstarter/certificates.go`:
- Around line 511-525: The current error handling around r.Client.Get when
reading the CA secret (caSecret, caSecretName) treats all errors as "not found"
and proceeds to create an empty CA ConfigMap; change this to differentiate
NotFound vs other errors by using apierrors.IsNotFound(err) (from
k8s.io/apimachinery/pkg/api/errors) — if apierrors.IsNotFound(err) keep the
existing log and continue, otherwise return the error (or requeue) from the
reconcile function so transient/API/RBAC failures are retried and not silently
masked; update imports to include apierrors if missing.

@mangelajo
Copy link
Member Author

Thank you @bkhizgiy !!

@mangelajo mangelajo merged commit 96e1a1e into main Feb 3, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants