mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-07-09 16:00:59 +00:00
Dedupe internal/api handler families behind shared flows and generics
Clears the sixteen dupl pair groups in internal/api plus the pkg/pulsecli pair: - router.go: privileged settings endpoints share the serveSetupTokenOrSettingsWrite gate; patrol findings convert via one unifiedFindingFromAI; the five infrastructure-summary chart loops share collectGuestChartData / fillChartSeriesFromBatch; the VM/LXC workloads summary loops share appendGuestWorkloadSummaries. - deploy_handlers.go: preflight and job status/SSE handlers share handleDeployJobStatus / handleDeployJobEvents. - recovery_handlers.go: points series/facets share parseRecoveryListPointsOptions. - truenas_handlers.go / vmware_handlers.go / router_routes_registration.go: the connection update flow (locate, decode-with-fallback, normalize, preserve masked secrets, validate, save, redact) moves to the new platform_connection_shared.go (updatePlatformConnection + decodeOptionalInstanceRequest + the admin-gated item-route builder); per-platform wrappers carry nolint'd declarative wiring only. - docker_metadata.go / guest_metadata.go: GET/PUT payload semantics move to metadata_handlers_shared.go; the zero-record-instead-of-404 contract is pinned by TestContract_MetadataGetPayloadsUseZeroRecordsInsteadOf404. - kubernetes_agents.go / docker_agents.go: lifecycle PUTs share per-handler action helpers. - config_node_handlers.go: PBS/PMG probes share testProxmoxPlatformConnection. - cloud_handoff_handlers.go / purchase_return_redemptions.go: secrets sqlite stores open through openHardenedSecretsDB so permission hardening stays single-sourced. - ai_handlers.go / chat_service_adapter.go: the GetMessages adapters are deliberate contract mirrors — suppressed with nolint and enforced by TestOrchestratorAndChatAdaptersMapTheSameMessageFields. - pkg/pulsecli/actions.go: action subcommands seed env defaults via actionAPIDefaults (tested); the audit/events cobra registration pair is nolint'd parallel wiring. - .golangci.yml: exclude gitignored tmp/ from ./... typechecking. - subsystem_lookup_test.py: refresh the pinned api-contracts.md line numbers shifted by the contract additions. golangci-lint run ./... is now fully green. Full internal/api and pkg/pulsecli test suites pass.
This commit is contained in:
parent
26c7ca910c
commit
6340cd36f2
24 changed files with 977 additions and 1132 deletions
|
|
@ -109,18 +109,26 @@ type actionExecutionResponse struct {
|
|||
Audit unified.ActionAuditRecord `json:"audit"`
|
||||
}
|
||||
|
||||
// actionAPIDefaults seeds the shared Pulse API URL and token defaults for
|
||||
// action subcommands from the environment.
|
||||
func actionAPIDefaults(deps *ActionsDeps) (apiURL, token string) {
|
||||
apiURL = strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL"))
|
||||
if apiURL == "" {
|
||||
apiURL = defaultPulseAPIURL
|
||||
}
|
||||
return apiURL, strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN"))
|
||||
}
|
||||
|
||||
func newActionsCmd(deps *ActionsDeps) *cobra.Command {
|
||||
actionsCmd := &cobra.Command{
|
||||
Use: "actions",
|
||||
Short: "Inspect and plan governed Pulse actions",
|
||||
}
|
||||
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionPlanOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
}
|
||||
|
||||
planCmd := &cobra.Command{
|
||||
|
|
@ -152,12 +160,10 @@ func newActionsCmd(deps *ActionsDeps) *cobra.Command {
|
|||
}
|
||||
|
||||
func newActionCapabilitiesCmd(deps *ActionsDeps) *cobra.Command {
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionCapabilitiesOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -174,12 +180,10 @@ func newActionCapabilitiesCmd(deps *ActionsDeps) *cobra.Command {
|
|||
}
|
||||
|
||||
func newActionDecisionCmd(deps *ActionsDeps) *cobra.Command {
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionDecisionOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -198,12 +202,10 @@ func newActionDecisionCmd(deps *ActionsDeps) *cobra.Command {
|
|||
}
|
||||
|
||||
func newActionExecutionCmd(deps *ActionsDeps) *cobra.Command {
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionExecutionOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
|
@ -220,15 +222,14 @@ func newActionExecutionCmd(deps *ActionsDeps) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
//nolint:dupl // parallel cobra subcommand registration; flags/help diverge per command
|
||||
func newActionAuditCmd(deps *ActionsDeps) *cobra.Command {
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionAuditOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
Limit: 100,
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "audit",
|
||||
|
|
@ -245,15 +246,14 @@ func newActionAuditCmd(deps *ActionsDeps) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
//nolint:dupl // parallel cobra subcommand registration; flags/help diverge per command
|
||||
func newActionEventsCmd(deps *ActionsDeps) *cobra.Command {
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
opts := actionEventsOptions{
|
||||
APIURL: strings.TrimSpace(actionGetenv(deps, "PULSE_API_URL")),
|
||||
Token: strings.TrimSpace(actionGetenv(deps, "PULSE_API_TOKEN")),
|
||||
APIURL: apiURL,
|
||||
Token: token,
|
||||
Limit: 100,
|
||||
}
|
||||
if opts.APIURL == "" {
|
||||
opts.APIURL = defaultPulseAPIURL
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "events",
|
||||
|
|
|
|||
|
|
@ -651,3 +651,31 @@ func newTestActionsRootCommand(env map[string]string) *cobra.Command {
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestActionAPIDefaultsSeedsFromEnvironment(t *testing.T) {
|
||||
deps := &ActionsDeps{Getenv: func(key string) string {
|
||||
switch key {
|
||||
case "PULSE_API_URL":
|
||||
return " https://pulse.example.test "
|
||||
case "PULSE_API_TOKEN":
|
||||
return " token-123 "
|
||||
}
|
||||
return ""
|
||||
}}
|
||||
apiURL, token := actionAPIDefaults(deps)
|
||||
if apiURL != "https://pulse.example.test" {
|
||||
t.Fatalf("apiURL = %q, want trimmed env value", apiURL)
|
||||
}
|
||||
if token != "token-123" {
|
||||
t.Fatalf("token = %q, want trimmed env value", token)
|
||||
}
|
||||
|
||||
empty := &ActionsDeps{Getenv: func(string) string { return "" }}
|
||||
apiURL, token = actionAPIDefaults(empty)
|
||||
if apiURL != defaultPulseAPIURL {
|
||||
t.Fatalf("apiURL = %q, want default %q when env is unset", apiURL, defaultPulseAPIURL)
|
||||
}
|
||||
if token != "" {
|
||||
t.Fatalf("token = %q, want empty when env is unset", token)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue