2121
2222
2323import com .cloud .agent .api .StoragePoolInfo ;
24+ import com .cloud .dc .ClusterVO ;
25+ import com .cloud .dc .dao .ClusterDao ;
26+ import com .cloud .host .HostVO ;
2427import com .cloud .hypervisor .Hypervisor ;
28+ import com .cloud .resource .ResourceManager ;
29+ import com .cloud .storage .Storage ;
30+ import com .cloud .storage .StorageManager ;
2531import com .cloud .storage .StoragePool ;
32+ import com .cloud .utils .exception .CloudRuntimeException ;
33+ import com .google .common .base .Preconditions ;
2634import org .apache .cloudstack .engine .subsystem .api .storage .ClusterScope ;
2735import org .apache .cloudstack .engine .subsystem .api .storage .DataStore ;
2836import org .apache .cloudstack .engine .subsystem .api .storage .HostScope ;
37+ import org .apache .cloudstack .engine .subsystem .api .storage .PrimaryDataStoreInfo ;
2938import org .apache .cloudstack .engine .subsystem .api .storage .PrimaryDataStoreLifeCycle ;
39+ import org .apache .cloudstack .engine .subsystem .api .storage .PrimaryDataStoreParameters ;
3040import org .apache .cloudstack .engine .subsystem .api .storage .ZoneScope ;
41+ import org .apache .cloudstack .storage .datastore .lifecycle .BasePrimaryDataStoreLifeCycleImpl ;
42+ import org .apache .cloudstack .storage .provider .StorageProviderManager ;
43+ import org .apache .cloudstack .storage .volume .datastore .PrimaryDataStoreHelper ;
3144import org .apache .logging .log4j .LogManager ;
3245import org .apache .logging .log4j .Logger ;
33- import java .util .Map ;
3446
35- public class OntapPrimaryDatastoreLifecycle implements PrimaryDataStoreLifeCycle {
47+ import javax .inject .Inject ;
48+ import java .util .ArrayList ;
49+ import java .util .List ;
50+ import java .util .Map ;
51+ import java .util .UUID ;
3652
53+ public class OntapPrimaryDatastoreLifecycle extends BasePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
54+ @ Inject private ClusterDao _clusterDao ;
55+ @ Inject private StorageManager _storageMgr ;
56+ @ Inject private ResourceManager _resourceMgr ;
57+ @ Inject private PrimaryDataStoreHelper _dataStoreHelper ;
3758 private static final Logger s_logger = (Logger )LogManager .getLogger (OntapPrimaryDatastoreLifecycle .class );
3859
3960 /**
@@ -43,14 +64,94 @@ public class OntapPrimaryDatastoreLifecycle implements PrimaryDataStoreLifeCycle
4364 */
4465 @ Override
4566 public DataStore initialize (Map <String , Object > dsInfos ) {
46-
47- return null ;
48-
67+ String url = dsInfos .get ("url" ).toString ();
68+ Long zoneId = (Long ) dsInfos .get ("zoneId" );
69+ Long podId = (Long )dsInfos .get ("podId" );
70+ Long clusterId = (Long )dsInfos .get ("clusterId" );
71+ String storagePoolName = dsInfos .get ("name" ).toString ();
72+ String providerName = dsInfos .get ("providerName" ).toString ();
73+ String tags = dsInfos .get ("tags" ).toString ();
74+ Boolean isTagARule = (Boolean ) dsInfos .get ("isTagARule" );
75+ String scheme = dsInfos .get ("scheme" ).toString ();
76+
77+ // Additional details requested for ONTAP primary storage pool creation
78+ @ SuppressWarnings ("unchecked" )
79+ Map <String , String > details = (Map <String , String >)dsInfos .get ("details" );
80+ // Validations
81+ if (podId != null && clusterId == null ) {
82+ s_logger .error ("Cluster Id is null, cannot create primary storage" );
83+ return null ;
84+ } else if (podId == null && clusterId != null ) {
85+ s_logger .error ("Pod Id is null, cannot create primary storage" );
86+ return null ;
87+ }
88+
89+ if (podId == null && clusterId == null ) {
90+ if (zoneId != null ) {
91+ s_logger .info ("Both Pod Id and Cluster Id are null, Primary storage pool will be associated with a Zone" );
92+ } else {
93+ throw new CloudRuntimeException ("Pod Id, Cluster Id and Zone Id are all null, cannot create primary storage" );
94+ }
95+ }
96+
97+ PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters ();
98+ if (clusterId != null ) {
99+ ClusterVO clusterVO = _clusterDao .findById (clusterId );
100+ Preconditions .checkNotNull (clusterVO , "Unable to locate the specified cluster" );
101+ if (clusterVO .getHypervisorType () != Hypervisor .HypervisorType .KVM ) {
102+ throw new CloudRuntimeException ("ONTAP primary storage is not supported for KVM hypervisor" );
103+ }
104+ parameters .setHypervisorType (clusterVO .getHypervisorType ());
105+ }
106+ // Validate the ONTAP details
107+ StorageProviderManager storageProviderManager = new StorageProviderManager (details , scheme );
108+ boolean isValid = storageProviderManager .connect (details );
109+ if (isValid ) {
110+ // String volumeName = storagePoolName + "_vol"; //TODO: Figure out a better naming convention
111+ storageProviderManager .createVolume (storagePoolName , Integer .parseInt ((details .get ("size" )))); // TODO: size should be in bytes, so see if conversion is needed
112+ } else {
113+ throw new CloudRuntimeException ("ONTAP details validation failed, cannot create primary storage" );
114+ }
115+
116+ // TODO: While testing need to check what does this actually do and if the fields corresponding to each protocol should also be set
117+ if (scheme .equalsIgnoreCase ("nfs" )) {
118+ parameters .setType (Storage .StoragePoolType .NetworkFilesystem );
119+ } else if (scheme .equalsIgnoreCase ("iscsi" )) {
120+ parameters .setType (Storage .StoragePoolType .Iscsi );
121+ } else {
122+ throw new CloudRuntimeException ("Unsupported protocol: " + scheme + ", cannot create primary storage" );
123+ }
124+
125+ parameters .setTags (tags );
126+ parameters .setIsTagARule (isTagARule );
127+ parameters .setDetails (details );
128+ parameters .setUuid (UUID .randomUUID ().toString ());
129+ parameters .setZoneId (zoneId );
130+ parameters .setPodId (podId );
131+ parameters .setClusterId (clusterId );
132+ parameters .setName (storagePoolName );
133+ parameters .setProviderName (providerName );
134+ parameters .setManaged (true );
135+
136+ return _dataStoreHelper .createPrimaryDataStore (parameters );
49137 }
50138
51139 @ Override
52- public boolean attachCluster (DataStore store , ClusterScope scope ) {
53- return false ;
140+ public boolean attachCluster (DataStore dataStore , ClusterScope scope ) {
141+ PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo )dataStore ;
142+ List <HostVO > hostsToConnect = _resourceMgr .getEligibleUpAndEnabledHostsInClusterForStorageConnection (primarystore );
143+
144+ logger .debug (String .format ("Attaching the pool to each of the hosts %s in the cluster: %s" , hostsToConnect , primarystore .getClusterId ()));
145+ for (HostVO host : hostsToConnect ) {
146+ // TODO: Fetch the host IQN and add to the initiator group on ONTAP cluster
147+ try {
148+ _storageMgr .connectHostToSharedPool (host , dataStore .getId ());
149+ } catch (Exception e ) {
150+ logger .warn ("Unable to establish a connection between " + host + " and " + dataStore , e );
151+ }
152+ }
153+ _dataStoreHelper .attachCluster (dataStore );
154+ return true ;
54155 }
55156
56157 @ Override
@@ -60,7 +161,24 @@ public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo exis
60161
61162 @ Override
62163 public boolean attachZone (DataStore dataStore , ZoneScope scope , Hypervisor .HypervisorType hypervisorType ) {
63- return false ;
164+ List <HostVO > hostsToConnect = new ArrayList <>();
165+ Hypervisor .HypervisorType [] hypervisorTypes = {Hypervisor .HypervisorType .XenServer , Hypervisor .HypervisorType .VMware , Hypervisor .HypervisorType .KVM };
166+
167+ for (Hypervisor .HypervisorType type : hypervisorTypes ) {
168+ hostsToConnect .addAll (_resourceMgr .getEligibleUpAndEnabledHostsInZoneForStorageConnection (dataStore , scope .getScopeId (), type ));
169+ }
170+
171+ logger .debug (String .format ("In createPool. Attaching the pool to each of the hosts in %s." , hostsToConnect ));
172+ for (HostVO host : hostsToConnect ) {
173+ // TODO: Fetch the host IQN and add to the initiator group on ONTAP cluster
174+ try {
175+ _storageMgr .connectHostToSharedPool (host , dataStore .getId ());
176+ } catch (Exception e ) {
177+ logger .warn ("Unable to establish a connection between " + host + " and " + dataStore , e );
178+ }
179+ }
180+ _dataStoreHelper .attachZone (dataStore );
181+ return true ;
64182 }
65183
66184 @ Override
0 commit comments