karmada/operator/pkg/certs/store.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
}