|
|
@@ -86,6 +86,7 @@ var (
|
|
|
type Accesses struct {
|
|
|
Router *httprouter.Router
|
|
|
PrometheusClient prometheus.Client
|
|
|
+ PrometheusScrapeClient prometheus.Client
|
|
|
ThanosClient prometheus.Client
|
|
|
KubeClientSet kubernetes.Interface
|
|
|
ClusterCache clustercache.ClusterCache
|
|
|
@@ -1132,7 +1133,7 @@ func (a *Accesses) PrometheusConfig(w http.ResponseWriter, r *http.Request, _ ht
|
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
|
|
|
|
pConfig := map[string]string{
|
|
|
- "address": env.GetPrometheusServerEndpoint(),
|
|
|
+ "address": env.GetPrometheusEndpoints()[env.Scrape],
|
|
|
}
|
|
|
|
|
|
body, err := json.Marshal(pConfig)
|
|
|
@@ -1407,15 +1408,19 @@ func (a *Accesses) Status(w http.ResponseWriter, r *http.Request, _ httprouter.P
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
|
|
|
|
- promServer := env.GetPrometheusServerEndpoint()
|
|
|
+ endpoints := env.GetPrometheusEndpoints()
|
|
|
+ scrapeServer, ok := endpoints[env.Scrape]
|
|
|
+ if !ok {
|
|
|
+ scrapeServer = endpoints[env.Server]
|
|
|
+ }
|
|
|
|
|
|
- api := prometheusAPI.NewAPI(a.PrometheusClient)
|
|
|
+ api := prometheusAPI.NewAPI(a.PrometheusScrapeClient)
|
|
|
result, err := api.Config(r.Context())
|
|
|
if err != nil {
|
|
|
- fmt.Fprintf(w, "Using Prometheus at "+promServer+". Error: "+err.Error())
|
|
|
+ fmt.Fprintf(w, "Using Prometheus at "+scrapeServer+". Error: "+err.Error())
|
|
|
} else {
|
|
|
|
|
|
- fmt.Fprintf(w, "Using Prometheus at "+promServer+". PrometheusConfig: "+result.YAML)
|
|
|
+ fmt.Fprintf(w, "Using Prometheus at "+scrapeServer+". PrometheusConfig: "+result.YAML)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1506,8 +1511,8 @@ func Initialize(additionalConfigWatchers ...*watcher.ConfigMapWatcher) *Accesses
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- address := env.GetPrometheusServerEndpoint()
|
|
|
- if address == "" {
|
|
|
+ promAddrs := env.GetPrometheusEndpoints()
|
|
|
+ if promAddrs[env.Server] == "" {
|
|
|
log.Fatalf("No address for prometheus set in $%s. Aborting.", env.PrometheusServerEndpointEnvVar)
|
|
|
}
|
|
|
|
|
|
@@ -1527,46 +1532,53 @@ func Initialize(additionalConfigWatchers ...*watcher.ConfigMapWatcher) *Accesses
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- promCli, err := prom.NewPrometheusClient(address, &prom.PrometheusClientConfig{
|
|
|
- Timeout: timeout,
|
|
|
- KeepAlive: keepAlive,
|
|
|
- TLSHandshakeTimeout: tlsHandshakeTimeout,
|
|
|
- TLSInsecureSkipVerify: env.GetInsecureSkipVerify(),
|
|
|
- RateLimitRetryOpts: rateLimitRetryOpts,
|
|
|
- Auth: &prom.ClientAuth{
|
|
|
- Username: env.GetDBBasicAuthUsername(),
|
|
|
- Password: env.GetDBBasicAuthUserPassword(),
|
|
|
- BearerToken: env.GetDBBearerToken(),
|
|
|
- },
|
|
|
- QueryConcurrency: queryConcurrency,
|
|
|
- QueryLogFile: "",
|
|
|
- HeaderXScopeOrgId: env.GetPrometheusHeaderXScopeOrgId(),
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- log.Fatalf("Failed to create prometheus client, Error: %v", err)
|
|
|
- }
|
|
|
-
|
|
|
- m, err := prom.Validate(promCli)
|
|
|
- if err != nil || !m.Running {
|
|
|
+ promClis := map[env.PrometheusType]prometheus.Client{}
|
|
|
+ for clientName, addr := range promAddrs {
|
|
|
+ promClis[clientName], err = prom.NewPrometheusClient(addr, &prom.PrometheusClientConfig{
|
|
|
+ Timeout: timeout,
|
|
|
+ KeepAlive: keepAlive,
|
|
|
+ TLSHandshakeTimeout: tlsHandshakeTimeout,
|
|
|
+ TLSInsecureSkipVerify: env.GetInsecureSkipVerify(clientName),
|
|
|
+ RateLimitRetryOpts: rateLimitRetryOpts,
|
|
|
+ Auth: &prom.ClientAuth{
|
|
|
+ Username: env.GetDBBasicAuthUsername(clientName),
|
|
|
+ Password: env.GetDBBasicAuthUserPassword(clientName),
|
|
|
+ BearerToken: env.GetDBBearerToken(clientName),
|
|
|
+ },
|
|
|
+ QueryConcurrency: queryConcurrency,
|
|
|
+ QueryLogFile: "",
|
|
|
+ HeaderXScopeOrgId: env.GetPrometheusHeaderXScopeOrgId(clientName),
|
|
|
+ })
|
|
|
if err != nil {
|
|
|
- log.Errorf("Failed to query prometheus at %s. Error: %s . Troubleshooting help available at: %s", address, err.Error(), prom.PrometheusTroubleshootingURL)
|
|
|
- } else if !m.Running {
|
|
|
- log.Errorf("Prometheus at %s is not running. Troubleshooting help available at: %s", address, prom.PrometheusTroubleshootingURL)
|
|
|
+ log.Fatalf("Failed to create prometheus client, Error: %v", err)
|
|
|
+ }
|
|
|
+ m, err := prom.Validate(promClis[clientName])
|
|
|
+ if err != nil || !m.Running {
|
|
|
+ if err != nil {
|
|
|
+ log.Errorf("Failed to query prometheus at %s. Error: %s . Troubleshooting help available at: %s", addr, err.Error(), prom.PrometheusTroubleshootingURL)
|
|
|
+ } else if !m.Running {
|
|
|
+ log.Errorf("Prometheus at %s is not running. Troubleshooting help available at: %s", addr, prom.PrometheusTroubleshootingURL)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.Infof("Success: retrieved the 'up' query against prometheus at: " + addr)
|
|
|
}
|
|
|
- } else {
|
|
|
- log.Infof("Success: retrieved the 'up' query against prometheus at: " + address)
|
|
|
}
|
|
|
-
|
|
|
- api := prometheusAPI.NewAPI(promCli)
|
|
|
+ scrapeKey := env.Scrape
|
|
|
+ promScrapeCli, ok := promClis[env.Scrape]
|
|
|
+ if !ok {
|
|
|
+ promScrapeCli = promClis[env.Server]
|
|
|
+ scrapeKey = env.Server
|
|
|
+ }
|
|
|
+ api := prometheusAPI.NewAPI(promScrapeCli)
|
|
|
_, err = api.Config(context.Background())
|
|
|
if err != nil {
|
|
|
- log.Infof("No valid prometheus config file at %s. Error: %s . Troubleshooting help available at: %s. Ignore if using cortex/mimir/thanos here.", address, err.Error(), prom.PrometheusTroubleshootingURL)
|
|
|
+ log.Infof("No valid prometheus config file at %s. Error: %s . Troubleshooting help available at: %s. Ignore if using cortex/mimir/thanos here.", promAddrs[scrapeKey], err.Error(), prom.PrometheusTroubleshootingURL)
|
|
|
} else {
|
|
|
- log.Infof("Retrieved a prometheus config file from: %s", address)
|
|
|
+ log.Infof("Retrieved a prometheus config file from: %s", promAddrs[scrapeKey])
|
|
|
}
|
|
|
|
|
|
// Lookup scrape interval for kubecost job, update if found
|
|
|
- si, err := prom.ScrapeIntervalFor(promCli, env.GetKubecostJobName())
|
|
|
+ si, err := prom.ScrapeIntervalFor(promClis[env.Server], env.GetKubecostJobName())
|
|
|
if err == nil {
|
|
|
scrapeInterval = si
|
|
|
}
|
|
|
@@ -1647,7 +1659,7 @@ func Initialize(additionalConfigWatchers ...*watcher.ConfigMapWatcher) *Accesses
|
|
|
Timeout: timeout,
|
|
|
KeepAlive: keepAlive,
|
|
|
TLSHandshakeTimeout: tlsHandshakeTimeout,
|
|
|
- TLSInsecureSkipVerify: env.GetInsecureSkipVerify(),
|
|
|
+ TLSInsecureSkipVerify: env.GetInsecureSkipVerify(env.Server),
|
|
|
RateLimitRetryOpts: rateLimitRetryOpts,
|
|
|
Auth: &prom.ClientAuth{
|
|
|
Username: env.GetMultiClusterBasicAuthUsername(),
|
|
|
@@ -1687,7 +1699,7 @@ func Initialize(additionalConfigWatchers ...*watcher.ConfigMapWatcher) *Accesses
|
|
|
if thanosClient != nil {
|
|
|
clusterMap = clusters.NewClusterMap(thanosClient, clusterInfoProvider, 10*time.Minute)
|
|
|
} else {
|
|
|
- clusterMap = clusters.NewClusterMap(promCli, clusterInfoProvider, 5*time.Minute)
|
|
|
+ clusterMap = clusters.NewClusterMap(promClis[env.Server], clusterInfoProvider, 5*time.Minute)
|
|
|
}
|
|
|
|
|
|
// cache responses from model and aggregation for a default of 10 minutes;
|
|
|
@@ -1713,31 +1725,32 @@ func Initialize(additionalConfigWatchers ...*watcher.ConfigMapWatcher) *Accesses
|
|
|
if thanosClient != nil {
|
|
|
pc = thanosClient
|
|
|
} else {
|
|
|
- pc = promCli
|
|
|
+ pc = promClis[env.Server]
|
|
|
}
|
|
|
costModel := NewCostModel(pc, cloudProvider, k8sCache, clusterMap, scrapeInterval)
|
|
|
- metricsEmitter := NewCostModelMetricsEmitter(promCli, k8sCache, cloudProvider, clusterInfoProvider, costModel)
|
|
|
+ metricsEmitter := NewCostModelMetricsEmitter(promClis[env.Server], k8sCache, cloudProvider, clusterInfoProvider, costModel)
|
|
|
|
|
|
a := &Accesses{
|
|
|
- Router: httprouter.New(),
|
|
|
- PrometheusClient: promCli,
|
|
|
- ThanosClient: thanosClient,
|
|
|
- KubeClientSet: kubeClientset,
|
|
|
- ClusterCache: k8sCache,
|
|
|
- ClusterMap: clusterMap,
|
|
|
- CloudProvider: cloudProvider,
|
|
|
- CloudConfigController: cloudconfig.NewController(cloudProvider),
|
|
|
- ConfigFileManager: confManager,
|
|
|
- ClusterInfoProvider: clusterInfoProvider,
|
|
|
- Model: costModel,
|
|
|
- MetricsEmitter: metricsEmitter,
|
|
|
- AggregateCache: aggregateCache,
|
|
|
- CostDataCache: costDataCache,
|
|
|
- ClusterCostsCache: clusterCostsCache,
|
|
|
- OutOfClusterCache: outOfClusterCache,
|
|
|
- SettingsCache: settingsCache,
|
|
|
- CacheExpiration: cacheExpiration,
|
|
|
- httpServices: services.NewCostModelServices(),
|
|
|
+ Router: httprouter.New(),
|
|
|
+ PrometheusClient: promClis[env.Server],
|
|
|
+ PrometheusScrapeClient: promClis[scrapeKey],
|
|
|
+ ThanosClient: thanosClient,
|
|
|
+ KubeClientSet: kubeClientset,
|
|
|
+ ClusterCache: k8sCache,
|
|
|
+ ClusterMap: clusterMap,
|
|
|
+ CloudProvider: cloudProvider,
|
|
|
+ CloudConfigController: cloudconfig.NewController(cloudProvider),
|
|
|
+ ConfigFileManager: confManager,
|
|
|
+ ClusterInfoProvider: clusterInfoProvider,
|
|
|
+ Model: costModel,
|
|
|
+ MetricsEmitter: metricsEmitter,
|
|
|
+ AggregateCache: aggregateCache,
|
|
|
+ CostDataCache: costDataCache,
|
|
|
+ ClusterCostsCache: clusterCostsCache,
|
|
|
+ OutOfClusterCache: outOfClusterCache,
|
|
|
+ SettingsCache: settingsCache,
|
|
|
+ CacheExpiration: cacheExpiration,
|
|
|
+ httpServices: services.NewCostModelServices(),
|
|
|
}
|
|
|
|
|
|
// Use the Accesses instance, itself, as the CostModelAggregator. This is
|