From 9b0af8df63215c82224a0ab2b5942ed9706295c9 Mon Sep 17 00:00:00 2001 From: Deyuan Deng Date: Fri, 13 Feb 2015 14:07:23 -0500 Subject: [PATCH] Node addresses --- pkg/api/types.go | 20 +++++++++- pkg/api/v1beta1/conversion.go | 27 ++++++++++++- pkg/api/v1beta1/types.go | 17 +++++++++ pkg/api/v1beta2/conversion.go | 27 ++++++++++++- pkg/api/v1beta2/types.go | 21 +++++++++- pkg/api/v1beta3/types.go | 18 ++++++++- pkg/api/validation/validation_test.go | 14 +++++-- pkg/client/client_test.go | 3 -- .../controller/nodecontroller.go | 17 +++++---- .../controller/nodecontroller_test.go | 38 +++++++++++-------- pkg/master/pod_cache.go | 19 +++++++++- pkg/master/pod_cache_test.go | 4 +- pkg/registry/minion/rest.go | 7 ---- pkg/registry/minion/rest_test.go | 8 +++- 14 files changed, 189 insertions(+), 51 deletions(-) diff --git a/pkg/api/types.go b/pkg/api/types.go index 272a370674f..4d3255a5d4e 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -789,12 +789,12 @@ type NodeSpec struct { // NodeStatus is information about the current status of a node. type NodeStatus struct { - // Queried from cloud provider, if available. - HostIP string `json:"hostIP,omitempty"` // NodePhase is the current lifecycle phase of the node. Phase NodePhase `json:"phase,omitempty"` // Conditions is an array of current node conditions. Conditions []NodeCondition `json:"conditions,omitempty"` + // Queried from cloud provider, if available. + Addresses []NodeAddress `json:"addresses,omitempty"` } type NodePhase string @@ -830,6 +830,22 @@ type NodeCondition struct { Message string `json:"message,omitempty"` } +type NodeAddressType string + +// These are valid address types of node. NodeLegacyHostIP is used to transit +// from out-dated HostIP field to NodeAddress. +const ( + NodeLegacyHostIP NodeAddressType = "LegacyHostIP" + NodeHostName NodeAddressType = "Hostname" + NodeExternalIP NodeAddressType = "ExternalIP" + NodeInternalIP NodeAddressType = "InternalIP" +) + +type NodeAddress struct { + Type NodeAddressType `json:"type"` + Address string `json:"address"` +} + // NodeResources is an object for conveying resource information about a node. // see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md for more details. // TODO: Use ResourceList instead? diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 715b08b82ae..d078df19e63 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -696,8 +696,15 @@ func init() { if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } + if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { + return err + } - out.HostIP = in.Status.HostIP + for _, address := range in.Status.Addresses { + if address.Type == newer.NodeLegacyHostIP { + out.HostIP = address.Address + } + } out.PodCIDR = in.Spec.PodCIDR out.ExternalID = in.Spec.ExternalID return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0) @@ -718,12 +725,19 @@ func init() { if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } + if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { + return err + } - out.Status.HostIP = in.HostIP + if in.HostIP != "" { + out.Status.Addresses = append(out.Status.Addresses, + newer.NodeAddress{Type: newer.NodeLegacyHostIP, Address: in.HostIP}) + } out.Spec.PodCIDR = in.PodCIDR out.Spec.ExternalID = in.ExternalID return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, + func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -748,6 +762,7 @@ func init() { } return nil }, + func(in *Namespace, out *newer.Namespace, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -763,6 +778,7 @@ func init() { } return nil }, + func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { *out = LimitRangeSpec{} out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) @@ -783,6 +799,7 @@ func init() { } return nil }, + func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} out.Type = LimitType(in.Type) @@ -805,6 +822,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -835,6 +853,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaUsage, out *ResourceQuotaUsage, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -859,6 +878,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { *out = ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { @@ -873,6 +893,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { *out = ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { @@ -893,6 +914,7 @@ func init() { } return nil }, + // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { @@ -1133,6 +1155,7 @@ func init() { out.TimeoutSeconds = in.TimeoutSeconds return nil }, + func(in *newer.Endpoints, out *Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index c4b7b2e7083..101fc76d128 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -623,6 +623,8 @@ type NodeStatus struct { Phase NodePhase `json:"phase,omitempty" description:"node phase is the current lifecycle phase of the node"` // Conditions is an array of current node conditions. Conditions []NodeCondition `json:"conditions,omitempty" description:"conditions is an array of current node conditions"` + // Queried from cloud provider, if available. + Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"` } type NodePhase string @@ -658,6 +660,20 @@ type NodeCondition struct { Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"` } +type NodeAddressType string + +// These are valid address types of node. +const ( + NodeHostName NodeAddressType = "Hostname" + NodeExternalIP NodeAddressType = "ExternalIP" + NodeInternalIP NodeAddressType = "InternalIP" +) + +type NodeAddress struct { + Type NodeAddressType `json:"type" description:"type of the node address, e.g. external ip, internal ip, hostname, etc"` + Address string `json:"address" description:"string representation of the address"` +} + // NodeResources represents resources on a Kubernetes system node // see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md for more details. type NodeResources struct { @@ -680,6 +696,7 @@ type ResourceList map[ResourceName]util.IntOrString // The name of the minion according to etcd is in ID. type Minion struct { TypeMeta `json:",inline"` + // DEPRECATED: Use Status.Addresses instead. // Queried from cloud provider, if available. HostIP string `json:"hostIP,omitempty" description:"IP address of the node"` // Resources available on the node diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index df1d6f794e7..83cea0f1e92 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -616,8 +616,15 @@ func init() { if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } + if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { + return err + } - out.HostIP = in.Status.HostIP + for _, address := range in.Status.Addresses { + if address.Type == newer.NodeLegacyHostIP { + out.HostIP = address.Address + } + } out.PodCIDR = in.Spec.PodCIDR out.ExternalID = in.Spec.ExternalID return s.Convert(&in.Spec.Capacity, &out.NodeResources.Capacity, 0) @@ -638,12 +645,19 @@ func init() { if err := s.Convert(&in.Status.Conditions, &out.Status.Conditions, 0); err != nil { return err } + if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil { + return err + } - out.Status.HostIP = in.HostIP + if in.HostIP != "" { + out.Status.Addresses = append(out.Status.Addresses, + newer.NodeAddress{Type: newer.NodeLegacyHostIP, Address: in.HostIP}) + } out.Spec.PodCIDR = in.PodCIDR out.Spec.ExternalID = in.ExternalID return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, + func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -668,6 +682,7 @@ func init() { } return nil }, + func(in *Namespace, out *newer.Namespace, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -683,6 +698,7 @@ func init() { } return nil }, + func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { *out = LimitRangeSpec{} out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) @@ -703,6 +719,7 @@ func init() { } return nil }, + func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} out.Type = LimitType(in.Type) @@ -725,6 +742,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -755,6 +773,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaUsage, out *ResourceQuotaUsage, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err @@ -779,6 +798,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { *out = ResourceQuotaSpec{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { @@ -793,6 +813,7 @@ func init() { } return nil }, + func(in *newer.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { *out = ResourceQuotaStatus{} if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { @@ -813,6 +834,7 @@ func init() { } return nil }, + // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { @@ -1049,6 +1071,7 @@ func init() { out.TimeoutSeconds = in.TimeoutSeconds return nil }, + func(in *newer.Endpoints, out *Endpoints, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index be7f14c4668..b613968d8f5 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -587,6 +587,8 @@ type NodeStatus struct { Phase NodePhase `json:"phase,omitempty" description:"node phase is the current lifecycle phase of the node"` // Conditions is an array of current node conditions. Conditions []NodeCondition `json:"conditions,omitempty" description:"conditions is an array of current node conditions"` + // Queried from cloud provider, if available. + Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"` } type NodePhase string @@ -622,6 +624,20 @@ type NodeCondition struct { Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"` } +type NodeAddressType string + +// These are valid address types of node. +const ( + NodeHostName NodeAddressType = "Hostname" + NodeExternalIP NodeAddressType = "ExternalIP" + NodeInternalIP NodeAddressType = "InternalIP" +) + +type NodeAddress struct { + Type NodeAddressType `json:"type" description:"type of the node address, e.g. external ip, internal ip, hostname, etc"` + Address string `json:"address" description:"string representation of the address"` +} + // NodeResources represents resources on a Kubernetes system node // see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/resources.md for more details. type NodeResources struct { @@ -644,12 +660,13 @@ type ResourceList map[ResourceName]util.IntOrString // The name of the minion according to etcd is in ID. type Minion struct { TypeMeta `json:",inline"` + // DEPRECATED: Use Status.Addresses instead. // Queried from cloud provider, if available. HostIP string `json:"hostIP,omitempty" description:"IP address of the node"` - // Pod IP range assigned to the node - PodCIDR string `json:"cidr,omitempty" description:"IP range assigned to the node"` // Resources available on the node NodeResources NodeResources `json:"resources,omitempty" description:"characterization of node resources"` + // Pod IP range assigned to the node + PodCIDR string `json:"cidr,omitempty" description:"IP range assigned to the node"` // Status describes the current status of a node Status NodeStatus `json:"status,omitempty" description:"current status of node"` // Labels for the node diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index bd93a78356a..0917909f951 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -820,12 +820,12 @@ type NodeSpec struct { // NodeStatus is information about the current status of a node. type NodeStatus struct { - // Queried from cloud provider, if available. - HostIP string `json:"hostIP,omitempty"` // NodePhase is the current lifecycle phase of the node. Phase NodePhase `json:"phase,omitempty"` // Conditions is an array of current node conditions. Conditions []NodeCondition `json:"conditions,omitempty"` + // Queried from cloud provider, if available. + Addresses []NodeAddress `json:"addresses,omitempty"` } type NodePhase string @@ -861,6 +861,20 @@ type NodeCondition struct { Message string `json:"message,omitempty"` } +type NodeAddressType string + +// These are valid address type of node. +const ( + NodeHostName NodeAddressType = "Hostname" + NodeExternalIP NodeAddressType = "ExternalIP" + NodeInternalIP NodeAddressType = "InternalIP" +) + +type NodeAddress struct { + Type NodeAddressType `json:"type"` + Address string `json:"address"` +} + // ResourceName is the name identifying various resources in a ResourceList. type ResourceName string diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 54fc64d3778..a81f03c1e99 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -1919,7 +1919,9 @@ func TestValidateMinion(t *testing.T) { Labels: validSelector, }, Status: api.NodeStatus{ - HostIP: "something", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "something"}, + }, }, }, { @@ -1927,7 +1929,9 @@ func TestValidateMinion(t *testing.T) { Name: "abc", }, Status: api.NodeStatus{ - HostIP: "something", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "something"}, + }, }, }, } @@ -1944,7 +1948,7 @@ func TestValidateMinion(t *testing.T) { Labels: validSelector, }, Status: api.NodeStatus{ - HostIP: "something", + Addresses: []api.NodeAddress{}, }, }, "invalid-labels": { @@ -2073,7 +2077,9 @@ func TestValidateMinionUpdate(t *testing.T) { Labels: map[string]string{"bar": "foo"}, }, Status: api.NodeStatus{ - HostIP: "1.2.3.4", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "1.2.3.4"}, + }, }, }, api.Node{ ObjectMeta: api.ObjectMeta{ diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 096b887dbcf..6798346da7b 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -730,9 +730,6 @@ func TestCreateMinion(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "minion-1", }, - Status: api.NodeStatus{ - HostIP: "123.321.456.654", - }, Spec: api.NodeSpec{ Capacity: api.ResourceList{ api.ResourceCPU: resource.MustParse("1000m"), diff --git a/pkg/cloudprovider/controller/nodecontroller.go b/pkg/cloudprovider/controller/nodecontroller.go index 2429c84583a..0218d304e0d 100644 --- a/pkg/cloudprovider/controller/nodecontroller.go +++ b/pkg/cloudprovider/controller/nodecontroller.go @@ -108,7 +108,7 @@ func (s *NodeController) Run(period time.Duration, syncNodeList, syncNodeStatus glog.Errorf("Error loading initial static nodes: %v", err) } } - nodes, err = s.PopulateIPs(nodes) + nodes, err = s.PopulateAddresses(nodes) if err != nil { glog.Errorf("Error getting nodes ips: %v", err) } @@ -220,7 +220,7 @@ func (s *NodeController) SyncNodeStatus() error { return err } nodes = s.DoChecks(nodes) - nodes, err = s.PopulateIPs(nodes) + nodes, err = s.PopulateAddresses(nodes) if err != nil { return err } @@ -264,8 +264,8 @@ func latestReadyTime(node *api.Node) util.Time { return readyTime } -// PopulateIPs queries IPs for given list of nodes. -func (s *NodeController) PopulateIPs(nodes *api.NodeList) (*api.NodeList, error) { +// PopulateAddresses queries Address for given list of nodes. +func (s *NodeController) PopulateAddresses(nodes *api.NodeList) (*api.NodeList, error) { if s.isRunningCloudProvider() { instances, ok := s.cloud.Instances() if !ok { @@ -277,7 +277,8 @@ func (s *NodeController) PopulateIPs(nodes *api.NodeList) (*api.NodeList, error) if err != nil { glog.Errorf("error getting instance ip address for %s: %v", node.Name, err) } else { - node.Status.HostIP = hostIP.String() + address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: hostIP.String()} + node.Status.Addresses = append(node.Status.Addresses, address) } } } else { @@ -285,7 +286,8 @@ func (s *NodeController) PopulateIPs(nodes *api.NodeList) (*api.NodeList, error) node := &nodes.Items[i] addr := net.ParseIP(node.Name) if addr != nil { - node.Status.HostIP = node.Name + address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: addr.String()} + node.Status.Addresses = append(node.Status.Addresses, address) } else { addrs, err := lookupIP(node.Name) if err != nil { @@ -293,7 +295,8 @@ func (s *NodeController) PopulateIPs(nodes *api.NodeList) (*api.NodeList, error) } else if len(addrs) == 0 { glog.Errorf("No ip address for node %v", node.Name) } else { - node.Status.HostIP = addrs[0].String() + address := api.NodeAddress{Type: api.NodeLegacyHostIP, Address: addrs[0].String()} + node.Status.Addresses = append(node.Status.Addresses, address) } } } diff --git a/pkg/cloudprovider/controller/nodecontroller_test.go b/pkg/cloudprovider/controller/nodecontroller_test.go index eee20d76b15..c62912601b3 100644 --- a/pkg/cloudprovider/controller/nodecontroller_test.go +++ b/pkg/cloudprovider/controller/nodecontroller_test.go @@ -621,35 +621,37 @@ func TestHealthCheckNode(t *testing.T) { } } -func TestPopulateNodeIPs(t *testing.T) { +func TestPopulateNodeAddresses(t *testing.T) { table := []struct { - nodes *api.NodeList - fakeCloud *fake_cloud.FakeCloud - expectedFail bool - expectedIP string + nodes *api.NodeList + fakeCloud *fake_cloud.FakeCloud + expectedFail bool + expectedAddresses []api.NodeAddress }{ { - nodes: &api.NodeList{Items: []api.Node{*newNode("node0"), *newNode("node1")}}, - fakeCloud: &fake_cloud.FakeCloud{IP: net.ParseIP("1.2.3.4")}, - expectedIP: "1.2.3.4", + nodes: &api.NodeList{Items: []api.Node{*newNode("node0"), *newNode("node1")}}, + fakeCloud: &fake_cloud.FakeCloud{IP: net.ParseIP("1.2.3.4")}, + expectedAddresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "1.2.3.4"}, + }, }, { - nodes: &api.NodeList{Items: []api.Node{*newNode("node0"), *newNode("node1")}}, - fakeCloud: &fake_cloud.FakeCloud{Err: ErrQueryIPAddress}, - expectedIP: "", + nodes: &api.NodeList{Items: []api.Node{*newNode("node0"), *newNode("node1")}}, + fakeCloud: &fake_cloud.FakeCloud{Err: ErrQueryIPAddress}, + expectedAddresses: nil, }, } for _, item := range table { nodeController := NewNodeController(item.fakeCloud, ".*", nil, nil, nil, nil, 10, time.Minute) - result, err := nodeController.PopulateIPs(item.nodes) + result, err := nodeController.PopulateAddresses(item.nodes) // In case of IP querying error, we should continue. if err != nil { t.Errorf("unexpected error: %v", err) } for _, node := range result.Items { - if node.Status.HostIP != item.expectedIP { - t.Errorf("expect HostIP %s, got %s", item.expectedIP, node.Status.HostIP) + if !reflect.DeepEqual(item.expectedAddresses, node.Status.Addresses) { + t.Errorf("expect HostIP %s, got %s", item.expectedAddresses, node.Status.Addresses) } } } @@ -1031,7 +1033,9 @@ func TestSyncNodeStatus(t *testing.T) { Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok", }, }, - HostIP: "1.2.3.4", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "1.2.3.4"}, + }, }, }, { @@ -1044,7 +1048,9 @@ func TestSyncNodeStatus(t *testing.T) { Reason: "Node health check succeeded: kubelet /healthz endpoint returns ok", }, }, - HostIP: "1.2.3.4", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "1.2.3.4"}, + }, }, }, }, diff --git a/pkg/master/pod_cache.go b/pkg/master/pod_cache.go index a3f24f22375..ab95f3a2d04 100644 --- a/pkg/master/pod_cache.go +++ b/pkg/master/pod_cache.go @@ -140,6 +140,23 @@ func (p *PodCache) clearNodeStatus() { p.currentNodes = map[objKey]api.NodeStatus{} } +func (p *PodCache) getHostAddress(addresses []api.NodeAddress) string { + addressMap := make(map[api.NodeAddressType][]api.NodeAddress) + for i := range addresses { + addressMap[addresses[i].Type] = append(addressMap[addresses[i].Type], addresses[i]) + } + if addresses, ok := addressMap[api.NodeLegacyHostIP]; ok { + return addresses[0].Address + } + if addresses, ok := addressMap[api.NodeInternalIP]; ok { + return addresses[0].Address + } + if addresses, ok := addressMap[api.NodeExternalIP]; ok { + return addresses[0].Address + } + return "" +} + // TODO: once Host gets moved to spec, this can take a podSpec + metadata instead of an // entire pod? func (p *PodCache) updatePodStatus(pod *api.Pod) error { @@ -193,7 +210,7 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) { if err != nil { glog.V(5).Infof("error getting pod %s status: %v, retry later", pod.Name, err) } else { - newStatus.HostIP = nodeStatus.HostIP + newStatus.HostIP = p.getHostAddress(nodeStatus.Addresses) newStatus.Info = result.Status.Info newStatus.PodIP = result.Status.PodIP if newStatus.Info == nil { diff --git a/pkg/master/pod_cache_test.go b/pkg/master/pod_cache_test.go index 8f2bd2f3a88..f99377cfbe1 100644 --- a/pkg/master/pod_cache_test.go +++ b/pkg/master/pod_cache_test.go @@ -224,7 +224,9 @@ func makeHealthyNode(name string, ip string) *api.Node { return &api.Node{ ObjectMeta: api.ObjectMeta{Name: name}, Status: api.NodeStatus{ - HostIP: ip, + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: ip}, + }, Conditions: []api.NodeCondition{ {Type: api.NodeReady, Status: api.ConditionFull}, }, diff --git a/pkg/registry/minion/rest.go b/pkg/registry/minion/rest.go index cd6db1ef475..86f5f6861ef 100644 --- a/pkg/registry/minion/rest.go +++ b/pkg/registry/minion/rest.go @@ -121,13 +121,6 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo return nil, false, err } - // This is hacky, but minion HostIP has been moved from spec to status since v1beta2. When updating - // minion from older client, HostIP will be lost. Fix it here temporarily until we strip out status - // info from user input. - if minion.Status.HostIP == "" { - minion.Status.HostIP = oldMinion.Status.HostIP - } - if errs := validation.ValidateMinionUpdate(oldMinion, minion); len(errs) > 0 { return nil, false, kerrors.NewInvalid("minion", minion.Name, errs) } diff --git a/pkg/registry/minion/rest_test.go b/pkg/registry/minion/rest_test.go index fe53157e31a..b6b1e669443 100644 --- a/pkg/registry/minion/rest_test.go +++ b/pkg/registry/minion/rest_test.go @@ -121,7 +121,9 @@ func TestMinionRegistryValidatesCreate(t *testing.T) { Labels: validSelector, }, Status: api.NodeStatus{ - HostIP: "something", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "something"}, + }, }, }, "invalid-labels": { @@ -158,7 +160,9 @@ func TestCreate(t *testing.T) { // valid &api.Node{ Status: api.NodeStatus{ - HostIP: "something", + Addresses: []api.NodeAddress{ + {Type: api.NodeLegacyHostIP, Address: "something"}, + }, }, }, // invalid