Skip to content

Commit

Permalink
Merge pull request kubernetes#5030 from simon3z/nodeinfo
Browse files Browse the repository at this point in the history
Add support for fetching node collected information
  • Loading branch information
bgrant0607 committed Mar 10, 2015
2 parents 25cad2c + 644d775 commit 9aa7449
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 37 deletions.
4 changes: 4 additions & 0 deletions cmd/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ func (fakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.Pod
return r, nil
}

func (fakeKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
return api.NodeInfo{}, nil
}

func (fakeKubeletClient) HealthCheck(host string) (probe.Result, error) {
return probe.Success, nil
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func init() {
&Service{},
&NodeList{},
&Node{},
&NodeInfo{},
&Status{},
&Endpoints{},
&EndpointsList{},
Expand Down Expand Up @@ -70,6 +71,7 @@ func (*ServiceList) IsAnAPIObject() {}
func (*Endpoints) IsAnAPIObject() {}
func (*EndpointsList) IsAnAPIObject() {}
func (*Node) IsAnAPIObject() {}
func (*NodeInfo) IsAnAPIObject() {}
func (*NodeList) IsAnAPIObject() {}
func (*Binding) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
Expand Down
19 changes: 19 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,14 @@ type NodeSpec struct {
ExternalID string `json:"externalID,omitempty"`
}

// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
type NodeSystemInfo struct {
// MachineID is the machine-id reported by the node
MachineID string `json:"machineID"`
// SystemUUID is the system-uuid reported by the node
SystemUUID string `json:"systemUUID"`
}

// NodeStatus is information about the current status of a node.
type NodeStatus struct {
// NodePhase is the current lifecycle phase of the node.
Expand All @@ -796,6 +804,17 @@ type NodeStatus struct {
Conditions []NodeCondition `json:"conditions,omitempty"`
// Queried from cloud provider, if available.
Addresses []NodeAddress `json:"addresses,omitempty"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"`
}

// NodeInfo is the information collected on the node.
type NodeInfo struct {
TypeMeta `json:",inline"`
// Capacity represents the available resources of a node
Capacity ResourceList `json:"capacity,omitempty"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeSystemInfo `json:",inline,omitempty"`
}

type NodePhase string
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,9 @@ func init() {
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
return err
}
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
return err
}

for _, address := range in.Status.Addresses {
if address.Type == newer.NodeLegacyHostIP {
Expand Down Expand Up @@ -728,6 +731,9 @@ func init() {
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
return err
}
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
return err
}

if in.HostIP != "" {
newer.AddToNodeAddresses(&out.Status.Addresses,
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func init() {
&EndpointsList{},
&Minion{},
&MinionList{},
&NodeInfo{},
&Binding{},
&Status{},
&Event{},
Expand Down Expand Up @@ -77,6 +78,7 @@ func (*ServiceList) IsAnAPIObject() {}
func (*Endpoints) IsAnAPIObject() {}
func (*EndpointsList) IsAnAPIObject() {}
func (*Minion) IsAnAPIObject() {}
func (*NodeInfo) IsAnAPIObject() {}
func (*MinionList) IsAnAPIObject() {}
func (*Binding) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
Expand Down
19 changes: 19 additions & 0 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,14 @@ type EndpointsList struct {
Items []Endpoints `json:"items" description:"list of service endpoint lists"`
}

// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
type NodeSystemInfo struct {
// MachineID is the machine-id reported by the node
MachineID string `json:"machineID" description:"machine id is the machine-id reported by the node"`
// SystemUUID is the system-uuid reported by the node
SystemUUID string `json:"systemUUID" description:"system uuid is the system-uuid reported by the node"`
}

// NodeStatus is information about the current status of a node.
type NodeStatus struct {
// NodePhase is the current lifecycle phase of the node.
Expand All @@ -626,6 +634,17 @@ type NodeStatus struct {
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"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
}

// NodeInfo is the information collected on the node.
type NodeInfo struct {
TypeMeta `json:",inline"`
// Capacity represents the available resources.
Capacity ResourceList `json:"capacity,omitempty" description:"resource capacity of a node represented as a map of resource name to quantity of resource"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeSystemInfo `json:",inline,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
}

type NodePhase string
Expand Down
6 changes: 6 additions & 0 deletions pkg/api/v1beta2/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,9 @@ func init() {
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
return err
}
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
return err
}

for _, address := range in.Status.Addresses {
if address.Type == newer.NodeLegacyHostIP {
Expand Down Expand Up @@ -648,6 +651,9 @@ func init() {
if err := s.Convert(&in.Status.Addresses, &out.Status.Addresses, 0); err != nil {
return err
}
if err := s.Convert(&in.Status.NodeInfo, &out.Status.NodeInfo, 0); err != nil {
return err
}

if in.HostIP != "" {
newer.AddToNodeAddresses(&out.Status.Addresses,
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func init() {
&Endpoints{},
&EndpointsList{},
&Minion{},
&NodeInfo{},
&MinionList{},
&Binding{},
&Status{},
Expand Down Expand Up @@ -77,6 +78,7 @@ func (*ServiceList) IsAnAPIObject() {}
func (*Endpoints) IsAnAPIObject() {}
func (*EndpointsList) IsAnAPIObject() {}
func (*Minion) IsAnAPIObject() {}
func (*NodeInfo) IsAnAPIObject() {}
func (*MinionList) IsAnAPIObject() {}
func (*Binding) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
Expand Down
19 changes: 19 additions & 0 deletions pkg/api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@ type EndpointsList struct {
Items []Endpoints `json:"items" description:"list of service endpoint lists"`
}

// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
type NodeSystemInfo struct {
// MachineID is the machine-id reported by the node
MachineID string `json:"machineID" description:"machine id is the machine-id reported by the node"`
// SystemUUID is the system-uuid reported by the node
SystemUUID string `json:"systemUUID" description:"system uuid is the system-uuid reported by the node"`
}

// NodeStatus is information about the current status of a node.
//
// https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/node.md#node-status
Expand All @@ -633,6 +641,17 @@ type NodeStatus struct {
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"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
}

// NodeInfo is the information collected on the node.
type NodeInfo struct {
TypeMeta `json:",inline"`
// Capacity represents the available resources.
Capacity ResourceList `json:"capacity,omitempty" description:"resource capacity of a node represented as a map of resource name to quantity of resource"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeSystemInfo `json:",inline,omitempty" description:"node identity is a set of ids/uuids to uniquely identify the node"`
}

// Described the current lifecycle phase of a node.
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1beta3/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func init() {
&Endpoints{},
&EndpointsList{},
&Node{},
&NodeInfo{},
&NodeList{},
&Binding{},
&Status{},
Expand Down Expand Up @@ -75,6 +76,7 @@ func (*ServiceList) IsAnAPIObject() {}
func (*Endpoints) IsAnAPIObject() {}
func (*EndpointsList) IsAnAPIObject() {}
func (*Node) IsAnAPIObject() {}
func (*NodeInfo) IsAnAPIObject() {}
func (*NodeList) IsAnAPIObject() {}
func (*Binding) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
Expand Down
19 changes: 19 additions & 0 deletions pkg/api/v1beta3/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,14 @@ type NodeSpec struct {
ExternalID string `json:"externalID,omitempty" description:"external ID assigned to the node by some machine database (e.g. a cloud provider)"`
}

// NodeSystemInfo is a set of ids/uuids to uniquely identify the node.
type NodeSystemInfo struct {
// MachineID is the machine-id reported by the node
MachineID string `json:"machineID"`
// SystemUUID is the system-uuid reported by the node
SystemUUID string `json:"systemUUID"`
}

// NodeStatus is information about the current status of a node.
type NodeStatus struct {
// NodePhase is the current lifecycle phase of the node.
Expand All @@ -827,6 +835,17 @@ type NodeStatus struct {
Conditions []NodeCondition `json:"conditions,omitempty" description:"list of node conditions observed"`
// Queried from cloud provider, if available.
Addresses []NodeAddress `json:"addresses,omitempty" description:"list of addresses reachable to the node"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeInfo NodeSystemInfo `json:"nodeInfo,omitempty"`
}

// NodeInfo is the information collected on the node.
type NodeInfo struct {
TypeMeta `json:",inline"`
// Capacity represents the available resources of a node
Capacity ResourceList `json:"capacity,omitempty"`
// NodeSystemInfo is a set of ids/uuids to uniquely identify the node
NodeSystemInfo `json:",inline,omitempty"`
}

type NodePhase string
Expand Down
74 changes: 45 additions & 29 deletions pkg/client/kubelet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import (
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"

"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/probe"
httprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)

// ErrPodInfoNotAvailable may be returned when the requested pod info is not available.
Expand All @@ -37,6 +39,7 @@ var ErrPodInfoNotAvailable = errors.New("no pod info available")
type KubeletClient interface {
KubeletHealthChecker
PodInfoGetter
NodeInfoGetter
}

// KubeletHealthchecker is an interface for healthchecking kubelets
Expand All @@ -52,6 +55,10 @@ type PodInfoGetter interface {
GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error)
}

type NodeInfoGetter interface {
GetNodeInfo(host string) (api.NodeInfo, error)
}

// HTTPKubeletClient is the default implementation of PodInfoGetter and KubeletHealthchecker, accesses the kubelet over HTTP.
type HTTPKubeletClient struct {
Client *http.Client
Expand Down Expand Up @@ -85,57 +92,61 @@ func NewKubeletClient(config *KubeletConfig) (KubeletClient, error) {
}, nil
}

func (c *HTTPKubeletClient) url(host string) string {
scheme := "http://"
func (c *HTTPKubeletClient) url(host, path, query string) string {
scheme := "http"
if c.EnableHttps {
scheme = "https://"
scheme = "https"
}

return fmt.Sprintf(
"%s%s",
scheme,
net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)))
return (&url.URL{
Scheme: scheme,
Host: net.JoinHostPort(host, strconv.FormatUint(uint64(c.Port), 10)),
Path: path,
RawQuery: query,
}).String()
}

// GetPodInfo gets information about the specified pod.
func (c *HTTPKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) {
request, err := http.NewRequest(
"GET",
fmt.Sprintf(
"%s/api/v1beta1/podInfo?podID=%s&podNamespace=%s",
c.url(host),
podID,
podNamespace),
nil)
status := api.PodStatusResult{}
query := url.Values{"podID": {podID}, "podNamespace": {podNamespace}}
response, err := c.getEntity(host, "/api/v1beta1/podInfo", query.Encode(), &status)
if response.StatusCode == http.StatusNotFound {
return status, ErrPodInfoNotAvailable
}
return status, err
}

// GetNodeInfo gets information about the specified node.
func (c *HTTPKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
info := api.NodeInfo{}
_, err := c.getEntity(host, "/api/v1beta1/nodeInfo", "", &info)
return info, err
}

func (c *HTTPKubeletClient) getEntity(host, path, query string, entity runtime.Object) (*http.Response, error) {
request, err := http.NewRequest("GET", c.url(host, path, query), nil)
if err != nil {
return status, err
return nil, err
}
response, err := c.Client.Do(request)
if err != nil {
return status, err
return response, err
}
defer response.Body.Close()
if response.StatusCode == http.StatusNotFound {
return status, ErrPodInfoNotAvailable
}
if response.StatusCode >= 300 || response.StatusCode < 200 {
return status, fmt.Errorf("kubelet %q server responded with HTTP error code %d for pod %s/%s", host, response.StatusCode, podNamespace, podID)
return response, fmt.Errorf("kubelet %q server responded with HTTP error code %d", host, response.StatusCode)
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return status, err
return response, err
}
// Check that this data can be unmarshalled
err = latest.Codec.DecodeInto(body, &status)
if err != nil {
return status, err
}
return status, nil
err = latest.Codec.DecodeInto(body, entity)
return response, err
}

func (c *HTTPKubeletClient) HealthCheck(host string) (probe.Result, error) {
return httprobe.DoHTTPProbe(fmt.Sprintf("%s/healthz", c.url(host)), c.Client)
return httprobe.DoHTTPProbe(c.url(host, "/healthz", ""), c.Client)
}

// FakeKubeletClient is a fake implementation of KubeletClient which returns an error
Expand All @@ -148,6 +159,11 @@ func (c FakeKubeletClient) GetPodStatus(host, podNamespace string, podID string)
return api.PodStatusResult{}, errors.New("Not Implemented")
}

// GetNodeInfo is a fake implementation of PodInfoGetter.GetNodeInfo
func (c FakeKubeletClient) GetNodeInfo(host string) (api.NodeInfo, error) {
return api.NodeInfo{}, errors.New("Not Implemented")
}

func (c FakeKubeletClient) HealthCheck(host string) (probe.Result, error) {
return probe.Unknown, errors.New("Not Implemented")
}
Loading

0 comments on commit 9aa7449

Please sign in to comment.