mirror of
https://github.com/gravitational/teleport.git
synced 2026-11-03 07:40:28 +08:00
344 lines
9.9 KiB
Go
344 lines
9.9 KiB
Go
/*
|
|
Copyright 2015 Gravitational, Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package ui
|
|
|
|
import (
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gravitational/teleport/api/constants"
|
|
"github.com/gravitational/teleport/api/types"
|
|
"github.com/gravitational/teleport/lib/defaults"
|
|
"github.com/gravitational/teleport/lib/services"
|
|
)
|
|
|
|
// Label describes label for webapp
|
|
type Label struct {
|
|
// Name is this label name
|
|
Name string `json:"name"`
|
|
// Value is this label value
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
// Server describes a server for webapp
|
|
type Server struct {
|
|
// Tunnel indicates of this server is connected over a reverse tunnel.
|
|
Tunnel bool `json:"tunnel"`
|
|
// Name is this server name
|
|
Name string `json:"id"`
|
|
// ClusterName is this server cluster name
|
|
ClusterName string `json:"siteId"`
|
|
// Hostname is this server hostname
|
|
Hostname string `json:"hostname"`
|
|
// Addrr is this server ip address
|
|
Addr string `json:"addr"`
|
|
// Labels is this server list of labels
|
|
Labels []Label `json:"tags"`
|
|
// SSHLogins is the list of logins this user can use on this server
|
|
SSHLogins []string `json:"sshLogins"`
|
|
}
|
|
|
|
// sortedLabels is a sort wrapper that sorts labels by name
|
|
type sortedLabels []Label
|
|
|
|
func (s sortedLabels) Len() int {
|
|
return len(s)
|
|
}
|
|
|
|
func (s sortedLabels) Less(i, j int) bool {
|
|
return s[i].Name < s[j].Name
|
|
}
|
|
|
|
func (s sortedLabels) Swap(i, j int) {
|
|
s[i], s[j] = s[j], s[i]
|
|
}
|
|
|
|
// MakeServers creates server objects for webapp
|
|
func MakeServers(clusterName string, servers []types.Server, userRoles services.RoleSet) []Server {
|
|
uiServers := []Server{}
|
|
for _, server := range servers {
|
|
uiLabels := []Label{}
|
|
serverLabels := server.GetStaticLabels()
|
|
for name, value := range serverLabels {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
serverCmdLabels := server.GetCmdLabels()
|
|
for name, cmd := range serverCmdLabels {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: cmd.GetResult(),
|
|
})
|
|
}
|
|
|
|
sort.Sort(sortedLabels(uiLabels))
|
|
|
|
serverLogins := userRoles.EnumerateServerLogins(server)
|
|
sshLogins := serverLogins.Allowed()
|
|
if sshLogins == nil {
|
|
sshLogins = []string{}
|
|
}
|
|
|
|
uiServers = append(uiServers, Server{
|
|
ClusterName: clusterName,
|
|
Labels: uiLabels,
|
|
Name: server.GetName(),
|
|
Hostname: server.GetHostname(),
|
|
Addr: server.GetAddr(),
|
|
Tunnel: server.GetUseTunnel(),
|
|
SSHLogins: sshLogins,
|
|
})
|
|
}
|
|
|
|
return uiServers
|
|
}
|
|
|
|
// KubeCluster describes a kube cluster.
|
|
type KubeCluster struct {
|
|
// Name is the name of the kube cluster.
|
|
Name string `json:"name"`
|
|
// Labels is a map of static and dynamic labels associated with an kube cluster.
|
|
Labels []Label `json:"labels"`
|
|
}
|
|
|
|
// MakeKubes creates ui kube objects and returns a list..
|
|
func MakeKubeClusters(clusters []types.KubeCluster) []KubeCluster {
|
|
uiKubeClusters := make([]KubeCluster, 0, len(clusters))
|
|
for _, cluster := range clusters {
|
|
staticLabels := cluster.GetStaticLabels()
|
|
dynamicLabels := cluster.GetDynamicLabels()
|
|
uiLabels := make([]Label, 0, len(staticLabels)+len(dynamicLabels))
|
|
|
|
for name, value := range staticLabels {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
for name, cmd := range dynamicLabels {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: cmd.GetResult(),
|
|
})
|
|
}
|
|
|
|
sort.Sort(sortedLabels(uiLabels))
|
|
|
|
uiKubeClusters = append(uiKubeClusters, KubeCluster{
|
|
Name: cluster.GetName(),
|
|
Labels: uiLabels,
|
|
})
|
|
}
|
|
|
|
return uiKubeClusters
|
|
}
|
|
|
|
// ConnectionDiagnostic describes a connection diagnostic.
|
|
type ConnectionDiagnostic struct {
|
|
// ID is the identifier of the connection diagnostic.
|
|
ID string `json:"id"`
|
|
// Success is whether the connection was successful
|
|
Success bool `json:"success"`
|
|
// Message is the diagnostic summary
|
|
Message string `json:"message"`
|
|
// Traces contains multiple checkpoints results
|
|
Traces []ConnectionDiagnosticTraceUI `json:"traces,omitempty"`
|
|
}
|
|
|
|
// ConnectionDiagnosticTraceUI describes a connection diagnostic trace using a UI representation.
|
|
// This is required in order to have a more friendly representation of the enum fields - TraceType and Status.
|
|
// They are converted into string instead of using the numbers (as they are represented in gRPC).
|
|
type ConnectionDiagnosticTraceUI struct {
|
|
// TraceType as string
|
|
TraceType string `json:"traceType,omitempty"`
|
|
// Status as string
|
|
Status string `json:"status,omitempty"`
|
|
// Details of the trace
|
|
Details string `json:"details,omitempty"`
|
|
// Error in case of failure
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
// ConnectionDiagnosticTraceUIFromTypes converts a list of ConnectionDiagnosticTrace into its format for HTTP API.
|
|
// This is mostly copying things around and converting the enum into a string value.
|
|
func ConnectionDiagnosticTraceUIFromTypes(traces []*types.ConnectionDiagnosticTrace) []ConnectionDiagnosticTraceUI {
|
|
ret := make([]ConnectionDiagnosticTraceUI, 0)
|
|
|
|
for _, t := range traces {
|
|
ret = append(ret, ConnectionDiagnosticTraceUI{
|
|
TraceType: t.Type.String(),
|
|
Status: t.Status.String(),
|
|
Details: t.Details,
|
|
Error: t.Error,
|
|
})
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
// Database describes a database server.
|
|
type Database struct {
|
|
// Name is the name of the database.
|
|
Name string `json:"name"`
|
|
// Desc is the database description.
|
|
Desc string `json:"desc"`
|
|
// Protocol is the database description.
|
|
Protocol string `json:"protocol"`
|
|
// Type is the database type, self-hosted or cloud-hosted.
|
|
Type string `json:"type"`
|
|
// Labels is a map of static and dynamic labels associated with a database.
|
|
Labels []Label `json:"labels"`
|
|
}
|
|
|
|
// MakeDatabases creates database objects.
|
|
func MakeDatabases(clusterName string, databases []types.Database) []Database {
|
|
uiServers := make([]Database, 0, len(databases))
|
|
for _, database := range databases {
|
|
uiLabels := []Label{}
|
|
|
|
for name, value := range database.GetStaticLabels() {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
for name, cmd := range database.GetDynamicLabels() {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: cmd.GetResult(),
|
|
})
|
|
}
|
|
|
|
sort.Sort(sortedLabels(uiLabels))
|
|
|
|
uiServers = append(uiServers, Database{
|
|
Name: database.GetName(),
|
|
Desc: database.GetDescription(),
|
|
Protocol: database.GetProtocol(),
|
|
Type: database.GetType(),
|
|
Labels: uiLabels,
|
|
})
|
|
}
|
|
|
|
return uiServers
|
|
}
|
|
|
|
// Desktop describes a desktop to pass to the ui.
|
|
type Desktop struct {
|
|
// OS is the os of this desktop. Should be one of constants.WindowsOS, constants.LinuxOS, or constants.DarwinOS.
|
|
OS string `json:"os"`
|
|
// Name is name (uuid) of the windows desktop.
|
|
Name string `json:"name"`
|
|
// Addr is the network address the desktop can be reached at.
|
|
Addr string `json:"addr"`
|
|
// Labels is a map of static and dynamic labels associated with a desktop.
|
|
Labels []Label `json:"labels"`
|
|
// HostID is the ID of the Windows Desktop Service reporting the desktop.
|
|
HostID string `json:"host_id"`
|
|
}
|
|
|
|
// MakeDesktop converts a desktop from its API form to a type the UI can display.
|
|
func MakeDesktop(windowsDesktop types.WindowsDesktop) Desktop {
|
|
// stripRdpPort strips the default rdp port from an ip address since it is unimportant to display
|
|
stripRdpPort := func(addr string) string {
|
|
splitAddr := strings.Split(addr, ":")
|
|
if len(splitAddr) > 1 && splitAddr[1] == strconv.Itoa(defaults.RDPListenPort) {
|
|
return splitAddr[0]
|
|
}
|
|
return addr
|
|
}
|
|
uiLabels := []Label{}
|
|
|
|
for name, value := range windowsDesktop.GetAllLabels() {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
sort.Sort(sortedLabels(uiLabels))
|
|
|
|
return Desktop{
|
|
OS: constants.WindowsOS,
|
|
Name: windowsDesktop.GetName(),
|
|
Addr: stripRdpPort(windowsDesktop.GetAddr()),
|
|
Labels: uiLabels,
|
|
HostID: windowsDesktop.GetHostID(),
|
|
}
|
|
}
|
|
|
|
// MakeDesktops converts desktops from their API form to a type the UI can display.
|
|
func MakeDesktops(windowsDesktops []types.WindowsDesktop) []Desktop {
|
|
uiDesktops := make([]Desktop, 0, len(windowsDesktops))
|
|
|
|
for _, windowsDesktop := range windowsDesktops {
|
|
uiDesktops = append(uiDesktops, MakeDesktop(windowsDesktop))
|
|
}
|
|
|
|
return uiDesktops
|
|
}
|
|
|
|
// DesktopService describes a desktop service to pass to the ui.
|
|
type DesktopService struct {
|
|
// Name is hostname of the Windows Desktop Service.
|
|
Name string `json:"name"`
|
|
// Hostname is hostname of the Windows Desktop Service.
|
|
Hostname string `json:"hostname"`
|
|
// Addr is the network address the Windows Desktop Service can be reached at.
|
|
Addr string `json:"addr"`
|
|
// Labels is a map of static and dynamic labels associated with a desktop.
|
|
Labels []Label `json:"labels"`
|
|
}
|
|
|
|
// MakeDesktop converts a desktop from its API form to a type the UI can display.
|
|
func MakeDesktopService(desktopService types.WindowsDesktopService) DesktopService {
|
|
uiLabels := []Label{}
|
|
|
|
for name, value := range desktopService.GetAllLabels() {
|
|
uiLabels = append(uiLabels, Label{
|
|
Name: name,
|
|
Value: value,
|
|
})
|
|
}
|
|
|
|
sort.Sort(sortedLabels(uiLabels))
|
|
|
|
return DesktopService{
|
|
Name: desktopService.GetName(),
|
|
Hostname: desktopService.GetHostname(),
|
|
Addr: desktopService.GetAddr(),
|
|
Labels: uiLabels,
|
|
}
|
|
}
|
|
|
|
// MakeDesktopServices converts desktops from their API form to a type the UI can display.
|
|
func MakeDesktopServices(windowsDesktopServices []types.WindowsDesktopService) []DesktopService {
|
|
desktopServices := make([]DesktopService, 0, len(windowsDesktopServices))
|
|
|
|
for _, desktopService := range windowsDesktopServices {
|
|
desktopServices = append(desktopServices, MakeDesktopService(desktopService))
|
|
}
|
|
|
|
return desktopServices
|
|
}
|