Skip to content

Cross-Connector Shared Infrastructure Package (issue 1 of 29) #4039

Description

@gabemontero

Labels: ready-to-code
Dependencies: None
RHIDP Stories: RHIDP-15265, RHIDP-15266, RHIDP-15329, RHIDP-15330
Feature: RHDHPLAN-1510 — Epic RHIDP-15316

Create the @red-hat-developer-hub/backstage-plugin-boost-connector-utils shared package providing CA bundle resolution, fault isolation wrappers (including createSafeRefresh() for scheduled refresh callbacks), enable/disable patterns, and configurable endpoint/credential validation. All entity-provider connectors (MCP Registry, RHOAI, OCI Skill) depend on this package. Includes reference app-config YAML for air-gapped deployment with Helm and Operator CR examples.

Config note: ai-catalog.providers.<id>.enabled controls startup registration (YAML-only). boost.connectors.<id>.enabled controls runtime sync-skip (db-overridable). Do not treat them as the same flag — see openspec/changes/connector-config-hot-reload/design.md.

Tasks

From openspec/changes/connector-shared-infrastructure/tasks.md group 1 (RHIDP-15329):

  • 1.1 Create @red-hat-developer-hub/backstage-plugin-boost-connector-utils package with package.json, TypeScript config, and README
  • 1.2 Define loadCaBundle(connectorConfig: Config): Buffer | undefined function signature — caller passes the Config subtree containing the tls block
  • 1.3 Implement caFile resolution — read CA from tls.caFile within the provided Config subtree
  • 1.4 Implement caSecret resolution — read CA from tls.caSecret.$env within the provided Config subtree
  • 1.5 Add per-connector config isolation — each connector resolves its own Config nesting before calling loadCaBundle() (e.g., MCP passes config.getConfig('ai-catalog.providers.mcpRegistry'), RHOAI passes config.getConfig('ai-catalog.providers.rhoai.mcpCatalog'), OCI passes per-registry Config node)
  • 1.6 Create https.Agent factory utility: createHttpsAgent(caBundle?: Buffer): https.Agent | undefined
  • 1.7 Handle missing CA file: log WARN-level warning with expected file path, return undefined (don't crash)
  • 1.8 Handle invalid/expired CA certificate: log ERROR with certificate details
  • 1.9 Support CA certificate chains (concatenated PEM blocks)
  • 1.10–1.15 Unit tests for CA bundle utility (file path, env var, missing, invalid, chain, isolation)

From openspec/changes/connector-shared-infrastructure/tasks.md group 2 (RHIDP-15330):

  • 2.1 Define ConnectorErrorContext interface
  • 2.2 Create createProviderWrapper(provider: EntityProvider, logger: LoggerService): EntityProvider function
  • 2.3 Implement try/catch wrapper around provider connect() via createProviderWrapper() to catch unhandled rejections
  • 2.4 Implement createSafeRefresh() — try/catch wrapper around scheduled refresh callback to catch unhandled rejections
  • 2.5 Implement structured error logging with connector context fields
  • 2.6 Log errors via Backstage LoggerService for structured JSON output
  • 2.7 Ensure wrappers do NOT rethrow errors — allow catalog backend to continue
  • 2.8 Verify Backstage entity bucket isolation per provider (documentation + integration test)
  • 2.9–2.11 Unit tests for fault isolation wrapper

From openspec/changes/connector-shared-infrastructure/tasks.md group 3 (RHIDP-15330):

  • 3.1 Define enable/disable config schema: ai-catalog.providers.<id>.enabled: boolean
  • 3.2 Create isConnectorEnabled(connectorConfig: Config): boolean utility — caller passes the Config subtree (same pattern as loadCaBundle)
  • 3.3 Implement config reader: return true if enabled is omitted (default enabled)
  • 3.4 Create registration guard pattern for backend module init() example in README
  • 3.5 Log INFO-level message when connector is disabled
  • 3.6 Verify disabled connector uses zero resources
  • 3.7–3.10 Unit tests for enable/disable pattern

From openspec/changes/connector-shared-infrastructure/tasks.md group 4:

  • 4.1 Export shared utilities from src/index.ts: loadCaBundle, createHttpsAgent, createProviderWrapper, createSafeRefresh, isConnectorEnabled, ConnectorErrorContext
  • 4.2–4.7 Documentation: app-config schema, enable/disable, error logging, examples for each connector
  • 4.8 Add JSDoc comments for all exported functions

From openspec/changes/connector-shared-infrastructure/tasks.md group 5:

  • 5.1–5.6 Integration tests: CA from file, CA from env, https.Agent with custom CA, provider failure containment, disabled connector skip, structured error log

From openspec/changes/connector-shared-infrastructure/tasks.md group 6 (RHIDP-15266):

  • 6.1 Create reference app-config.yaml snippet (endpoint URL, CA bundle, Secret-based creds, sync schedule)
  • 6.2 Include MCP Registry connector example
  • 6.3 Include RHOAI connector example
  • 6.4 Include OCI Skill connector example
  • 6.5 Document each config field with inline comments
  • 6.6 Add air-gapped deployment variant
  • 6.7 Place reference YAML in workspaces/boost/examples/

From openspec/changes/connector-shared-infrastructure/tasks.md group 7 (Connector Integration) — deferred: these tasks require connectors that are created in Tier 1 (Issues 9–16). Each connector issue will consume boost-connector-utils as part of its own implementation. See Issues 9 (OCI), 13–14 (MCP Registry), 15–16 (RHOAI).

From openspec/changes/ai-catalog-entity-model/tasks.md group 6 (RHIDP-15265 — moved to RHIDP-15316):

  • 6.3 Implement startup validation rejecting plaintext credentials with descriptive error message
  • 6.4 Add $secret reference support for all credential fields
  • 6.5 Implement configurable endpoint URLs (baseUrl) for all providers with startup validation

Specifications

  • openspec/changes/connector-shared-infrastructure/specs/ca-bundle-resolution/spec.md
  • openspec/changes/connector-shared-infrastructure/specs/fault-isolation/spec.md
  • openspec/changes/connector-shared-infrastructure/specs/reference-app-config/spec.md
  • openspec/changes/ai-catalog-entity-model/specs/air-gapped-deployment/spec.md

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions