Skip to content

Conversation

@sandeeplocharla
Copy link
Collaborator

@sandeeplocharla sandeeplocharla commented Nov 4, 2025

Description

This PR includes changes for Primary storage pool creation

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

Primary Storage Pool 'SanPrimary' creation has been tested from Management Server
Screenshot 2025-11-05 at 8 56 11 AM
Screenshot 2025-11-05 at 8 57 47 AM
Screenshot 2025-11-05 at 8 57 55 AM

How did you try to break this feature and the system with this change?

Copilot AI review requested due to automatic review settings November 4, 2025 04:41
@sandeeplocharla sandeeplocharla self-assigned this Nov 4, 2025
Copy link

Copilot AI left a 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 primary storage pool creation functionality for NetApp ONTAP integration in CloudStack. The changes migrate from Spring Cloud OpenFeign to standard OpenFeign, refactor dependency injection patterns, and add core infrastructure for creating and managing ONTAP storage pools.

Key Changes:

  • Migration from Spring Cloud OpenFeign to core OpenFeign library with manual client initialization
  • Implementation of primary storage pool creation workflow including SVM validation and volume creation
  • Refactoring of dependency injection from Spring @Inject to constructor-based instantiation

Reviewed Changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pom.xml Replaces Spring Cloud OpenFeign dependencies with core OpenFeign libraries (feign-core, feign-httpclient, feign-jackson)
FeignClientFactory.java New factory class for creating Feign clients with custom configuration
FeignConfiguration.java Migrated from Spring @bean annotations to factory methods for Feign components
All FeignClient interfaces Converted from Spring annotations (@FeignClient, @RequestMapping) to core Feign annotations (@RequestLine, @headers)
StorageStrategy.java Replaced @Inject dependencies with constructor-based initialization using FeignClientFactory
UnifiedSANStrategy.java, UnifiedNASStrategy.java Added constructor-based initialization and setter methods for OntapStorage
StorageProviderFactory.java Converted from Spring @component to static factory pattern
OntapPrimaryDatastoreLifecycle.java Implemented primary storage creation logic with URL parsing and validation
OntapStorage.java Fixed setter methods to properly assign instance variables
Utility.java Removed unused methods and Spring dependencies
Constants.java Added SIZE constant, removed unused API endpoint constants

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

s_logger.info("Successfully connected to ONTAP cluster and validated ONTAP details provided");
} catch (Exception e) {
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage());
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e);
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message loses the original exception's specific message. Consider using 'e.getMessage()' instead of 'e' to avoid printing the full stack trace in the message, or wrap the exception properly with 'new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage(), e)' to preserve the cause.

Suggested change
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e);
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage(), e);

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 85 to 86
s_logger.info("Attempting to connect to ONTAP cluster at " + storage.getManagementLIF() + " and validate SVM " +
storage.getSvmName() + ", username " + storage.getUsername() + ", password " + storage.getPassword() + ", protocol " + storage.getProtocol());
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging sensitive credentials (username and password) in plaintext is a security risk. Remove password from the log statement and consider masking or omitting the username as well.

Suggested change
s_logger.info("Attempting to connect to ONTAP cluster at " + storage.getManagementLIF() + " and validate SVM " +
storage.getSvmName() + ", username " + storage.getUsername() + ", password " + storage.getPassword() + ", protocol " + storage.getProtocol());
// Mask username except first character, if present
String maskedUsername = storage.getUsername() != null && !storage.getUsername().isEmpty()
? storage.getUsername().charAt(0) + "***"
: "";
s_logger.info("Attempting to connect to ONTAP cluster at " + storage.getManagementLIF() +
" and validate SVM " + storage.getSvmName() +
", username " + maskedUsername +
", protocol " + storage.getProtocol());

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@PathVariable(name="igroup.uuid", required=true) String igroupUUID);

// LUN Operation APIs
@RequestLine("POST /")
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RequestLine is incomplete - it uses '/' as the path, but based on the previous implementation this should include the full API path like 'POST /api/storage/luns'. Without the full path in the annotation, the API calls will fail.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TODO, for developers who are going to use this file

