added validation of application names to prevent conflicts at a later
stage with genrated resource names. The Server resource names will use the -pNNNN suffix to indicates a linkerd Server resource for port NNNN
This commit is contained in:
		
							parent
							
								
									60ebbf0ef4
								
							
						
					
					
						commit
						c9022a8036
					
				| @ -4,7 +4,7 @@ import ( | |||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/goccy/go-yaml" | 	yaml "github.com/goccy/go-yaml" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"net" | 	"net" | ||||||
| 	"os" | 	"os" | ||||||
| @ -49,7 +49,7 @@ type Port struct { | |||||||
| 
 | 
 | ||||||
| // Network represents each network entry in the YAML
 | // Network represents each network entry in the YAML
 | ||||||
| type Network struct { | type Network struct { | ||||||
| 	Name   string `yaml:"name" validate:"required"` | 	Name   string `yaml:"name" validate:"required,applicationName"` | ||||||
| 	CIDR   CIDR   `yaml:"cidr"` | 	CIDR   CIDR   `yaml:"cidr"` | ||||||
| 	Except []CIDR `yaml:"except,omitempty" validate:"dive,required"` | 	Except []CIDR `yaml:"except,omitempty" validate:"dive,required"` | ||||||
| 	Ports  []Port `yaml:"ports,omitempty"  validate:"dive,required"` | 	Ports  []Port `yaml:"ports,omitempty"  validate:"dive,required"` | ||||||
| @ -62,7 +62,7 @@ type MatchExpression struct { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Application struct { | type Application struct { | ||||||
| 	Name        string            `yaml:"name"` | 	Name        string            `yaml:"name" validate:"required,applicationName"` | ||||||
| 	Ports       []Port            `yaml:"ports,omitempty"` | 	Ports       []Port            `yaml:"ports,omitempty"` | ||||||
| 	MatchLabels map[string]string `yaml:"matchLabels"` | 	MatchLabels map[string]string `yaml:"matchLabels"` | ||||||
| 	//MatchExpressions []MatchExpression `yaml:"matchExpressions" validate:"omitempty,dive"`
 | 	//MatchExpressions []MatchExpression `yaml:"matchExpressions" validate:"omitempty,dive"`
 | ||||||
| @ -79,8 +79,11 @@ func (a Application) Selector() *metav1.LabelSelector { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Namespace struct { | type Namespace struct { | ||||||
| 	Name         string         `yaml:"name"` | 	Name string `yaml:"name"` | ||||||
| 	Open         bool           `yaml:"open"` | 	// Open closed for network policies
 | ||||||
|  | 	Open bool `yaml:"open"` | ||||||
|  | 	// service mesh, authorized True or not (allow anything)
 | ||||||
|  | 	Authorized   bool           `yaml:"authorized"` | ||||||
| 	Capabilities []string       `yaml:"capabilities"` | 	Capabilities []string       `yaml:"capabilities"` | ||||||
| 	Applications []*Application `yaml:"applications" validate:"dive,required"` | 	Applications []*Application `yaml:"applications" validate:"dive,required"` | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,8 +4,9 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/go-playground/locales/en" | 	"github.com/go-playground/locales/en" | ||||||
| 	ut "github.com/go-playground/universal-translator" | 	ut "github.com/go-playground/universal-translator" | ||||||
| 	"github.com/go-playground/validator/v10" | 	validator "github.com/go-playground/validator/v10" | ||||||
| 	en_translations "github.com/go-playground/validator/v10/translations/en" | 	en_translations "github.com/go-playground/validator/v10/translations/en" | ||||||
|  | 	"regexp" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Validator struct { | type Validator struct { | ||||||
| @ -30,6 +31,12 @@ var translations = map[string]Translation{ | |||||||
| 			return []any{fe.Namespace(), fe.Param(), fe.Value()} | 			return []any{fe.Namespace(), fe.Param(), fe.Value()} | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
|  | 	"applicationName": { | ||||||
|  | 		"{0} must not end with -p[0-9]+$ to prevent conflicts with generated resource names", | ||||||
|  | 		func(fe validator.FieldError) []any { | ||||||
|  | 			return []any{fe.Namespace()} | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type TranslatedFieldError struct { | type TranslatedFieldError struct { | ||||||
| @ -48,8 +55,21 @@ func (e TranslatedFieldError) Error() string { | |||||||
| 	return e.msg | 	return e.msg | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func applicationNameValidator(fl validator.FieldLevel) bool { | ||||||
|  | 	// Get the field's value as string
 | ||||||
|  | 	value := fl.Field().String() | ||||||
|  | 	regexString := "-p[0-9]+$" | ||||||
|  | 	regex, err := regexp.Compile(regexString) | ||||||
|  | 	if err != nil { | ||||||
|  | 		// programming error
 | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return !regex.MatchString(value) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func NewValidator() (*Validator, error) { | func NewValidator() (*Validator, error) { | ||||||
| 	validate := validator.New(validator.WithRequiredStructEnabled()) | 	validate := validator.New(validator.WithRequiredStructEnabled()) | ||||||
|  | 	validate.RegisterValidation("applicationName", applicationNameValidator) | ||||||
| 	language := en.New() | 	language := en.New() | ||||||
| 	translator := ut.New(language, language) | 	translator := ut.New(language, language) | ||||||
| 	trans, ok := translator.GetTranslator("en") | 	trans, ok := translator.GetTranslator("en") | ||||||
|  | |||||||
| @ -16,6 +16,9 @@ namespaces: | |||||||
|   - name: openns |   - name: openns | ||||||
|     open: true |     open: true | ||||||
|     applications: |     applications: | ||||||
|  |       - name: myapp | ||||||
|  |         matchLabels: | ||||||
|  |           app: myapp | ||||||
|       - name: openapp |       - name: openapp | ||||||
|         ports: |         ports: | ||||||
|           - port: 100 |           - port: 100 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user