Skip to content

Commit

Permalink
Remove proxy ability.
Browse files Browse the repository at this point in the history
Instead of using the proxy, I'm using a configurable datasource in grafana.
Currently the queries I make to ForecastMetrics and VictoriaMetrics are not resolvable by each other, so by switching the datasource, I'm switching which queries resolve.
This is much less complicated than trying to handle special cases when proxying.
Also removes a bunch of todo items.
  • Loading branch information
tedpearson committed Oct 6, 2023
1 parent 099dda2 commit 9d9bb7c
Show file tree
Hide file tree
Showing 5 changed files with 3 additions and 81 deletions.
17 changes: 0 additions & 17 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ type Config struct {
BingToken string `yaml:"bing_token"`
ServerPort int64 `yaml:"server_port"`
AdHocCacheEntries int `yaml:"ad_hoc_cache_entries"`
ProxyUrl string `yaml:"proxy_url"`
Sources struct {
Enabled []string
VisualCrossing struct {
Expand Down Expand Up @@ -83,22 +82,6 @@ func NewConfigService(configFile, locationsFile string) *ConfigService {
}
}

// HasLocation returns true if this Location is being regularly exported.
func (c *ConfigService) HasLocation(location Location) bool {
return c.GetLocation(location.Name) != nil
}

// GetLocation returns a pointer to a location if one with this name exists, otherwise nil.
func (c *ConfigService) GetLocation(name string) *Location {
idx := slices.IndexFunc(c.locations, func(location Location) bool {
return location.Name == name
})
if idx >= 0 {
return &c.locations[idx]
}
return nil
}

// GetLocations returns a copy of all actively exported locations.
func (c *ConfigService) GetLocations() []Location {
c.lock.Lock()
Expand Down
1 change: 0 additions & 1 deletion forecastmetrics.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ overwrite_data: false
bing_token: your_token_here
server_port: 8080
ad_hoc_cache_entries: 100
proxy_url: "http://localhost:8428"

sources:
enabled:
Expand Down
7 changes: 1 addition & 6 deletions location.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ var latLonRe = regexp.MustCompile(`(\d+\.\d+),\s*(\d+\.\d+)`)

// LocationService parses strings into Location, using the Bing Maps Locations API.
type LocationService struct {
BingToken string
ConfigService *ConfigService
BingToken string
}

// ParseLocation turns strings into Locations
Expand All @@ -34,10 +33,6 @@ func (l LocationService) ParseLocation(s string) (*Location, error) {
if len(parts) > 1 {
name = parts[1]
}
// return existing proxyable location if it exists with this name
if got := l.ConfigService.GetLocation(name); got != nil {
return got, nil
}
m := latLonRe.FindStringSubmatch(loc)
if m != nil {
return &Location{
Expand Down
9 changes: 1 addition & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ func main() {
configService := NewConfigService(*configFile, *locationsFile)
config := configService.Config
locationService := LocationService{
BingToken: config.BingToken,
ConfigService: configService,
BingToken: config.BingToken,
}
forecasters := MakeForecasters(config.Sources.Enabled, config.HttpCacheDir, config.Sources.VisualCrossing.Key)
c := influxdb2.NewClient(config.InfluxDB.Host, config.InfluxDB.AuthToken)
Expand All @@ -61,10 +60,8 @@ func main() {
server := Server{
LocationService: locationService,
Dispatcher: dispatcher,
ConfigService: configService,
PromConverter: promConverter,
AuthToken: config.InfluxDB.AuthToken,
ProxyUrl: config.ProxyUrl,
AllowedMetricNames: []string{
config.ForecastMeasurementName,
config.AstronomyMeasurementName,
Expand Down Expand Up @@ -101,9 +98,5 @@ func MakeForecasters(enabled []string, cacheDir string, vcKey string) map[string
}

// todo
// make influx forwarded token and our required auth token allowed to be different
// update readme
// proxy only works for VM, turn it off by default
// allow http server functionality to be turned off if desired, by not including a port to listen on or something
// also allow proxy to be turned off
// proxy accumulated_precip to running_sum(metric+forecast_time)
50 changes: 1 addition & 49 deletions server.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
package main

import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/http/httputil"
_ "net/http/pprof"
"net/url"
"regexp"
"slices"
"strconv"
"strings"
"time"
)

// Server provides the promethus endpoint for ForecastMetrics.
type Server struct {
LocationService LocationService
Dispatcher *Dispatcher
ConfigService *ConfigService
PromConverter PromConverter
AuthToken string
ProxyUrl string
AllowedMetricNames []string
}

Expand Down Expand Up @@ -53,14 +47,7 @@ func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
return
}
// get params
body, err := io.ReadAll(req.Body)
if err != nil {
resp.WriteHeader(http.StatusInternalServerError)
return
}
// prepare body to be read by ParseForm
req.Body = io.NopCloser(bytes.NewReader(body))
err = req.ParseForm()
err := req.ParseForm()
if err != nil {
resp.WriteHeader(http.StatusBadRequest)
fmt.Printf("Failed to parse form: %s", err)
Expand All @@ -71,14 +58,6 @@ func (s *Server) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
return
}

// check if we should proxy
if s.ConfigService.HasLocation(params.Location) {
// prepare body to be read by reverse proxy
req.Body = io.NopCloser(bytes.NewReader(body))
s.Proxy(resp, req, *params)
return
}

forecast, err := s.Dispatcher.GetForecast(params.Location, params.Source, params.AdHoc)
if err != nil {
fmt.Printf("Error getting forecast: %+v\n", err)
Expand Down Expand Up @@ -112,33 +91,6 @@ func Auth(authHeader, authToken string) bool {
return false
}

// Proxy proxies the request to the database.
func (s *Server) Proxy(resp http.ResponseWriter, req *http.Request, params Params) {
fmt.Printf("Proxying forecast for %s from %s\n", params.Location.Name, params.Source)
u, _ := url.Parse(s.ProxyUrl)
proxy := &httputil.ReverseProxy{
Rewrite: func(r *httputil.ProxyRequest) {
r.SetURL(u)
// no need to parse form here as it was already parsed
values := r.In.Form
// add forecast time label to query
// simplify and rename location as well
tagFmt := `%s="%s"`
loc := fmt.Sprintf(tagFmt, "location", params.Location.Name)
src := fmt.Sprintf(tagFmt, "source", params.Source)
fts := time.Now().Add(-5 * time.Minute).Truncate(time.Hour).Format(ForecastTimeFormat)
ft := fmt.Sprintf(tagFmt, "forecast_time", fts)
query := fmt.Sprintf("%s{%s,%s,%s}", params.Metric, loc, src, ft)
//query := fmt.Sprintf()
values.Set("query", query)
body := values.Encode()
r.Out.ContentLength = int64(len(body))
r.Out.Body = io.NopCloser(strings.NewReader(body))
},
}
proxy.ServeHTTP(resp, req)
}

// ParsedQuery is the information parsed and looked up from the prometheus query string
type ParsedQuery struct {
Metric string
Expand Down

0 comments on commit 9d9bb7c

Please sign in to comment.