mirror of https://github.com/dapr/dapr.git
175 lines
4.5 KiB
Go
175 lines
4.5 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
scheme "github.com/dapr/dapr/pkg/client/clientset/versioned"
|
|
daprGlobalConfig "github.com/dapr/dapr/pkg/config"
|
|
"github.com/dapr/dapr/utils"
|
|
"github.com/dapr/kit/logger"
|
|
)
|
|
|
|
const (
|
|
kubernetesServiceHostEnvVar = "KUBERNETES_SERVICE_HOST"
|
|
kubernetesConfig = "kubernetes"
|
|
selfHostedConfig = "selfhosted"
|
|
defaultWorkloadCertTTL = time.Hour * 24
|
|
defaultAllowedClockSkew = time.Minute * 15
|
|
|
|
// defaultDaprSystemConfigName is the default resource object name for Dapr System Config.
|
|
defaultDaprSystemConfigName = "daprsystem"
|
|
|
|
DefaultPort = 50001
|
|
)
|
|
|
|
var log = logger.NewLogger("dapr.sentry.config")
|
|
|
|
// SentryConfig holds the configuration for the Certificate Authority.
|
|
type SentryConfig struct {
|
|
Port int
|
|
TrustDomain string
|
|
CAStore string
|
|
WorkloadCertTTL time.Duration
|
|
AllowedClockSkew time.Duration
|
|
RootCertPath string
|
|
IssuerCertPath string
|
|
IssuerKeyPath string
|
|
Features []daprGlobalConfig.FeatureSpec
|
|
TokenAudience *string
|
|
}
|
|
|
|
func (c SentryConfig) GetTokenAudiences() (audiences []string) {
|
|
if c.TokenAudience != nil && *c.TokenAudience != "" {
|
|
audiences = strings.Split(*c.TokenAudience, ",")
|
|
}
|
|
return
|
|
}
|
|
|
|
// String implements fmt.Stringer.
|
|
func (c SentryConfig) String() string {
|
|
caStore := "default"
|
|
if c.CAStore != "" {
|
|
caStore = c.CAStore
|
|
}
|
|
|
|
return fmt.Sprintf("Configuration: port:'%v' ca store:'%s', allowed clock skew:'%s', workload cert ttl:'%s'",
|
|
c.Port, caStore, c.AllowedClockSkew.String(), c.WorkloadCertTTL.String())
|
|
}
|
|
|
|
var configGetters = map[string]func(string) (SentryConfig, error){
|
|
selfHostedConfig: getSelfhostedConfig,
|
|
kubernetesConfig: getKubernetesConfig,
|
|
}
|
|
|
|
// FromConfigName returns a Sentry configuration based on a configuration spec.
|
|
// A default configuration is loaded in case of an error.
|
|
func FromConfigName(configName string) (SentryConfig, error) {
|
|
var confGetterFn func(string) (SentryConfig, error)
|
|
|
|
if IsKubernetesHosted() {
|
|
confGetterFn = configGetters[kubernetesConfig]
|
|
} else {
|
|
confGetterFn = configGetters[selfHostedConfig]
|
|
}
|
|
|
|
conf, err := confGetterFn(configName)
|
|
if err != nil {
|
|
err = fmt.Errorf("loading default config. couldn't find config name '%s': %w", configName, err)
|
|
conf = getDefaultConfig()
|
|
}
|
|
|
|
log.Info(conf.String())
|
|
return conf, err
|
|
}
|
|
|
|
func IsKubernetesHosted() bool {
|
|
return os.Getenv(kubernetesServiceHostEnvVar) != ""
|
|
}
|
|
|
|
func getDefaultConfig() SentryConfig {
|
|
return SentryConfig{
|
|
Port: DefaultPort,
|
|
WorkloadCertTTL: defaultWorkloadCertTTL,
|
|
AllowedClockSkew: defaultAllowedClockSkew,
|
|
}
|
|
}
|
|
|
|
func getKubernetesConfig(configName string) (SentryConfig, error) {
|
|
defaultConfig := getDefaultConfig()
|
|
|
|
kubeConf := utils.GetConfig()
|
|
daprClient, err := scheme.NewForConfig(kubeConf)
|
|
if err != nil {
|
|
return defaultConfig, err
|
|
}
|
|
|
|
list, err := daprClient.ConfigurationV1alpha1().Configurations(metaV1.NamespaceAll).List(metaV1.ListOptions{})
|
|
if err != nil {
|
|
return defaultConfig, err
|
|
}
|
|
|
|
if configName == "" {
|
|
configName = defaultDaprSystemConfigName
|
|
}
|
|
|
|
for _, i := range list.Items {
|
|
if i.GetName() == configName {
|
|
spec, _ := json.Marshal(i.Spec)
|
|
|
|
var configSpec daprGlobalConfig.ConfigurationSpec
|
|
json.Unmarshal(spec, &configSpec)
|
|
|
|
conf := daprGlobalConfig.Configuration{
|
|
Spec: configSpec,
|
|
}
|
|
return parseConfiguration(defaultConfig, &conf)
|
|
}
|
|
}
|
|
return defaultConfig, errors.New("config CRD not found")
|
|
}
|
|
|
|
func getSelfhostedConfig(configName string) (SentryConfig, error) {
|
|
defaultConfig := getDefaultConfig()
|
|
daprConfig, err := daprGlobalConfig.LoadStandaloneConfiguration(configName)
|
|
if err != nil {
|
|
return defaultConfig, err
|
|
}
|
|
|
|
if daprConfig != nil {
|
|
return parseConfiguration(defaultConfig, daprConfig)
|
|
}
|
|
return defaultConfig, nil
|
|
}
|
|
|
|
func parseConfiguration(conf SentryConfig, daprConfig *daprGlobalConfig.Configuration) (SentryConfig, error) {
|
|
mtlsSpec := daprConfig.GetMTLSSpec()
|
|
if mtlsSpec.WorkloadCertTTL != "" {
|
|
d, err := time.ParseDuration(mtlsSpec.WorkloadCertTTL)
|
|
if err != nil {
|
|
return conf, fmt.Errorf("error parsing WorkloadCertTTL duration: %w", err)
|
|
}
|
|
|
|
conf.WorkloadCertTTL = d
|
|
}
|
|
|
|
if mtlsSpec.AllowedClockSkew != "" {
|
|
d, err := time.ParseDuration(mtlsSpec.AllowedClockSkew)
|
|
if err != nil {
|
|
return conf, fmt.Errorf("error parsing AllowedClockSkew duration: %w", err)
|
|
}
|
|
|
|
conf.AllowedClockSkew = d
|
|
}
|
|
|
|
conf.Features = daprConfig.Spec.Features
|
|
|
|
return conf, nil
|
|
}
|