mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package gce
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"sync"
|
|
"time"
|
|
|
|
"golang.org/x/oauth2/google"
|
|
)
|
|
|
|
type apiConfig struct {
|
|
client *http.Client
|
|
apiURL string
|
|
project string
|
|
tagSeparator string
|
|
port int
|
|
}
|
|
|
|
func getAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
|
apiConfigMapLock.Lock()
|
|
defer apiConfigMapLock.Unlock()
|
|
|
|
if !hasAPIConfigMapCleaner {
|
|
hasAPIConfigMapCleaner = true
|
|
go apiConfigMapCleaner()
|
|
}
|
|
|
|
e := apiConfigMap[sdc]
|
|
if e != nil {
|
|
e.lastAccessTime = time.Now()
|
|
return e.cfg, nil
|
|
}
|
|
cfg, err := newAPIConfig(sdc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
apiConfigMap[sdc] = &apiConfigMapEntry{
|
|
cfg: cfg,
|
|
lastAccessTime: time.Now(),
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func apiConfigMapCleaner() {
|
|
tc := time.NewTicker(15 * time.Minute)
|
|
for currentTime := range tc.C {
|
|
apiConfigMapLock.Lock()
|
|
for k, e := range apiConfigMap {
|
|
if currentTime.Sub(e.lastAccessTime) > 10*time.Minute {
|
|
delete(apiConfigMap, k)
|
|
}
|
|
}
|
|
apiConfigMapLock.Unlock()
|
|
}
|
|
}
|
|
|
|
type apiConfigMapEntry struct {
|
|
cfg *apiConfig
|
|
lastAccessTime time.Time
|
|
}
|
|
|
|
var (
|
|
apiConfigMap = make(map[*SDConfig]*apiConfigMapEntry)
|
|
apiConfigMapLock sync.Mutex
|
|
hasAPIConfigMapCleaner bool
|
|
)
|
|
|
|
func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
|
|
ctx := context.Background()
|
|
client, err := google.DefaultClient(ctx, "https://www.googleapis.com/auth/compute.readonly")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot create oauth2 client for gce: %s", err)
|
|
}
|
|
// See https://cloud.google.com/compute/docs/reference/rest/v1/instances/list
|
|
apiURL := fmt.Sprintf("https://compute.googleapis.com/compute/v1/projects/%s/zones/%s/instances", sdc.Project, sdc.Zone)
|
|
if len(sdc.Filter) > 0 {
|
|
apiURL += fmt.Sprintf("?filter=%s", url.QueryEscape(sdc.Filter))
|
|
}
|
|
tagSeparator := ","
|
|
if sdc.TagSeparator != nil {
|
|
tagSeparator = *sdc.TagSeparator
|
|
}
|
|
port := 80
|
|
if sdc.Port != nil {
|
|
port = *sdc.Port
|
|
}
|
|
return &apiConfig{
|
|
client: client,
|
|
apiURL: apiURL,
|
|
project: sdc.Project,
|
|
tagSeparator: tagSeparator,
|
|
port: port,
|
|
}, nil
|
|
}
|