dynamo/deploy/operator/internal/secrets/docker.go

73 lines
2.1 KiB
Go

package secrets
import (
"context"
"encoding/json"
"fmt"
"sync"
"github.com/ai-dynamo/dynamo/deploy/operator/internal/common"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type DockerSecretIndexer struct {
// maps for a namespace, a docker registry server to a list of secret names
secrets map[string]map[string][]string
client client.Client
mu sync.RWMutex
}
func NewDockerSecretIndexer(client client.Client) *DockerSecretIndexer {
return &DockerSecretIndexer{
secrets: make(map[string]map[string][]string),
client: client,
}
}
func (i *DockerSecretIndexer) RefreshIndex(ctx context.Context) error {
// scan for all secrets in the namespace
secrets := &corev1.SecretList{}
if err := i.client.List(ctx, secrets); err != nil {
return fmt.Errorf("unable to list secrets: %w", err)
}
tmpSecrets := make(map[string]map[string][]string)
for _, secret := range secrets.Items {
if secret.Type == corev1.SecretTypeDockerConfigJson {
// unmarshal the secret data
dockerConfig := &struct {
Auths map[string]any `json:"auths"`
}{}
if err := json.Unmarshal(secret.Data[corev1.DockerConfigJsonKey], dockerConfig); err != nil {
return fmt.Errorf("unable to unmarshal docker config json for secret %s: %w", secret.Name, err)
}
namespace := secret.Namespace
if _, ok := tmpSecrets[namespace]; !ok {
tmpSecrets[namespace] = make(map[string][]string)
}
for auth := range dockerConfig.Auths {
// retrieve the registry host
registry, err := common.GetHost(auth)
if err != nil {
return fmt.Errorf("unable to get host for registry %s for secret %s: %w", auth, secret.Name, err)
}
tmpSecrets[namespace][registry] = append(tmpSecrets[namespace][registry], secret.Name)
}
}
}
i.mu.Lock()
defer i.mu.Unlock()
i.secrets = tmpSecrets
return nil
}
func (i *DockerSecretIndexer) GetSecrets(namespace, registry string) ([]string, error) {
registry, err := common.GetHost(registry)
if err != nil {
return nil, err
}
i.mu.RLock()
defer i.mu.RUnlock()
return i.secrets[namespace][registry], nil
}