TUN-6583: Remove legacy --ui flag

This commit is contained in:
Devin Carr
2022-07-20 16:17:29 -07:00
parent 1733fe8c65
commit 2a177e0fc4
171 changed files with 19 additions and 31556 deletions

View File

@@ -25,7 +25,6 @@ import (
"github.com/cloudflare/cloudflared/cfapi"
"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
"github.com/cloudflare/cloudflared/cmd/cloudflared/proxydns"
"github.com/cloudflare/cloudflared/cmd/cloudflared/ui"
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
"github.com/cloudflare/cloudflared/config"
"github.com/cloudflare/cloudflared/connection"
@@ -218,7 +217,7 @@ func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath stri
// runClassicTunnel creates a "classic" non-named tunnel
func runClassicTunnel(sc *subcommandContext) error {
return StartServer(sc.c, buildInfo, nil, sc.log, sc.isUIEnabled)
return StartServer(sc.c, buildInfo, nil, sc.log)
}
func routeFromFlag(c *cli.Context) (route cfapi.HostnameRoute, ok bool) {
@@ -236,7 +235,6 @@ func StartServer(
info *cliutil.BuildInfo,
namedTunnel *connection.NamedTunnelProperties,
log *zerolog.Logger,
isUIEnabled bool,
) error {
_ = raven.SetDSN(sentryDSN)
var wg sync.WaitGroup
@@ -331,9 +329,9 @@ func StartServer(
return fmt.Errorf(errText)
}
logTransport := logger.CreateTransportLoggerFromContext(c, isUIEnabled)
logTransport := logger.CreateTransportLoggerFromContext(c, logger.EnableTerminalLog)
observer := connection.NewObserver(log, logTransport, isUIEnabled)
observer := connection.NewObserver(log, logTransport)
// Send Quick Tunnel URL to UI if applicable
var quickTunnelURL string
@@ -392,18 +390,6 @@ func StartServer(
errC <- supervisor.StartTunnelDaemon(ctx, tunnelConfig, orchestrator, connectedSignal, reconnectCh, graceShutdownC)
}()
if isUIEnabled {
tunnelUI := ui.NewUIModel(
info.Version(),
hostname,
metricsListener.Addr().String(),
orchestratorConfig.Ingress,
tunnelConfig.HAConnections,
)
app := tunnelUI.Launch(ctx, log, logTransport)
observer.RegisterSink(app)
}
gracePeriod, err := gracePeriod(c)
if err != nil {
return err
@@ -663,9 +649,9 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
}),
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: uiFlag,
Usage: "Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.",
Usage: "(depreciated) Launch tunnel UI. Tunnel logs are scrollable via 'j', 'k', or arrow keys.",
Value: false,
Hidden: shouldHide,
Hidden: true,
}),
altsrc.NewStringFlag(&cli.StringFlag{
Name: "quick-service",

View File

@@ -78,7 +78,6 @@ func RunQuickTunnel(sc *subcommandContext) error {
buildInfo,
&connection.NamedTunnelProperties{Credentials: credentials, QuickTunnelUrl: data.Result.Hostname},
sc.log,
sc.isUIEnabled,
)
}

View File

@@ -31,10 +31,9 @@ func (e errInvalidJSONCredential) Error() string {
// subcommandContext carries structs shared between subcommands, to reduce number of arguments needed to
// pass between subcommands, and make sure they are only initialized once
type subcommandContext struct {
c *cli.Context
log *zerolog.Logger
isUIEnabled bool
fs fileSystem
c *cli.Context
log *zerolog.Logger
fs fileSystem
// These fields should be accessed using their respective Getter
tunnelstoreClient cfapi.Client
@@ -42,16 +41,10 @@ type subcommandContext struct {
}
func newSubcommandContext(c *cli.Context) (*subcommandContext, error) {
isUIEnabled := c.IsSet(uiFlag) && c.String("name") != ""
// If UI is enabled, terminal log output should be disabled -- log should be written into a UI log window instead
log := logger.CreateLoggerFromContext(c, isUIEnabled)
return &subcommandContext{
c: c,
log: log,
isUIEnabled: isUIEnabled,
fs: realFileSystem{},
c: c,
log: logger.CreateLoggerFromContext(c, logger.EnableTerminalLog),
fs: realFileSystem{},
}, nil
}
@@ -312,7 +305,6 @@ func (sc *subcommandContext) runWithCredentials(credentials connection.Credentia
buildInfo,
&connection.NamedTunnelProperties{Credentials: credentials},
sc.log,
sc.isUIEnabled,
)
}

View File

@@ -35,7 +35,6 @@ func Test_subcommandContext_findCredentials(t *testing.T) {
type fields struct {
c *cli.Context
log *zerolog.Logger
isUIEnabled bool
fs fileSystem
tunnelstoreClient cfapi.Client
userCredential *userCredential
@@ -168,7 +167,6 @@ func Test_subcommandContext_findCredentials(t *testing.T) {
sc := &subcommandContext{
c: tt.fields.c,
log: tt.fields.log,
isUIEnabled: tt.fields.isUIEnabled,
fs: tt.fields.fs,
tunnelstoreClient: tt.fields.tunnelstoreClient,
userCredential: tt.fields.userCredential,
@@ -307,7 +305,6 @@ func Test_subcommandContext_Delete(t *testing.T) {
sc := &subcommandContext{
c: tt.fields.c,
log: tt.fields.log,
isUIEnabled: tt.fields.isUIEnabled,
fs: tt.fields.fs,
tunnelstoreClient: tt.fields.tunnelstoreClient,
userCredential: tt.fields.userCredential,

View File

@@ -1,223 +0,0 @@
package ui
import (
"context"
"fmt"
"strings"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
"github.com/rs/zerolog"
"github.com/cloudflare/cloudflared/connection"
"github.com/cloudflare/cloudflared/ingress"
)
type connState struct {
location string
}
type uiModel struct {
version string
edgeURL string
metricsURL string
localServices []string
connections []connState
}
type palette struct {
url string
connected string
defaultText string
disconnected string
reconnecting string
unregistered string
}
func NewUIModel(version, hostname, metricsURL string, ing *ingress.Ingress, haConnections int) *uiModel {
localServices := make([]string, len(ing.Rules))
for i, rule := range ing.Rules {
localServices[i] = rule.Service.String()
}
return &uiModel{
version: version,
edgeURL: hostname,
metricsURL: metricsURL,
localServices: localServices,
connections: make([]connState, haConnections),
}
}
func (data *uiModel) Launch(
ctx context.Context,
log, transportLog *zerolog.Logger,
) connection.EventSink {
// Configure the logger to stream logs into the textview
// Add TextView as a group to write output to
logTextView := NewDynamicColorTextView()
// TODO: Format log for UI
//log.Add(logTextView, logger.NewUIFormatter(time.RFC3339), logLevels...)
//transportLog.Add(logTextView, logger.NewUIFormatter(time.RFC3339), logLevels...)
// Construct the UI
palette := palette{
url: "lightblue",
connected: "lime",
defaultText: "white",
disconnected: "red",
reconnecting: "orange",
unregistered: "orange",
}
app := tview.NewApplication()
grid := tview.NewGrid().SetGap(1, 0)
frame := tview.NewFrame(grid)
header := fmt.Sprintf("cloudflared [::b]%s", data.version)
frame.AddText(header, true, tview.AlignLeft, tcell.ColorWhite)
// Create table to store connection info and status
connTable := tview.NewTable()
// SetColumns takes a value for each column, representing the size of the column
// Numbers <= 0 represent proportional widths and positive numbers represent absolute widths
grid.SetColumns(20, 0)
// SetRows takes a value for each row, representing the size of the row
grid.SetRows(1, 1, len(data.connections), 1, 0)
// AddItem takes a primitive tview type, row, column, rowSpan, columnSpan, minGridHeight, minGridWidth, and focus
grid.AddItem(tview.NewTextView().SetText("Tunnel:"), 0, 0, 1, 1, 0, 0, false)
grid.AddItem(tview.NewTextView().SetText("Status:"), 1, 0, 1, 1, 0, 0, false)
grid.AddItem(tview.NewTextView().SetText("Connections:"), 2, 0, 1, 1, 0, 0, false)
grid.AddItem(tview.NewTextView().SetText("Metrics:"), 3, 0, 1, 1, 0, 0, false)
tunnelHostText := tview.NewTextView().SetText(data.edgeURL)
grid.AddItem(tunnelHostText, 0, 1, 1, 1, 0, 0, false)
status := fmt.Sprintf("[%s]\u2022[%s] Proxying to [%s::b]%s", palette.connected, palette.defaultText, palette.url, strings.Join(data.localServices, ", "))
grid.AddItem(NewDynamicColorTextView().SetText(status), 1, 1, 1, 1, 0, 0, false)
grid.AddItem(connTable, 2, 1, 1, 1, 0, 0, false)
grid.AddItem(NewDynamicColorTextView().SetText(fmt.Sprintf("Metrics at [%s::b]http://%s/metrics", palette.url, data.metricsURL)), 3, 1, 1, 1, 0, 0, false)
// Add TextView to stream logs
// Logs are displayed in a new grid so a border can be set around them
logGrid := tview.NewGrid().SetBorders(true).AddItem(logTextView.SetChangedFunc(handleNewText(app, logTextView)), 0, 0, 5, 2, 0, 0, false)
// LogFrame holds the Logs header as well as the grid with the textView for streamed logs
logFrame := tview.NewFrame(logGrid).AddText("[::b]Logs:[::-]", true, tview.AlignLeft, tcell.ColorWhite).SetBorders(0, 0, 0, 0, 0, 0)
// Footer for log frame
logFrame.AddText("[::d]Use Ctrl+C to exit[::-]", false, tview.AlignRight, tcell.ColorWhite)
grid.AddItem(logFrame, 4, 0, 5, 2, 0, 0, false)
go func() {
<-ctx.Done()
app.Stop()
return
}()
go func() {
if err := app.SetRoot(frame, true).Run(); err != nil {
log.Error().Msgf("Error launching UI: %s", err)
}
}()
return connection.EventSinkFunc(func(event connection.Event) {
switch event.EventType {
case connection.Connected:
data.setConnTableCell(event, connTable, palette)
case connection.Disconnected, connection.Reconnecting, connection.Unregistering:
data.changeConnStatus(event, connTable, log, palette)
case connection.SetURL:
tunnelHostText.SetText(event.URL)
data.edgeURL = event.URL
case connection.RegisteringTunnel:
if data.edgeURL == "" {
tunnelHostText.SetText(fmt.Sprintf("Registering tunnel connection %d...", event.Index))
}
}
app.Draw()
})
}
func NewDynamicColorTextView() *tview.TextView {
return tview.NewTextView().SetDynamicColors(true)
}
// Re-draws application when new logs are streamed to UI
func handleNewText(app *tview.Application, logTextView *tview.TextView) func() {
return func() {
app.Draw()
// SetFocus to enable scrolling in textview
app.SetFocus(logTextView)
}
}
func (data *uiModel) changeConnStatus(event connection.Event, table *tview.Table, log *zerolog.Logger, palette palette) {
index := int(event.Index)
// Get connection location and state
connState := data.getConnState(index)
// Check if connection is already displayed in UI
if connState == nil {
log.Info().Msg("Connection is not in the UI table")
return
}
locationState := event.Location
if event.EventType == connection.Reconnecting {
locationState = "Reconnecting..."
}
connectionNum := index + 1
// Get table cell
cell := table.GetCell(index, 0)
// Change dot color in front of text as well as location state
text := newCellText(palette, connectionNum, locationState, event.EventType)
cell.SetText(text)
}
// Return connection location and row in UI table
func (data *uiModel) getConnState(connID int) *connState {
if connID < len(data.connections) {
return &data.connections[connID]
}
return nil
}
func (data *uiModel) setConnTableCell(event connection.Event, table *tview.Table, palette palette) {
index := int(event.Index)
connectionNum := index + 1
// Update slice to keep track of connection location and state in UI table
data.connections[index].location = event.Location
// Update text in table cell to show disconnected state
text := newCellText(palette, connectionNum, event.Location, event.EventType)
cell := tview.NewTableCell(text)
table.SetCell(index, 0, cell)
}
func newCellText(palette palette, connectionNum int, location string, connectedStatus connection.Status) string {
// HA connection indicator formatted as: "• #<CONNECTION_INDEX>: <COLO>",
// where the left middle dot's color depends on the status of the connection
const connFmtString = "[%s]\u2022[%s] #%d: %s"
var dotColor string
switch connectedStatus {
case connection.Connected:
dotColor = palette.connected
case connection.Disconnected:
dotColor = palette.disconnected
case connection.Reconnecting:
dotColor = palette.reconnecting
case connection.Unregistering:
dotColor = palette.unregistered
}
return fmt.Sprintf(connFmtString, dotColor, palette.defaultText, connectionNum, location)
}