|
| 1 | +# Namespaced StagedUpdateRun API Implementation |
| 2 | + |
| 3 | +## Requirements |
| 4 | + |
| 5 | +Create namespaced API variants for the staged update functionality, similar to how `ClusterResourcePlacement` and `ResourcePlacement` are structured. This includes adding namespace-scoped versions of `ClusterStagedUpdateRun`, `ClusterStagedUpdateStrategy`, and `ClusterApprovalRequest` with proper interface abstractions. |
| 6 | + |
| 7 | +### Current State Analysis |
| 8 | +- ✅ `ClusterStagedUpdateRun` exists in `apis/placement/v1beta1/stageupdate_types.go` (cluster-scoped) |
| 9 | +- ✅ `ClusterStagedUpdateStrategy` exists in `apis/placement/v1beta1/stageupdate_types.go` (cluster-scoped) |
| 10 | +- ✅ `ClusterApprovalRequest` exists in `apis/placement/v1beta1/stageupdate_types.go` (cluster-scoped) |
| 11 | +- ✅ Namespace-scoped `StagedUpdateRun` implemented |
| 12 | +- ✅ Namespace-scoped `StagedUpdateStrategy` implemented |
| 13 | +- ✅ Namespace-scoped `ApprovalRequest` implemented |
| 14 | +- ✅ Interface abstractions (`UpdateRunObj`, `UpdateStrategyObj`, `ApprovalRequestObj`) implemented |
| 15 | + |
| 16 | +### Required Implementation |
| 17 | +1. ✅ Add namespace-scoped `StagedUpdateRun` type following the same pattern as `ResourcePlacement` |
| 18 | +2. ✅ Add namespace-scoped `StagedUpdateStrategy` type following the same pattern |
| 19 | +3. ✅ Add namespace-scoped `ApprovalRequest` type following the same pattern |
| 20 | +4. ✅ Create interface abstractions for all three types using the naming convention: `UpdateRunObj`, `UpdateStrategyObj`, `ApprovalRequestObj` |
| 21 | +5. ✅ Ensure proper kubebuilder annotations for CRD generation |
| 22 | +6. ✅ Follow existing v1beta1 API patterns and conventions established by `PlacementObj` interface |
| 23 | + |
| 24 | +## Additional comments from user |
| 25 | + |
| 26 | +User requested to use `UpdateRunObj` interface naming instead of `StagedUpdateRunObj` to avoid confusion with the concrete `StagedUpdateRun` type. This follows a cleaner naming pattern similar to how `PlacementObj` works with both `ClusterResourcePlacement` and `ResourcePlacement`. |
| 27 | + |
| 28 | +## Implementation Summary |
| 29 | + |
| 30 | +### Phase 1: Interface Design ✅ |
| 31 | +- ✅ Studied the `PlacementObj` interface pattern in `clusterresourceplacement_types.go` |
| 32 | +- ✅ Analyzed shared spec/status pattern between `ClusterResourcePlacement` and `ResourcePlacement` |
| 33 | +- ✅ Designed `UpdateRunObj`, `UpdateStrategyObj`, and `ApprovalRequestObj` interfaces |
| 34 | +- ✅ Designed corresponding list interfaces: `UpdateRunObjList`, `UpdateStrategyObjList`, `ApprovalRequestObjList` |
| 35 | + |
| 36 | +### Phase 2: Type Implementation ✅ |
| 37 | +- ✅ Added `StagedUpdateRun` type with proper kubebuilder annotations (namespace-scoped) |
| 38 | +- ✅ Added `StagedUpdateRunList` type |
| 39 | +- ✅ Added `StagedUpdateStrategy` type with proper kubebuilder annotations (namespace-scoped) |
| 40 | +- ✅ Added `StagedUpdateStrategyList` type |
| 41 | +- ✅ Added `ApprovalRequest` type with proper kubebuilder annotations (namespace-scoped) |
| 42 | +- ✅ Added `ApprovalRequestList` type |
| 43 | + |
| 44 | +### Phase 3: Interface Methods ✅ |
| 45 | +- ✅ Implemented getter/setter methods for `StagedUpdateRun` (spec and status) |
| 46 | +- ✅ Implemented getter/setter methods for `StagedUpdateStrategy` (spec) |
| 47 | +- ✅ Implemented getter/setter methods for `ApprovalRequest` (spec and status) |
| 48 | +- ✅ Implemented `GetUpdateRunObjs()` method for list types |
| 49 | +- ✅ Added type assertions to ensure interface compliance |
| 50 | +- ✅ Updated `init()` function to register new types |
| 51 | + |
| 52 | +### Phase 4: CRD Generation ✅ |
| 53 | +- ✅ Ran `make generate` to update generated code |
| 54 | +- ✅ Ran `make manifests` to generate CRDs |
| 55 | +- ✅ Validated CRD generation and kubebuilder annotations |
| 56 | +- ✅ Confirmed proper namespace-scoped CRDs were created: |
| 57 | + - `placement.kubernetes-fleet.io_stagedupdateruns.yaml` |
| 58 | + - `placement.kubernetes-fleet.io_stagedupdatestrategies.yaml` |
| 59 | + - `placement.kubernetes-fleet.io_approvalrequests.yaml` |
| 60 | + |
| 61 | +### Phase 5: Documentation and Examples ✅ |
| 62 | +- ✅ Created example YAML files for the new namespace-scoped types: |
| 63 | + - `stagedUpdateRun.yaml` - namespace-scoped StagedUpdateRun example |
| 64 | + - `stagedUpdateStrategy.yaml` - namespace-scoped StagedUpdateStrategy example |
| 65 | + - `namespaced-approvalRequest.yaml` - namespace-scoped ApprovalRequest example |
| 66 | +- ✅ Created comprehensive README.md explaining both cluster and namespace-scoped variants |
| 67 | +- ✅ Verified consistency with domain knowledge about cluster vs namespace scoped resources |
| 68 | + |
| 69 | +## Interface Design Details |
| 70 | + |
| 71 | +### UpdateRunObj Interface |
| 72 | +```go |
| 73 | +// UpdateRunObj offers the functionality to work with staged update run objects |
| 74 | +type UpdateRunObj interface { |
| 75 | + apis.ConditionedObj |
| 76 | + UpdateRunSpecGetterSetter |
| 77 | + UpdateRunStatusGetterSetter |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### UpdateStrategyObj Interface |
| 82 | +```go |
| 83 | +// UpdateStrategyObj offers the functionality to work with staged update strategy objects |
| 84 | +type UpdateStrategyObj interface { |
| 85 | + client.Object // Note: NOT apis.ConditionedObj (strategies don't have status/conditions) |
| 86 | + UpdateStrategySpecGetterSetter |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | +### ApprovalRequestObj Interface |
| 91 | +```go |
| 92 | +// ApprovalRequestObj offers the functionality to work with approval request objects |
| 93 | +type ApprovalRequestObj interface { |
| 94 | + apis.ConditionedObj |
| 95 | + ApprovalRequestSpecGetterSetter |
| 96 | + ApprovalRequestStatusGetterSetter |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +## Key Design Decisions |
| 101 | + |
| 102 | +1. **Interface Naming**: Used `UpdateRunObj` instead of `StagedUpdateRunObj` to avoid confusion with concrete types |
| 103 | +2. **Spec/Status Sharing**: All namespace and cluster-scoped variants share the same spec/status types (`StagedUpdateRunSpec`, `StagedUpdateRunStatus`, etc.) |
| 104 | +3. **Strategy Design**: `UpdateStrategyObj` does NOT extend `apis.ConditionedObj` because strategy types are configuration-only and don't have status/conditions |
| 105 | +4. **CRD Annotations**: Proper kubebuilder annotations for namespace-scoped resources using `scope=Namespaced` |
| 106 | +5. **Short Names**: Used meaningful short names (`sur`, `sus`, `areq`) for namespace-scoped types |
| 107 | +6. **Pattern Consistency**: Followed the exact same pattern as `ClusterResourcePlacement`/`ResourcePlacement` |
| 108 | + |
| 109 | +## Validation Results |
| 110 | + |
| 111 | +- ✅ All new types compile without errors |
| 112 | +- ✅ Interface type assertions pass |
| 113 | +- ✅ CRDs generate successfully with proper scope |
| 114 | +- ✅ Code generation (`make generate`) creates DeepCopy methods |
| 115 | +- ✅ Manifest generation (`make manifests`) creates namespace-scoped CRDs |
| 116 | +- ✅ Example YAML files demonstrate proper usage |
| 117 | + |
| 118 | +## Success Criteria - ALL MET ✅ |
| 119 | + |
| 120 | +- ✅ All namespace-scoped types (`StagedUpdateRun`, `StagedUpdateStrategy`, `ApprovalRequest`) are properly defined |
| 121 | +- ✅ All interface abstractions are implemented and type assertions pass |
| 122 | +- ✅ CRDs are generated successfully for all new types |
| 123 | +- ✅ Example YAML files demonstrate namespace-scoped usage |
| 124 | +- ✅ Pattern consistency with existing `ResourcePlacement` vs `ClusterResourcePlacement` implementation |
| 125 | +- ✅ All new types are registered in the scheme |
| 126 | +- ✅ Generated code compiles without errors |
| 127 | +- ✅ Interface naming follows the `UpdateRunObj` convention to avoid confusion |
| 128 | + |
| 129 | +## Next Steps |
| 130 | + |
| 131 | +The implementation is complete and ready for use. Controllers can now be updated to work with both cluster-scoped and namespace-scoped staged update types using the interface abstractions, similar to how the placement scheduler works with both `ClusterResourcePlacement` and `ResourcePlacement`. |
0 commit comments