Skip to content

Commit

Permalink
feat(file) process sugar attribute url of Service entity
Browse files Browse the repository at this point in the history
`url` property is deconstructed on file read into protocol, host, port
and path.
There are checks in place but this is likely not going to be full-proof
and the code will break in corner cases if all the components are not
specified. It should suffice for most use-cases.

Fix #123
  • Loading branch information
hbagdi committed Feb 7, 2020
1 parent beaced6 commit 4dc933c
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 9 deletions.
3 changes: 3 additions & 0 deletions file/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 58 additions & 9 deletions file/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package file

import (
"encoding/json"
"net/url"
"strconv"
"strings"

"github.com/hbagdi/deck/utils"
"github.com/hbagdi/go-kong/kong"
"github.com/pkg/errors"
)

// Format is a file format for Kong's configuration.
Expand All @@ -26,6 +30,9 @@ type FService struct {
kong.Service
Routes []*FRoute `json:"routes,omitempty" yaml:",omitempty"`
Plugins []*FPlugin `json:"plugins,omitempty" yaml:",omitempty"`

// sugar property
URL *string `json:"url,omitempty" yaml:",omitempty"`
}

// id is used for sorting.
Expand Down Expand Up @@ -56,6 +63,9 @@ type service struct {
Tags []*string `json:"tags,omitempty" yaml:"tags,omitempty"`
Routes []*FRoute `json:"routes,omitempty" yaml:",omitempty"`
Plugins []*FPlugin `json:"plugins,omitempty" yaml:",omitempty"`

// sugar property
URL *string `json:"url,omitempty" yaml:",omitempty"`
}

func copyToService(fService FService) service {
Expand Down Expand Up @@ -83,28 +93,69 @@ func copyToService(fService FService) service {
return s
}

func copyFromService(service service, fService *FService) {
func unwrapURL(urlString string, fService *FService) error {
parsed, err := url.Parse(urlString)
if err != nil {
return errors.New("invaid url: " + urlString)
}
if parsed.Scheme == "" {
return errors.New("invalid url:" + urlString)
}

fService.Protocol = kong.String(parsed.Scheme)
if parsed.Host != "" {
hostPort := strings.Split(parsed.Host, ":")
fService.Host = kong.String(hostPort[0])
if len(hostPort) > 1 {
port, err := strconv.Atoi(hostPort[1])
if err == nil {
fService.Port = kong.Int(port)
}
}
}
if parsed.Path != "" {
fService.Path = kong.String(parsed.Path)
}
return nil
}

func copyFromService(service service, fService *FService) error {
if service.ClientCertificate != nil &&
!utils.Empty(service.ClientCertificate) {
fService.ClientCertificate = &kong.Certificate{
ID: kong.String(*service.ClientCertificate),
}
}
if !utils.Empty(service.URL) {
err := unwrapURL(*service.URL, fService)
if err != nil {
return err
}
}
fService.ConnectTimeout = service.ConnectTimeout
fService.CreatedAt = service.CreatedAt
fService.Host = service.Host
fService.ID = service.ID
fService.Name = service.Name
fService.Path = service.Path
fService.Port = service.Port
fService.Protocol = service.Protocol
if service.Protocol != nil {
fService.Protocol = service.Protocol
}
if service.Host != nil {
fService.Host = service.Host
}
if service.Port != nil {
fService.Port = service.Port
}
if service.Path != nil {
fService.Path = service.Path
}
fService.ReadTimeout = service.ReadTimeout
fService.Retries = service.Retries
fService.UpdatedAt = service.UpdatedAt
fService.WriteTimeout = service.WriteTimeout
fService.Tags = service.Tags
fService.Routes = service.Routes
fService.Plugins = service.Plugins
return nil
}

// MarshalYAML is a custom marshal to handle
Expand All @@ -120,8 +171,7 @@ func (s *FService) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := unmarshal(&service); err != nil {
return err
}
copyFromService(service, s)
return nil
return copyFromService(service, s)
}

// MarshalJSON is a custom marshal method to handle
Expand All @@ -139,8 +189,7 @@ func (s *FService) UnmarshalJSON(b []byte) error {
if err != nil {
return err
}
copyFromService(service, s)
return nil
return copyFromService(service, s)
}

// FRoute represents a Kong Route and it's associated plugins.
Expand Down
105 changes: 105 additions & 0 deletions file/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package file

import (
"encoding/json"
"fmt"
"reflect"
"testing"

Expand Down Expand Up @@ -172,3 +173,107 @@ func Test_copyFromCert(t *testing.T) {
})
}
}

func Test_unwrapURL(t *testing.T) {
type args struct {
urlString string
fService *FService
}
tests := []struct {
name string
args args
wantErr bool
}{
{
args: args{
urlString: "https://foo.com:8008/bar",
fService: &FService{
Service: kong.Service{
Host: kong.String("foo.com"),
Port: kong.Int(8008),
Protocol: kong.String("https"),
Path: kong.String("/bar"),
},
},
},
wantErr: false,
},
{
args: args{
urlString: "https://foo.com/bar",
fService: &FService{
Service: kong.Service{
Host: kong.String("foo.com"),
Protocol: kong.String("https"),
Path: kong.String("/bar"),
},
},
},
wantErr: false,
},
{
args: args{
urlString: "https://foo.com/",
fService: &FService{
Service: kong.Service{
Host: kong.String("foo.com"),
Protocol: kong.String("https"),
Path: kong.String("/"),
},
},
},
wantErr: false,
},
{
args: args{
urlString: "grpc://foocom",
fService: &FService{
Service: kong.Service{
Host: kong.String("foocom"),
Protocol: kong.String("grpc"),
},
},
},
wantErr: false,
},
{
args: args{
urlString: "foo.com/sdf",
fService: &FService{
Service: kong.Service{},
},
},
wantErr: true,
},
{
args: args{
urlString: "foo.com",
fService: &FService{
Service: kong.Service{},
},
},
wantErr: true,
},
{
args: args{
urlString: "42:",
fService: &FService{
Service: kong.Service{},
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
in := FService{}
if err := unwrapURL(tt.args.urlString, &in); (err != nil) != tt.wantErr {
t.Errorf("unwrapURL() error = %v, wantErr %v", err, tt.wantErr)
}
fmt.Printf("\n\n%+v", in)
if !reflect.DeepEqual(tt.args.fService, &in) {
t.Errorf("unwrapURL() got = %v, want = %v", &in, tt.args.fService)
}
})
}
}

0 comments on commit 4dc933c

Please sign in to comment.