diff --git a/scripts/dev/delete_om_projects.sh b/scripts/dev/delete_om_projects.sh index 4978df786..4c31b2b42 100755 --- a/scripts/dev/delete_om_projects.sh +++ b/scripts/dev/delete_om_projects.sh @@ -32,10 +32,31 @@ delete_project() { delete_project "${NAMESPACE}" +# Delete resource-specific projects (e.g. mongodb-test-mdb-sh) that the operator +# creates when a MongoDB CR uses a custom project name. Without this, stale +# automation configs persist in Cloud Manager across test runs, causing cert +# hash mismatches that deadlock the agent. +delete_projects_with_prefix() { + local prefix=$1 + echo "Listing projects with prefix '${prefix}-' to clean up" + local projects + projects=$(curl -s -u "${OM_USER}:${OM_API_KEY}" --digest \ + "${OM_HOST}/api/public/v1.0/groups?itemsPerPage=100" \ + | jq -r ".results[]? | select(.name | startswith(\"${prefix}-\")) | .name") || true + if [[ -z "${projects}" ]]; then + echo "No prefixed projects found" + return + fi + for project_name in ${projects}; do + delete_project "${project_name}" || true + done +} + +delete_projects_with_prefix "${NAMESPACE}" + if [[ "${WATCH_NAMESPACE:-}" != "" && "${WATCH_NAMESPACE:-}" != "*" ]]; then for ns in ${WATCH_NAMESPACE/,// }; do delete_project "${ns}" || true + delete_projects_with_prefix "${ns}" || true done fi - - diff --git a/scripts/dev/prepare-multi-cluster/main.go b/scripts/dev/prepare-multi-cluster/main.go index 8a0e2f704..f07a08e72 100644 --- a/scripts/dev/prepare-multi-cluster/main.go +++ b/scripts/dev/prepare-multi-cluster/main.go @@ -86,8 +86,8 @@ func main() { runParallel(cfg.memberClusters, func(cluster string) { collectError := collectErrorFor(cluster) ensureNamespace(ctx, clients[cluster], cluster, cfg.namespace, cfg.taskID, collectError) - labelNamespaceIstio(ctx, clients[cluster], cluster, cfg.namespace, collectError) if cfg.applyMTLS { + labelNamespaceIstio(ctx, clients[cluster], cluster, cfg.namespace, collectError) applyPeerAuthentication(ctx, dynamicClients[cluster], cluster, cfg.namespace, collectError) } }) @@ -211,6 +211,12 @@ type config struct { func loadConfig() config { localVal := os.Getenv("local") // nolint:forbidigo noMesh := os.Getenv("MULTI_CLUSTER_NO_MESH") // nolint:forbidigo + // The old bash code defaulted MULTI_CLUSTER_NO_MESH to "true" when unset: + // "${MULTI_CLUSTER_NO_MESH:-"true"}" != "true" + // So mTLS is only applied when MULTI_CLUSTER_NO_MESH is explicitly set to something other than "true". + if noMesh == "" { + noMesh = "true" + } applyMTLS := localVal == "" && noMesh != "true" cfg := config{ diff --git a/scripts/dev/reset/main.go b/scripts/dev/reset/main.go index 86c5f8e19..890aff274 100644 --- a/scripts/dev/reset/main.go +++ b/scripts/dev/reset/main.go @@ -160,6 +160,32 @@ func resetContext(ctx context.Context, contextName string, deleteCRD bool, colle fmt.Printf("Finished resetting context %s\n", contextName) } +// removeIstioConfig removes Istio sidecar injection label and PeerAuthentication from the namespace. +// This prevents Istio artifacts from a multi-cluster run from leaking into subsequent single-cluster tests. +func removeIstioConfig(ctx context.Context, kubeClient *kubernetes.Clientset, dynamicClient dynamic.Interface, namespace string, collectError func(error, string)) { + // Remove istio-injection label from namespace + ns, err := kubeClient.CoreV1().Namespaces().Get(ctx, namespace, v1.GetOptions{}) + if err == nil && ns.Labels["istio-injection"] != "" { + delete(ns.Labels, "istio-injection") + _, err = kubeClient.CoreV1().Namespaces().Update(ctx, ns, v1.UpdateOptions{}) + collectError(err, fmt.Sprintf("failed to remove istio-injection label from namespace %s", namespace)) + } + + // Delete PeerAuthentication resources + peerAuthGVR := schema.GroupVersionResource{ + Group: "security.istio.io", + Version: "v1beta1", + Resource: "peerauthentications", + } + err = dynamicClient.Resource(peerAuthGVR).Namespace(namespace).DeleteCollection(ctx, deleteOptionsNoGrace, v1.ListOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + // Ignore "the server could not find the requested resource" when Istio CRDs are not installed + if !strings.Contains(err.Error(), "could not find the requested resource") { + collectError(err, fmt.Sprintf("failed to delete PeerAuthentication resources in namespace %s", namespace)) + } + } +} + // resetNamespace cleans up the namespace in the given context func resetNamespace(ctx context.Context, contextName string, namespace string, deleteCRD bool, collectError func(error, string)) { kubeClient, dynamicClient, err := initKubeClient(contextName) @@ -168,6 +194,9 @@ func resetNamespace(ctx context.Context, contextName string, namespace string, d return } + // Remove Istio configuration that may have been set by a previous multi-cluster test + removeIstioConfig(ctx, kubeClient, dynamicClient, namespace, collectError) + // Hack: remove the statefulset for backup daemon first - otherwise it may get stuck on removal if AppDB is removed first stsList, err := kubeClient.AppsV1().StatefulSets(namespace).List(ctx, v1.ListOptions{}) collectError(err, "failed to list statefulsets")