Skip to content
This repository was archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
Merge branch 'lporoli/fix-clean-resources' into lporoli/fix-tel-inter
Browse files Browse the repository at this point in the history
  • Loading branch information
leoporoli committed Sep 26, 2024
2 parents 8a7e17a + c76ef72 commit ba44d21
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ All you need is a Kubernetes cluster with Istio enabled, and kubectl installed o
Make sure that kubectl is pointing to your cluster, and then run the following command:

```
kardinal manager deploy kloud-kontrol
kardinal manager deploy kloud-kardinal-kontrol
```

Once installed check out our docs on [creating your first flow](https://kardinal.dev/docs/getting-started/own-app).
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) {
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,
}
}
4 changes: 2 additions & 2 deletions website/app/docs/getting-started/install/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ istioctl install --set profile=default -y
Make sure that `kubectl` is pointing to your cluster, and then run the following command:

```bash
kardinal manager deploy kloud-kontrol
kardinal manager deploy kloud-kardinal-kontrol
```

Now the Kardinal Manager is deployed in your cluster, you're ready to set up your baseline application and start creating flows.
Expand Down Expand Up @@ -95,4 +95,4 @@ To create a flow on the demo application, run:
kardinal flow create frontend kurtosistech/frontend:demo-on-sale -s productcatalogservice=kurtosistech/productcatalogservice:demo-on-sale
```

For a more in-depth guide to deploying your own application and creating a flow, see our guide on [deploying Kardinal on your own app](/getting-started/own-app).
For a more in-depth guide to deploying your own application and creating a flow, see our guide on [deploying Kardinal on your own app](/getting-started/own-app).
2 changes: 1 addition & 1 deletion website/components/GetStarted/CodeSnippet.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
```bash
curl get.kardinal.dev -sL | sh
kardinal manager deploy kloud-kontrol
kardinal manager deploy kloud-kardinal-kontrol
curl -O https://raw.githubusercontent.com/kurtosis-tech/kardinal-playground/main/obd-demo.yaml
kardinal deploy -k obd-demo.yaml
```

0 comments on commit ba44d21

Please sign in to comment.