mirror of https://github.com/knative/func.git
feat!: use key&value for Labels (#472)
* feat!: use key/value for labels Signed-off-by: Zbynek Roubalik <zroubali@redhat.com> * fix typo Signed-off-by: Zbynek Roubalik <zroubali@redhat.com>
This commit is contained in:
parent
c7332ffb7b
commit
55696811e3
|
@ -175,7 +175,7 @@ func runAddEnvsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
newEnv := fn.Pair{}
|
||||
newEnv := fn.Env{}
|
||||
|
||||
switch selectedOption {
|
||||
// SECTION - add new Environment variable with the specified value
|
||||
|
@ -403,7 +403,7 @@ func runRemoveEnvsPrompt(f fn.Function) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
var newEnvs fn.Pairs
|
||||
var newEnvs fn.Envs
|
||||
removed := false
|
||||
for i, e := range f.Envs {
|
||||
if e.String() == selectedEnv {
|
||||
|
|
|
@ -152,17 +152,17 @@ func runAddLabelsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
newPair := fn.Pair{}
|
||||
newPair := fn.Label{}
|
||||
|
||||
switch selectedOption {
|
||||
// SECTION - add new label with the specified value
|
||||
case optionLabelValue:
|
||||
qs := []*survey.Question{
|
||||
{
|
||||
Name: "name",
|
||||
Prompt: &survey.Input{Message: "Please specify the label name:"},
|
||||
Name: "key",
|
||||
Prompt: &survey.Input{Message: "Please specify the label key:"},
|
||||
Validate: func(val interface{}) error {
|
||||
return utils.ValidateLabelName(val.(string))
|
||||
return utils.ValidateLabelKey(val.(string))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ func runAddLabelsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
}},
|
||||
}
|
||||
answers := struct {
|
||||
Name string
|
||||
Key string
|
||||
Value string
|
||||
}{}
|
||||
|
||||
|
@ -185,17 +185,17 @@ func runAddLabelsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
newPair.Name = &answers.Name
|
||||
newPair.Key = &answers.Key
|
||||
newPair.Value = &answers.Value
|
||||
|
||||
// SECTION - add new label with value from a local environment variable
|
||||
case optionLabelLocal:
|
||||
qs := []*survey.Question{
|
||||
{
|
||||
Name: "name",
|
||||
Prompt: &survey.Input{Message: "Please specify the label name:"},
|
||||
Name: "key",
|
||||
Prompt: &survey.Input{Message: "Please specify the label key:"},
|
||||
Validate: func(val interface{}) error {
|
||||
return utils.ValidateLabelName(val.(string))
|
||||
return utils.ValidateLabelKey(val.(string))
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -207,7 +207,7 @@ func runAddLabelsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
},
|
||||
}
|
||||
answers := struct {
|
||||
Name string
|
||||
Key string
|
||||
Value string
|
||||
}{}
|
||||
|
||||
|
@ -224,7 +224,7 @@ func runAddLabelsPrompt(ctx context.Context, f fn.Function) (err error) {
|
|||
}
|
||||
|
||||
value := fmt.Sprintf("{{ env:%s }}", answers.Value)
|
||||
newPair.Name = &answers.Name
|
||||
newPair.Key = &answers.Key
|
||||
newPair.Value = &value
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ func runRemoveLabelsPrompt(f fn.Function) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
var newLabels fn.Pairs
|
||||
var newLabels fn.Labels
|
||||
removed := false
|
||||
for i, e := range f.Labels {
|
||||
if e.String() == selectedLabel {
|
||||
|
|
|
@ -276,7 +276,7 @@ func envFromCmd(cmd *cobra.Command) (*util.OrderedMap, []string, error) {
|
|||
return util.NewOrderedMap(), []string{}, nil
|
||||
}
|
||||
|
||||
func mergeEnvs(envs fn.Pairs, envToUpdate *util.OrderedMap, envToRemove []string) (fn.Pairs, error) {
|
||||
func mergeEnvs(envs fn.Envs, envToUpdate *util.OrderedMap, envToRemove []string) (fn.Envs, error) {
|
||||
updated := sets.NewString()
|
||||
|
||||
for i := range envs {
|
||||
|
@ -294,7 +294,7 @@ func mergeEnvs(envs fn.Pairs, envToUpdate *util.OrderedMap, envToRemove []string
|
|||
if !updated.Has(name) {
|
||||
n := name
|
||||
v := value
|
||||
envs = append(envs, fn.Pair{Name: &n, Value: &v})
|
||||
envs = append(envs, fn.Env{Name: &n, Value: &v})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ func mergeEnvs(envs fn.Pairs, envToUpdate *util.OrderedMap, envToRemove []string
|
|||
|
||||
errMsg := fn.ValidateEnvs(envs)
|
||||
if len(errMsg) > 0 {
|
||||
return fn.Pairs{}, fmt.Errorf(strings.Join(errMsg, "\n"))
|
||||
return fn.Envs{}, fmt.Errorf(strings.Join(errMsg, "\n"))
|
||||
}
|
||||
|
||||
return envs, nil
|
||||
|
|
|
@ -18,77 +18,77 @@ func Test_mergeEnvMaps(t *testing.T) {
|
|||
v2 := "y"
|
||||
|
||||
type args struct {
|
||||
envs fn.Pairs
|
||||
envs fn.Envs
|
||||
toUpdate *util.OrderedMap
|
||||
toRemove []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want fn.Pairs
|
||||
want fn.Envs
|
||||
}{
|
||||
{
|
||||
"add new var to empty list",
|
||||
args{
|
||||
fn.Pairs{},
|
||||
fn.Envs{},
|
||||
util.NewOrderedMapWithKVStrings([][]string{{a, v1}}),
|
||||
[]string{},
|
||||
},
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}},
|
||||
},
|
||||
{
|
||||
"add new var",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &b, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &b, Value: &v2}},
|
||||
util.NewOrderedMapWithKVStrings([][]string{{a, v1}}),
|
||||
[]string{},
|
||||
},
|
||||
fn.Pairs{fn.Pair{Name: &b, Value: &v2}, fn.Pair{Name: &a, Value: &v1}},
|
||||
fn.Envs{fn.Env{Name: &b, Value: &v2}, fn.Env{Name: &a, Value: &v1}},
|
||||
},
|
||||
{
|
||||
"update var",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}},
|
||||
util.NewOrderedMapWithKVStrings([][]string{{a, v2}}),
|
||||
[]string{},
|
||||
},
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v2}},
|
||||
},
|
||||
{
|
||||
"update multiple vars",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}, fn.Pair{Name: &b, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}, fn.Env{Name: &b, Value: &v2}},
|
||||
util.NewOrderedMapWithKVStrings([][]string{{a, v2}, {b, v1}}),
|
||||
[]string{},
|
||||
},
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v2}, fn.Pair{Name: &b, Value: &v1}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v2}, fn.Env{Name: &b, Value: &v1}},
|
||||
},
|
||||
{
|
||||
"remove var",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}},
|
||||
util.NewOrderedMap(),
|
||||
[]string{a},
|
||||
},
|
||||
fn.Pairs{},
|
||||
fn.Envs{},
|
||||
},
|
||||
{
|
||||
"remove multiple vars",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}, fn.Pair{Name: &b, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}, fn.Env{Name: &b, Value: &v2}},
|
||||
util.NewOrderedMap(),
|
||||
[]string{a, b},
|
||||
},
|
||||
fn.Pairs{},
|
||||
fn.Envs{},
|
||||
},
|
||||
{
|
||||
"update and remove vars",
|
||||
args{
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v1}, fn.Pair{Name: &b, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v1}, fn.Env{Name: &b, Value: &v2}},
|
||||
util.NewOrderedMapWithKVStrings([][]string{{a, v2}}),
|
||||
[]string{b},
|
||||
},
|
||||
fn.Pairs{fn.Pair{Name: &a, Value: &v2}},
|
||||
fn.Envs{fn.Env{Name: &a, Value: &v2}},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
|
92
config.go
92
config.go
|
@ -42,13 +42,13 @@ func (v Volume) String() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
type Pairs []Pair
|
||||
type Pair struct {
|
||||
Name *string `yaml:"name,omitempty"`
|
||||
type Envs []Env
|
||||
type Env struct {
|
||||
Name *string `yaml:"name,omitempty" jsonschema:"pattern=^[-._a-zA-Z][-._a-zA-Z0-9]*$"`
|
||||
Value *string `yaml:"value"`
|
||||
}
|
||||
|
||||
func (e Pair) String() string {
|
||||
func (e Env) String() string {
|
||||
if e.Name == nil && e.Value != nil {
|
||||
match := regWholeSecret.FindStringSubmatch(*e.Value)
|
||||
if len(match) == 2 {
|
||||
|
@ -61,18 +61,40 @@ func (e Pair) String() string {
|
|||
} else if e.Name != nil && e.Value != nil {
|
||||
match := regKeyFromSecret.FindStringSubmatch(*e.Value)
|
||||
if len(match) == 3 {
|
||||
return fmt.Sprintf("Entry \"%s\" with value set from key \"%s\" from Secret \"%s\"", *e.Name, match[2], match[1])
|
||||
return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from Secret \"%s\"", *e.Name, match[2], match[1])
|
||||
}
|
||||
match = regKeyFromConfigMap.FindStringSubmatch(*e.Value)
|
||||
if len(match) == 3 {
|
||||
return fmt.Sprintf("Entry \"%s\" with value set from key \"%s\" from ConfigMap \"%s\"", *e.Name, match[2], match[1])
|
||||
return fmt.Sprintf("Env \"%s\" with value set from key \"%s\" from ConfigMap \"%s\"", *e.Name, match[2], match[1])
|
||||
}
|
||||
match = regLocalEnv.FindStringSubmatch(*e.Value)
|
||||
if len(match) == 2 {
|
||||
return fmt.Sprintf("Entry \"%s\" with value set from local env variable \"%s\"", *e.Name, match[1])
|
||||
return fmt.Sprintf("Env \"%s\" with value set from local env variable \"%s\"", *e.Name, match[1])
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Entry \"%s\" with value \"%s\"", *e.Name, *e.Value)
|
||||
return fmt.Sprintf("Env \"%s\" with value \"%s\"", *e.Name, *e.Value)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Labels []Label
|
||||
type Label struct {
|
||||
// Key consist of optional prefix part (ended by '/') and name part
|
||||
// Prefix part validation pattern: [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
|
||||
// Name part validation pattern: ([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]
|
||||
Key *string `yaml:"key" jsonschema:"pattern=^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/)?([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$"`
|
||||
Value *string `yaml:"value,omitempty" jsonschema:"pattern=^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$"`
|
||||
}
|
||||
|
||||
func (l Label) String() string {
|
||||
if l.Key != nil && l.Value == nil {
|
||||
return fmt.Sprintf("Label with key \"%s\"", *l.Key)
|
||||
} else if l.Key != nil && l.Value != nil {
|
||||
match := regLocalEnv.FindStringSubmatch(*l.Value)
|
||||
if len(match) == 2 {
|
||||
return fmt.Sprintf("Label with key \"%s\" and value set from local env variable \"%s\"", *l.Key, match[1])
|
||||
}
|
||||
return fmt.Sprintf("Label with key \"%s\" and value \"%s\"", *l.Key, *l.Value)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -117,10 +139,10 @@ type Config struct {
|
|||
Builder string `yaml:"builder"`
|
||||
BuilderMap map[string]string `yaml:"builderMap"`
|
||||
Volumes Volumes `yaml:"volumes"`
|
||||
Envs Pairs `yaml:"envs"`
|
||||
Envs Envs `yaml:"envs"`
|
||||
Annotations map[string]string `yaml:"annotations"`
|
||||
Options Options `yaml:"options"`
|
||||
Labels Pairs `yaml:"labels"`
|
||||
Labels Labels `yaml:"labels"`
|
||||
// Add new values to the toConfig/fromConfig functions.
|
||||
}
|
||||
|
||||
|
@ -307,7 +329,7 @@ func validateVolumes(volumes Volumes) (errors []string) {
|
|||
// - name: EXAMPLE4
|
||||
// value: {{ configMap:configMapName:key }} # ENV from a key in configMap
|
||||
// - value: {{ configMap:configMapName }} # all key-pair values from configMap are set as ENV
|
||||
func ValidateEnvs(envs Pairs) (errors []string) {
|
||||
func ValidateEnvs(envs Envs) (errors []string) {
|
||||
|
||||
for i, env := range envs {
|
||||
if env.Name == nil && env.Value == nil {
|
||||
|
@ -347,36 +369,38 @@ func ValidateEnvs(envs Pairs) (errors []string) {
|
|||
// Returns array of error messages, empty if no errors are found
|
||||
//
|
||||
// Allowed settings:
|
||||
// - name: EXAMPLE1 # label directly from a value
|
||||
// - key: EXAMPLE1 # label directly from a value
|
||||
// value: value1
|
||||
// - name: EXAMPLE2 # label from the local ENV var
|
||||
// - key: EXAMPLE2 # label from the local ENV var
|
||||
// value: {{ env:MY_ENV }}
|
||||
func ValidateLabels(labels Pairs) (errors []string) {
|
||||
func ValidateLabels(labels Labels) (errors []string) {
|
||||
for i, label := range labels {
|
||||
if label.Name == nil && label.Value == nil {
|
||||
if label.Key == nil && label.Value == nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d is not properly set", i))
|
||||
} else if label.Value == nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d is missing value field, only name '%s' is set", i, *label.Name))
|
||||
} else if label.Key == nil && label.Value != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d is missing key field, only value '%s' is set", i, *label.Value))
|
||||
} else {
|
||||
|
||||
if err := utils.ValidateLabelName(*label.Name); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d has invalid name or value set: %q %q; %s", i, *label.Name, *label.Value, err.Error()))
|
||||
} else if err := utils.ValidateLabelValue(*label.Value); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d has invalid name or value set: %q %q; %s", i, *label.Name, *label.Value, err.Error()))
|
||||
if err := utils.ValidateLabelKey(*label.Key); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d has invalid key set: %q; %s", i, *label.Key, err.Error()))
|
||||
}
|
||||
if label.Value != nil {
|
||||
if err := utils.ValidateLabelValue(*label.Value); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d has invalid value set: %q; %s", i, *label.Value, err.Error()))
|
||||
}
|
||||
|
||||
if strings.HasPrefix(*label.Value, "{{") {
|
||||
// ENV from the local ENV var; {{ env:MY_ENV }}
|
||||
if !regLocalEnv.MatchString(*label.Value) {
|
||||
errors = append(errors,
|
||||
fmt.Sprintf(
|
||||
"label entry #%d with name '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'",
|
||||
i, *label.Name, *label.Value))
|
||||
} else {
|
||||
match := regLocalEnv.FindStringSubmatch(*label.Value)
|
||||
value := os.Getenv(match[1])
|
||||
if err := utils.ValidateLabelValue(value); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d with name '%s' has invalid value when the environment is evaluated: '%s': %s", i, *label.Name, value, err.Error()))
|
||||
if strings.HasPrefix(*label.Value, "{{") {
|
||||
// ENV from the local ENV var; {{ env:MY_ENV }}
|
||||
if !regLocalEnv.MatchString(*label.Value) {
|
||||
errors = append(errors,
|
||||
fmt.Sprintf(
|
||||
"label entry #%d with key '%s' has invalid value field set, it has '%s', but allowed is only '{{ env:MY_ENV }}'",
|
||||
i, *label.Key, *label.Value))
|
||||
} else {
|
||||
match := regLocalEnv.FindStringSubmatch(*label.Value)
|
||||
value := os.Getenv(match[1])
|
||||
if err := utils.ValidateLabelValue(value); err != nil {
|
||||
errors = append(errors, fmt.Sprintf("label entry #%d with key '%s' has invalid value when the environment is evaluated: '%s': %s", i, *label.Key, value, err.Error()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
329
config_test.go
329
config_test.go
|
@ -180,13 +180,13 @@ func Test_validateEnvs(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
envs Pairs
|
||||
envs Envs
|
||||
errs int
|
||||
}{
|
||||
{
|
||||
"correct entry - single env with value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &value,
|
||||
},
|
||||
|
@ -195,8 +195,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - missing value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
},
|
||||
},
|
||||
|
@ -204,8 +204,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - invalid name",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &incorrectName,
|
||||
Value: &value,
|
||||
},
|
||||
|
@ -214,8 +214,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - invalid name2",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &incorrectName2,
|
||||
Value: &value,
|
||||
},
|
||||
|
@ -224,12 +224,12 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple envs with value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &value,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name2,
|
||||
Value: &value2,
|
||||
},
|
||||
|
@ -238,11 +238,11 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - mmissing value - multiple envs",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name2,
|
||||
},
|
||||
},
|
||||
|
@ -250,8 +250,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - single env with value Local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
|
@ -260,16 +260,16 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple envs with value Local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv3,
|
||||
},
|
||||
|
@ -278,20 +278,20 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - multiple envs with value Local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnvIncorrect,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnvIncorrect2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnvIncorrect3,
|
||||
},
|
||||
|
@ -300,8 +300,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - single secret with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey,
|
||||
},
|
||||
|
@ -310,8 +310,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - single configMap with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueConfigMapKey,
|
||||
},
|
||||
|
@ -320,16 +320,16 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple secrets with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey3,
|
||||
},
|
||||
|
@ -338,12 +338,12 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - both secret and configmap with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueConfigMapKey,
|
||||
},
|
||||
|
@ -352,8 +352,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - single secret with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKeyIncorrect,
|
||||
},
|
||||
|
@ -362,20 +362,20 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - mutliple secrets with key",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKeyIncorrect,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKeyIncorrect2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKeyIncorrect3,
|
||||
},
|
||||
|
@ -384,8 +384,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - single whole secret",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &valueSecret,
|
||||
},
|
||||
},
|
||||
|
@ -393,8 +393,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - single whole configMap",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &valueConfigMap,
|
||||
},
|
||||
},
|
||||
|
@ -402,14 +402,14 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple whole secret",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &valueSecret,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret3,
|
||||
},
|
||||
},
|
||||
|
@ -417,11 +417,11 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - both whole secret and configMap",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &valueSecret,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueConfigMap,
|
||||
},
|
||||
},
|
||||
|
@ -429,8 +429,8 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - single whole secret",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &value,
|
||||
},
|
||||
},
|
||||
|
@ -438,29 +438,29 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - multiple whole secret",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Value: &valueSecretIncorrect,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecretIncorrect2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecretIncorrect3,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &value,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueLocalEnv2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueLocalEnv3,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret,
|
||||
},
|
||||
},
|
||||
|
@ -468,52 +468,52 @@ func Test_validateEnvs(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - all combinations",
|
||||
Pairs{
|
||||
Pair{
|
||||
Envs{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &value,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name2,
|
||||
Value: &value2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueLocalEnv3,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueSecret3,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Value: &valueConfigMap,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey2,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueSecretKey3,
|
||||
},
|
||||
Pair{
|
||||
Env{
|
||||
Name: &name,
|
||||
Value: &valueConfigMapKey,
|
||||
},
|
||||
|
@ -534,15 +534,15 @@ func Test_validateEnvs(t *testing.T) {
|
|||
|
||||
func Test_validateLabels(t *testing.T) {
|
||||
|
||||
name := "name"
|
||||
name2 := "name-two"
|
||||
name3 := "prefix.io/name3"
|
||||
key := "name"
|
||||
key2 := "name-two"
|
||||
key3 := "prefix.io/name3"
|
||||
value := "value"
|
||||
value2 := "value2"
|
||||
value3 := "value3"
|
||||
|
||||
incorrectName := ",foo"
|
||||
incorrectName2 := ":foo"
|
||||
incorrectKey := ",foo"
|
||||
incorrectKey2 := ":foo"
|
||||
incorrectValue := ":foo"
|
||||
|
||||
valueLocalEnv := "{{ env:MY_ENV }}"
|
||||
|
@ -559,15 +559,15 @@ func Test_validateLabels(t *testing.T) {
|
|||
valueLocalEnv4 := "{{env:GOOD_EXAMPLE}}"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
labels Pairs
|
||||
key string
|
||||
labels Labels
|
||||
errs int
|
||||
}{
|
||||
{
|
||||
"correct entry - single label with value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &value,
|
||||
},
|
||||
},
|
||||
|
@ -575,37 +575,48 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - prefixed label with value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name3,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key3,
|
||||
Value: &value3,
|
||||
},
|
||||
},
|
||||
0,
|
||||
}, {
|
||||
"incorrect entry - missing value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
"incorrect entry - missing key",
|
||||
Labels{
|
||||
Label{
|
||||
Value: &value,
|
||||
},
|
||||
},
|
||||
1,
|
||||
},{
|
||||
"incorrect entry - missing multiple keys",
|
||||
Labels{
|
||||
Label{
|
||||
Value: &value,
|
||||
},
|
||||
Label{
|
||||
Value: &value2,
|
||||
},
|
||||
},
|
||||
2,
|
||||
},
|
||||
{
|
||||
"incorrect entry - invalid name",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &incorrectName,
|
||||
"incorrect entry - invalid key",
|
||||
Labels{
|
||||
Label{
|
||||
Key: &incorrectKey,
|
||||
Value: &value,
|
||||
},
|
||||
},
|
||||
1,
|
||||
},
|
||||
{
|
||||
"incorrect entry - invalid name2",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &incorrectName2,
|
||||
"incorrect entry - invalid key2",
|
||||
Labels{
|
||||
Label{
|
||||
Key: &incorrectKey2,
|
||||
Value: &value,
|
||||
},
|
||||
},
|
||||
|
@ -613,9 +624,9 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - invalid value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &incorrectValue,
|
||||
},
|
||||
},
|
||||
|
@ -623,35 +634,35 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple labels with value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &value,
|
||||
},
|
||||
Pair{
|
||||
Name: &name2,
|
||||
Label{
|
||||
Key: &key2,
|
||||
Value: &value2,
|
||||
},
|
||||
},
|
||||
0,
|
||||
},
|
||||
{
|
||||
"incorrect entry - missing value - multiple labels",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
"correct entry - missing value - multiple labels",
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
},
|
||||
Pair{
|
||||
Name: &name2,
|
||||
Label{
|
||||
Key: &key2,
|
||||
},
|
||||
},
|
||||
2,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"correct entry - single label with value from local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
},
|
||||
|
@ -659,17 +670,17 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - multiple labels with values from Local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv2,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv3,
|
||||
},
|
||||
},
|
||||
|
@ -677,21 +688,21 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"incorrect entry - multiple labels with values from Local env",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnvIncorrect,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnvIncorrect2,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnvIncorrect3,
|
||||
},
|
||||
},
|
||||
|
@ -699,18 +710,18 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - good environment variable value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv4,
|
||||
},
|
||||
},
|
||||
0,
|
||||
}, {
|
||||
"incorrect entry - bad environment variable value",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnvIncorrect4,
|
||||
},
|
||||
},
|
||||
|
@ -718,29 +729,29 @@ func Test_validateLabels(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"correct entry - all combinations",
|
||||
Pairs{
|
||||
Pair{
|
||||
Name: &name,
|
||||
Labels{
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &value,
|
||||
},
|
||||
Pair{
|
||||
Name: &name2,
|
||||
Label{
|
||||
Key: &key2,
|
||||
Value: &value2,
|
||||
},
|
||||
Pair{
|
||||
Name: &name3,
|
||||
Label{
|
||||
Key: &key3,
|
||||
Value: &value3,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv2,
|
||||
},
|
||||
Pair{
|
||||
Name: &name,
|
||||
Label{
|
||||
Key: &key,
|
||||
Value: &valueLocalEnv3,
|
||||
},
|
||||
},
|
||||
|
@ -749,7 +760,7 @@ func Test_validateLabels(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Run(tt.key, func(t *testing.T) {
|
||||
if got := ValidateLabels(tt.labels); len(got) != tt.errs {
|
||||
t.Errorf("validateLabels() = %v\n got %d errors but want %d", got, len(got), tt.errs)
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ directly from a value or from a local environment value. Eg. `'{{ env:USER }}'`,
|
|||
|
||||
```yaml
|
||||
labels:
|
||||
- name: role # (1) label directly from a value
|
||||
- key: role # (1) label directly from a value
|
||||
value: backend
|
||||
- name: author # (2) label from a local environment value
|
||||
- key: author # (2) label from a local environment value
|
||||
value: '{{ env:USER }}'
|
||||
```
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ type Function struct {
|
|||
Volumes Volumes
|
||||
|
||||
// Env variables to be set
|
||||
Envs Pairs
|
||||
Envs Envs
|
||||
|
||||
// Map containing user-supplied annotations
|
||||
// Example: { "division": "finance" }
|
||||
|
@ -66,7 +66,7 @@ type Function struct {
|
|||
Options Options
|
||||
|
||||
// Map of user-supplied labels
|
||||
Labels Pairs
|
||||
Labels Labels
|
||||
}
|
||||
|
||||
// NewFunction loads a Function from a path on disk. use .Initialized() to determine if
|
||||
|
|
|
@ -250,9 +250,9 @@ func updateService(f fn.Function, newEnv []corev1.EnvVar, newEnvFrom []corev1.En
|
|||
|
||||
// processLabels generates a map of labels as key/value pairs from a function config
|
||||
// labels:
|
||||
// - name: EXAMPLE1 # Label directly from a value
|
||||
// - key: EXAMPLE1 # Label directly from a value
|
||||
// value: value1
|
||||
// - name: EXAMPLE2 # Label from the local ENV var
|
||||
// - key: EXAMPLE2 # Label from the local ENV var
|
||||
// value: {{ env:MY_ENV }}
|
||||
func processLabels(f fn.Function) (map[string]string, error) {
|
||||
labels := map[string]string{
|
||||
|
@ -260,7 +260,7 @@ func processLabels(f fn.Function) (map[string]string, error) {
|
|||
"boson.dev/runtime": f.Runtime,
|
||||
}
|
||||
for _, label := range f.Labels {
|
||||
if label.Name != nil && label.Value != nil {
|
||||
if label.Key != nil && label.Value != nil {
|
||||
if strings.HasPrefix(*label.Value, "{{") {
|
||||
slices := strings.Split(strings.Trim(*label.Value, "{} "), ":")
|
||||
if len(slices) == 2 {
|
||||
|
@ -269,14 +269,16 @@ func processLabels(f fn.Function) (map[string]string, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
labels[*label.Name] = localValue
|
||||
labels[*label.Key] = localValue
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
// a standard label with key and value, eg. author=alice@example.com
|
||||
labels[*label.Name] = *label.Value
|
||||
labels[*label.Key] = *label.Value
|
||||
continue
|
||||
}
|
||||
} else if label.Key != nil && label.Value == nil {
|
||||
labels[*label.Key] = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,7 +297,7 @@ func processLabels(f fn.Function) (map[string]string, error) {
|
|||
// - name: EXAMPLE4
|
||||
// value: {{ configMap:configMapName:key }} # ENV from a key in ConfigMap
|
||||
// - value: {{ configMap:configMapName }} # all key-pair values from ConfigMap are set as ENV
|
||||
func processEnvs(envs fn.Pairs, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.EnvVar, []corev1.EnvFromSource, error) {
|
||||
func processEnvs(envs fn.Envs, referencedSecrets, referencedConfigMaps *sets.String) ([]corev1.EnvVar, []corev1.EnvFromSource, error) {
|
||||
|
||||
envVars := []corev1.EnvVar{{Name: "BUILT", Value: time.Now().Format("20060102T150405")}}
|
||||
envFrom := []corev1.EnvFromSource{}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
"envs": {
|
||||
"items": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Pair"
|
||||
"$ref": "#/definitions/Env"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
|
@ -73,7 +73,8 @@
|
|||
},
|
||||
"labels": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/Pair"
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Label"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
|
@ -81,6 +82,39 @@
|
|||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Env": {
|
||||
"required": [
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"pattern": "^[-._a-zA-Z][-._a-zA-Z0-9]*$",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Label": {
|
||||
"required": [
|
||||
"key"
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\\/)?([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"pattern": "^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Options": {
|
||||
"properties": {
|
||||
"scale": {
|
||||
|
@ -95,21 +129,6 @@
|
|||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Pair": {
|
||||
"required": [
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"ResourcesLimitsOptions": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
|
|
|
@ -44,15 +44,15 @@ func ValidateEnvVarName(name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ValidateLabelName validates that the input name is a valid Kubernetes key.
|
||||
// ValidateLabelKey validates that the input name is a valid Kubernetes key.
|
||||
// Valid label names have two segments: an optional prefix and name, separated by a slash (/).
|
||||
// The name segment is required and must be 63 characters or less, beginning and ending with
|
||||
// an alphanumeric character ([a-z0-9A-Z]) with dashes (-), underscores (_), dots (.), and
|
||||
// alphanumerics between. The prefix is optional. If specified, the prefix must be a DNS subdomain:
|
||||
// a series of DNS labels separated by dots (.), not longer than 253 characters in total, followed
|
||||
// by a slash (/).
|
||||
func ValidateLabelName(name string) error {
|
||||
errs := validation.IsQualifiedName(name)
|
||||
func ValidateLabelKey(key string) error {
|
||||
errs := validation.IsQualifiedName(key)
|
||||
if len(errs) > 0 {
|
||||
return ErrInvalidLabel(errors.New(strings.Join(errs, "")))
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ func TestValidateLabelName(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
err := ValidateLabelName(c.In)
|
||||
err := ValidateLabelKey(c.In)
|
||||
if err != nil && c.Valid {
|
||||
t.Fatalf("Unexpected error: %v, for '%v'", err, c.In)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue