Add more validation methods 14/103914/2
authorEric Multanen <eric.w.multanen@intel.com>
Thu, 19 Mar 2020 00:33:27 +0000 (17:33 -0700)
committerEric Multanen <eric.w.multanen@intel.com>
Thu, 19 Mar 2020 17:46:24 +0000 (10:46 -0700)
Add more validation methods and move to package
orchestration/infra/validation

Issue-ID: MULTICLOUD-1029
Signed-off-by: Eric Multanen <eric.w.multanen@intel.com>
Change-Id: Id37bbb73fff9ab115ec49c88cdd3e08ee6be3098

src/orchestrator/api/app_profilehandler.go
src/orchestrator/api/apphandler.go
src/orchestrator/pkg/infra/validation/validation.go [new file with mode: 0644]
src/orchestrator/pkg/infra/validation/validation_test.go [new file with mode: 0644]
src/orchestrator/utils/utils.go [deleted file]
src/orchestrator/utils/utils_test.go [deleted file]

index 1642348..ef7833d 100644 (file)
@@ -27,8 +27,8 @@ import (
        "net/http"
        "net/textproto"
 
+       "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
        moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
-       "github.com/onap/multicloud-k8s/src/orchestrator/utils"
 
        "github.com/gorilla/mux"
        pkgerrors "github.com/pkg/errors"
@@ -89,7 +89,7 @@ func (h appProfileHandler) createAppProfileHandler(w http.ResponseWriter, r *htt
                return
        }
 
-       err = utils.IsTarGz(bytes.NewBuffer(content))
+       err = validation.IsTarGz(bytes.NewBuffer(content))
        if err != nil {
                http.Error(w, "Error in file format", http.StatusUnprocessableEntity)
                return
index 06341e7..2c81431 100644 (file)
@@ -27,8 +27,8 @@ import (
        "net/http"
        "net/textproto"
 
+       "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/validation"
        moduleLib "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module"
-       "github.com/onap/multicloud-k8s/src/orchestrator/utils"
 
        "github.com/gorilla/mux"
 )
@@ -92,7 +92,7 @@ func (h appHandler) createAppHandler(w http.ResponseWriter, r *http.Request) {
                return
        }
 
-       err = utils.IsTarGz(bytes.NewBuffer(content))
+       err = validation.IsTarGz(bytes.NewBuffer(content))
        if err != nil {
                http.Error(w, "Error in file format", http.StatusUnprocessableEntity)
                return
diff --git a/src/orchestrator/pkg/infra/validation/validation.go b/src/orchestrator/pkg/infra/validation/validation.go
new file mode 100644 (file)
index 0000000..d744dc3
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2020 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package validation
+
+import (
+       "archive/tar"
+       "compress/gzip"
+       "io"
+       "net"
+       "regexp"
+       "strings"
+
+       pkgerrors "github.com/pkg/errors"
+       "k8s.io/apimachinery/pkg/util/validation"
+)
+
+func IsTarGz(r io.Reader) error {
+       //Check if it is a valid gz
+       gzf, err := gzip.NewReader(r)
+       if err != nil {
+               return pkgerrors.Wrap(err, "Invalid gzip format")
+       }
+
+       //Check if it is a valid tar file
+       //Unfortunately this can only be done by inspecting all the tar contents
+       tarR := tar.NewReader(gzf)
+       first := true
+
+       for true {
+               header, err := tarR.Next()
+
+               if err == io.EOF {
+                       //Check if we have just a gzip file without a tar archive inside
+                       if first {
+                               return pkgerrors.New("Empty or non-existant Tar file found")
+                       }
+                       //End of archive
+                       break
+               }
+
+               if err != nil {
+                       return pkgerrors.Errorf("Error reading tar file %s", err.Error())
+               }
+
+               //Check if files are of type directory and regular file
+               if header.Typeflag != tar.TypeDir &&
+                       header.Typeflag != tar.TypeReg {
+                       return pkgerrors.Errorf("Unknown header in tar %s, %s",
+                               header.Name, string(header.Typeflag))
+               }
+
+               first = false
+       }
+
+       return nil
+}
+
+func IsIpv4Cidr(cidr string) error {
+       _, _, err := net.ParseCIDR(cidr)
+       if err != nil {
+               return pkgerrors.Wrapf(err, "could not parse subnet %v", cidr)
+       }
+       return nil
+}
+
+func IsIpv4(ip string) error {
+       addr := net.ParseIP(ip)
+       if addr == nil {
+               return pkgerrors.Errorf("invalid ipv4 address %v", ip)
+       }
+       return nil
+}
+
+// default name check - matches valid label value with addtion that length > 0
+func IsValidName(name string) []string {
+       var errs []string
+
+       errs = validation.IsValidLabelValue(name)
+       if len(name) == 0 {
+               errs = append(errs, "name must have non-zero length")
+       }
+       return errs
+}
+
+const VALID_NAME_STR string = "NAME"
+
+var validNameRegEx = regexp.MustCompile("^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$")
+
+const VALID_ALPHA_STR string = "ALPHA"
+
+var validAlphaStrRegEx = regexp.MustCompile("^[A-Za-z]*$")
+
+const VALID_ALPHANUM_STR string = "ALPHANUM"
+
+var validAlphaNumStrRegEx = regexp.MustCompile("^[A-Za-z0-9]*$")
+
+// doesn't verify valid base64 length - just checks for proper base64 characters
+const VALID_BASE64_STR string = "BASE64"
+
+var validBase64StrRegEx = regexp.MustCompile("^[A-Za-z0-9+/]+={0,2}$")
+
+const VALID_ANY_STR string = "ANY"
+
+var validAnyStrRegEx = regexp.MustCompile("(?s)^.*$")
+
+// string check - validates for conformance to provided lengths and specified content
+// min and max - the string
+// if format string provided - check against matching predefined
+func IsValidString(str string, min, max int, format string) []string {
+       var errs []string
+
+       if min > max {
+               errs = append(errs, "Invalid string length constraints - min is greater than max")
+               return errs
+       }
+
+       if len(str) < min {
+               errs = append(errs, "string length is less than the minimum constraint")
+               return errs
+       }
+       if len(str) > max {
+               errs = append(errs, "string length is greater than the maximum constraint")
+               return errs
+       }
+
+       switch format {
+       case VALID_ALPHA_STR:
+               if !validAlphaStrRegEx.MatchString(str) {
+                       errs = append(errs, "string does not match the alpha only constraint")
+               }
+       case VALID_ALPHANUM_STR:
+               if !validAlphaNumStrRegEx.MatchString(str) {
+                       errs = append(errs, "string does not match the alphanumeric only constraint")
+               }
+       case VALID_NAME_STR:
+               if !validNameRegEx.MatchString(str) {
+                       errs = append(errs, "string does not match the valid k8s name constraint")
+               }
+       case VALID_BASE64_STR:
+               if !validBase64StrRegEx.MatchString(str) {
+                       errs = append(errs, "string does not match the valid base64 characters constraint")
+               }
+               if len(str)%4 != 0 {
+                       errs = append(errs, "base64 string length should be a multiple of 4")
+               }
+       case VALID_ANY_STR:
+               if !validAnyStrRegEx.MatchString(str) {
+                       errs = append(errs, "string does not match the any characters constraint")
+               }
+       default:
+               // invalid string format supplied
+               errs = append(errs, "an invalid string constraint was supplied")
+       }
+
+       return errs
+}
+
+// validate that label conforms to kubernetes label conventions
+//  general label format expected is:
+//  "<labelprefix>/<labelname>=<Labelvalue>"
+//  where labelprefix matches DNS1123Subdomain format
+//        labelname matches DNS1123Label format
+//
+// Input labels are allowed to  match following formats:
+//  "<DNS1123Subdomain>/<DNS1123Label>=<Labelvalue>"
+//  "<DNS1123Label>=<LabelValue>"
+//  "<LabelValue>"
+func IsValidLabel(label string) []string {
+       var labelerrs []string
+
+       expectLabelName := false
+       expectLabelPrefix := false
+
+       // split label up into prefix, name and value
+       // format:  prefix/name=value
+       var labelprefix, labelname, labelvalue string
+
+       kv := strings.SplitN(label, "=", 2)
+       if len(kv) == 1 {
+               labelprefix = ""
+               labelname = ""
+               labelvalue = kv[0]
+       } else {
+               pn := strings.SplitN(kv[0], "/", 2)
+               if len(pn) == 1 {
+                       labelprefix = ""
+                       labelname = pn[0]
+               } else {
+                       labelprefix = pn[0]
+                       labelname = pn[1]
+                       expectLabelPrefix = true
+               }
+               labelvalue = kv[1]
+               // if "=" was in the label input, then expect a non-zero length name
+               expectLabelName = true
+       }
+
+       // check label prefix validity - prefix is optional
+       if len(labelprefix) > 0 {
+               errs := validation.IsDNS1123Subdomain(labelprefix)
+               if len(errs) > 0 {
+                       labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"], errors: ")
+                       for _, err := range errs {
+                               labelerrs = append(labelerrs, err)
+                       }
+               }
+       } else if expectLabelPrefix {
+               labelerrs = append(labelerrs, "Invalid label prefix - label=["+label+"%], labelprefix=["+labelprefix+"]")
+       }
+       if expectLabelName {
+               errs := validation.IsDNS1123Label(labelname)
+               if len(errs) > 0 {
+                       labelerrs = append(labelerrs, "Invalid label name - label=["+label+"%], labelname=["+labelname+"], errors: ")
+                       for _, err := range errs {
+                               labelerrs = append(labelerrs, err)
+                       }
+               }
+       }
+       if len(labelvalue) > 0 {
+               errs := validation.IsValidLabelValue(labelvalue)
+               if len(errs) > 0 {
+                       labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"], errors: ")
+                       for _, err := range errs {
+                               labelerrs = append(labelerrs, err)
+                       }
+               }
+       } else {
+               // expect a non-zero value
+               labelerrs = append(labelerrs, "Invalid label value - label=["+label+"%], labelvalue=["+labelvalue+"]")
+       }
+
+       return labelerrs
+}
+
+func IsValidNumber(value, min, max int) []string {
+       var errs []string
+
+       if min > max {
+               errs = append(errs, "invalid constraints")
+               return errs
+       }
+
+       if value < min {
+               errs = append(errs, "value less than minimum")
+       }
+       if value > max {
+               errs = append(errs, "value greater than maximum")
+       }
+       return errs
+}
diff --git a/src/orchestrator/pkg/infra/validation/validation_test.go b/src/orchestrator/pkg/infra/validation/validation_test.go
new file mode 100644 (file)
index 0000000..5109b6c
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2018 Intel Corporation, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package validation
+
+import (
+       "bytes"
+       "testing"
+)
+
+func TestIsTarGz(t *testing.T) {
+
+       t.Run("Valid tar.gz", func(t *testing.T) {
+               content := []byte{
+                       0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
+                       0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
+                       0x61, 0x72, 0x00, 0xed, 0xce, 0x41, 0x0a, 0xc2,
+                       0x30, 0x10, 0x85, 0xe1, 0xac, 0x3d, 0x45, 0x4e,
+                       0x50, 0x12, 0xd2, 0xc4, 0xe3, 0x48, 0xa0, 0x01,
+                       0x4b, 0x52, 0x0b, 0xed, 0x88, 0x1e, 0xdf, 0x48,
+                       0x11, 0x5c, 0x08, 0xa5, 0x8b, 0x52, 0x84, 0xff,
+                       0xdb, 0xbc, 0x61, 0x66, 0x16, 0x4f, 0xd2, 0x2c,
+                       0x8d, 0x3c, 0x45, 0xed, 0xc8, 0x54, 0x21, 0xb4,
+                       0xef, 0xb4, 0x67, 0x6f, 0xbe, 0x73, 0x61, 0x9d,
+                       0xb2, 0xce, 0xd5, 0x55, 0xf0, 0xde, 0xd7, 0x3f,
+                       0xdb, 0xd6, 0x49, 0x69, 0xb3, 0x67, 0xa9, 0x8f,
+                       0xfb, 0x2c, 0x71, 0xd2, 0x5a, 0xc5, 0xee, 0x92,
+                       0x73, 0x8e, 0x43, 0x7f, 0x4b, 0x3f, 0xff, 0xd6,
+                       0xee, 0x7f, 0xea, 0x9a, 0x4a, 0x19, 0x1f, 0xe3,
+                       0x54, 0xba, 0xd3, 0xd1, 0x55, 0x00, 0x00, 0x00,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0x00, 0x00, 0x1b, 0xbc, 0x00, 0xb5, 0xe8,
+                       0x4a, 0xf9, 0x00, 0x28, 0x00, 0x00,
+               }
+
+               err := IsTarGz(bytes.NewBuffer(content))
+               if err != nil {
+                       t.Errorf("Error reading valid tar.gz file %s", err.Error())
+               }
+       })
+
+       t.Run("Invalid tar.gz", func(t *testing.T) {
+               content := []byte{
+                       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0x00, 0xff, 0xf2, 0x48, 0xcd,
+               }
+
+               err := IsTarGz(bytes.NewBuffer(content))
+               if err == nil {
+                       t.Errorf("Error should NOT be nil")
+               }
+       })
+
+       t.Run("Empty tar.gz", func(t *testing.T) {
+               content := []byte{}
+               err := IsTarGz(bytes.NewBuffer(content))
+               if err == nil {
+                       t.Errorf("Error should NOT be nil")
+               }
+       })
+}
+
+func TestIsValidName(t *testing.T) {
+       t.Run("Valid Names", func(t *testing.T) {
+               validnames := []string{
+                       "abc123",
+                       "1_abc123.ONE",
+                       "0abcABC_-.5",
+                       "123456789012345678901234567890123456789012345678901234567890123", // max of 63 characters
+               }
+               for _, name := range validnames {
+                       errs := IsValidName(name)
+                       if len(errs) > 0 {
+                               t.Errorf("Valid name failed to pass: %v", name)
+                       }
+               }
+       })
+
+       t.Run("Invalid Names", func(t *testing.T) {
+               invalidnames := []string{
+                       "",               // empty
+                       "_abc123",        // starts with non-alphanum
+                       "-abc123",        // starts with non-alphanum
+                       ".abc123",        // starts with non-alphanum
+                       "abc123-",        // ends with non-alphanum
+                       "abc123_",        // ends with non-alphanum
+                       "abc123.",        // ends with non-alphanum
+                       "1_abc-123.O=NE", // contains not allowed character
+                       "1_a/bc-123.ONE", // contains not allowed character
+                       "1234567890123456789012345678901234567890123456789012345678901234", // longer than 63 characters
+               }
+               for _, name := range invalidnames {
+                       errs := IsValidName(name)
+                       if len(errs) == 0 {
+                               t.Errorf("Invalid name passed: %v", name)
+                       }
+               }
+       })
+}
+
+func TestIsIpv4Cidr(t *testing.T) {
+       t.Run("Valid IPv4 Cidr", func(t *testing.T) {
+               validipv4cidr := []string{
+                       "1.2.3.4/32",
+                       "10.11.12.0/24",
+                       "192.168.1.2/8",
+                       "255.0.0.0/16",
+               }
+               for _, ip := range validipv4cidr {
+                       err := IsIpv4Cidr(ip)
+                       if err != nil {
+                               t.Errorf("Valid IPv4 CIDR string failed to pass: %v", ip)
+                       }
+               }
+       })
+
+       t.Run("Invalid IPv4 Cidr", func(t *testing.T) {
+               invalidipv4cidr := []string{
+                       "",
+                       "1.2.3.4.5/32",
+                       "1.2.3.415/16",
+                       "1.2.3.4/33",
+                       "2.3.4/24",
+                       "1.2.3.4",
+                       "1.2.3.4/",
+               }
+               for _, ip := range invalidipv4cidr {
+                       err := IsIpv4Cidr(ip)
+                       if err == nil {
+                               t.Errorf("Invalid IPv4 Cidr passed: %v", ip)
+                       }
+               }
+       })
+}
+
+func TestIsIpv4(t *testing.T) {
+       t.Run("Valid IPv4", func(t *testing.T) {
+               validipv4 := []string{
+                       "1.2.3.42",
+                       "10.11.12.0",
+                       "192.168.1.2",
+                       "255.0.0.0",
+                       "255.255.255.255",
+                       "0.0.0.0",
+               }
+               for _, ip := range validipv4 {
+                       err := IsIpv4(ip)
+                       if err != nil {
+                               t.Errorf("Valid IPv4 string failed to pass: %v", ip)
+                       }
+               }
+       })
+
+       t.Run("Invalid IPv4", func(t *testing.T) {
+               invalidipv4 := []string{
+                       "",
+                       "1.2.3.4.5",
+                       "1.2.3.45/32",
+                       "1.2.3.4a",
+                       "2.3.4",
+                       "1.2.3.400",
+                       "256.255.255.255",
+                       "10,11,12,13",
+                       "1.2.3.4/",
+               }
+               for _, ip := range invalidipv4 {
+                       err := IsIpv4(ip)
+                       if err == nil {
+                               t.Errorf("Invalid IPv4 passed: %v", ip)
+                       }
+               }
+       })
+}
+
+func TestIsValidString(t *testing.T) {
+       t.Run("Valid Strings", func(t *testing.T) {
+               validStrings := []struct {
+                       str    string
+                       min    int
+                       max    int
+                       format string
+               }{
+                       {
+                               str:    "abc123",
+                               min:    0,
+                               max:    16,
+                               format: VALID_NAME_STR,
+                       },
+                       {
+                               str:    "ab-c1_2.3",
+                               min:    0,
+                               max:    16,
+                               format: VALID_NAME_STR,
+                       },
+                       {
+                               str:    "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                               min:    0,
+                               max:    62,
+                               format: VALID_ALPHANUM_STR,
+                       },
+                       {
+                               str:    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                               min:    0,
+                               max:    52,
+                               format: VALID_ALPHA_STR,
+                       },
+                       {
+                               str:    "",
+                               min:    0,
+                               max:    52,
+                               format: VALID_ALPHA_STR,
+                       },
+                       {
+                               str:    "",
+                               min:    0,
+                               max:    52,
+                               format: VALID_ALPHANUM_STR,
+                       },
+                       {
+                               str:    "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg==",
+                               min:    0,
+                               max:    52,
+                               format: VALID_BASE64_STR,
+                       },
+                       {
+                               str:    "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",
+                               min:    0,
+                               max:    256,
+                               format: VALID_ANY_STR,
+                       },
+               }
+               for _, test := range validStrings {
+                       errs := IsValidString(test.str, test.min, test.max, test.format)
+                       if len(errs) > 0 {
+                               t.Errorf("Valid string failed to pass: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)
+                       }
+               }
+       })
+
+       t.Run("Invalid Strings", func(t *testing.T) {
+               inValidStrings := []struct {
+                       str    string
+                       min    int
+                       max    int
+                       format string
+               }{
+                       {
+                               str:    "abc123",
+                               min:    0,
+                               max:    5,
+                               format: VALID_NAME_STR,
+                       },
+                       {
+                               str:    "",
+                               min:    0,
+                               max:    5,
+                               format: VALID_NAME_STR,
+                       },
+                       {
+                               str:    "-ab-c1_2.3",
+                               min:    0,
+                               max:    16,
+                               format: VALID_NAME_STR,
+                       },
+                       {
+                               str:    "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=",
+                               min:    0,
+                               max:    100,
+                               format: VALID_ALPHANUM_STR,
+                       },
+                       {
+                               str:    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456",
+                               min:    0,
+                               max:    62,
+                               format: VALID_ALPHA_STR,
+                       },
+                       {
+                               str:    "",
+                               min:    1,
+                               max:    52,
+                               format: VALID_ALPHA_STR,
+                       },
+                       {
+                               str:    "abc123",
+                               min:    1,
+                               max:    3,
+                               format: VALID_ALPHA_STR,
+                       },
+                       {
+                               str:    "",
+                               min:    1,
+                               max:    52,
+                               format: VALID_ALPHANUM_STR,
+                       },
+                       {
+                               str:    "dGhpcyBpcyBhCnRlc3Qgc3RyaW5nCg===",
+                               min:    0,
+                               max:    52,
+                               format: VALID_BASE64_STR,
+                       },
+                       {
+                               str:    "dGhpcyBpcyBhCnRlc3=Qgc3RyaW5nCg==",
+                               min:    0,
+                               max:    52,
+                               format: VALID_BASE64_STR,
+                       },
+                       {
+                               str:    "dGhpcyBpcyBhCnRlc3#Qgc3RyaW5nCg==",
+                               min:    0,
+                               max:    52,
+                               format: VALID_BASE64_STR,
+                       },
+                       {
+                               str:    "\t\n \n0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+-=,.<>/?'\"\\[]{}\n",
+                               min:    0,
+                               max:    10,
+                               format: VALID_ANY_STR,
+                       },
+                       {
+                               str:    "abc123",
+                               min:    0,
+                               max:    10,
+                               format: "unknownformat",
+                       },
+               }
+               for _, test := range inValidStrings {
+                       errs := IsValidString(test.str, test.min, test.max, test.format)
+                       if len(errs) == 0 {
+                               t.Errorf("Invalid string passed: str:%v, min:%v, max:%v, format:%v", test.str, test.min, test.max, test.format)
+                       }
+               }
+       })
+}
+
+func TestIsValidLabel(t *testing.T) {
+       t.Run("Valid Labels", func(t *testing.T) {
+               validlabels := []string{
+                       "kubernetes.io/hostname=localhost",
+                       "hostname=localhost",
+                       "localhost",
+               }
+               for _, label := range validlabels {
+                       errs := IsValidLabel(label)
+                       if len(errs) > 0 {
+                               t.Errorf("Valid label failed to pass: %v %v", label, errs)
+                       }
+               }
+       })
+
+       t.Run("Invalid Labels", func(t *testing.T) {
+               invalidlabels := []string{
+                       "",
+                       "kubernetes$.io/hostname=localhost",
+                       "hostname==localhost",
+                       "=localhost",
+                       "/hostname=localhost",
+                       ".a.b/hostname=localhost",
+                       "kubernetes.io/hostname",
+                       "kubernetes.io/hostname=",
+                       "kubernetes.io/1234567890123456789012345678901234567890123456789012345678901234=localhost",         // too long name
+                       "kubernetes.io/hostname=localhost1234567890123456789012345678901234567890123456789012345678901234", // too long value
+                       "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234/hostname=localhost", // too long prefix
+               }
+               for _, label := range invalidlabels {
+                       errs := IsValidLabel(label)
+                       if len(errs) == 0 {
+                               t.Errorf("Invalid label passed: %v", label)
+                       }
+               }
+       })
+}
+
+func TestIsValidNumber(t *testing.T) {
+       t.Run("Valid Number", func(t *testing.T) {
+               validNumbers := []struct {
+                       value int
+                       min   int
+                       max   int
+               }{
+                       {
+                               value: 0,
+                               min:   0,
+                               max:   5,
+                       },
+                       {
+                               value: 1000,
+                               min:   0,
+                               max:   4095,
+                       },
+                       {
+                               value: 0,
+                               min:   0,
+                               max:   0,
+                       },
+                       {
+                               value: -100,
+                               min:   -200,
+                               max:   -99,
+                       },
+                       {
+                               value: 123,
+                               min:   123,
+                               max:   123,
+                       },
+               }
+               for _, test := range validNumbers {
+                       err := IsValidNumber(test.value, test.min, test.max)
+                       if len(err) > 0 {
+                               t.Errorf("Valid number failed to pass - value:%v, min:%v, max:%v", test.value, test.min, test.max)
+                       }
+               }
+       })
+
+       t.Run("Invalid Number", func(t *testing.T) {
+               inValidNumbers := []struct {
+                       value int
+                       min   int
+                       max   int
+               }{
+                       {
+                               value: 6,
+                               min:   0,
+                               max:   5,
+                       },
+                       {
+                               value: 4096,
+                               min:   0,
+                               max:   4095,
+                       },
+                       {
+                               value: 11,
+                               min:   10,
+                               max:   10,
+                       },
+                       {
+                               value: -100,
+                               min:   -99,
+                               max:   -200,
+                       },
+                       {
+                               value: 123,
+                               min:   223,
+                               max:   123,
+                       },
+               }
+               for _, test := range inValidNumbers {
+                       err := IsValidNumber(test.value, test.min, test.max)
+                       if len(err) == 0 {
+                               t.Errorf("Invalid number passed - value:%v, min:%v, max:%v", test.value, test.min, test.max)
+                       }
+               }
+       })
+}
diff --git a/src/orchestrator/utils/utils.go b/src/orchestrator/utils/utils.go
deleted file mode 100644 (file)
index 44cf512..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2020 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package utils
-
-import (
-       "archive/tar"
-       "compress/gzip"
-       "io"
-
-       pkgerrors "github.com/pkg/errors"
-)
-
-func IsTarGz(r io.Reader) error {
-       //Check if it is a valid gz
-       gzf, err := gzip.NewReader(r)
-       if err != nil {
-               return pkgerrors.Wrap(err, "Invalid gzip format")
-       }
-
-       //Check if it is a valid tar file
-       //Unfortunately this can only be done by inspecting all the tar contents
-       tarR := tar.NewReader(gzf)
-       first := true
-
-       for true {
-               header, err := tarR.Next()
-
-               if err == io.EOF {
-                       //Check if we have just a gzip file without a tar archive inside
-                       if first {
-                               return pkgerrors.New("Empty or non-existant Tar file found")
-                       }
-                       //End of archive
-                       break
-               }
-
-               if err != nil {
-                       return pkgerrors.Errorf("Error reading tar file %s", err.Error())
-               }
-
-               //Check if files are of type directory and regular file
-               if header.Typeflag != tar.TypeDir &&
-                       header.Typeflag != tar.TypeReg {
-                       return pkgerrors.Errorf("Unknown header in tar %s, %s",
-                               header.Name, string(header.Typeflag))
-               }
-
-               first = false
-       }
-
-       return nil
-}
diff --git a/src/orchestrator/utils/utils_test.go b/src/orchestrator/utils/utils_test.go
deleted file mode 100644 (file)
index 63230e4..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package utils
-
-import (
-       "bytes"
-       "testing"
-)
-
-func TestIsTarGz(t *testing.T) {
-
-       t.Run("Valid tar.gz", func(t *testing.T) {
-               content := []byte{
-                       0x1f, 0x8b, 0x08, 0x08, 0xb0, 0x6b, 0xf4, 0x5b,
-                       0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74,
-                       0x61, 0x72, 0x00, 0xed, 0xce, 0x41, 0x0a, 0xc2,
-                       0x30, 0x10, 0x85, 0xe1, 0xac, 0x3d, 0x45, 0x4e,
-                       0x50, 0x12, 0xd2, 0xc4, 0xe3, 0x48, 0xa0, 0x01,
-                       0x4b, 0x52, 0x0b, 0xed, 0x88, 0x1e, 0xdf, 0x48,
-                       0x11, 0x5c, 0x08, 0xa5, 0x8b, 0x52, 0x84, 0xff,
-                       0xdb, 0xbc, 0x61, 0x66, 0x16, 0x4f, 0xd2, 0x2c,
-                       0x8d, 0x3c, 0x45, 0xed, 0xc8, 0x54, 0x21, 0xb4,
-                       0xef, 0xb4, 0x67, 0x6f, 0xbe, 0x73, 0x61, 0x9d,
-                       0xb2, 0xce, 0xd5, 0x55, 0xf0, 0xde, 0xd7, 0x3f,
-                       0xdb, 0xd6, 0x49, 0x69, 0xb3, 0x67, 0xa9, 0x8f,
-                       0xfb, 0x2c, 0x71, 0xd2, 0x5a, 0xc5, 0xee, 0x92,
-                       0x73, 0x8e, 0x43, 0x7f, 0x4b, 0x3f, 0xff, 0xd6,
-                       0xee, 0x7f, 0xea, 0x9a, 0x4a, 0x19, 0x1f, 0xe3,
-                       0x54, 0xba, 0xd3, 0xd1, 0x55, 0x00, 0x00, 0x00,
-                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                       0x00, 0x00, 0x00, 0x1b, 0xbc, 0x00, 0xb5, 0xe8,
-                       0x4a, 0xf9, 0x00, 0x28, 0x00, 0x00,
-               }
-
-               err := IsTarGz(bytes.NewBuffer(content))
-               if err != nil {
-                       t.Errorf("Error reading valid tar.gz file %s", err.Error())
-               }
-       })
-
-       t.Run("Invalid tar.gz", func(t *testing.T) {
-               content := []byte{
-                       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-                       0x00, 0xff, 0xf2, 0x48, 0xcd,
-               }
-
-               err := IsTarGz(bytes.NewBuffer(content))
-               if err == nil {
-                       t.Errorf("Error should NOT be nil")
-               }
-       })
-
-       t.Run("Empty tar.gz", func(t *testing.T) {
-               content := []byte{}
-               err := IsTarGz(bytes.NewBuffer(content))
-               if err == nil {
-                       t.Errorf("Error should NOT be nil")
-               }
-       })
-}