Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ on:

jobs:
e2e-tests:
runs-on: ubuntu-latest
strategy:
matrix:
os:
- ubuntu-24.04
- ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
steps:
- uses: jumpstarter-dev/jumpstarter-e2e@main
with:
Expand Down
25 changes: 21 additions & 4 deletions .github/workflows/pr-kind.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,32 @@ on:
pull_request:
branches:
- main

jobs:
deploy-kind:
runs-on: ubuntu-latest
deploy-kind-matrix:
strategy:
matrix:
os:
- ubuntu-24.04
- ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Run make deploy
run: make deploy
# https://github.com/orgs/community/discussions/26822
deploy-kind:
runs-on: ubuntu-latest
needs:
- deploy-kind-matrix
if: ${{ always() }}
steps:
- run: exit 1
if: >-
${{
contains(needs.*.result, 'failure')
|| contains(needs.*.result, 'cancelled')
|| contains(needs.*.result, 'skipped')
}}
3 changes: 1 addition & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"crypto/tls"
"encoding/pem"
"flag"
"net"
"os"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
Expand Down Expand Up @@ -135,7 +134,7 @@ func main() {
os.Exit(1)
}

oidcCert, err := service.NewSelfSignedCertificate("jumpstarter oidc", []string{"localhost"}, []net.IP{})
oidcCert, err := service.NewSelfSignedLocalhostCertificate()
if err != nil {
setupLog.Error(err, "unable to generate certificate for internal oidc provider")
os.Exit(1)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
{{- define "router.endpoint" }}{{ if .Values.grpc.routerHostname }}{{ .Values.grpc.routerHostname }}{{ else }}router.{{ .Values.global.baseDomain | required "grpc.routerHostname or global.baseDomain must be set"}}{{ end }}{{- end }}
{{- define "controller.endpoint" }}{{ if .Values.grpc.hostname }}{{ .Values.grpc.hostname }}{{ else }}grpc.{{ .Values.global.baseDomain | required "grpc.hostname or global.baseDomain must be set"}}{{ end }}{{- end }}
{{- define "controller.endpoint" }}{{ if .Values.grpc.endpoint }}{{ .Values.grpc.endpoint }}{{ else if .Values.hostname }}{{ .Values.hostname }}:{{ .Values.grpc.tls.port }}{{ else }}grpc.{{ .Values.global.baseDomain | required "grpc.endpoint or hostname or global.baseDomain must be set" }}:{{ .Values.grpc.tls.port }}{{ end }}{{- end }}
{{- define "router.endpoint" }}{{ if .Values.grpc.routerEndpoint }}{{ .Values.grpc.routerEndpoint }}{{ else if .Values.routerHostname }}{{ .Values.routerHostname }}:{{ .Values.grpc.tls.port }}{{ else }}router.{{ .Values.global.baseDomain | required "grpc.routerEndpoint or routerHostname or global.baseDomain must be set" }}:{{ .Values.grpc.tls.port }}{{ end }}{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,20 @@ spec:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- name: tls
secret:
secretName: jumpstarter-tls
containers:
- args:
- --leader-elect
- --health-probe-bind-address=:8081
- -metrics-bind-address=:8080
env:
- name: GRPC_ENDPOINT
{{ if .Values.grpc.endpoint }}
value : {{ .Values.grpc.endpoint }}
{{ else if .Values.hostname }}
value: {{ .Values.hostname }}:{{ .Values.grpc.tls.port }}
{{ else }}
value: grpc.{{ .Values.global.baseDomain }}:{{ .Values.grpc.tls.port }}
{{ end }}
value: {{ template "controller.endpoint" . }}
- name: GRPC_ROUTER_ENDPOINT
{{ if .Values.grpc.routerEndpoint }}
value: {{ .Values.grpc.routerEndpoint }}
{{ else if .Values.routerHostname }}
value: {{ .Values.routerHostname }}:{{ .Values.grpc.tls.port }}
{{ else }}
value: router.{{ .Values.global.baseDomain }}:{{ .Values.grpc.tls.port }}
{{ end }}
value: {{ template "router.endpoint" . }}
- name: CONTROLLER_KEY
valueFrom:
secretKeyRef:
Expand All @@ -84,6 +76,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: tls
mountPath: "/etc/jumpstarter/tls"
readOnly: true

image: {{ .Values.image }}:{{ default .Chart.AppVersion .Values.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,43 @@ spec:
metadata:
name: jumpstarter-secrets
spec:
ttlSecondsAfterFinished: 600
serviceAccountName: controller-manager
containers:
- name: jumpstarter-secrets
image: quay.io/openshift/origin-cli
image: quay.io/jumpstarter-dev/jumpstarter-utils:latest
command:
- /bin/sh
- -c
- |
set -e

CONTROLLER_HOSTNAME=$(trurl {{ template "controller.endpoint" . }} --get "{host}")
ROUTER_HOSTNAME=$(trurl {{ template "router.endpoint" . }} --get "{host}")

export EASYRSA_BATCH=1
export EASYRSA_PKI=pki
/usr/share/easy-rsa/3/easyrsa init-pki
/usr/share/easy-rsa/3/easyrsa --no-pass build-ca
/usr/share/easy-rsa/3/easyrsa --no-pass \
--subject-alt-name=DNS:"${CONTROLLER_HOSTNAME}" \
--subject-alt-name=DNS:"${ROUTER_HOSTNAME}" \
build-server-full "${CONTROLLER_HOSTNAME}"

if ! kubectl get secret jumpstarter-tls-ca -n {{ $namespace }} >/dev/null 2>&1; then
kubectl create secret tls jumpstarter-tls-ca -n={{ $namespace }} \
--cert=pki/ca.crt --key=pki/private/ca.key
fi

if ! kubectl get secret jumpstarter-tls -n {{ $namespace }} >/dev/null 2>&1; then
kubectl create secret tls jumpstarter-tls -n={{ $namespace }} \
--cert=pki/issued/"${CONTROLLER_HOSTNAME}".crt \
--key=pki/private/"${CONTROLLER_HOSTNAME}".key
fi

{{- range $name := tuple "jumpstarter-router-secret" "jumpstarter-controller-secret" }}
if ! oc get secret {{ $name }} -n {{ $namespace }} >/dev/null 2>&1; then
oc create secret generic {{ $name }} -n={{ $namespace }} \
if ! kubectl get secret {{ $name }} -n {{ $namespace }} >/dev/null 2>&1; then
kubectl create secret generic {{ $name }} -n={{ $namespace }} \
--from-literal=key="$(openssl rand -hex 32)"
fi
{{- end }}
Expand Down
7 changes: 1 addition & 6 deletions internal/service/controller_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,12 +699,7 @@ func (s *ControllerService) ListLeases(
func (s *ControllerService) Start(ctx context.Context) error {
logger := log.FromContext(ctx)

dnsnames, ipaddresses, err := endpointToSAN(controllerEndpoint())
if err != nil {
return err
}

cert, err := NewSelfSignedCertificate("jumpstarter controller", dnsnames, ipaddresses)
cert, err := LoadCertificate("/etc/jumpstarter/tls/")
if err != nil {
return err
}
Expand Down
22 changes: 0 additions & 22 deletions internal/service/endpoints.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,13 @@
package service

import (
"net"
"os"
)

func controllerEndpoint() string {
ep := os.Getenv("GRPC_ENDPOINT")
if ep == "" {
return "localhost:8082"
}
return ep
}

func routerEndpoint() string {
ep := os.Getenv("GRPC_ROUTER_ENDPOINT")
if ep == "" {
return "localhost:8083"
}
return ep
}

func endpointToSAN(endpoint string) ([]string, []net.IP, error) {
host, _, err := net.SplitHostPort(endpoint)
if err != nil {
return nil, nil, err
}
ip := net.ParseIP(host)
if ip != nil {
return []string{}, []net.IP{ip}, nil
} else {
return []string{host}, []net.IP{}, nil
}
}
7 changes: 1 addition & 6 deletions internal/service/router_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,7 @@ func (s *RouterService) Stream(stream pb.RouterService_StreamServer) error {
func (s *RouterService) Start(ctx context.Context) error {
log := log.FromContext(ctx)

dnsnames, ipaddresses, err := endpointToSAN(routerEndpoint())
if err != nil {
return err
}

cert, err := NewSelfSignedCertificate("jumpstarter router", dnsnames, ipaddresses)
cert, err := LoadCertificate("/etc/jumpstarter/tls/")
if err != nil {
return err
}
Expand Down
28 changes: 22 additions & 6 deletions internal/service/selfsigned.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,36 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"net"
"os"
"path"
"time"
)

func NewSelfSignedCertificate(commonName string, dnsnames []string, ipaddresses []net.IP) (*tls.Certificate, error) {
func LoadCertificate(base string) (*tls.Certificate, error) {
crt, err := os.ReadFile(path.Join(base, "tls.crt"))
if err != nil {
return nil, err
}
key, err := os.ReadFile(path.Join(base, "tls.key"))
if err != nil {
return nil, err
}
cert, err := tls.X509KeyPair(crt, key)
if err != nil {
return nil, err
}
return &cert, nil
}

func NewSelfSignedLocalhostCertificate() (*tls.Certificate, error) {
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: commonName},
Issuer: pkix.Name{CommonName: commonName},
Subject: pkix.Name{CommonName: "localhost"},
Issuer: pkix.Name{CommonName: "localhost"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
BasicConstraintsValid: true,
DNSNames: dnsnames,
IPAddresses: ipaddresses,
DNSNames: []string{"localhost"},
}

priv, err := rsa.GenerateKey(rand.Reader, 2048)
Expand Down