# Provider-Agnostic Architecture Documentation

## Overview

The new provider-agnostic architecture eliminates hardcoded provider dependencies and enables true multi-provider infrastructure deployments. This addresses two critical limitations of the previous middleware:

1. **Hardcoded provider dependencies** - No longer requires importing specific provider modules
2. **Single-provider limitation** - Now supports mixing multiple providers in the same deployment (for example, AWS compute + Cloudflare DNS + UpCloud backup)

## Architecture Components

### 1. Provider Interface (`interface.nu`)

Defines the contract that all providers must implement:

```nushell
# Standard interface functions
- query_servers
- server_info
- server_exists
- create_server
- delete_server
- server_state
- get_ip
# ... and 20+ other functions
```plaintext

**Key Features:**

- Type-safe function signatures
- Comprehensive validation
- Provider capability flags
- Interface versioning

### 2. Provider Registry (`registry.nu`)

Manages provider discovery and registration:

```nushell
# Initialize registry
init-provider-registry

# List available providers
list-providers --available-only

# Check provider availability
is-provider-available "aws"
```plaintext

**Features:**

- Automatic provider discovery
- Core and extension provider support
- Caching for performance
- Provider capability tracking

### 3. Provider Loader (`loader.nu`)

Handles dynamic provider loading and validation:

```nushell
# Load provider dynamically
load-provider "aws"

# Get provider with auto-loading
get-provider "upcloud"

# Call provider function
call-provider-function "aws" "query_servers" $find $cols
```plaintext

**Features:**

- Lazy loading (load only when needed)
- Interface compliance validation
- Error handling and recovery
- Provider health checking

### 4. Provider Adapters

Each provider implements a standard adapter:

```plaintext
provisioning/extensions/providers/
├── aws/provider.nu        # AWS adapter
├── upcloud/provider.nu    # UpCloud adapter
├── local/provider.nu      # Local adapter
└── {custom}/provider.nu   # Custom providers
```plaintext

**Adapter Structure:**

```nushell
# AWS Provider Adapter
export def query_servers [find?: string, cols?: string] {
    aws_query_servers $find $cols
}

export def create_server [settings: record, server: record, check: bool, wait: bool] {
    # AWS-specific implementation
}
```plaintext

### 5. Provider-Agnostic Middleware (`middleware_provider_agnostic.nu`)

The new middleware that uses dynamic dispatch:

```nushell
# No hardcoded imports!
export def mw_query_servers [settings: record, find?: string, cols?: string] {
    $settings.data.servers | each { |server|
        # Dynamic provider loading and dispatch
        dispatch_provider_function $server.provider "query_servers" $find $cols
    }
}
```plaintext

## Multi-Provider Support

### Example: Mixed Provider Infrastructure

```nickel
let servers = [
    {
        hostname = "compute-01",
        provider = "aws",
        # AWS-specific config
    },
    {
        hostname = "backup-01",
        provider = "upcloud",
        # UpCloud-specific config
    },
    {
        hostname = "api.example.com",
        provider = "cloudflare",
        # DNS-specific config
    },
] in
servers
```plaintext

### Multi-Provider Deployment

```nushell
# Deploy across multiple providers automatically
mw_deploy_multi_provider_infra $settings $deployment_plan

# Get deployment strategy recommendations
mw_suggest_deployment_strategy {
    regions: ["us-east-1", "eu-west-1"]
    high_availability: true
    cost_optimization: true
}
```plaintext

## Provider Capabilities

Providers declare their capabilities:

```nushell
capabilities: {
    server_management: true
    network_management: true
    auto_scaling: true        # AWS: yes, Local: no
    multi_region: true        # AWS: yes, Local: no
    serverless: true          # AWS: yes, UpCloud: no
    compliance_certifications: ["SOC2", "HIPAA"]
}
```plaintext

## Migration Guide

### From Old Middleware

**Before (hardcoded):**

```nushell
# middleware.nu
use ../aws/nulib/aws/servers.nu *
use ../upcloud/nulib/upcloud/servers.nu *

match $server.provider {
    "aws" => { aws_query_servers $find $cols }
    "upcloud" => { upcloud_query_servers $find $cols }
}
```plaintext