return null;
}
String json = null;
try (var bodyStream = response.body().asInputStream()) {
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using 'var' for type inference is valid in Java 11+, but may reduce code readability. Consider explicitly declaring the type as 'InputStream bodyStream' for clarity.

Suggested change
try (var bodyStream = response.body().asInputStream()) {
try (InputStream bodyStream = response.body().asInputStream()) {

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 93 to 107
try {
s_logger.info("Fetching the SVM details...");
if (svmFeignClient == null) {
throw new CloudRuntimeException("SVM Feign client is not initialized.");
}
Map<String, Object> queryParams = Map.of("name", svmName, "fields", "aggregates,state");
OntapResponse<Svm> svms = svmFeignClient.getSvmResponse(queryParams, authHeader);
if (svms != null && svms.getRecords() != null && !svms.getRecords().isEmpty()) {
svm = svms.getRecords().get(0);
} else {
throw new CloudRuntimeException("No SVM found on the ONTAP cluster by the name" + svmName + ".");
}
} catch (FeignException.FeignClientException e) {
throw new CloudRuntimeException("Failed to fetch SVM details: " + e.getMessage());
}
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This catch block only handles FeignException.FeignClientException, but line 129 has a broader catch block for all exceptions. The inner try-catch adds unnecessary nesting and the outer catch will handle FeignException already. Consider removing the inner try-catch block.

Suggested change
try {
s_logger.info("Fetching the SVM details...");
if (svmFeignClient == null) {
throw new CloudRuntimeException("SVM Feign client is not initialized.");
}
Map<String, Object> queryParams = Map.of("name", svmName, "fields", "aggregates,state");
OntapResponse<Svm> svms = svmFeignClient.getSvmResponse(queryParams, authHeader);
if (svms != null && svms.getRecords() != null && !svms.getRecords().isEmpty()) {
svm = svms.getRecords().get(0);
} else {
throw new CloudRuntimeException("No SVM found on the ONTAP cluster by the name" + svmName + ".");
}
} catch (FeignException.FeignClientException e) {
throw new CloudRuntimeException("Failed to fetch SVM details: " + e.getMessage());
}
s_logger.info("Fetching the SVM details...");
if (svmFeignClient == null) {
throw new CloudRuntimeException("SVM Feign client is not initialized.");
}
Map<String, Object> queryParams = Map.of("name", svmName, "fields", "aggregates,state");
OntapResponse<Svm> svms = svmFeignClient.getSvmResponse(queryParams, authHeader);
if (svms != null && svms.getRecords() != null && !svms.getRecords().isEmpty()) {
svm = svms.getRecords().get(0);
} else {
throw new CloudRuntimeException("No SVM found on the ONTAP cluster by the name" + svmName + ".");
}

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


}

public StorageStrategy getStrategyByStoragePoolDetails(Map<String, String> details) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it 'private'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
OntapResponse<Lun> createLun(@Param("authHeader") String authHeader,
@Param("returnRecords") boolean returnRecords,
@Param("lun") Lun lun);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: All feign clients should be revisited for proper implementation according to ontap api spec

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done
Developer now has to only take care of the URLs in SANFeignClient and NASFeignClient files. Will try to make those changes also in the next PR, if its not already taken care of

private String password;
private String managementLIF;
private String svmName;
private String username;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make them all final

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

private static final Logger s_logger = LogManager.getLogger(OntapPrimaryDatastoreDriver.class);

@Inject private Utility utils;
private Utility utils;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it 'final'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import java.util.List;
import java.util.Objects;

@JsonInclude(JsonInclude.Include.NON_NULL)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Unknown properties to all models

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its ignore unknown propoerties

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@Bean
public Client client(ApacheHttpClientFactory httpClientFactory) {
public FeignConfiguration() {
this.objectMapper = new ObjectMapper();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out if json mapper could be used here to ignore unknown properties

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Long clusterId = (Long)dsInfos.get("clusterId");
String storagePoolName = (String)dsInfos.get("name");
String providerName = (String)dsInfos.get("providerName");
Long capacityBytes = (Long)dsInfos.get("capacityBytes");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reuse this for Volume size

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

String storagePoolName = (String)dsInfos.get("name");
String providerName = (String)dsInfos.get("providerName");
Long capacityBytes = (Long)dsInfos.get("capacityBytes");
String tags = (String)dsInfos.get("tags");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add validation on this (for NPE)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary, as cloudstack provides 'tags' key in dsInfos map, while the value could be 'null', if in case tags are not set.

@SuppressWarnings("unchecked")
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
// Validations
if (capacityBytes == null || capacityBytes <= 0) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Ontap related check here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

// Get ONTAP details from the URL
Map<String, String> storageDetails = Map.of(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use hashset from here and check below if the key exists in it before setting, else throw an exception

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, explaination on current implementation has been provided for another comment on the same file

// TODO: scheme could be 'custom' in our case and we might have to ask 'protocol' separately to the user
ProtocolType protocol = ProtocolType.valueOf(details.get(Constants.PROTOCOL).toLowerCase());
String path = "";
ProtocolType protocol = ProtocolType.valueOf(details.get(Constants.PROTOCOL));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add NFS3 in the Protocols enum

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


@RequestLine("POST /{uuid}/igroups")
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
OntapResponse<Igroup> addNestedIgroups(@Param("authHeader") String authHeader,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will not have nested igroups here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pending to be addressed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

parameters.setClusterId(clusterId);
parameters.setName(storagePoolName);
parameters.setProviderName(providerName);
parameters.setManaged(true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this hardcoded, shall we assign this based on the check box value coming from CS UI form?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whenever, user chooses ONTAP storage provider, any entity created in cloudstack via ONTAP provider should be managed by us. So, by default irrespective of whether user chooses to be managed or not, this should be 'true'. I've checked other vendors implementation also doing the same.
One thing that we could do is to check if 'managed' field is set to 'null' by the user, callout via an exception to draw user's attention to enable it.
Let me know if we should be doing this?

ProtocolType protocol = ontapStorage.getProtocol();
s_logger.info("Initializing StorageProviderFactory with protocol: " + protocol);
switch (protocol) {
case NFS:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets add NFS3 even here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

public boolean connect() {
s_logger.info("Attempting to connect to ONTAP cluster at " + storage.getManagementLIF());
s_logger.info("Attempting to connect to ONTAP cluster at " + storage.getManagementLIF() + " and validate SVM " +
storage.getSvmName() + ", username " + storage.getUsername() + ", password " + storage.getPassword() + ", protocol " + storage.getProtocol());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not print username and password in logs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

throw new CloudRuntimeException("No SVM found on the ONTAP cluster by the name" + svmName + ".");
try {
s_logger.info("Fetching the SVM details...");
if (svmFeignClient == null) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This initialization is happening in the constructor of this class, do we see any chances of not getting this initialized?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this came in from earlier code where we were using spring-feign, will don't need this

abstract AccessGroup updateAccessGroup(AccessGroup accessGroup);

/**
* Method encapsulates the behavior based on the opted protocol in subclasses

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reasons for removing these methods?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted them, thankyou
Copilot has removed them due to a comment, I've added for my reference in the code

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this version inside property tag

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thankyou

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thankyou

private Utility utils;
@Inject private StoragePoolDetailsDao storagePoolDetailsDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
public OntapPrimaryDatastoreDriver() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can also create utility method as static, so we need not to instantiate utility class here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thankyou

this.utils = new Utility();
// Initialize FeignClientFactory and create clients
this.feignClientFactory = new FeignClientFactory();
this.volumeFeignClient = feignClientFactory.createClient(VolumeFeignClient.class, baseURL);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can also create the feign client based on the protocol

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not currently required in StorageStrategy also any protocol specific feign calls must be made in the respective classes

if (svmFeignClient == null) {
throw new CloudRuntimeException("SVM Feign client is not initialized.");
}
Map<String, Object> queryParams = Map.of("name", svmName, "fields", "aggregates,state");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass these values as a constant

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copilot AI review requested due to automatic review settings November 5, 2025 03:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 42 out of 42 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +37
@RequestLine("POST /")
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
OntapResponse<Lun> createLun(@Param("authHeader") String authHeader,
@Param("returnRecords") boolean returnRecords,
Lun lun);
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @RequestLine annotation specifies only POST / without the full API path. This should include the complete endpoint path like POST /api/storage/luns to match the ONTAP API structure, similar to other Feign clients in this PR.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a TODO task to be taken up when using these methods in implementation

logger.info("Body: {}", template.requestBody().asString());
public void encode(Object object, Type bodyType, feign.RequestTemplate template) throws EncodeException {
if (object == null) {
template.body((byte[]) null, StandardCharsets.UTF_8);
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting null to (byte[]) is unnecessary. The method accepts a null value directly, so this cast can be removed for cleaner code.

Suggested change
template.body((byte[]) null, StandardCharsets.UTF_8);
template.body(null, StandardCharsets.UTF_8);

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken care

s_logger.info("Successfully connected to ONTAP cluster and validated ONTAP details provided");
} catch (Exception e) {
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage());
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage(), e);
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message only includes the exception message but loses important context about which SVM connection failed. Consider including the SVM name and management LIF in the error message for better troubleshooting: \"Failed to connect to ONTAP cluster at \" + storage.getManagementLIF() + \" for SVM \" + storage.getSvmName() + \": \" + e.getMessage()

Suggested change
throw new CloudRuntimeException("Failed to connect to ONTAP cluster: " + e.getMessage(), e);
throw new CloudRuntimeException("Failed to connect to ONTAP cluster at " + storage.getManagementLIF() + " for SVM " + storage.getSvmName() + ": " + e.getMessage(), e);

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details are already being logged earlier in the code

Copy link

@rajiv-jain-netapp rajiv-jain-netapp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multiple comments are pending

@Inject private Utility utils;
@Inject private StoragePoolDetailsDao storagePoolDetailsDao;
@Inject private PrimaryDataStoreDao storagePoolDao;
public OntapPrimaryDatastoreDriver() {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this constructor?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. Removed


@RequestLine("POST /{uuid}/igroups")
@Headers({"Authorization: {authHeader}", "return_records: {returnRecords}"})
OntapResponse<Igroup> addNestedIgroups(@Param("authHeader") String authHeader,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pending to be addressed

break;
case ISCSI:
parameters.setType(Storage.StoragePoolType.Iscsi);
path = "iqn.1992-08.com.netapp:" + details.get(Constants.SVM_NAME) + "." + storagePoolName;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can put this in constant

@sandeeplocharla sandeeplocharla merged commit 1b0c7f7 into main Nov 5, 2025
13 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants