VictoriaMetrics/lib/promscrape/discovery/vultr/instance.go

110 lines
3.6 KiB
Go
Raw Normal View History

feature: [vmagent] Add service discovery support for Vultr (#6068) ### Describe Your Changes related issue: https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6041 #### Added - Added service discovery support for Vultr. #### Docs - `CHANGELOG.md`, `sd_configs.md`, `vmagent.md` are updated. #### Note - Useful links: - Vultr API: https://www.vultr.com/api/#tag/instances/operation/list-instances - Vultr client SDK: https://github.com/vultr/govultr - Prometheus SD: https://github.com/prometheus/prometheus/tree/main/discovery/vultr --- ### Checklist The following checks are mandatory: - [X] I have read the [Contributing Guidelines](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/CONTRIBUTING.md) - [x] All commits are signed and include `Signed-off-by` line. Use `git commit -s` to include `Signed-off-by` your commits. See this [doc](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work) about how to sign your commits. - [x] Tests are passing locally. Use `make test` to run all tests locally. - [x] Linting is passing locally. Use `make check-all` to run all linters locally. Further checks are optional for External Contributions: - [X] Include a link to the GitHub issue in the commit message, if issue exists. - [x] Mention the change in the [Changelog](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/docs/CHANGELOG.md). Explain what has changed and why. If there is a related issue or documentation change - link them as well. Tips for writing a good changelog message:: * Write a human-readable changelog message that describes the problem and solution. * Include a link to the issue or pull request in your changelog message. * Use specific language identifying the fix, such as an error message, metric name, or flag name. * Provide a link to the relevant documentation for any new features you add or modify. - [ ] After your pull request is merged, please add a message to the issue with instructions for how to test the fix or try the feature you added. Here is an [example](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4048#issuecomment-1546453726) - [x] Do not close the original issue before the change is released. Please note, in some cases Github can automatically close the issue once PR is merged. Re-open the issue in such case. - [x] If the change somehow affects public interfaces (a new flag was added or updated, or some behavior has changed) - add the corresponding change to documentation. Signed-off-by: Jiekun <jiekun.dev@gmail.com> (cherry picked from commit 17e3d019d2dbe6cd3ae565ae55dce702409a3215)
2024-05-08 08:01:48 +00:00
package vultr
import (
"encoding/json"
"fmt"
"net/url"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
)
// ListInstanceResponse is the response structure of Vultr ListInstance API.
type ListInstanceResponse struct {
Instances []Instance `json:"instances"`
Meta *Meta `json:"Meta"`
}
// Instance represents Vultr Instance (VPS).
// See: https://github.com/vultr/govultr/blob/5125e02e715ae6eb3ce854f0e7116c7ce545a710/instance.go#L81
type Instance struct {
ID string `json:"id"`
Os string `json:"os"`
RAM int `json:"ram"`
Disk int `json:"disk"`
MainIP string `json:"main_ip"`
VCPUCount int `json:"vcpu_count"`
Region string `json:"region"`
ServerStatus string `json:"server_status"`
AllowedBandwidth int `json:"allowed_bandwidth"`
V6MainIP string `json:"v6_main_ip"`
Hostname string `json:"hostname"`
Label string `json:"label"`
InternalIP string `json:"internal_ip"`
OsID int `json:"os_id"`
Features []string `json:"features"`
Plan string `json:"plan"`
Tags []string `json:"tags"`
// The following fields are defined in the response but are not used during service discovery.
//DefaultPassword string `json:"default_password,omitempty"`
//DateCreated string `json:"date_created"`
//Status string `json:"status"`
//PowerStatus string `json:"power_status"`
//NetmaskV4 string `json:"netmask_v4"`
//GatewayV4 string `json:"gateway_v4"`
//V6Network string `json:"v6_network"`
//V6NetworkSize int `json:"v6_network_size"`
//// Deprecated: Tag should no longer be used. Instead, use Tags.
//Tag string `json:"tag"`
//KVM string `json:"kvm"`
//AppID int `json:"app_id"`
//ImageID string `json:"image_id"`
//FirewallGroupID string `json:"firewall_group_id"`
//UserScheme string `json:"user_scheme"`
}
// Meta represents the available pagination information
type Meta struct {
Total int `json:"total"`
Links *Links
}
// Links represent the next/previous cursor in your pagination calls
type Links struct {
Next string `json:"next"`
Prev string `json:"prev"`
}
// getInstances retrieve instance from Vultr HTTP API.
func getInstances(cfg *apiConfig) ([]Instance, error) {
var instances []Instance
// prepare GET params
params := url.Values{}
params.Set("per_page", "100")
params.Set("label", cfg.label)
params.Set("main_ip", cfg.mainIP)
params.Set("region", cfg.region)
params.Set("firewall_group_id", cfg.firewallGroupID)
params.Set("hostname", cfg.hostname)
// send request to vultr API
for {
// See: https://www.vultr.com/api/#tag/instances/operation/list-instances
path := fmt.Sprintf("/v2/instances?%s", params.Encode())
resp, err := cfg.c.GetAPIResponse(path)
if err != nil {
logger.Errorf("get response from vultr failed, path:%s, err: %v", path, err)
return nil, err
}
var listInstanceResp ListInstanceResponse
if err = json.Unmarshal(resp, &listInstanceResp); err != nil {
logger.Errorf("unmarshal response from vultr failed, err: %v", err)
return nil, err
}
instances = append(instances, listInstanceResp.Instances...)
if listInstanceResp.Meta != nil && listInstanceResp.Meta.Links != nil && listInstanceResp.Meta.Links.Next != "" {
// if `next page` is available, set the cursor param and request again.
params.Set("cursor", listInstanceResp.Meta.Links.Next)
} else {
// otherwise exit the loop
break
}
}
return instances, nil
}