**After (provider-agnostic):**

```nushell
# middleware_provider_agnostic.nu
# No hardcoded imports!

# Dynamic dispatch
dispatch_provider_function $server.provider "query_servers" $find $cols
```plaintext

### Migration Steps

1. **Replace middleware file:**

   ```bash
   cp provisioning/extensions/providers/prov_lib/middleware.nu \
      provisioning/extensions/providers/prov_lib/middleware_legacy.backup

   cp provisioning/extensions/providers/prov_lib/middleware_provider_agnostic.nu \
      provisioning/extensions/providers/prov_lib/middleware.nu
   ```

1. **Test with existing infrastructure:**

   ```nushell
   ./provisioning/tools/test-provider-agnostic.nu run-all-tests
   ```

2. **Update any custom code** that directly imported provider modules

## Adding New Providers

### 1. Create Provider Adapter

Create `provisioning/extensions/providers/{name}/provider.nu`:

```nushell
# Digital Ocean Provider Example
export def get-provider-metadata [] {
    {
        name: "digitalocean"
        version: "1.0.0"
        capabilities: {
            server_management: true
            # ... other capabilities
        }
    }
}

# Implement required interface functions
export def query_servers [find?: string, cols?: string] {
    # DigitalOcean-specific implementation
}

export def create_server [settings: record, server: record, check: bool, wait: bool] {
    # DigitalOcean-specific implementation
}

# ... implement all required functions
```plaintext

### 2. Provider Discovery

The registry will automatically discover the new provider on next initialization.

### 3. Test New Provider

```nushell
# Check if discovered
is-provider-available "digitalocean"

# Load and test
load-provider "digitalocean"
check-provider-health "digitalocean"
```plaintext

## Best Practices

### Provider Development

1. **Implement full interface** - All functions must be implemented
2. **Handle errors gracefully** - Return appropriate error values
3. **Follow naming conventions** - Use consistent function naming
4. **Document capabilities** - Accurately declare what your provider supports
5. **Test thoroughly** - Validate against the interface specification

### Multi-Provider Deployments

1. **Use capability-based selection** - Choose providers based on required features
2. **Handle provider failures** - Design for provider unavailability
3. **Optimize for cost/performance** - Mix providers strategically
4. **Monitor cross-provider dependencies** - Understand inter-provider communication

### Profile-Based Security

```nushell
# Environment profiles can restrict providers
PROVISIONING_PROFILE=production  # Only allows certified providers
PROVISIONING_PROFILE=development # Allows all providers including local
```plaintext

## Troubleshooting

### Common Issues

1. **Provider not found**
   - Check provider is in correct directory
   - Verify provider.nu exists and implements interface
   - Run `init-provider-registry` to refresh

2. **Interface validation failed**
   - Use `validate-provider-interface` to check compliance
   - Ensure all required functions are implemented
   - Check function signatures match interface

3. **Provider loading errors**
   - Check Nushell module syntax
   - Verify import paths are correct
   - Use `check-provider-health` for diagnostics

### Debug Commands

```nushell
# Registry diagnostics
get-provider-stats
list-providers --verbose

# Provider diagnostics
check-provider-health "aws"
check-all-providers-health

# Loader diagnostics
get-loader-stats
```plaintext

## Performance Benefits

1. **Lazy Loading** - Providers loaded only when needed
2. **Caching** - Provider registry cached to disk
3. **Reduced Memory** - No hardcoded imports reducing memory usage
4. **Parallel Operations** - Multi-provider operations can run in parallel

## Future Enhancements

1. **Provider Plugins** - Support for external provider plugins
2. **Provider Versioning** - Multiple versions of same provider
3. **Provider Composition** - Compose providers for complex scenarios
4. **Provider Marketplace** - Community provider sharing

## API Reference

See the interface specification for complete function documentation:

```nushell
get-provider-interface-docs | table
```plaintext

This returns the complete API with signatures and descriptions for all provider interface functions.
