Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide internal labels from UI #18638

Merged
merged 15 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/web/ui/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package ui
import (
"fmt"
"sort"
"strings"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/tlsca"
Expand Down Expand Up @@ -68,6 +69,10 @@ func MakeApps(c MakeAppsConfig) []App {
fqdn := AssembleAppFQDN(c.LocalClusterName, c.LocalProxyDNSName, c.AppClusterName, teleApp)
labels := []Label{}
for name, value := range teleApp.GetAllLabels() {
if strings.HasPrefix(name, "teleport.internal/") {
sielakos marked this conversation as resolved.
Show resolved Hide resolved
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of repeating the same filtering logic in all locations and writing tests for each, why not create a function that removes labels from the map returned by GetAllLabels? That way we'd only need to test the new function rather than adding tests for all the places that require this logic.

func removeHiddenLabels(m map[string]string) map[string]string {
	for name := range m {
		if strings.HasPrefix(name, "teleport.internal/") {
			delete(m, name)
		}
	}
	return m // return map so it can be used directly in for loops
}

// ... then 
for name, value := range removeHiddenLabels(teleApp.GetAllLabels()) {

This would isolate all testing to this new func - no need to test all places where the labels are hidden. Also makes it much easier to add new scenarios for hidden labels.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that function would be good, I could go even deeper because there is no need to repeat logic appending Labels to slice. It looks exactly the same everywhere.

About tests, I actually would like to keep them. I would even love to add more unit tests for those functions, as they are not tested that way. Unless there is a reason not to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So with a bit of refactoring, I have added makeLabels function that does all the repetitive stuff related to labels.

  1. transforming from maps to slice
  2. filtering
  3. sorting

I have also added tests for this function.

All that taken into account I would actually like to leave tests for MakeServers etc. as they are. If for no other reason than just to test that makeLabels is used.


labels = append(labels, Label{
Name: name,
Value: value,
Expand Down
76 changes: 76 additions & 0 deletions lib/web/ui/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2020 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 (
"testing"

"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/types"
)

func TestMakeAppsLabelFilter(t *testing.T) {
type testCase struct {
types.Apps
expected []App
name string
}

testCases := []testCase{
{
name: "Single App with teleport.internal/ label",
Apps: types.Apps{
&types.AppV3{
Metadata: types.Metadata{
Name: "App1",
Labels: map[string]string{
"first": "value1",
"teleport.internal/dd": "hidden1",
},
},
},
},
expected: []App{
{
Name: "App1",
Labels: []Label{
{
Name: "first",
Value: "value1",
},
},
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
config := MakeAppsConfig{
Apps: tc.Apps,
}
apps := MakeApps(config)

for i, app := range apps {
expectedLabels := tc.expected[i].Labels

require.Equal(t, expectedLabels, app.Labels)
}
})
}
}
30 changes: 28 additions & 2 deletions lib/web/ui/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ func MakeServers(clusterName string, servers []types.Server, userRoles services.
uiLabels := []Label{}
serverLabels := server.GetStaticLabels()
for name, value := range serverLabels {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: value,
Expand Down Expand Up @@ -128,13 +132,21 @@ func MakeKubeClusters(clusters []types.KubeCluster, userRoles services.RoleSet)
uiLabels := make([]Label, 0, len(staticLabels)+len(dynamicLabels))

for name, value := range staticLabels {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: value,
})
}

for name, cmd := range dynamicLabels {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: cmd.GetResult(),
Expand Down Expand Up @@ -162,7 +174,10 @@ func MakeKubeClusters(clusters []types.KubeCluster, userRoles services.RoleSet)
// This function ignores any verification of the TTL associated with
// each Role, and focuses only on listing all users and groups that the user may
// have access to.
func getAllowedKubeUsersAndGroupsForCluster(roles services.RoleSet, kube types.KubeCluster) (kubeUsers []string, kubeGroups []string) {
func getAllowedKubeUsersAndGroupsForCluster(
roles services.RoleSet,
kube types.KubeCluster,
) (kubeUsers []string, kubeGroups []string) {
sielakos marked this conversation as resolved.
Show resolved Hide resolved
matcher := services.NewKubernetesClusterLabelMatcher(kube.GetAllLabels())
// We ignore the TTL verification because we want to include every possibility.
// Later, if the user certificate expiration is longer than the maximum allowed TTL
Expand Down Expand Up @@ -236,10 +251,13 @@ type Database struct {

// MakeDatabase creates database objects.
func MakeDatabase(database types.Database, dbUsers, dbNames []string) Database {

uiLabels := []Label{}

for name, value := range database.GetAllLabels() {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: value,
Expand Down Expand Up @@ -297,6 +315,10 @@ func MakeDesktop(windowsDesktop types.WindowsDesktop) Desktop {
uiLabels := []Label{}

for name, value := range windowsDesktop.GetAllLabels() {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: value,
Expand Down Expand Up @@ -342,6 +364,10 @@ func MakeDesktopService(desktopService types.WindowsDesktopService) DesktopServi
uiLabels := []Label{}

for name, value := range desktopService.GetAllLabels() {
if strings.HasPrefix(name, "teleport.internal/") {
continue
}

uiLabels = append(uiLabels, Label{
Name: name,
Value: value,
Expand Down
151 changes: 151 additions & 0 deletions lib/web/ui/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,154 @@ func makeTestKubeCluster(t *testing.T, labels map[string]string) types.KubeClust
require.NoError(t, err)
return s
}

func TestMakeClusterHiddenLabels(t *testing.T) {
type testCase struct {
name string
clusters []types.KubeCluster
expectedLabels [][]Label
roleSet services.RoleSet
}

testCases := []testCase{
{
name: "Single server with internal label",
clusters: []types.KubeCluster{
makeTestKubeCluster(t, map[string]string{
"teleport.internal/test": "value1",
"label2": "value2",
}),
},
expectedLabels: [][]Label{
{
{
Name: "label2",
Value: "value2",
},
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
clusters := MakeKubeClusters(tc.clusters, tc.roleSet)
for i, cluster := range clusters {
require.Equal(t, tc.expectedLabels[i], cluster.Labels)
}
})
}
}

func TestMakeServersHiddenLabels(t *testing.T) {
type testCase struct {
name string
clusterName string
servers []types.Server
expectedLabels [][]Label
roleSet services.RoleSet
}

testCases := []testCase{
{
name: "Single server with internal label",
clusterName: "cluster1",
servers: []types.Server{
makeTestServer(t, "server1", map[string]string{
"simple": "value1",
"teleport.internal/app": "app1",
}),
},
expectedLabels: [][]Label{
{
{
Name: "simple",
Value: "value1",
},
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
servers := MakeServers(tc.clusterName, tc.servers, tc.roleSet)
for i, server := range servers {
require.Equal(t, tc.expectedLabels[i], server.Labels)
}
})
}
}

func makeTestServer(t *testing.T, name string, labels map[string]string) types.Server {
server, err := types.NewServerWithLabels(name, types.KindNode, types.ServerSpecV2{}, labels)
require.NoError(t, err)
return server
}

func TestMakeDatabaseHiddenLabels(t *testing.T) {
inputDb := &types.DatabaseV3{
Metadata: types.Metadata{
Name: "db name",
Labels: map[string]string{
"label": "value1",
"teleport.internal/label2": "value2",
},
},
}

outputDb := MakeDatabase(inputDb, nil, nil)

require.Equal(t, []Label{
{
Name: "label",
Value: "value1",
},
}, outputDb.Labels)
}

func TestMakeDesktopHiddenLabel(t *testing.T) {
windowsDesktop := &types.WindowsDesktopV3{
ResourceHeader: types.ResourceHeader{
Metadata: types.Metadata{
Labels: map[string]string{
"teleport.internal/t2": "tt",
"label3": "value2",
},
},
},
}

desktop := MakeDesktop(windowsDesktop)
labels := []Label{
{
Name: "label3",
Value: "value2",
},
}

require.Equal(t, labels, desktop.Labels)
}

func TestMakeDesktopServiceHiddenLabel(t *testing.T) {
windowsDesktopService := &types.WindowsDesktopServiceV3{
ResourceHeader: types.ResourceHeader{
Metadata: types.Metadata{
Labels: map[string]string{
"teleport.internal/t2": "tt",
"label3": "value2",
},
},
},
}

desktopService := MakeDesktopService(windowsDesktopService)
labels := []Label{
{
Name: "label3",
Value: "value2",
},
}

require.Equal(t, labels, desktopService.Labels)
}