Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## 0.10.0 (2019-08-30)
**Features**
* cache/redis: add configurable key expiration time. #600 (@tierpod)
* server: configurable webserver URI Prefix #136 (@ARolek)

**Bug Fixes**
* server: Content-Length for non-gzipped responses (@thomersch)
* cmd: tegola command fails when running version subcommand without a config. #626 (@ear7h)

**Maintenance**
* Upgraded internal viewer Mapbox GL JS to 1.0.0 (@ARolek)
* Skip S3 tests on external pull requests (@gdey)

**Breaking Changes**
* If a `webserver.hostname` is set in the config the port is no longer added to the hostname. When setting the `hostname` it's now assumed the user wants full control of `hostname:port` combo.

## 0.9.0 (2019-04-09)
**Features**
* Add support for --no-cache command line flag override (#517 @tierpod)
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Tegola is a vector tile server delivering [Mapbox Vector Tiles](https://github.c
## Usage
```
tegola is a vector tile server
Version: v0.9.0
Version: v0.10.0

Usage:
tegola [command]
Expand Down Expand Up @@ -243,7 +243,8 @@ The requested tile will be encode a layer with the `name` value set to `debug` a

## Building from source

Tegola is written in [Go](https://golang.org/) and requires Go 1.8+ to compile from source. To build tegola from source, make sure you have Go installed and have cloned the repository to your `$GOPATH`. Navigate to the repository then run the following commands:
Tegola is written in [Go](https://golang.org/) and requires Go 1.x to compile from source. (We support the three newest versions of Go.) To build tegola from source, make sure you have Go installed and have cloned the repository to your `$GOPATH`. Navigate to the repository then run the following commands:


```bash
cd cmd/tegola/
Expand Down
3 changes: 2 additions & 1 deletion cache/redis/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ The rediscache config supports the following properties:
- `address` (string): [Optional] the address of the Redis instance in form of `ip:port`. Defaults to '127.0.0.1:6379'.
- `password` (string): [Optional] password for the Redis instance. Defaults to '' (no password).
- `db` (int): [Optional] the database within the Redis instance to cache to.
- `max_zoom` (int): [Optional] the max zoom the cache should cache to. After this zoom, Set() calls will return before doing work.
- `max_zoom` (int): [Optional] the max zoom the cache should cache to. After this zoom, Set() calls will return before doing work.
- `ttl` (int): [Optional] the key ttl time in seconds. Defaults to 0 (the key has no expiration time).
13 changes: 10 additions & 3 deletions cache/redis/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"time"

"github.com/go-redis/redis"

"github.com/go-spatial/tegola"
"github.com/go-spatial/tegola/cache"
"github.com/go-spatial/tegola/dict"
Expand All @@ -19,6 +18,7 @@ const (
ConfigKeyPassword = "password"
ConfigKeyDB = "db"
ConfigKeyMaxZoom = "max_zoom"
ConfigKeyTTL = "ttl"
)

func init() {
Expand All @@ -33,6 +33,7 @@ func New(config dict.Dicter) (rcache cache.Interface, err error) {
defaultPassword := ""
defaultDB := 0
defaultMaxZoom := uint(tegola.MaxZ)
defaultTTL := 0

c := config

Expand Down Expand Up @@ -79,9 +80,15 @@ func New(config dict.Dicter) (rcache cache.Interface, err error) {
return nil, err
}

ttl, err := c.Int(ConfigKeyTTL, &defaultTTL)
if err != nil {
return nil, err
}

return &RedisCache{
Redis: client,
MaxZoom: maxZoom,
Redis: client,
MaxZoom: maxZoom,
Expiration: time.Duration(ttl) * time.Second,
}, nil
}

Expand Down
37 changes: 25 additions & 12 deletions cache/s3/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"reflect"
"strings"
"testing"

"github.com/go-spatial/tegola/cache"
Expand All @@ -14,10 +15,28 @@ import (
// gzip encoded test data
var testData = []byte{0x1f, 0x8b, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x2a, 0xce, 0xcc, 0x49, 0x2c, 0x6, 0x4, 0x0, 0x0, 0xff, 0xff, 0xaf, 0x9d, 0x59, 0xca, 0x5, 0x0, 0x0, 0x0}

func TestNew(t *testing.T) {
if os.Getenv("RUN_S3_TESTS") != "yes" {
return
// skipS3Test will check the environment to see if the test should be skipped
func skipS3Tests(t *testing.T) {
if strings.TrimSpace(strings.ToLower(os.Getenv("RUN_S3_TESTS"))) != "yes" {
t.Skipf("skipping %v, RUN_S3_TESTS not set to 'yes'", t.Name())
}
// Test for static Credentials as well. If there are not there we skip the tests

var config dict.Dict = map[string]interface{}{
"bucket": os.Getenv("AWS_TEST_BUCKET"),
"region": os.Getenv("AWS_REGION"),
"aws_access_key_id": os.Getenv("AWS_ACCESS_KEY_ID"),
"aws_secret_access_key": os.Getenv("AWS_SECRET_ACCESS_KEY"),
}
_, err := s3.New(config)
if err != nil {
t.Skipf("skipping %v, static ENV's not set or correct", t.Name())
}

}

func TestNew(t *testing.T) {
skipS3Tests(t)

type tcase struct {
config dict.Dict
Expand Down Expand Up @@ -82,9 +101,7 @@ func TestNew(t *testing.T) {
}

func TestSetGetPurge(t *testing.T) {
if os.Getenv("RUN_S3_TESTS") != "yes" {
return
}
skipS3Tests(t)

type tcase struct {
config dict.Dict
Expand Down Expand Up @@ -154,9 +171,7 @@ func TestSetGetPurge(t *testing.T) {
}

func TestSetOverwrite(t *testing.T) {
if os.Getenv("RUN_S3_TESTS") != "yes" {
return
}
skipS3Tests(t)

type tcase struct {
config dict.Dict
Expand Down Expand Up @@ -236,9 +251,7 @@ func TestSetOverwrite(t *testing.T) {
}

func TestMaxZoom(t *testing.T) {
if os.Getenv("RUN_S3_TESTS") != "yes" {
return
}
skipS3Tests(t)

type tcase struct {
config dict.Dict
Expand Down
8 changes: 6 additions & 2 deletions cmd/tegola/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@ Version: %v`, Version),

func rootCmdValidatePersistent(cmd *cobra.Command, args []string) (err error) {
requireCache := RequireCache || cachecmd.RequireCache

return initConfig(configFile, requireCache)
switch cmd.CalledAs() {
case "help", "version":
return nil
default:
return initConfig(configFile, requireCache)
}
}

func initConfig(configFile string, cacheRequired bool) (err error) {
Expand Down
4 changes: 4 additions & 0 deletions cmd/tegola/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ var serverCmd = &cobra.Command{
server.Headers[name] = val
}

if conf.Webserver.URIPrefix != "" {
server.URIPrefix = string(conf.Webserver.URIPrefix)
}

// start our webserver
srv := server.Start(nil, serverPort)
shutdown(srv)
Expand Down
8 changes: 6 additions & 2 deletions cmd/tegola_lambda/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func main() {
server.Headers[name] = val
}

if conf.Webserver.URIPrefix != "" {
server.URIPrefix = string(conf.Webserver.URIPrefix)
}

// http route setup
mux := server.NewRouter(nil)

Expand All @@ -105,7 +109,7 @@ func main() {

// URLRoot overrides the default server.URLRoot function in order to include the "stage" part of the root
// that is part of lambda's URL scheme
func URLRoot(r *http.Request) string {
func URLRoot(r *http.Request) *url.URL {
u := url.URL{
Scheme: scheme(r),
Host: r.Header.Get("Host"),
Expand All @@ -116,7 +120,7 @@ func URLRoot(r *http.Request) string {
u.Path = ctx.RequestContext.Stage
}

return u.String()
return &u
}

// various checks to determine if the request is http or https. the scheme is needed for the TileJSON URLs
Expand Down
20 changes: 14 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
config loads and understands the tegola config format.
*/
// Package config loads and understands the tegola config format.
package config

import (
Expand Down Expand Up @@ -35,9 +33,10 @@ type Config struct {
}

type Webserver struct {
HostName env.String `toml:"hostname"`
Port env.String `toml:"port"`
Headers env.Dict `toml:"headers"`
HostName env.String `toml:"hostname"`
Port env.String `toml:"port"`
URIPrefix env.String `toml:"uri_prefix"`
Headers env.Dict `toml:"headers"`
}

// A Map represents a map in the Tegola Config file.
Expand Down Expand Up @@ -140,6 +139,15 @@ func (c *Config) Validate() error {
}
}

// check if webserver.uri_prefix is set and if so
// confirm it starts with a forward slash "/"
if string(c.Webserver.URIPrefix) != "" {
uriPrefix := string(c.Webserver.URIPrefix)
if string(uriPrefix[0]) != "/" {
return ErrInvalidURIPrefix(uriPrefix)
}
}

return nil
}

Expand Down
6 changes: 6 additions & 0 deletions config/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ type ErrInvalidHeader struct {
func (e ErrInvalidHeader) Error() string {
return fmt.Sprintf("config: header (%v) blacklisted", e.Header)
}

type ErrInvalidURIPrefix string

func (e ErrInvalidURIPrefix) Error() string {
return fmt.Sprintf("config: invalid uri_prefix (%v). uri_prefix must start with a forward slash '/' ", string(e))
}
69 changes: 35 additions & 34 deletions provider/postgis/postgis_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,44 +48,46 @@ func TestLayerGeomType(t *testing.T) {
ConfigKeySSLRootCert: os.Getenv("PGSSLROOTCERT"),
}

fn := func(t *testing.T, tc tcase) {
// check if we have env vars to override
if len(tc.configOverride) > 0 {
conf := map[string]interface{}{}
// copy the original config
for k, v := range tc.config {
conf[k] = v
fn := func(tc tcase) func(t *testing.T) {
return func(t *testing.T) {
// check if we have env vars to override
if len(tc.configOverride) > 0 {
conf := map[string]interface{}{}
// copy the original config
for k, v := range tc.config {
conf[k] = v
}

// set the config overrides
for k, v := range tc.configOverride {
conf[k] = v
}

// override the test's config with our new one
tc.config = conf
}

// set the config overrides
for k, v := range tc.configOverride {
conf[k] = v
}

// override the test's config with our new one
tc.config = conf
}

tc.config[ConfigKeyLayers] = []map[string]interface{}{tc.layerConfig}
tc.config[ConfigKeyLayers] = []map[string]interface{}{tc.layerConfig}

provider, err := NewTileProvider(dict.Dict(tc.config))
if tc.err != "" {
if err == nil || !strings.Contains(err.Error(), tc.err) {
t.Errorf("expected error with %q in NewProvider, got: %v", tc.err, err)
provider, err := NewTileProvider(dict.Dict(tc.config))
if tc.err != "" {
if err == nil || !strings.Contains(err.Error(), tc.err) {
t.Errorf("expected error with %q in NewProvider, got: %v", tc.err, err)
}
return
}
if err != nil {
t.Errorf("NewProvider unexpected error: %v", err)
return
}
return
}
if err != nil {
t.Errorf("NewProvider unexpected error: %v", err)
return
}

p := provider.(Provider)
layer := p.layers[tc.layerName]
p := provider.(Provider)
layer := p.layers[tc.layerName]

if !reflect.DeepEqual(tc.geom, layer.geomType) {
t.Errorf("geom type, expected %v got %v", tc.geom, layer.geomType)
return
if !reflect.DeepEqual(tc.geom, layer.geomType) {
t.Errorf("geom type, expected %v got %v", tc.geom, layer.geomType)
return
}
}
}

Expand Down Expand Up @@ -155,7 +157,6 @@ func TestLayerGeomType(t *testing.T) {
}

for name, tc := range tests {
tc := tc
t.Run(name, func(t *testing.T) { fn(t, tc) })
t.Run(name, fn(tc))
}
}
Loading