From 00ab9e949aab5034f28ef46c43bbf8a8cee3d7f8 Mon Sep 17 00:00:00 2001 From: Matt Hook Date: Thu, 16 May 2024 09:03:10 +1200 Subject: [PATCH] fix(pending-actions): correctly detect unreachable/down cluster [EE-7049] (#11809) --- api/kubernetes/cli/server_version.go | 7 +++++++ api/pendingactions/pendingactions.go | 12 ++++++++++-- api/portainer.go | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 api/kubernetes/cli/server_version.go diff --git a/api/kubernetes/cli/server_version.go b/api/kubernetes/cli/server_version.go new file mode 100644 index 000000000..b529c22f7 --- /dev/null +++ b/api/kubernetes/cli/server_version.go @@ -0,0 +1,7 @@ +package cli + +import "k8s.io/apimachinery/pkg/version" + +func (kcl *KubeClient) ServerVersion() (*version.Info, error) { + return kcl.cli.Discovery().ServerVersion() +} diff --git a/api/pendingactions/pendingactions.go b/api/pendingactions/pendingactions.go index be5a466f0..0bc4c0def 100644 --- a/api/pendingactions/pendingactions.go +++ b/api/pendingactions/pendingactions.go @@ -73,8 +73,16 @@ func (service *PendingActionsService) Execute(id portainer.EndpointID) { return } } else { - // For Kubernetes endpoints, we need to check if the client can be created - if _, err := service.kubeFactory.GetKubeClient(endpoint); err != nil { + // For Kubernetes endpoints, we need to check if the endpoint is up by + // creating a kube client and performing a simple operation + client, err := service.kubeFactory.GetKubeClient(endpoint) + if err != nil { + log.Debug().Msgf("failed to create Kubernetes client for environment %d: %v", id, err) + return + } + + if _, err = client.ServerVersion(); err != nil { + log.Debug().Err(err).Msgf("Environment %q (id: %d) is not up", endpoint.Name, id) return } } diff --git a/api/portainer.go b/api/portainer.go index 9ffcb9a3b..3c6da319f 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -14,6 +14,7 @@ import ( "github.com/portainer/portainer/pkg/featureflags" "golang.org/x/oauth2" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/version" ) type ( @@ -1487,6 +1488,8 @@ type ( // KubeClient represents a service used to query a Kubernetes environment(endpoint) KubeClient interface { + ServerVersion() (*version.Info, error) + SetupUserServiceAccount(userID int, teamIDs []int, restrictDefaultNamespace bool) error IsRBACEnabled() (bool, error) GetServiceAccount(tokendata *TokenData) (*v1.ServiceAccount, error)