Skip to content

Commit

Permalink
improve URI parsing for elasticsearch bindings * more elegant alterna…
Browse files Browse the repository at this point in the history
…tive determination of port based on URI scheme #83
  • Loading branch information
schefDev committed Dec 27, 2023
1 parent 5a2ca8b commit 1562003
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 39 deletions.
27 changes: 16 additions & 11 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,24 +129,14 @@ func enrichBinding(binding config.ServiceBinding) config.ServiceBinding {
}

// set host and port too if still missing
h, p, _ := net.SplitHostPort(u.Host)
h, p, _ := net.SplitHostPort(canonicalHost(u))
if len(binding.Host) == 0 {
binding.Host = h
}
if binding.Port == 0 {
binding.Port, _ = strconv.Atoi(p)
}

// set well-known port based on scheme if still missing
if binding.Port == 0 {
if strings.EqualFold(u.Scheme, "https") {
binding.Port = 443
}
if strings.EqualFold(u.Scheme, "http") {
binding.Port = 80
}
}

// set database if not defined yet but can be found in URI
if len(binding.Database) == 0 {
binding.Database = strings.TrimPrefix(u.Path, "/")
Expand Down Expand Up @@ -196,3 +186,18 @@ func GetService(serviceType, serviceName string) config.Service {
}
return config.Service{}
}

// canonicalHost returns url.Host but always with a ":port" suffix
// adapted from net/http/transport canonicalAddr
func canonicalHost(url *url.URL) string {
portMap := map[string]string{
"http": "80",
"https": "443",
}
addr := url.Hostname()
port := url.Port()
if port == "" {
port = portMap[url.Scheme]
}
return net.JoinHostPort(addr, port)
}
28 changes: 0 additions & 28 deletions service/service_bindings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,3 @@ func Test_Service_ParseServiceBindings(t *testing.T) {
assert.Equal(t, "dev-secret", c.Services["my_postgres_db"].Binding.Password) // from service_binding_root/*
assert.Equal(t, "postgres://dev-user:[email protected]:5432/my_postgres_db?sslmode=disable", c.Services["my_postgres_db"].Binding.URI) // from service_binding_root/*
}

func Test_Service_MergeVCAPServices(t *testing.T) {
config.SetConfigFile("_fixtures/config_without_bindings.json")

c := config.Get()
mergeVCAPServices()

assert.Equal(t, "postgres", c.Services["my_postgres_db"].Binding.Type)
assert.Equal(t, "127.0.0.1", c.Services["my_postgres_db"].Binding.Host)
assert.Equal(t, 5432, c.Services["my_postgres_db"].Binding.Port)
assert.Equal(t, "dev-user", c.Services["my_postgres_db"].Binding.Username)
assert.Equal(t, "dev-secret", c.Services["my_postgres_db"].Binding.Password)
assert.Equal(t, "postgres://dev-user:[email protected]:5432/my_postgres_db?sslmode=disable", c.Services["my_postgres_db"].Binding.URI)
assert.Equal(t, "https://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com:443", c.Services["my-elasticsearch"].Binding.URI)

elasticsearchServiceConfig := c.Services["my-elasticsearch"]
// without enrichBinding is port undefined
assert.Equal(t, 0, elasticsearchServiceConfig.Binding.Port)
// if port is defined in uri, it is determined from there
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 443, elasticsearchServiceConfig.Binding.Port)
// if no port is defined in uri, it is determined by schema/protocol
elasticsearchServiceConfig.Binding.Host = "https://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com"
elasticsearchServiceConfig.Binding.URI = elasticsearchServiceConfig.Binding.Host
elasticsearchServiceConfig.Binding.Port = 0
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 443, elasticsearchServiceConfig.Binding.Port)
}
50 changes: 50 additions & 0 deletions service/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package service

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/swisscom/backman/config"
)

func init() {
_ = os.Chdir("../")
}

func Test_Service_EnrichBinding(t *testing.T) {
config.SetConfigFile("_fixtures/config_without_bindings.json")

c := config.Get()
mergeVCAPServices()

elasticsearchServiceConfig := c.Services["my-elasticsearch"]

// without enrichBinding is port undefined
assert.Equal(t, 0, elasticsearchServiceConfig.Binding.Port)

// if port is defined in uri, it is determined from there
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 443, elasticsearchServiceConfig.Binding.Port)

// if no port is defined in uri, it is determined by schema/protocol
elasticsearchServiceConfig.Binding.Host = "https://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com"
elasticsearchServiceConfig.Binding.URI = elasticsearchServiceConfig.Binding.Host
elasticsearchServiceConfig.Binding.Port = 0
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 443, elasticsearchServiceConfig.Binding.Port)

// if no port is defined in uri, it is determined by schema/protocol
elasticsearchServiceConfig.Binding.Host = "http://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com"
elasticsearchServiceConfig.Binding.URI = elasticsearchServiceConfig.Binding.Host
elasticsearchServiceConfig.Binding.Port = 0
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 80, elasticsearchServiceConfig.Binding.Port)

// if no port is defined in uri, it is determined by schema/protocol
elasticsearchServiceConfig.Binding.Host = "nonehttp://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com"
elasticsearchServiceConfig.Binding.URI = elasticsearchServiceConfig.Binding.Host
elasticsearchServiceConfig.Binding.Port = 0
elasticsearchServiceConfig.Binding = enrichBinding(elasticsearchServiceConfig.Binding)
assert.Equal(t, 0, elasticsearchServiceConfig.Binding.Port)
}
28 changes: 28 additions & 0 deletions service/vcap_services_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package service

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/swisscom/backman/config"
)

func init() {
_ = os.Chdir("../")
}

func Test_Service_MergeVCAPServices(t *testing.T) {
config.SetConfigFile("_fixtures/config_without_bindings.json")

c := config.Get()
mergeVCAPServices()

assert.Equal(t, "postgres", c.Services["my_postgres_db"].Binding.Type)
assert.Equal(t, "127.0.0.1", c.Services["my_postgres_db"].Binding.Host)
assert.Equal(t, 5432, c.Services["my_postgres_db"].Binding.Port)
assert.Equal(t, "dev-user", c.Services["my_postgres_db"].Binding.Username)
assert.Equal(t, "dev-secret", c.Services["my_postgres_db"].Binding.Password)
assert.Equal(t, "postgres://dev-user:[email protected]:5432/my_postgres_db?sslmode=disable", c.Services["my_postgres_db"].Binding.URI)
assert.Equal(t, "https://0c061730-1b19-424b-8efd-349fd40957a0.yolo.elasticsearch.lyra-836.appcloud.swisscom.com:443", c.Services["my-elasticsearch"].Binding.URI)
}

0 comments on commit 1562003

Please sign in to comment.