commit ad0776e6d3494ecb42b4839df8693455758ebbdf Author: Zhongwei Li Date: Sun Nov 30 08:51:59 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..cc267f5 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "newt-blueprint-generator", + "description": "Generate and validate Pangolin Newt blueprint configurations in YAML or Docker Labels format. Creates proxy resources (HTTP/TCP/UDP), client resources, authentication settings, and access control rules", + "version": "1.0.0", + "author": { + "name": "rknall", + "email": "zhongweili@tubi.tv" + }, + "skills": [ + "./" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4719052 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# newt-blueprint-generator + +Generate and validate Pangolin Newt blueprint configurations in YAML or Docker Labels format. Creates proxy resources (HTTP/TCP/UDP), client resources, authentication settings, and access control rules diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..00cadba --- /dev/null +++ b/SKILL.md @@ -0,0 +1,495 @@ +--- +name: "Newt Blueprint Generator" +description: "Generate and validate Pangolin Newt blueprint configurations in YAML or Docker Labels format. Use when creating Pangolin resource configurations, proxy resources, client resources, authentication settings, or Docker Compose blueprints." +--- + +# Newt Blueprint Generator + +Expert assistance for creating, validating, and managing Pangolin Newt blueprint configurations. + +## When to Use This Skill + +This skill should be triggered when: +- Creating Pangolin blueprint configurations +- Generating YAML configuration files for Newt +- Creating Docker Compose files with Pangolin labels +- Configuring proxy resources (HTTP, TCP, UDP) +- Setting up client resources for Olm +- Configuring authentication (SSO, basic auth, pincode, password) +- Validating blueprint configurations +- Troubleshooting blueprint validation errors +- Converting between YAML and Docker Labels formats + +## Overview + +Pangolin Blueprints are declarative configurations that allow you to define resources and their settings in a structured format. They support two formats: + +1. **YAML Configuration Files**: Standalone configuration files +2. **Docker Labels**: Configuration embedded in Docker Compose files + +## Blueprint Formats + +### YAML Configuration Format + +YAML configs can be applied using: +- **Newt CLI**: Pass `--blueprint-file /path/to/blueprint.yaml` +- **API**: POST to `/org/{orgId}/blueprint` with base64-encoded JSON body + +Example Newt usage: +```bash +newt --blueprint-file /path/to/blueprint.yaml +``` + +### Docker Labels Format + +For containerized applications, blueprints can be defined using Docker labels with the `pangolin.` prefix. + +Enable Docker socket access: +```bash +newt --docker-socket /var/run/docker.sock +``` + +Or use environment variable: +```bash +DOCKER_SOCKET=/var/run/docker.sock +``` + +## Resource Types + +### Proxy Resources + +Proxy resources expose HTTP, TCP, or UDP services through Pangolin. + +#### HTTP Proxy Resource Example + +```yaml +proxy-resources: + resource-nice-id-uno: + name: this is a http resource + protocol: http + full-domain: uno.example.com + host-header: example.com + tls-server-name: example.com + headers: + - name: X-Example-Header + value: example-value + - name: X-Another-Header + value: another-value + rules: + - action: allow + match: ip + value: 1.1.1.1 + - action: deny + match: cidr + value: 2.2.2.2/32 + - action: pass + match: path + value: /admin + targets: + - site: lively-yosemite-toad + hostname: localhost + method: http + port: 8000 + - site: slim-alpine-chipmunk + hostname: localhost + path: /admin + path-match: exact + method: https + port: 8001 +``` + +#### TCP/UDP Proxy Resource Example + +```yaml +proxy-resources: + resource-nice-id-dos: + name: this is a raw resource + protocol: tcp + proxy-port: 3000 + targets: + - site: lively-yosemite-toad + hostname: localhost + port: 3000 +``` + +#### Targets-Only Resources + +Simplified resources containing only target configurations: + +```yaml +proxy-resources: + additional-targets: + targets: + - site: another-site + hostname: backend-server + method: https + port: 8443 + - site: another-site + hostname: backup-server + method: http + port: 8080 +``` + +**Note**: When using targets-only resources, `name` and `protocol` fields are not required. + +### Client Resources + +Client resources define proxied resources accessible via Olm client (SSH, RDP): + +```yaml +client-resources: + client-resource-nice-id-uno: + name: this is my resource + protocol: tcp + proxy-port: 3001 + hostname: localhost + internal-port: 3000 + site: lively-yosemite-toad +``` + +## Authentication Configuration + +Authentication is **off by default**. Enable by adding fields in the `auth` section. + +**Note**: Authentication is only allowed on HTTP resources, not TCP/UDP. + +```yaml +proxy-resources: + secure-resource: + name: Secured Resource + protocol: http + full-domain: secure.example.com + auth: + pincode: 123456 + password: your-secure-password + basic-auth: + user: asdfa + password: sadf + sso-enabled: true + sso-roles: + - Member + - Admin + sso-users: + - user@example.com + whitelist-users: + - admin@example.com +``` + +## Docker Labels Format + +### Complete Docker Compose Example + +```yaml +services: + newt: + image: fosrl/newt + container_name: newt + restart: unless-stopped + volumes: + - /var/run/docker.sock:/var/run/docker.sock + environment: + - PANGOLIN_ENDPOINT=https://app.pangolin.net + - NEWT_ID=h1rbsgku89wf9z3 + - NEWT_SECRET=z7g54mbcwkglpx1aau9gb8mzcccoof2fdbs97keoakg2pp5z + - DOCKER_SOCKET=/var/run/docker.sock + + nginx1: + image: nginxdemos/hello + container_name: nginx1 + labels: + # Proxy Resource Configuration + - pangolin.proxy-resources.nginx.name=nginx + - pangolin.proxy-resources.nginx.full-domain=nginx.fosrl.io + - pangolin.proxy-resources.nginx.protocol=http + - pangolin.proxy-resources.nginx.headers[0].name=X-Example-Header + - pangolin.proxy-resources.nginx.headers[0].value=example-value + # Target Configuration - port and hostname auto-detected + - pangolin.proxy-resources.nginx.targets[0].method=http + - pangolin.proxy-resources.nginx.targets[0].path=/path + - pangolin.proxy-resources.nginx.targets[0].path-match=prefix + + nginx2: + image: nginxdemos/hello + container_name: nginx2 + labels: + # Additional target with explicit hostname and port + - pangolin.proxy-resources.nginx.targets[1].method=http + - pangolin.proxy-resources.nginx.targets[1].hostname=nginx2 + - pangolin.proxy-resources.nginx.targets[1].port=80 + +networks: + default: + name: pangolin_default +``` + +### Docker Labels Considerations + +- **Automatic Discovery**: When hostname and internal port are not defined, Pangolin auto-detects from container configuration +- **Site Assignment**: If no site is specified, resource is assigned to the discovering Newt site +- **Configuration Merging**: Configuration across containers is merged to form complete resource definitions + +## Configuration Properties Reference + +### Proxy Resources Properties + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `name` | string | Conditional | Human-readable name | Required unless targets-only | +| `protocol` | string | Conditional | Protocol type (`http`, `tcp`, `udp`) | Required unless targets-only | +| `full-domain` | string | HTTP only | Full domain name | Required for HTTP, must be unique | +| `proxy-port` | number | TCP/UDP only | Port for raw TCP/UDP | Required for TCP/UDP, 1-65535, must be unique | +| `ssl` | boolean | No | Enable SSL/TLS | - | +| `enabled` | boolean | No | Whether resource is enabled | Defaults to `true` | +| `host-header` | string | No | Custom Host header | - | +| `tls-server-name` | string | No | SNI name for TLS | - | +| `headers` | array | No | Custom headers | Each requires `name` and `value` (min 1 char) | +| `rules` | array | No | Access control rules | See Rules section | +| `auth` | object | HTTP only | Authentication config | See Authentication section | +| `targets` | array | Yes | Target endpoints | See Targets section | + +### Target Configuration Properties + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `site` | string | No | Site identifier | - | +| `hostname` | string | Yes | Target hostname or IP | - | +| `port` | number | Yes | Target port | 1-65535 | +| `method` | string | HTTP only | Protocol method (`http`, `https`, `h2c`) | Required for HTTP | +| `enabled` | boolean | No | Whether target is enabled | Defaults to `true` | +| `internal-port` | number | No | Internal port mapping | 1-65535 | +| `path` | string | HTTP only | Path prefix, exact, or regex | - | +| `path-match` | string | HTTP only | Path matching type (`prefix`, `exact`, `regex`) | - | + +### Authentication Properties + +**Not allowed on TCP/UDP resources.** + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `pincode` | number | No | 6-digit PIN | Must be exactly 6 digits | +| `password` | string | No | Password for access | - | +| `basic-auth` | object | No | Basic auth config | Requires `user` and `password` | +| `sso-enabled` | boolean | No | Enable SSO | Defaults to `false` | +| `sso-roles` | array | No | Allowed SSO roles | Cannot include "Admin" role | +| `sso-users` | array | No | Allowed SSO user emails | Must be valid emails | +| `whitelist-users` | array | No | Whitelisted user emails | Must be valid emails | + +### Rules Configuration Properties + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `action` | string | Yes | Rule action (`allow`, `deny`, `pass`) | - | +| `match` | string | Yes | Match type (`cidr`, `path`, `ip`, `country`) | - | +| `value` | string | Yes | Value to match | Format depends on match type | + +### Client Resources Properties + +| Property | Type | Required | Description | Constraints | +|----------|------|----------|-------------|-------------| +| `name` | string | Yes | Human-readable name | 2-100 characters | +| `protocol` | string | Yes | Protocol type (`tcp`, `udp`) | - | +| `proxy-port` | number | Yes | Port accessible to clients | 1-65535, must be unique | +| `hostname` | string | Yes | Target hostname or IP | 1-255 characters | +| `internal-port` | number | Yes | Port on target system | 1-65535 | +| `site` | string | No | Site identifier | 2-100 characters | +| `enabled` | boolean | No | Whether resource is enabled | Defaults to `true` | + +## Validation Rules and Constraints + +### Resource-Level Validations + +1. **Targets-Only Resources**: A resource can contain only `targets` field, making `name` and `protocol` optional +2. **Protocol-Specific Requirements**: + - **HTTP Protocol**: Must have `full-domain` and all targets must have `method` field + - **TCP/UDP Protocol**: Must have `proxy-port` and targets must NOT have `method` field + - **TCP/UDP Protocol**: Cannot have `auth` configuration +3. **Port Uniqueness**: + - `proxy-port` values must be unique within `proxy-resources` + - `proxy-port` values must be unique within `client-resources` + - Cross-validation between proxy and client resources is not enforced +4. **Domain Uniqueness**: `full-domain` values must be unique across all proxy resources +5. **Target Method Requirements**: When protocol is `http`, all non-null targets must specify a `method` + +## Common Validation Errors + +### "Admin role cannot be included in sso-roles" + +The `Admin` role is reserved and cannot be included in the `sso-roles` array. + +**Solution**: Remove "Admin" from the `sso-roles` array. + +### "Duplicate 'full-domain' values found" + +Each `full-domain` must be unique across all proxy resources. + +**Solution**: Use different subdomains or paths for multiple resources. + +### "Duplicate 'proxy-port' values found" + +Port numbers in `proxy-port` must be unique within their resource type. + +**Solution**: Assign unique port numbers within `proxy-resources` and `client-resources` separately. + +### "When protocol is 'http', all targets must have a 'method' field" + +All targets in HTTP proxy resources must specify the connection method. + +**Solution**: Add `method: http`, `method: https`, or `method: h2c` to all targets. + +### "When protocol is 'tcp' or 'udp', targets must not have a 'method' field" + +TCP and UDP targets should not include the `method` field. + +**Solution**: Remove the `method` field from TCP/UDP resource targets. + +### "When protocol is 'tcp' or 'udp', 'auth' must not be provided" + +Authentication is only supported for HTTP resources. + +**Solution**: Remove the `auth` section from TCP/UDP resources. + +### "Resource must either be targets-only or have both 'name' and 'protocol' fields" + +Resources must be either targets-only or complete resource definitions. + +**Solution**: Either provide only `targets` field, or include both `name` and `protocol` fields. + +## Workflow for Generating Blueprints + +When a user requests a Pangolin Newt blueprint configuration: + +1. **Gather Requirements**: + - Resource type (proxy or client) + - Protocol (HTTP, TCP, UDP) + - Domain or port requirements + - Target endpoints (hostname, port, site) + - Authentication needs (if HTTP) + - Access control rules (if any) + - Format preference (YAML or Docker Labels) + +2. **Select Format**: + - Use **YAML** for standalone configurations or API deployment + - Use **Docker Labels** for containerized applications + +3. **Validate Configuration**: + - Ensure protocol-specific requirements are met + - Check for unique `full-domain` (HTTP) or `proxy-port` (TCP/UDP) + - Verify authentication is only on HTTP resources + - Confirm all HTTP targets have `method` field + - Ensure TCP/UDP targets don't have `method` field + +4. **Generate Configuration**: + - Create well-structured YAML or Docker Compose file + - Include helpful comments explaining each section + - Follow naming conventions (kebab-case for resource IDs) + +5. **Provide Usage Instructions**: + - Explain how to apply the configuration (Newt CLI or API) + - Document any environment variables needed + - Include validation commands if applicable + +## Best Practices + +1. **Resource IDs**: Use descriptive, kebab-case identifiers (e.g., `web-app-prod`, `database-backup`) +2. **Target Organization**: Group related targets under the same resource ID +3. **Security First**: Enable authentication for sensitive HTTP resources +4. **Port Management**: Document port assignments to avoid conflicts +5. **Site Assignment**: Explicitly specify `site` for multi-site deployments +6. **Path Matching**: Use `prefix` for broad matches, `exact` for specific endpoints +7. **Headers**: Add custom headers for backend requirements (e.g., X-Forwarded-* headers) +8. **Rules**: Order rules from most specific to least specific +9. **Validation**: Always validate configurations before deployment +10. **Documentation**: Include comments in YAML or Docker Compose files explaining non-obvious choices + +## Resources + +- **API Documentation**: https://api.pangolin.net/v1/docs/#/Organization/put_org__orgId__blueprint +- **Python Example**: https://github.com/fosrl/pangolin/blob/dev/blueprint.py +- **Official Docs**: https://docs.pangolin.net/manage/blueprints + +## Example Use Cases + +### Use Case 1: Simple Web Application + +**Requirements**: Expose a web app running on localhost:8080 via HTTPS at app.example.com + +```yaml +proxy-resources: + web-app: + name: Web Application + protocol: http + full-domain: app.example.com + targets: + - hostname: localhost + port: 8080 + method: https +``` + +### Use Case 2: TCP Database Access + +**Requirements**: Expose PostgreSQL database on port 5432 + +```yaml +proxy-resources: + postgres-db: + name: PostgreSQL Database + protocol: tcp + proxy-port: 5432 + targets: + - hostname: localhost + port: 5432 +``` + +### Use Case 3: Multi-Target Load Balanced HTTP Service + +**Requirements**: Multiple backend servers for the same domain + +```yaml +proxy-resources: + api-service: + name: API Service + protocol: http + full-domain: api.example.com + targets: + - site: site-01 + hostname: backend-01 + port: 8080 + method: http + - site: site-02 + hostname: backend-02 + port: 8080 + method: http +``` + +### Use Case 4: Secured Resource with SSO + +**Requirements**: Web app with SSO authentication + +```yaml +proxy-resources: + secure-app: + name: Secure Application + protocol: http + full-domain: secure.example.com + auth: + sso-enabled: true + sso-roles: + - Member + - Developer + sso-users: + - admin@example.com + targets: + - hostname: localhost + port: 3000 + method: https +``` + +## Communication Style + +When generating blueprints: +- Ask clarifying questions if requirements are unclear +- Explain validation errors in plain language +- Provide complete, working examples +- Include comments for complex configurations +- Suggest security best practices proactively +- Offer both YAML and Docker Labels formats when appropriate diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..b27baae --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,49 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:rknall/claude-skills:newt-blueprint-generator", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "4a013daf740104f4f9bb39eec139dbeebe2a114d", + "treeHash": "dae32f7386bbbfbafc1ab8fb67bc54cf084c9b71c61ef4317f0186539f959ed5", + "generatedAt": "2025-11-28T10:27:59.701748Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "newt-blueprint-generator", + "description": "Generate and validate Pangolin Newt blueprint configurations in YAML or Docker Labels format. Creates proxy resources (HTTP/TCP/UDP), client resources, authentication settings, and access control rules", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "aa1b65979102e6adc5f9aee0db4f09620dbc1cdab7d23e5d8d0d1ec552beb91f" + }, + { + "path": "SKILL.md", + "sha256": "943f4af9fe6fde2f32c2792c7154f2e14a6b1a280e13e60ca6f448fd97fb78d4" + }, + { + "path": "validation-reference.md", + "sha256": "57f4c3ebddc13d42efba4beec0a2e0b1f5fad92ed0f4687ebfd66bd5ddd1bbdb" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "f733e83af446ab3d93aad3a5521e277056cf8b00ddad41626b0092e001036f1e" + } + ], + "dirSha256": "dae32f7386bbbfbafc1ab8fb67bc54cf084c9b71c61ef4317f0186539f959ed5" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/validation-reference.md b/validation-reference.md new file mode 100644 index 0000000..12b2174 --- /dev/null +++ b/validation-reference.md @@ -0,0 +1,454 @@ +# Validation Reference + +This document provides a comprehensive reference for all validation rules and constraints in Pangolin Newt blueprints. + +## Table of Contents + +1. [Resource-Level Validations](#resource-level-validations) +2. [Property Constraints](#property-constraints) +3. [Common Validation Errors](#common-validation-errors) +4. [Validation Quick Reference](#validation-quick-reference) + +## Resource-Level Validations + +### Targets-Only Resources + +A resource can contain **only** the `targets` field: + +```yaml +proxy-resources: + additional-targets: + targets: + - site: another-site + hostname: backend-server + method: https + port: 8443 +``` + +When using targets-only: +- `name` field is NOT required +- `protocol` field is NOT required +- All other resource-level validations are skipped + +### Protocol-Specific Requirements + +#### HTTP Protocol + +**Required fields:** +- `full-domain` - Must be unique across all proxy resources +- All targets must have `method` field (`http`, `https`, or `h2c`) + +**Optional features:** +- `auth` configuration (SSO, basic auth, pincode, password) +- `headers` array +- `rules` array +- `host-header` +- `tls-server-name` +- `ssl` boolean + +**Not allowed:** +- `proxy-port` (use `full-domain` instead) + +#### TCP/UDP Protocol + +**Required fields:** +- `proxy-port` - Must be unique within `proxy-resources` +- Port range: 1-65535 + +**Not allowed:** +- `method` field in targets +- `auth` configuration (authentication not supported) +- `full-domain` (use `proxy-port` instead) + +## Property Constraints + +### Port Constraints + +| Property | Scope | Range | Uniqueness | +|----------|-------|-------|------------| +| `proxy-port` | proxy-resources | 1-65535 | Must be unique within proxy-resources | +| `proxy-port` | client-resources | 1-65535 | Must be unique within client-resources | +| `port` (target) | All | 1-65535 | No uniqueness constraint | +| `internal-port` | All | 1-65535 | No uniqueness constraint | + +**Important:** Cross-validation between proxy and client resources is NOT enforced. You can use the same port in both `proxy-resources` and `client-resources`. + +### Domain Constraints + +| Property | Scope | Uniqueness | Format | +|----------|-------|------------|--------| +| `full-domain` | proxy-resources (HTTP only) | Must be unique across all proxy resources | Valid domain name | + +### String Length Constraints + +| Property | Min Length | Max Length | Context | +|----------|------------|------------|---------| +| `name` | 2 | 100 | All resources | +| `hostname` | 1 | 255 | All targets | +| `site` | 2 | 100 | Optional site identifier | +| `header.name` | 1 | - | Header names | +| `header.value` | 1 | - | Header values | + +### Authentication Constraints + +#### SSO Roles + +- Cannot include `"Admin"` role (reserved) +- Must be array of strings +- Each role must be valid + +#### SSO Users & Whitelist Users + +- Must be valid email addresses +- Must be array of strings + +#### Pincode + +- Must be exactly 6 digits +- Type: number +- Example: `123456` + +#### Basic Auth + +- Must have both `user` and `password` fields +- Both fields are required strings + +## Common Validation Errors + +### 1. "Admin role cannot be included in sso-roles" + +**Cause:** The `Admin` role is reserved and cannot be included in `sso-roles` array. + +**Solution:** +```yaml +# ❌ Wrong +auth: + sso-enabled: true + sso-roles: + - Admin # This will fail + - Member + +# ✅ Correct +auth: + sso-enabled: true + sso-roles: + - Member + - Developer +``` + +### 2. "Duplicate 'full-domain' values found" + +**Cause:** Each `full-domain` must be unique across all proxy resources. + +**Solution:** +```yaml +# ❌ Wrong - same domain twice +proxy-resources: + app1: + full-domain: app.example.com + # ... + app2: + full-domain: app.example.com # Duplicate! + # ... + +# ✅ Correct - use different subdomains or paths +proxy-resources: + app1: + full-domain: app1.example.com + # ... + app2: + full-domain: app2.example.com + # ... +``` + +### 3. "Duplicate 'proxy-port' values found" + +**Cause:** Port numbers in `proxy-port` must be unique within their resource type. + +**Solution:** +```yaml +# ❌ Wrong - same port twice in proxy-resources +proxy-resources: + db1: + protocol: tcp + proxy-port: 5432 + # ... + db2: + protocol: tcp + proxy-port: 5432 # Duplicate! + # ... + +# ✅ Correct - use different ports +proxy-resources: + db1: + protocol: tcp + proxy-port: 5432 + # ... + db2: + protocol: tcp + proxy-port: 5433 + # ... +``` + +### 4. "When protocol is 'http', all targets must have a 'method' field" + +**Cause:** HTTP targets must specify connection method. + +**Solution:** +```yaml +# ❌ Wrong - missing method +proxy-resources: + web-app: + protocol: http + full-domain: app.example.com + targets: + - hostname: localhost + port: 8080 + # Missing method! + +# ✅ Correct - method specified +proxy-resources: + web-app: + protocol: http + full-domain: app.example.com + targets: + - hostname: localhost + port: 8080 + method: https # Added method +``` + +### 5. "When protocol is 'tcp' or 'udp', targets must not have a 'method' field" + +**Cause:** TCP/UDP targets should not include the `method` field. + +**Solution:** +```yaml +# ❌ Wrong - method on TCP target +proxy-resources: + database: + protocol: tcp + proxy-port: 5432 + targets: + - hostname: localhost + port: 5432 + method: tcp # Not allowed for TCP/UDP! + +# ✅ Correct - no method field +proxy-resources: + database: + protocol: tcp + proxy-port: 5432 + targets: + - hostname: localhost + port: 5432 + # No method field +``` + +### 6. "When protocol is 'tcp' or 'udp', 'auth' must not be provided" + +**Cause:** Authentication is only supported for HTTP resources. + +**Solution:** +```yaml +# ❌ Wrong - auth on TCP resource +proxy-resources: + database: + protocol: tcp + proxy-port: 5432 + auth: + password: secret # Not allowed! + targets: + - hostname: localhost + port: 5432 + +# ✅ Correct - no auth on TCP +proxy-resources: + database: + protocol: tcp + proxy-port: 5432 + # No auth field + targets: + - hostname: localhost + port: 5432 +``` + +### 7. "Resource must either be targets-only or have both 'name' and 'protocol' fields" + +**Cause:** Incomplete resource definition. + +**Solution:** +```yaml +# ❌ Wrong - has name but no protocol +proxy-resources: + incomplete: + name: My Resource + # Missing protocol! + targets: + - hostname: localhost + port: 8080 + +# ✅ Correct - complete definition +proxy-resources: + complete: + name: My Resource + protocol: http + full-domain: app.example.com + targets: + - hostname: localhost + port: 8080 + method: http + +# ✅ Also correct - targets-only +proxy-resources: + targets-only: + targets: + - hostname: localhost + port: 8080 + method: http +``` + +## Validation Quick Reference + +### ✅ Valid Configurations + +#### HTTP Resource - Complete + +```yaml +proxy-resources: + web-app: + name: Web Application + protocol: http + full-domain: app.example.com + enabled: true + ssl: true + host-header: backend.internal + tls-server-name: backend.internal + headers: + - name: X-Custom-Header + value: custom-value + auth: + sso-enabled: true + sso-roles: + - Member + sso-users: + - user@example.com + rules: + - action: allow + match: ip + value: 1.1.1.1 + targets: + - site: site-01 + hostname: localhost + port: 8080 + method: https + enabled: true + path: /api + path-match: prefix +``` + +#### TCP Resource - Complete + +```yaml +proxy-resources: + database: + name: PostgreSQL Database + protocol: tcp + proxy-port: 5432 + enabled: true + targets: + - site: site-01 + hostname: localhost + port: 5432 + enabled: true +``` + +#### Targets-Only Resource + +```yaml +proxy-resources: + additional-targets: + targets: + - site: site-02 + hostname: backend-02 + port: 8080 + method: http +``` + +#### Client Resource + +```yaml +client-resources: + ssh-server: + name: SSH Server + protocol: tcp + proxy-port: 2222 + hostname: localhost + internal-port: 22 + site: site-01 + enabled: true +``` + +### ❌ Invalid Configurations + +#### Mixed Protocol Requirements + +```yaml +# ❌ INVALID - HTTP resource with proxy-port instead of full-domain +proxy-resources: + wrong: + name: Wrong Config + protocol: http + proxy-port: 8080 # Should be full-domain for HTTP! + targets: + - hostname: localhost + port: 8080 + method: http +``` + +#### TCP with Auth + +```yaml +# ❌ INVALID - TCP resource with auth +proxy-resources: + wrong: + name: Wrong Config + protocol: tcp + proxy-port: 5432 + auth: # Auth not allowed on TCP/UDP! + password: secret + targets: + - hostname: localhost + port: 5432 +``` + +#### Missing Required Fields + +```yaml +# ❌ INVALID - HTTP target without method +proxy-resources: + wrong: + name: Wrong Config + protocol: http + full-domain: app.example.com + targets: + - hostname: localhost + port: 8080 + # Missing method field! +``` + +## Validation Checklist + +Before deploying a blueprint, verify: + +- [ ] All HTTP resources have unique `full-domain` values +- [ ] All TCP/UDP resources have unique `proxy-port` values within their type +- [ ] All HTTP targets have `method` field specified +- [ ] No TCP/UDP targets have `method` field +- [ ] No TCP/UDP resources have `auth` configuration +- [ ] All port numbers are in range 1-65535 +- [ ] All email addresses in `sso-users` and `whitelist-users` are valid +- [ ] SSO roles do not include "Admin" +- [ ] Pincode (if used) is exactly 6 digits +- [ ] Basic auth (if used) has both `user` and `password` fields +- [ ] String fields meet minimum/maximum length requirements +- [ ] Resources are either targets-only OR have both `name` and `protocol`