FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

CSTACKEX-7: ONTAP Primary storage pool by sandeeplocharla · Pull Request #9 · NetApp/cloudstack · GitHub

CSTACKEX-7: ONTAP Primary storage pool - #9

Merged
sandeeplocharla merged 4 commits into
mainfrom
feature/CSTACKEX-7
Oct 24, 2025
Merged

CSTACKEX-7: ONTAP Primary storage pool#9
sandeeplocharla merged 4 commits into
mainfrom
feature/CSTACKEX-7

Conversation

sandeeplocharla commented Oct 21, 2025
edited
Loading

Copy link
Copy Markdown
Collaborator

Description

This PR...

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?

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

//this method to get all svms and also filtered svms based on query params as a part of URL
@RequestMapping(method = RequestMethod.GET)
OntapResponse<Svm> getSvmResponse(URI baseURL, @RequestHeader("Authorization") String header);
OntapResponse<Svm> getSvms(URI baseURL, @RequestHeader("Authorization") String header);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

we kept this naming convention for other feign client and this can return only one record also

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Reverted it back

public static String Username;
public static String Password;
public static String ManagementLIF;
public static String Svm;

suryag1201 Oct 22, 2025
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

svm is an object which can not be string use svmName instead

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

sure, will rename it

public static String Password;
public static String ManagementLIF;
public static String Svm;
public static String Protocol;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Can we have type as enum with supported protocols?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Done

@SuppressWarnings("unchecked")
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
// Validations
if (podId != null && clusterId == null) {

suryag1201 Oct 22, 2025
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

we can combine this check into one check bcz both are required, also clusterId can be empty

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah, in my previous review to this change i nanother PR, I gave comment to use trim command and then empty check. Please add them for each mandatory parameter

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Taken care of it, done

}

PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
if (clusterId != null) {

suryag1201 Oct 22, 2025
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

why this check is required again? it is already checked above

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Customer has an option to not send both cluster and pod ids, in case of creating a zone level primary storage pool.

details.put(Constants.MANAGEMENTLIF, url);

// Validate the ONTAP details
if(details.get(Constants.ISDISAGGREGATED) == null || details.get(Constants.ISDISAGGREGATED).isEmpty()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

add _ for ISDISAGGREGATED constant like IS_DISAGGREGATED

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done

// Call the SVM API to check if the SVM exists
Svm svm = null;
URI url = URI.create(Constants.HTTPS + storage.getManagementLIF() + Constants.GETSVMs);
OntapResponse<Svm> svms = svmFeignClient.getSvms(url, authHeader);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

add a check for svms null check object

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done

public class Constants {
public static final String NFS = "nfs";
public static final String ISCSI = "iscsi";
public static final String PROTOCOL = "protocol";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

add _ where ever possible

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done

// Create URI for POST CreateVolume API
URI url = utils.generateURI(Constants.CREATEVOLUME);
// Call the VolumeFeignClient to create the volume
JobResponse jobResponse = volumeFeignClient.createVolumeWithJob(url, authHeader, volumeRequest);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

add null checks

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done, thanks

url = utils.generateURI(Constants.GETJOBBYUUID);
int jobRetryCount = 0, maxJobRetries = Constants.JOBMAXRETRIES;
Job createVolumeJob = null;
while(createVolumeJob == null || createVolumeJob.getState().equals(Constants.JOBRUNNING) || createVolumeJob.getState().equals(Constants.JOBQUEUE) || createVolumeJob.getState().equals(Constants.JOBPAUSED)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

instead of checking for all state of job, check for not success

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

this seems to be lost during rebase, thanks, done

Svm svm = null;
URI url = URI.create(Constants.HTTPS + storage.getManagementLIF() + Constants.GETSVMs);
OntapResponse<Svm> svms = svmFeignClient.getSvms(url, authHeader);
for (Svm storageVM : svms.getRecords()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Instead of getting all svm and picking based on name, better to call getSVMByName. We may need to add this method in svmFeignClient

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes, this approach is not optimized. fetch the SVM using name as query parameter instead fetch all then find for desired name.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Made the necessary changes


@RequestMapping(method = RequestMethod.DELETE, value="/{uuid}")
void deleteVolume(@RequestHeader("Authorization") String authHeader, @PathVariable("uuid") String uuid);
void deleteVolume(URI baseURL, @RequestHeader("Authorization") String authHeader, @PathVariable("uuid") String uuid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

with this change, why do we need to add url parameter at class level annotation?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

If we don't pass it explicitly, we need to set a property statically in application.properties or somewhere like that, which in our case is not feasible. Also, user might ask us to deal with multiple filers, so, the IP wouldn't be static

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I am not seeing any significant changes here, better remove this class from the PR

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This came in as part of rebase. It just has some space changes. Sure, will try to revert it

@SuppressWarnings("unchecked")
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
// Validations
if (podId != null && clusterId == null) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yeah, in my previous review to this change i nanother PR, I gave comment to use trim command and then empty check. Please add them for each mandatory parameter

Svm svm = null;
URI url = URI.create(Constants.HTTPS + storage.getManagementLIF() + Constants.GETSVMs);
OntapResponse<Svm> svms = svmFeignClient.getSvms(url, authHeader);
for (Svm storageVM : svms.getRecords()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes, this approach is not optimized. fetch the SVM using name as query parameter instead fetch all then find for desired name.

ClusterVO clusterVO = _clusterDao.findById(clusterId);
Preconditions.checkNotNull(clusterVO, "Unable to locate the specified cluster");
if (clusterVO.getHypervisorType() != Hypervisor.HypervisorType.KVM) {
throw new CloudRuntimeException("ONTAP primary storage is not supported for KVM hypervisor");

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

change the message

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

done

import org.apache.cloudstack.storage.utils.Constants.ProtocolType;

public class OntapStorage {
public static String Username;

suryag1201 Oct 23, 2025
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Follow naming convention for all fields

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

why you added only inports in this class ?

public class OntapStorage {
public static String _username;
public static String _password;
public static String _managementLIF;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Lets use camel casing for the variable name

}
}

if (storagePoolName == null || storagePoolName.isEmpty()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

empty check on the sting parameters must use trim method as well

throw new CloudRuntimeException("iSCSI protocol is not enabled on SVM " + svmName);
}
List<Aggregate> aggrs = svm.getAggregates();
if (aggrs == null || aggrs.isEmpty()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

One use case to validate here is that if the passed credentials belong to the cluster, then by default, all the aggregates are mapped to the underlying SVMs. However, if credentials belong to an SVM user, then aggregates must be assigned to the SVM to access them.

@suryag1201 can you help @sandeeplocharla to close on this use case implementation.

rajiv-jain-netapp left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

there are dependencies on these changes for other engineers, approving this PR for now. Ensure you are picking up the given comments in subsequent PR

sandeeplocharla merged commit 25353c2 into main Oct 24, 2025
13 of 16 checks passed
piyush5netapp pushed a commit that referenced this pull request Dec 4, 2025
# This is the 1st commit message:

NFS Cloudstack volume and export policy utils

# This is the commit message #2:

Licencse add in files

# This is the commit message #3:

accessgroup create recode

# This is the commit message #4:

creatacessgroup for NFS impl

# This is the commit message #5:

storage pool mounting on host

# This is the commit message #6:

storage pool mounting on host 1

# This is the commit message #7:

vm restart issue

# This is the commit message #8:

vm restart issue 1

# This is the commit message #9:

vm restart issue 2

# This is the commit message #10:

vm instance creation test1

# This is the commit message #11:

vm instance creation test4
sandeeplocharla added a commit that referenced this pull request Jan 30, 2026
* CSTACKEX-7: ONTAP Primary storage pool

---------

Co-authored-by: Locharla, Sandeep <Sandeep.Locharla@netapp.com>
rajiv-jain-netapp pushed a commit that referenced this pull request Apr 16, 2026
* CSTACKEX-7: ONTAP Primary storage pool

---------

Co-authored-by: Locharla, Sandeep <Sandeep.Locharla@netapp.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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


Back | FazBrowse Home | New Git URL