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

fix: telepresence http server check #251

Merged
merged 4 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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: 1 addition & 4 deletions kardinal-cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ var telepresenceInterceptCmd = &cobra.Command{

// Is the port open and HTTP
if err := isPortOpenAndHTTP(localPort); err != nil {
log.Fatalf("An error occurred checking port '%s': %s", localPort, err)
log.Fatalf("An error occurred checking HTTP server on port '%s': %s", localPort, err)
}

// is Traffic-manager installed
Expand Down Expand Up @@ -424,9 +424,6 @@ func isPortOpenAndHTTP(localPortStr string) error {
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
lostbean marked this conversation as resolved.
Show resolved Hide resolved
return stacktrace.NewError("the HTTP server in 'httpServerAddr' did not return a successful response. Got '%d'", resp.StatusCode)
}
return nil
}

Expand Down
114 changes: 112 additions & 2 deletions kardinal-manager/kardinal-manager/cluster_manager/cluster_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cluster_manager
import (
"context"
"encoding/json"
"k8s.io/apimachinery/pkg/labels"
"strings"

"github.com/kurtosis-tech/kardinal/libs/manager-kontrol-api/api/golang/types"
Expand Down Expand Up @@ -305,6 +306,13 @@ func (manager *ClusterManager) CleanUpClusterResources(ctx context.Context, clus
return nil
}

if isEmpty(clusterResources) {
lostbean marked this conversation as resolved.
Show resolved Hide resolved
if err := manager.removeKardinalNamespaces(ctx); err != nil {
return stacktrace.Propagate(err, "an error occurred removing the Kardinal namespaces")
}
return nil
}

// Clean up virtual services
virtualServicesByNS := lo.GroupBy(*clusterResources.VirtualServices, func(item v1alpha3.VirtualService) string { return item.Namespace })
for namespace, virtualServices := range virtualServicesByNS {
Expand Down Expand Up @@ -399,6 +407,70 @@ func (manager *ClusterManager) CleanUpClusterResources(ctx context.Context, clus
return nil
}

func (manager *ClusterManager) getKardinalNamespaces(ctx context.Context) (*corev1.NamespaceList, error) {
labels := map[string]string{
istioLabel: enabledIstioValue,
kardinalLabelKey: enabledKardinal,
}

kardinalNamespaces, err := manager.getNamespacesByLabels(ctx, labels)
if err != nil {
return nil, stacktrace.Propagate(err, "an error occurred getting Kardinal namespaces using labels '%+v'", labels)
}

return kardinalNamespaces, nil
}

func (manager *ClusterManager) removeKardinalNamespaces(ctx context.Context) error {
kardinalNamespaces, err := manager.getKardinalNamespaces(ctx)
if err != nil {
return stacktrace.Propagate(err, "an error occurred getting Kardinal namespaces")
}

for _, namespace := range kardinalNamespaces.Items {
if err := manager.removeNamespace(ctx, &namespace); err != nil {
return stacktrace.Propagate(err, "an error occurred while removing Kardinal namespace '%s'", namespace.GetName())
}
}
return nil
}

func (manager *ClusterManager) getNamespacesByLabels(ctx context.Context, namespaceLabels map[string]string) (*corev1.NamespaceList, error) {
namespaceClient := manager.kubernetesClient.clientSet.CoreV1().Namespaces()

listOptions := buildListOptionsFromLabels(namespaceLabels)
namespaces, err := namespaceClient.List(ctx, listOptions)
if err != nil {
return nil, stacktrace.Propagate(err, "Failed to list namespaces with labels '%+v'", namespaceLabels)
}

// Only return objects not tombstoned by Kubernetes
var namespacesNotMarkedForDeletionList []corev1.Namespace
for _, namespace := range namespaces.Items {
deletionTimestamp := namespace.GetObjectMeta().GetDeletionTimestamp()
if deletionTimestamp == nil {
namespacesNotMarkedForDeletionList = append(namespacesNotMarkedForDeletionList, namespace)
}
}
namespacesNotMarkedForDeletionnamespaceList := corev1.NamespaceList{
Items: namespacesNotMarkedForDeletionList,
TypeMeta: namespaces.TypeMeta,
ListMeta: namespaces.ListMeta,
}
return &namespacesNotMarkedForDeletionnamespaceList, nil
}

func (manager *ClusterManager) removeNamespace(ctx context.Context, namespace *corev1.Namespace) error {
name := namespace.Name
namespaceClient := manager.kubernetesClient.clientSet.CoreV1().Namespaces()

if err := namespaceClient.Delete(ctx, name, globalDeleteOptions); err != nil {
return stacktrace.Propagate(err, "Failed to delete namespace with name '%s' with delete options '%+v'", name, globalDeleteOptions)
}

return nil
}

func (manager *ClusterManager) ensureNamespace(ctx context.Context, name string) error {

if name == istioSystemNamespace {
Expand Down Expand Up @@ -837,14 +909,33 @@ func isValid(clusterResources *types.ClusterResources) bool {
clusterResources.Deployments == nil &&
clusterResources.DestinationRules == nil &&
clusterResources.Services == nil &&
clusterResources.VirtualServices == nil {
logrus.Debugf("cluster resources is empty.")
clusterResources.VirtualServices == nil &&
clusterResources.AuthorizationPolicies == nil &&
clusterResources.EnvoyFilters == nil &&
clusterResources.Ingresses == nil {
logrus.Debugf("cluster resources is invalid because all the internal fields are nil.")
return false
}

return true
}

func isEmpty(clusterResources *types.ClusterResources) bool {
if clusterResources != nil &&
len(*clusterResources.Gateways) == 0 &&
len(*clusterResources.HttpRoutes) == 0 &&
len(*clusterResources.Deployments) == 0 &&
len(*clusterResources.DestinationRules) == 0 &&
len(*clusterResources.Services) == 0 &&
len(*clusterResources.VirtualServices) == 0 &&
len(*clusterResources.AuthorizationPolicies) == 0 &&
len(*clusterResources.EnvoyFilters) == 0 &&
len(*clusterResources.Ingresses) == 0 {
return true
}
return false
}

func deepCheckEqual(a, b interface{}) bool {
aj, err := json.Marshal(a)
if err != nil {
Expand All @@ -856,3 +947,22 @@ func deepCheckEqual(a, b interface{}) bool {
}
return string(aj) == string(bj)
}

func buildListOptionsFromLabels(labelsMap map[string]string) metav1.ListOptions {
return metav1.ListOptions{
TypeMeta: metav1.TypeMeta{
Kind: "",
APIVersion: "",
},
LabelSelector: labels.SelectorFromSet(labelsMap).String(),
FieldSelector: "",
Watch: false,
AllowWatchBookmarks: false,
ResourceVersion: "",
ResourceVersionMatch: "",
TimeoutSeconds: int64Ptr(listOptionsTimeoutSeconds),
Limit: 0,
Continue: "",
SendInitialEvents: nil,
}
}
Loading