-
Notifications
You must be signed in to change notification settings - Fork 0
CSTACKEX-50: Disable, Re-Enable, Delete Storage pool and Enter, Exit maintenance mode workflows #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…Storage pool workflows
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements several critical ONTAP storage pool management workflows including:
- Storage pool lifecycle operations (create with underlying ONTAP volume, disable/enable, enter/exit maintenance mode, and delete with volume cleanup)
- Migration from Spring Cloud OpenFeign to vanilla Feign clients with custom factory pattern
- Enhanced aggregate selection logic to validate state and available space during connection
- Protocol naming correction from NFS to NFS3
Key Changes:
- Replaced Spring dependency injection with direct FeignClientFactory instantiation for better control
- Added volume creation/deletion with job polling mechanism
- Implemented storage pool maintenance mode and disable/enable operations
- Added comprehensive validation for ONTAP connection details and aggregate selection
Reviewed Changes
Copilot reviewed 42 out of 42 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| Utility.java | Converted utility methods to static, removed unused dependencies |
| Constants.java | Added new constants for volume operations, query parameters, and ONTAP port |
| ProtocolType.java | Renamed NFS enum to NFS3 for protocol accuracy |
| UnifiedSANStrategy.java | Replaced @Inject with FeignClientFactory for client initialization |
| UnifiedNASStrategy.java | Added FeignClientFactory setup and visibility modifiers to methods |
| StorageStrategy.java | Added aggregate validation logic, volume deletion, and job polling utility |
| StorageProviderFactory.java | Refactored to static factory pattern, removed Spring component annotations |
| OntapPrimaryDatastoreLifecycle.java | Implemented volume creation/deletion, maintenance mode, and enhanced validation |
| Model classes (OntapResponse, Volume, Svm, Aggregate, etc.) | Added @JsonIgnoreProperties for robust JSON deserialization |
| Feign clients (VolumeFeignClient, SvmFeignClient, etc.) | Migrated from Spring annotations to vanilla Feign annotations |
| FeignConfiguration.java | Converted from Spring bean configuration to factory methods |
| FeignClientFactory.java | New factory class for creating configured Feign clients |
| OntapPrimaryDatastoreDriver.java | Moved getStrategyByStoragePoolDetails from Utility to driver |
| pom.xml | Replaced Spring Cloud OpenFeign with vanilla Feign dependencies |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @JsonProperty("self") | ||
| private Self self; |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect @JsonProperty annotation value. The property should be 'self' not 'message', but the field variable is already named 'self'. The annotation on line 90 should map to the actual JSON property name returned by the ONTAP API. Please verify the correct JSON property name from the API documentation.
| @JsonProperty("href") | ||
| private String href; |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect @JsonProperty annotation value. The property should be 'href' not 'message', but the field variable is already named 'href'. The annotation on line 97 should map to the actual JSON property name returned by the ONTAP API. Please verify the correct JSON property name from the API documentation.
| StoragePool storagePool = _storageMgr.getStoragePool(storagePoolId); | ||
| if (storagePool == null) { | ||
| s_logger.warn("Storage pool not found for id: " + storagePoolId + ", cannot delete underlying ONTAP volume"); | ||
| return false;// TODO: As the CS entity is not present, should we return true here? |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or resolve the TODO comment. The return value logic needs to be decided: returning false when storage pool is not found may prevent cleanup of orphaned resources, while returning true could incorrectly signal successful deletion. This should be resolved before merging.
| return false;// TODO: As the CS entity is not present, should we return true here? | |
| // Storage pool does not exist; treat as successful deletion (idempotent) | |
| return true; |
| s_logger.warn("Aggregate " + aggr.getName() + " is not in online state. Skipping this aggregate."); | ||
| continue; | ||
| } else if (aggrResp.getSpace() == null || aggrResp.getAvailableBlockStorageSpace() == null || | ||
| aggrResp.getAvailableBlockStorageSpace() <= storage.getSize().doubleValue()) { |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect comparison operator. The condition should use < instead of <= because an aggregate with exactly the required size should be acceptable. The current logic incorrectly skips aggregates that have exactly the needed capacity.
| aggrResp.getAvailableBlockStorageSpace() <= storage.getSize().doubleValue()) { | |
| aggrResp.getAvailableBlockStorageSpace() < storage.getSize().doubleValue()) { |
|
|
||
| @Lazy | ||
| @FeignClient(name = "SANClient", url = "", configuration = FeignConfiguration.class ) | ||
| //TODO: Proper URLs should be added in the RequestLine annotations below |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TODO indicates that proper API endpoint paths are missing from @RequestLine annotations. All SAN client methods use placeholder paths like 'POST /' and 'GET /' instead of actual ONTAP REST API endpoints (e.g., '/api/storage/luns'). These need to be corrected for the client to function properly.
| */ | ||
| @Lazy | ||
| @FeignClient(name = "NASClient", url = "" , configuration = FeignConfiguration.class) | ||
| //TODO: Proper URLs should be added in the RequestLine annotations below |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TODO indicates that proper API endpoint paths are missing from @RequestLine annotations. All NAS client methods use placeholder or incomplete paths instead of full ONTAP REST API endpoints. These need to be corrected for the client to function properly.
| @RequestLine("GET /") | ||
| @Headers({"Authorization: {authHeader}"}) // TODO: Check this again, uuid should be part of the path? |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TODO indicates uncertainty about API design. The uuid parameter appears in the method signature but isn't used in the @RequestLine path. Either remove the uuid parameter if it should be a query parameter, or add it to the path as '/{uuid}' in the @RequestLine annotation.
| @RequestLine("GET /") | |
| @Headers({"Authorization: {authHeader}"}) // TODO: Check this again, uuid should be part of the path? | |
| @RequestLine("GET /{uuid}") | |
| @Headers({"Authorization: {authHeader}"}) |
| // Calling the VolumeFeignClient to delete the volume | ||
| String authHeader = Utility.generateAuthHeader(storage.getUsername(), storage.getPassword()); | ||
| try { | ||
| // TODO: Implement lun and file deletion, if any, before deleting the volume |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TODO indicates incomplete implementation. Before deleting an ONTAP volume, any LUNs or files within it should be deleted first to prevent orphaned resources. This logic needs to be implemented to ensure proper cleanup.
| s_logger.error("iSCSI protocol is not enabled on SVM " + svmName); | ||
| throw new CloudRuntimeException("iSCSI protocol is not enabled on SVM " + svmName); | ||
| } | ||
| // TODO: Implement logic to select appropriate aggregate based on storage requirements |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misleading TODO comment. The code following this comment (lines 117-140) already implements aggregate selection logic based on state and available space. The TODO should be removed or updated to reflect what additional selection criteria might be needed.
| // TODO: Implement logic to select appropriate aggregate based on storage requirements |
Description
This PR has the following changes implemented:
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
How did you try to break this feature and the system with this change?