small pixel drawing of a pufferfish cascade

api/agent.go

package api

// AgentMember represents a cluster member known to the agent
type AgentMember struct {
	Name string
	Addr string
	Port uint16
	Tags map[string]string
	// Status of the Member which corresponds to  github.com/hashicorp/serf/serf.MemberStatus
	// Value is one of:
	//
	// 	  AgentMemberNone    = 0
	//	  AgentMemberAlive   = 1
	//	  AgentMemberLeaving = 2
	//	  AgentMemberLeft    = 3
	//	  AgentMemberFailed  = 4
	Status      int
	ProtocolMin uint8
	ProtocolMax uint8
	ProtocolCur uint8
	DelegateMin uint8
	DelegateMax uint8
	DelegateCur uint8
}

func (am *AgentMember) StatusPretty() string {
	result := "unknown"
	switch am.Status {
	case 0:
		result = "none"
	case 1:
		result = "alive"
	case 2:
		result = "leaving"
	case 3:
		result = "left"
	case 4:
		result = "failed"
	}
	return result
}

// XXX: this may be needed for consul compatability, but I'm leaving it
// out for now in case it isn't.
const AllSegments = "_all"

// Agent can be used to query the Agent endpoints
type Agent struct {
	c *Client

	// cache the node name
	nodeName string
}

// Agent returns a handle to the agent endpoints
func (c *Client) Agent() *Agent {
	return &Agent{c: c}
}

// Self is used to query the agent we are speaking to for
// information about itself
func (a *Agent) Self() (map[string]map[string]interface{}, error) {
	r := a.c.newRequest("GET", "/v1/agent/self")
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return nil, err
	}
	defer closeResponseBody(resp)

	var out map[string]map[string]interface{}
	if err := decodeBody(resp, &out); err != nil {
		return nil, err
	}
	return out, nil
}

// Host is used to retrieve information about the host the
// agent is running on such as CPU, memory, and disk. Requires
// a operator:read ACL token.
func (a *Agent) Host() (map[string]interface{}, error) {
	r := a.c.newRequest("GET", "/v1/agent/host")
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return nil, err
	}
	defer closeResponseBody(resp)

	var out map[string]interface{}
	if err := decodeBody(resp, &out); err != nil {
		return nil, err
	}
	return out, nil
}

// NodeName is used to get the node name of the agent
func (a *Agent) NodeName() (string, error) {
	if a.nodeName != "" {
		return a.nodeName, nil
	}
	info, err := a.Self()
	if err != nil {
		return "", err
	}
	name := info["Config"]["NodeName"].(string)
	a.nodeName = name
	return name, nil
}

// Members returns the known serf gossip members
func (a *Agent) Members() ([]*AgentMember, error) {
	r := a.c.newRequest("GET", "/v1/agent/members")
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return nil, err
	}
	defer closeResponseBody(resp)

	var out []*AgentMember
	if err := decodeBody(resp, &out); err != nil {
		return nil, err
	}
	return out, nil
}