Ingestor Plugin Architecture
Overview
The Ingestor plugin is a Backstage backend module that automatically discovers Kubernetes resources and transforms Crossplane XRDs into Backstage entities. The plugin uses a modular architecture with a template-based transformation system for generating Backstage templates from XRDs.
Directory Structure
ingestor/
├── src/
│ ├── backstage-plugin/ # Backstage integration
│ │ ├── entity-providers/ # Entity provider implementations
│ │ │ ├── XRDTemplateEntityProvider.ts # XRD/CRD template generation
│ │ │ ├── KubernetesEntityProvider.ts # K8s resource ingestion
│ │ │ └── index.ts
│ │ │
│ │ ├── interfaces/ # Type definitions
│ │ │ ├── BackstageLink.ts # Link interface for entities
│ │ │ └── index.ts
│ │ │
│ │ ├── data-providers/ # Data fetching providers
│ │ │ ├── CRDDataProvider.ts # Fetches CRD definitions
│ │ │ ├── XRDDataProvider.ts # Fetches XRD definitions
│ │ │ ├── KubernetesDataProvider.ts # Fetches K8s resources
│ │ │ └── index.ts
│ │ │
│ │ ├── services/ # Core services
│ │ │ ├── KubernetesResourceFetcher.ts # K8s API client wrapper
│ │ │ ├── LoggerWrapper.ts # Winston logger adapter
│ │ │ └── index.ts
│ │ │
│ │ ├── module.ts # Backend module registration
│ │ └── types.ts # Plugin-specific types
│ │
│ ├── xrd-transform/ # XRD transformation tool (NEW!)
│ │ ├── cli/ # CLI interface
│ │ │ └── xrd-transform-cli.ts # Command-line tool
│ │ │
│ │ ├── lib/ # Core transformation library
│ │ │ ├── transform.ts # XRDTransformer class
│ │ │ └── types.ts # Transform-specific types
│ │ │
│ │ ├── helpers/ # Template helper functions
│ │ │ └── index.ts # Handlebars helpers
│ │ │
│ │ └── index.ts # Public API exports
│ │
│ ├── index.ts # Main entry point
│ └── types.ts # Shared type definitions
│
├── templates/ # Handlebars templates (NEW!)
│ ├── backstage/ # Main Backstage Template entities
│ │ └── default.hbs
│ ├── parameters/ # Scaffolder form parameters
│ │ └── default.hbs
│ ├── steps/ # Scaffolder workflow steps
│ │ └── default.hbs
│ ├── api/ # API documentation entities
│ │ └── default.hbs
│ └── README.md # Template development guide
│
├── docs/ # Documentation
├── config.d.ts # Configuration schema
├── package.json # Package metadata
└── tsconfig.json # TypeScript configuration
Architecture Diagram
Component Overview
1. Backstage Plugin Layer
Entity Providers
XRDTemplateEntityProvider
- Discovers Crossplane XRDs from Kubernetes clusters
- Uses XRDTransformer to generate Backstage Template entities
- Supports annotation-based template selection
- Generates both Template and API documentation entities
KubernetesEntityProvider
- Discovers standard Kubernetes resources
- Converts resources to Backstage Component entities
- Extracts metadata and relationships
- Supports XR status link extraction
Data Providers
XRDDataProvider
- Fetches Crossplane Composite Resource Definitions
- Filters by labels and annotations
- Provides structured XRD data to entity providers
CRDDataProvider
- Fetches standard Kubernetes Custom Resource Definitions
- Used for CRD-based template generation
KubernetesDataProvider
- Generic Kubernetes resource fetching
- Supports any resource kind/version
- Namespace filtering and label selectors
Services
KubernetesResourceFetcher
- Wrapper around Kubernetes client
- Handles authentication and cluster connections
- Provides consistent error handling
- Supports multiple cluster configurations
LoggerWrapper
- Adapts Winston logger to plugin needs
- Consistent logging across components
- Debug and error tracking
2. XRD Transform System (NEW!)
The XRD Transform system is the core of template generation, using a modular Handlebars-based approach.
XRDTransformer Class
Located in src/xrd-transform/lib/transform.ts:
export class XRDTransformer {
private handlebars: typeof Handlebars;
private templateDir: string;
private helpers: ReturnType<typeof createHelpers>;
async transform(xrdData: XRDExtractData, options?: TransformOptions): Promise<TransformResult>
async transformBatch(xrdDataArray: XRDExtractData[], options?: TransformOptions): Promise<TransformResult>
}
Key Features:
- Modular Templates: Separate templates for parameters, steps, main structure
- Helper Functions: Custom Handlebars helpers for XRD processing
- Annotation-Based: Template selection via XRD annotations
- Multi-Stage Rendering: Parameters and steps rendered first, then composed
Template System
Templates are organized by function:
Main Templates (templates/backstage/)
default.hbs- Standard Backstage Template entity structure- Composes pre-rendered parameters and steps
Parameter Templates (templates/parameters/)
default.hbs- Scaffolder form field generation- Extracts properties from XRD schema
- Generates validation rules
Step Templates (templates/steps/)
default.hbs- Scaffolder workflow definition- Creates kubernetes:apply actions
- Handles catalog registration
API Templates (templates/api/)
default.hbs- OpenAPI documentation generation- Documents resource endpoints
- Includes schema definitions
Helper Functions
Located in src/xrd-transform/helpers/index.ts:
slugify(text)- Convert text to URL-safe formatextractTitle(xrd)- Get human-readable titleextractProperties(xrd)- Parse schema propertiesgetAnnotation(xrd, key)- Get annotation valuegetLabel(xrd, key)- Get label valuebackstageVar(path)- Preserve Backstage variable syntaxsplit(str, delimiter)- Split comma-separated stringstrim(str)- Remove whitespace
Annotation-Based Template Selection
XRDs can specify which templates to use:
apiVersion: apiextensions.crossplane.io/v2
kind: CompositeResourceDefinition
metadata:
name: databases.platform.io
annotations:
openportal.dev/template-api: "default" # API docs
openportal.dev/template: "default" # Main template
openportal.dev/template-parameters: "database" # Custom form fields
openportal.dev/template-steps: "gitops" # Custom workflow
openportal.dev/tags: "database,storage" # Comma-separated tags
3. CLI Tools
XRD Transform CLI
Located in src/xrd-transform/cli/xrd-transform-cli.ts:
Features:
- Transform XRDs from files or stdin
- Entity type filtering (
--only template|api) - Custom template directories (
-t) - Output to files or stdout (
-o) - Verbose mode for debugging (
-v)
Usage:
npx ts-node src/xrd-transform/cli/xrd-transform-cli.ts xrd.yaml --only template
Wrapper Script:
The workspace provides scripts/xrd-transform.sh for easier access:
./scripts/xrd-transform.sh template-namespace/configuration/xrd.yaml
Data Flow
Template Generation Flow
- Discovery: XRDTemplateEntityProvider discovers XRDs from Kubernetes
- Fetch: XRDDataProvider fetches XRD YAML via KubernetesResourceFetcher
- Extract: XRD data is structured with metadata (cluster, namespace, etc.)
- Transform:
- XRDTransformer reads template configuration from annotations
- Renders parameters template with XRD context
- Renders steps template with XRD context
- Composes main template with pre-rendered sections
- Parse: YAML output is parsed into entity objects
- Register: Entities are provided to Backstage catalog
Resource Ingestion Flow
- Discovery: KubernetesEntityProvider discovers resources from Kubernetes
- Fetch: KubernetesDataProvider fetches resource YAMLs
- Extract: Metadata and status links are extracted
- Transform: Resources are converted to Component entities
- Enrich: Links and relationships are added
- Register: Entities are provided to Backstage catalog
Configuration
The plugin supports extensive configuration:
kubernetesIngestor:
components:
enabled: true
excludedNamespaces:
- kube-system
crossplane:
enabled: true
xrds:
enabled: true
templateDir: ./custom-templates # Optional custom templates
See configuration.md for complete reference.
Extension Points
Custom Templates
Create custom templates for specific use cases:
-
Copy built-in templates:
cp -r templates my-templates -
Modify templates:
vim my-templates/parameters/database.hbs -
Use via annotation:
metadata:
annotations:
openportal.dev/template-parameters: "database" -
Configure plugin:
kubernetesIngestor:
crossplane:
xrds:
templateDir: ./my-templates
Custom Helpers
Add custom Handlebars helpers in src/xrd-transform/helpers/index.ts:
export function createHelpers() {
return {
myCustomHelper: (value: string) => {
// Custom logic
return transformedValue;
},
// ... other helpers
};
}
Testing
The plugin includes comprehensive testing:
- Unit Tests: Test individual components
- Integration Tests: Test complete transformation flows
- CLI Tests: Test command-line interface
- Template Tests: Test template rendering
Run tests:
yarn test
Performance Considerations
- Caching: Template compilation is cached per XRDTransformer instance
- Batch Processing: Multiple XRDs can be transformed together
- Scheduling: Entity providers use configurable refresh intervals
- Resource Filtering: Namespace and label filters reduce API calls
Security
- RBAC: Requires appropriate Kubernetes service account permissions
- Template Validation: Templates are validated before use
- Input Sanitization: XRD data is sanitized before template rendering
- Secret Handling: No secrets are included in generated entities
Troubleshooting
Template Errors
Template not found:
Error: Template not found: custom-template (and no default.hbs)
- Ensure template exists in
templates/{type}/directory - Check template name matches annotation value
- Verify
templateDirconfiguration
YAML parsing errors:
Failed to parse template output as YAML
- Check template indentation (YAML requires precise spacing)
- Use
{{{variable}}}for pre-rendered content (triple braces) - Test template with
--verboseflag
Common Issues
- XRDs not discovered: Check RBAC permissions
- Templates not generated: Verify XRD has required schema
- Custom templates not loaded: Check
templateDirpath - Helper function errors: Ensure helpers return correct types
Migration from Legacy System
The plugin was refactored from a complex multi-layer architecture to the current template-based system:
Removed:
core/- IngestionEngine, ResourceValidator, XRDEntityBuilder (~5,000 lines)entity-builders/- ParametersBuilder, StepsBuilder, TemplateEntityBuildertemplate-handlers/- XRDTemplateHandlerV1/V2yaml-builders/- OpenAPIDocBuilder, StepsYamlBuilder
Added:
xrd-transform/- Modular transformation systemtemplates/- Handlebars template files- Annotation-based configuration
Benefits:
- ~5,600 fewer lines of code
- Easier to understand and maintain
- Template customization without code changes
- Clear separation of concerns