diff --git a/client/pom.xml b/client/pom.xml index 605487404a87..997d530725da 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -121,6 +121,11 @@ cloud-plugin-storage-volume-adaptive ${project.version} + + org.apache.cloudstack + cloud-plugin-storage-volume-ontap + ${project.version} + org.apache.cloudstack cloud-plugin-storage-volume-solidfire diff --git a/plugins/pom.xml b/plugins/pom.xml index d665f90b623d..cc05cab121cd 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -129,6 +129,7 @@ storage/volume/default storage/volume/nexenta storage/volume/sample + storage/volume/ontap storage/volume/solidfire storage/volume/scaleio storage/volume/linstor diff --git a/plugins/storage/volume/ontap/pom.xml b/plugins/storage/volume/ontap/pom.xml new file mode 100644 index 000000000000..decfb29743da --- /dev/null +++ b/plugins/storage/volume/ontap/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + cloud-plugin-storage-volume-ontap + Apache CloudStack Plugin - Storage Volume ONTAP Provider + + org.apache.cloudstack + cloudstack-plugins + 4.22.0.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-plugin-storage-volume-default + ${project.version} + + + org.json + json + 20230227 + + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java new file mode 100644 index 000000000000..2209b3168090 --- /dev/null +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java @@ -0,0 +1,190 @@ +package org.apache.cloudstack.storage.driver; + + +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.host.Host; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePool; +import com.cloud.storage.Volume; +import com.cloud.utils.Pair; +import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver { + + private static final Logger s_logger = (Logger)LogManager.getLogger(OntapPrimaryDatastoreDriver.class); + @Override + public Map getCapabilities() { + s_logger.trace("OntapPrimaryDatastoreDriver: getCapabilities: Called"); + Map mapCapabilities = new HashMap<>(); + + mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString()); + mapCapabilities.put(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_SNAPSHOT.toString(), Boolean.TRUE.toString()); + + return mapCapabilities; + } + + @Override + public DataTO getTO(DataObject data) { + return null; + } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + return null; + } + + @Override + public void createAsync(DataStore store, DataObject data, AsyncCompletionCallback callback) { + + s_logger.trace("OntapPrimaryDatastoreDriver: createAsync: Store: "+store+", data: "+data); + } + + @Override + public void deleteAsync(DataStore store, DataObject data, AsyncCompletionCallback callback) { + + } + + @Override + public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { + + } + + @Override + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + return false; + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + + } + + @Override + public ChapInfo getChapInfo(DataObject dataObject) { + return null; + } + + @Override + public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) { + return true; + } + + @Override + public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) { + + } + + @Override + public long getDataObjectSizeIncludingHypervisorSnapshotReserve(DataObject dataObject, StoragePool storagePool) { + return 0; + } + + @Override + public long getBytesRequiredForTemplate(TemplateInfo templateInfo, StoragePool storagePool) { + return 0; + } + + @Override + public long getUsedBytes(StoragePool storagePool) { + return 0; + } + + @Override + public long getUsedIops(StoragePool storagePool) { + return 0; + } + + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + + } + + @Override + public void revertSnapshot(SnapshotInfo snapshotOnImageStore, SnapshotInfo snapshotOnPrimaryStore, AsyncCompletionCallback callback) { + + } + + @Override + public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, QualityOfServiceState qualityOfServiceState) { + + } + + @Override + public boolean canProvideStorageStats() { + return true; + } + + @Override + public Pair getStorageStats(StoragePool storagePool) { + return null; + } + + @Override + public boolean canProvideVolumeStats() { + return true; + } + + @Override + public Pair getVolumeStats(StoragePool storagePool, String volumeId) { + return null; + } + + @Override + public boolean canHostAccessStoragePool(Host host, StoragePool pool) { + return true; + } + + @Override + public boolean isVmInfoNeeded() { + return true; + } + + @Override + public void provideVmInfo(long vmId, long volumeId) { + + } + + @Override + public boolean isVmTagsNeeded(String tagKey) { + return true; + } + + @Override + public void provideVmTags(long vmId, long volumeId, String tagValue) { + + } + + @Override + public boolean isStorageSupportHA(Storage.StoragePoolType type) { + return true; + } + + @Override + public void detachVolumeFromAllStorageNodes(Volume volume) { + + } +} \ No newline at end of file diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java new file mode 100644 index 000000000000..d20ef863d841 --- /dev/null +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -0,0 +1,91 @@ +package org.apache.cloudstack.storage.lifecycle; + + +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.storage.StoragePool; +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import java.util.Map; + +public class OntapPrimaryDatastoreLifecycle implements PrimaryDataStoreLifeCycle { + + private static final Logger s_logger = (Logger)LogManager.getLogger(OntapPrimaryDatastoreLifecycle.class); + + /** + * Creates primary storage on NetApp storage + * @param dsInfos + * @return + */ + @Override + public DataStore initialize(Map dsInfos) { + + return null; + + } + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + return false; + } + + @Override + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { + return false; + } + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope, Hypervisor.HypervisorType hypervisorType) { + return false; + } + + @Override + public boolean maintain(DataStore store) { + return true; + } + + @Override + public boolean cancelMaintain(DataStore store) { + return true; + } + + @Override + public boolean deleteDataStore(DataStore store) { + return true; + } + + @Override + public boolean migrateToObjectStore(DataStore store) { + return true; + } + + @Override + public void updateStoragePool(StoragePool storagePool, Map details) { + + } + + @Override + public void enableStoragePool(DataStore store) { + + } + + @Override + public void disableStoragePool(DataStore store) { + + } + + @Override + public void changeStoragePoolScopeToZone(DataStore store, ClusterScope clusterScope, Hypervisor.HypervisorType hypervisorType) { + + } + + @Override + public void changeStoragePoolScopeToCluster(DataStore store, ClusterScope clusterScope, Hypervisor.HypervisorType hypervisorType) { + + } +} \ No newline at end of file diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/provider/OntapPrimaryDatastoreProvider.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/provider/OntapPrimaryDatastoreProvider.java new file mode 100644 index 000000000000..639b98506874 --- /dev/null +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/provider/OntapPrimaryDatastoreProvider.java @@ -0,0 +1,65 @@ +package org.apache.cloudstack.storage.provider; + + +import com.cloud.utils.component.ComponentContext; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; +import org.apache.cloudstack.storage.driver.OntapPrimaryDatastoreDriver; +import org.apache.cloudstack.storage.lifecycle.OntapPrimaryDatastoreLifecycle; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Logger; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@Component +public class OntapPrimaryDatastoreProvider implements PrimaryDataStoreProvider { + + private static final Logger s_logger = (Logger)LogManager.getLogger(OntapPrimaryDatastoreProvider.class); + private OntapPrimaryDatastoreDriver primaryDatastoreDriver; + private OntapPrimaryDatastoreLifecycle primaryDatastoreLifecycle; + + public OntapPrimaryDatastoreProvider() { + s_logger.info("OntapPrimaryDatastoreProvider initialized"); + } + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + return primaryDatastoreLifecycle; + } + + @Override + public DataStoreDriver getDataStoreDriver() { + return primaryDatastoreDriver; + } + + @Override + public HypervisorHostListener getHostListener() { + return null; + } + + @Override + public String getName() { + s_logger.trace("OntapPrimaryDatastoreProvider: getName: Called"); + return "ONTAP Primary Datastore Provider"; + } + + @Override + public boolean configure(Map params) { + s_logger.trace("OntapPrimaryDatastoreProvider: configure: Called"); + primaryDatastoreDriver = ComponentContext.inject(OntapPrimaryDatastoreDriver.class); + primaryDatastoreLifecycle = ComponentContext.inject(OntapPrimaryDatastoreLifecycle.class); + return true; + } + + @Override + public Set getTypes() { + s_logger.trace("OntapPrimaryDatastoreProvider: getTypes: Called"); + Set typeSet = new HashSet(); + typeSet.add(DataStoreProviderType.PRIMARY); + return typeSet; + } +} \ No newline at end of file diff --git a/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/module.properties b/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/module.properties new file mode 100644 index 000000000000..67fd086eba10 --- /dev/null +++ b/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=storage-volume-ontap +parent=storage diff --git a/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/spring-storage-volume-ontap-context.xml b/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/spring-storage-volume-ontap-context.xml new file mode 100644 index 000000000000..6ab9c46fcf9d --- /dev/null +++ b/plugins/storage/volume/ontap/src/main/resources/META-INF/cloudstack/storage-volume-ontap/spring-storage-volume-ontap-context.xml @@ -0,0 +1,33 @@ + + + + + +