small pixel drawing of a pufferfish cascade

api/service.go

package api

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
)

// AgentService describes a service registered on an agent. The JSON shape
// mirrors Consul's so existing SDKs round-trip cleanly.
type AgentService struct {
	ID      string
	Service string
	Tags    []string
	Address string
	Port    int
	Meta    map[string]string
}

// ServiceRegister registers a service with the local agent. The agent owns
// the entry and gossips it to the rest of the cluster.
func (a *Agent) ServiceRegister(svc *AgentService) error {
	body, err := json.Marshal(svc)
	if err != nil {
		return err
	}
	r := a.c.newRequest("PUT", "/v1/agent/service/register")
	r.body = bytes.NewReader(body)
	r.header.Set("Content-Type", "application/json")
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return err
	}
	defer closeResponseBody(resp)
	return nil
}

// ServiceDeregister removes a service the local agent owns.
func (a *Agent) ServiceDeregister(id string) error {
	r := a.c.newRequest("PUT", fmt.Sprintf("/v1/agent/service/deregister/%s", id))
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return err
	}
	defer closeResponseBody(resp)
	return nil
}

// Services lists services registered on the local agent.
func (a *Agent) Services() (map[string]*AgentService, error) {
	r := a.c.newRequest("GET", "/v1/agent/services")
	_, resp, err := requireOK(a.c.doRequest(r))
	if err != nil {
		return nil, err
	}
	defer closeResponseBody(resp)

	var out map[string]*AgentService
	if err := decodeJSONBody(resp.Body, &out); err != nil {
		return nil, err
	}
	return out, nil
}

func decodeJSONBody(body io.Reader, out interface{}) error {
	return json.NewDecoder(body).Decode(out)
}