124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
/*
|
|
Copyright 2023 The Karmada Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package certs
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
)
|
|
|
|
// CertStore is an Interface that define the cert read and store operator to a cache.
|
|
// And we can load a set of certs form a k8s secret.
|
|
type CertStore interface {
|
|
AddCert(cert *KarmadaCert)
|
|
GetCert(name string) *KarmadaCert
|
|
CertList() []*KarmadaCert
|
|
LoadCertFromSecret(secret *corev1.Secret) error
|
|
}
|
|
|
|
type splitToPairNameFunc func(name string) string
|
|
|
|
// SplitToPairName is default function to split cert pair name
|
|
// from a secret data key. It only works in this format:
|
|
// karmada.crt, karmada.key.
|
|
func SplitToPairName(name string) string {
|
|
if strings.Contains(name, keyExtension) {
|
|
strArr := strings.Split(name, keyExtension)
|
|
return strArr[0]
|
|
}
|
|
|
|
if strings.Contains(name, certExtension) {
|
|
strArr := strings.Split(name, certExtension)
|
|
return strArr[0]
|
|
}
|
|
|
|
return name
|
|
}
|
|
|
|
// KarmadaCertStore is a cache to store karmada certificate. the key is cert baseName by default.
|
|
type KarmadaCertStore struct {
|
|
certs map[string]*KarmadaCert
|
|
pairNameFunc splitToPairNameFunc
|
|
}
|
|
|
|
// NewCertStore returns a cert store. It use default SplitToPairName function to
|
|
// get cert pair name form cert file name.
|
|
func NewCertStore() CertStore {
|
|
return &KarmadaCertStore{
|
|
certs: make(map[string]*KarmadaCert),
|
|
pairNameFunc: SplitToPairName,
|
|
}
|
|
}
|
|
|
|
// AddCert adds a cert to cert store, the cache key is cert pairName by default.
|
|
func (store *KarmadaCertStore) AddCert(cert *KarmadaCert) {
|
|
store.certs[cert.pairName] = cert
|
|
}
|
|
|
|
// GetCert get cert from store by cert pairName.
|
|
func (store *KarmadaCertStore) GetCert(name string) *KarmadaCert {
|
|
for _, c := range store.certs {
|
|
if c.pairName == name {
|
|
return c
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CertList lists all of karmada certs in the cert cache.
|
|
func (store *KarmadaCertStore) CertList() []*KarmadaCert {
|
|
certs := make([]*KarmadaCert, 0, len(store.certs))
|
|
|
|
for _, c := range store.certs {
|
|
certs = append(certs, c)
|
|
}
|
|
|
|
return certs
|
|
}
|
|
|
|
// LoadCertFromSecret loads a set of certs form k8s secret resource. we get cert
|
|
// cache key by calling the pairNameFunc function. if the secret data key suffix is ".crt",
|
|
// it be considered cert data. if the suffix is ".key", it be considered cert key data.
|
|
func (store *KarmadaCertStore) LoadCertFromSecret(secret *corev1.Secret) error {
|
|
if len(secret.Data) == 0 {
|
|
return fmt.Errorf("cert data is empty")
|
|
}
|
|
|
|
for name, data := range secret.Data {
|
|
pairName := store.pairNameFunc(name)
|
|
kc := store.GetCert(pairName)
|
|
if kc == nil {
|
|
kc = &KarmadaCert{
|
|
pairName: pairName,
|
|
}
|
|
}
|
|
|
|
if strings.Contains(name, certExtension) {
|
|
kc.cert = data
|
|
}
|
|
if strings.Contains(name, keyExtension) {
|
|
kc.key = data
|
|
}
|
|
|
|
store.AddCert(kc)
|
|
}
|
|
|
|
return nil
|
|
}
|