# Dataplane Manager Architecture

## Namespace Layout

| Namespace | Contents |
|-----------|----------|
| `dataplane-manager` | Controller and server pods |
| `dataplane-metadata` | All managed CRs (DataPlane, VPC, AppBox, etc.) |

All CRs are created in `dataplane-metadata`. The namespace is set via controller config (`t.Config.Namespace`).

## CRD Hierarchy

Dataplane-manager defines 11 CRD types in `api/v1alpha1/`. The DataPlane CR is the top-level orchestrator — it creates and manages all other CRs through a task pipeline.

```
DataPlane (top-level)
├── VPC                    # Virtual network per cloud
├── Internet               # NAT gateway + IGW (depends on VPC)
├── AppBox                 # K8s cluster + components (depends on VPC)
│   └── (component tasks)  # goldpinger, node-exporter, cert-manager, etc.
├── NodePool               # Worker node groups (EKS only)
├── Bucket                 # Object storage (backup/restore)
├── Key                    # Encryption key management
├── LoadBalancer           # LB provisioning
├── VPCPeering             # Cross-VPC connectivity
├── PrivateLinkService     # Private endpoint service
└── PrivateLinkEndpoint    # Private endpoint consumer
```

### Key Labels

Defined in `pkg/consts/labels.go`:

| Label | Purpose |
|-------|---------|
| `tags.tidbcloud.com/shared-pool` | Associates CRs with a SharedPool |
| `tags.tidbcloud.com/tenant` | Tenant isolation |

## DataPlane Task Pipeline

The DataPlane controller (`pkg/controllers/dataplane/`) uses a sequential task pipeline to orchestrate infrastructure creation. Tasks are defined in `pkg/controllers/dataplane/task/` and registered in `pkg/controllers/dataplane/taskbuilder.go`.

### Execution Order

```
1. VPC task          → Creates VPC CR
2. Internet task     → Creates Internet CR (VPCRef → waits for VPC ready)
3. AppBox task       → Creates AppBox CR (VPCRef → waits for VPC ready)
4. NodePool task     → Creates NodePool CRs (EKS only, after AppBox)
```

### Dependency Enforcement

Dependencies are enforced via **PostCreate readiness checks**:
- Internet task's `PostCreate` waits for VPC to reach ready phase
- AppBox task's `PostCreate` waits for VPC to reach ready phase
- Each task sets a `VPCRef` on the child CR pointing to the parent VPC

### Cloud Provider Selection

Each VPC CR carries an `AccountRef.ProviderConfigName` that determines which cloud provider API to use. Child tasks inherit provider config from the VPC via `ProviderConfigName()` method in `pkg/controllers/vpc/task/context.go`.

## Cloud-Specific Resource Mapping

Each high-level CR reconciles into provider-specific low-level resources in `dataplane-metadata`.
In the current implementation, many of those low-level resources are still Upbound/Crossplane-managed CRs, and some flows also use direct cloud SDK calls or helper controllers.

### AWS

```
VPC.dedicated
  └── VPC, Subnets, Security Groups, Route Tables

Internet.dedicated
  └── NAT Gateway, Elastic IP, Internet Gateway

AppBox.dedicated
  └── EKS Cluster, EKS Add-ons, IAM Roles
      └── (component tasks: goldpinger, node-exporter, etc.)

NodePool
  └── EKS Managed Node Groups
```

Low-level K8s CRs in `dataplane-metadata` (for inspection):
`vpc.ec2`, `natgateway`, `eip`, `cluster.eks`, `nodegroup.eks`

### Alibaba Cloud (ACK)

```
VPC.dedicated
  └── VPC, VSwitch, Security Groups

Internet.dedicated
  └── IPv4 Gateway, NAT Gateway, EIP Address

AppBox.dedicated
  └── Managed Kubernetes (ACK), Add-ons, RAM Permissions
      └── (component tasks)
```

Low-level CRs: `vpc.vpc`, `vswitch.vpc`, `ipv4gateway`, `natgateway`, `eipaddress`, `managedkubernetes`, `kubernetesnodepool`, `kubernetesaddon`, `kubernetespermissions`

### Azure (AKS)

```
VPC.dedicated
  └── Virtual Network, Subnets

Internet.dedicated
  └── NAT Gateway, Public IP

AppBox.dedicated
  └── AKS Cluster
      └── (component tasks)
```

Low-level CRs: `virtualnetwork`, `subnet`, `natgateway`, `publicip`, `kubernetescluster`, `kubernetesclusternodepool`

## CR Dependency Chain (Troubleshooting)

When a DataPlane is unhealthy, follow the dependency chain top-down:

```
DataPlane (abnormal)
  ↓ Check child CRs:
  ├── VPC.dedicated (abnormal?)
  │     └── Check cloud-specific low-level CRs (see above)
  ├── Internet.dedicated (abnormal?)
  │     └── Depends on VPC — check VPC first
  ├── AppBox.dedicated (abnormal?)
  │     └── Depends on VPC — check VPC first, then K8s cluster CRs
  └── NodePool (abnormal? EKS only)
        └── Depends on AppBox — check AppBox first
```

### Inspection Commands

```bash
# All high-level CRs for a shared pool
kubectl get dataplane.dedicated,vpc.dedicated,internet.dedicated,appbox.dedicated,\
loadbalancer.dedicated,privatelinkservice.dedicated,privatelinkendpoint.dedicated,bucket.dedicated \
  -n dataplane-metadata -l tags.tidbcloud.com/shared-pool=<pool-id>

# AWS low-level CRs
kubectl get vpc.ec2,natgateway,eip,cluster.eks,nodegroup.eks \
  -n dataplane-metadata -l tags.tidbcloud.com/shared-pool=<pool-id>

# Aliyun low-level CRs
kubectl get vpc.vpc,vswitch.vpc,ipv4gateway,natgateway,eipaddress,\
managedkubernetes,kubernetesnodepool \
  -n dataplane-metadata -l tags.tidbcloud.com/shared-pool=<pool-id>

# Azure low-level CRs
kubectl get virtualnetwork,subnet,natgateway,publicip,\
kubernetescluster,kubernetesclusternodepool \
  -n dataplane-metadata -l tags.tidbcloud.com/shared-pool=<pool-id>

# Events for a pool
kubectl get events -n dataplane-metadata --sort-by='.lastTimestamp' | grep -i <pool-id>
```

## AppBox Component Pipeline

AppBox has its own internal task pipeline for deploying K8s cluster components. Use [`AGENTS.md`](AGENTS.md) as the local code map, then work from the provider task trees below.

The pipeline is cloud-specific:
- **EKS tasks**: `pkg/controllers/appbox/task/eks/`
- **ACK tasks**: `pkg/controllers/appbox/task/ack/`
- **AKS tasks**: `pkg/controllers/appbox/task/aks/`
- **Common tasks**: `pkg/controllers/appbox/task/common/` (shared across all clouds)

Task registration happens in `pkg/controllers/appbox/taskbuilder.go` via `GetEKSAPPBoxTasks()`, `GetACKAPPBoxTasks()`, `GetAKSAPPBoxTasks()`.
