2525import com .cloud .exception .InvalidParameterValueException ;
2626import com .cloud .host .Host ;
2727import com .cloud .storage .Storage ;
28- import com .cloud .storage .StoragePool ;
28+ import com .cloud .storage .ScopeType ;
29+ import com .cloud .storage .VolumeVO ;
2930import com .cloud .storage .Volume ;
31+ import com .cloud .storage .StoragePool ;
32+ import com .cloud .storage .dao .VolumeDao ;
3033import com .cloud .utils .Pair ;
3134import com .cloud .utils .exception .CloudRuntimeException ;
3235import org .apache .cloudstack .engine .subsystem .api .storage .ChapInfo ;
4548import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailsDao ;
4649import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
4750import org .apache .cloudstack .storage .service .StorageStrategy ;
51+ import org .apache .cloudstack .storage .service .model .AccessGroup ;
4852import org .apache .cloudstack .storage .service .model .CloudStackVolume ;
4953import org .apache .cloudstack .storage .service .model .ProtocolType ;
5054import org .apache .cloudstack .storage .utils .Constants ;
5660import java .util .HashMap ;
5761import java .util .Map ;
5862
59- public class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver {
63+ public abstract class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver {
6064
6165 private static final Logger s_logger = LogManager .getLogger (OntapPrimaryDatastoreDriver .class );
6266
6367 @ Inject private Utility utils ;
6468 @ Inject private StoragePoolDetailsDao storagePoolDetailsDao ;
6569 @ Inject private PrimaryDataStoreDao storagePoolDao ;
70+ @ Inject private VolumeDao volumeDao ;
6671 @ Override
6772 public Map <String , String > getCapabilities () {
6873 s_logger .trace ("OntapPrimaryDatastoreDriver: getCapabilities: Called" );
@@ -99,10 +104,16 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
99104 throw new InvalidParameterValueException ("createAsync: callback should not be null" );
100105 }
101106 try {
102- s_logger .info ("createAsync: Started for data store [{}] and data object [{}] of type [{}]" ,
103- dataStore , dataObject , dataObject .getType ());
107+ s_logger .info ("createAsync: Started for data store [{}] and data object [{}] of type [{}]" , dataStore , dataObject , dataObject .getType ());
108+
109+ StoragePoolVO storagePool = storagePoolDao .findById (dataStore .getId ());
110+ if (storagePool == null ) {
111+ s_logger .error ("createCloudStackVolume : Storage Pool not found for id: " + dataStore .getId ());
112+ throw new CloudRuntimeException ("createCloudStackVolume : Storage Pool not found for id: " + dataStore .getId ());
113+ }
114+
104115 if (dataObject .getType () == DataObjectType .VOLUME ) {
105- path = createCloudStackVolumeForTypeVolume (dataStore , dataObject );
116+ path = createCloudStackVolumeForTypeVolume (storagePool , dataObject );
106117 createCmdResult = new CreateCmdResult (path , new Answer (null , true , null ));
107118 } else {
108119 errMsg = "Invalid DataObjectType (" + dataObject .getType () + ") passed to createAsync" ;
@@ -119,13 +130,8 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
119130 }
120131 }
121132
122- private String createCloudStackVolumeForTypeVolume (DataStore dataStore , DataObject dataObject ) {
123- StoragePoolVO storagePool = storagePoolDao .findById (dataStore .getId ());
124- if (storagePool == null ) {
125- s_logger .error ("createCloudStackVolume : Storage Pool not found for id: " + dataStore .getId ());
126- throw new CloudRuntimeException ("createCloudStackVolume : Storage Pool not found for id: " + dataStore .getId ());
127- }
128- Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (dataStore .getId ());
133+ private String createCloudStackVolumeForTypeVolume (StoragePoolVO storagePool , DataObject dataObject ) {
134+ Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (storagePool .getId ());
129135 StorageStrategy storageStrategy = utils .getStrategyByStoragePoolDetails (details );
130136 s_logger .info ("createCloudStackVolumeForTypeVolume: Connection to Ontap SVM [{}] successful, preparing CloudStackVolumeRequest" , details .get (Constants .SVM_NAME ));
131137 CloudStackVolume cloudStackVolumeRequest = utils .createCloudStackVolumeRequestByProtocol (storagePool , details , dataObject );
@@ -171,9 +177,83 @@ public ChapInfo getChapInfo(DataObject dataObject) {
171177
172178 @ Override
173179 public boolean grantAccess (DataObject dataObject , Host host , DataStore dataStore ) {
180+ if (dataStore == null ) {
181+ throw new InvalidParameterValueException ("grantAccess: dataStore should not be null" );
182+ }
183+ if (dataObject == null ) {
184+ throw new InvalidParameterValueException ("grantAccess: dataObject should not be null" );
185+ }
186+ if (host == null ) {
187+ throw new InvalidParameterValueException ("grantAccess: host should not be null" );
188+ }
189+ try {
190+ StoragePoolVO storagePool = storagePoolDao .findById (dataStore .getId ());
191+ if (storagePool == null ) {
192+ s_logger .error ("grantAccess : Storage Pool not found for id: " + dataStore .getId ());
193+ throw new CloudRuntimeException ("grantAccess : Storage Pool not found for id: " + dataStore .getId ());
194+ }
195+ if (storagePool .getScope () != ScopeType .CLUSTER || storagePool .getScope () != ScopeType .ZONE ) {
196+ s_logger .error ("grantAccess: Only Cluster and ZONE scoped primary storage is supported. Storage Pool: " + storagePool .getName ());
197+ throw new CloudRuntimeException ("grantAccess: Only Cluster and ZONE scoped primary storage is supported. Storage Pool: " + storagePool .getName ());
198+ }
199+
200+ VolumeVO volumeVO = volumeDao .findById (dataObject .getId ());
201+ if (volumeVO == null ) {
202+ s_logger .error ("grantAccess : Cloud Stack Volume not found for id: " + dataObject .getId ());
203+ throw new CloudRuntimeException ("grantAccess : Cloud Stack Volume not found for id: " + dataObject .getId ());
204+ }
205+
206+ if (dataObject .getType () == DataObjectType .VOLUME ) {
207+ grantAccessForVolume (storagePool , volumeVO , host );
208+ } else {
209+ s_logger .error ("Invalid DataObjectType (" + dataObject .getType () + ") passed to grantAccess" );
210+ throw new CloudRuntimeException ("Invalid DataObjectType (" + dataObject .getType () + ") passed to grantAccess" );
211+ }
212+ } catch (Exception e ){
213+ s_logger .error ("grantAccess: Failed for dataObject [{}]: {}" , dataObject , e .getMessage ());
214+ throw new CloudRuntimeException ("grantAccess: Failed with error :" + e .getMessage ());
215+ }
174216 return true ;
175217 }
176218
219+ private void grantAccessForVolume (StoragePoolVO storagePool , VolumeVO volumeVO , Host host ) {
220+ Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (storagePool .getId ());
221+ StorageStrategy storageStrategy = utils .getStrategyByStoragePoolDetails (details );
222+ String svmName = details .get (Constants .SVM_NAME );
223+
224+ if (ProtocolType .ISCSI .name ().equalsIgnoreCase (details .get (Constants .PROTOCOL ))) {
225+ Map <String , String > getCloudStackVolumeMap = new HashMap <>();
226+ getCloudStackVolumeMap .put (Constants .NAME , volumeVO .getPath ());
227+ getCloudStackVolumeMap .put (Constants .SVM_DOT_NAME , svmName );
228+ CloudStackVolume cloudStackVolume = storageStrategy .getCloudStackVolume (getCloudStackVolumeMap );
229+ if (cloudStackVolume == null ||cloudStackVolume .getLun () == null || cloudStackVolume .getLun ().getName () == null ) {
230+ s_logger .error ("grantAccess: Failed to get LUN details [{}]" , volumeVO .getName ());
231+ throw new CloudRuntimeException ("grantAccess: Failed to get LUN [" + volumeVO .getName () + "]" );
232+ }
233+
234+ long scopeId = (storagePool .getScope () == ScopeType .CLUSTER ) ? host .getClusterId () : host .getDataCenterId ();
235+ String igroupName = utils .getIgroupName (storagePool .getName (), scopeId );
236+ Map <String , String > getAccessGroupMap = new HashMap <>();
237+ getAccessGroupMap .put (Constants .NAME , igroupName );
238+ getAccessGroupMap .put (Constants .SVM_DOT_NAME , svmName );
239+ AccessGroup accessGroup = storageStrategy .getAccessGroup (getAccessGroupMap );
240+ if (accessGroup == null || accessGroup .getIgroup () == null || accessGroup .getIgroup ().getName () == null ) {
241+ s_logger .error ("grantAccess: Failed to get iGroup details for host [{}]" , host .getName ());
242+ throw new CloudRuntimeException ("grantAccess: Failed to get iGroup details for host [" + host .getName () + "]" );
243+ }
244+ if (!accessGroup .getIgroup ().getInitiators ().contains (host .getStorageUrl ())) {
245+ s_logger .error ("grantAccess: initiator [{}] is not present in iGroup [{}]" , host .getStorageUrl (), igroupName );
246+ throw new CloudRuntimeException ("grantAccess: initiator [" + host .getStorageUrl () + "] is not present in iGroup [" + igroupName );
247+ }
248+
249+ Map <String , String > enableLogicalAccessMap = new HashMap <>();
250+ enableLogicalAccessMap .put (Constants .LUN_DOT_NAME , volumeVO .getPath ());
251+ enableLogicalAccessMap .put (Constants .SVM_DOT_NAME , svmName );
252+ enableLogicalAccessMap .put (Constants .IGROUP_DOT_NAME , igroupName );
253+ storageStrategy .enableLogicalAccess (enableLogicalAccessMap );
254+ }
255+ }
256+
177257 @ Override
178258 public void revokeAccess (DataObject dataObject , Host host , DataStore dataStore ) {
179259
0 commit comments