mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
fix(kubernetes): kube env permissions when down [EE-5427] (#10327)
This commit is contained in:
parent
cc37ccfe4d
commit
14853f6da0
18 changed files with 282 additions and 103 deletions
113
api/pendingactions/pendingactions.go
Normal file
113
api/pendingactions/pendingactions.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package pendingactions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/internal/authorization"
|
||||
kubecli "github.com/portainer/portainer/api/kubernetes/cli"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type (
|
||||
PendingActionsService struct {
|
||||
authorizationService *authorization.Service
|
||||
clientFactory *kubecli.ClientFactory
|
||||
dataStore dataservices.DataStore
|
||||
shutdownCtx context.Context
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
)
|
||||
|
||||
func NewService(
|
||||
dataStore dataservices.DataStore,
|
||||
clientFactory *kubecli.ClientFactory,
|
||||
authorizationService *authorization.Service,
|
||||
shutdownCtx context.Context,
|
||||
) *PendingActionsService {
|
||||
return &PendingActionsService{
|
||||
dataStore: dataStore,
|
||||
shutdownCtx: shutdownCtx,
|
||||
authorizationService: authorizationService,
|
||||
clientFactory: clientFactory,
|
||||
mu: sync.Mutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (service *PendingActionsService) Create(r portainer.PendingActions) error {
|
||||
return service.dataStore.PendingActions().Create(&r)
|
||||
}
|
||||
|
||||
func (service *PendingActionsService) Execute(id portainer.EndpointID) error {
|
||||
|
||||
service.mu.Lock()
|
||||
defer service.mu.Unlock()
|
||||
|
||||
endpoint, err := service.dataStore.Endpoint().Endpoint(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve endpoint %d: %w", id, err)
|
||||
}
|
||||
|
||||
if endpoint.Status != portainer.EndpointStatusUp {
|
||||
log.Debug().Msgf("Endpoint %d is not up", id)
|
||||
return fmt.Errorf("endpoint %d is not up: %w", id, err)
|
||||
}
|
||||
|
||||
pendingActions, err := service.dataStore.PendingActions().ReadAll()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed to retrieve pending actions")
|
||||
return fmt.Errorf("failed to retrieve pending actions for endpoint %d: %w", id, err)
|
||||
}
|
||||
|
||||
for _, endpointPendingAction := range pendingActions {
|
||||
if endpointPendingAction.EndpointID == id {
|
||||
err := service.executePendingAction(endpointPendingAction, endpoint)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed to execute pending action")
|
||||
return fmt.Errorf("failed to execute pending action: %w", err)
|
||||
} else {
|
||||
// delete the pending action
|
||||
err := service.dataStore.PendingActions().Delete(endpointPendingAction.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed to delete pending action")
|
||||
return fmt.Errorf("failed to delete pending action: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service *PendingActionsService) executePendingAction(pendingAction portainer.PendingActions, endpoint *portainer.Endpoint) error {
|
||||
log.Debug().Msgf("Executing pending action %s for endpoint %d", pendingAction.Action, pendingAction.EndpointID)
|
||||
|
||||
defer func() {
|
||||
log.Debug().Msgf("End executing pending action %s for endpoint %d", pendingAction.Action, pendingAction.EndpointID)
|
||||
}()
|
||||
|
||||
switch pendingAction.Action {
|
||||
case "CleanNAPWithOverridePolicies":
|
||||
if (pendingAction.ActionData == nil) || (pendingAction.ActionData.(portainer.EndpointGroupID) == 0) {
|
||||
service.authorizationService.CleanNAPWithOverridePolicies(service.dataStore, endpoint, nil)
|
||||
} else {
|
||||
endpointGroupID := pendingAction.ActionData.(portainer.EndpointGroupID)
|
||||
endpointGroup, err := service.dataStore.EndpointGroup().Read(portainer.EndpointGroupID(endpointGroupID))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Error reading endpoint group to clean NAP with override policies for endpoint %d and endpoint group %d", endpoint.ID, endpointGroup.ID)
|
||||
return fmt.Errorf("failed to retrieve endpoint group %d: %w", endpointGroupID, err)
|
||||
}
|
||||
err = service.authorizationService.CleanNAPWithOverridePolicies(service.dataStore, endpoint, endpointGroup)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Error cleaning NAP with override policies for endpoint %d and endpoint group %d", endpoint.ID, endpointGroup.ID)
|
||||
return fmt.Errorf("failed to clean NAP with override policies for endpoint %d and endpoint group %d: %w", endpoint.ID, endpointGroup.ID, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue