|
2 | 2 |
|
3 | 3 | ## Current Status |
4 | 4 |
|
5 | | -**Last updated:** 2026-01-12 |
6 | | -**Current phase:** REST API Enhancement - POST /scenarios COMPLETED |
| 5 | +**Last updated:** 2026-01-13 |
| 6 | +**Current phase:** REST API Enhancement - POST /scenarios/detail COMPLETED |
7 | 7 |
|
8 | 8 | ### Completed |
9 | 9 | - Project scaffolding with Kubebuilder |
|
62 | 62 | - ✅ Returns list of available krkn scenario tags with metadata |
63 | 63 | - ✅ Request/response types defined in internal/api/types.go |
64 | 64 | - ✅ Handler registered at POST /scenarios |
| 65 | +- **POST /scenarios/detail/{scenario_name} endpoint completed:** |
| 66 | + - ✅ Extracts scenario_name from URL path |
| 67 | + - ✅ Reuses krknctl models.ScenarioDetail (no custom DTOs) |
| 68 | + - ✅ Same registry configuration pattern as /scenarios |
| 69 | + - ✅ Calls GetScenarioDetail(scenario_name, registry) |
| 70 | + - ✅ Returns detailed scenario information (title, description, input fields) |
| 71 | + - ✅ Returns 404 if scenario not found |
| 72 | + - ✅ Handler registered at POST /scenarios/detail/{scenario_name} |
65 | 73 |
|
66 | 74 | ### In Progress |
67 | 75 | - None |
|
305 | 313 | - Supports multiple authentication methods: username/password, token |
306 | 314 | - Optional TLS skip and insecure connection for private registries |
307 | 315 |
|
| 316 | +#### POST /scenarios/detail/{scenario_name} |
| 317 | +**Purpose:** Retrieve detailed information about a specific chaos scenario |
| 318 | + |
| 319 | +**Path Parameter:** |
| 320 | +- `scenario_name` (required): The name/tag of the scenario to retrieve |
| 321 | + |
| 322 | +**Request Body (optional):** |
| 323 | +Same as POST /scenarios - registry configuration for private registry |
| 324 | +```json |
| 325 | +{ |
| 326 | + "registryUrl": "registry.example.com", |
| 327 | + "scenarioRepository": "org/krkn-scenarios", |
| 328 | + "username": "user", |
| 329 | + "password": "pass", |
| 330 | + "token": "alternative-to-user-pass", |
| 331 | + "skipTls": false, |
| 332 | + "insecure": false |
| 333 | +} |
| 334 | +``` |
| 335 | + |
| 336 | +**Behavior:** |
| 337 | +1. Extract scenario_name from URL path |
| 338 | +2. Parse optional request body for registry configuration |
| 339 | +3. If body contains registry configuration → use RegistryV2 provider (Private mode) |
| 340 | +4. If no body or empty body → use Quay provider (default to quay.io) |
| 341 | +5. Load krknctl configuration (embedded config.json) |
| 342 | +6. Create provider factory and instantiate appropriate provider |
| 343 | +7. Call `GetScenarioDetail(scenario_name, registry)` to fetch scenario details |
| 344 | +8. Return scenario detail with input fields metadata |
| 345 | +9. Return 404 if scenario not found |
| 346 | + |
| 347 | +**Status:** COMPLETED |
| 348 | + |
| 349 | +**Response Format (200 OK):** |
| 350 | +```json |
| 351 | +{ |
| 352 | + "name": "pod-scenarios", |
| 353 | + "digest": "sha256:abc123...", |
| 354 | + "size": 123456789, |
| 355 | + "lastModified": "2025-01-13T10:30:00Z", |
| 356 | + "title": "Pod Scenarios", |
| 357 | + "description": "Chaos engineering scenarios for Kubernetes pods", |
| 358 | + "fields": [ |
| 359 | + { |
| 360 | + "name": "namespace", |
| 361 | + "variable": "NAMESPACE", |
| 362 | + "type": "string", |
| 363 | + "description": "Target namespace for pod scenarios", |
| 364 | + "required": true, |
| 365 | + "default": "default" |
| 366 | + }, |
| 367 | + { |
| 368 | + "name": "label_selector", |
| 369 | + "variable": "LABEL_SELECTOR", |
| 370 | + "type": "string", |
| 371 | + "description": "Label selector to filter pods", |
| 372 | + "required": false |
| 373 | + }, |
| 374 | + { |
| 375 | + "name": "config_file", |
| 376 | + "variable": "CONFIG_FILE", |
| 377 | + "type": "file", |
| 378 | + "description": "Configuration file for scenario", |
| 379 | + "required": false, |
| 380 | + "mount_path": "/config/scenario.yaml" |
| 381 | + } |
| 382 | + ] |
| 383 | +} |
| 384 | +``` |
| 385 | + |
| 386 | +**Error Responses:** |
| 387 | + |
| 388 | +400 Bad Request (missing scenario_name): |
| 389 | +```json |
| 390 | +{ |
| 391 | + "error": "bad_request", |
| 392 | + "message": "scenario_name parameter is required in path" |
| 393 | +} |
| 394 | +``` |
| 395 | + |
| 396 | +400 Bad Request (invalid body): |
| 397 | +```json |
| 398 | +{ |
| 399 | + "error": "bad_request", |
| 400 | + "message": "Invalid request body: ..." |
| 401 | +} |
| 402 | +``` |
| 403 | + |
| 404 | +400 Bad Request (partial registry info): |
| 405 | +```json |
| 406 | +{ |
| 407 | + "error": "bad_request", |
| 408 | + "message": "Both registryUrl and scenarioRepository are required for private registry" |
| 409 | +} |
| 410 | +``` |
| 411 | + |
| 412 | +404 Not Found (scenario not found): |
| 413 | +```json |
| 414 | +{ |
| 415 | + "error": "not_found", |
| 416 | + "message": "Scenario 'invalid-scenario' not found" |
| 417 | +} |
| 418 | +``` |
| 419 | + |
| 420 | +500 Internal Server Error: |
| 421 | +```json |
| 422 | +{ |
| 423 | + "error": "internal_error", |
| 424 | + "message": "Failed to get scenario detail: ..." |
| 425 | +} |
| 426 | +``` |
| 427 | + |
| 428 | +**Implementation Details:** |
| 429 | +- Uses `github.com/krkn-chaos/krknctl/pkg/provider` package |
| 430 | +- Reuses krknctl `models.ScenarioDetail` structure (no custom DTOs) |
| 431 | +- Factory pattern: `factory.NewProviderFactory(config).NewInstance(mode)` |
| 432 | +- Same registry configuration pattern as POST /scenarios |
| 433 | +- Two modes: |
| 434 | + - `provider.Quay`: Default quay.io registry |
| 435 | + - `provider.Private`: Custom registry with RegistryV2 configuration |
| 436 | +- Returns complete scenario metadata including: |
| 437 | + - Basic info: name, digest, size, lastModified |
| 438 | + - Descriptive info: title, description |
| 439 | + - Input fields: detailed field configurations with types, validation, defaults |
| 440 | + |
| 441 | +**Input Field Types:** |
| 442 | +- `string`: Text input with optional regex validation |
| 443 | +- `number`: Numeric input |
| 444 | +- `boolean`: Boolean flag (true/false) |
| 445 | +- `enum`: Enumerated values with allowed_values list |
| 446 | +- `file`: File mount (requires mount_path) |
| 447 | +- `file_base64`: Base64-encoded file content |
| 448 | + |
308 | 449 | ## Architecture Decisions |
309 | 450 |
|
310 | 451 | ### REST API Framework |
|
543 | 684 | - **Authentication**: Supports username/password or token |
544 | 685 | - **Flexibility**: SkipTLS and Insecure options for development environments |
545 | 686 |
|
| 687 | +### Phase 10: POST /scenarios/detail/{scenario_name} Endpoint ✅ |
| 688 | +**Status:** COMPLETED |
| 689 | + |
| 690 | +1. ✅ Architecture Decision |
| 691 | + - Decided to reuse krknctl `models.ScenarioDetail` structure |
| 692 | + - No custom DTOs created - direct use of upstream models |
| 693 | + - Maintains consistency with krknctl ecosystem |
| 694 | + |
| 695 | +2. ✅ Handler Implementation (internal/api/handlers.go) |
| 696 | + - Implemented `PostScenarioDetail(w, r)` handler |
| 697 | + - Path parameter extraction for scenario_name |
| 698 | + - Same registry configuration pattern as POST /scenarios |
| 699 | + - Request body parsing with ContentLength check |
| 700 | + - Validation logic: both registryUrl and scenarioRepository required for private registry |
| 701 | + - Mode selection: provider.Quay (default) vs provider.Private |
| 702 | + - Factory pattern: `factory.NewProviderFactory(&cfg).NewInstance(mode)` |
| 703 | + - Call to `GetScenarioDetail(scenario_name, registry)` for detailed scenario retrieval |
| 704 | + - 404 response when scenario not found |
| 705 | + - Direct JSON marshaling of krknctl models.ScenarioDetail |
| 706 | + - Comprehensive error handling (400, 404, 500) |
| 707 | + |
| 708 | +3. ✅ Route Registration (internal/api/server.go) |
| 709 | + - Registered POST /scenarios/detail/{scenario_name} route |
| 710 | + - Handler accessible at http://operator:8080/scenarios/detail/{scenario_name} |
| 711 | + |
| 712 | +4. ✅ Build Verification |
| 713 | + - Successful compilation with no errors |
| 714 | + - All dependencies resolved |
| 715 | + - Binary built and ready for testing |
| 716 | + |
| 717 | +5. ✅ Documentation |
| 718 | + - Updated REQUIREMENTS.md with ✅ COMPLETED marker |
| 719 | + - Added complete endpoint documentation to PROGRESS.md |
| 720 | + - Documented all request/response formats |
| 721 | + - Documented all input field types (string, number, boolean, enum, file, file_base64) |
| 722 | + |
| 723 | +**Implementation Highlights:** |
| 724 | +- **Reuses upstream models**: No DTOs, direct krknctl models.ScenarioDetail |
| 725 | +- **Consistent pattern**: Same registry config as POST /scenarios |
| 726 | +- **Rich metadata**: Returns title, description, and complete field configurations |
| 727 | +- **Field metadata includes**: |
| 728 | + - Field type and validation rules |
| 729 | + - Required/optional flags |
| 730 | + - Default values |
| 731 | + - Mount paths for file types |
| 732 | + - Dependencies and mutual exclusions |
| 733 | + - Secret field marking |
| 734 | + |
546 | 735 | ## Technical Notes |
547 | 736 |
|
548 | 737 | ### KrknTargetRequest Structure |
@@ -635,9 +824,10 @@ type KrknTargetRequestStatus struct { |
635 | 824 | 7. ✅ Podman support and container tooling |
636 | 825 | 8. ✅ Kubernetes Service for REST API access |
637 | 826 | 9. ✅ Implement POST /scenarios endpoint with krknctl integration |
638 | | -10. Create API documentation (OpenAPI/Swagger spec) |
639 | | -11. Add additional endpoints as requirements evolve |
640 | | -12. Implement controller logic for KrknTargetRequest |
| 827 | +10. ✅ Implement POST /scenarios/detail/{scenario_name} endpoint |
| 828 | +11. Create API documentation (OpenAPI/Swagger spec) |
| 829 | +12. Add additional endpoints as requirements evolve |
| 830 | +13. Implement controller logic for KrknTargetRequest |
641 | 831 |
|
642 | 832 | ## Future Work (Not in Current Scope) |
643 | 833 |
|
|
0 commit comments