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

Introduce a new check for extension namespace configuration #11629

Merged
merged 4 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions cli/cmd/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func configureAndRunChecks(cmd *cobra.Command, wout io.Writer, werr io.Writer, o
checks = append(checks, healthcheck.LinkerdOpaquePortsDefinitionChecks)
} else {
checks = append(checks, healthcheck.LinkerdControlPlaneVersionChecks)
checks = append(checks, healthcheck.LinkerdExtensionChecks)
}
checks = append(checks, healthcheck.LinkerdCNIPluginChecks)
checks = append(checks, healthcheck.LinkerdHAChecks)
Expand Down
69 changes: 68 additions & 1 deletion pkg/healthcheck/healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ const (
// corresponding pods
LinkerdOpaquePortsDefinitionChecks CategoryID = "linkerd-opaque-ports-definition"

// LinkerdExtensionChecks adds checks to validate configuration for all
// extensions discovered in the cluster at runtime
LinkerdExtensionChecks CategoryID = "linkerd-extension-checks"

// LinkerdCNIResourceLabel is the label key that is used to identify
// whether a Kubernetes resource is related to the install-cni command
// The value is expected to be "true", "false" or "", where "false" and
Expand Down Expand Up @@ -1414,6 +1418,20 @@ func (hc *HealthChecker) allCategories() []*Category {
},
false,
),
NewCategory(
LinkerdExtensionChecks,
[]Checker{
{
description: "namespace configuration for extensions",
warning: true,
hintAnchor: "l5d-extension-namespaces",
check: func(ctx context.Context) error {
return hc.checkExtensionNsLabels(ctx)
},
},
},
false,
),
}
}

Expand Down Expand Up @@ -2673,7 +2691,7 @@ func (hc *HealthChecker) checkExtensionAPIServerAuthentication(ctx context.Conte
func (hc *HealthChecker) checkClockSkew(ctx context.Context) error {
if hc.kubeAPI == nil {
// we should never get here
return fmt.Errorf("unexpected error: Kubernetes ClientSet not initialized")
return errors.New("unexpected error: Kubernetes ClientSet not initialized")
}

var clockSkewNodes []string
Expand Down Expand Up @@ -2702,6 +2720,55 @@ func (hc *HealthChecker) checkClockSkew(ctx context.Context) error {
return nil
}

func (hc *HealthChecker) checkExtensionNsLabels(ctx context.Context) error {
if hc.kubeAPI == nil {
// oops something wrong happened
return errors.New("unexpected error: Kubernetes ClientSet not initialized")
}

namespaces, err := hc.kubeAPI.GetAllNamespacesWithExtensionLabel(ctx)
if err != nil {
return fmt.Errorf("unexpected error when retrieving namespaces: %s", err)
}

freq := make(map[string][]string)
for _, ns := range namespaces {
// We can guarantee the namespace has the extension label since we used
// a label selector when retrieving namespaces
ext := ns.Labels[k8s.LinkerdExtensionLabel]
// To make it easier to print, store already error-formatted namespace
// in freq table
freq[ext] = append(freq[ext], fmt.Sprintf("\t * %s", ns.Name))
}

errs := []string{}
for ext, namespaces := range freq {
if len(namespaces) == 1 {
continue
}
errs = append(errs, fmt.Sprintf("* label \"%s=%s\" is present on more than one namespace:\n%s", k8s.LinkerdExtensionLabel, ext, strings.Join(namespaces, "\n")))
}

if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n "))
}

return nil

/*
if err != nil {
return false, false, err
}
nsLabels := []string{}
for _, ns := range namespaces {
ext := ns.Labels[k8s.LinkerdExtensionLabel]
nsLabels = append(nsLabels, ext)
}

*/
mateiidavid marked this conversation as resolved.
Show resolved Hide resolved

}

// CheckRoles checks that the expected roles exist.
func CheckRoles(ctx context.Context, kubeAPI *k8s.KubernetesAPI, shouldExist bool, namespace string, expectedNames []string, labelSelector string) error {
options := metav1.ListOptions{
Expand Down
Loading