mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Adding a 'Typename' strongtype for representing all compute resource types.
This commit is contained in:
		@@ -21,6 +21,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/davecgh/go-spew/spew"
 | 
						"github.com/davecgh/go-spew/spew"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -60,3 +61,9 @@ var Semantic = conversion.EqualitiesOrDie(
 | 
				
			|||||||
		return a.Amount.Cmp(b.Amount) == 0
 | 
							return a.Amount.Cmp(b.Amount) == 0
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var standardResources = util.NewStringSet(string(ResourceMemory), string(ResourceCPU))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsStandardResourceName(str string) bool {
 | 
				
			||||||
 | 
						return standardResources.Has(str)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,3 +67,21 @@ func TestSemantic(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestIsStandardResource(t *testing.T) {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							input  string
 | 
				
			||||||
 | 
							output bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"cpu", true},
 | 
				
			||||||
 | 
							{"memory", true},
 | 
				
			||||||
 | 
							{"disk", false},
 | 
				
			||||||
 | 
							{"blah", false},
 | 
				
			||||||
 | 
							{"x.y.z", false},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							if IsStandardResourceName(tc.input) != tc.output {
 | 
				
			||||||
 | 
								t.Errorf("case[%d], expected: %t, got: %t", i, tc.output, !tc.output)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -764,6 +764,8 @@ type NodeResources struct {
 | 
				
			|||||||
type ResourceName string
 | 
					type ResourceName string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
						// The default compute resource namespace for all standard resource types.
 | 
				
			||||||
 | 
						DefaultResourceNamespace = "kubernetes.io"
 | 
				
			||||||
	// CPU, in cores. (500m = .5 cores)
 | 
						// CPU, in cores. (500m = .5 cores)
 | 
				
			||||||
	ResourceCPU ResourceName = "cpu"
 | 
						ResourceCPU ResourceName = "cpu"
 | 
				
			||||||
	// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
 | 
						// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -785,6 +785,8 @@ type NodeCondition struct {
 | 
				
			|||||||
type ResourceName string
 | 
					type ResourceName string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
						// The default compute resource namespace for all standard resource types.
 | 
				
			||||||
 | 
						DefaultResourceNamespace = "kubernetes.io"
 | 
				
			||||||
	// CPU, in cores. (500m = .5 cores)
 | 
						// CPU, in cores. (500m = .5 cores)
 | 
				
			||||||
	ResourceCPU ResourceName = "cpu"
 | 
						ResourceCPU ResourceName = "cpu"
 | 
				
			||||||
	// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
 | 
						// Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -622,3 +622,30 @@ func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.Validation
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return allErrs
 | 
						return allErrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Typename is a generic representation for all compute resource typenames.
 | 
				
			||||||
 | 
					// Refer to docs/resources.md for more details.
 | 
				
			||||||
 | 
					func ValidateResourceName(str string) errs.ValidationErrorList {
 | 
				
			||||||
 | 
						if !util.IsQualifiedName(str) {
 | 
				
			||||||
 | 
							return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename format %q", str)}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts := strings.Split(str, "/")
 | 
				
			||||||
 | 
						switch len(parts) {
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							if !api.IsStandardResourceName(parts[0]) {
 | 
				
			||||||
 | 
								return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename. %q is neither a standard resource type nor is fully qualified", str)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							if parts[0] == api.DefaultResourceNamespace {
 | 
				
			||||||
 | 
								if !api.IsStandardResourceName(parts[1]) {
 | 
				
			||||||
 | 
									return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename. %q contains a compute resource type not supported", str)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return errs.ValidationErrorList{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1440,3 +1440,40 @@ func TestValidateMinionUpdate(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestValidateResourceNames(t *testing.T) {
 | 
				
			||||||
 | 
						longString := "a"
 | 
				
			||||||
 | 
						for i := 0; i < 6; i++ {
 | 
				
			||||||
 | 
							longString += longString
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						table := []struct {
 | 
				
			||||||
 | 
							input   string
 | 
				
			||||||
 | 
							success bool
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"memory", true},
 | 
				
			||||||
 | 
							{"cpu", true},
 | 
				
			||||||
 | 
							{"network", false},
 | 
				
			||||||
 | 
							{"disk", false},
 | 
				
			||||||
 | 
							{"", false},
 | 
				
			||||||
 | 
							{".", false},
 | 
				
			||||||
 | 
							{"..", false},
 | 
				
			||||||
 | 
							{"kubernetes.io/cpu", true},
 | 
				
			||||||
 | 
							{"kubernetes.io/disk", false},
 | 
				
			||||||
 | 
							{"my.favorite.app.co/12345", true},
 | 
				
			||||||
 | 
							{"my.favorite.app.co/_12345", false},
 | 
				
			||||||
 | 
							{"my.favorite.app.co/12345_", false},
 | 
				
			||||||
 | 
							{"kubernetes.io/..", false},
 | 
				
			||||||
 | 
							{"kubernetes.io/" + longString, false},
 | 
				
			||||||
 | 
							{"kubernetes.io//", false},
 | 
				
			||||||
 | 
							{"kubernetes.io", false},
 | 
				
			||||||
 | 
							{"kubernetes.io/will/not/work/", false},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, item := range table {
 | 
				
			||||||
 | 
							err := ValidateResourceName(item.input)
 | 
				
			||||||
 | 
							if len(err) != 0 && item.success {
 | 
				
			||||||
 | 
								t.Errorf("expected no failure for input %q", item.input)
 | 
				
			||||||
 | 
							} else if len(err) == 0 && !item.success {
 | 
				
			||||||
 | 
								t.Errorf("expected failure for input %q", item.input)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,10 +20,12 @@ import (
 | 
				
			|||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/golang/glog"
 | 
				
			||||||
@@ -183,3 +185,20 @@ func AllPtrFieldsNil(obj interface{}) bool {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Splits a fully qualified name and returns its namespace and name.
 | 
				
			||||||
 | 
					// Assumes that the input 'str' has been validated.
 | 
				
			||||||
 | 
					func SplitQualifiedName(str string) (string, string) {
 | 
				
			||||||
 | 
						parts := strings.Split(str, "/")
 | 
				
			||||||
 | 
						if len(parts) < 2 {
 | 
				
			||||||
 | 
							return "", str
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parts[0], parts[1]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Joins 'namespace' and 'name' and returns a fully qualified name
 | 
				
			||||||
 | 
					// Assumes that the input is valid.
 | 
				
			||||||
 | 
					func JoinQualifiedName(namespace, name string) string {
 | 
				
			||||||
 | 
						return path.Join(namespace, name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -263,3 +263,37 @@ func TestAllPtrFieldsNil(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestSplitQualifiedName(t *testing.T) {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							input  string
 | 
				
			||||||
 | 
							output []string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{"kubernetes.io/blah", []string{"kubernetes.io", "blah"}},
 | 
				
			||||||
 | 
							{"blah", []string{"", "blah"}},
 | 
				
			||||||
 | 
							{"kubernetes.io/blah/blah", []string{"kubernetes.io", "blah"}},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							namespace, name := SplitQualifiedName(tc.input)
 | 
				
			||||||
 | 
							if namespace != tc.output[0] || name != tc.output[1] {
 | 
				
			||||||
 | 
								t.Errorf("case[%d]: expected (%q, %q), got (%q, %q)", i, tc.output[0], tc.output[1], namespace, name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestJoinQualifiedName(t *testing.T) {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							input  []string
 | 
				
			||||||
 | 
							output string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{[]string{"kubernetes.io", "blah"}, "kubernetes.io/blah"},
 | 
				
			||||||
 | 
							{[]string{"blah", ""}, "blah"},
 | 
				
			||||||
 | 
							{[]string{"kubernetes.io", "blah"}, "kubernetes.io/blah"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							res := JoinQualifiedName(tc.input[0], tc.input[1])
 | 
				
			||||||
 | 
							if res != tc.output {
 | 
				
			||||||
 | 
								t.Errorf("case[%d]: expected %q, got %q", i, tc.output, res)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user