Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,17 @@ GOPROXY=direct go build -o bin/boot-service ./cmd/server
make build
```

**Note**: `go.mod` has `replace github.com/openchami/fabrica => ../fabrica` for local development.

### Running

```bash
# Copy and edit config first
cp config.example.yaml config.yaml

# Run with config file
./bin/boot-service serve
./bin/server serve

# Override with flags
./bin/boot-service serve --port 8082 --enable-auth --hsm-url http://localhost:27779
./bin/server serve --port 8082 --enable-auth --hsm-url http://localhost:27779
```

### Testing
Expand Down Expand Up @@ -148,7 +146,7 @@ Three templates exist: `DefaultIPXETemplate`, `MinimalIPXETemplate`, `ErrorIPXET

### TokenSmith Integration

Authentication is **optional** and controlled via config. Three modes:
The repository contains a reusable `pkg/auth` package with three common modes:

```go
// Development - auth disabled
Expand All @@ -163,6 +161,11 @@ config.JWKSURL = "https://auth.openchami.org/.well-known/jwks.json"
config.RequiredScopes = []string{"boot:read"}
```

**Important current runtime note**: the standalone server in `cmd/server/main.go`
does not currently attach `pkg/auth.CreateMiddleware(...)` to its route tree.
`enable_auth` currently affects startup validation and TokenSmith-backed HSM
service-token exchange, not documented request-time route enforcement.

### Middleware Application

**IMPORTANT**: Apply middleware to router **before** registering routes:
Expand Down Expand Up @@ -200,35 +203,38 @@ Common scopes: `boot:read`, `boot:write`, `boot:admin`, `node:read`, `node:write
# config.yaml structure
port: 8080
enable_auth: false
enable_metrics: true
enable_metrics: false
enable_legacy_api: true
# metrics_port is configured separately because it becomes active as soon as
# metrics are enabled, even though metrics default to off.
metrics_port: 9090
hsm_url: "http://localhost:27779"

auth:
enabled: false
jwks_url: "https://auth.example.com/.well-known/jwks.json"
required_scopes: ["boot:read"]
tokensmith_url: "http://localhost:8080"
```

Environment variables use prefix `BOOT_SERVICE_` (e.g., `BOOT_SERVICE_PORT=8082`).
Environment variables use prefix `BOOT_SERVICE_` for standard server settings,
plus `TOKENSMITH_*` for bootstrap-token exchange settings.

## External Service Integration

### HSM (Hardware State Manager)

**Auto-enabled** when `--hsm-url` flag is provided or `hsm_url` is set in config.

**Current Status**: HSM client is initialized and validates connectivity, but not yet fully integrated into the boot script generation pipeline.
**Current Status**: HSM-backed node resolution is wired into the server through
`FlexibleBootScriptController` in `cmd/server/server_extensions.go` when
`hsm_url` is configured.

**Implementation**:
- HSM client: `pkg/clients/hsm/client.go` - HTTP client for HSM v2 API with caching
- Integration service: `pkg/clients/hsm/integration.go` - Wraps HSM client with node provider interface
- Flexible controller: `pkg/controllers/bootscript/flexible_controller.go` - Supports pluggable node providers

**Integration Options** (see TODOs in `cmd/server/main.go`):
1. **FlexibleBootScriptController**: Use `NewFlexibleBootScriptController` with HSM provider config
2. **Controller-level**: Add NodeProvider parameter to BootScriptController
3. **Storage-level**: Add HSM fallback in storage.GetNode() for transparent integration
**Current Integration Path**:
1. Build an HSM client in `cmd/server/main.go`
2. Create `FlexibleBootScriptController` in `cmd/server/server_extensions.go`
3. Register legacy routes with `NewLegacyHandlerWithController(...)`
4. Start optional HSM background sync when enabled

