
After review, there are cases where having common requirements for namespaces and identifiers creates contention between applications. One example is that it is nice to have namespaces comply with domain name requirement, but that does not allow underscores, which are required for certain identifiers. The namespaces validation has been reverted to be in line with RFC 1035. Existing identifiers has been modified to allow simply alpha-numeric identifiers, while limiting adjacent separators. We may follow up tweaks for the identifier charset but this split should remove the hard decisions. Signed-off-by: Stephen J Day <stephen.day@docker.com>
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
// Package identifiers provides common validation for identifiers and keys
|
|
// across containerd.
|
|
//
|
|
// Identifiers in containerd must be a alphanumeric, allowing limited
|
|
// underscores, dashes and dots.
|
|
//
|
|
// While the character set may be expanded in the future, identifiers
|
|
// are guaranteed to be safely used as filesystem path components.
|
|
package identifiers
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"github.com/containerd/containerd/errdefs"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const (
|
|
maxLength = 76
|
|
alphanum = `[A-Za-z0-9]+`
|
|
separators = `[._-]`
|
|
)
|
|
|
|
var (
|
|
// identifierRe defines the pattern for valid identifiers.
|
|
identifierRe = regexp.MustCompile(reAnchor(alphanum + reGroup(separators+reGroup(alphanum)) + "*"))
|
|
)
|
|
|
|
// Validate return nil if the string s is a valid identifier.
|
|
//
|
|
// identifiers must be valid domain names according to RFC 1035, section 2.3.1. To
|
|
// enforce case insensitvity, all characters must be lower case.
|
|
//
|
|
// In general, identifiers that pass this validation, should be safe for use as
|
|
// a domain names or filesystem path component.
|
|
func Validate(s string) error {
|
|
if len(s) == 0 {
|
|
return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier must not be empty")
|
|
}
|
|
|
|
if len(s) > maxLength {
|
|
return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier %q greater than maximum length (%d characters)", s, maxLength)
|
|
}
|
|
|
|
if !identifierRe.MatchString(s) {
|
|
return errors.Wrapf(errdefs.ErrInvalidArgument, "identifier %q must match %v", s, identifierRe)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func reGroup(s string) string {
|
|
return `(?:` + s + `)`
|
|
}
|
|
|
|
func reAnchor(s string) string {
|
|
return `^` + s + `$`
|
|
}
|