Skip to content

Commit

Permalink
viz: Prohibit authority resource targets in stat commands (#13578)
Browse files Browse the repository at this point in the history
There are plans to remove the authority label in inbound proxy metrics. When that happens we would not longer be able to use the viz stat/top commands to query by `authority`. This is a change to disable being able to invoke these commands with an `authority` resource target.

Signed-off-by: Zahari Dichev <[email protected]>
  • Loading branch information
zaharidichev authored Jan 23, 2025
1 parent a726757 commit 31a5806
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 421 deletions.
7 changes: 0 additions & 7 deletions pkg/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
// These constants are string representations of Kubernetes resource types.
const (
All = "all"
Authority = "authority"
ConfigMap = "configmap"
CronJob = "cronjob"
DaemonSet = "daemonset"
Expand Down Expand Up @@ -73,7 +72,6 @@ type resourceName struct {

// AllResources is a sorted list of all resources defined as constants above.
var AllResources = []string{
Authority,
AuthorizationPolicy,
CronJob,
DaemonSet,
Expand All @@ -100,7 +98,6 @@ var StatAllResourceTypes = []string{
ReplicationController,
Pod,
Service,
Authority,
CronJob,
ReplicaSet,
}
Expand All @@ -115,13 +112,11 @@ var CompletionResourceTypes = []string{
ReplicationController,
Pod,
Service,
Authority,
CronJob,
ReplicaSet,
}

var resourceNames = []resourceName{
{"au", "authority", "authorities"},
{"cj", "cronjob", "cronjobs"},
{"ds", "daemonset", "daemonsets"},
{"deploy", "deployment", "deployments"},
Expand Down Expand Up @@ -190,8 +185,6 @@ func PluralResourceNameFromFriendlyName(friendlyName string) (string, error) {
// Essentially the reverse of CanonicalResourceNameFromFriendlyName
func ShortNameFromCanonicalResourceName(canonicalName string) string {
switch canonicalName {
case Authority:
return "au"
case CronJob:
return "cj"
case DaemonSet:
Expand Down
2 changes: 0 additions & 2 deletions pkg/k8s/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ func TestCanonicalResourceNameFromFriendlyName(t *testing.T) {
"pod": Pod,
"deployment": Deployment,
"deployments": Deployment,
"au": Authority,
"authorities": Authority,
"cj": CronJob,
"cronjob": CronJob,
"serverauthz": ServerAuthorization,
Expand Down
43 changes: 3 additions & 40 deletions test/integration/external/stat/stat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -37,7 +36,7 @@ func TestMain(m *testing.M) {
// requesting, and the test will pass.
func TestCliStatForLinkerdNamespace(t *testing.T) {
ctx := context.Background()
var prometheusPod, prometheusAuthority, prometheusNamespace, prometheusDeployment, metricsPod string
var prometheusPod, prometheusNamespace, prometheusDeployment, metricsPod string
// Get Metrics Pod
pods, err := TestHelper.GetPodNamesForDeployment(ctx, TestHelper.GetVizNamespace(), "metrics-api")
if err != nil {
Expand All @@ -62,13 +61,11 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
testutil.Fatalf(t, "expected 1 pod for prometheus, got %d", len(pods))
}
prometheusPod = pods[0]
prometheusAuthority = prometheusDeployment + "." + prometheusNamespace + ".svc.cluster.local:9090"

testCases := []struct {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetLinkerdNamespace()},
Expand Down Expand Up @@ -103,35 +100,13 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
"metrics-api": "1/1",
},
},
{
args: []string{"viz", "stat", "po", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("au/%s", prometheusAuthority), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
metricsPod: "1/1",
},
status: "Running",
},
{
args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
prometheusAuthority: "-",
},
isAuthority: true,
},
{
args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
prometheusAuthority: "-",
},
isAuthority: true,
},
}

if !TestHelper.ExternalPrometheus() {
testCases = append(testCases, []struct {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
Expand Down Expand Up @@ -162,7 +137,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
Expand Down Expand Up @@ -212,7 +186,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "svc", "-n", prefixedNs},
Expand Down Expand Up @@ -244,9 +217,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
}

expectedColumnCount := 8
if tt.isAuthority {
expectedColumnCount = 7
}
if tt.status != "" {
expectedColumnCount++
}
Expand All @@ -256,7 +226,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
}

for name, meshed := range tt.expectedRows {
if err := validateRowStats(name, meshed, tt.status, rowStats, tt.isAuthority); err != nil {
if err := validateRowStats(name, meshed, tt.status, rowStats); err != nil {
return err
}
}
Expand All @@ -271,7 +241,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
})
}

func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat, isAuthority bool) error {
func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat) error {
stat, ok := rowStats[name]
if !ok {
return fmt.Errorf("no stats found for [%s]", name)
Expand Down Expand Up @@ -313,12 +283,5 @@ func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats m
name, stat.P99Latency)
}

if stat.TCPOpenConnections != "-" && !isAuthority {
_, err := strconv.Atoi(stat.TCPOpenConnections)
if err != nil {
return fmt.Errorf("error parsing number of TCP connections [%s]: %w", stat.TCPOpenConnections, err)
}
}

return nil
}
43 changes: 3 additions & 40 deletions test/integration/viz/stat/stat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -37,7 +36,7 @@ func TestMain(m *testing.M) {
// requesting, and the test will pass.
func TestCliStatForLinkerdNamespace(t *testing.T) {
ctx := context.Background()
var prometheusPod, prometheusAuthority, prometheusNamespace, prometheusDeployment, metricsPod string
var prometheusPod, prometheusNamespace, prometheusDeployment, metricsPod string
// Get Metrics Pod
pods, err := TestHelper.GetPodNamesForDeployment(ctx, TestHelper.GetVizNamespace(), "metrics-api")
if err != nil {
Expand All @@ -62,13 +61,11 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
testutil.Fatalf(t, "expected 1 pod for prometheus, got %d", len(pods))
}
prometheusPod = pods[0]
prometheusAuthority = prometheusDeployment + "." + prometheusNamespace + ".svc.cluster.local:9090"

testCases := []struct {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetLinkerdNamespace()},
Expand Down Expand Up @@ -103,35 +100,13 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
"metrics-api": "1/1",
},
},
{
args: []string{"viz", "stat", "po", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("au/%s", prometheusAuthority), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
metricsPod: "1/1",
},
status: "Running",
},
{
args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
prometheusAuthority: "-",
},
isAuthority: true,
},
{
args: []string{"viz", "stat", "au", "-n", TestHelper.GetVizNamespace(), "--to", fmt.Sprintf("po/%s", prometheusPod), "--to-namespace", prometheusNamespace},
expectedRows: map[string]string{
prometheusAuthority: "-",
},
isAuthority: true,
},
}

