Skip to content

Commit

Permalink
feat: implement inspect page
Browse files Browse the repository at this point in the history
Added a new handler and respective tests to get affiliate data in a cluster.
Signed-off-by: Rohit Dandamudi <rohit.dandamudi@siderolabs.com>
  • Loading branch information
Rohit Dandamudi authored and Rohit Dandamudi committed Nov 23, 2021
1 parent 4906c98 commit 52b44de
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cmd/discovery-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func run(ctx context.Context, logger *zap.Logger) error {
}

landingServer := http.Server{
Handler: landing.Handler(),
Handler: landing.Handler(state, logger),
}

eg, ctx := errgroup.WithContext(ctx)
Expand Down
4 changes: 4 additions & 0 deletions internal/landing/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,9 @@ <h2>Details</h2>
<p>
To summarize, the discovery service knows the client version, cluster ID, the number of affiliates, some encrypted data for each affiliate, and a list of encrypted endpoints.
</p>

<p>
You can get data stored in the discovery service for the cluster ID on <a href="/inspect">inspect page</a>.
</p>
</body>
</html>
50 changes: 49 additions & 1 deletion internal/landing/landing.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,70 @@ package landing

import (
"embed"
"fmt"
"html/template"
"io/fs"
"net/http"
"net/url"

"go.uber.org/zap"

"github.com/talos-systems/discovery-service/internal/state"
)

//go:embed "html/index.html"
var static embed.FS

//go:embed "templates/inspect.html.tmpl"
var inspectTemplate []byte

// ClusterInspectData represents all affiliate data asssociated with a cluster.
type ClusterInspectData struct {
ClusterID string
Affiliates []*state.AffiliateExport
}

var inspectPage = template.Must(template.New("inspect").Parse(string(inspectTemplate)))

// InspectHandler provides data to inspect a cluster.
func InspectHandler(w http.ResponseWriter, req *http.Request, state *state.State) error {
clusterData := ClusterInspectData{}

formData, err := url.ParseQuery(req.URL.RawQuery)
if err != nil {
return err
}

clusterData.ClusterID = formData.Get("clusterID")
fetchedCluster := state.GetCluster(clusterData.ClusterID)
clusterData.Affiliates = fetchedCluster.List()

if err := inspectPage.Execute(w, clusterData); err != nil {
return err
}

return nil
}

// Handler returns static landing page handler.
func Handler() http.Handler {
func Handler(state *state.State, logger *zap.Logger) http.Handler {
subfs, err := fs.Sub(static, "html")
if err != nil {
panic(err)
}

mux := http.NewServeMux()

mux.Handle("/", http.FileServer(http.FS(subfs)))

// wrapper to pass state
mux.HandleFunc("/inspect", func(w http.ResponseWriter, r *http.Request) {
if err := InspectHandler(w, r, state); err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, "Oops, try again")
logger.Error("failed to return the page:", zap.Error(err))
}
})

return mux
}
41 changes: 41 additions & 0 deletions internal/landing/templates/inspect.html.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<title> Inspect Cluster </title>
</head>
<body>
<form class="form-group" action="/inspect" method="GET">
<div class="form-group">
<label for="clusterID">Enter Cluster ID :</label>
<input type="text" id="clusterID" name="clusterID" class = "form-control" placeholder="sjdhfUG@%HKA^Srasfjskfj9987sfkj"><br>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<br><hr>
{{ if .ClusterID }}
<h4>The affiliates associated with given cluster ID {{.ClusterID}}: </h4>
{{if not .Affiliates}}
<p>No Affiliate data found</p>
{{end}}
<ol>
{{range .Affiliates}}
<li class="affiliateID">Affliate ID: {{.ID}} </li>
<ul>
<li class="affiliateData">
<span style="width:90%; word-wrap:break-word; display:inline-block;">
Affliate Data: {{.Data | printf "%x"}}
</span>
</li>
<li class="affiliateEndpoints">Affiliate Endpoints:
<ul>
{{range .Endpoints}}
<li> {{. | printf "%x"}}</li>
{{end}}
</ul>
</li>
</ul>
{{end}}
</ol>
{{end}}
</body>
</html>
68 changes: 68 additions & 0 deletions pkg/server/landing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2021 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.

package server_test

import (
"context"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"

"github.com/talos-systems/discovery-service/internal/landing"
"github.com/talos-systems/discovery-service/internal/state"
)

// TestInspectHandler tests the /inspect endpoint.
// Tests at 3001 port filled with dummy cluster/affiliate data.
func TestInspectHanlder(t *testing.T) {
logger := zaptest.NewLogger(t)
now := time.Now()
stateInstance := state.NewState(logger)
testCluster := stateInstance.GetCluster("fake1")
ctx, cancel := context.WithCancel(context.Background())

t.Cleanup(cancel)

// add affiliates to the cluster "fake1"
err := testCluster.WithAffiliate("af1", func(affiliate *state.Affiliate) error {
affiliate.Update([]byte("data1"), now.Add(time.Minute))

return nil
})
require.NoError(t, err)

err = testCluster.WithAffiliate("af2", func(affiliate *state.Affiliate) error {
affiliate.Update([]byte("data2"), now.Add(time.Minute))

return nil
})
require.NoError(t, err)

ts := httptest.NewServer(landing.Handler(stateInstance, logger))
defer ts.Close()

req, err := http.NewRequestWithContext(ctx, http.MethodGet, ts.URL+"/inspect?clusterID=fake1", nil)
require.NoError(t, err)

res, err := http.DefaultClient.Do(req)
require.NoError(t, err)

inspectPage, err := io.ReadAll(res.Body)
require.NoError(t, err)

err = res.Body.Close()
require.NoError(t, err)

assert.Equal(t, 200, res.StatusCode)

t.Log(string(inspectPage))
}

0 comments on commit 52b44de

Please sign in to comment.