Search by labels and prefixes

Implemented in API and ctl.
This commit is contained in:
Adam Štrauch 2021-09-05 17:30:21 +02:00
parent b120970054
commit c6cb674053
Signed by: cx
GPG Key ID: 018304FFA8988F8D
5 changed files with 105 additions and 16 deletions

View File

@ -182,7 +182,7 @@ So far the REST API is super simple and it has only two endpoints:
GET / # Same as /v1/discoveries
GET /v1/discovery # Returns current local discovery packet
GET /v1/discoveries # Returns list of all discovered servers and their labels.
GET /v1/discoveries?labels=LABELS # output will be filtered based on one or multiple labels separated by comma
GET /v1/discoveries?labels=LABELS&prefixes=PREFIXES # output will be filtered based on one or multiple labels separated by comma or it can search for given prefixes, only one of those will be used
GET /v1/prometheus/:name # Generates output for Prometheus's SD config, name is group of the monitoring services described above.
POST /v1/labels # Add runtime labels that will persist over daemon restarts. Labels should be in the body of the request, one line per one label.
DELETE /v1/labels # Delete runtime labels. One label per line. Can't affect the labels from environment variables or labels added from the LabelPath.

View File

@ -115,13 +115,38 @@ func (l *LobbyClient) GetDiscoveries() ([]server.Discovery, error) {
}
// Find discoveries by their labels
func (l *LobbyClient) FindByLabels(labels server.Labels) (server.Discoveries, error) {
func (l *LobbyClient) FindByLabels(labels server.Labels) ([]server.Discovery, error) {
l.init()
path := fmt.Sprintf("/v1/discoveries?labels=%s", strings.Join(labels.StringSlice(), ","))
method := "GET"
var discoveries server.Discoveries
var discoveries []server.Discovery
status, body, err := l.call(method, path, "")
if err != nil {
return discoveries, err
}
if status != 200 {
return discoveries, fmt.Errorf("non-200 response: %s", body)
}
err = json.Unmarshal([]byte(body), &discoveries)
if err != nil {
return discoveries, fmt.Errorf("response parsing error: %v", err)
}
return discoveries, nil
}
// Find discoveries by label prefixes
func (l *LobbyClient) FindByPrefixes(prefixes []string) ([]server.Discovery, error) {
l.init()
path := fmt.Sprintf("/v1/discoveries?prefixes=%s", strings.Join(prefixes, ","))
method := "GET"
var discoveries []server.Discovery
status, body, err := l.call(method, path, "")
if err != nil {

View File

@ -16,6 +16,8 @@ func Usage() {
fmt.Println("Commands:")
fmt.Println(" discovery returns discovery packet of the server where the client is connected to")
fmt.Println(" discoveries returns list of all registered discovery packets")
fmt.Println(" discoveries labels [LABEL] ... returns list of all registered discovery packets with given labels (OR)")
fmt.Println(" discoveries search [LABEL] ... returns list of all registered discovery packets with given label prefixes (OR)")
fmt.Println(" labels add LABEL [LABEL] ... adds new runtime labels")
fmt.Println(" labels del LABEL [LABEL] ... deletes runtime labels")
}
@ -66,10 +68,41 @@ func main() {
switch flag.Args()[0] {
case "discoveries":
discoveries, err := client.GetDiscoveries()
var discoveries []server.Discovery
var err error
if len(flag.Args()) > 2 {
if flag.Arg(1) == "labels" {
labels := []server.Label{}
for _, label := range flag.Args()[2:] {
labels = append(labels, server.Label(label))
}
discoveries, err = client.FindByLabels(labels)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
} else if flag.Arg(1) == "search" {
discoveries, err = client.FindByPrefixes(flag.Args()[2:])
if err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
fmt.Println("ERROR: unknown usage of discoveries arguments")
fmt.Println("")
Usage()
os.Exit(0)
}
} else {
discoveries, err = client.GetDiscoveries()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
printDiscoveries(discoveries)
case "discovery":
discovery, err := client.GetDiscovery()

View File

@ -12,12 +12,15 @@ import (
func listHandler(c echo.Context) error {
labels := c.QueryParam("labels")
prefixes := c.QueryParam("prefixes")
var discoveries []server.Discovery
if len(labels) > 0 {
labelsFilterSlice := strings.Split(labels, ",")
discoveries = discoveryStorage.Filter(labelsFilterSlice)
} else if len(prefixes) > 0 {
discoveries = discoveryStorage.FilterPrefix(strings.Split(prefixes, ","))
} else {
discoveries = discoveryStorage.GetAll()
}

View File

@ -148,6 +148,7 @@ func (d *Discoveries) GetAll() []Discovery {
return d.activeServers
}
// Filter returns list of discoveries based on given labels
func (d *Discoveries) Filter(labelsFilter []string) []Discovery {
newSet := []Discovery{}
@ -174,6 +175,33 @@ func (d *Discoveries) Filter(labelsFilter []string) []Discovery {
return newSet
}
// Filter returns list of discoveries based on given label prefixes.
func (d *Discoveries) FilterPrefix(prefixes []string) []Discovery {
newSet := []Discovery{}
var found bool
if len(prefixes) > 0 {
for _, discovery := range d.activeServers {
found = false
for _, label := range discovery.Labels {
for _, prefix := range prefixes {
if strings.HasPrefix(label.String(), prefix) {
newSet = append(newSet, discovery)
found = true
break
}
}
if found {
break
}
}
}
}
return newSet
}
// Clean checks loops over last check values for each discovery object and removes it if it's passed
func (d *Discoveries) Clean() {
newSet := []Discovery{}