Skip to content

Commit

Permalink
feat: initial discovery endpoint functions
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Sep 23, 2024
1 parent 22471ef commit 85366bd
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
55 changes: 55 additions & 0 deletions utils/discovery/discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package discovery

import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
)

type DiscoveryEndpoint struct {
LagoonVersion string `json:"lagoon_version"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
SSHTokenExchange SSHTokenExchange `json:"ssh_token_exchange"`
WebhookEndpoint string `json:"webhook_endpoint"`
UIHostname string `json:"ui_url"`
}

type SSHTokenExchange struct {
TokenHost string `json:"token_endpoint_host"`
TokenPort int `json:"token_endpoint_port"`
}

// the wellknown path of the lagoon discovery endpoint
const wellKnown = ".well-known/appspecific/sh.lagoon.discovery.json"

func Discover(hostname string) (*DiscoveryEndpoint, error) {
// check if the hostname provided is actually valid-ish
u, err := url.Parse(strings.TrimRight(hostname, "/"))
if err != nil {
return nil, err
}
switch u.Scheme {
case "":
u.Scheme = "https"
case "http", "https":
default:
return nil, fmt.Errorf("url scheme must be http or https not %s", u.Scheme)

}
// check the discovery endpoint
resp, err := http.Get(fmt.Sprintf("%s/%s", u, wellKnown))
if err != nil {
return nil, err
}
defer resp.Body.Close()
// decode the response into the discovery struct
d := &DiscoveryEndpoint{}
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(d)
if err != nil {
return nil, err
}
return d, nil
}
61 changes: 61 additions & 0 deletions utils/discovery/discovery_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package discovery

import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"testing"
)

func TestDiscover(t *testing.T) {
type args struct {
testserverpayload string
}
tests := []struct {
name string
args args
want *DiscoveryEndpoint
wantErr bool
}{
{
name: "test1",
args: args{
testserverpayload: `{"lagoon_version":"v2.17.0","authorization_endpoint":"https://keycloak.lagoon.sh","ssh_token_exchange":{"token_endpoint_host":"token.lagoon.sh","token_endpoint_port":22},"webhook_endpoint":"https://webhookhandler.lagoon.sh","ui_url":"https://ui.lagoon.sh"}`,
},
want: &DiscoveryEndpoint{
LagoonVersion: "v2.17.0",
AuthorizationEndpoint: "https://keycloak.lagoon.sh",
WebhookEndpoint: "https://webhookhandler.lagoon.sh",
UIHostname: "https://ui.lagoon.sh",
SSHTokenExchange: SSHTokenExchange{
TokenPort: 22,
TokenHost: "token.lagoon.sh",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// create a test server with the wellknown path
mux := http.NewServeMux()
mux.HandleFunc(fmt.Sprintf("/%s", wellKnown), func(res http.ResponseWriter, req *http.Request) {
// return the payload
res.Write([]byte(tt.args.testserverpayload))
})
// start the test server
svr := httptest.NewServer(mux)
defer svr.Close()
// perform the request
got, err := Discover(svr.URL)
if (err != nil) != tt.wantErr {
t.Errorf("Discover() error = %v, wantErr %v", err, tt.wantErr)
return
}
// check the result is as expected
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Discover() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 85366bd

Please sign in to comment.