358 lines
9.7 KiB
Text
358 lines
9.7 KiB
Text
# Dynamic Cache Configuration Manager
|
|
# Manages cache settings at runtime via persistent JSON config
|
|
# Follows Nushell 0.109.0+ guidelines
|
|
|
|
# Helper: Get runtime config file path
|
|
def get-runtime-config-path [] {
|
|
let home = ($env.HOME? | default "~" | path expand)
|
|
$home | path join ".provisioning" "cache" "config" "settings.json"
|
|
}
|
|
|
|
# Helper: Get system defaults path
|
|
def get-defaults-config-path [] {
|
|
let provisioning = ($env.PROVISIONING? | default "/usr/local/provisioning")
|
|
$provisioning | path join "config" "config.defaults.toml"
|
|
}
|
|
|
|
# Helper: Load runtime config file
|
|
def load-runtime-config [] {
|
|
let config_path = (get-runtime-config-path)
|
|
|
|
if ($config_path | path exists) {
|
|
let load_result = (do {
|
|
open $config_path
|
|
} | complete)
|
|
|
|
if $load_result.exit_code == 0 {
|
|
return $load_result.stdout
|
|
}
|
|
}
|
|
|
|
# Return empty record if not exists
|
|
{}
|
|
}
|
|
|
|
# Helper: Save runtime config file
|
|
def save-runtime-config [
|
|
config: record
|
|
] {
|
|
let config_path = (get-runtime-config-path)
|
|
let config_dir = ($config_path | path dirname)
|
|
|
|
# Ensure directory exists
|
|
if not ($config_dir | path exists) {
|
|
mkdir $config_dir
|
|
}
|
|
|
|
# Save with pretty formatting
|
|
do {
|
|
$config | to json --indent 2 | save --force $config_path
|
|
} | complete | ignore
|
|
}
|
|
|
|
# ============================================================================
|
|
# PUBLIC API: Configuration Management
|
|
# ============================================================================
|
|
|
|
# Get complete cache configuration (merged: runtime overrides + defaults)
|
|
export def get-cache-config [] {
|
|
let defaults = {
|
|
enabled: true,
|
|
max_cache_size: 104857600, # 100 MB
|
|
ttl: {
|
|
final_config: 300, # 5 minutes
|
|
nickel_compilation: 1800, # 30 minutes
|
|
sops_decryption: 900, # 15 minutes
|
|
provider_config: 600, # 10 minutes
|
|
platform_config: 600 # 10 minutes
|
|
},
|
|
paths: {
|
|
base: (($env.HOME? | default "~" | path expand) | path join ".provisioning" "cache" "config")
|
|
},
|
|
security: {
|
|
sops_file_permissions: "0600",
|
|
sops_dir_permissions: "0700"
|
|
},
|
|
validation: {
|
|
strict_mtime: true
|
|
},
|
|
metadata: {
|
|
last_modified: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
|
|
modified_by: "system",
|
|
version: "1.0"
|
|
}
|
|
}
|
|
|
|
# Load runtime overrides
|
|
let runtime = (load-runtime-config)
|
|
|
|
# Merge: runtime overrides take precedence
|
|
$defaults | merge $runtime
|
|
}
|
|
|
|
# Get specific cache setting (dot notation: "ttl.final_config")
|
|
export def cache-config-get [
|
|
setting_path: string # "enabled", "ttl.final_config", etc.
|
|
] {
|
|
let config = (get-cache-config)
|
|
let result = (do {
|
|
eval $"$config | get ($setting_path)"
|
|
} | complete)
|
|
|
|
if $result.exit_code == 0 {
|
|
$result.stdout
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
# Set cache configuration (persists to runtime config)
|
|
export def cache-config-set [
|
|
setting_path: string
|
|
value: any
|
|
] {
|
|
let runtime = (load-runtime-config)
|
|
|
|
# Build nested structure from dot notation
|
|
mut updated = $runtime
|
|
|
|
# Simple update for direct keys
|
|
if not ($setting_path | str contains ".") {
|
|
$updated = ($updated | insert $setting_path $value)
|
|
} else {
|
|
# For nested paths, we need to handle carefully
|
|
# Convert "ttl.final_config" -> insert into ttl section
|
|
let parts = ($setting_path | split row ".")
|
|
|
|
if ($parts | length) == 2 {
|
|
let section = ($parts | get 0)
|
|
let key = ($parts | get 1)
|
|
|
|
let section_obj = if ($runtime | has -c $section) {
|
|
$runtime | get $section
|
|
} else {
|
|
{}
|
|
}
|
|
|
|
let updated_section = ($section_obj | insert $key $value)
|
|
$updated = ($updated | insert $section $updated_section)
|
|
}
|
|
}
|
|
|
|
# Add metadata
|
|
$updated = ($updated | insert "metadata" {
|
|
last_modified: (date now | format date "%Y-%m-%dT%H:%M:%SZ"),
|
|
modified_by: "user",
|
|
version: "1.0"
|
|
})
|
|
|
|
save-runtime-config $updated
|
|
}
|
|
|
|
# Reset cache configuration (delete runtime overrides)
|
|
export def cache-config-reset [
|
|
setting_path?: string = "" # Optional: reset specific setting
|
|
] {
|
|
if ($setting_path | is-empty) {
|
|
# Delete entire runtime config file
|
|
let config_path = (get-runtime-config-path)
|
|
if ($config_path | path exists) {
|
|
do {
|
|
rm -f $config_path
|
|
} | complete | ignore
|
|
}
|
|
} else {
|
|
# Remove specific setting
|
|
let runtime = (load-runtime-config)
|
|
|
|
mut updated = $runtime
|
|
|
|
# Handle nested paths
|
|
if not ($setting_path | str contains ".") {
|
|
if ($updated | has -c $setting_path) {
|
|
$updated = ($updated | del $setting_path)
|
|
}
|
|
} else {
|
|
let parts = ($setting_path | split row ".")
|
|
if ($parts | length) == 2 {
|
|
let section = ($parts | get 0)
|
|
let key = ($parts | get 1)
|
|
|
|
if ($updated | has -c $section) {
|
|
let section_obj = ($updated | get $section)
|
|
let updated_section = (if ($section_obj | has -c $key) {
|
|
$section_obj | del $key
|
|
} else {
|
|
$section_obj
|
|
})
|
|
$updated = ($updated | insert $section $updated_section)
|
|
}
|
|
}
|
|
}
|
|
|
|
save-runtime-config $updated
|
|
}
|
|
}
|
|
|
|
# Show cache configuration in formatted output
|
|
export def cache-config-show [
|
|
--format: string = "yaml" # "yaml", "json", "table"
|
|
] {
|
|
let config = (get-cache-config)
|
|
|
|
match $format {
|
|
"json" => {
|
|
$config | to json --indent 2 | print
|
|
},
|
|
"table" => {
|
|
$config | print
|
|
},
|
|
_ => {
|
|
$config | to yaml | print
|
|
}
|
|
}
|
|
}
|
|
|
|
# Validate cache configuration
|
|
export def cache-config-validate [] {
|
|
let config = (get-cache-config)
|
|
|
|
mut errors = []
|
|
mut warnings = []
|
|
|
|
# Validate enabled field
|
|
if not ($config | has -c "enabled") {
|
|
$errors = ($errors | append "Missing 'enabled' field")
|
|
}
|
|
|
|
# Validate TTL values (should be positive integers)
|
|
if ($config | has -c "ttl") {
|
|
for ttl_key in [
|
|
"final_config"
|
|
"nickel_compilation"
|
|
"sops_decryption"
|
|
"provider_config"
|
|
"platform_config"
|
|
] {
|
|
let ttl_value = ($config.ttl | get --optional $ttl_key | default 0)
|
|
if ($ttl_value <= 0) {
|
|
$warnings = ($warnings | append $"TTL ($ttl_key) is not positive: ($ttl_value)")
|
|
}
|
|
}
|
|
}
|
|
|
|
# Validate max cache size (should be reasonable)
|
|
if ($config | has -c "max_cache_size") {
|
|
let max_size = $config.max_cache_size
|
|
if ($max_size < 1048576) { # Less than 1 MB
|
|
$warnings = ($warnings | append $"max_cache_size is very small: ($max_size) bytes")
|
|
}
|
|
if ($max_size > 10737418240) { # More than 10 GB
|
|
$warnings = ($warnings | append $"max_cache_size is very large: ($max_size) bytes")
|
|
}
|
|
}
|
|
|
|
{
|
|
valid: (($errors | length) == 0),
|
|
errors: $errors,
|
|
warnings: $warnings
|
|
}
|
|
}
|
|
|
|
# Get cache statistics along with configuration
|
|
export def get-cache-status [] {
|
|
use ../../cache/core.nu get-cache-stats
|
|
|
|
let config = (get-cache-config)
|
|
let stats = (get-cache-stats)
|
|
|
|
{
|
|
configuration: $config,
|
|
statistics: $stats,
|
|
enabled: $config.enabled,
|
|
max_size_mb: ($config.max_cache_size / 1048576),
|
|
current_usage_percent: (
|
|
if ($stats.total_size_mb | is-not-empty) {
|
|
($stats.total_size_mb / ($config.max_cache_size / 1048576) * 100) | math round -p 1
|
|
} else {
|
|
0
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
# Export configuration to portable format
|
|
export def cache-config-export [
|
|
--format: string = "json"
|
|
] {
|
|
let config = (get-cache-config)
|
|
|
|
match $format {
|
|
"json" => {
|
|
$config | to json --indent 2
|
|
},
|
|
"yaml" => {
|
|
$config | to yaml
|
|
},
|
|
"toml" => {
|
|
# Basic TOML conversion (limited)
|
|
$"[cache]
|
|
enabled = ($config.enabled)
|
|
max_cache_size = ($config.max_cache_size)
|
|
"
|
|
},
|
|
_ => {
|
|
$config | to json --indent 2
|
|
}
|
|
}
|
|
}
|
|
|
|
# Import configuration from JSON string
|
|
export def cache-config-import [
|
|
json_string: string
|
|
] {
|
|
let result = (do {
|
|
$json_string | from json
|
|
} | complete)
|
|
|
|
if $result.exit_code == 0 {
|
|
save-runtime-config $result.stdout
|
|
} else {
|
|
error make { msg: "Failed to parse configuration JSON" }
|
|
}
|
|
}
|
|
|
|
# Get configuration defaults (system-wide)
|
|
export def get-cache-defaults [] {
|
|
{
|
|
enabled: true,
|
|
max_cache_size: 104857600, # 100 MB
|
|
ttl: {
|
|
final_config: 300,
|
|
nickel_compilation: 1800,
|
|
sops_decryption: 900,
|
|
provider_config: 600,
|
|
platform_config: 600
|
|
},
|
|
paths: {
|
|
base: (($env.HOME? | default "~" | path expand) | path join ".provisioning" "cache" "config")
|
|
},
|
|
security: {
|
|
sops_file_permissions: "0600",
|
|
sops_dir_permissions: "0700"
|
|
},
|
|
validation: {
|
|
strict_mtime: true
|
|
}
|
|
}
|
|
}
|
|
|
|
# Restore default configuration
|
|
export def cache-config-restore-defaults [] {
|
|
let config_path = (get-runtime-config-path)
|
|
if ($config_path | path exists) {
|
|
do {
|
|
rm -f $config_path
|
|
} | complete | ignore
|
|
}
|
|
}
|