Skip to content

Commit 6db6faf

Browse files
committed
change cert generate
Signed-off-by: tiansuo <[email protected]>
1 parent 2ce8546 commit 6db6faf

File tree

5 files changed

+705
-53
lines changed

5 files changed

+705
-53
lines changed

pkg/karmadactl/cmdinit/cert/cert.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,85 @@ func NewCertConfig(cn string, org []string, altNames certutil.AltNames, notAfter
268268
}
269269
}
270270

271+
// NewGenCerts generates a full set of certificates driven by certConfigMap and
272+
// writes them to pkiPath. It always ensures three CAs exist:
273+
// - Main CA (karmada CA)
274+
// - Front-proxy CA
275+
// - Etcd CA
276+
// Certificates are signed by CA chosen by their names:
277+
// - etcd server/client and etcd-client variants -> etcd-ca
278+
// - front-proxy-client -> front-proxy-ca
279+
// - others -> main CA
280+
func NewGenCerts(pkiPath, caCertFile, caKeyFile string, certConfigMap map[string]*CertsConfig) error {
281+
// Main CA (karmada CA)
282+
caCert, caKey, err := getCACertAndKey(caCertFile, caKeyFile)
283+
if err != nil {
284+
return err
285+
}
286+
if err = WriteCertAndKey(pkiPath, globaloptions.CaCertAndKeyName, caCert, caKey); err != nil {
287+
return err
288+
}
289+
290+
// Front-proxy CA
291+
frontProxyCaCert, frontProxyCaKey, err := NewCACertAndKey(options.FrontProxyCaCertAndKeyName)
292+
if err != nil {
293+
return err
294+
}
295+
if err = WriteCertAndKey(pkiPath, options.FrontProxyCaCertAndKeyName, frontProxyCaCert, frontProxyCaKey); err != nil {
296+
return err
297+
}
298+
299+
// Etcd CA
300+
etcdCaCert, etcdCaKey, err := NewCACertAndKey(options.EtcdCaCertAndKeyName)
301+
if err != nil {
302+
return err
303+
}
304+
if err = WriteCertAndKey(pkiPath, options.EtcdCaCertAndKeyName, etcdCaCert, etcdCaKey); err != nil {
305+
return err
306+
}
307+
308+
// Choose signing CA by cert name
309+
for certName, certConfig := range certConfigMap {
310+
if certConfig == nil {
311+
continue
312+
}
313+
314+
var signerCACert *x509.Certificate
315+
var signerCAKey crypto.Signer
316+
317+
switch certName {
318+
// etcd server/client and all etcd-client variants should be signed by etcd-ca
319+
case options.EtcdServerCertAndKeyName,
320+
options.EtcdClientCertAndKeyName,
321+
options.KarmadaAPIServerEtcdClientCertAndKeyName,
322+
options.KarmadaAggregatedAPIServerEtcdClientCertAndKeyName,
323+
options.KarmadaSearchEtcdClientCertAndKeyName:
324+
signerCACert = etcdCaCert
325+
signerCAKey = *etcdCaKey
326+
327+
// front-proxy client should be signed by front-proxy-ca
328+
case options.FrontProxyClientCertAndKeyName:
329+
signerCACert = frontProxyCaCert
330+
signerCAKey = *frontProxyCaKey
331+
332+
// default: signed by main karmada CA
333+
default:
334+
signerCACert = caCert
335+
signerCAKey = *caKey
336+
}
337+
338+
cert, key, err := NewCertAndKey(signerCACert, signerCAKey, certConfig)
339+
if err != nil {
340+
return err
341+
}
342+
if err = WriteCertAndKey(pkiPath, certName, cert, &key); err != nil {
343+
return err
344+
}
345+
}
346+
347+
return nil
348+
}
349+
271350
// GenCerts Create CA certificate and sign etcd karmada certificate.
272351
func GenCerts(pkiPath, caCertFile, caKeyFile string, etcdServerCertCfg, etcdClientCertCfg, karmadaCertCfg, apiserverCertCfg, frontProxyClientCertCfg *CertsConfig) error {
273352
caCert, caKey, err := getCACertAndKey(caCertFile, caKeyFile)

pkg/karmadactl/cmdinit/cert/cert_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package cert
1818

1919
import (
2020
"crypto/sha256"
21+
"crypto/x509"
22+
"encoding/pem"
2123
"fmt"
2224
"io"
2325
"net"
@@ -29,7 +31,9 @@ import (
2931
certutil "k8s.io/client-go/util/cert"
3032
"k8s.io/klog/v2"
3133

34+
initopt "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/options"
3235
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
36+
globalopt "github.com/karmada-io/karmada/pkg/karmadactl/options"
3337
"github.com/karmada-io/karmada/pkg/util/names"
3438
)
3539

@@ -189,3 +193,63 @@ func compareCertFilesInDirs(dir1, dir2, filename string) (bool, error) {
189193
file2 := filepath.Join(dir2, filename)
190194
return compareFiles(file1, file2)
191195
}
196+
197+
// helper: read certificate from dir/name.{crt}
198+
func readCertFromPath(t *testing.T, dir, name string) *x509.Certificate {
199+
t.Helper()
200+
b, err := os.ReadFile(filepath.Join(dir, fmt.Sprintf("%s.crt", name)))
201+
if err != nil {
202+
t.Fatalf("failed reading cert %s: %v", name, err)
203+
}
204+
blk, _ := pem.Decode(b)
205+
if blk == nil {
206+
t.Fatalf("failed decoding PEM for %s", name)
207+
}
208+
crt, err := x509.ParseCertificate(blk.Bytes)
209+
if err != nil {
210+
t.Fatalf("failed parsing x509 for %s: %v", name, err)
211+
}
212+
return crt
213+
}
214+
215+
// TestNewGenCerts_CASelection verifies certificates are signed by the expected CA
216+
// according to their names: etcd-* by etcd-ca, front-proxy-client by front-proxy-ca,
217+
// others by main CA.
218+
func TestNewGenCerts_CASelection(t *testing.T) {
219+
dir := t.TempDir()
220+
notAfter := time.Now().Add(Duration365d).UTC()
221+
222+
cfg := map[string]*CertsConfig{
223+
// main CA signer
224+
initopt.KarmadaAPIServerCertAndKeyName: NewCertConfig(initopt.KarmadaAPIServerCN, nil, certutil.AltNames{DNSNames: []string{"localhost"}, IPs: []net.IP{utils.StringToNetIP("127.0.0.1")}}, &notAfter),
225+
// front-proxy CA signer
226+
initopt.FrontProxyClientCertAndKeyName: NewCertConfig(initopt.KarmadaFrontProxyClientCN, nil, certutil.AltNames{}, &notAfter),
227+
// etcd CA signer
228+
initopt.KarmadaAPIServerEtcdClientCertAndKeyName: NewCertConfig(initopt.KarmadaAPIServerEtcdClientCN, nil, certutil.AltNames{}, &notAfter),
229+
}
230+
231+
if err := NewGenCerts(dir, "", "", cfg); err != nil {
232+
t.Fatalf("NewGenCerts error: %v", err)
233+
}
234+
235+
// load CA certs
236+
ca := readCertFromPath(t, dir, globalopt.CaCertAndKeyName)
237+
etcdCA := readCertFromPath(t, dir, initopt.EtcdCaCertAndKeyName)
238+
fpCA := readCertFromPath(t, dir, initopt.FrontProxyCaCertAndKeyName)
239+
240+
cases := []struct {
241+
name string
242+
expected string
243+
}{
244+
{initopt.KarmadaAPIServerCertAndKeyName, ca.Subject.CommonName},
245+
{initopt.FrontProxyClientCertAndKeyName, fpCA.Subject.CommonName},
246+
{initopt.KarmadaAPIServerEtcdClientCertAndKeyName, etcdCA.Subject.CommonName},
247+
}
248+
249+
for _, tc := range cases {
250+
crt := readCertFromPath(t, dir, tc.name)
251+
if got := crt.Issuer.CommonName; got != tc.expected {
252+
t.Fatalf("%s issuer CN = %q, want %q", tc.name, got, tc.expected)
253+
}
254+
}
255+
}

0 commit comments

Comments
 (0)