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 | ||||
| 	} | ||||
|  | @ -83,6 +85,7 @@ type Config struct { | |||
| 	LeaseDuration           time.Duration | ||||
| 	RenewDeadline           time.Duration | ||||
| 	RetryPeriod             time.Duration | ||||
| 	LeaseNamesPrefixMapping map[string]string | ||||
| } | ||||
| 
 | ||||
| func (c *Config) GetComponentConfig(name string) ComponentConfig { | ||||
|  | @ -92,6 +95,7 @@ func (c *Config) GetComponentConfig(name string) ComponentConfig { | |||
| 		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