1818 */
1919package org .apache .cloudstack .storage .driver ;
2020
21+ import com .cloud .agent .api .Answer ;
22+ import com .cloud .agent .api .to .DataObjectType ;
2123import com .cloud .agent .api .to .DataStoreTO ;
2224import com .cloud .agent .api .to .DataTO ;
25+ import com .cloud .exception .InvalidParameterValueException ;
2326import com .cloud .host .Host ;
2427import com .cloud .storage .Storage ;
2528import com .cloud .storage .StoragePool ;
2629import com .cloud .storage .Volume ;
2730import com .cloud .utils .Pair ;
31+ import com .cloud .utils .exception .CloudRuntimeException ;
2832import org .apache .cloudstack .engine .subsystem .api .storage .ChapInfo ;
2933import org .apache .cloudstack .engine .subsystem .api .storage .CopyCommandResult ;
3034import org .apache .cloudstack .engine .subsystem .api .storage .CreateCmdResult ;
3741import org .apache .cloudstack .engine .subsystem .api .storage .VolumeInfo ;
3842import org .apache .cloudstack .framework .async .AsyncCompletionCallback ;
3943import org .apache .cloudstack .storage .command .CommandResult ;
44+ import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
45+ import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailsDao ;
46+ import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
47+ import org .apache .cloudstack .storage .feign .model .Lun ;
48+ import org .apache .cloudstack .storage .provider .StorageProviderFactory ;
49+ import org .apache .cloudstack .storage .service .SANStrategy ;
50+ import org .apache .cloudstack .storage .service .StorageStrategy ;
51+ import org .apache .cloudstack .storage .feign .model .OntapStorage ;
52+ import org .apache .cloudstack .storage .utils .Constants ;
4053import org .apache .logging .log4j .LogManager ;
4154import org .apache .logging .log4j .Logger ;
4255
56+ import javax .inject .Inject ;
57+ import java .util .Arrays ;
4358import java .util .HashMap ;
59+ import java .util .List ;
4460import java .util .Map ;
4561
4662public class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver {
4763
48- private static final Logger s_logger = (Logger )LogManager .getLogger (OntapPrimaryDatastoreDriver .class );
64+ private static final Logger logger = (Logger )LogManager .getLogger (OntapPrimaryDatastoreDriver .class );
65+
66+ @ Inject
67+ private StoragePoolDetailsDao storagePoolDetailsDao ;
68+ @ Inject private PrimaryDataStoreDao storagePoolDao ;
69+
4970 @ Override
5071 public Map <String , String > getCapabilities () {
51- s_logger .trace ("OntapPrimaryDatastoreDriver: getCapabilities: Called" );
72+ logger .trace ("OntapPrimaryDatastoreDriver: getCapabilities: Called" );
5273 Map <String , String > mapCapabilities = new HashMap <>();
5374
5475 mapCapabilities .put (DataStoreCapabilities .STORAGE_SYSTEM_SNAPSHOT .toString (), Boolean .TRUE .toString ());
@@ -68,9 +89,74 @@ public DataStoreTO getStoreTO(DataStore store) {
6889 }
6990
7091 @ Override
71- public void createAsync (DataStore store , DataObject data , AsyncCompletionCallback <CreateCmdResult > callback ) {
92+ public void createAsync (DataStore dataStore , DataObject dataObject , AsyncCompletionCallback <CreateCmdResult > callback ) {
93+ CreateCmdResult createCmdResult = null ;
94+ String path = null ;
95+ String errMsg = null ;
96+ if (dataStore == null ) {
97+ throw new InvalidParameterValueException ("createAsync: dataStore should not be null" );
98+ }
99+ if (dataObject == null ) {
100+ throw new InvalidParameterValueException ("createAsync: dataObject should not be null" );
101+ }
102+ if (callback == null ) {
103+ throw new InvalidParameterValueException ("createAsync: callback should not be null" );
104+ }
105+
106+ try {
107+ logger .info ("createAsync: Volume creation starting for data store [{}] and data object [{}] of type [{}]" ,
108+ dataStore , dataObject , dataObject .getType ());
109+ if (dataObject .getType () == DataObjectType .VOLUME ) {
110+ path = createCloudStackVolume (dataStore .getId (), dataObject );
111+ createCmdResult = new CreateCmdResult (path , new Answer (null , true , null ));
112+ } else {
113+ errMsg = "Invalid DataObjectType (" + dataObject .getType () + ") passed to createAsync" ;
114+ logger .error (errMsg );
115+ throw new CloudRuntimeException (errMsg );
116+ }
117+ } catch (Exception e ) {
118+ errMsg = e .getMessage ();
119+ logger .error ("createAsync: Volume creation failed for dataObject [{}]: {}" , dataObject , errMsg );
120+ createCmdResult = new CreateCmdResult (null , new Answer (null , false , errMsg ));
121+ createCmdResult .setResult (e .toString ());
122+ } finally {
123+ callback .complete (createCmdResult );
124+ }
125+ }
72126
73- s_logger .trace ("OntapPrimaryDatastoreDriver: createAsync: Store: " +store +", data: " +data );
127+ private String createCloudStackVolume (long storagePoolId , DataObject dataObject ) {
128+ String path = null ;
129+ StoragePoolVO storagePool = storagePoolDao .findById (storagePoolId );
130+ if (storagePool == null ) {
131+ throw new CloudRuntimeException ("createCloudStackVolume : Storage Pool not found for id: " + storagePoolId );
132+ }
133+ List <String > keyList = Arrays .asList (Constants .USERNAME , Constants .PROTOCOL , Constants .IS_DISAGGREGATED , Constants .PASSWORD , Constants .MANAGEMENT_LIF ,
134+ Constants .SVM_NAME , Constants .NAME );
135+ Map <String , String > storagePoolDetailMap = storagePoolDetailsDao .listDetailsKeyPairs (storagePoolId , keyList );
136+ OntapStorage ontapStorage = new OntapStorage (storagePoolDetailMap .get (Constants .USERNAME ), storagePoolDetailMap .get (Constants .PASSWORD ),
137+ storagePoolDetailMap .get (Constants .MANAGEMENT_LIF ), storagePoolDetailMap .get (Constants .SVM_NAME ), Constants .ProtocolType .valueOf (storagePoolDetailMap .get (Constants .PROTOCOL )),
138+ Boolean .parseBoolean (storagePoolDetailMap .get (Constants .IS_DISAGGREGATED )));
139+ StorageStrategy storageStrategy = StorageProviderFactory .createStrategy (ontapStorage );
140+ boolean isValid = storageStrategy .connect ();
141+ if (isValid ) {
142+ String svmName = ontapStorage .getSvmName ();
143+ String lunOrFileName = dataObject .getName ();
144+ Long size = dataObject .getSize ();
145+ String volName = storagePool .getName ();
146+
147+ // Create LUN based on protocol
148+ if (ontapStorage .getProtocol ().equals (Constants .ISCSI )) {
149+ SANStrategy sanStrategy = StorageProviderFactory .getSANStrategy (ontapStorage );
150+ Lun lun = sanStrategy .createLUN (svmName , volName , lunOrFileName , size , Lun .OsTypeEnum .LINUX .getValue ());
151+ if (lun .getName () == null || lun .getName ().isEmpty ()) {
152+ throw new CloudRuntimeException ("createCloudStackVolume : LUN Name is invalid" );
153+ }
154+ path = lun .getName ();
155+ }
156+ } else {
157+ throw new CloudRuntimeException ("createCloudStackVolume : ONTAP details validation failed, cannot connect to ONTAP cluster" );
158+ }
159+ return path ;
74160 }
75161
76162 @ Override
@@ -105,6 +191,15 @@ public ChapInfo getChapInfo(DataObject dataObject) {
105191
106192 @ Override
107193 public boolean grantAccess (DataObject dataObject , Host host , DataStore dataStore ) {
194+ if (dataStore == null ) {
195+ throw new CloudRuntimeException ("grantAccess: dataStore should not be null" );
196+ }
197+ if (dataObject == null ) {
198+ throw new CloudRuntimeException ("grantAccess: dataObject should not be null" );
199+ }
200+ if (host == null ) {
201+ throw new CloudRuntimeException ("grantAccess: host should not be null" );
202+ }
108203 return true ;
109204 }
110205
0 commit comments