From d0e447d29b4a5763055eaa3537aa338309942dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Tisa=CC=88ter?= Date: Mon, 26 May 2014 01:59:48 +0200 Subject: [PATCH 1/2] Add `/v1/agent/self` and return local agent config --- command/agent/agent.go | 5 ++++ command/agent/agent_endpoint.go | 4 +++ command/agent/agent_endpoint_test.go | 22 ++++++++++++++ command/agent/http.go | 1 + command/agent/http_api.md | 3 +- consul/server.go | 5 ++++ website/source/docs/agent/http.html.markdown | 31 +++++++++++++++++++- 7 files changed, 69 insertions(+), 2 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index e96ed228e4..c57e45b664 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -311,6 +311,11 @@ func (a *Agent) ForceLeave(node string) (err error) { return err } +// LocalMember is used to return the local node +func (a *Agent) LocalMember() serf.Member { + return a.server.LocalMember() +} + // LANMembers is used to retrieve the LAN members func (a *Agent) LANMembers() []serf.Member { if a.server != nil { diff --git a/command/agent/agent_endpoint.go b/command/agent/agent_endpoint.go index f4b9c06d72..f5eeda8d47 100644 --- a/command/agent/agent_endpoint.go +++ b/command/agent/agent_endpoint.go @@ -7,6 +7,10 @@ import ( "strings" ) +func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) { + return s.agent.LocalMember(), nil +} + func (s *HTTPServer) AgentServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) { services := s.agent.state.Services() return services, nil diff --git a/command/agent/agent_endpoint_test.go b/command/agent/agent_endpoint_test.go index c106496722..71bc9c3055 100644 --- a/command/agent/agent_endpoint_test.go +++ b/command/agent/agent_endpoint_test.go @@ -66,6 +66,28 @@ func TestHTTPAgentChecks(t *testing.T) { } } +func TestHTTPAgentSelf(t *testing.T) { + dir, srv := makeHTTPServer(t) + defer os.RemoveAll(dir) + defer srv.Shutdown() + defer srv.agent.Shutdown() + + req, err := http.NewRequest("GET", "/v1/agent/self", nil) + if err != nil { + t.Fatalf("err: %v", err) + } + + obj, err := srv.AgentSelf(nil, req) + if err != nil { + t.Fatalf("Err: %v", err) + } + + val := obj.(serf.Member) + if int(val.Port) != srv.agent.config.Ports.SerfLan { + t.Fatalf("incorrect port: %v", obj) + } +} + func TestHTTPAgentMembers(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) diff --git a/command/agent/http.go b/command/agent/http.go index c44c049804..792055b6bf 100644 --- a/command/agent/http.go +++ b/command/agent/http.go @@ -76,6 +76,7 @@ func (s *HTTPServer) registerHandlers(enableDebug bool) { s.mux.HandleFunc("/v1/health/state/", s.wrap(s.HealthChecksInState)) s.mux.HandleFunc("/v1/health/service/", s.wrap(s.HealthServiceNodes)) + s.mux.HandleFunc("/v1/agent/self", s.wrap(s.AgentSelf)) s.mux.HandleFunc("/v1/agent/services", s.wrap(s.AgentServices)) s.mux.HandleFunc("/v1/agent/checks", s.wrap(s.AgentChecks)) s.mux.HandleFunc("/v1/agent/members", s.wrap(s.AgentMembers)) diff --git a/command/agent/http_api.md b/command/agent/http_api.md index ff379faac6..d35c17e421 100644 --- a/command/agent/http_api.md +++ b/command/agent/http_api.md @@ -28,7 +28,8 @@ Status: * /v1/status/peers : Returns the current Raft peer set Agent: -* /v1/agent/checks: Returns the checks the local agent is managing +* /v1/agent/self : Returns the local configuration +* /v1/agent/checks : Returns the checks the local agent is managing * /v1/agent/services : Returns the services local agent is managing * /v1/agent/members : Returns the members as seen by the local serf agent * /v1/agent/join/ : Instructs the local agent to join a node diff --git a/consul/server.go b/consul/server.go index e8fcd4655c..9e73a2b66c 100644 --- a/consul/server.go +++ b/consul/server.go @@ -484,6 +484,11 @@ func (s *Server) JoinWAN(addrs []string) (int, error) { return s.serfWAN.Join(addrs, true) } +// LocalMember is used to return the local node +func (c *Server) LocalMember() serf.Member { + return c.serfLAN.LocalMember() +} + // LANMembers is used to return the members of the LAN cluster func (s *Server) LANMembers() []serf.Member { return s.serfLAN.Members() diff --git a/website/source/docs/agent/http.html.markdown b/website/source/docs/agent/http.html.markdown index 4c8dfd92a6..db375b8e91 100644 --- a/website/source/docs/agent/http.html.markdown +++ b/website/source/docs/agent/http.html.markdown @@ -200,7 +200,8 @@ msgpack RPC protocol. The following endpoints are supported: -* /v1/agent/checks: Returns the checks the local agent is managing +* /v1/agent/self : Returns the local node configuration +* /v1/agent/checks : Returns the checks the local agent is managing * /v1/agent/services : Returns the services local agent is managing * /v1/agent/members : Returns the members as seen by the local serf agent * /v1/agent/join/\ : Trigger local agent to join a node @@ -213,6 +214,34 @@ The following endpoints are supported: * /v1/agent/service/register : Registers a new local service * /v1/agent/service/deregister/\ : Deregister a local service +### /v1/agent/self + +This endpoint is used to return configuration of the local agent. + +It returns a JSON body like this: + + { + "Name": "foobar", + "Addr": "10.1.10.12", + "Port": 8301, + "Tags": { + "bootstrap": "1", + "dc": "dc1", + "port": "8300", + "role": "consul", + "vsn": "1", + "vsn_max": "1", + "vsn_min":"1" + }, + "Status": 1, + "ProtocolMin": 1, + "ProtocolMax": 2, + "ProtocolCur": 2, + "DelegateMin": 2, + "DelegateMax": 4, + "DelegateCur": 4 + } + ### /v1/agent/checks This endpoint is used to return the all the checks that are registered with From d794a187613538dc89842617fb9c267a59c99234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Tisa=CC=88ter?= Date: Wed, 28 May 2014 00:09:28 +0200 Subject: [PATCH 2/2] Return both member and config in `/v1/agent/self` --- command/agent/agent_endpoint.go | 11 +- command/agent/agent_endpoint_test.go | 8 +- website/source/docs/agent/http.html.markdown | 101 +++++++++++++------ 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/command/agent/agent_endpoint.go b/command/agent/agent_endpoint.go index f5eeda8d47..2edee0c09d 100644 --- a/command/agent/agent_endpoint.go +++ b/command/agent/agent_endpoint.go @@ -3,12 +3,21 @@ package agent import ( "fmt" "github.com/hashicorp/consul/consul/structs" + "github.com/hashicorp/serf/serf" "net/http" "strings" ) +type AgentSelf struct { + Config *Config + Member serf.Member +} + func (s *HTTPServer) AgentSelf(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - return s.agent.LocalMember(), nil + return AgentSelf{ + Config: s.agent.config, + Member: s.agent.LocalMember(), + }, nil } func (s *HTTPServer) AgentServices(resp http.ResponseWriter, req *http.Request) (interface{}, error) { diff --git a/command/agent/agent_endpoint_test.go b/command/agent/agent_endpoint_test.go index 71bc9c3055..73682a9cc4 100644 --- a/command/agent/agent_endpoint_test.go +++ b/command/agent/agent_endpoint_test.go @@ -82,8 +82,12 @@ func TestHTTPAgentSelf(t *testing.T) { t.Fatalf("Err: %v", err) } - val := obj.(serf.Member) - if int(val.Port) != srv.agent.config.Ports.SerfLan { + val := obj.(AgentSelf) + if int(val.Member.Port) != srv.agent.config.Ports.SerfLan { + t.Fatalf("incorrect port: %v", obj) + } + + if int(val.Config.Ports.SerfLan) != srv.agent.config.Ports.SerfLan { t.Fatalf("incorrect port: %v", obj) } } diff --git a/website/source/docs/agent/http.html.markdown b/website/source/docs/agent/http.html.markdown index db375b8e91..34a45f4731 100644 --- a/website/source/docs/agent/http.html.markdown +++ b/website/source/docs/agent/http.html.markdown @@ -200,10 +200,10 @@ msgpack RPC protocol. The following endpoints are supported: -* /v1/agent/self : Returns the local node configuration * /v1/agent/checks : Returns the checks the local agent is managing * /v1/agent/services : Returns the services local agent is managing * /v1/agent/members : Returns the members as seen by the local serf agent +* /v1/agent/self : Returns the local node configuration * /v1/agent/join/\ : Trigger local agent to join a node * /v1/agent/force-leave/\: Force remove node * /v1/agent/check/register : Registers a new local check @@ -214,34 +214,6 @@ The following endpoints are supported: * /v1/agent/service/register : Registers a new local service * /v1/agent/service/deregister/\ : Deregister a local service -### /v1/agent/self - -This endpoint is used to return configuration of the local agent. - -It returns a JSON body like this: - - { - "Name": "foobar", - "Addr": "10.1.10.12", - "Port": 8301, - "Tags": { - "bootstrap": "1", - "dc": "dc1", - "port": "8300", - "role": "consul", - "vsn": "1", - "vsn_max": "1", - "vsn_min":"1" - }, - "Status": 1, - "ProtocolMin": 1, - "ProtocolMax": 2, - "ProtocolCur": 2, - "DelegateMin": 2, - "DelegateMax": 4, - "DelegateCur": 4 - } - ### /v1/agent/checks This endpoint is used to return the all the checks that are registered with @@ -319,6 +291,77 @@ This endpoint returns a JSON body like: } ] +### /v1/agent/self + +This endpoint is used to return configuration of the local agent and member information. + +It returns a JSON body like this: + + { + "Config": { + "Bootstrap": true, + "Server": true, + "Datacenter": "dc1", + "DataDir": "/tmp/consul", + "DNSRecursor": "", + "Domain": "consul.", + "EncryptKey": "", + "LogLevel": "INFO", + "NodeName": "foobar", + "ClientAddr": "127.0.0.1", + "BindAddr": "0.0.0.0", + "AdvertiseAddr": "10.1.10.12", + "Ports": { + "DNS": 8600, + "HTTP": 8500, + "RPC": 8400, + "SerfLan": 8301, + "SerfWan": 8302, + "Server": 8300 + }, + "LeaveOnTerm": false, + "SkipLeaveOnInt": false, + "StatsiteAddr": "", + "Protocol": 1, + "EnableDebug": false, + "VerifyIncoming": false, + "VerifyOutgoing": false, + "CAFile": "", + "CertFile": "", + "KeyFile": "", + "StartJoin": [], + "UiDir": "", + "PidFile": "", + "EnableSyslog": false, + "RejoinAfterLeave": false, + "AEInterval": 60000000000, + "Checks": null, + "Services": null, + "ConsulConfig": null + }, + "Member": { + "Name": "foobar", + "Addr": "10.1.10.12", + "Port": 8301, + "Tags": { + "bootstrap": "1", + "dc": "dc1", + "port": "8300", + "role": "consul", + "vsn": "1", + "vsn_max": "1", + "vsn_min": "1" + }, + "Status": 1, + "ProtocolMin": 1, + "ProtocolMax": 2, + "ProtocolCur": 2, + "DelegateMin": 2, + "DelegateMax": 4, + "DelegateCur": 4 + } + } + ### /v1/agent/join/\ This endpoint is hit with a GET and is used to instruct the agent to attempt to