Skip to content

Commit

Permalink
hide internal labels from UI (#18638)
Browse files Browse the repository at this point in the history
* hide labels from UI

* add test cases for hidding teleport.internal/ labels

* move labels logic to separate file

* move constant to right api/types/constants.go

* add godoc to makeLabels and rework label constants

Co-authored-by: Jim Bishopp <jim@goteleport.com>
  • Loading branch information
sielakos and jimbishopp authored Dec 6, 2022
1 parent 7b4c99b commit f0dbc34
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 84 deletions.
21 changes: 12 additions & 9 deletions api/types/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,26 +474,29 @@ const (
)

const (
// TeleportInternalLabelPrefix is the prefix used by all Teleport internal labels
TeleportInternalLabelPrefix = "teleport.internal/"

// BotLabel is a label used to identify a resource used by a certificate renewal bot.
BotLabel = "teleport.internal/bot"
BotLabel = TeleportInternalLabelPrefix + "bot"

// BotGenerationLabel is a label used to record the certificate generation counter.
BotGenerationLabel = "teleport.internal/bot-generation"
BotGenerationLabel = TeleportInternalLabelPrefix + "bot-generation"

// InternalResourceIDLabel is a label used to store an ID to correlate between two resources
// A pratical example of this is to create a correlation between a Node Provision Token and
// the Node that used that token to join the cluster
InternalResourceIDLabel = "teleport.internal/resource-id"
InternalResourceIDLabel = TeleportInternalLabelPrefix + "resource-id"

// AlertOnLogin is an internal label that indicates an alert should be displayed to users on login
AlertOnLogin = "teleport.internal/alert-on-login"
AlertOnLogin = TeleportInternalLabelPrefix + "alert-on-login"

// AlertPermitAll is an internal label that indicates that an alert is suitable for display
// to all users.
AlertPermitAll = "teleport.internal/alert-permit-all"
AlertPermitAll = TeleportInternalLabelPrefix + "alert-permit-all"

// AlertLink is an internal label that indicates that an alert is a link.
AlertLink = "teleport.internal/link"
AlertLink = TeleportInternalLabelPrefix + "link"

// AlertVerbPermit is an internal label that permits a user to view the alert if they
// hold a specific resource permission verb (e.g. 'node:list'). Note that this label is
Expand All @@ -502,17 +505,17 @@ const (
// label selectors or where clauses, it can't reliably protect information related to a
// specific resource. This label should be used only for permitting of alerts that are
// of concern to holders of a given <resource>:<verb> capability in the most general case.
AlertVerbPermit = "teleport.internal/alert-verb-permit"
AlertVerbPermit = TeleportInternalLabelPrefix + "alert-verb-permit"

// AlertSupersedes is an internal label used to indicate when one alert supersedes
// another. Teleport may choose to hide the superseded alert if the superseding alert
// is also visible to the user and of higher or equivalent severity. This intended as
// a mechanism for reducing noise/redundancy, and is not a form of access control. Use
// one of the "permit" labels if you need to restrict viewership of an alert.
AlertSupersedes = "teleport.internal/alert-supersedes"
AlertSupersedes = TeleportInternalLabelPrefix + "alert-supersedes"

// AlertLicenseExpired is an internal label that indicates that the license has expired.
AlertLicenseExpired = "teleport.internal/license-expired-warning"
AlertLicenseExpired = TeleportInternalLabelPrefix + "license-expired-warning"
)

// RequestableResourceKinds lists all Teleport resource kinds users can request access to.
Expand Down
11 changes: 1 addition & 10 deletions lib/web/ui/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package ui

import (
"fmt"
"sort"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/tlsca"
Expand Down Expand Up @@ -66,15 +65,7 @@ func MakeApps(c MakeAppsConfig) []App {
result := []App{}
for _, teleApp := range c.Apps {
fqdn := AssembleAppFQDN(c.LocalClusterName, c.LocalProxyDNSName, c.AppClusterName, teleApp)
labels := []Label{}
for name, value := range teleApp.GetAllLabels() {
labels = append(labels, Label{
Name: name,
Value: value,
})
}

sort.Sort(sortedLabels(labels))
labels := makeLabels(teleApp.GetAllLabels())

app := App{
Name: teleApp.GetName(),
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)
}
})
}
}
59 changes: 59 additions & 0 deletions lib/web/ui/labels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
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 (
"sort"
"strings"

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

// makeLabels is a function that transforms map[string]string arguments passed to it to sorted slice of Labels.
// It also removes all Teleport internal labels from output.
func makeLabels(labelMaps ...map[string]string) []Label {
length := 0
for _, labelMap := range labelMaps {
length += len(labelMap)
}

labels := make([]Label, 0, length)

for _, labelMap := range labelMaps {
for name, value := range labelMap {
if strings.HasPrefix(name, types.TeleportInternalLabelPrefix) {
continue
}

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

sort.Sort(sortedLabels(labels))

return labels
}

func transformCommandLabels(commandLabels map[string]types.CommandLabel) map[string]string {
labels := make(map[string]string, len(commandLabels))

for name, cmd := range commandLabels {
labels[name] = cmd.GetResult()
}

return labels
}
135 changes: 135 additions & 0 deletions lib/web/ui/labels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
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 TestMakeLabels(t *testing.T) {
type testCase struct {
name string
labelMaps []map[string]string
expected []Label
}

testCases := []testCase{
{
name: "Single map single label case",
labelMaps: []map[string]string{
{
"label1": "value1",
},
},
expected: []Label{
{
Name: "label1",
Value: "value1",
},
},
},
{
name: "Single map multiple labels case",
labelMaps: []map[string]string{
{
"label1": "value1",
"label2": "value2",
},
},
expected: []Label{
{
Name: "label1",
Value: "value1",
},
{
Name: "label2",
Value: "value2",
},
},
},
{
name: "Multiple maps single label case",
labelMaps: []map[string]string{
{
"label1": "value1",
},
{
"label2": "value2",
},
},
expected: []Label{
{
Name: "label1",
Value: "value1",
},
{
Name: "label2",
Value: "value2",
},
},
},
{
name: "Multiple maps with internal labels",
labelMaps: []map[string]string{
{
"label1": "value1",
"teleport.internal/label3": "value3",
},
{
"label2": "value2",
"teleport.internal/label4": "value4",
},
},
expected: []Label{
{
Name: "label1",
Value: "value1",
},
{
Name: "label2",
Value: "value2",
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
labels := makeLabels(tc.labelMaps...)

require.Equal(t, tc.expected, labels)
})
}
}

func TestTransformCommandLabels(t *testing.T) {
commandLabels := map[string]types.CommandLabel{
"label1": &types.CommandLabelV2{
Result: "value1",
},
}
labels := transformCommandLabels(commandLabels)
expected := map[string]string{
"label1": "value1",
}

require.Equal(t, expected, labels)
}
Loading

0 comments on commit f0dbc34

Please sign in to comment.