mcp-framework/secretstore/manifest_open.go

127 lines
3.5 KiB
Go

package secretstore
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"gitea.lclr.dev/AI/mcp-framework/manifest"
)
type ManifestLoader func(startDir string) (manifest.File, string, error)
type ExecutableResolver func() (string, error)
type OpenFromManifestOptions struct {
ServiceName string
LookupEnv func(string) (string, bool)
KWalletAppID string
KWalletFolder string
BitwardenCommand string
BitwardenDebug bool
DisableBitwardenCache bool
Shell string
ManifestLoader ManifestLoader
ExecutableResolver ExecutableResolver
}
func OpenFromManifest(options OpenFromManifestOptions) (Store, error) {
manifestPolicy, err := resolveManifestPolicy(options)
if err != nil {
return nil, err
}
return Open(Options{
ServiceName: options.ServiceName,
BackendPolicy: manifestPolicy.Policy,
LookupEnv: options.LookupEnv,
KWalletAppID: options.KWalletAppID,
KWalletFolder: options.KWalletFolder,
BitwardenCommand: strings.TrimSpace(options.BitwardenCommand),
BitwardenDebug: options.BitwardenDebug,
DisableBitwardenCache: disableBitwardenCacheOption(options.DisableBitwardenCache, manifestPolicy.BitwardenCache),
Shell: strings.TrimSpace(options.Shell),
})
}
func resolveManifestBackendPolicy(options OpenFromManifestOptions) (BackendPolicy, error) {
resolution, err := resolveManifestPolicy(options)
if err != nil {
return "", err
}
return resolution.Policy, nil
}
type manifestPolicyResolution struct {
Policy BackendPolicy
Source string
BitwardenCache bool
}
func resolveManifestPolicy(options OpenFromManifestOptions) (manifestPolicyResolution, error) {
manifestLoader := options.ManifestLoader
if manifestLoader == nil {
manifestLoader = manifest.LoadDefault
}
executableResolver := options.ExecutableResolver
if executableResolver == nil {
executableResolver = os.Executable
}
executablePath, err := executableResolver()
if err != nil {
return manifestPolicyResolution{}, fmt.Errorf("resolve executable path for manifest lookup: %w", err)
}
startDir := filepath.Dir(strings.TrimSpace(executablePath))
if strings.TrimSpace(startDir) == "" {
startDir = "."
}
file, manifestPath, err := manifestLoader(startDir)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return manifestPolicyResolution{
Policy: BackendAuto,
Source: "",
BitwardenCache: true,
}, nil
}
return manifestPolicyResolution{}, fmt.Errorf("load runtime manifest from %q: %w", startDir, err)
}
bitwardenCache := true
if file.SecretStore.BitwardenCache != nil {
bitwardenCache = *file.SecretStore.BitwardenCache
}
if strings.TrimSpace(file.SecretStore.BackendPolicy) == "" {
return manifestPolicyResolution{
Policy: BackendAuto,
Source: strings.TrimSpace(manifestPath),
BitwardenCache: bitwardenCache,
}, nil
}
policy, err := normalizeBackendPolicy(BackendPolicy(file.SecretStore.BackendPolicy))
if err != nil {
return manifestPolicyResolution{}, fmt.Errorf(
"invalid secret_store.backend_policy in manifest %q: %w",
strings.TrimSpace(manifestPath),
err,
)
}
return manifestPolicyResolution{
Policy: policy,
Source: strings.TrimSpace(manifestPath),
BitwardenCache: bitwardenCache,
}, nil
}
func disableBitwardenCacheOption(runtimeDisabled bool, manifestEnabled bool) bool {
return runtimeDisabled || !manifestEnabled
}