mirror of https://github.com/knative/pkg.git
Allow overriding lease name for a reconciler (#2435)
Add a `map-lease-prefix` prefix for config keys for `config-leader-election` that is a map from a generated lease prefix to a new prefix: ```yaml map-lease-prefix.<component>.<package>.<reconciler_type_name>: <new_prefix> map-lease-prefix.<component-x>.<package-x>.<reconciler_type_name-x>: <new_prefix> ``` Signed-off-by: Pierangelo Di Pilato <pierdipi@redhat.com>
This commit is contained in:
parent
9b5c41135d
commit
fe26417344
|
|
@ -244,3 +244,16 @@ func Parse(data map[string]string, parsers ...ParseFunc) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsOptionalMap parses the data into the target as a map[string]string, if it exists.
|
||||
// The map is represented as a list of key-value pairs with a common prefix.
|
||||
func AsOptionalMap(prefix string, target map[string]string) ParseFunc {
|
||||
return func(data map[string]string) error {
|
||||
for k, v := range data {
|
||||
if strings.HasPrefix(k, prefix) && len(k) > len(prefix)+1 {
|
||||
target[k[len(prefix)+1: /* remove dot `.` */]] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ type testConfig struct {
|
|||
|
||||
nsn types.NamespacedName
|
||||
onsn *types.NamespacedName
|
||||
|
||||
dict map[string]string
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
|
|
@ -70,6 +72,12 @@ func TestParse(t *testing.T) {
|
|||
|
||||
"test-namespaced-name": "some-namespace/some-name",
|
||||
"test-optional-namespaced-name": "some-other-namespace/some-other-name",
|
||||
|
||||
"test-dict.k": "v",
|
||||
"test-dict.k1": "v1",
|
||||
},
|
||||
conf: testConfig{
|
||||
dict: map[string]string{},
|
||||
},
|
||||
want: testConfig{
|
||||
str: "foo.bar",
|
||||
|
|
@ -92,6 +100,10 @@ func TestParse(t *testing.T) {
|
|||
Name: "some-other-name",
|
||||
Namespace: "some-other-namespace",
|
||||
},
|
||||
dict: map[string]string{
|
||||
"k": "v",
|
||||
"k1": "v1",
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "respect defaults",
|
||||
|
|
@ -175,6 +187,18 @@ func TestParse(t *testing.T) {
|
|||
"test-namespaced-name": "default/resource/whut",
|
||||
},
|
||||
expectErr: true,
|
||||
}, {
|
||||
name: "dict without key and dot",
|
||||
data: map[string]string{
|
||||
"test-dict": "v",
|
||||
},
|
||||
expectErr: false,
|
||||
}, {
|
||||
name: "dict without key",
|
||||
data: map[string]string{
|
||||
"test-dict.": "v",
|
||||
},
|
||||
expectErr: false,
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
@ -194,6 +218,7 @@ func TestParse(t *testing.T) {
|
|||
AsQuantity("test-quantity", &test.conf.qua),
|
||||
AsNamespacedName("test-namespaced-name", &test.conf.nsn),
|
||||
AsOptionalNamespacedName("test-optional-namespaced-name", &test.conf.onsn),
|
||||
AsOptionalMap("test-dict", test.conf.dict),
|
||||
); (err == nil) == test.expectErr {
|
||||
t.Fatal("Failed to parse data:", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ func NewConfigFromMap(data map[string]string) (*Config, error) {
|
|||
cm.AsDuration("retry-period", &config.RetryPeriod),
|
||||
|
||||
cm.AsUint32("buckets", &config.Buckets),
|
||||
|
||||
cm.AsOptionalMap("map-lease-prefix", config.LeaseNamesPrefixMapping),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -79,19 +81,21 @@ func NewConfigFromConfigMap(configMap *corev1.ConfigMap) (*Config, error) {
|
|||
// contained within a single namespace. Typically these will correspond to a
|
||||
// single source repository, viz: serving or eventing.
|
||||
type Config struct {
|
||||
Buckets uint32
|
||||
LeaseDuration time.Duration
|
||||
RenewDeadline time.Duration
|
||||
RetryPeriod time.Duration
|
||||
Buckets uint32
|
||||
LeaseDuration time.Duration
|
||||
RenewDeadline time.Duration
|
||||
RetryPeriod time.Duration
|
||||
LeaseNamesPrefixMapping map[string]string
|
||||
}
|
||||
|
||||
func (c *Config) GetComponentConfig(name string) ComponentConfig {
|
||||
return ComponentConfig{
|
||||
Component: name,
|
||||
Buckets: c.Buckets,
|
||||
LeaseDuration: c.LeaseDuration,
|
||||
RenewDeadline: c.RenewDeadline,
|
||||
RetryPeriod: c.RetryPeriod,
|
||||
Component: name,
|
||||
Buckets: c.Buckets,
|
||||
LeaseDuration: c.LeaseDuration,
|
||||
RenewDeadline: c.RenewDeadline,
|
||||
RetryPeriod: c.RetryPeriod,
|
||||
LeaseNamesPrefixMapping: c.LeaseNamesPrefixMapping,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +127,11 @@ type ComponentConfig struct {
|
|||
// be generated to be used as identity for each BuildElector call.
|
||||
// Autoscaler uses the pod IP as identity.
|
||||
Identity string
|
||||
|
||||
// LeaseNamesPrefixMapping maps lease prefixes
|
||||
// from <component>.<package>.<reconciler_type_name> to the
|
||||
// associated value when using standardBuilder.
|
||||
LeaseNamesPrefixMapping map[string]string
|
||||
}
|
||||
|
||||
// statefulSetID is a envconfig Decodable controller ordinal and name.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
|
||||
"knative.dev/pkg/hash"
|
||||
"knative.dev/pkg/logging"
|
||||
"knative.dev/pkg/network"
|
||||
|
|
@ -192,7 +193,11 @@ func newStandardBuckets(queueName string, cc ComponentConfig) []reconciler.Bucke
|
|||
}
|
||||
|
||||
func standardBucketName(ordinal uint32, queueName string, cc ComponentConfig) string {
|
||||
return strings.ToLower(fmt.Sprintf("%s.%s.%02d-of-%02d", cc.Component, queueName, ordinal, cc.Buckets))
|
||||
prefix := fmt.Sprintf("%s.%s", cc.Component, queueName)
|
||||
if v, ok := cc.LeaseNamesPrefixMapping[prefix]; ok && len(v) > 0 {
|
||||
prefix = v
|
||||
}
|
||||
return strings.ToLower(fmt.Sprintf("%s.%02d-of-%02d", prefix, ordinal, cc.Buckets))
|
||||
}
|
||||
|
||||
type statefulSetBuilder struct {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
fakekube "k8s.io/client-go/kubernetes/fake"
|
||||
ktesting "k8s.io/client-go/testing"
|
||||
|
||||
"knative.dev/pkg/reconciler"
|
||||
_ "knative.dev/pkg/system/testing"
|
||||
)
|
||||
|
|
@ -355,3 +356,42 @@ func TestWithUnopposedElector(t *testing.T) {
|
|||
// Wait to see if PromoteFunc is called with nil or our enq function.
|
||||
<-time.After(time.Second)
|
||||
}
|
||||
|
||||
func TestStandardBucketName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ordinal uint32
|
||||
queueName string
|
||||
cc ComponentConfig
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "identity",
|
||||
ordinal: 0,
|
||||
queueName: "queue-queue",
|
||||
cc: ComponentConfig{
|
||||
Component: "my-comp",
|
||||
},
|
||||
want: "my-comp.queue-queue.00-of-00",
|
||||
},
|
||||
{
|
||||
name: "remapping",
|
||||
ordinal: 0,
|
||||
queueName: "queue-queue",
|
||||
cc: ComponentConfig{
|
||||
Component: "my-comp",
|
||||
LeaseNamesPrefixMapping: map[string]string{
|
||||
"my-comp.queue-queue": "my-comp-2.queue",
|
||||
},
|
||||
},
|
||||
want: "my-comp-2.queue.00-of-00",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := standardBucketName(tt.ordinal, tt.queueName, tt.cc); got != tt.want {
|
||||
t.Errorf("got %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue