Skip to content

Commit

Permalink
Merge pull request #907 from KTruesdellENA/feature/source-link
Browse files Browse the repository at this point in the history
Feature/source link
  • Loading branch information
KTruesdellENA committed Nov 17, 2022
2 parents 1693793 + fc7a2d0 commit 87c4da1
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 15 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ fabio.sublime-*
demo/cert/
/pkg/
dist/
*.app
*.hugo_build.lock
2 changes: 1 addition & 1 deletion admin/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (s *Server) handler() http.Handler {
mux.Handle("/api/config", &api.ConfigHandler{Config: s.Cfg})
mux.Handle("/api/routes", &api.RoutesHandler{})
mux.Handle("/api/version", &api.VersionHandler{Version: s.Version})
mux.Handle("/routes", &ui.RoutesHandler{Color: s.Color, Title: s.Title, Version: s.Version})
mux.Handle("/routes", &ui.RoutesHandler{Color: s.Color, Title: s.Title, Version: s.Version, RoutingTable: s.Cfg.UI.RoutingTable})
mux.HandleFunc("/health", handleHealth)

mux.Handle("/assets/", http.FileServer(http.FS(ui.Static)))
Expand Down
53 changes: 43 additions & 10 deletions admin/ui/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ package ui
import (
"html/template"
"net/http"

"github.com/fabiolb/fabio/config"
)

// RoutesHandler provides the UI for managing the routing table.
type RoutesHandler struct {
Color string
Title string
Version string
Color string
Title string
Version string
RoutingTable config.RoutingTable
}

func (h *RoutesHandler) ServeHTTP(w http.ResponseWriter, _ *http.Request) {
tmplRoutes.ExecuteTemplate(w, "routes", h)
}

var tmplRoutes = template.Must(template.New("routes").Parse( // language=HTML
`
<!doctype html>
`<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
Expand All @@ -37,6 +39,21 @@ var tmplRoutes = template.Must(template.New("routes").Parse( // language=HTML
@media (min-width: 78em) {
td.tags{ display: table-cell; }
}
.tooltip { position: relative; display: inline-block; }
.tooltip .tooltiptext {
visibility: hidden;
width: 250px;
background-color: #000000;
color: #ffffff;
text-align: center;
margin: 30px 0px 0px 30px;
padding: 5px 0;
border-radius: 6px;
position: absolute;
z-index: 1000;
}
.tooltip:hover .tooltiptext { visibility: visible; }
</style>
</head>
<body>
Expand Down Expand Up @@ -91,15 +108,31 @@ $(function(){
let $tbody = $('<tbody />');
console.log(routes);
if (routes != null) {
for (let i=0; i < routes.length; i++) {
const r = routes[i];
let $tr = $('<tr />');
if (/^https?:\/+/i.exec(r.src) != null) {
$tr = $('<tr />').attr('style', 'background-color: #ff1a1a;');
$tr.append($('<td />').addClass('tooltip').append($('<span class="tooltiptext"></span>').text("Route Source cannot start with the protocol or scheme (e.g. - 'http' and 'https' are invalid to have listed in the route source)")).append($('<span class="valign-wrapper" />').append(i+1).append($('<i class="material-icons">error_outline</i>'))));
} else {
$tr.append($('<td />').text(i+1));
}
$tr.append($('<td />').text(r.service));
const $tr = $('<tr />')
if ({{.RoutingTable.Source.LinkEnabled}} == true && /^https?:\/+/i.exec(r.dst) != null && /^https?:\/+/i.exec(r.src) == null) {
const hrefScheme = ({{.RoutingTable.Source.Scheme}} != '' ? {{.RoutingTable.Source.Scheme}} + ':' : window.location.protocol) + '//';
const hrefHost = ({{.RoutingTable.Source.Host}} != '' ? {{.RoutingTable.Source.Host}} : window.location.hostname);
const hrefPort = (/:/gi.exec(r.src) != null ? /:[0-9]*\/?/gi.exec(r.src)[0] : '{{if .RoutingTable.Source.Port}}:{{.RoutingTable.Source.Port}}{{end}}');
const hrefStr = (r.src.startsWith('/') ? hrefScheme + hrefHost + hrefPort : '{{if .RoutingTable.Source.Scheme}}{{.RoutingTable.Source.Scheme}}:{{end}}//') + r.src;
$tr.append($('<td />').append($('<a />').attr('href', hrefStr){{if .RoutingTable.Source.NewTab}}.attr('target', '_blank'){{end}}.text(r.src)));
} else {
$tr.append($('<td />').text(r.src));
}
$tr.append($('<td />').text(i+1));
$tr.append($('<td />').text(r.service));
$tr.append($('<td />').text(r.src));
$tr.append($('<td />').append($('<a />').attr('href', r.dst).text(r.dst)));
$tr.append($('<td />').text(r.opts));
$tr.append($('<td />').text((r.weight * 100).toFixed(2) + '%'));
Expand Down Expand Up @@ -145,7 +178,7 @@ $(function(){
$.each(data, function(idx, val) {
let path = val;
if (val == "") {
val = "default"
val = "default";
}
d.append(
$('<li />').append(
Expand Down
21 changes: 17 additions & 4 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,24 @@ type Listen struct {
Refresh time.Duration
}

type Source struct {
LinkEnabled bool
NewTab bool
Scheme string
Host string
Port string
}

type RoutingTable struct {
Source Source
}

type UI struct {
Listen Listen
Color string
Title string
Access string
Listen Listen
Color string
Title string
Access string
RoutingTable RoutingTable
}

type Proxy struct {
Expand Down
7 changes: 7 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ var defaultConfig = &Config{
},
Color: "light-green",
Access: "rw",
RoutingTable: RoutingTable{
Source: Source{
LinkEnabled: false,
NewTab: true,
Scheme: "http",
},
},
},

Tracing: Tracing{
Expand Down
7 changes: 7 additions & 0 deletions config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ func load(cmdline, environ, envprefix []string, props *properties.Properties) (c
f.StringVar(&uiListenerValue, "ui.addr", defaultValues.UIListenerValue, "Address the UI/API is listening on")
f.StringVar(&cfg.UI.Color, "ui.color", defaultConfig.UI.Color, "background color of the UI")
f.StringVar(&cfg.UI.Title, "ui.title", defaultConfig.UI.Title, "optional title for the UI")

f.BoolVar(&cfg.UI.RoutingTable.Source.LinkEnabled, "ui.routingtable.source.linkenabled", defaultConfig.UI.RoutingTable.Source.LinkEnabled, "optional true/false flag if the source in the routing table of the admin UI should have a link")
f.BoolVar(&cfg.UI.RoutingTable.Source.NewTab, "ui.routingtable.source.newtab", defaultConfig.UI.RoutingTable.Source.NewTab, "optional true/false flag if the source link should be opened in a new tab, not affected if linkenabled is false")
f.StringVar(&cfg.UI.RoutingTable.Source.Scheme, "ui.routingtable.source.scheme", defaultConfig.UI.RoutingTable.Source.Scheme, "optional protocol scheme for the source link on the routing table in the admin UI, not affected if linkenabled is false")
f.StringVar(&cfg.UI.RoutingTable.Source.Host, "ui.routingtable.source.host", defaultConfig.UI.RoutingTable.Source.Host, "optional host for the source link on the routing table in the admin UI, not affected if linkenabled is false")
f.StringVar(&cfg.UI.RoutingTable.Source.Port, "ui.routingtable.source.port", defaultConfig.UI.RoutingTable.Source.Port, "optional port for the host of the source link on the routing table in the admin UI, not affected if linkenabled is false")

f.StringVar(&cfg.ProfileMode, "profile.mode", defaultConfig.ProfileMode, "enable profiling mode, one of [cpu, mem, mutex, block, trace]")
f.StringVar(&cfg.ProfilePath, "profile.path", defaultConfig.ProfilePath, "path to profile dump file")
f.BoolVar(&cfg.Tracing.TracingEnabled, "tracing.TracingEnabled", defaultConfig.Tracing.TracingEnabled, "Enable/Disable OpenTrace, one of [true, false]")
Expand Down
14 changes: 14 additions & 0 deletions docs/content/ref/ui.routingtable.source.host.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: "ui.routingtable.source.host"
---

`ui.routingtable.source.host` configures an optional host or base address for the link in the source column.

This is only used when the source is not a separate server (does not begin with '/', e.g. 'dev.google.net'). If source is subdirectory it will set the link for the source to this host.
If this is not set, and the source link is enabled, the link will default to current host.

This is only applicable if the [linkenabled](/ref/ui.routingtable.source.linkenabled/) is set to true.

The default is

ui.routingtable.source.host =
9 changes: 9 additions & 0 deletions docs/content/ref/ui.routingtable.source.linkenabled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "ui.routingtable.source.linkenabled"
---

`ui.routingtable.source.linkenabled` optionally configures if the routing table's column "source" should be a clickable link.

The default is

ui.routingtable.source.linkenabled = false
12 changes: 12 additions & 0 deletions docs/content/ref/ui.routingtable.source.newtab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "ui.routingtable.source.newtab"
---

`ui.routingtable.source.scheme` configures the scheme protocol for the link of the source on the routing table. This is useful when the scheme is different than the current page
or to force the traffic to a certain protocol.

This is only applicable if the [linkenabled](/ref/ui.routingtable.source.linkenabled/) is set to true.

The default is

ui.routingtable.source.scheme = http
13 changes: 13 additions & 0 deletions docs/content/ref/ui.routingtable.source.port.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: "ui.routingtable.source.port"
---

`ui.routingtable.source.port` configures an optional port for the routing table source column link. This is used in conjunction with the [scheme](/ref/ui.routingtable.source.scheme/) and [host](/ref/ui.routingtable.source.host/).

If the source is not a separate server (does not begin with '/', e.g. 'dev.google.net'), and the [host](/ref/ui.routingtable.source.host/) is set, this will use the port that is set, or default to the current scheme protocol port (80 for http or 443 for https).

This is only applicable if the [linkenabled](/ref/ui.routingtable.source.linkenabled/) is set to true.

The default is

ui.routingtable.source.port =
12 changes: 12 additions & 0 deletions docs/content/ref/ui.routingtable.source.scheme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "ui.routingtable.source.scheme"
---

`ui.routingtable.source.scheme` configures the scheme protocol for the link of the source on the routing table. This is useful when the scheme is different than the current page or to force the traffic to a certain protocol.


This is only applicable if the [linkenabled](/ref/ui.routingtable.source.linkenabled/) is set to true.

The default is

ui.routingtable.source.scheme = http
55 changes: 55 additions & 0 deletions fabio.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,61 @@
# ui.title =


# ui.routingtable.source.linkenabled optionally configure if the
# routing table's column "source" should be a clickable link.
#
# The default is
#
# ui.routingtable.source.linkenabled = false


# ui.routingtable.source.newtab configures if the source
# link should open in a new tab.
# This is only applicable if the 'linkenabled' is set to true.
#
# The default is
#
# ui.routingtable.source.newtab = true


# ui.routingtable.source.scheme configures the scheme protocol
# for the link of the source on the routing table. This is
# useful when the scheme is different than the current page
# or to force the traffic to a certain protocol.
# This is only applicable if the 'linkenabled' is set to true.
#
# The default is
#
# ui.routingtable.source.scheme = http


# ui.routingtable.source.host configures an optional host or
# base address for the link in the source column.
# This is only used when the source is not a separate
# server (does not begin with '/', e.g. 'dev.google.net'). If
# source is subdirectory it will set the link for the source to
# this host. If this is not set, and the source link is
# enabled, the link will default to current host.
# This is only applicable if the 'linkenabled' is set to true.
#
# The default is
#
# ui.routingtable.source.host =


# ui.routingtable.source.port configures an optional port
# for the routing table source column link. This
# is used in conjunction with the host and scheme. If the
# source is not a separate server (does not begin with '/',
# e.g. 'dev.google.net'), and the host is set, or default to
# the current scheme protocol port (80 for http or 443 for https).
# This is only applicable if the 'linkenabled' is set to true.
#
# The default is
#
# ui.routingtable.source.port =


# Open Trace Configuration Currently supports ZipKin Collector
# tracing.TracingEnabled enables/disables Open Tracing in Fabio. Bool value true/false
#
Expand Down

0 comments on commit 87c4da1

Please sign in to comment.