Validates resource names before storing in inventory

This commit is contained in:
Sean Sullivan 2020-07-14 14:06:32 -07:00
parent 07e7070650
commit 2f6a1ef017
2 changed files with 59 additions and 3 deletions

View File

@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/cli-runtime/pkg/resource"
)
@ -45,10 +46,15 @@ func CreateObjMetadata(namespace string, name string, gk schema.GroupKind) (*Obj
// Namespace can be empty, but name cannot.
name = strings.TrimSpace(name)
if name == "" {
return nil, fmt.Errorf("empty name for inventory object")
return nil, fmt.Errorf("empty name for object")
}
// Manually validate name, since by the time k8s reports the error
// the invalid name has already been encoded into the inventory object.
if !validateNameChars(name) {
return nil, fmt.Errorf("invalid characters in object name: %s", name)
}
if gk.Empty() {
return nil, fmt.Errorf("empty GroupKind for inventory object")
return nil, fmt.Errorf("empty GroupKind for object")
}
return &ObjMetadata{
@ -58,6 +64,23 @@ func CreateObjMetadata(namespace string, name string, gk schema.GroupKind) (*Obj
}, nil
}
// validateNameChars returns false if the passed name string contains
// any invalid characters; true otherwise. The allowed characters for
// a Kubernetes resource name are:
//
// Most resource types require a name that can be used as a DNS label name
// as defined in RFC 1123. This means the name must:
//
// * contain no more than 253 characters
// * contain only lowercase alphanumeric characters, '-'
// * start with an alphanumeric character
// * end with an alphanumeric character
//
func validateNameChars(name string) bool {
errs := validation.IsDNS1123Subdomain(name)
return len(errs) == 0
}
// ParseObjMetadata takes a string, splits it into its five fields,
// and returns a pointer to an ObjMetadata struct storing the
// five fields. Example inventory string:

View File

@ -56,13 +56,46 @@ func TestCreateObjMetadata(t *testing.T) {
expected: "",
isError: true,
},
// Error with invalid name characters "_".
{
namespace: "test-namespace",
name: "test_name", // Invalid "_" character
gk: schema.GroupKind{
Group: "apps",
Kind: "ReplicaSet",
},
expected: "",
isError: true,
},
// Error name not starting with alphanumeric char
{
namespace: "test-namespace",
name: "-test",
gk: schema.GroupKind{
Group: "apps",
Kind: "ReplicaSet",
},
expected: "",
isError: true,
},
// Error name not ending with alphanumeric char
{
namespace: "test-namespace",
name: "test-",
gk: schema.GroupKind{
Group: "apps",
Kind: "ReplicaSet",
},
expected: "",
isError: true,
},
}
for _, test := range tests {
inv, err := CreateObjMetadata(test.namespace, test.name, test.gk)
if !test.isError {
if err != nil {
t.Errorf("Error creating inventory when it should have worked.")
t.Errorf("Error creating ObjMetadata when it should have worked.")
} else if test.expected != inv.String() {
t.Errorf("Expected inventory (%s) != created inventory(%s)\n", test.expected, inv.String())
}