Merge pull request #6325 from rjnagal/node

Remove validation for Capacity. Add default for ExternalID
This commit is contained in:
Brian Grant 2015-04-01 18:25:32 -07:00
commit 0e67b299d5
14 changed files with 72 additions and 95 deletions

View File

@ -230,6 +230,10 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
}
}
},
func(n *api.Node, c fuzz.Continue) {
c.FuzzNoCustom(n)
n.Spec.ExternalID = "external"
},
)
return f
}

View File

@ -175,10 +175,15 @@ func TestVolumeMountConversionToNew(t *testing.T) {
func TestMinionListConversionToNew(t *testing.T) {
oldMinion := func(id string) current.Minion {
return current.Minion{TypeMeta: current.TypeMeta{ID: id}}
return current.Minion{
TypeMeta: current.TypeMeta{ID: id},
ExternalID: id}
}
newNode := func(id string) newer.Node {
return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}}
return newer.Node{
ObjectMeta: newer.ObjectMeta{Name: id},
Spec: newer.NodeSpec{ExternalID: id},
}
}
oldMinions := []current.Minion{
oldMinion("foo"),

View File

@ -153,6 +153,11 @@ func init() {
obj.Phase = NamespaceActive
}
},
func(obj *Minion) {
if obj.ExternalID == "" {
obj.ExternalID = obj.ID
}
},
)
}

View File

@ -187,3 +187,14 @@ func TestSetDefaultServicePort(t *testing.T) {
t.Errorf("Expected port %d, got %v", in.Ports[0].Port, out.Ports[0].ContainerPort)
}
}
func TestSetDefaultMinionExternalID(t *testing.T) {
name := "node0"
m := &current.Minion{}
m.ID = name
obj2 := roundTrip(t, runtime.Object(m))
m2 := obj2.(*current.Minion)
if m2.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, m2.ExternalID)
}
}

View File

@ -986,7 +986,7 @@ type Minion struct {
// Labels for the node
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize minions; labels of a minion assigned by the scheduler must match the scheduled pod's nodeSelector"`
// External ID of the node
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider)"`
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
}
// MinionList is a list of minions.

View File

@ -154,6 +154,11 @@ func init() {
obj.Phase = NamespaceActive
}
},
func(obj *Minion) {
if obj.ExternalID == "" {
obj.ExternalID = obj.ID
}
},
)
}

View File

@ -186,3 +186,14 @@ func TestSetDefaultServicePort(t *testing.T) {
t.Errorf("Expected port %d, got %v", in.Ports[0].Port, out.Ports[0].ContainerPort)
}
}
func TestSetDefaultMinionExternalID(t *testing.T) {
name := "node0"
m := &current.Minion{}
m.ID = name
obj2 := roundTrip(t, runtime.Object(m))
m2 := obj2.(*current.Minion)
if m2.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, m2.ExternalID)
}
}

View File

@ -1001,7 +1001,7 @@ type Minion struct {
// Labels for the node
Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize minions; labels of a minion assigned by the scheduler must match the scheduled pod's nodeSelector"`
// External ID of the node
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider)"`
ExternalID string `json:"externalID,omitempty" description:"external id of the node assigned by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
}
// MinionList is a list of minions.

View File

@ -108,6 +108,11 @@ func init() {
obj.Phase = NamespaceActive
}
},
func(obj *Node) {
if obj.Spec.ExternalID == "" {
obj.Spec.ExternalID = obj.Name
}
},
)
}

View File

@ -182,3 +182,14 @@ func TestSetDefaultPodSpecHostNetwork(t *testing.T) {
t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
}
}
func TestSetDefaultNodeExternalID(t *testing.T) {
name := "node0"
n := &current.Node{}
n.Name = name
obj2 := roundTrip(t, runtime.Object(n))
n2 := obj2.(*current.Node)
if n2.Spec.ExternalID != name {
t.Errorf("Expected default External ID: %s, got: %s", name, n2.Spec.ExternalID)
}
}

View File

@ -999,7 +999,7 @@ type NodeSpec struct {
// PodCIDR represents the pod IP range assigned to the node
PodCIDR string `json:"podCIDR,omitempty" description:"pod IP range assigned to the node"`
// External ID of the node assigned by some machine database (e.g. a cloud provider)
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider)"`
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider). Defaults to node name when empty."`
// Unschedulable controls node schedulability of new pods. By default node is schedulable.
Unschedulable bool `json:"unschedulable,omitempty" description:"disable pod scheduling on the node"`
}

View File

@ -942,21 +942,8 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume) errs.ValidationErrorL
func ValidateMinion(node *api.Node) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
allErrs = append(allErrs, ValidateObjectMeta(&node.ObjectMeta, false, ValidateNodeName).Prefix("metadata")...)
// Capacity is required. Within capacity, memory and cpu resources are required.
if len(node.Status.Capacity) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity"))
} else {
if val, ok := node.Status.Capacity[api.ResourceMemory]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity[memory]"))
} else if val.Value() < 0 {
allErrs = append(allErrs, errs.NewFieldInvalid("status.Capacity[memory]", val, "memory capacity cannot be negative"))
}
if val, ok := node.Status.Capacity[api.ResourceCPU]; !ok {
allErrs = append(allErrs, errs.NewFieldRequired("status.Capacity[cpu]"))
} else if val.Value() < 0 {
allErrs = append(allErrs, errs.NewFieldInvalid("status.Capacity[cpu]", val, "cpu capacity cannot be negative"))
}
}
// Only validate spec. All status fields are optional and can be updated later.
// external ID is required.
if len(node.Spec.ExternalID) == 0 {

View File

@ -1938,73 +1938,6 @@ func TestValidateMinion(t *testing.T) {
},
},
},
"missing-capacity": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"missing-memory": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"missing-cpu": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"invalid-memory": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("-10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
"invalid-cpu": {
ObjectMeta: api.ObjectMeta{
Name: "abc-123",
Labels: validSelector,
},
Status: api.NodeStatus{
Capacity: api.ResourceList{
api.ResourceName(api.ResourceCPU): resource.MustParse("-10"),
api.ResourceName(api.ResourceMemory): resource.MustParse("10G"),
},
},
Spec: api.NodeSpec{
ExternalID: "external",
},
},
}
for k, v := range errorCases {
errs := ValidateMinion(&v)
@ -2014,14 +1947,11 @@ func TestValidateMinion(t *testing.T) {
for i := range errs {
field := errs[i].(*errors.ValidationError).Field
expectedFields := map[string]bool{
"metadata.name": true,
"metadata.labels": true,
"metadata.annotations": true,
"metadata.namespace": true,
"status.Capacity": true,
"status.Capacity[memory]": true,
"status.Capacity[cpu]": true,
"spec.ExternalID": true,
"metadata.name": true,
"metadata.labels": true,
"metadata.annotations": true,
"metadata.namespace": true,
"spec.ExternalID": true,
}
if expectedFields[field] == false {
t.Errorf("%s: missing prefix for: %v", k, errs[i])

View File

@ -319,6 +319,9 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
ObjectMeta: api.ObjectMeta{
Name: "foo",
},
Spec: api.NodeSpec{
ExternalID: "ext",
},
}
f, tf, codec := NewAPIFactory()