2026-09-30 03:29:28 +00:00
|
|
|
package configuration
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"io"
|
2026-11-02 03:58:49 +00:00
|
|
|
"strconv"
|
2026-09-30 03:29:28 +00:00
|
|
|
"strings"
|
|
|
|
|
|
2026-11-02 03:51:39 +00:00
|
|
|
"go.maximumdirect.net/configkit"
|
2026-09-30 03:29:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Inspection is the read-only subset of the retained ConfigKit result used by
|
|
|
|
|
// the facade. It does not expose typed configuration or resource contexts.
|
|
|
|
|
type Inspection interface {
|
|
|
|
|
Metadata() configkit.Metadata
|
|
|
|
|
Sources() []configkit.SourceInfo
|
|
|
|
|
Diagnostics() []configkit.Diagnostic
|
|
|
|
|
Explain(configkit.Path) (configkit.Explanation, bool)
|
|
|
|
|
WriteEffective(io.Writer) error
|
|
|
|
|
WriteExplanation(io.Writer, configkit.Path) error
|
2026-10-09 15:58:04 +00:00
|
|
|
capturedResult() *configkit.Result[document]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type inspectionResult struct {
|
|
|
|
|
*configkit.Result[document]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (inspection inspectionResult) capturedResult() *configkit.Result[document] {
|
|
|
|
|
return inspection.Result
|
2026-09-30 03:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Inspection returns only the retained result's inspection operations.
|
|
|
|
|
func (state *loaded) Inspection() Inspection {
|
|
|
|
|
if state == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-10-09 15:58:04 +00:00
|
|
|
return inspectionResult{Result: state.result}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Diff compares two captured ConfigKit results without reconstructing them.
|
|
|
|
|
func Diff(left, right Inspection) ([]configkit.Difference, error) {
|
|
|
|
|
var leftResult, rightResult *configkit.Result[document]
|
|
|
|
|
if left != nil {
|
|
|
|
|
leftResult = left.capturedResult()
|
|
|
|
|
}
|
|
|
|
|
if right != nil {
|
|
|
|
|
rightResult = right.capturedResult()
|
|
|
|
|
}
|
|
|
|
|
return configkit.Diff(leftResult, rightResult)
|
2026-09-30 03:29:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func secretProviderPath(path configkit.Path) bool {
|
|
|
|
|
pointer := path.String()
|
|
|
|
|
if pointer == "" {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
parts := strings.Split(strings.TrimPrefix(pointer, "/"), "/")
|
2026-10-17 05:33:03 +00:00
|
|
|
if !providerExtraParamsPath(parts) {
|
2026-09-30 03:29:28 +00:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
key := strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(parts[len(parts)-1], "~1", "/"), "~0", "~"))
|
|
|
|
|
switch key {
|
|
|
|
|
case "api_key", "apikey", "authorization", "credential", "credentials", "password", "secret", "token", "access_token":
|
|
|
|
|
return true
|
|
|
|
|
default:
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-17 05:33:03 +00:00
|
|
|
|
|
|
|
|
func providerExtraParamsPath(parts []string) bool {
|
2026-11-02 03:58:49 +00:00
|
|
|
if len(parts) >= 4 && sequenceIndex(parts[1]) &&
|
2026-10-17 06:03:28 +00:00
|
|
|
(parts[0] == "backends" || parts[0] == "profiles") && parts[2] == "extra_params" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return len(parts) >= 6 && parts[0] == "collections" && parts[1] != "" &&
|
|
|
|
|
(parts[2] == "backends" || parts[2] == "profiles") &&
|
2026-11-02 03:58:49 +00:00
|
|
|
sequenceIndex(parts[3]) && parts[4] == "extra_params"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func sequenceIndex(segment string) bool {
|
|
|
|
|
index, err := strconv.Atoi(segment)
|
|
|
|
|
return err == nil && index >= 0 && strconv.Itoa(index) == segment
|
2026-10-17 05:33:03 +00:00
|
|
|
}
|