mirror of https://github.com/dapr/dapr.git
Allow passing multiple `--config` flags to daprd in standalone mode
Spin-off from #6101 where support for Kubernetes mode has been dropped, to avoid modifying the CRDs. Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
parent
46813f2fd2
commit
1e268507d1
|
|
@ -135,6 +135,7 @@ linters-settings:
|
|||
- "github.com/cenkalti/backoff/v3": "must use github.com/cenkalti/backoff/v4"
|
||||
- "github.com/benbjohnson/clock": "must use k8s.io/utils/clock"
|
||||
- "github.com/ghodss/yaml": "must use sigs.k8s.io/yaml"
|
||||
- "gopkg.in/yaml.v2": "must use gopkg.in/yaml.v3"
|
||||
misspell:
|
||||
# Correct spellings using locale preferences for US or UK.
|
||||
# Default is to use a neutral variety of English.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1
|
|||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.9.2
|
||||
controller-gen.kubebuilder.io/version: v0.11.3
|
||||
creationTimestamp: null
|
||||
name: configurations.dapr.io
|
||||
labels:
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ func main() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Infof("starting Dapr Runtime -- version %s -- commit %s", buildinfo.Version(), buildinfo.Commit())
|
||||
log.Infof("log level set to: %s", opts.Logger.OutputLevel)
|
||||
log.Infof("Starting Dapr Runtime -- version %s -- commit %s", buildinfo.Version(), buildinfo.Commit())
|
||||
log.Infof("Log level set to: %s", opts.Logger.OutputLevel)
|
||||
|
||||
rt, err := runtime.FromConfig(&runtime.Config{
|
||||
AppID: opts.AppID,
|
||||
|
|
@ -108,7 +108,7 @@ func main() {
|
|||
AppHealthThreshold: opts.AppHealthThreshold,
|
||||
AppChannelAddress: opts.AppChannelAddress,
|
||||
EnableAPILogging: opts.EnableAPILogging,
|
||||
ConfigPath: opts.ConfigPath,
|
||||
Config: opts.Config,
|
||||
Metrics: opts.Metrics,
|
||||
AppSSL: opts.AppSSL,
|
||||
ComponentsPath: opts.ComponentsPath,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ limitations under the License.
|
|||
package options
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -61,7 +60,7 @@ type Options struct {
|
|||
AppHealthThreshold int
|
||||
EnableAppHealthCheck bool
|
||||
Mode string
|
||||
ConfigPath string
|
||||
Config stringSliceFlag
|
||||
UnixDomainSocket string
|
||||
DaprHTTPReadBufferSize int
|
||||
DisableBuiltinK8sSecretStore bool
|
||||
|
|
@ -87,7 +86,7 @@ func New(args []string) *Options {
|
|||
flag.StringVar(&opts.AppProtocol, "app-protocol", string(protocol.HTTPProtocol), "Protocol for the application: grpc, grpcs, http, https, h2c")
|
||||
flag.StringVar(&opts.ComponentsPath, "components-path", "", "Alias for --resources-path [Deprecated, use --resources-path]")
|
||||
flag.Var(&opts.ResourcesPath, "resources-path", "Path for resources directory. If not specified, no resources will be loaded. Can be passed multiple times")
|
||||
flag.StringVar(&opts.ConfigPath, "config", "", "Path to config file, or name of a configuration object")
|
||||
flag.Var(&opts.Config, "config", "Path to config file, or name of a configuration object. In standalone mode, can be passed multiple times")
|
||||
flag.StringVar(&opts.AppID, "app-id", "", "A unique ID for Dapr. Used for Service Discovery and state")
|
||||
flag.StringVar(&opts.ControlPlaneAddress, "control-plane-address", "", "Address for a Dapr control plane")
|
||||
flag.StringVar(&opts.SentryAddress, "sentry-address", "", "Address for the Sentry CA service")
|
||||
|
|
@ -151,7 +150,7 @@ func (f stringSliceFlag) String() string {
|
|||
// Set the flag value.
|
||||
func (f *stringSliceFlag) Set(value string) error {
|
||||
if value == "" {
|
||||
return errors.New("value is empty")
|
||||
return nil
|
||||
}
|
||||
*f = append(*f, value)
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -40,5 +40,5 @@ func TestStandaloneGlobalConfig(t *testing.T) {
|
|||
opts := New([]string{"--app-id", "testapp", "--mode", string(modes.StandaloneMode), "--config", "../../../pkg/config/testdata/metric_disabled.yaml", "--metrics-port", strconv.Itoa(10000)})
|
||||
assert.EqualValues(t, "testapp", opts.AppID)
|
||||
assert.EqualValues(t, string(modes.StandaloneMode), opts.Mode)
|
||||
assert.Equal(t, "../../../pkg/config/testdata/metric_disabled.yaml", opts.ConfigPath)
|
||||
assert.Equal(t, []string{"../../../pkg/config/testdata/metric_disabled.yaml"}, []string(opts.Config))
|
||||
}
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -62,7 +62,7 @@ require (
|
|||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
|
||||
google.golang.org/grpc v1.54.0
|
||||
google.golang.org/protobuf v1.30.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/apiextensions-apiserver v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
|
|
@ -399,7 +399,7 @@ require (
|
|||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/component-base v0.26.3 // indirect
|
||||
k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
|
|
|
|||
|
|
@ -35,25 +35,26 @@ import (
|
|||
var log = logger.NewLogger("dapr.acl")
|
||||
|
||||
// ParseAccessControlSpec creates an in-memory copy of the Access Control Spec for fast lookup.
|
||||
func ParseAccessControlSpec(accessControlSpec config.AccessControlSpec, isHTTP bool) (*config.AccessControlList, error) {
|
||||
if accessControlSpec.TrustDomain == "" &&
|
||||
accessControlSpec.DefaultAction == "" &&
|
||||
(accessControlSpec.AppPolicies == nil || len(accessControlSpec.AppPolicies) == 0) {
|
||||
func ParseAccessControlSpec(accessControlSpec *config.AccessControlSpec, isHTTP bool) (*config.AccessControlList, error) {
|
||||
if accessControlSpec == nil ||
|
||||
(accessControlSpec.TrustDomain == "" &&
|
||||
accessControlSpec.DefaultAction == "" &&
|
||||
len(accessControlSpec.AppPolicies) == 0) {
|
||||
// No ACL has been specified
|
||||
log.Debugf("No Access control policy specified")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var accessControlList config.AccessControlList
|
||||
accessControlList.PolicySpec = make(map[string]config.AccessControlListPolicySpec)
|
||||
accessControlList.DefaultAction = strings.ToLower(accessControlSpec.DefaultAction)
|
||||
accessControlList := config.AccessControlList{
|
||||
PolicySpec: make(map[string]config.AccessControlListPolicySpec),
|
||||
DefaultAction: strings.ToLower(accessControlSpec.DefaultAction),
|
||||
TrustDomain: accessControlSpec.TrustDomain,
|
||||
}
|
||||
|
||||
accessControlList.TrustDomain = accessControlSpec.TrustDomain
|
||||
if accessControlSpec.TrustDomain == "" {
|
||||
accessControlList.TrustDomain = config.DefaultTrustDomain
|
||||
}
|
||||
|
||||
accessControlList.DefaultAction = accessControlSpec.DefaultAction
|
||||
if accessControlSpec.DefaultAction == "" {
|
||||
if accessControlSpec.AppPolicies == nil || len(accessControlSpec.AppPolicies) > 0 {
|
||||
// Some app level policies have been specified but not default global action is set. Default to more secure option - Deny
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dapr/dapr/pkg/config"
|
||||
"github.com/dapr/dapr/pkg/proto/common/v1"
|
||||
|
|
@ -130,7 +131,7 @@ func initializeAccessControlList(isHTTP bool) (*config.AccessControlList, error)
|
|||
},
|
||||
},
|
||||
}
|
||||
accessControlList, err := ParseAccessControlSpec(inputSpec, isHTTP)
|
||||
accessControlList, err := ParseAccessControlSpec(&inputSpec, isHTTP)
|
||||
|
||||
return accessControlList, err
|
||||
}
|
||||
|
|
@ -139,7 +140,7 @@ func TestParseAccessControlSpec(t *testing.T) {
|
|||
t.Run("translate to in-memory rules", func(t *testing.T) {
|
||||
accessControlList, err := initializeAccessControlList(true)
|
||||
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, config.DenyAccess, accessControlList.DefaultAction)
|
||||
assert.Equal(t, "abcd", accessControlList.TrustDomain)
|
||||
|
|
@ -237,7 +238,7 @@ func TestParseAccessControlSpec(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("test when no trust domain and namespace specified in app policy", func(t *testing.T) {
|
||||
invalidAccessControlSpec := config.AccessControlSpec{
|
||||
invalidAccessControlSpec := &config.AccessControlSpec{
|
||||
DefaultAction: config.DenyAccess,
|
||||
TrustDomain: "public",
|
||||
AppPolicies: []config.AppPolicySpec{
|
||||
|
|
@ -300,7 +301,7 @@ func TestParseAccessControlSpec(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("test when no trust domain is specified for the app", func(t *testing.T) {
|
||||
accessControlSpec := config.AccessControlSpec{
|
||||
accessControlSpec := &config.AccessControlSpec{
|
||||
DefaultAction: config.DenyAccess,
|
||||
TrustDomain: "",
|
||||
AppPolicies: []config.AppPolicySpec{
|
||||
|
|
@ -330,18 +331,23 @@ func TestParseAccessControlSpec(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("test when no access control policy has been specified", func(t *testing.T) {
|
||||
invalidAccessControlSpec := config.AccessControlSpec{
|
||||
accessControlList, err := ParseAccessControlSpec(nil, true)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, accessControlList)
|
||||
|
||||
invalidAccessControlSpec := &config.AccessControlSpec{
|
||||
DefaultAction: "",
|
||||
TrustDomain: "",
|
||||
AppPolicies: []config.AppPolicySpec{},
|
||||
}
|
||||
|
||||
accessControlList, _ := ParseAccessControlSpec(invalidAccessControlSpec, true)
|
||||
accessControlList, _ = ParseAccessControlSpec(invalidAccessControlSpec, true)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, accessControlList)
|
||||
})
|
||||
|
||||
t.Run("test when no default global action has been specified", func(t *testing.T) {
|
||||
invalidAccessControlSpec := config.AccessControlSpec{
|
||||
invalidAccessControlSpec := &config.AccessControlSpec{
|
||||
TrustDomain: "public",
|
||||
AppPolicies: []config.AppPolicySpec{
|
||||
{
|
||||
|
|
@ -377,25 +383,25 @@ func TestSpiffeID(t *testing.T) {
|
|||
assert.Equal(t, "mydomain", id.TrustDomain)
|
||||
assert.Equal(t, "mynamespace", id.Namespace)
|
||||
assert.Equal(t, "myappid", id.AppID)
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("test parse invalid spiffe id", func(t *testing.T) {
|
||||
spiffeID := "abcd"
|
||||
_, err := parseSpiffeID(spiffeID)
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("test parse spiffe id with not all fields", func(t *testing.T) {
|
||||
spiffeID := "spiffe://mydomain/ns/myappid"
|
||||
_, err := parseSpiffeID(spiffeID)
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("test empty spiffe id", func(t *testing.T) {
|
||||
spiffeID := ""
|
||||
_, err := parseSpiffeID(spiffeID)
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,31 +36,31 @@ type Configuration struct {
|
|||
// ConfigurationSpec is the spec for an configuration.
|
||||
type ConfigurationSpec struct {
|
||||
// +optional
|
||||
AppHTTPPipelineSpec PipelineSpec `json:"appHttpPipeline,omitempty"`
|
||||
AppHTTPPipelineSpec *PipelineSpec `json:"appHttpPipeline,omitempty"`
|
||||
// +optional
|
||||
HTTPPipelineSpec PipelineSpec `json:"httpPipeline,omitempty"`
|
||||
HTTPPipelineSpec *PipelineSpec `json:"httpPipeline,omitempty"`
|
||||
// +optional
|
||||
TracingSpec TracingSpec `json:"tracing,omitempty"`
|
||||
TracingSpec *TracingSpec `json:"tracing,omitempty"`
|
||||
// +kubebuilder:default={enabled:true}
|
||||
MetricSpec MetricSpec `json:"metric,omitempty"`
|
||||
MetricSpec *MetricSpec `json:"metric,omitempty"`
|
||||
// +kubebuilder:default={enabled:true}
|
||||
MetricsSpec MetricSpec `json:"metrics,omitempty"`
|
||||
MetricsSpec *MetricSpec `json:"metrics,omitempty"`
|
||||
// +optional
|
||||
MTLSSpec MTLSSpec `json:"mtls,omitempty"`
|
||||
MTLSSpec *MTLSSpec `json:"mtls,omitempty"`
|
||||
// +optional
|
||||
Secrets SecretsSpec `json:"secrets,omitempty"`
|
||||
Secrets *SecretsSpec `json:"secrets,omitempty"`
|
||||
// +optional
|
||||
AccessControlSpec AccessControlSpec `json:"accessControl,omitempty"`
|
||||
AccessControlSpec *AccessControlSpec `json:"accessControl,omitempty"`
|
||||
// +optional
|
||||
NameResolutionSpec NameResolutionSpec `json:"nameResolution,omitempty"`
|
||||
NameResolutionSpec *NameResolutionSpec `json:"nameResolution,omitempty"`
|
||||
// +optional
|
||||
Features []FeatureSpec `json:"features,omitempty"`
|
||||
// +optional
|
||||
APISpec APISpec `json:"api,omitempty"`
|
||||
APISpec *APISpec `json:"api,omitempty"`
|
||||
// +optional
|
||||
ComponentsSpec ComponentsSpec `json:"components,omitempty"`
|
||||
ComponentsSpec *ComponentsSpec `json:"components,omitempty"`
|
||||
// +optional
|
||||
LoggingSpec LoggingSpec `json:"logging,omitempty"`
|
||||
LoggingSpec *LoggingSpec `json:"logging,omitempty"`
|
||||
}
|
||||
|
||||
// APISpec describes the configuration for Dapr APIs.
|
||||
|
|
@ -78,14 +78,14 @@ type APIAccessRule struct {
|
|||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
// +optional
|
||||
Protocol string `json:"protocol"`
|
||||
Protocol string `json:"protocol,omitempty"`
|
||||
}
|
||||
|
||||
// NameResolutionSpec is the spec for name resolution configuration.
|
||||
type NameResolutionSpec struct {
|
||||
Component string `json:"component"`
|
||||
Version string `json:"version"`
|
||||
Configuration DynamicValue `json:"configuration"`
|
||||
Component string `json:"component"`
|
||||
Version string `json:"version"`
|
||||
Configuration *DynamicValue `json:"configuration"`
|
||||
}
|
||||
|
||||
// SecretsSpec is the spec for secrets configuration.
|
||||
|
|
@ -95,9 +95,9 @@ type SecretsSpec struct {
|
|||
|
||||
// SecretsScope defines the scope for secrets.
|
||||
type SecretsScope struct {
|
||||
StoreName string `json:"storeName"`
|
||||
// +optional
|
||||
DefaultAccess string `json:"defaultAccess,omitempty"`
|
||||
StoreName string `json:"storeName"`
|
||||
// +optional
|
||||
AllowedSecrets []string `json:"allowedSecrets,omitempty"`
|
||||
// +optional
|
||||
|
|
@ -111,18 +111,25 @@ type PipelineSpec struct {
|
|||
|
||||
// HandlerSpec defines a request handlers.
|
||||
type HandlerSpec struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
SelectorSpec SelectorSpec `json:"selector,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
// +optional
|
||||
SelectorSpec *SelectorSpec `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// MTLSSpec defines mTLS configuration.
|
||||
type MTLSSpec struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
// +optional
|
||||
WorkloadCertTTL string `json:"workloadCertTTL"`
|
||||
WorkloadCertTTL *string `json:"workloadCertTTL,omitempty"`
|
||||
// +optional
|
||||
AllowedClockSkew string `json:"allowedClockSkew"`
|
||||
AllowedClockSkew *string `json:"allowedClockSkew,omitempty"`
|
||||
}
|
||||
|
||||
// GetEnabled returns true if mTLS is enabled.
|
||||
func (m *MTLSSpec) GetEnabled() bool {
|
||||
// Defaults to true if unset
|
||||
return m == nil || m.Enabled == nil || *m.Enabled
|
||||
}
|
||||
|
||||
// SelectorSpec selects target services to which the handler is to be applied.
|
||||
|
|
@ -140,18 +147,18 @@ type SelectorField struct {
|
|||
type TracingSpec struct {
|
||||
SamplingRate string `json:"samplingRate"`
|
||||
// +optional
|
||||
Stdout bool `json:"stdout"`
|
||||
Stdout *bool `json:"stdout,omitempty"`
|
||||
// +optional
|
||||
Zipkin ZipkinSpec `json:"zipkin"`
|
||||
Zipkin *ZipkinSpec `json:"zipkin,omitempty"`
|
||||
// +optional
|
||||
Otel OtelSpec `json:"otel"`
|
||||
Otel *OtelSpec `json:"otel,omitempty"`
|
||||
}
|
||||
|
||||
// OtelSpec defines Otel exporter configurations.
|
||||
type OtelSpec struct {
|
||||
Protocol string `json:"protocol" yaml:"protocol"`
|
||||
EndpointAddress string `json:"endpointAddress" yaml:"endpointAddress"`
|
||||
IsSecure bool `json:"isSecure" yaml:"isSecure"`
|
||||
IsSecure *bool `json:"isSecure" yaml:"isSecure"`
|
||||
}
|
||||
|
||||
// ZipkinSpec defines Zipkin trace configurations.
|
||||
|
|
@ -161,9 +168,9 @@ type ZipkinSpec struct {
|
|||
|
||||
// MetricSpec defines metrics configuration.
|
||||
type MetricSpec struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
// +optional
|
||||
Rules []MetricsRule `json:"rules"`
|
||||
Rules []MetricsRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// MetricsRule defines configuration options for a metric.
|
||||
|
|
@ -182,37 +189,37 @@ type MetricLabel struct {
|
|||
type AppPolicySpec struct {
|
||||
AppName string `json:"appId" yaml:"appId"`
|
||||
// +optional
|
||||
DefaultAction string `json:"defaultAction" yaml:"defaultAction"`
|
||||
DefaultAction string `json:"defaultAction,omitempty" yaml:"defaultAction,omitempty"`
|
||||
// +optional
|
||||
TrustDomain string `json:"trustDomain" yaml:"trustDomain"`
|
||||
TrustDomain string `json:"trustDomain,omitempty" yaml:"trustDomain,omitempty"`
|
||||
// +optional
|
||||
Namespace string `json:"namespace" yaml:"namespace"`
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
// +optional
|
||||
AppOperationActions []AppOperationAction `json:"operations" yaml:"operations"`
|
||||
AppOperationActions []AppOperationAction `json:"operations,omitempty" yaml:"operations,omitempty"`
|
||||
}
|
||||
|
||||
// AppOperationAction defines the data structure for each app operation.
|
||||
type AppOperationAction struct {
|
||||
Operation string `json:"name" yaml:"name"`
|
||||
Action string `json:"action" yaml:"action"`
|
||||
// +optional
|
||||
HTTPVerb []string `json:"httpVerb" yaml:"httpVerb"`
|
||||
Action string `json:"action" yaml:"action"`
|
||||
HTTPVerb []string `json:"httpVerb,omitempty" yaml:"httpVerb,omitempty"`
|
||||
}
|
||||
|
||||
// AccessControlSpec is the spec object in ConfigurationSpec.
|
||||
type AccessControlSpec struct {
|
||||
// +optional
|
||||
DefaultAction string `json:"defaultAction" yaml:"defaultAction"`
|
||||
DefaultAction string `json:"defaultAction,omitempty" yaml:"defaultAction,omitempty"`
|
||||
// +optional
|
||||
TrustDomain string `json:"trustDomain" yaml:"trustDomain"`
|
||||
TrustDomain string `json:"trustDomain,omitempty" yaml:"trustDomain,omitempty"`
|
||||
// +optional
|
||||
AppPolicies []AppPolicySpec `json:"policies" yaml:"policies"`
|
||||
AppPolicies []AppPolicySpec `json:"policies,omitempty" yaml:"policies,omitempty"`
|
||||
}
|
||||
|
||||
// FeatureSpec defines the features that are enabled/disabled.
|
||||
type FeatureSpec struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
Enabled *bool `json:"enabled" yaml:"enabled"`
|
||||
}
|
||||
|
||||
// ComponentsSpec describes the configuration for Dapr components
|
||||
|
|
@ -222,6 +229,30 @@ type ComponentsSpec struct {
|
|||
Deny []string `json:"deny,omitempty" yaml:"deny,omitempty"`
|
||||
}
|
||||
|
||||
// LoggingSpec defines the configuration for logging.
|
||||
type LoggingSpec struct {
|
||||
// Configure API logging.
|
||||
// +optional
|
||||
APILogging *APILoggingSpec `json:"apiLogging,omitempty" yaml:"apiLogging,omitempty"`
|
||||
}
|
||||
|
||||
// APILoggingSpec defines the configuration for API logging.
|
||||
type APILoggingSpec struct {
|
||||
// Default value for enabling API logging. Sidecars can always override this by setting `--enable-api-logging` to true or false explicitly.
|
||||
// The default value is false.
|
||||
// +optional
|
||||
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
|
||||
// When enabled, obfuscates the values of URLs in HTTP API logs, logging the route name rather than the full path being invoked, which could contain PII.
|
||||
// Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
// +optional
|
||||
ObfuscateURLs *bool `json:"obfuscateURLs,omitempty" yaml:"obfuscateURLs,omitempty"`
|
||||
// If true, health checks are not reported in API logs. Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
// +optional
|
||||
OmitHealthChecks *bool `json:"omitHealthChecks,omitempty" yaml:"omitHealthChecks,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ConfigurationList is a list of Dapr event sources.
|
||||
|
|
@ -232,30 +263,6 @@ type ConfigurationList struct {
|
|||
Items []Configuration `json:"items"`
|
||||
}
|
||||
|
||||
// LoggingSpec defines the configuration for logging.
|
||||
type LoggingSpec struct {
|
||||
// Configure API logging.
|
||||
// +optional
|
||||
APILogging APILoggingSpec `json:"apiLogging" yaml:"apiLogging"`
|
||||
}
|
||||
|
||||
// APILoggingSpec defines the configuration for API logging.
|
||||
type APILoggingSpec struct {
|
||||
// Default value for enabling API logging. Sidecars can always override this by setting `--enable-api-logging` to true or false explicitly.
|
||||
// The default value is false.
|
||||
// +optional
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
// When enabled, obfuscates the values of URLs in HTTP API logs, logging the route name rather than the full path being invoked, which could contain PII.
|
||||
// Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
// +optional
|
||||
ObfuscateURLs bool `json:"obfuscateURLs" yaml:"obfuscateURLs"`
|
||||
// If true, health checks are not reported in API logs. Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
// +optional
|
||||
OmitHealthChecks bool `json:"omitHealthChecks" yaml:"omitHealthChecks"`
|
||||
}
|
||||
|
||||
// DynamicValue is a dynamic value struct for the component.metadata pair value.
|
||||
type DynamicValue struct {
|
||||
v1.JSON `json:",inline"`
|
||||
|
|
|
|||
|
|
@ -43,6 +43,21 @@ func (in *APIAccessRule) DeepCopy() *APIAccessRule {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *APILoggingSpec) DeepCopyInto(out *APILoggingSpec) {
|
||||
*out = *in
|
||||
if in.Enabled != nil {
|
||||
in, out := &in.Enabled, &out.Enabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.ObfuscateURLs != nil {
|
||||
in, out := &in.ObfuscateURLs, &out.ObfuscateURLs
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.OmitHealthChecks != nil {
|
||||
in, out := &in.OmitHealthChecks, &out.OmitHealthChecks
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APILoggingSpec.
|
||||
|
|
@ -225,23 +240,73 @@ func (in *ConfigurationList) DeepCopyObject() runtime.Object {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ConfigurationSpec) DeepCopyInto(out *ConfigurationSpec) {
|
||||
*out = *in
|
||||
in.AppHTTPPipelineSpec.DeepCopyInto(&out.AppHTTPPipelineSpec)
|
||||
in.HTTPPipelineSpec.DeepCopyInto(&out.HTTPPipelineSpec)
|
||||
out.TracingSpec = in.TracingSpec
|
||||
in.MetricSpec.DeepCopyInto(&out.MetricSpec)
|
||||
in.MetricsSpec.DeepCopyInto(&out.MetricsSpec)
|
||||
out.MTLSSpec = in.MTLSSpec
|
||||
in.Secrets.DeepCopyInto(&out.Secrets)
|
||||
in.AccessControlSpec.DeepCopyInto(&out.AccessControlSpec)
|
||||
in.NameResolutionSpec.DeepCopyInto(&out.NameResolutionSpec)
|
||||
if in.AppHTTPPipelineSpec != nil {
|
||||
in, out := &in.AppHTTPPipelineSpec, &out.AppHTTPPipelineSpec
|
||||
*out = new(PipelineSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.HTTPPipelineSpec != nil {
|
||||
in, out := &in.HTTPPipelineSpec, &out.HTTPPipelineSpec
|
||||
*out = new(PipelineSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.TracingSpec != nil {
|
||||
in, out := &in.TracingSpec, &out.TracingSpec
|
||||
*out = new(TracingSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.MetricSpec != nil {
|
||||
in, out := &in.MetricSpec, &out.MetricSpec
|
||||
*out = new(MetricSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.MetricsSpec != nil {
|
||||
in, out := &in.MetricsSpec, &out.MetricsSpec
|
||||
*out = new(MetricSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.MTLSSpec != nil {
|
||||
in, out := &in.MTLSSpec, &out.MTLSSpec
|
||||
*out = new(MTLSSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Secrets != nil {
|
||||
in, out := &in.Secrets, &out.Secrets
|
||||
*out = new(SecretsSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AccessControlSpec != nil {
|
||||
in, out := &in.AccessControlSpec, &out.AccessControlSpec
|
||||
*out = new(AccessControlSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.NameResolutionSpec != nil {
|
||||
in, out := &in.NameResolutionSpec, &out.NameResolutionSpec
|
||||
*out = new(NameResolutionSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Features != nil {
|
||||
in, out := &in.Features, &out.Features
|
||||
*out = make([]FeatureSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.APISpec != nil {
|
||||
in, out := &in.APISpec, &out.APISpec
|
||||
*out = new(APISpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ComponentsSpec != nil {
|
||||
in, out := &in.ComponentsSpec, &out.ComponentsSpec
|
||||
*out = new(ComponentsSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.LoggingSpec != nil {
|
||||
in, out := &in.LoggingSpec, &out.LoggingSpec
|
||||
*out = new(LoggingSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.APISpec.DeepCopyInto(&out.APISpec)
|
||||
in.ComponentsSpec.DeepCopyInto(&out.ComponentsSpec)
|
||||
out.LoggingSpec = in.LoggingSpec
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigurationSpec.
|
||||
|
|
@ -273,6 +338,11 @@ func (in *DynamicValue) DeepCopy() *DynamicValue {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FeatureSpec) DeepCopyInto(out *FeatureSpec) {
|
||||
*out = *in
|
||||
if in.Enabled != nil {
|
||||
in, out := &in.Enabled, &out.Enabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureSpec.
|
||||
|
|
@ -288,7 +358,11 @@ func (in *FeatureSpec) DeepCopy() *FeatureSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HandlerSpec) DeepCopyInto(out *HandlerSpec) {
|
||||
*out = *in
|
||||
in.SelectorSpec.DeepCopyInto(&out.SelectorSpec)
|
||||
if in.SelectorSpec != nil {
|
||||
in, out := &in.SelectorSpec, &out.SelectorSpec
|
||||
*out = new(SelectorSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HandlerSpec.
|
||||
|
|
@ -304,7 +378,11 @@ func (in *HandlerSpec) DeepCopy() *HandlerSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoggingSpec) DeepCopyInto(out *LoggingSpec) {
|
||||
*out = *in
|
||||
out.APILogging = in.APILogging
|
||||
if in.APILogging != nil {
|
||||
in, out := &in.APILogging, &out.APILogging
|
||||
*out = new(APILoggingSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingSpec.
|
||||
|
|
@ -320,6 +398,21 @@ func (in *LoggingSpec) DeepCopy() *LoggingSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MTLSSpec) DeepCopyInto(out *MTLSSpec) {
|
||||
*out = *in
|
||||
if in.Enabled != nil {
|
||||
in, out := &in.Enabled, &out.Enabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.WorkloadCertTTL != nil {
|
||||
in, out := &in.WorkloadCertTTL, &out.WorkloadCertTTL
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.AllowedClockSkew != nil {
|
||||
in, out := &in.AllowedClockSkew, &out.AllowedClockSkew
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MTLSSpec.
|
||||
|
|
@ -357,6 +450,11 @@ func (in *MetricLabel) DeepCopy() *MetricLabel {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
||||
*out = *in
|
||||
if in.Enabled != nil {
|
||||
in, out := &in.Enabled, &out.Enabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Rules != nil {
|
||||
in, out := &in.Rules, &out.Rules
|
||||
*out = make([]MetricsRule, len(*in))
|
||||
|
|
@ -401,7 +499,11 @@ func (in *MetricsRule) DeepCopy() *MetricsRule {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NameResolutionSpec) DeepCopyInto(out *NameResolutionSpec) {
|
||||
*out = *in
|
||||
in.Configuration.DeepCopyInto(&out.Configuration)
|
||||
if in.Configuration != nil {
|
||||
in, out := &in.Configuration, &out.Configuration
|
||||
*out = new(DynamicValue)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NameResolutionSpec.
|
||||
|
|
@ -417,6 +519,11 @@ func (in *NameResolutionSpec) DeepCopy() *NameResolutionSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OtelSpec) DeepCopyInto(out *OtelSpec) {
|
||||
*out = *in
|
||||
if in.IsSecure != nil {
|
||||
in, out := &in.IsSecure, &out.IsSecure
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OtelSpec.
|
||||
|
|
@ -536,8 +643,21 @@ func (in *SelectorSpec) DeepCopy() *SelectorSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *TracingSpec) DeepCopyInto(out *TracingSpec) {
|
||||
*out = *in
|
||||
out.Zipkin = in.Zipkin
|
||||
out.Otel = in.Otel
|
||||
if in.Stdout != nil {
|
||||
in, out := &in.Stdout, &out.Stdout
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Zipkin != nil {
|
||||
in, out := &in.Zipkin, &out.Zipkin
|
||||
*out = new(ZipkinSpec)
|
||||
**out = **in
|
||||
}
|
||||
if in.Otel != nil {
|
||||
in, out := &in.Otel, &out.Otel
|
||||
*out = new(OtelSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingSpec.
|
||||
|
|
|
|||
|
|
@ -25,13 +25,14 @@ import (
|
|||
env "github.com/dapr/dapr/pkg/config/env"
|
||||
|
||||
grpcRetry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"github.com/dapr/dapr/pkg/buildinfo"
|
||||
operatorv1pb "github.com/dapr/dapr/pkg/proto/operator/v1"
|
||||
"github.com/dapr/dapr/utils"
|
||||
"github.com/dapr/kit/ptr"
|
||||
)
|
||||
|
||||
// Feature Flags section
|
||||
|
|
@ -99,35 +100,35 @@ type AccessControlListOperationAction struct {
|
|||
}
|
||||
|
||||
type ConfigurationSpec struct {
|
||||
HTTPPipelineSpec PipelineSpec `json:"httpPipeline,omitempty" yaml:"httpPipeline,omitempty"`
|
||||
AppHTTPPipelineSpec PipelineSpec `json:"appHttpPipeline,omitempty" yaml:"appHttpPipeline,omitempty"`
|
||||
TracingSpec TracingSpec `json:"tracing,omitempty" yaml:"tracing,omitempty"`
|
||||
MTLSSpec MTLSSpec `json:"mtls,omitempty" yaml:"mtls,omitempty"`
|
||||
MetricSpec MetricSpec `json:"metric,omitempty" yaml:"metric,omitempty"`
|
||||
MetricsSpec MetricSpec `json:"metrics,omitempty" yaml:"metrics,omitempty"`
|
||||
Secrets SecretsSpec `json:"secrets,omitempty" yaml:"secrets,omitempty"`
|
||||
AccessControlSpec AccessControlSpec `json:"accessControl,omitempty" yaml:"accessControl,omitempty"`
|
||||
NameResolutionSpec NameResolutionSpec `json:"nameResolution,omitempty" yaml:"nameResolution,omitempty"`
|
||||
Features []FeatureSpec `json:"features,omitempty" yaml:"features,omitempty"`
|
||||
APISpec APISpec `json:"api,omitempty" yaml:"api,omitempty"`
|
||||
ComponentsSpec ComponentsSpec `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
LoggingSpec LoggingSpec `json:"logging,omitempty" yaml:"logging,omitempty"`
|
||||
HTTPPipelineSpec *PipelineSpec `json:"httpPipeline,omitempty" yaml:"httpPipeline,omitempty"`
|
||||
AppHTTPPipelineSpec *PipelineSpec `json:"appHttpPipeline,omitempty" yaml:"appHttpPipeline,omitempty"`
|
||||
TracingSpec *TracingSpec `json:"tracing,omitempty" yaml:"tracing,omitempty"`
|
||||
MTLSSpec *MTLSSpec `json:"mtls,omitempty" yaml:"mtls,omitempty"`
|
||||
MetricSpec *MetricSpec `json:"metric,omitempty" yaml:"metric,omitempty"`
|
||||
MetricsSpec *MetricSpec `json:"metrics,omitempty" yaml:"metrics,omitempty"`
|
||||
Secrets *SecretsSpec `json:"secrets,omitempty" yaml:"secrets,omitempty"`
|
||||
AccessControlSpec *AccessControlSpec `json:"accessControl,omitempty" yaml:"accessControl,omitempty"`
|
||||
NameResolutionSpec *NameResolutionSpec `json:"nameResolution,omitempty" yaml:"nameResolution,omitempty"`
|
||||
Features []FeatureSpec `json:"features,omitempty" yaml:"features,omitempty"`
|
||||
APISpec *APISpec `json:"api,omitempty" yaml:"api,omitempty"`
|
||||
ComponentsSpec *ComponentsSpec `json:"components,omitempty" yaml:"components,omitempty"`
|
||||
LoggingSpec *LoggingSpec `json:"logging,omitempty" yaml:"logging,omitempty"`
|
||||
}
|
||||
|
||||
type SecretsSpec struct {
|
||||
Scopes []SecretsScope `json:"scopes"`
|
||||
Scopes []SecretsScope `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// SecretsScope defines the scope for secrets.
|
||||
type SecretsScope struct {
|
||||
DefaultAccess string `json:"defaultAccess,omitempty" yaml:"defaultAccess,omitempty"`
|
||||
StoreName string `json:"storeName" yaml:"storeName"`
|
||||
StoreName string `json:"storeName,omitempty" yaml:"storeName,omitempty"`
|
||||
AllowedSecrets []string `json:"allowedSecrets,omitempty" yaml:"allowedSecrets,omitempty"`
|
||||
DeniedSecrets []string `json:"deniedSecrets,omitempty" yaml:"deniedSecrets,omitempty"`
|
||||
}
|
||||
|
||||
type PipelineSpec struct {
|
||||
Handlers []HandlerSpec `json:"handlers" yaml:"handlers"`
|
||||
Handlers []HandlerSpec `json:"handlers,omitempty" yaml:"handlers,omitempty"`
|
||||
}
|
||||
|
||||
// APISpec describes the configuration for Dapr APIs.
|
||||
|
|
@ -171,9 +172,9 @@ func (r APIAccessRules) GetRulesByProtocol(protocol APIAccessRuleProtocol) []API
|
|||
}
|
||||
|
||||
type HandlerSpec struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
Version string `json:"version" yaml:"version"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
||||
Version string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
SelectorSpec SelectorSpec `json:"selector,omitempty" yaml:"selector,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +184,7 @@ func (h HandlerSpec) LogName() string {
|
|||
}
|
||||
|
||||
type SelectorSpec struct {
|
||||
Fields []SelectorField `json:"fields" yaml:"fields"`
|
||||
Fields []SelectorField `json:"fields,omitempty" yaml:"fields,omitempty"`
|
||||
}
|
||||
|
||||
type SelectorField struct {
|
||||
|
|
@ -192,75 +193,89 @@ type SelectorField struct {
|
|||
}
|
||||
|
||||
type TracingSpec struct {
|
||||
SamplingRate string `json:"samplingRate" yaml:"samplingRate"`
|
||||
Stdout bool `json:"stdout" yaml:"stdout"`
|
||||
Zipkin ZipkinSpec `json:"zipkin" yaml:"zipkin"`
|
||||
Otel OtelSpec `json:"otel" yaml:"otel"`
|
||||
SamplingRate string `json:"samplingRate,omitempty" yaml:"samplingRate,omitempty"`
|
||||
Stdout bool `json:"stdout,omitempty" yaml:"stdout,omitempty"`
|
||||
Zipkin *ZipkinSpec `json:"zipkin,omitempty" yaml:"zipkin,omitempty"`
|
||||
Otel *OtelSpec `json:"otel,omitempty" yaml:"otel,omitempty"`
|
||||
}
|
||||
|
||||
// ZipkinSpec defines Zipkin exporter configurations.
|
||||
type ZipkinSpec struct {
|
||||
EndpointAddress string `json:"endpointAddress" yaml:"endpointAddress"`
|
||||
EndpointAddress string `json:"endpointAddress,omitempty" yaml:"endpointAddress,omitempty"`
|
||||
}
|
||||
|
||||
// OtelSpec defines Otel exporter configurations.
|
||||
type OtelSpec struct {
|
||||
Protocol string `json:"protocol" yaml:"protocol"`
|
||||
EndpointAddress string `json:"endpointAddress" yaml:"endpointAddress"`
|
||||
IsSecure bool `json:"isSecure" yaml:"isSecure"`
|
||||
Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"`
|
||||
EndpointAddress string `json:"endpointAddress,omitempty" yaml:"endpointAddress,omitempty"`
|
||||
// Defaults to true
|
||||
IsSecure *bool `json:"isSecure,omitempty" yaml:"isSecure,omitempty"`
|
||||
}
|
||||
|
||||
// GetIsSecure returns true if the connection should be secured.
|
||||
func (o OtelSpec) GetIsSecure() bool {
|
||||
// Defaults to true if nil
|
||||
return o.IsSecure == nil || *o.IsSecure
|
||||
}
|
||||
|
||||
// MetricSpec configuration for metrics.
|
||||
type MetricSpec struct {
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
Rules []MetricsRule `json:"rules" yaml:"rules"`
|
||||
// Defaults to true
|
||||
Enabled *bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
|
||||
Rules []MetricsRule `json:"rules,omitempty" yaml:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// GetEnabled returns true if metrics are enabled.
|
||||
func (m MetricSpec) GetEnabled() bool {
|
||||
// Defaults to true if nil
|
||||
return m.Enabled == nil || *m.Enabled
|
||||
}
|
||||
|
||||
// MetricsRule defines configuration options for a metric.
|
||||
type MetricsRule struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Labels []MetricLabel `json:"labels" yaml:"labels"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Labels []MetricLabel `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
}
|
||||
|
||||
// MetricsLabel defines an object that allows to set regex expressions for a label.
|
||||
type MetricLabel struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Regex map[string]string `json:"regex" yaml:"regex"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Regex map[string]string `json:"regex,omitempty" yaml:"regex,omitempty"`
|
||||
}
|
||||
|
||||
// AppPolicySpec defines the policy data structure for each app.
|
||||
type AppPolicySpec struct {
|
||||
AppName string `json:"appId" yaml:"appId"`
|
||||
DefaultAction string `json:"defaultAction" yaml:"defaultAction"`
|
||||
TrustDomain string `json:"trustDomain" yaml:"trustDomain"`
|
||||
Namespace string `json:"namespace" yaml:"namespace"`
|
||||
AppOperationActions []AppOperation `json:"operations" yaml:"operations"`
|
||||
AppName string `json:"appId,omitempty" yaml:"appId,omitempty"`
|
||||
DefaultAction string `json:"defaultAction,omitempty" yaml:"defaultAction,omitempty"`
|
||||
TrustDomain string `json:"trustDomain,omitempty" yaml:"trustDomain,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
|
||||
AppOperationActions []AppOperation `json:"operations,omitempty" yaml:"operations,omitempty"`
|
||||
}
|
||||
|
||||
// AppOperation defines the data structure for each app operation.
|
||||
type AppOperation struct {
|
||||
Operation string `json:"name" yaml:"name"`
|
||||
HTTPVerb []string `json:"httpVerb" yaml:"httpVerb"`
|
||||
Action string `json:"action" yaml:"action"`
|
||||
Operation string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
HTTPVerb []string `json:"httpVerb,omitempty" yaml:"httpVerb,omitempty"`
|
||||
Action string `json:"action,omitempty" yaml:"action,omitempty"`
|
||||
}
|
||||
|
||||
// AccessControlSpec is the spec object in ConfigurationSpec.
|
||||
type AccessControlSpec struct {
|
||||
DefaultAction string `json:"defaultAction" yaml:"defaultAction"`
|
||||
TrustDomain string `json:"trustDomain" yaml:"trustDomain"`
|
||||
AppPolicies []AppPolicySpec `json:"policies" yaml:"policies"`
|
||||
DefaultAction string `json:"defaultAction,omitempty" yaml:"defaultAction,omitempty"`
|
||||
TrustDomain string `json:"trustDomain,omitempty" yaml:"trustDomain,omitempty"`
|
||||
AppPolicies []AppPolicySpec `json:"policies,omitempty" yaml:"policies,omitempty"`
|
||||
}
|
||||
|
||||
type NameResolutionSpec struct {
|
||||
Component string `json:"component" yaml:"component"`
|
||||
Version string `json:"version" yaml:"version"`
|
||||
Configuration interface{} `json:"configuration" yaml:"configuration"`
|
||||
Component string `json:"component,omitempty" yaml:"component,omitempty"`
|
||||
Version string `json:"version,omitempty" yaml:"version,omitempty"`
|
||||
Configuration any `json:"configuration,omitempty" yaml:"configuration,omitempty"`
|
||||
}
|
||||
|
||||
type MTLSSpec struct {
|
||||
Enabled bool `json:"enabled" yaml:"enabled"`
|
||||
WorkloadCertTTL string `json:"workloadCertTTL" yaml:"workloadCertTTL"`
|
||||
AllowedClockSkew string `json:"allowedClockSkew" yaml:"allowedClockSkew"`
|
||||
Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
|
||||
WorkloadCertTTL string `json:"workloadCertTTL,omitempty" yaml:"workloadCertTTL,omitempty"`
|
||||
AllowedClockSkew string `json:"allowedClockSkew,omitempty" yaml:"allowedClockSkew,omitempty"`
|
||||
}
|
||||
|
||||
// SpiffeID represents the separated fields in a spiffe id.
|
||||
|
|
@ -285,7 +300,7 @@ type ComponentsSpec struct {
|
|||
// LoggingSpec defines the configuration for logging.
|
||||
type LoggingSpec struct {
|
||||
// Configure API logging.
|
||||
APILogging APILoggingSpec `json:"apiLogging,omitempty" yaml:"apiLogging,omitempty"`
|
||||
APILogging *APILoggingSpec `json:"apiLogging,omitempty" yaml:"apiLogging,omitempty"`
|
||||
}
|
||||
|
||||
// APILoggingSpec defines the configuration for API logging.
|
||||
|
|
@ -296,7 +311,7 @@ type APILoggingSpec struct {
|
|||
// When enabled, obfuscates the values of URLs in HTTP API logs, logging the route name rather than the full path being invoked, which could contain PII.
|
||||
// Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
ObfuscateURLs bool `json:"obfuscateURLs" yaml:"obfuscateURLs"`
|
||||
ObfuscateURLs bool `json:"obfuscateURLs,omitempty" yaml:"obfuscateURLs,omitempty"`
|
||||
// If true, health checks are not reported in API logs. Default: false.
|
||||
// This option has no effect if API logging is disabled.
|
||||
OmitHealthChecks bool `json:"omitHealthChecks,omitempty" yaml:"omitHealthChecks,omitempty"`
|
||||
|
|
@ -306,19 +321,15 @@ type APILoggingSpec struct {
|
|||
func LoadDefaultConfiguration() *Configuration {
|
||||
return &Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
TracingSpec: TracingSpec{
|
||||
SamplingRate: "",
|
||||
Otel: OtelSpec{
|
||||
IsSecure: true,
|
||||
TracingSpec: &TracingSpec{
|
||||
Otel: &OtelSpec{
|
||||
IsSecure: ptr.Of(true),
|
||||
},
|
||||
},
|
||||
MetricSpec: MetricSpec{
|
||||
Enabled: true,
|
||||
MetricSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(true),
|
||||
},
|
||||
MetricsSpec: MetricSpec{
|
||||
Enabled: true,
|
||||
},
|
||||
AccessControlSpec: AccessControlSpec{
|
||||
AccessControlSpec: &AccessControlSpec{
|
||||
DefaultAction: AllowAccess,
|
||||
TrustDomain: "public",
|
||||
},
|
||||
|
|
@ -327,36 +338,41 @@ func LoadDefaultConfiguration() *Configuration {
|
|||
}
|
||||
|
||||
// LoadStandaloneConfiguration gets the path to a config file and loads it into a configuration.
|
||||
func LoadStandaloneConfiguration(config string) (*Configuration, string, error) {
|
||||
_, err := os.Stat(config)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(config)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// Parse environment variables from yaml
|
||||
b = []byte(os.ExpandEnv(string(b)))
|
||||
|
||||
func LoadStandaloneConfiguration(configs ...string) (*Configuration, error) {
|
||||
conf := LoadDefaultConfiguration()
|
||||
err = yaml.Unmarshal(b, conf)
|
||||
if err != nil {
|
||||
return nil, string(b), err
|
||||
}
|
||||
err = sortAndValidateSecretsConfiguration(conf)
|
||||
if err != nil {
|
||||
return nil, string(b), err
|
||||
|
||||
// Load all config files and apply them on top of the default config
|
||||
for _, config := range configs {
|
||||
_, err := os.Stat(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse environment variables from yaml
|
||||
b = []byte(os.ExpandEnv(string(b)))
|
||||
|
||||
err = yaml.Unmarshal(b, conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
sortMetricsSpec(conf)
|
||||
return conf, string(b), nil
|
||||
err := conf.sortAndValidateSecretsConfiguration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conf.sortMetricsSpec()
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// LoadKubernetesConfiguration gets configuration from the Kubernetes operator with a given name.
|
||||
func LoadKubernetesConfiguration(config, namespace string, podName string, operatorClient operatorv1pb.OperatorClient) (*Configuration, error) {
|
||||
func LoadKubernetesConfiguration(config string, namespace string, podName string, operatorClient operatorv1pb.OperatorClient) (*Configuration, error) {
|
||||
resp, err := operatorClient.GetConfiguration(context.Background(), &operatorv1pb.GetConfigurationRequest{
|
||||
Name: config,
|
||||
Namespace: namespace,
|
||||
|
|
@ -365,21 +381,22 @@ func LoadKubernetesConfiguration(config, namespace string, podName string, opera
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.GetConfiguration() == nil {
|
||||
b := resp.GetConfiguration()
|
||||
if len(b) == 0 {
|
||||
return nil, fmt.Errorf("configuration %s not found", config)
|
||||
}
|
||||
conf := LoadDefaultConfiguration()
|
||||
err = json.Unmarshal(resp.GetConfiguration(), conf)
|
||||
err = json.Unmarshal(b, conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = sortAndValidateSecretsConfiguration(conf)
|
||||
err = conf.sortAndValidateSecretsConfiguration()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sortMetricsSpec(conf)
|
||||
conf.sortMetricsSpec()
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
|
|
@ -410,46 +427,11 @@ func SetTracingSpecFromEnv(conf *Configuration) {
|
|||
}
|
||||
|
||||
if insecure := os.Getenv(env.OtlpExporterInsecure); insecure == "true" {
|
||||
conf.Spec.TracingSpec.Otel.IsSecure = false
|
||||
conf.Spec.TracingSpec.Otel.IsSecure = ptr.Of(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply .metrics if set. If not, retain .metric.
|
||||
func sortMetricsSpec(conf *Configuration) {
|
||||
if !conf.Spec.MetricsSpec.Enabled {
|
||||
conf.Spec.MetricSpec.Enabled = false
|
||||
}
|
||||
|
||||
if len(conf.Spec.MetricsSpec.Rules) > 0 {
|
||||
conf.Spec.MetricSpec.Rules = conf.Spec.MetricsSpec.Rules
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the secrets configuration and sort to the allowed and denied lists if present.
|
||||
func sortAndValidateSecretsConfiguration(conf *Configuration) error {
|
||||
scopes := conf.Spec.Secrets.Scopes
|
||||
set := sets.NewString()
|
||||
for _, scope := range scopes {
|
||||
// validate scope
|
||||
if set.Has(scope.StoreName) {
|
||||
return fmt.Errorf("%q storeName is repeated in secrets configuration", scope.StoreName)
|
||||
}
|
||||
if scope.DefaultAccess != "" &&
|
||||
!strings.EqualFold(scope.DefaultAccess, AllowAccess) &&
|
||||
!strings.EqualFold(scope.DefaultAccess, DenyAccess) {
|
||||
return fmt.Errorf("defaultAccess %q can be either allow or deny", scope.DefaultAccess)
|
||||
}
|
||||
set.Insert(scope.StoreName)
|
||||
|
||||
// modify scope
|
||||
sort.Strings(scope.AllowedSecrets)
|
||||
sort.Strings(scope.DeniedSecrets)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsSecretAllowed Check if the secret is allowed to be accessed.
|
||||
func (c SecretsScope) IsSecretAllowed(key string) bool {
|
||||
// By default, set allow access for the secret store.
|
||||
|
|
@ -515,3 +497,133 @@ func (c Configuration) EnabledFeatures() []string {
|
|||
}
|
||||
return features[:i]
|
||||
}
|
||||
|
||||
// GetTracingSpec returns the tracing spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetTracingSpec() TracingSpec {
|
||||
if c.Spec.TracingSpec == nil {
|
||||
return TracingSpec{}
|
||||
}
|
||||
return *c.Spec.TracingSpec
|
||||
}
|
||||
|
||||
// GetMTLSSpec returns the mTLS spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetMTLSSpec() MTLSSpec {
|
||||
if c.Spec.MTLSSpec == nil {
|
||||
return MTLSSpec{}
|
||||
}
|
||||
return *c.Spec.MTLSSpec
|
||||
}
|
||||
|
||||
// GetMetricsSpec returns the metrics spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetMetricsSpec() MetricSpec {
|
||||
if c.Spec.MetricSpec == nil {
|
||||
return MetricSpec{}
|
||||
}
|
||||
return *c.Spec.MetricSpec
|
||||
}
|
||||
|
||||
// GetAPISpec returns the API spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetAPISpec() APISpec {
|
||||
if c.Spec.APISpec == nil {
|
||||
return APISpec{}
|
||||
}
|
||||
return *c.Spec.APISpec
|
||||
}
|
||||
|
||||
// GetLoggingSpec returns the Logging spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetLoggingSpec() LoggingSpec {
|
||||
if c.Spec.LoggingSpec == nil {
|
||||
return LoggingSpec{}
|
||||
}
|
||||
return *c.Spec.LoggingSpec
|
||||
}
|
||||
|
||||
// GetLoggingSpec returns the Logging.APILogging spec.
|
||||
// It's a short-hand that includes nil-checks for safety.
|
||||
func (c Configuration) GetAPILoggingSpec() APILoggingSpec {
|
||||
if c.Spec.LoggingSpec == nil || c.Spec.LoggingSpec.APILogging == nil {
|
||||
return APILoggingSpec{}
|
||||
}
|
||||
return *c.Spec.LoggingSpec.APILogging
|
||||
}
|
||||
|
||||
// ToYAML returns the Configuration represented as YAML.
|
||||
func (c *Configuration) ToYAML() (string, error) {
|
||||
b, err := yaml.Marshal(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer and is used for debugging. It returns the Configuration object encoded as YAML.
|
||||
func (c *Configuration) String() string {
|
||||
enc, err := c.ToYAML()
|
||||
if err != nil {
|
||||
return "Failed to marshal Configuration object to YAML: " + err.Error()
|
||||
}
|
||||
return enc
|
||||
}
|
||||
|
||||
// Apply .metrics if set. If not, retain .metric.
|
||||
func (c *Configuration) sortMetricsSpec() {
|
||||
if c.Spec.MetricsSpec != nil {
|
||||
if c.Spec.MetricsSpec.Enabled != nil {
|
||||
c.Spec.MetricSpec.Enabled = c.Spec.MetricsSpec.Enabled
|
||||
}
|
||||
|
||||
if len(c.Spec.MetricsSpec.Rules) > 0 {
|
||||
c.Spec.MetricSpec.Rules = c.Spec.MetricsSpec.Rules
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the secrets configuration and sort to the allowed and denied lists if present.
|
||||
func (c *Configuration) sortAndValidateSecretsConfiguration() error {
|
||||
if c.Spec.Secrets == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
set := sets.NewString()
|
||||
for _, scope := range c.Spec.Secrets.Scopes {
|
||||
// validate scope
|
||||
if set.Has(scope.StoreName) {
|
||||
return fmt.Errorf("%s storeName is repeated in secrets configuration", scope.StoreName)
|
||||
}
|
||||
if scope.DefaultAccess != "" &&
|
||||
!strings.EqualFold(scope.DefaultAccess, AllowAccess) &&
|
||||
!strings.EqualFold(scope.DefaultAccess, DenyAccess) {
|
||||
return fmt.Errorf("defaultAccess %s can be either allow or deny", scope.DefaultAccess)
|
||||
}
|
||||
set.Insert(scope.StoreName)
|
||||
|
||||
// modify scope
|
||||
sort.Strings(scope.AllowedSecrets)
|
||||
sort.Strings(scope.DeniedSecrets)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToYAML returns the ConfigurationSpec represented as YAML.
|
||||
func (c ConfigurationSpec) ToYAML() (string, error) {
|
||||
b, err := yaml.Marshal(&c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer and is used for debugging. It returns the Configuration object encoded as YAML.
|
||||
func (c ConfigurationSpec) String() string {
|
||||
enc, err := c.ToYAML()
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Failed to marshal ConfigurationSpec object to YAML: %v", err)
|
||||
}
|
||||
return enc
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,17 @@ limitations under the License.
|
|||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dapr/dapr/pkg/buildinfo"
|
||||
"github.com/dapr/kit/ptr"
|
||||
)
|
||||
|
||||
func TestLoadStandaloneConfiguration(t *testing.T) {
|
||||
|
|
@ -47,7 +52,7 @@ func TestLoadStandaloneConfiguration(t *testing.T) {
|
|||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration(tc.path)
|
||||
config, err := LoadStandaloneConfiguration(tc.path)
|
||||
if tc.errorExpected {
|
||||
assert.Error(t, err, "Expected an error")
|
||||
assert.Nil(t, config, "Config should not be loaded")
|
||||
|
|
@ -58,72 +63,165 @@ func TestLoadStandaloneConfiguration(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
t.Run("Parse environment variables", func(t *testing.T) {
|
||||
t.Run("parse environment variables", func(t *testing.T) {
|
||||
t.Setenv("DAPR_SECRET", "keepitsecret")
|
||||
config, _, err := LoadStandaloneConfiguration("./testdata/env_variables_config.yaml")
|
||||
config, err := LoadStandaloneConfiguration("./testdata/env_variables_config.yaml")
|
||||
assert.NoError(t, err, "Unexpected error")
|
||||
assert.NotNil(t, config, "Config not loaded as expected")
|
||||
assert.Equal(t, "keepitsecret", config.Spec.Secrets.Scopes[0].AllowedSecrets[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadStandaloneConfigurationKindName(t *testing.T) {
|
||||
t.Run("test Kind and Name", func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration("./testdata/config.yaml")
|
||||
t.Run("check Kind and Name", func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration("./testdata/config.yaml")
|
||||
assert.NoError(t, err, "Unexpected error")
|
||||
assert.NotNil(t, config, "Config not loaded as expected")
|
||||
assert.Equal(t, "secretappconfig", config.ObjectMeta.Name)
|
||||
assert.Equal(t, "Configuration", config.TypeMeta.Kind)
|
||||
})
|
||||
|
||||
t.Run("metrics spec", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
metricEnabled bool
|
||||
}{
|
||||
{
|
||||
name: "metric is enabled by default",
|
||||
confFile: "./testdata/config.yaml",
|
||||
metricEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "metric is disabled by config",
|
||||
confFile: "./testdata/metric_disabled.yaml",
|
||||
metricEnabled: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.metricEnabled, config.Spec.MetricSpec.GetEnabled())
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("components spec", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
componentsDeny []string
|
||||
}{
|
||||
{
|
||||
name: "component deny list",
|
||||
confFile: "./testdata/components_config.yaml",
|
||||
componentsDeny: []string{"foo.bar", "hello.world/v1"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, reflect.DeepEqual(tc.componentsDeny, config.Spec.ComponentsSpec.Deny))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("features spec", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
featureName Feature
|
||||
featureEnabled bool
|
||||
}{
|
||||
{
|
||||
name: "feature is enabled",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Actor.Reentrancy"),
|
||||
featureEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "feature is disabled",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Test.Feature"),
|
||||
featureEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "feature is disabled if missing",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Test.Missing"),
|
||||
featureEnabled: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
require.NoError(t, err)
|
||||
config.LoadFeatures()
|
||||
assert.Equal(t, tc.featureEnabled, config.IsFeatureEnabled(tc.featureName))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("mTLS spec", func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration("./testdata/mtls_config.yaml")
|
||||
require.NoError(t, err)
|
||||
mtlsSpec := config.GetMTLSSpec()
|
||||
assert.True(t, mtlsSpec.Enabled)
|
||||
assert.Equal(t, "25s", mtlsSpec.WorkloadCertTTL)
|
||||
assert.Equal(t, "1h", mtlsSpec.AllowedClockSkew)
|
||||
})
|
||||
|
||||
t.Run("multiple configurations", func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration("./testdata/feature_config.yaml", "./testdata/mtls_config.yaml")
|
||||
require.NoError(t, err)
|
||||
|
||||
// From feature_config.yaml
|
||||
config.LoadFeatures()
|
||||
assert.True(t, config.IsFeatureEnabled("Actor.Reentrancy"))
|
||||
assert.False(t, config.IsFeatureEnabled("Test.Feature"))
|
||||
|
||||
// From mtls_config.yaml
|
||||
mtlsSpec := config.GetMTLSSpec()
|
||||
assert.True(t, mtlsSpec.Enabled)
|
||||
assert.Equal(t, "25s", mtlsSpec.WorkloadCertTTL)
|
||||
assert.Equal(t, "1h", mtlsSpec.AllowedClockSkew)
|
||||
})
|
||||
|
||||
t.Run("multiple configurations with overriding", func(t *testing.T) {
|
||||
config, err := LoadStandaloneConfiguration("./testdata/feature_config.yaml", "./testdata/mtls_config.yaml", "./testdata/override.yaml")
|
||||
require.NoError(t, err)
|
||||
|
||||
// From feature_config.yaml
|
||||
// Should both be overridden
|
||||
config.LoadFeatures()
|
||||
assert.False(t, config.IsFeatureEnabled("Actor.Reentrancy"))
|
||||
assert.True(t, config.IsFeatureEnabled("Test.Feature"))
|
||||
|
||||
// From mtls_config.yaml
|
||||
mtlsSpec := config.GetMTLSSpec()
|
||||
assert.False(t, mtlsSpec.Enabled) // Overridden
|
||||
assert.Equal(t, "25s", mtlsSpec.WorkloadCertTTL)
|
||||
assert.Equal(t, "1h", mtlsSpec.AllowedClockSkew)
|
||||
|
||||
// Spec part encoded as YAML
|
||||
compareWithFile(t, "./testdata/override_spec_gen.yaml", config.Spec.String())
|
||||
|
||||
// Complete YAML
|
||||
compareWithFile(t, "./testdata/override_gen.yaml", config.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestMetricSpecForStandAlone(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
metricEnabled bool
|
||||
}{
|
||||
{
|
||||
name: "metric is enabled by default",
|
||||
confFile: "./testdata/config.yaml",
|
||||
metricEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "metric is disabled by config",
|
||||
confFile: "./testdata/metric_disabled.yaml",
|
||||
metricEnabled: false,
|
||||
},
|
||||
}
|
||||
func compareWithFile(t *testing.T, file string, expect string) {
|
||||
f, err := os.ReadFile(file)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.metricEnabled, config.Spec.MetricSpec.Enabled)
|
||||
})
|
||||
}
|
||||
}
|
||||
// Replace all "\r\n" with "\n" because (*wave hands*, *lesigh*) ... Windows
|
||||
f = bytes.ReplaceAll(f, []byte{'\r', '\n'}, []byte{'\n'})
|
||||
|
||||
func TestComponentsSpecForStandAlone(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
componentsDeny []string
|
||||
}{
|
||||
{
|
||||
name: "component deny list",
|
||||
confFile: "./testdata/components_config.yaml",
|
||||
componentsDeny: []string{"foo.bar", "hello.world/v1"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, reflect.DeepEqual(tc.componentsDeny, config.Spec.ComponentsSpec.Deny))
|
||||
})
|
||||
}
|
||||
assert.Equal(t, expect, string(f))
|
||||
}
|
||||
|
||||
func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
||||
|
|
@ -140,7 +238,7 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
name: "incorrect default access",
|
||||
config: Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
Secrets: SecretsSpec{
|
||||
Secrets: &SecretsSpec{
|
||||
Scopes: []SecretsScope{
|
||||
{
|
||||
StoreName: "testStore",
|
||||
|
|
@ -156,7 +254,7 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
name: "empty default access",
|
||||
config: Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
Secrets: SecretsSpec{
|
||||
Secrets: &SecretsSpec{
|
||||
Scopes: []SecretsScope{
|
||||
{
|
||||
StoreName: "testStore",
|
||||
|
|
@ -171,7 +269,7 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
name: "repeated store Name",
|
||||
config: Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
Secrets: SecretsSpec{
|
||||
Secrets: &SecretsSpec{
|
||||
Scopes: []SecretsScope{
|
||||
{
|
||||
StoreName: "testStore",
|
||||
|
|
@ -191,7 +289,7 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
name: "simple secrets config",
|
||||
config: Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
Secrets: SecretsSpec{
|
||||
Secrets: &SecretsSpec{
|
||||
Scopes: []SecretsScope{
|
||||
{
|
||||
StoreName: "testStore",
|
||||
|
|
@ -208,7 +306,7 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
name: "case-insensitive default access",
|
||||
config: Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
Secrets: SecretsSpec{
|
||||
Secrets: &SecretsSpec{
|
||||
Scopes: []SecretsScope{
|
||||
{
|
||||
StoreName: "testStore",
|
||||
|
|
@ -224,10 +322,10 @@ func TestSortAndValidateSecretsConfigration(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := sortAndValidateSecretsConfiguration(&tc.config)
|
||||
err := tc.config.sortAndValidateSecretsConfiguration()
|
||||
if tc.errorExpected {
|
||||
assert.Error(t, err, "expected validation to fail")
|
||||
} else {
|
||||
} else if tc.config.Spec.Secrets != nil {
|
||||
for _, scope := range tc.config.Spec.Secrets.Scopes {
|
||||
assert.True(t, sort.StringsAreSorted(scope.AllowedSecrets), "expected sorted slice")
|
||||
assert.True(t, sort.StringsAreSorted(scope.DeniedSecrets), "expected sorted slice")
|
||||
|
|
@ -340,56 +438,18 @@ func TestFeatureEnabled(t *testing.T) {
|
|||
},
|
||||
}
|
||||
config.LoadFeatures()
|
||||
|
||||
assert.True(t, config.IsFeatureEnabled("testEnabled"))
|
||||
assert.False(t, config.IsFeatureEnabled("testDisabled"))
|
||||
assert.False(t, config.IsFeatureEnabled("testMissing"))
|
||||
}
|
||||
|
||||
func TestFeatureSpecForStandAlone(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
confFile string
|
||||
featureName Feature
|
||||
featureEnabled bool
|
||||
}{
|
||||
{
|
||||
name: "Feature is enabled",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Actor.Reentrancy"),
|
||||
featureEnabled: true,
|
||||
},
|
||||
{
|
||||
name: "Feature is disabled",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Test.Feature"),
|
||||
featureEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "Feature is disabled if missing",
|
||||
confFile: "./testdata/feature_config.yaml",
|
||||
featureName: Feature("Test.Missing"),
|
||||
featureEnabled: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration(tc.confFile)
|
||||
require.NoError(t, err)
|
||||
config.LoadFeatures()
|
||||
assert.Equal(t, tc.featureEnabled, config.IsFeatureEnabled(tc.featureName))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMTLSSpecForStandAlone(t *testing.T) {
|
||||
t.Run("test mtls spec config", func(t *testing.T) {
|
||||
config, _, err := LoadStandaloneConfiguration("./testdata/mtls_config.yaml")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, config.Spec.MTLSSpec.Enabled)
|
||||
assert.Equal(t, "25s", config.Spec.MTLSSpec.WorkloadCertTTL)
|
||||
assert.Equal(t, "1h", config.Spec.MTLSSpec.AllowedClockSkew)
|
||||
})
|
||||
// Test config.EnabledFeatures
|
||||
// We sort the values before comparing because order isn't guaranteed (and doesn't matter)
|
||||
actual := config.EnabledFeatures()
|
||||
expect := append([]string{"testEnabled"}, buildinfo.Features()...)
|
||||
sort.Strings(actual)
|
||||
sort.Strings(expect)
|
||||
assert.EqualValues(t, actual, expect)
|
||||
}
|
||||
|
||||
func TestSetTracingSpecFromEnv(t *testing.T) {
|
||||
|
|
@ -405,42 +465,84 @@ func TestSetTracingSpecFromEnv(t *testing.T) {
|
|||
|
||||
assert.Equal(t, "otlpendpoint:1234", conf.Spec.TracingSpec.Otel.EndpointAddress)
|
||||
assert.Equal(t, "http", conf.Spec.TracingSpec.Otel.Protocol)
|
||||
assert.Equal(t, false, conf.Spec.TracingSpec.Otel.IsSecure)
|
||||
require.False(t, conf.Spec.TracingSpec.Otel.GetIsSecure())
|
||||
|
||||
// Spec from config file should not be overridden
|
||||
conf = LoadDefaultConfiguration()
|
||||
conf.Spec.TracingSpec.Otel.EndpointAddress = "configfileendpoint:4321"
|
||||
conf.Spec.TracingSpec.Otel.Protocol = "grpc"
|
||||
conf.Spec.TracingSpec.Otel.IsSecure = true
|
||||
conf.Spec.TracingSpec.Otel.IsSecure = ptr.Of(true)
|
||||
|
||||
// set tracing spec from env
|
||||
SetTracingSpecFromEnv(conf)
|
||||
|
||||
assert.Equal(t, "configfileendpoint:4321", conf.Spec.TracingSpec.Otel.EndpointAddress)
|
||||
assert.Equal(t, "grpc", conf.Spec.TracingSpec.Otel.Protocol)
|
||||
assert.Equal(t, true, conf.Spec.TracingSpec.Otel.IsSecure)
|
||||
require.True(t, conf.Spec.TracingSpec.Otel.GetIsSecure())
|
||||
}
|
||||
|
||||
func TestSortMetrics(t *testing.T) {
|
||||
t.Run("metrics overrides metric", func(t *testing.T) {
|
||||
t.Run("metrics overrides metric - enabled false", func(t *testing.T) {
|
||||
config := &Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
MetricSpec: MetricSpec{
|
||||
Enabled: true,
|
||||
MetricSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(true),
|
||||
Rules: []MetricsRule{
|
||||
{
|
||||
Name: "rule",
|
||||
},
|
||||
},
|
||||
},
|
||||
MetricsSpec: MetricSpec{
|
||||
Enabled: false,
|
||||
MetricsSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(false),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
sortMetricsSpec(config)
|
||||
assert.False(t, config.Spec.MetricSpec.Enabled)
|
||||
config.sortMetricsSpec()
|
||||
assert.False(t, config.Spec.MetricSpec.GetEnabled())
|
||||
assert.Equal(t, "rule", config.Spec.MetricSpec.Rules[0].Name)
|
||||
})
|
||||
|
||||
t.Run("metrics overrides metric - enabled true", func(t *testing.T) {
|
||||
config := &Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
MetricSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(false),
|
||||
Rules: []MetricsRule{
|
||||
{
|
||||
Name: "rule",
|
||||
},
|
||||
},
|
||||
},
|
||||
MetricsSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(true),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
config.sortMetricsSpec()
|
||||
assert.True(t, config.Spec.MetricSpec.GetEnabled())
|
||||
assert.Equal(t, "rule", config.Spec.MetricSpec.Rules[0].Name)
|
||||
})
|
||||
|
||||
t.Run("nil metrics enabled doesn't overrides", func(t *testing.T) {
|
||||
config := &Configuration{
|
||||
Spec: ConfigurationSpec{
|
||||
MetricSpec: &MetricSpec{
|
||||
Enabled: ptr.Of(true),
|
||||
Rules: []MetricsRule{
|
||||
{
|
||||
Name: "rule",
|
||||
},
|
||||
},
|
||||
},
|
||||
MetricsSpec: &MetricSpec{},
|
||||
},
|
||||
}
|
||||
|
||||
config.sortMetricsSpec()
|
||||
assert.True(t, config.Spec.MetricSpec.GetEnabled())
|
||||
assert.Equal(t, "rule", config.Spec.MetricSpec.Rules[0].Name)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ metadata:
|
|||
spec:
|
||||
secrets:
|
||||
scopes:
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
allowedSecrets: ["daprsecret","redissecret"]
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
allowedSecrets: ["daprsecret","redissecret"]
|
||||
|
|
@ -5,6 +5,6 @@ metadata:
|
|||
spec:
|
||||
secrets:
|
||||
scopes:
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
allowedSecrets: ["${DAPR_SECRET}"]
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
allowedSecrets: ["${DAPR_SECRET}"]
|
||||
|
|
@ -4,7 +4,7 @@ metadata:
|
|||
name: daprConfig
|
||||
spec:
|
||||
features:
|
||||
- name: Actor.Reentrancy
|
||||
enabled: true
|
||||
- name: Test.Feature
|
||||
enabled: false
|
||||
- name: Actor.Reentrancy
|
||||
enabled: true
|
||||
- name: Test.Feature
|
||||
enabled: false
|
||||
|
|
@ -5,7 +5,7 @@ metadata:
|
|||
spec:
|
||||
secrets:
|
||||
scopes:
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
- storeName: "local"
|
||||
defaultAccess: "deny"
|
||||
- storeName: "local"
|
||||
defaultAccess: "allow"
|
||||
- storeName: "local"
|
||||
defaultAccess: "deny"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: daprsystem
|
||||
namespace: default
|
||||
spec:
|
||||
mtls:
|
||||
enabled: false
|
||||
features:
|
||||
- name: Test.Feature
|
||||
enabled: true
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
kind: Configuration
|
||||
apiversion: ""
|
||||
metadata:
|
||||
name: daprsystem
|
||||
generatename: ""
|
||||
namespace: default
|
||||
selflink: ""
|
||||
uid: ""
|
||||
resourceversion: ""
|
||||
generation: 0
|
||||
creationtimestamp: "0001-01-01T00:00:00Z"
|
||||
deletiontimestamp: null
|
||||
deletiongraceperiodseconds: null
|
||||
labels: {}
|
||||
annotations: {}
|
||||
ownerreferences: []
|
||||
finalizers: []
|
||||
managedfields: []
|
||||
spec:
|
||||
tracing:
|
||||
otel:
|
||||
isSecure: true
|
||||
mtls:
|
||||
workloadCertTTL: 25s
|
||||
allowedClockSkew: 1h
|
||||
metric:
|
||||
enabled: true
|
||||
accessControl:
|
||||
defaultAction: allow
|
||||
trustDomain: public
|
||||
features:
|
||||
- name: Test.Feature
|
||||
enabled: true
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
tracing:
|
||||
otel:
|
||||
isSecure: true
|
||||
mtls:
|
||||
workloadCertTTL: 25s
|
||||
allowedClockSkew: 1h
|
||||
metric:
|
||||
enabled: true
|
||||
accessControl:
|
||||
defaultAction: allow
|
||||
trustDomain: public
|
||||
features:
|
||||
- name: Test.Feature
|
||||
enabled: true
|
||||
|
|
@ -215,9 +215,8 @@ func ConstructSubscriptionSpanAttributes(topic string) map[string]string {
|
|||
}
|
||||
|
||||
// StartInternalCallbackSpan starts trace span for internal callback such as input bindings and pubsub subscription.
|
||||
func StartInternalCallbackSpan(ctx context.Context, spanName string, parent trace.SpanContext, spec config.TracingSpec) (context.Context, trace.Span) {
|
||||
traceEnabled := diagUtils.IsTracingEnabled(spec.SamplingRate)
|
||||
if !traceEnabled {
|
||||
func StartInternalCallbackSpan(ctx context.Context, spanName string, parent trace.SpanContext, spec *config.TracingSpec) (context.Context, trace.Span) {
|
||||
if spec == nil || !diagUtils.IsTracingEnabled(spec.SamplingRate) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ func TestStartInternalCallbackSpan(t *testing.T) {
|
|||
otel.SetTracerProvider(tp)
|
||||
|
||||
t.Run("traceparent is provided and sampling is enabled", func(t *testing.T) {
|
||||
traceSpec := config.TracingSpec{SamplingRate: "1"}
|
||||
traceSpec := &config.TracingSpec{SamplingRate: "1"}
|
||||
|
||||
scConfig := trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{75, 249, 47, 53, 119, 179, 77, 166, 163, 206, 146, 157, 14, 14, 71, 54},
|
||||
|
|
@ -142,7 +142,7 @@ func TestStartInternalCallbackSpan(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("traceparent is provided with sampling flag = 1 but sampling is disabled", func(t *testing.T) {
|
||||
traceSpec := config.TracingSpec{SamplingRate: "0"}
|
||||
traceSpec := &config.TracingSpec{SamplingRate: "0"}
|
||||
|
||||
scConfig := trace.SpanContextConfig{
|
||||
TraceID: trace.TraceID{75, 249, 47, 53, 119, 179, 77, 166, 163, 206, 146, 157, 14, 14, 71, 54},
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ func (s *server) getMiddlewareOptions() []grpcGo.ServerOption {
|
|||
intrStream = append(intrStream, diag.GRPCTraceStreamServerInterceptor(s.config.AppID, s.tracingSpec))
|
||||
}
|
||||
|
||||
if s.metricSpec.Enabled {
|
||||
if s.metricSpec.GetEnabled() {
|
||||
s.logger.Info("Enabled gRPC metrics middleware")
|
||||
intr = append(intr, diag.DefaultGRPCMonitoring.UnaryServerInterceptor())
|
||||
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ func (s *server) useTracing(r chi.Router) {
|
|||
}
|
||||
|
||||
func (s *server) useMetrics(r chi.Router) {
|
||||
if !s.metricSpec.Enabled {
|
||||
if !s.metricSpec.GetEnabled() {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
"github.com/dapr/dapr/utils"
|
||||
"github.com/dapr/kit/logger"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ func mTLSEnabled(daprClient scheme.Interface) bool {
|
|||
|
||||
for _, c := range resp.Items {
|
||||
if c.GetName() == defaultConfig {
|
||||
return c.Spec.MTLSSpec.Enabled
|
||||
return c.Spec.MTLSSpec.GetEnabled()
|
||||
}
|
||||
}
|
||||
log.Infof("Dapr system configuration (%s) is not found, use default value %t for mTLSEnabled", defaultConfig, defaultMtlsEnabled)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ func GetSidecarContainer(cfg ContainerConfig) (*corev1.Container, error) {
|
|||
"--control-plane-address", cfg.ControlPlaneAddress,
|
||||
"--app-protocol", cfg.Annotations.GetStringOrDefault(annotations.KeyAppProtocol, annotations.DefaultAppProtocol),
|
||||
"--placement-host-address", cfg.PlacementServiceAddress,
|
||||
"--config", cfg.Annotations.GetString(annotations.KeyConfig),
|
||||
"--log-level", cfg.Annotations.GetStringOrDefault(annotations.KeyLogLevel, annotations.DefaultLogLevel),
|
||||
"--app-max-concurrency", strconv.Itoa(int(maxConcurrency)),
|
||||
"--sentry-address", cfg.SentryAddress,
|
||||
|
|
@ -150,6 +149,10 @@ func GetSidecarContainer(cfg ContainerConfig) (*corev1.Container, error) {
|
|||
"--disable-builtin-k8s-secret-store=" + strconv.FormatBool(disableBuiltinK8sSecretStore),
|
||||
}
|
||||
|
||||
if v := cfg.Annotations.GetString(annotations.KeyConfig); v != "" {
|
||||
args = append(args, "--config", v)
|
||||
}
|
||||
|
||||
if v, ok := cfg.Annotations[annotations.KeyAppChannel]; ok && v != "" {
|
||||
args = append(args, "--app-channel-address", v)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
|
|
@ -34,14 +35,14 @@ const (
|
|||
func TestGetResourceRequirements(t *testing.T) {
|
||||
t.Run("no resource requirements", func(t *testing.T) {
|
||||
r, err := getResourceRequirements(nil)
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, r)
|
||||
})
|
||||
|
||||
t.Run("valid resource limits", func(t *testing.T) {
|
||||
a := map[string]string{annotations.KeyCPULimit: "100m", annotations.KeyMemoryLimit: "1Gi"}
|
||||
r, err := getResourceRequirements(a)
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "100m", r.Limits.Cpu().String())
|
||||
assert.Equal(t, "1Gi", r.Limits.Memory().String())
|
||||
})
|
||||
|
|
@ -63,7 +64,7 @@ func TestGetResourceRequirements(t *testing.T) {
|
|||
t.Run("valid resource requests", func(t *testing.T) {
|
||||
a := map[string]string{annotations.KeyCPURequest: "100m", annotations.KeyMemoryRequest: "1Gi"}
|
||||
r, err := getResourceRequirements(a)
|
||||
assert.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "100m", r.Requests.Cpu().String())
|
||||
assert.Equal(t, "1Gi", r.Requests.Memory().String())
|
||||
})
|
||||
|
|
@ -163,7 +164,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -173,6 +173,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-as-json",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -237,7 +238,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -247,6 +247,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-as-json",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -311,7 +312,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -321,6 +321,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-as-json",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -383,7 +384,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -393,6 +393,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-as-json",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -456,7 +457,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "some-host:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -466,6 +466,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-as-json",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -511,7 +512,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -521,6 +521,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
||||
|
|
@ -554,7 +555,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -564,6 +564,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +598,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -607,6 +607,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "5",
|
||||
"--disable-builtin-k8s-secret-store=false",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
||||
|
|
@ -684,7 +685,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -694,6 +694,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=true",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
||||
|
|
@ -730,7 +731,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -740,6 +740,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=true",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
||||
|
|
@ -764,7 +765,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -774,6 +774,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=true",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-api-logging=true",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
@ -799,7 +800,6 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--control-plane-address", "controlplane:9000",
|
||||
"--app-protocol", "http",
|
||||
"--placement-host-address", "placement:50000",
|
||||
"--config", defaultTestConfig,
|
||||
"--log-level", "info",
|
||||
"--app-max-concurrency", "-1",
|
||||
"--sentry-address", "sentry:50000",
|
||||
|
|
@ -809,6 +809,7 @@ func TestGetSidecarContainer(t *testing.T) {
|
|||
"--dapr-http-read-buffer-size", "-1",
|
||||
"--dapr-graceful-shutdown-seconds", "-1",
|
||||
"--disable-builtin-k8s-secret-store=true",
|
||||
"--config", defaultTestConfig,
|
||||
"--enable-api-logging=false",
|
||||
"--enable-mtls",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,6 @@ func LoadConfiguration(name string, client client.Client) (*Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
return &Config{
|
||||
MTLSEnabled: conf.Spec.MTLSSpec.Enabled,
|
||||
MTLSEnabled: conf.Spec.MTLSSpec.GetEnabled(),
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/dapr/dapr/pkg/runtime/security"
|
||||
"github.com/dapr/dapr/pkg/validation"
|
||||
"github.com/dapr/dapr/utils"
|
||||
"github.com/dapr/kit/ptr"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -95,7 +96,7 @@ type Config struct {
|
|||
AppHealthThreshold int
|
||||
EnableAppHealthCheck bool
|
||||
Mode string
|
||||
ConfigPath string
|
||||
Config []string
|
||||
UnixDomainSocket string
|
||||
DaprHTTPReadBufferSize int
|
||||
DisableBuiltinK8sSecretStore bool
|
||||
|
|
@ -127,7 +128,7 @@ type internalConfig struct {
|
|||
gracefulShutdownDuration time.Duration
|
||||
enableAPILogging *bool
|
||||
disableBuiltinK8sSecretStore bool
|
||||
configPath string
|
||||
config []string
|
||||
certChain *credentials.CertChain
|
||||
}
|
||||
|
||||
|
|
@ -166,9 +167,6 @@ func FromConfig(cfg *Config) (*DaprRuntime, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var globalConfig *config.Configuration
|
||||
var configErr error
|
||||
|
||||
if intc.mTLSEnabled || intc.mode == modes.KubernetesMode {
|
||||
intc.certChain, err = security.GetCertChain()
|
||||
if err != nil {
|
||||
|
|
@ -188,18 +186,26 @@ func FromConfig(cfg *Config) (*DaprRuntime, error) {
|
|||
operatorClient = client
|
||||
}
|
||||
|
||||
var accessControlList *config.AccessControlList
|
||||
namespace := os.Getenv("NAMESPACE")
|
||||
podName := os.Getenv("POD_NAME")
|
||||
|
||||
if intc.configPath != "" {
|
||||
var (
|
||||
globalConfig *config.Configuration
|
||||
configErr error
|
||||
)
|
||||
|
||||
if len(intc.config) > 0 {
|
||||
switch intc.mode {
|
||||
case modes.KubernetesMode:
|
||||
log.Debug("Loading Kubernetes config resource: " + intc.configPath)
|
||||
globalConfig, configErr = config.LoadKubernetesConfiguration(intc.configPath, namespace, podName, operatorClient)
|
||||
if len(intc.config) > 1 {
|
||||
// We are not returning an error here because in Kubernetes mode, the injector itself doesn't allow multiple configuration flags to be added, so this should never happen in normal environments
|
||||
log.Warnf("Multiple configurations are not supported in Kubernetes mode; only the first one will be loaded")
|
||||
}
|
||||
log.Debug("Loading Kubernetes config resource: " + intc.config[0])
|
||||
globalConfig, configErr = config.LoadKubernetesConfiguration(intc.config[0], namespace, podName, operatorClient)
|
||||
case modes.StandaloneMode:
|
||||
log.Debug("Loading config from file: " + intc.configPath)
|
||||
globalConfig, _, configErr = config.LoadStandaloneConfiguration(intc.configPath)
|
||||
log.Debug("Loading config from file(s): " + strings.Join(intc.config, ", "))
|
||||
globalConfig, configErr = config.LoadStandaloneConfiguration(intc.config...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,8 +224,9 @@ func FromConfig(cfg *Config) (*DaprRuntime, error) {
|
|||
}
|
||||
|
||||
// Initialize metrics only if MetricSpec is enabled.
|
||||
if globalConfig.Spec.MetricSpec.Enabled {
|
||||
if mErr := diag.InitMetrics(intc.id, namespace, globalConfig.Spec.MetricSpec.Rules); mErr != nil {
|
||||
metricsSpec := globalConfig.GetMetricsSpec()
|
||||
if metricsSpec.GetEnabled() {
|
||||
if mErr := diag.InitMetrics(intc.id, namespace, metricsSpec.Rules); mErr != nil {
|
||||
log.Errorf(rterrors.NewInit(rterrors.InitFailure, "metrics", mErr).Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -241,7 +248,7 @@ func FromConfig(cfg *Config) (*DaprRuntime, error) {
|
|||
}
|
||||
}
|
||||
|
||||
accessControlList, err = acl.ParseAccessControlSpec(
|
||||
accessControlList, err := acl.ParseAccessControlSpec(
|
||||
globalConfig.Spec.AccessControlSpec,
|
||||
intc.appConnectionConfig.Protocol.IsHTTP(),
|
||||
)
|
||||
|
|
@ -251,7 +258,7 @@ func FromConfig(cfg *Config) (*DaprRuntime, error) {
|
|||
|
||||
// API logging can be enabled for this app or for every app, globally in the config
|
||||
if intc.enableAPILogging == nil {
|
||||
intc.enableAPILogging = &globalConfig.Spec.LoggingSpec.APILogging.Enabled
|
||||
intc.enableAPILogging = ptr.Of(globalConfig.GetAPILoggingSpec().Enabled)
|
||||
}
|
||||
|
||||
return newDaprRuntime(intc, globalConfig, accessControlList, resiliencyProvider), nil
|
||||
|
|
@ -261,7 +268,7 @@ func (c *Config) toInternal() (*internalConfig, error) {
|
|||
intc := &internalConfig{
|
||||
id: c.AppID,
|
||||
mode: modes.DaprMode(c.Mode),
|
||||
configPath: c.ConfigPath,
|
||||
config: c.Config,
|
||||
sentryServiceAddress: c.SentryAddress,
|
||||
allowedOrigins: c.AllowedOrigins,
|
||||
kubernetes: configmodes.KubernetesConfig{
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ func newDaprRuntime(runtimeConfig *internalConfig, globalConfig *config.Configur
|
|||
}
|
||||
|
||||
rt.componentAuthorizers = []ComponentAuthorizer{rt.namespaceComponentAuthorizer}
|
||||
if globalConfig != nil && len(globalConfig.Spec.ComponentsSpec.Deny) > 0 {
|
||||
if globalConfig != nil && globalConfig.Spec.ComponentsSpec != nil && len(globalConfig.Spec.ComponentsSpec.Deny) > 0 {
|
||||
dl := newComponentDenyList(globalConfig.Spec.ComponentsSpec.Deny)
|
||||
rt.componentAuthorizers = append(rt.componentAuthorizers, dl.IsAllowed)
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@ func (a *DaprRuntime) getOperatorClient() (operatorv1pb.OperatorClient, error) {
|
|||
// setupTracing set up the trace exporters. Technically we don't need to pass `hostAddress` in,
|
||||
// but we do so here to explicitly call out the dependency on having `hostAddress` computed.
|
||||
func (a *DaprRuntime) setupTracing(hostAddress string, tpStore tracerProviderStore) error {
|
||||
tracingSpec := a.globalConfig.Spec.TracingSpec
|
||||
tracingSpec := a.globalConfig.GetTracingSpec()
|
||||
|
||||
// Register stdout trace exporter if user wants to debug requests or log as Info level.
|
||||
if tracingSpec.Stdout {
|
||||
|
|
@ -353,7 +353,7 @@ func (a *DaprRuntime) setupTracing(hostAddress string, tpStore tracerProviderSto
|
|||
}
|
||||
|
||||
// Register zipkin trace exporter if ZipkinSpec is specified
|
||||
if tracingSpec.Zipkin.EndpointAddress != "" {
|
||||
if tracingSpec.Zipkin != nil && tracingSpec.Zipkin.EndpointAddress != "" {
|
||||
zipkinExporter, err := zipkin.New(tracingSpec.Zipkin.EndpointAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -362,24 +362,23 @@ func (a *DaprRuntime) setupTracing(hostAddress string, tpStore tracerProviderSto
|
|||
}
|
||||
|
||||
// Register otel trace exporter if OtelSpec is specified
|
||||
if tracingSpec.Otel.EndpointAddress != "" && tracingSpec.Otel.Protocol != "" {
|
||||
if tracingSpec.Otel != nil && tracingSpec.Otel.EndpointAddress != "" && tracingSpec.Otel.Protocol != "" {
|
||||
endpoint := tracingSpec.Otel.EndpointAddress
|
||||
protocol := tracingSpec.Otel.Protocol
|
||||
if protocol != "http" && protocol != "grpc" {
|
||||
return fmt.Errorf("invalid protocol %v provided for Otel endpoint", protocol)
|
||||
}
|
||||
isSecure := tracingSpec.Otel.IsSecure
|
||||
|
||||
var client otlptrace.Client
|
||||
if protocol == "http" {
|
||||
clientOptions := []otlptracehttp.Option{otlptracehttp.WithEndpoint(endpoint)}
|
||||
if !isSecure {
|
||||
if !tracingSpec.Otel.GetIsSecure() {
|
||||
clientOptions = append(clientOptions, otlptracehttp.WithInsecure())
|
||||
}
|
||||
client = otlptracehttp.NewClient(clientOptions...)
|
||||
} else {
|
||||
clientOptions := []otlptracegrpc.Option{otlptracegrpc.WithEndpoint(endpoint)}
|
||||
if !isSecure {
|
||||
if !tracingSpec.Otel.GetIsSecure() {
|
||||
clientOptions = append(clientOptions, otlptracegrpc.WithInsecure())
|
||||
}
|
||||
client = otlptracegrpc.NewClient(clientOptions...)
|
||||
|
|
@ -666,50 +665,59 @@ func (a *DaprRuntime) appHealthChanged(status uint8) {
|
|||
|
||||
func (a *DaprRuntime) populateSecretsConfiguration() {
|
||||
// Populate in a map for easy lookup by store name.
|
||||
if a.globalConfig.Spec.Secrets == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, scope := range a.globalConfig.Spec.Secrets.Scopes {
|
||||
a.compStore.AddSecretsConfiguration(scope.StoreName, scope)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *DaprRuntime) buildHTTPPipelineForSpec(spec config.PipelineSpec, targetPipeline string) (pipeline httpMiddleware.Pipeline, err error) {
|
||||
if a.globalConfig != nil {
|
||||
pipeline.Handlers = make([]func(next nethttp.Handler) nethttp.Handler, 0, len(spec.Handlers))
|
||||
for i := 0; i < len(spec.Handlers); i++ {
|
||||
middlewareSpec := spec.Handlers[i]
|
||||
component, exists := a.compStore.GetComponent(middlewareSpec.Type, middlewareSpec.Name)
|
||||
if !exists {
|
||||
// Log the error but continue with initializing the pipeline
|
||||
log.Error("couldn't find middleware component defined in configuration with name %s and type %s/%s",
|
||||
middlewareSpec.Name, middlewareSpec.Type, middlewareSpec.Version)
|
||||
continue
|
||||
}
|
||||
md := middleware.Metadata{Base: a.toBaseMetadata(component)}
|
||||
handler, err := a.httpMiddlewareRegistry.Create(middlewareSpec.Type, middlewareSpec.Version, md, middlewareSpec.LogName())
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("process component %s error: %s", component.Name, err.Error())
|
||||
if !component.Spec.IgnoreErrors {
|
||||
log.Warn("error processing middleware component, daprd process will exit gracefully")
|
||||
a.Shutdown(a.runtimeConfig.gracefulShutdownDuration)
|
||||
log.Fatal(e)
|
||||
// This error is only caught by tests, since during normal execution we panic
|
||||
return pipeline, errors.New("dapr panicked")
|
||||
}
|
||||
log.Error(e)
|
||||
continue
|
||||
}
|
||||
log.Infof("enabled %s/%s %s middleware", middlewareSpec.Type, targetPipeline, middlewareSpec.Version)
|
||||
pipeline.Handlers = append(pipeline.Handlers, handler)
|
||||
pipeline.Handlers = make([]func(next nethttp.Handler) nethttp.Handler, 0, len(spec.Handlers))
|
||||
for i := 0; i < len(spec.Handlers); i++ {
|
||||
middlewareSpec := spec.Handlers[i]
|
||||
component, exists := a.compStore.GetComponent(middlewareSpec.Type, middlewareSpec.Name)
|
||||
if !exists {
|
||||
// Log the error but continue with initializing the pipeline
|
||||
log.Error("couldn't find middleware component defined in configuration with name %s and type %s/%s",
|
||||
middlewareSpec.Name, middlewareSpec.Type, middlewareSpec.Version)
|
||||
continue
|
||||
}
|
||||
md := middleware.Metadata{Base: a.toBaseMetadata(component)}
|
||||
handler, err := a.httpMiddlewareRegistry.Create(middlewareSpec.Type, middlewareSpec.Version, md, middlewareSpec.LogName())
|
||||
if err != nil {
|
||||
e := fmt.Sprintf("process component %s error: %s", component.Name, err.Error())
|
||||
if !component.Spec.IgnoreErrors {
|
||||
log.Warn("error processing middleware component, daprd process will exit gracefully")
|
||||
a.Shutdown(a.runtimeConfig.gracefulShutdownDuration)
|
||||
log.Fatal(e)
|
||||
// This error is only caught by tests, since during normal execution we panic
|
||||
return pipeline, errors.New("dapr panicked")
|
||||
}
|
||||
log.Error(e)
|
||||
continue
|
||||
}
|
||||
log.Infof("enabled %s/%s %s middleware", middlewareSpec.Type, targetPipeline, middlewareSpec.Version)
|
||||
pipeline.Handlers = append(pipeline.Handlers, handler)
|
||||
}
|
||||
|
||||
return pipeline, nil
|
||||
}
|
||||
|
||||
func (a *DaprRuntime) buildHTTPPipeline() (httpMiddleware.Pipeline, error) {
|
||||
return a.buildHTTPPipelineForSpec(a.globalConfig.Spec.HTTPPipelineSpec, "http")
|
||||
if a.globalConfig == nil || a.globalConfig.Spec.HTTPPipelineSpec == nil {
|
||||
return httpMiddleware.Pipeline{}, nil
|
||||
}
|
||||
return a.buildHTTPPipelineForSpec(*a.globalConfig.Spec.HTTPPipelineSpec, "http")
|
||||
}
|
||||
|
||||
func (a *DaprRuntime) buildAppHTTPPipeline() (httpMiddleware.Pipeline, error) {
|
||||
return a.buildHTTPPipelineForSpec(a.globalConfig.Spec.AppHTTPPipelineSpec, "app channel")
|
||||
if a.globalConfig == nil || a.globalConfig.Spec.AppHTTPPipelineSpec == nil {
|
||||
return httpMiddleware.Pipeline{}, nil
|
||||
}
|
||||
return a.buildHTTPPipelineForSpec(*a.globalConfig.Spec.AppHTTPPipelineSpec, "app channel")
|
||||
}
|
||||
|
||||
func (a *DaprRuntime) initBinding(c componentsV1alpha1.Component) error {
|
||||
|
|
@ -1537,7 +1545,7 @@ func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int
|
|||
PubsubAdapter: a.getPublishAdapter(),
|
||||
Actors: a.actor,
|
||||
SendToOutputBindingFn: a.sendToOutputBinding,
|
||||
TracingSpec: a.globalConfig.Spec.TracingSpec,
|
||||
TracingSpec: a.globalConfig.GetTracingSpec(),
|
||||
Shutdown: a.ShutdownWithWait,
|
||||
GetComponentsCapabilitiesFn: a.getComponentsCapabilitesMap,
|
||||
MaxRequestBodySize: int64(a.runtimeConfig.maxRequestBodySize) << 20, // Convert from MB to bytes
|
||||
|
|
@ -1559,17 +1567,17 @@ func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int
|
|||
UnixDomainSocket: a.runtimeConfig.unixDomainSocket,
|
||||
ReadBufferSizeKB: a.runtimeConfig.readBufferSize,
|
||||
EnableAPILogging: *a.runtimeConfig.enableAPILogging,
|
||||
APILoggingObfuscateURLs: a.globalConfig.Spec.LoggingSpec.APILogging.ObfuscateURLs,
|
||||
APILogHealthChecks: !a.globalConfig.Spec.LoggingSpec.APILogging.OmitHealthChecks,
|
||||
APILoggingObfuscateURLs: a.globalConfig.GetAPILoggingSpec().ObfuscateURLs,
|
||||
APILogHealthChecks: !a.globalConfig.GetAPILoggingSpec().OmitHealthChecks,
|
||||
}
|
||||
|
||||
server := http.NewServer(http.NewServerOpts{
|
||||
API: a.daprHTTPAPI,
|
||||
Config: serverConf,
|
||||
TracingSpec: a.globalConfig.Spec.TracingSpec,
|
||||
MetricSpec: a.globalConfig.Spec.MetricSpec,
|
||||
TracingSpec: a.globalConfig.GetTracingSpec(),
|
||||
MetricSpec: a.globalConfig.GetMetricsSpec(),
|
||||
Pipeline: pipeline,
|
||||
APISpec: a.globalConfig.Spec.APISpec,
|
||||
APISpec: a.globalConfig.GetAPISpec(),
|
||||
})
|
||||
if err := server.StartNonBlocking(); err != nil {
|
||||
return err
|
||||
|
|
@ -1582,7 +1590,7 @@ func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int
|
|||
func (a *DaprRuntime) startGRPCInternalServer(api grpc.API, port int) error {
|
||||
// Since GRPCInteralServer is encrypted & authenticated, it is safe to listen on *
|
||||
serverConf := a.getNewServerConfig([]string{""}, port)
|
||||
server := grpc.NewInternalServer(api, serverConf, a.globalConfig.Spec.TracingSpec, a.globalConfig.Spec.MetricSpec, a.authenticator, a.proxy)
|
||||
server := grpc.NewInternalServer(api, serverConf, a.globalConfig.GetTracingSpec(), a.globalConfig.GetMetricsSpec(), a.authenticator, a.proxy)
|
||||
if err := server.StartNonBlocking(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1593,7 +1601,7 @@ func (a *DaprRuntime) startGRPCInternalServer(api grpc.API, port int) error {
|
|||
|
||||
func (a *DaprRuntime) startGRPCAPIServer(api grpc.API, port int) error {
|
||||
serverConf := a.getNewServerConfig(a.runtimeConfig.apiListenAddresses, port)
|
||||
server := grpc.NewAPIServer(api, serverConf, a.globalConfig.Spec.TracingSpec, a.globalConfig.Spec.MetricSpec, a.globalConfig.Spec.APISpec, a.proxy, a.workflowEngine)
|
||||
server := grpc.NewAPIServer(api, serverConf, a.globalConfig.GetTracingSpec(), a.globalConfig.GetMetricsSpec(), a.globalConfig.GetAPISpec(), a.proxy, a.workflowEngine)
|
||||
if err := server.StartNonBlocking(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1632,7 +1640,7 @@ func (a *DaprRuntime) getGRPCAPI() grpc.API {
|
|||
DirectMessaging: a.directMessaging,
|
||||
Actors: a.actor,
|
||||
SendToOutputBindingFn: a.sendToOutputBinding,
|
||||
TracingSpec: a.globalConfig.Spec.TracingSpec,
|
||||
TracingSpec: a.globalConfig.GetTracingSpec(),
|
||||
AccessControlList: a.accessControlList,
|
||||
Shutdown: a.ShutdownWithWait,
|
||||
GetComponentsCapabilitiesFn: a.getComponentsCapabilitesMap,
|
||||
|
|
@ -2240,8 +2248,11 @@ func (a *DaprRuntime) initNameResolution() error {
|
|||
var err error
|
||||
resolverMetadata := nr.Metadata{}
|
||||
|
||||
resolverName := a.globalConfig.Spec.NameResolutionSpec.Component
|
||||
resolverVersion := a.globalConfig.Spec.NameResolutionSpec.Version
|
||||
var resolverName, resolverVersion string
|
||||
if a.globalConfig.Spec.NameResolutionSpec != nil {
|
||||
resolverName = a.globalConfig.Spec.NameResolutionSpec.Component
|
||||
resolverVersion = a.globalConfig.Spec.NameResolutionSpec.Version
|
||||
}
|
||||
|
||||
if resolverName == "" {
|
||||
switch a.runtimeConfig.mode {
|
||||
|
|
@ -2262,7 +2273,9 @@ func (a *DaprRuntime) initNameResolution() error {
|
|||
fName := utils.ComponentLogName(resolverName, "nameResolution", resolverVersion)
|
||||
resolver, err = a.nameResolutionRegistry.Create(resolverName, resolverVersion, fName)
|
||||
resolverMetadata.Name = resolverName
|
||||
resolverMetadata.Configuration = a.globalConfig.Spec.NameResolutionSpec.Configuration
|
||||
if a.globalConfig.Spec.NameResolutionSpec != nil {
|
||||
resolverMetadata.Configuration = a.globalConfig.Spec.NameResolutionSpec.Configuration
|
||||
}
|
||||
resolverMetadata.Properties = map[string]string{
|
||||
nr.DaprHTTPPort: strconv.Itoa(a.runtimeConfig.httpPort),
|
||||
nr.DaprPort: strconv.Itoa(a.runtimeConfig.internalGRPCPort),
|
||||
|
|
@ -2578,7 +2591,7 @@ func (a *DaprRuntime) initActors() error {
|
|||
GRPCConnectionFn: a.grpc.GetGRPCConnection,
|
||||
Config: actorConfig,
|
||||
CertChain: a.runtimeConfig.certChain,
|
||||
TracingSpec: a.globalConfig.Spec.TracingSpec,
|
||||
TracingSpec: a.globalConfig.GetTracingSpec(),
|
||||
Resiliency: a.resiliency,
|
||||
StateStoreName: a.actorStateStoreName,
|
||||
CompStore: a.compStore,
|
||||
|
|
@ -3271,7 +3284,7 @@ func (a *DaprRuntime) getAppHTTPChannelConfig(pipeline httpMiddleware.Pipeline,
|
|||
CompStore: a.compStore,
|
||||
MaxConcurrency: a.runtimeConfig.appConnectionConfig.MaxConcurrency,
|
||||
Pipeline: pipeline,
|
||||
TracingSpec: a.globalConfig.Spec.TracingSpec,
|
||||
TracingSpec: a.globalConfig.GetTracingSpec(),
|
||||
MaxRequestBodySizeMB: a.runtimeConfig.maxRequestBodySize,
|
||||
}
|
||||
|
||||
|
|
@ -3534,7 +3547,7 @@ func pubsubTopicKey(componentName, topicName string) string {
|
|||
func createGRPCManager(runtimeConfig *internalConfig, globalConfig *config.Configuration) *grpc.Manager {
|
||||
grpcAppChannelConfig := &grpc.AppChannelConfig{}
|
||||
if globalConfig != nil {
|
||||
grpcAppChannelConfig.TracingSpec = globalConfig.Spec.TracingSpec
|
||||
grpcAppChannelConfig.TracingSpec = globalConfig.GetTracingSpec()
|
||||
grpcAppChannelConfig.AllowInsecureTLS = globalConfig.IsFeatureEnabled(config.AppChannelAllowInsecureTLS)
|
||||
}
|
||||
if runtimeConfig != nil {
|
||||
|
|
|
|||
|
|
@ -931,7 +931,9 @@ func TestInitNameResolution(t *testing.T) {
|
|||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec.Component = "targetResolver"
|
||||
rt.globalConfig.Spec.NameResolutionSpec = &config.NameResolutionSpec{
|
||||
Component: "targetResolver",
|
||||
}
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "anotherResolver", nil)
|
||||
|
|
@ -948,7 +950,9 @@ func TestInitNameResolution(t *testing.T) {
|
|||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec.Component = "someResolver"
|
||||
rt.globalConfig.Spec.NameResolutionSpec = &config.NameResolutionSpec{
|
||||
Component: "someResolver",
|
||||
}
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "someResolver", nil)
|
||||
|
|
@ -965,7 +969,24 @@ func TestInitNameResolution(t *testing.T) {
|
|||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec.Component = ""
|
||||
rt.globalConfig.Spec.NameResolutionSpec = &config.NameResolutionSpec{}
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "mdns", nil)
|
||||
|
||||
// act
|
||||
err := rt.initNameResolution()
|
||||
|
||||
// assert
|
||||
assert.NoError(t, err, "expected no error")
|
||||
})
|
||||
|
||||
t.Run("test init nameresolution nil in StandaloneMode", func(t *testing.T) {
|
||||
// given
|
||||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec = nil
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "mdns", nil)
|
||||
|
|
@ -982,7 +1003,24 @@ func TestInitNameResolution(t *testing.T) {
|
|||
rt := NewTestDaprRuntime(modes.KubernetesMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec.Component = ""
|
||||
rt.globalConfig.Spec.NameResolutionSpec = &config.NameResolutionSpec{}
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "kubernetes", nil)
|
||||
|
||||
// act
|
||||
err := rt.initNameResolution()
|
||||
|
||||
// assert
|
||||
assert.NoError(t, err, "expected no error")
|
||||
})
|
||||
|
||||
t.Run("test init nameresolution nil in KubernetesMode", func(t *testing.T) {
|
||||
// given
|
||||
rt := NewTestDaprRuntime(modes.KubernetesMode)
|
||||
|
||||
// target resolver
|
||||
rt.globalConfig.Spec.NameResolutionSpec = nil
|
||||
|
||||
// registered resolver
|
||||
initMockResolverForRuntime(rt, "kubernetes", nil)
|
||||
|
|
@ -1014,7 +1052,7 @@ func TestSetupTracing(t *testing.T) {
|
|||
}, {
|
||||
name: "bad host address, failing zipkin",
|
||||
tracingConfig: config.TracingSpec{
|
||||
Zipkin: config.ZipkinSpec{
|
||||
Zipkin: &config.ZipkinSpec{
|
||||
EndpointAddress: "localhost",
|
||||
},
|
||||
},
|
||||
|
|
@ -1022,7 +1060,7 @@ func TestSetupTracing(t *testing.T) {
|
|||
}, {
|
||||
name: "zipkin trace exporter",
|
||||
tracingConfig: config.TracingSpec{
|
||||
Zipkin: config.ZipkinSpec{
|
||||
Zipkin: &config.ZipkinSpec{
|
||||
EndpointAddress: "http://foo.bar",
|
||||
},
|
||||
},
|
||||
|
|
@ -1030,9 +1068,9 @@ func TestSetupTracing(t *testing.T) {
|
|||
}, {
|
||||
name: "otel trace http exporter",
|
||||
tracingConfig: config.TracingSpec{
|
||||
Otel: config.OtelSpec{
|
||||
Otel: &config.OtelSpec{
|
||||
EndpointAddress: "foo.bar",
|
||||
IsSecure: false,
|
||||
IsSecure: ptr.Of(false),
|
||||
Protocol: "http",
|
||||
},
|
||||
},
|
||||
|
|
@ -1040,9 +1078,9 @@ func TestSetupTracing(t *testing.T) {
|
|||
}, {
|
||||
name: "invalid otel trace exporter protocol",
|
||||
tracingConfig: config.TracingSpec{
|
||||
Otel: config.OtelSpec{
|
||||
Otel: &config.OtelSpec{
|
||||
EndpointAddress: "foo.bar",
|
||||
IsSecure: false,
|
||||
IsSecure: ptr.Of(false),
|
||||
Protocol: "tcp",
|
||||
},
|
||||
},
|
||||
|
|
@ -1056,12 +1094,12 @@ func TestSetupTracing(t *testing.T) {
|
|||
}, {
|
||||
name: "all trace exporters",
|
||||
tracingConfig: config.TracingSpec{
|
||||
Otel: config.OtelSpec{
|
||||
Otel: &config.OtelSpec{
|
||||
EndpointAddress: "http://foo.bar",
|
||||
IsSecure: false,
|
||||
IsSecure: ptr.Of(false),
|
||||
Protocol: "http",
|
||||
},
|
||||
Zipkin: config.ZipkinSpec{
|
||||
Zipkin: &config.ZipkinSpec{
|
||||
EndpointAddress: "http://foo.bar",
|
||||
},
|
||||
Stdout: true,
|
||||
|
|
@ -1073,7 +1111,7 @@ func TestSetupTracing(t *testing.T) {
|
|||
t.Run(tc.name, func(t *testing.T) {
|
||||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
defer stopRuntime(t, rt)
|
||||
rt.globalConfig.Spec.TracingSpec = tc.tracingConfig
|
||||
rt.globalConfig.Spec.TracingSpec = &tc.tracingConfig
|
||||
if tc.hostAddress != "" {
|
||||
rt.hostAddress = tc.hostAddress
|
||||
}
|
||||
|
|
@ -2458,10 +2496,12 @@ func TestPopulateSecretsConfiguration(t *testing.T) {
|
|||
// setup
|
||||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
defer stopRuntime(t, rt)
|
||||
rt.globalConfig.Spec.Secrets.Scopes = []config.SecretsScope{
|
||||
{
|
||||
StoreName: "testMock",
|
||||
DefaultAccess: "allow",
|
||||
rt.globalConfig.Spec.Secrets = &config.SecretsSpec{
|
||||
Scopes: []config.SecretsScope{
|
||||
{
|
||||
StoreName: "testMock",
|
||||
DefaultAccess: "allow",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -6069,10 +6109,10 @@ func initMockStateStoreForRuntime(rt *DaprRuntime, encryptKey string, e error) *
|
|||
func TestTraceShutdown(t *testing.T) {
|
||||
rt := NewTestDaprRuntime(modes.StandaloneMode)
|
||||
rt.runtimeConfig.gracefulShutdownDuration = 5 * time.Second
|
||||
rt.globalConfig.Spec.TracingSpec = config.TracingSpec{
|
||||
Otel: config.OtelSpec{
|
||||
rt.globalConfig.Spec.TracingSpec = &config.TracingSpec{
|
||||
Otel: &config.OtelSpec{
|
||||
EndpointAddress: "foo.bar",
|
||||
IsSecure: false,
|
||||
IsSecure: ptr.Of(false),
|
||||
Protocol: "http",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ func getKubernetesConfig(configName string) (SentryConfig, error) {
|
|||
|
||||
func getSelfhostedConfig(configName string) (SentryConfig, error) {
|
||||
defaultConfig := getDefaultConfig()
|
||||
daprConfig, _, err := daprGlobalConfig.LoadStandaloneConfiguration(configName)
|
||||
daprConfig, err := daprGlobalConfig.LoadStandaloneConfiguration(configName)
|
||||
if err != nil {
|
||||
return defaultConfig, err
|
||||
}
|
||||
|
|
@ -149,8 +149,9 @@ func getSelfhostedConfig(configName string) (SentryConfig, error) {
|
|||
}
|
||||
|
||||
func parseConfiguration(conf SentryConfig, daprConfig *daprGlobalConfig.Configuration) (SentryConfig, error) {
|
||||
if daprConfig.Spec.MTLSSpec.WorkloadCertTTL != "" {
|
||||
d, err := time.ParseDuration(daprConfig.Spec.MTLSSpec.WorkloadCertTTL)
|
||||
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)
|
||||
}
|
||||
|
|
@ -158,8 +159,8 @@ func parseConfiguration(conf SentryConfig, daprConfig *daprGlobalConfig.Configur
|
|||
conf.WorkloadCertTTL = d
|
||||
}
|
||||
|
||||
if daprConfig.Spec.MTLSSpec.AllowedClockSkew != "" {
|
||||
d, err := time.ParseDuration(daprConfig.Spec.MTLSSpec.AllowedClockSkew)
|
||||
if mtlsSpec.AllowedClockSkew != "" {
|
||||
d, err := time.ParseDuration(mtlsSpec.AllowedClockSkew)
|
||||
if err != nil {
|
||||
return conf, fmt.Errorf("error parsing AllowedClockSkew duration: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func TestConfig(t *testing.T) {
|
|||
t.Run("parse configuration", func(t *testing.T) {
|
||||
daprConfig := daprDaprConfig.Configuration{
|
||||
Spec: daprDaprConfig.ConfigurationSpec{
|
||||
MTLSSpec: daprDaprConfig.MTLSSpec{
|
||||
MTLSSpec: &daprDaprConfig.MTLSSpec{
|
||||
Enabled: true,
|
||||
WorkloadCertTTL: "5s",
|
||||
AllowedClockSkew: "1h",
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ func TestServiceInvocationWithAllowLists(t *testing.T) {
|
|||
t.Logf("configuration name: daprsystem, get failed: %s \n", err.Error())
|
||||
os.Exit(-1)
|
||||
}
|
||||
if !config.Spec.MTLSSpec.Enabled {
|
||||
if !config.Spec.MTLSSpec.GetEnabled() {
|
||||
t.Logf("mtls disabled. can't running unit tests")
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import (
|
|||
"github.com/dapr/dapr/tests/runner/summary"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/exp/slices"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ code-generate: controller-gen
|
|||
$(CONTROLLER_GEN) object:headerFile="./tools/boilerplate.go.txt" \
|
||||
crd:crdVersions=v1 paths="./pkg/apis/..." output:crd:artifacts:config=config/crd/bases
|
||||
$(CONTROLLER_GEN) object:headerFile="./tools/boilerplate.go.txt" \
|
||||
paths="./pkg/apis/..."
|
||||
paths="./pkg/apis/..."
|
||||
|
||||
# find or download controller-gen
|
||||
# download controller-gen if necessary
|
||||
|
|
@ -21,7 +21,7 @@ ifeq (, $(shell which controller-gen))
|
|||
set -e ;\
|
||||
CONTROLLER_GEN_TMP_DIR="$$(mktemp -d)" ;\
|
||||
cd "$$CONTROLLER_GEN_TMP_DIR" ;\
|
||||
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.5.0 ; \
|
||||
go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.3 ; \
|
||||
rm -rf "$$CONTROLLER_GEN_TMP_DIR" ;\
|
||||
}
|
||||
CONTROLLER_GEN=$(GOBIN)/controller-gen
|
||||
|
|
|
|||
Loading…
Reference in New Issue