diff --git a/api/v0/api.go b/api/v0/api.go index 405a6e5..2fcc122 100644 --- a/api/v0/api.go +++ b/api/v0/api.go @@ -32,6 +32,7 @@ type DeleteResponse struct { type ListResponse struct { Error *v2.Error `json:",omitempty"` StaticConfig []discovery.StaticConfig `json:",omitempty"` + Servers []string `json:",omitempty"` } // Network contains IPv4 and IPv6 addresses. diff --git a/handler/handler.go b/handler/handler.go index 0056bcf..e8c6ba6 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -347,32 +347,56 @@ func (s *Server) List(rw http.ResponseWriter, req *http.Request) { return } + format := req.URL.Query().Get("format") + // Create a prometheus StaticConfig for each known host. for i := range hosts { h, err := host.Parse(hosts[i]) if err != nil { continue } + if format == "script-exporter" { + // NOTE: do not assign any ports for script exporter. + ports[i] = []string{""} + } else { + // Convert port strings to ":". + p := []string{} + for j := range ports[i] { + p = append(p, ":"+ports[i][j]) + } + ports[i] = p + } for _, port := range ports[i] { + labels := map[string]string{ + "machine": hosts[i], + "type": "virtual", + "deployment": "byos", + "managed": "none", + "org": h.Org, + } + if req.URL.Query().Get("service") != "" { + labels["service"] = req.URL.Query().Get("service") + } // We create one record per host to add a unique "machine" label to each one. configs = append(configs, discovery.StaticConfig{ - Targets: []string{hosts[i] + ":" + port}, - Labels: map[string]string{ - "machine": hosts[i], - "type": "virtual", - "deployment": "byos", - "managed": "none", - "org": h.Org, - }, + Targets: []string{hosts[i] + port}, + Labels: labels, }) } } var results interface{} - format := req.URL.Query().Get("format") - if format == "prometheus" { + switch format { + case "script-exporter": + fallthrough + case "blackbox": + fallthrough + case "prometheus": // TODO(soltesz): retire this name. results = configs - } else { + case "servers": + resp.Servers = hosts + results = resp + default: // NOTE: default format is not valid for prometheus StaticConfig format. resp.StaticConfig = configs results = resp diff --git a/handler/handler_test.go b/handler/handler_test.go index 55fed02..33f64a9 100644 --- a/handler/handler_test.go +++ b/handler/handler_test.go @@ -576,11 +576,31 @@ func TestServer_List(t *testing.T) { params: "?format=prometheus", lister: &fakeStatusTracker{ nodes: []string{"test1"}, - ports: [][]string{[]string{}}, + ports: [][]string{{}}, }, wantCode: http.StatusOK, wantLength: 0, }, + { + name: "success-servers", + params: "?format=servers", + lister: &fakeStatusTracker{ + nodes: []string{"ndt-lga3356-040e9f4b.mlab.autojoin.measurement-lab.org"}, + ports: [][]string{{"9990"}}, + }, + wantCode: http.StatusOK, + wantLength: 1, + }, + { + name: "success-script-exporter", + params: "?format=script-exporter&service=ndt7_client_byos", + lister: &fakeStatusTracker{ + nodes: []string{"ndt-lga3356-040e9f4b.mlab.autojoin.measurement-lab.org"}, + ports: [][]string{{"9990"}}, + }, + wantCode: http.StatusOK, + wantLength: 1, + }, { name: "error-internal", params: "", @@ -606,17 +626,24 @@ func TestServer_List(t *testing.T) { var err error raw := rw.Body.Bytes() configs := []discovery.StaticConfig{} - if strings.Contains(tt.params, "prometheus") { + length := 0 + if strings.Contains(tt.params, "prometheus") || strings.Contains(tt.params, "script-exporter") { err = json.Unmarshal(raw, &configs) + length = len(configs) + } else if strings.Contains(tt.params, "servers") { + resp := v0.ListResponse{} + err = json.Unmarshal(raw, &resp) + length = len(resp.Servers) } else { resp := v0.ListResponse{} err = json.Unmarshal(raw, &resp) configs = resp.StaticConfig + length = len(configs) } testingx.Must(t, err, "failed to unmarshal response") - if len(configs) != tt.wantLength { - t.Errorf("List() returned wrong length; got %d, want %d", len(configs), tt.wantLength) + if length != tt.wantLength { + t.Errorf("List() returned wrong length; got %d, want %d", length, tt.wantLength) } }) }