if !TestHelper.ExternalPrometheus() {
testCases = append(testCases, []struct {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
Expand Down Expand Up @@ -162,7 +137,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "deploy", "-n", TestHelper.GetVizNamespace()},
Expand Down Expand Up @@ -212,7 +186,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
args []string
expectedRows map[string]string
status string
isAuthority bool
}{
{
args: []string{"viz", "stat", "svc", "-n", prefixedNs},
Expand Down Expand Up @@ -244,9 +217,6 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
}

expectedColumnCount := 8
if tt.isAuthority {
expectedColumnCount = 7
}
if tt.status != "" {
expectedColumnCount++
}
Expand All @@ -256,7 +226,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
}

for name, meshed := range tt.expectedRows {
if err := validateRowStats(name, meshed, tt.status, rowStats, tt.isAuthority); err != nil {
if err := validateRowStats(name, meshed, tt.status, rowStats); err != nil {
return err
}
}
Expand All @@ -271,7 +241,7 @@ func TestCliStatForLinkerdNamespace(t *testing.T) {
})
}

func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat, isAuthority bool) error {
func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats map[string]*testutil.RowStat) error {
stat, ok := rowStats[name]
if !ok {
return fmt.Errorf("No stats found for [%s]", name)
Expand Down Expand Up @@ -313,12 +283,5 @@ func validateRowStats(name, expectedMeshCount, expectedStatus string, rowStats m
name, stat.P99Latency)
}

if stat.TCPOpenConnections != "-" && !isAuthority {
_, err := strconv.Atoi(stat.TCPOpenConnections)
if err != nil {
return fmt.Errorf("Error parsing number of TCP connections [%s]: %w", stat.TCPOpenConnections, err)
}
}

return nil
}
2 changes: 1 addition & 1 deletion viz/cmd/edges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestEdges(t *testing.T) {
t.Run("Returns an error if request is for authority", func(t *testing.T) {
options.outputFormat = tableOutput
args := []string{"authority"}
expectedError := "Resource type is not supported: authority"
expectedError := "cannot find Kubernetes canonical name from friendly name [authority]"

_, err := buildEdgesRequests(args, options)
if err == nil || err.Error() != expectedError {
Expand Down
5 changes: 2 additions & 3 deletions viz/cmd/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/healthcheck"
"github.com/linkerd/linkerd2/pkg/k8s"
pb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
"github.com/linkerd/linkerd2/viz/metrics-api/util"
"github.com/linkerd/linkerd2/viz/pkg/api"
Expand Down Expand Up @@ -379,7 +378,7 @@ func buildTopRoutesRequest(resource string, options *routesOptions) (*pb.TopRout
LabelSelector: options.labelSelector,
}

options.dstIsService = target.GetType() != k8s.Authority
options.dstIsService = true

if options.toResource != "" {
if options.toNamespace == "" {
Expand All @@ -390,7 +389,7 @@ func buildTopRoutesRequest(resource string, options *routesOptions) (*pb.TopRout
return nil, err
}

options.dstIsService = toRes.GetType() != k8s.Authority
options.dstIsService = true

requestParams.ToName = toRes.Name
requestParams.ToNamespace = toRes.Namespace
Expand Down
6 changes: 3 additions & 3 deletions viz/cmd/stat.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ func statHasRequestData(stat *pb.BasicStats) bool {
}

func isPodOwnerResource(typ string) bool {
return typ != k8s.Authority && typ != k8s.Service && typ != k8s.Server && typ != k8s.ServerAuthorization && typ != k8s.AuthorizationPolicy && typ != k8s.HTTPRoute
return typ != k8s.Service && typ != k8s.Server && typ != k8s.ServerAuthorization && typ != k8s.AuthorizationPolicy && typ != k8s.HTTPRoute
}

func writeStatsToBuffer(rows []*pb.StatTable_PodGroup_Row, w *tabwriter.Writer, options *statOptions) {
Expand Down Expand Up @@ -433,7 +433,7 @@ func writeStatsToBuffer(rows []*pb.StatTable_PodGroup_Row, w *tabwriter.Writer,
statTables[resourceKey][key] = &row{}
if resourceKey != k8s.Server && resourceKey != k8s.ServerAuthorization {
meshedCount := fmt.Sprintf("%d/%d", r.MeshedPodCount, r.RunningPodCount)
if resourceKey == k8s.Authority || resourceKey == k8s.Service {
if resourceKey == k8s.Service {
meshedCount = "-"
}
statTables[resourceKey][key] = &row{
Expand Down Expand Up @@ -503,7 +503,7 @@ func showTCPBytes(options *statOptions, resourceType string) bool {
}

func showTCPConns(resourceType string) bool {
return resourceType != k8s.Authority && resourceType != k8s.ServerAuthorization && resourceType != k8s.AuthorizationPolicy && resourceType != k8s.HTTPRoute
return resourceType != k8s.ServerAuthorization && resourceType != k8s.AuthorizationPolicy && resourceType != k8s.HTTPRoute
}

func printSingleStatTable(stats map[string]*row, resourceTypeLabel, resourceType string, w *tabwriter.Writer, maxNameLength, maxNamespaceLength, maxLeafLength, maxApexLength, maxDstLength, maxWeightLength int, options *statOptions) {
Expand Down
Loading

0 comments on commit 31a5806

Please sign in to comment.