mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-27 14:07:31 +00:00
5d53fa7a3d
pulse_control only plans typed resource actions into Pulse Actions (executeControlResource -> typedActionPlanner). The handlers that sat behind the retired model-authored command, file and container paths stayed in the tree with no production caller: run command, guest control, app-container control, Docker control and container update, Kubernetes scale/restart/delete-pod/exec, and file append/write. registerFileTools was never called either, so pulse_file_edit is not registered at all; calls to it are denied by the mutation registry before any tool lookup. A whole-program reachability run over cmd/... lists each of them as unreachable, and so is everything only they used: approval-record and preflight authoring, the command and native-action audit lanes with their remediation-lock gate and plan-hash helpers, the Docker host resolvers, and the file write verification. The executor's autonomous flag, whose only readers were those handlers, goes with them (the executor's SetAutonomousMode and the flag argument of SetContext). Delete them with their tests and the constants, types and test helpers they stranded. The contract prose that described the removed broker now says that plan freshness and the operator remediation lock are enforced by internal/actionlifecycle. Two source pins that named deleted code go (the publishActionCompleted dispatch sites and the pulse_file_edit declaration), the standards tests drop their expectations of an ActionPlan construction in action_audit.go and of the legacy app_container rejection in the deleted file-edit test, and the RA35 evidence entry for the deleted run-command test goes with them. Left alone on purpose: the saved autonomous control level and its entitlement and approval-admission checks, which stay as legacy compatibility, Service.SetAutonomousMode and the chat clamp, SetOnActionCompleted and its router wiring (no dispatcher is left, the contract prose says so), and the protected-guests plumbing. Rebuilt on current main: the first version had 213 commits of drift. Two conflicts, both on code this change deletes. tools_control.go takes the deletion over the Protected guests cleanup that landed inside executeRunCommand. action_audit_remediation_lock_test.go goes with the audit lanes, including the test added for the dispatch gate's read through a succession; that gate is deleted here, and TestLockMovedBySuccessionStillRefusesTheIDThePreviousGenerationLists in internal/actionlifecycle covers the same refusal on the live path.
166 lines
4.1 KiB
Go
166 lines
4.1 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/agentexec"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
// Mock implementations for testing
|
|
|
|
type mockStateProvider struct {
|
|
mock.Mock
|
|
state models.StateSnapshot
|
|
}
|
|
|
|
func (m *mockStateProvider) ReadSnapshot() models.StateSnapshot {
|
|
if len(m.ExpectedCalls) == 0 {
|
|
return m.state
|
|
}
|
|
args := m.Called()
|
|
if args.Get(0) == nil {
|
|
return models.StateSnapshot{}
|
|
}
|
|
return args.Get(0).(models.StateSnapshot)
|
|
}
|
|
|
|
type mockAgentServer struct {
|
|
mock.Mock
|
|
agents []agentexec.ConnectedAgent
|
|
}
|
|
|
|
func (m *mockAgentServer) GetConnectedAgents() []agentexec.ConnectedAgent {
|
|
if len(m.ExpectedCalls) == 0 {
|
|
return m.agents
|
|
}
|
|
args := m.Called()
|
|
if args.Get(0) == nil {
|
|
return nil
|
|
}
|
|
return args.Get(0).([]agentexec.ConnectedAgent)
|
|
}
|
|
|
|
func (m *mockAgentServer) ExecuteCommand(ctx context.Context, agentID string, cmd agentexec.ExecuteCommandPayload) (*agentexec.CommandResultPayload, error) {
|
|
args := m.Called(ctx, agentID, cmd)
|
|
return args.Get(0).(*agentexec.CommandResultPayload), args.Error(1)
|
|
}
|
|
|
|
type mockMetricsHistoryProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockMetricsHistoryProvider) GetResourceMetrics(resourceID string, period time.Duration) ([]MetricPoint, error) {
|
|
args := m.Called(resourceID, period)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).([]MetricPoint), args.Error(1)
|
|
}
|
|
|
|
func (m *mockMetricsHistoryProvider) GetAllMetricsSummary(period time.Duration) (map[string]ResourceMetricsSummary, error) {
|
|
args := m.Called(period)
|
|
return args.Get(0).(map[string]ResourceMetricsSummary), args.Error(1)
|
|
}
|
|
|
|
type mockAlertProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockAlertProvider) GetActiveAlerts() []ActiveAlert {
|
|
args := m.Called()
|
|
return args.Get(0).([]ActiveAlert)
|
|
}
|
|
|
|
func (m *mockAlertProvider) GetRecentlyResolved(minutes int) []models.ResolvedAlert {
|
|
args := m.Called(minutes)
|
|
if args.Get(0) == nil {
|
|
return nil
|
|
}
|
|
return args.Get(0).([]models.ResolvedAlert)
|
|
}
|
|
|
|
type mockFindingsProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockFindingsProvider) GetActiveFindings() []Finding {
|
|
args := m.Called()
|
|
return args.Get(0).([]Finding)
|
|
}
|
|
|
|
func (m *mockFindingsProvider) GetDismissedFindings() []Finding {
|
|
args := m.Called()
|
|
return args.Get(0).([]Finding)
|
|
}
|
|
|
|
type mockDiskHealthProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockDiskHealthProvider) GetHosts() []*unifiedresources.HostView {
|
|
args := m.Called()
|
|
return args.Get(0).([]*unifiedresources.HostView)
|
|
}
|
|
|
|
type mockUpdatesProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockUpdatesProvider) GetPendingUpdates(hostID string) []ContainerUpdateInfo {
|
|
args := m.Called(hostID)
|
|
return args.Get(0).([]ContainerUpdateInfo)
|
|
}
|
|
|
|
func (m *mockUpdatesProvider) TriggerUpdateCheck(hostID string) (DockerCommandStatus, error) {
|
|
args := m.Called(hostID)
|
|
return args.Get(0).(DockerCommandStatus), args.Error(1)
|
|
}
|
|
|
|
func (m *mockUpdatesProvider) UpdateContainer(hostID, containerID, containerName string) (DockerCommandStatus, error) {
|
|
args := m.Called(hostID, containerID, containerName)
|
|
return args.Get(0).(DockerCommandStatus), args.Error(1)
|
|
}
|
|
|
|
func (m *mockUpdatesProvider) GetCommandStatus(commandID string) (DockerCommandStatus, bool) {
|
|
args := m.Called(commandID)
|
|
return args.Get(0).(DockerCommandStatus), args.Bool(1)
|
|
}
|
|
|
|
func (m *mockUpdatesProvider) IsUpdateActionsEnabled() bool {
|
|
args := m.Called()
|
|
return args.Bool(0)
|
|
}
|
|
|
|
type mockBackupProvider struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *mockBackupProvider) GetBackups() models.Backups {
|
|
args := m.Called()
|
|
return args.Get(0).(models.Backups)
|
|
}
|
|
|
|
func (m *mockBackupProvider) GetPBSInstances() []models.PBSInstance {
|
|
args := m.Called()
|
|
return args.Get(0).([]models.PBSInstance)
|
|
}
|
|
|
|
// stubUnifiedResourceProvider is a simple mock for UnifiedResourceProvider.
|
|
type stubUnifiedResourceProvider struct {
|
|
resources []unifiedresources.Resource
|
|
}
|
|
|
|
func (s *stubUnifiedResourceProvider) GetByType(t unifiedresources.ResourceType) []unifiedresources.Resource {
|
|
var out []unifiedresources.Resource
|
|
for _, r := range s.resources {
|
|
if r.Type == t {
|
|
out = append(out, r)
|
|
}
|
|
}
|
|
return out
|
|
}
|