Initial commit
This commit is contained in:
12
.claude-plugin/plugin.json
Normal file
12
.claude-plugin/plugin.json
Normal file
@@ -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": [
|
||||||
|
"./"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -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
|
||||||
495
SKILL.md
Normal file
495
SKILL.md
Normal file
@@ -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 <other-args>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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 <other-args>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
49
plugin.lock.json
Normal file
49
plugin.lock.json
Normal file
@@ -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": []
|
||||||
|
}
|
||||||
|
}
|
||||||
454
validation-reference.md
Normal file
454
validation-reference.md
Normal file
@@ -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`
|
||||||
Reference in New Issue
Block a user