Advanced Path Resolution and Type Inference
This document provides an in-depth technical guide to the sophisticated path resolution and type inference systems in the Kure patch module.
Path Resolution Architecture
PathPart Structure
Each patch path is decomposed into structured components:
type PathPart struct {
Field string // The field name (e.g., "containers", "ports")
MatchType string // "", "index", or "key"
MatchValue string // The match criteria ("0", "name=main")
}
Path Parsing Process
The ParsePatchPath()
function converts dot-notation paths into structured segments:
spec.containers[name=main].image
↓
[
{Field: "spec"},
{Field: "containers", MatchType: "key", MatchValue: "name=main"},
{Field: "image"}
]
Context-Aware Resolution
The patch system uses intelligent context-aware resolution:
- Resource Type Detection: Different behavior for Deployments vs Services vs ConfigMaps
- Field Validation: Checks if target fields exist in the resource schema
- List vs Object Disambiguation: Automatically determines if a path targets a list or object field
TOML Header Intelligence
Semantic Path Mapping
TOML headers are intelligently mapped to Kubernetes paths:
[deployment.app.containers.name=main]
# Automatically resolves to: spec.template.spec.containers[name=main]
[service.app.ports.name=http]
# Automatically resolves to: spec.ports[name=http]
[configmap.config]
# Automatically resolves to: data.*
Header Resolution Algorithm
- Resource Identification: Parse
kind.name
from header - Context Mapping: Apply resource-specific path transformations
- Selector Extraction: Extract list selectors and match criteria
- Path Validation: Verify the resolved path exists in the target resource
Resource-Specific Mappings
Deployment Resources
containers.*
→spec.template.spec.containers.*
volumes.*
→spec.template.spec.volumes.*
env.*
→spec.template.spec.containers[].env.*
Service Resources
ports.*
→spec.ports.*
selector.*
→spec.selector.*
ConfigMap/Secret Resources
- Direct field access to
data.*
fields - Automatic string/binary data type detection
Type Inference System
Automatic Type Detection
The inferValueType()
function performs context-aware type inference:
// Port numbers
"8080" → int64(8080) // when field contains "port"
"80" → int64(80) // when field is "containerPort", "targetPort"
// Resource quantities
"500m" → "500m" // preserved as string for Kubernetes resource.Quantity
"1Gi" → "1Gi" // preserved as string for memory quantities
// Boolean values
"true" → true // when field suggests boolean context
"enabled" → true // when field is "enabled", "debug", etc.
// Replica counts
"3" → int64(3) // when field is "replicas", "instances"
Context-Driven Inference
The system considers multiple context clues:
- Field Name Patterns:
port
,replicas
,timeout
,enabled
- Parent Path Context:
resources.limits.*
,spec.ports.*
- Value Format Recognition: Kubernetes quantity formats, duration strings
- Resource Type Context: Different inference rules for different Kubernetes kinds
Kubernetes Compatibility
All inferred types are compatible with unstructured.Unstructured
:
func convertValueForUnstructured(value interface{}) interface{} {
switch v := value.(type) {
case int: return int64(v) // Kubernetes expects int64
case int32: return int64(v) // Convert to standard int64
case float32: return float64(v) // Convert to standard float64
// ... handle maps and slices recursively
}
}
List Resolution Algorithms
Index Resolution
The resolveListIndex()
function handles multiple selector types:
// Numeric index
"2" → index 2
// Negative index (from end)
"-1" → len(list) - 1
// Key-value selector
"name=main" → find first item where item.name == "main"
// Multi-key selector
"name=web,port=80" → find item matching both criteria
Insertion Logic
Different insertion operations use sophisticated positioning:
// insertBefore: lst = append(lst[:idx], append([]interface{}{value}, lst[idx:]...)...)
// insertAfter: lst = append(lst[:idx+1], append([]interface{}{value}, lst[idx+1:]...)...)
// append: lst = append(lst, value)
Bounds Checking
Comprehensive validation prevents index errors:
if i < 0 {
i = len(list) + i // Handle negative indices
}
if i < 0 || i > len(list) {
return -1, fmt.Errorf("index out of bounds: %d", i)
}
Error Handling and Debugging
Graceful Degradation
The patch system follows a “warn, don’t fail” philosophy:
- Missing target resources generate warnings but don’t stop processing
- Invalid selectors are logged but don’t crash the operation
- Type inference failures fall back to string values
Debug Logging
Enable comprehensive debugging with KURE_DEBUG=1
:
DEBUG: Resolving TOML header [deployment.app.containers.name=main]
DEBUG: Mapped to path: spec.template.spec.containers[name=main]
DEBUG: Found target container at index 0
DEBUG: Applying patch: image.tag = "v1.2.3"
DEBUG: Type inference: "8080" → int64(8080) (field context: containerPort)
Validation Pipeline
Each patch goes through multiple validation stages:
- Syntax Validation: Parse the patch line syntax
- Path Validation: Verify the target path exists
- Type Validation: Check if the value type is appropriate
- Schema Validation: Ensure compatibility with Kubernetes schemas (future)
Performance Considerations
Path Caching
Frequently used paths are cached to avoid repeated parsing:
var pathCache = make(map[string][]PathPart)
func cachedParsePath(path string) []PathPart {
if cached, ok := pathCache[path]; ok {
return cached
}
// Parse and cache...
}
Batch Processing
Multiple patches are processed efficiently:
- Group by Resource: Batch patches targeting the same resource
- Optimize Selectors: Cache list index resolutions
- Minimize Conversions: Reuse type-converted values
Integration Points
Variable Substitution
Path resolution integrates with variable substitution:
[deployment.${values.app_name}.containers.name=${values.container_name}]
image.tag: "${values.version}"
Resolution happens after variable substitution:
- Substitute variables in headers and values
- Parse the resolved paths
- Apply type inference to final values
Structure Preservation
Path resolution works seamlessly with YAML structure preservation:
- Parse Original Structure: Maintain comments and formatting
- Resolve Target Paths: Find exact locations in preserved structure
- Apply Minimal Changes: Update only the targeted values
- Preserve Everything Else: Keep original formatting intact
This sophisticated system enables the patch module to handle complex Kubernetes resource modifications while maintaining type safety, performance, and user-friendly error handling.