**Node resolution with HSM** (when integrated):
- XName lookups: Direct HSM component query (`/hsm/v2/State/Components/{xname}`)
Expand All @@ -237,7 +243,9 @@ Environment variables use prefix `BOOT_SERVICE_` (e.g., `BOOT_SERVICE_PORT=8082`

**Caching**: HSM responses are cached (default: 5 minutes) to reduce load on HSM service.

**Current Limitation**: Legacy BSS API handlers use standard BootScriptController which queries local storage only. To enable HSM for boot scripts, modify handlers to accept controller interface and pass FlexibleBootScriptController instance.
**Current Limitation**: The legacy `/boot/v1/bootscript` HTTP route ignores the
`profile` query parameter and always asks the controller to auto-resolve the
best configuration across profiles.

### TokenSmith

Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/codegen-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,5 @@ jobs:
with:
go-version: stable

- name: Run code generation
run: make generate

- name: Verify generated code is committed
run: |
if ! git diff --quiet; then
echo "Generated files are out of sync. Run 'make generate' and commit the results."
git --no-pager diff --stat
exit 1
fi
run: make generate-check
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
lint:
runs-on: ubuntu-latest

steps:
- name: Set up latest stable Go
uses: actions/setup-go@v6.4.0
Expand Down
85 changes: 85 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!--
SPDX-FileCopyrightText: 2026 OpenCHAMI Contributors

SPDX-License-Identifier: MIT
-->

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Changes remain under `Unreleased` until they ship in the next tagged release.

## [Unreleased]

### Added

- Added `GET /health` and a generated `client health` command for quick service checks.
- Added OpenAPI publication endpoints at `GET /openapi.json` and `GET /docs`.
- Added `PATCH` operations for `BMC`, `BootConfiguration`, and `Node` resources.
- Added custom validation hooks for `BMC`, `BootConfiguration`, and `Node` handlers.

### Changed

- Regenerated server, client, storage, and OpenAPI surfaces against Fabrica `v0.4.5`.
- Updated generated file headers to include Fabrica version metadata.
- Updated the Docker release build to pass dynamic build arguments into image builds.
- Tightened code generation drift checks around the current Fabrica workflow.
- Documented the generated service endpoints added in this release, including `/health`, `/openapi.json`, and `/docs`.

## [0.1.4] - 2026-05-06

### Added

- Added HSM group membership lookups and response caching to improve node resolution.

### Changed

- Added missing configuration aliases used by HSM-related settings.

### Fixed

- Cleaned up HSM client handling and a small lint-related response body close issue.

## [0.1.3] - 2026-05-05

### Added

- Added the legacy boot script endpoint behind the `enable_legacy_api` feature flag.
- Added explicit code generation drift checks via `make generate-check`.

### Changed

- Clarified boot profile behavior and validation in the docs.
- Changed empty-profile boot script selection to auto-resolve the best matching configuration across profiles.
- Updated the local Fabrica workflow in the Makefile and regenerated outputs for the newer generator.
- Refactored server integration setup for clearer handler registration.

## [0.1.2] - 2026-04-26

### Fixed

- Added the missing OpenAPI API routes.

## [0.1.1] - 2026-04-15

### Changed

- Added Docker Buildx setup with a custom build image in the release pipeline.

## [0.1.0] - 2026-04-15

### Added

- Initial tagged release of the Fabrica-generated boot-service API.
- File-backed `BMC`, `BootConfiguration`, and `Node` resource APIs.
- Legacy BSS-compatible boot endpoints and generated Go client support.

[Unreleased]: https://github.com/OpenCHAMI/boot-service/compare/v0.1.4...HEAD
[0.1.4]: https://github.com/OpenCHAMI/boot-service/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/OpenCHAMI/boot-service/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/OpenCHAMI/boot-service/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/OpenCHAMI/boot-service/compare/v0.1.0...v0.1.1
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ TEST_TIMEOUT ?= 5m
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
DOCKER_GO_VERSION ?= $(shell awk '/^go / {print $$2; exit}' go.mod)
FABRICA_VERSION ?= $(shell awk '/github.com\/openchami\/fabrica[[:space:]]+v/ {print $$2; exit}' go.mod)
LDFLAGS=-ldflags "-X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.date=$(DATE)"
FABRICA_CMD ?= go run github.com/openchami/fabrica/cmd/fabrica@latest
FABRICA_CMD ?= go run github.com/openchami/fabrica/cmd/fabrica@$(FABRICA_VERSION)
FABRICA_SOURCE_ARG ?=
FABRICA_FORCE_FLAG ?=
FABRICA_ENV ?=
LOCAL_FABRICA ?=

ifneq ($(strip $(LOCAL_FABRICA)),)
FABRICA_CMD := $(LOCAL_FABRICA)/bin/fabrica
FABRICA_SOURCE_ARG := --fabrica-source $(LOCAL_FABRICA)
FABRICA_FORCE_FLAG := --force
FABRICA_ENV := GOTOOLCHAIN=auto
endif

Expand All @@ -41,7 +45,7 @@ ifneq ($(strip $(LOCAL_FABRICA)),)
exit 1; \
fi
endif
$(FABRICA_ENV) $(FABRICA_CMD) generate $(FABRICA_SOURCE_ARG)
$(FABRICA_ENV) $(FABRICA_CMD) generate $(FABRICA_SOURCE_ARG) $(FABRICA_FORCE_FLAG)

generate-check: ## Fail if generated files are out of sync (requires clean git tree)
@if ! git diff --quiet || ! git diff --cached --quiet; then \
Expand Down Expand Up @@ -85,7 +89,12 @@ run: build ## Build and run the application
./bin/$(BINARY_NAME)

docker-build: ## Build Docker image
docker build -t $(BINARY_NAME):latest .
docker build -f Dockerfile.standalone \
--build-arg GO_VERSION=$(DOCKER_GO_VERSION) \
--build-arg VERSION=$(VERSION) \
--build-arg COMMIT=$(COMMIT) \
--build-arg DATE=$(DATE) \
-t $(BINARY_NAME):latest .

docker-run: docker-build ## Build and run Docker container
docker run --rm $(BINARY_NAME):latest
Expand Down
Loading
Loading