Removing an old, unused NetApp plug-in

This commit is contained in:
Mike Tutkowski 2018-05-23 12:39:02 -06:00
parent 1d132d0e58
commit c7d6376964
50 changed files with 4 additions and 4353 deletions

View File

@ -1081,21 +1081,6 @@
</dependency> </dependency>
</dependencies> </dependencies>
</profile> </profile>
<profile>
<id>netapp</id>
<activation>
<property>
<name>noredist</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-netapp</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
<profile> <profile>
<id>f5</id> <id>f5</id>
<activation> <activation>

View File

@ -1,607 +0,0 @@
#!/usr/bin/env python
# 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.
import sys
import os
import subprocess
import cloudtool
import urllib2
from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
import xml.dom.minidom
NetAppServerIP=None
NetAppUserName=None
NetAppPassword=None
CloudStackSvrIP=None
CloudStackSvrPort=8096
cmds=["createvol","deletevol", "listvol", "createlun", "listlun", "destroylun", "assoclun", "disassoclun", "createpool", "modifypool", "destroypool", "listpools"]
header = "Volume Manager CLI, the available COMMANDS are:"
def cmd_help():
print header
print
print "createpool add a new pool to the system"
print "modifypool change the allocation algorithm for a pool"
print "destroypool destroy a pool"
print "listpools list all the pools"
print "createvol add volume to a storage server"
print "deletevol delete volume on a storage server"
print "listvol list volume on a storage server"
print "createlun create LUN on a storage server"
print "listlun list LUN on a storage server"
print "destroylun destroy LUN on a storage server"
print "assoclun assoc LUN on a storage server"
print "disassoclun disassoc LUN on a storage server"
print
print "\"cloudvoladm COMMAND --help\" for more information on a specific command"
print
print "Global Options:"
print "--cloudStackMgtSvrIP the IP address of CloudStack Management Server"
print
print "Config file is ~/.cloudvoladmrc, Config options including: "
print "cloudStackMgtSvrIP=Cloudstack Management Server Address, which can be overriden by --cloudStackMgtSvrIP. If neither is provided, localhost is used."
usage="Volume Manager CLI: add a new volume to a storage pool"
addvolParser= OptionParser(usage)
addvolParser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
addvolParser.add_option("-u", metavar="username", dest="username", help="username to access the storage server with")
addvolParser.add_option("-w", metavar="password", dest="password", help="the password to access the storage server with")
addvolParser.add_option("-p", dest="pool_name", help="the name of the pool to allocate from")
addvolParser.add_option("-a", dest="aggregate_name", help="the name of aggregate")
addvolParser.add_option("-v", dest="vol_name", help="the name of volume")
addvolParser.add_option("-s", dest="size", help="size in GB eg.1")
optionalGroup = OptionGroup(addvolParser, "Optional")
optionalGroup.add_option("-r", dest="percentage", help="Percentage used for snapshot reserve")
optionalGroup.add_option("-S", dest="snapshots", help="Snapshot schedule in <weeks> <days> <hours>@<which-hours> <minutes>@<which-minutes> e.g. \"2 4 5@1,4 6@2,5\"")
addvolParser.add_option_group(optionalGroup)
usage="Volume Manager CLI: remove a volume from a pool"
delvolParser= OptionParser(usage)
delvolParser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
delvolParser.add_option("-a", dest="aggregate_name", help="The name of aggregate")
delvolParser.add_option("-v", dest="vol_name", help="The name of volume")
usage="Volume Manager CLI: list all volumes known to exist in a pool"
listvolParser= OptionParser(usage)
listvolParser.add_option("-p", dest="pool_name", help="The name of the pool to list volumes from")
usage="Volume Manager CLI: create a LUN on a pool"
createlunParser = OptionParser(usage)
createlunParser.add_option("-p", dest="pool_name", help="The name of the pool to add the volume to")
createlunParser.add_option("-s", dest="size", help="The size in GB e.g. 100")
usage="Volume Manager CLI: list LUN on a pool"
listlunParser = OptionParser(usage)
listlunParser.add_option("-p", dest="pool_name", help="The pool name")
usage="Volume Manager CLI: destroy a LUN "
destroylunParser = OptionParser(usage)
destroylunParser.add_option("-l", dest="lun_name", help="The LUN name")
usage="Volume Manager CLI: Add a new pool to the system"
createPoolParser = OptionParser(usage)
createPoolParser.add_option("-p", dest="pool_name", help="The pool name")
createPoolParser.add_option("-A", dest="algorithm", help="roundrobin or leastfull")
usage="Volume Manager CLI: change the allocation algorithm for a pool"
modifyPoolParser = OptionParser(usage)
modifyPoolParser.add_option("-p", dest="pool_name", help="The pool name")
modifyPoolParser.add_option("-A", dest="algorithm", help="roundrobin or leastfull")
usage="Volume Manager CLI: destroy a pool"
destroyPoolParser = OptionParser(usage)
destroyPoolParser.add_option("-p", dest="pool_name", help="The pool name")
usage="Volume Manager CLI: list pools"
listPoolParser = OptionParser(usage)
usage="Volume Manager CLI: associate a LUN with a guest that uses the stated IQN as client"
assocLunParser = OptionParser(usage)
assocLunParser.add_option("-g", dest="guest_iqn", help="the guest IQN. By default, it reads from /etc/iscsi/initiatorname.iscsi")
assocLunParser.add_option("-l", dest="lun_name", help="The LUN name")
usage="Volume Manager CLI: disassociate a LUN with a guest that uses the stated IQN as client"
disassocLunParser = OptionParser(usage)
disassocLunParser.add_option("-g", dest="guest_iqn", help="the guest IQN. By default, it reads from /etc/iscsi/initiatorname.iscsi")
disassocLunParser.add_option("-l", dest="lun_name", help="The LUN name")
cmdParsers = {cmds[0]:addvolParser, cmds[1]:delvolParser, cmds[2]:listvolParser, cmds[3]:createlunParser, cmds[4]:listlunParser,
cmds[5]:destroylunParser, cmds[6]:assocLunParser, cmds[7]:disassocLunParser, cmds[8]:createPoolParser, cmds[9]:modifyPoolParser, cmds[10]:destroyPoolParser, cmds[11]:listPoolParser}
def validate_parameter(input, signature):
(options, args) = signature.parse_args([])
inputDict = input.__dict__
sigDict = options.__dict__
for k,v in sigDict.iteritems():
inputValue = inputDict[k]
if inputValue == None:
print "Volume Manager CLI: missing operand "
print
signature.parse_args(["--help"])
def help_callback(option, opt, value, parser):
argv = sys.argv[1:]
try:
argv.remove(opt)
except:
argv.remove("--h")
if len(argv) == 0:
cmd_help()
return
(options, args) = parser.parse_args(argv)
for cmd in cmds:
if cmd == args[0]:
cmdParsers[cmd].parse_args(["--help"])
def Help():
usage = "usage: %prog cmd[createpool|listpools|modifypool|destroypool|createvol|deletevol|listvol|createlun|listlun|destroylun|assoclun|disassoclun] arg1 arg2 [--help, -h]"
parser = OptionParser(usage=usage, add_help_option=False)
parser.add_option("-h", "--help", action="callback", callback=help_callback);
parser.add_option("-i", metavar="server ip", dest="server_ip", help="The IP address of the storage server")
parser.add_option("--cloudstackSvr", dest="cloudstackSvr", help="cloudStack Server IP")
parser.add_option("-u", metavar="username", dest="username", help="username to access the storage server with")
parser.add_option("-w", metavar="password", dest="password", help="the password to access the storage server with")
parser.add_option("-p", dest="pool_name", help="the name of the pool to allocate from")
parser.add_option("-v", dest="vol_name", help="the name of volume")
parser.add_option("-A", dest="algorithm", help="roundrobin or leastfull")
parser.add_option("-a", dest="aggregate_name", help="The name of aggregate")
parser.add_option("-o", dest="options", help="requested option string for the NFS export or attach")
parser.add_option("-S", dest="snapshots", help="Snapshot schedule e.g.2 4 5@1,4 6@2,5")
parser.add_option("-r", dest="percentage", help="Percentage used for snapshot reservation")
parser.add_option("-s", dest="size", help="size in GB eg.1")
parser.add_option("-t", dest="target_iqn", help="the target IQN")
parser.add_option("-g", dest="guest_iqn", help="the guest IQN")
parser.add_option("-l", dest="lun_name", help="the LUN name")
return parser
def httpErrorHandler(code, msg):
try:
errtext = xml.dom.minidom.parseString(msg)
if errtext.getElementsByTagName("errortext") is not None:
err = getText(errtext.getElementsByTagName("errortext")[0].childNodes).strip()
print err
except:
print "Internal Error %s"%msg
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE: rc.append(node.data)
return ''.join(rc)
def createvol(options):
args = []
if options.pool_name == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if options.aggregate_name == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if options.vol_name == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if options.snapshots != None:
args += ['--snapshotpolicy=' + options.snapshots]
if options.size == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if options.percentage != None:
args += ['--snapshotreservation=' + options.percentage]
if NetAppServerIP == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if NetAppUserName == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
if NetAppPassword == None:
print "Volume Manager CLI: missing operand "
print
addvolParser.parse_args(["--help"])
'''
snapshot = options.snapshots
tokens = snapshot.split(" ")
print tokens
pos = 0;
for token in tokens:
if pos == 0:
#week
try:
week = int(token)
if week < 0:
raise
except:
print "Pls input correct week"
sys.exit(1)
elif pos == 1:
try:
day = int(token)
if day < 0:
raise
except:
print "Pls input correct day"
sys.exit(1)
elif pos == 2:
try:
hours = token.split("@")
if int(hours[0]) < 0:
raise
hourlists = hours[1].split(",")
for hour in hourlists:
if int(hour) < 0 or int(hour) > 24:
raise
except:
print "Pls input correct hour"
sys.exit(1)
elif pos == 3:
try:
minutes = token.split("@")
if int(minutes[0]) < 0:
raise
minuteslist = minutes[1].split(",")
for minute in minuteslist:
if int(minute) < 0 or int(minute) > 60:
raise
except:
print "Pls input correct hour"
sys.exit(1)
'''
try:
output = cloudtool.main(['cloud-tool', 'createVolumeOnFiler', '--ipaddress=' + NetAppServerIP , '--aggregatename=' + options.aggregate_name,
'--poolname=' + options.pool_name, '--volumename=' + options.vol_name,
'--size=' + options.size,
'--username=' + NetAppUserName, '--password=' + NetAppPassword, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"] + args)
print "Successfully added volume"
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing createvol cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing createvol cmd failed: %s" % (err.reason)
sys.exit(1)
def deletevol(options):
validate_parameter(options, delvolParser)
try:
output = cloudtool.main(['cloud-tool', 'destroyVolumeOnFiler', '--ipaddress=' + NetAppServerIP, '--aggregatename=' + options.aggregate_name,
'--volumename=' + options.vol_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully deleted volume"
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing deletevol cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing deletevol cmd failed: %s" % (err.reason)
sys.exit(1)
def listvol(options):
validate_parameter(options, listvolParser)
try:
output = cloudtool.main(['cloud-tool', 'listVolumesOnFiler', '--poolname=' + options.pool_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"]).strip("\n")
xmlResult = xml.dom.minidom.parseString(output)
print "%-10s %-20s %-20s %-40s %-20s %-30s "%('Id', 'Address', 'Aggregate', 'Volume', 'Size(GB)', 'snapshotPolicy', )
for volume in xmlResult.getElementsByTagName("volume"):
aggregatename = getText(volume.getElementsByTagName('aggregatename')[0].childNodes).strip()
id = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
volumeName = getText(volume.getElementsByTagName('volumename')[0].childNodes).strip()
snapshotPolicy = getText(volume.getElementsByTagName('snapshotpolicy')[0].childNodes).strip()
ipaddress = getText(volume.getElementsByTagName('ipaddress')[0].childNodes).strip()
volSize = getText(volume.getElementsByTagName('size')[0].childNodes).strip()
print "%-10s %-20s %-20s %-40s %-20s %-30s "%(id, ipaddress, aggregatename, volumeName, volSize, snapshotPolicy)
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing listvol cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing listvol cmd failed: %s" % (err.reason)
sys.exit(1)
def createlun(options):
validate_parameter(options, createlunParser)
try:
output = cloudtool.main(['cloud-tool', 'createLunOnFiler', '--name=' + options.pool_name,
'--size=' + options.size, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
xmlResult = xml.dom.minidom.parseString(output.strip("\n"))
path = getText(xmlResult.getElementsByTagName("path")[0].childNodes).strip()
iqn = getText(xmlResult.getElementsByTagName("iqn")[0].childNodes).strip()
ipAddr = getText(xmlResult.getElementsByTagName('ipaddress')[0].childNodes).strip()
print "%-30s %-30s %-50s "%('LUN Name', 'Address', 'Target IQN')
print "%-30s %-30s %-50s "%(path, ipAddr, iqn)
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing createlun cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing createlun cmd failed: %s" % (err.reason)
sys.exit(1)
def listlun(options):
validate_parameter(options, listlunParser)
args = ["--poolname=" + options.pool_name, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"]
try:
output = cloudtool.main(['cloud-tool', 'listLunsOnFiler'] + args).strip("\n")
xmlResult = xml.dom.minidom.parseString(output)
print "%-10s %-10s %-50s %-30s "%('LUN Id', 'Volume Id', 'Target IQN', 'LUN Name')
for volume in xmlResult.getElementsByTagName("lun"):
uuid = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
path = getText(volume.getElementsByTagName('name')[0].childNodes).strip()
targetiqn = getText(volume.getElementsByTagName('iqn')[0].childNodes).strip()
volumeId = getText(volume.getElementsByTagName('volumeid')[0].childNodes).strip()
print "%-10s %-10s %-50s %-30s "%(uuid, volumeId, targetiqn, path)
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing listlun cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing listlun cmd failed: %s" % (err.reason)
sys.exit(1)
def destroylun(options):
validate_parameter(options, destroylunParser)
try:
output = cloudtool.main(['cloud-tool', 'destroyLunOnFiler', '--path=' + options.lun_name,
"--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully destroyed LUN"
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing destroylun cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing destroylun failed: %s" % (err.reason)
sys.exit(1)
def assoclun(options):
validate_parameter(options, assocLunParser)
try:
output = cloudtool.main(['cloud-tool', 'associateLun', '--name=' + options.lun_name,
'--iqn=' + options.guest_iqn, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
xmlResult = xml.dom.minidom.parseString(output.strip("\n"))
lunid = getText(xmlResult.getElementsByTagName("id")[0].childNodes).strip()
iqn = getText(xmlResult.getElementsByTagName("targetiqn")[0].childNodes).strip()
ipAddr = getText(xmlResult.getElementsByTagName('ipaddress')[0].childNodes).strip()
print "%-30s %-30s %-50s "%('LUN Id', 'Address', 'Target IQN')
print "%-30s %-30s %-50s" % (lunid, ipAddr, iqn)
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing assoclun cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing assoclun failed: %s" % (err.reason)
sys.exit(1)
def disassoclun(options):
validate_parameter(options, disassocLunParser)
try:
output = cloudtool.main(['cloud-tool', 'dissociateLun', '--path=' + options.lun_name,
'--iqn=' + options.guest_iqn, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully dissociated LUN"
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing disassoclun cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing disassoclun failed: %s" % (err.reason)
sys.exit(1)
def createpool(options):
validate_parameter(options, createPoolParser)
if not (options.algorithm == "roundrobin" or options.algorithm == "leastfull"):
print "Only roundrobin or leastfull algorithm is supported"
sys.exit(1)
try:
output = cloudtool.main(['cloud-tool', 'createPool', '--name=' + options.pool_name,
'--algorithm=' + options.algorithm, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully created pool"
except urllib2.HTTPError, err:
code = err.code
print "executing createpool cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, err.read())
sys.exit(1)
except urllib2.URLError, err:
print "executing createpool failed: %s" % (err.reason)
sys.exit(1)
def listpools(options):
try:
output = cloudtool.main(['cloud-tool', 'listPools',
"--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
output = output.strip("\n")
xmlResult = xml.dom.minidom.parseString(output)
print "%-10s %-40s %-10s" %('Id', 'Pool Name', 'Algorithm')
for volume in xmlResult.getElementsByTagName("pool"):
id = getText(volume.getElementsByTagName('id')[0].childNodes).strip()
poolname = getText(volume.getElementsByTagName('name')[0].childNodes).strip()
alg = getText(volume.getElementsByTagName('algorithm')[0].childNodes).strip()
print "%-10s %-40s %-10s"%(id, poolname, alg)
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing listpools cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing listpools failed, due to: %s" % (err.reason)
sys.exit(1)
def modifypool(options):
validate_parameter(options, modifyPoolParser)
try:
output = cloudtool.main(['cloud-tool', 'modifyPool', '--poolname=' + options.pool_name,
'--algorithm=' + options.algorithm, "--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully modified pool"
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing modifypool cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing modifypool failed, due to: %s" % (err.reason)
sys.exit(1)
def destroypool(options):
validate_parameter(options, destroyPoolParser)
try:
output = cloudtool.main(['cloud-tool', 'deletePool', '--poolname=' + options.pool_name,
"--server=" + CloudStackSvrIP + ":" + str(CloudStackSvrPort), "--stripxml=false"])
print "Successfully destroyed pool: " + options.pool_name
except urllib2.HTTPError, err:
code = err.code
msg = err.read()
print "executing destroypool cmd failed, http returning error code: %s" % (code)
httpErrorHandler(code, msg)
sys.exit(1)
except urllib2.URLError, err:
print "executing destroypool failed, due to: %s" % (err.reason)
sys.exit(1)
def loadCfgFile():
options = dict()
try:
cfgFile = open(os.environ['HOME'] + "/.cloudvoladmrc")
for line in cfgFile:
option = line.split("=")
if option[0] == "cloudStackMgtSvrIP":
options["cloudStackMgtSvrIP"] = option[1].strip("\n")
except:
return None
return options
def getGuestIQN():
try:
initialFile = open("/etc/iscsi/initiatorname.iscsi")
for line in initialFile:
iqn = line.split("=")
if iqn[0] == "InitiatorName":
return iqn[1].strip("\n")
except:
return None
return None
if __name__ == '__main__':
parser = Help()
(options, args) = parser.parse_args()
globalCfg = loadCfgFile()
NetAppServerIP= options.server_ip
NetAppUserName = options.username
NetAppPassword = options.password
CloudStackSvrIP = options.cloudstackSvr
if CloudStackSvrIP == None:
if globalCfg != None and "cloudStackMgtSvrIP" in globalCfg:
CloudStackSvrIP = globalCfg["cloudStackMgtSvrIP"]
if CloudStackSvrIP == None:
CloudStackSvrIP = "127.0.0.1"
if options.guest_iqn == None:
GuestIQN = getGuestIQN()
options.__dict__["guest_iqn"] = GuestIQN
if len(args) == 0:
sys.exit(1)
cmd = args[0]
if cmd == "createvol":
createvol(options)
elif cmd == "deletevol":
deletevol(options)
elif cmd == "listvol":
listvol(options)
elif cmd == "createlun":
createlun(options)
elif cmd == "listlun":
listlun(options)
elif cmd == "destroylun":
destroylun(options)
elif cmd == "assoclun":
assoclun(options)
elif cmd == "disassoclun":
disassoclun(options)
elif cmd == "createpool":
createpool(options)
elif cmd == "modifypool":
modifypool(options)
elif cmd == "destroypool":
destroypool(options)
elif cmd == "listpools":
listpools(options)
else:
print "Unrecoginzied command"
cmd_help()
sys.exit(1)

View File

@ -24,11 +24,6 @@ mvn install:install-file -Dfile=cloud-iControl.jar -DgroupId=com.cloud.com.
# Version: unknown # Version: unknown
mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx -Dversion=1.0 -Dpackaging=jar mvn install:install-file -Dfile=cloud-netscaler-sdx.jar -DgroupId=com.cloud.com.citrix -DartifactId=netscaler-sdx -Dversion=1.0 -Dpackaging=jar
# From http://support.netapp.com/ (not available online, contact your support representative)
# Version: 4.0
if [ -e cloud-manageontap.jar ]; then mv cloud-manageontap.jar manageontap.jar; fi
mvn install:install-file -Dfile=manageontap.jar -DgroupId=com.cloud.com.netapp -DartifactId=manageontap -Dversion=4.0 -Dpackaging=jar
# From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSP510-WEBSDK-510 # From https://my.vmware.com/group/vmware/get-download?downloadGroup=VSP510-WEBSDK-510
# Version: 5.1, Release-date: 2012-09-10, Build: 774886 # Version: 5.1, Release-date: 2012-09-10, Build: 774886
mvn install:install-file -Dfile=vim25_51.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=5.1 -Dpackaging=jar mvn install:install-file -Dfile=vim25_51.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25 -Dversion=5.1 -Dpackaging=jar

View File

@ -91,16 +91,6 @@ public class Upgrade2213to2214 implements DbUpgrade {
throw new CloudRuntimeException("Unable to execute cloud_usage usage_event table update", e); throw new CloudRuntimeException("Unable to execute cloud_usage usage_event table update", e);
} }
//Drop netapp_volume primary key and add it again
DbUpgradeUtils.dropPrimaryKeyIfExists(conn, "cloud.netapp_volume");
try {
PreparedStatement pstmt = conn.prepareStatement("ALTER TABLE `cloud`.`netapp_volume` add PRIMARY KEY (`id`)");
pstmt.executeUpdate();
pstmt.close();
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to update primary key for netapp_volume", e);
}
//Drop i_snapshots__removed key (if exists) and re-add it again //Drop i_snapshots__removed key (if exists) and re-add it again
keys = new ArrayList<String>(); keys = new ArrayList<String>();
keys.add("i_snapshots__removed"); keys.add("i_snapshots__removed");

View File

@ -18,45 +18,6 @@
--; --;
-- Schema upgrade from 2.2.7 to 2.2.8; -- Schema upgrade from 2.2.7 to 2.2.8;
--; --;
CREATE TABLE IF NOT EXISTS `cloud`.`netapp_pool` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`name` varchar(255) NOT NULL UNIQUE COMMENT 'name for the pool',
`algorithm` varchar(255) NOT NULL COMMENT 'algorithm',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud`.`netapp_volume` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`ip_address` varchar(255) NOT NULL COMMENT 'ip address/fqdn of the volume',
`pool_id` bigint unsigned NOT NULL COMMENT 'id for the pool',
`pool_name` varchar(255) NOT NULL COMMENT 'name for the pool',
`aggregate_name` varchar(255) NOT NULL COMMENT 'name for the aggregate',
`volume_name` varchar(255) NOT NULL COMMENT 'name for the volume',
`volume_size` varchar(255) NOT NULL COMMENT 'volume size',
`snapshot_policy` varchar(255) NOT NULL COMMENT 'snapshot policy',
`snapshot_reservation` int NOT NULL COMMENT 'snapshot reservation',
`username` varchar(255) NOT NULL COMMENT 'username',
`password` varchar(200) COMMENT 'password',
`round_robin_marker` int COMMENT 'This marks the volume to be picked up for lun creation, RR fashion',
PRIMARY KEY (`ip_address`,`aggregate_name`,`volume_name`),
CONSTRAINT `fk_netapp_volume__pool_id` FOREIGN KEY `fk_netapp_volume__pool_id` (`pool_id`) REFERENCES `netapp_pool` (`id`) ON DELETE CASCADE,
INDEX `i_netapp_volume__pool_id`(`pool_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud`.`netapp_lun` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`lun_name` varchar(255) NOT NULL COMMENT 'lun name',
`target_iqn` varchar(255) NOT NULL COMMENT 'target iqn',
`path` varchar(255) NOT NULL COMMENT 'lun path',
`size` bigint NOT NULL COMMENT 'lun size',
`volume_id` bigint unsigned NOT NULL COMMENT 'parent volume id',
PRIMARY KEY (`id`),
CONSTRAINT `fk_netapp_lun__volume_id` FOREIGN KEY `fk_netapp_lun__volume_id` (`volume_id`) REFERENCES `netapp_volume` (`id`) ON DELETE CASCADE,
INDEX `i_netapp_lun__volume_id`(`volume_id`),
INDEX `i_netapp_lun__lun_name`(`lun_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--; --;
-- Cleanup usage records for bug # 10727; -- Cleanup usage records for bug # 10727;

View File

@ -47,9 +47,6 @@ ALTER TABLE `cloud`.`iam_policy` DROP INDEX `id` ;
ALTER TABLE `cloud`.`iam_policy_permission` DROP INDEX `id` ; ALTER TABLE `cloud`.`iam_policy_permission` DROP INDEX `id` ;
ALTER TABLE `cloud`.`image_store_details` DROP INDEX `id` ; ALTER TABLE `cloud`.`image_store_details` DROP INDEX `id` ;
ALTER TABLE `cloud`.`instance_group` DROP INDEX `id` ; ALTER TABLE `cloud`.`instance_group` DROP INDEX `id` ;
ALTER TABLE `cloud`.`netapp_lun` DROP INDEX `id` ;
ALTER TABLE `cloud`.`netapp_pool` DROP INDEX `id` ;
ALTER TABLE `cloud`.`netapp_volume` DROP INDEX `id` ;
ALTER TABLE `cloud`.`network_acl_item_cidrs` DROP INDEX `id` ; ALTER TABLE `cloud`.`network_acl_item_cidrs` DROP INDEX `id` ;
ALTER TABLE `cloud`.`network_offerings` DROP INDEX `id` ; ALTER TABLE `cloud`.`network_offerings` DROP INDEX `id` ;
ALTER TABLE `cloud`.`nic_secondary_ips` DROP INDEX `id` ; ALTER TABLE `cloud`.`nic_secondary_ips` DROP INDEX `id` ;

View File

@ -1,36 +0,0 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-netapp</artifactId>
<name>Apache CloudStack Plugin - NetApp File System</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.12.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.cloud.com.netapp</groupId>
<artifactId>manageontap</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
</project>

View File

@ -1,102 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.AssociateLunCmdResponse;
@APICommand(name = "associateLun", description = "Associate a LUN with a guest IQN", responseObject = AssociateLunCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class AssociateLunCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AssociateLunCmd.class.getName());
private static final String s_name = "associatelunresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "LUN name.")
private String lunName;
@Parameter(name = ApiConstants.IQN, type = CommandType.STRING, required = true, description = "Guest IQN to which the LUN associate.")
private String guestIqn;
///////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public String getLunName() {
return lunName;
}
public String getGuestIQN() {
return guestIqn;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Inject
NetappManager netappMgr;
@Override
public void execute() {
try {
AssociateLunCmdResponse response = new AssociateLunCmdResponse();
String returnVals[] = null;
returnVals = netappMgr.associateLun(getGuestIQN(), getLunName());
response.setLun(returnVals[0]);
response.setIpAddress(returnVals[2]);
response.setTargetIQN(returnVals[1]);
response.setObjectName("lun");
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,101 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.CreateLunCmdResponse;
@APICommand(name = "createLunOnFiler", description = "Create a LUN from a pool", responseObject = CreateLunCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateLunCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateLunCmd.class.getName());
private static final String s_name = "createlunresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = true, description = "LUN size.")
private long size;
public String getPoolName() {
return poolName;
}
public long getLunSize() {
return size;
}
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
CreateLunCmdResponse response = new CreateLunCmdResponse();
String returnVals[] = null;
returnVals = netappMgr.createLunOnFiler(getPoolName(), getLunSize());
response.setPath(returnVals[0]);
response.setIqn(returnVals[1]);
response.setIpAddress(returnVals[2]);
response.setObjectName("lun");
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,147 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.net.UnknownHostException;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.CreateVolumeOnFilerCmdResponse;
@APICommand(name = "createVolumeOnFiler", description = "Create a volume", responseObject = CreateVolumeOnFilerCmdResponse.class,
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
public class CreateVolumeOnFilerCmd extends BaseCmd {
private static final String s_name = "createvolumeresponse";
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true, description = "ip address.")
private String ipAddress;
@Parameter(name = ApiConstants.AGGREGATE_NAME, type = CommandType.STRING, required = true, description = "aggregate name.")
private String aggrName;
@Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Parameter(name = ApiConstants.VOLUME_NAME, type = CommandType.STRING, required = true, description = "volume name.")
private String volName;
@Parameter(name = ApiConstants.SIZE, type = CommandType.INTEGER, required = true, description = "volume size.")
private Integer volSize;
@Parameter(name = ApiConstants.SNAPSHOT_POLICY, type = CommandType.STRING, required = false, description = "snapshot policy.")
private String snapshotPolicy;
@Parameter(name = ApiConstants.SNAPSHOT_RESERVATION, type = CommandType.INTEGER, required = false, description = "snapshot reservation.")
private Integer snapshotReservation;
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "user name.")
private String userName;
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = true, description = "password.")
private String password;
public String getIpAddress() {
return ipAddress;
}
public String getAggrName() {
return aggrName;
}
public String getPoolName() {
return poolName;
}
public String volName() {
return volName;
}
public Integer getVolSize() {
return volSize;
}
public String getSnapshotPolicy() {
return snapshotPolicy;
}
public Integer getSnapshotReservation() {
return snapshotReservation;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
//param checks
if (snapshotReservation != null && (snapshotReservation < 0 || snapshotReservation > 100))
throw new InvalidParameterValueException("Invalid snapshot reservation");
StringBuilder s = new StringBuilder(getVolSize().toString());
s.append("g");
try {
netappMgr.createVolumeOnFiler(ipAddress, aggrName, poolName, volName, s.toString(), snapshotPolicy, snapshotReservation, userName, password);
CreateVolumeOnFilerCmdResponse response = new CreateVolumeOnFilerCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (UnknownHostException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,87 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.CreateVolumePoolCmdResponse;
@APICommand(name = "createPool", description = "Create a pool", responseObject = CreateVolumePoolCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class CreateVolumePoolCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(CreateVolumePoolCmd.class.getName());
private static final String s_name = "createpoolresponse";
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Parameter(name = ApiConstants.ALGORITHM, type = CommandType.STRING, required = true, description = "algorithm.")
private String algorithm;
public String getPoolName() {
return poolName;
}
public String getAlgorithm() {
return algorithm;
}
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
CreateVolumePoolCmdResponse response = new CreateVolumePoolCmdResponse();
netappMgr.createPool(getPoolName(), getAlgorithm());
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,78 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.DeleteVolumePoolCmdResponse;
@APICommand(name = "deletePool", description = "Delete a pool", responseObject = DeleteVolumePoolCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DeleteVolumePoolCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteVolumePoolCmd.class.getName());
private static final String s_name = "deletepoolresponse";
@Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
netappMgr.deletePool(poolName);
DeleteVolumePoolCmdResponse response = new DeleteVolumePoolCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (ResourceInUseException e) {
throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,80 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.DeleteLUNCmdResponse;
@APICommand(name = "destroyLunOnFiler", description = "Destroy a LUN", responseObject = DeleteLUNCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DestroyLunCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DestroyLunCmd.class.getName());
private static final String s_name = "destroylunresponse";
@Parameter(name = ApiConstants.PATH, type = CommandType.STRING, required = true, description = "LUN path.")
private String path;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
netappMgr.destroyLunOnFiler(path);
DeleteLUNCmdResponse response = new DeleteLUNCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,89 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.DeleteVolumeOnFilerCmdResponse;
@APICommand(name = "destroyVolumeOnFiler", description = "Destroy a Volume", responseObject = DeleteVolumeOnFilerCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DestroyVolumeOnFilerCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DestroyVolumeOnFilerCmd.class.getName());
private static final String s_name = "destroyvolumeresponse";
@Parameter(name = ApiConstants.AGGREGATE_NAME, type = CommandType.STRING, required = true, description = "aggregate name.")
private String aggrName;
@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true, description = "ip address.")
private String ipAddr;
@Parameter(name = ApiConstants.VOLUME_NAME, type = CommandType.STRING, required = true, description = "volume name.")
private String volumeName;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
netappMgr.destroyVolumeOnFiler(ipAddr, aggrName, volumeName);
DeleteVolumeOnFilerCmdResponse response = new DeleteVolumeOnFilerCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (ResourceInUseException e) {
throw new ServerApiException(ApiErrorCode.RESOURCE_IN_USE_ERROR, e.toString());
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,82 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.rmi.ServerException;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.DissociateLunCmdResponse;
@APICommand(name = "dissociateLun", description = "Dissociate a LUN", responseObject = DissociateLunCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class DissociateLunCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DissociateLunCmd.class.getName());
private static final String s_name = "dissociatelunresponse";
@Parameter(name = ApiConstants.PATH, type = CommandType.STRING, required = true, description = "LUN path.")
private String path;
@Parameter(name = ApiConstants.IQN, type = CommandType.STRING, required = true, description = "Guest IQN.")
private String guestIQN;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
netappMgr.disassociateLun(guestIQN, path);
DissociateLunCmdResponse response = new DissociateLunCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
} catch (ServerException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,90 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ListResponse;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.LunVO;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.ListLunsCmdResponse;
@APICommand(name = "listLunsOnFiler", description = "List LUN", responseObject = ListLunsCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListLunsCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ListLunsCmd.class.getName());
private static final String s_name = "listlunresponse";
@Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
List<LunVO> lunList = netappMgr.listLunsOnFiler(poolName);
ListResponse<ListLunsCmdResponse> listResponse = new ListResponse<ListLunsCmdResponse>();
List<ListLunsCmdResponse> responses = new ArrayList<ListLunsCmdResponse>();
for (LunVO lun : lunList) {
ListLunsCmdResponse response = new ListLunsCmdResponse();
response.setId(lun.getId());
response.setIqn(lun.getTargetIqn());
response.setName(lun.getLunName());
response.setVolumeId(lun.getVolumeId());
response.setObjectName("lun");
responses.add(response);
}
listResponse.setResponses(responses);
listResponse.setResponseName(getCommandName());
this.setResponseObject(listResponse);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,86 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ListResponse;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.netapp.PoolVO;
import com.cloud.server.api.response.netapp.ListVolumePoolsCmdResponse;
@APICommand(name = "listPools", description = "List Pool", responseObject = ListVolumePoolsCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListVolumePoolsCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ListVolumePoolsCmd.class.getName());
private static final String s_name = "listpoolresponse";
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
List<PoolVO> poolList = netappMgr.listPools();
ListResponse<ListVolumePoolsCmdResponse> listResponse = new ListResponse<ListVolumePoolsCmdResponse>();
List<ListVolumePoolsCmdResponse> responses = new ArrayList<ListVolumePoolsCmdResponse>();
for (PoolVO pool : poolList) {
ListVolumePoolsCmdResponse response = new ListVolumePoolsCmdResponse();
response.setId(pool.getId());
response.setName(pool.getName());
response.setAlgorithm(pool.getAlgorithm());
response.setObjectName("pool");
responses.add(response);
}
listResponse.setResponses(responses);
listResponse.setResponseName(getCommandName());
this.setResponseObject(listResponse);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,96 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ListResponse;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.netapp.NetappVolumeVO;
import com.cloud.server.api.response.netapp.ListVolumesOnFilerCmdResponse;
@APICommand(name = "listVolumesOnFiler", description = "List Volumes", responseObject = ListVolumesOnFilerCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ListVolumesOnFilerCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ListVolumesOnFilerCmd.class.getName());
private static final String s_name = "listvolumesresponse";
@Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
try {
List<NetappVolumeVO> volumes = netappMgr.listVolumesOnFiler(poolName);
ListResponse<ListVolumesOnFilerCmdResponse> listResponse = new ListResponse<ListVolumesOnFilerCmdResponse>();
List<ListVolumesOnFilerCmdResponse> responses = new ArrayList<ListVolumesOnFilerCmdResponse>();
for (NetappVolumeVO volume : volumes) {
ListVolumesOnFilerCmdResponse response = new ListVolumesOnFilerCmdResponse();
response.setId(volume.getId());
response.setIpAddress(volume.getIpAddress());
response.setPoolName(volume.getPoolName());
response.setAggrName(volume.getAggregateName());
response.setVolumeName(volume.getVolumeName());
response.setSnapshotPolicy(volume.getSnapshotPolicy());
response.setSnapshotReservation(volume.getSnapshotReservation());
response.setVolumeSize(volume.getVolumeSize());
response.setObjectName("volume");
responses.add(response);
}
listResponse.setResponses(responses);
listResponse.setResponseName(getCommandName());
this.setResponseObject(listResponse);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
}
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,73 +0,0 @@
// 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.
package com.cloud.api.commands.netapp;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.netapp.NetappManager;
import com.cloud.server.api.response.netapp.ModifyVolumePoolCmdResponse;
@APICommand(name = "modifyPool", description = "Modify pool", responseObject = ModifyVolumePoolCmdResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class ModifyVolumePoolCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(ModifyVolumePoolCmd.class.getName());
private static final String s_name = "modifypoolresponse";
@Parameter(name = ApiConstants.POOL_NAME, type = CommandType.STRING, required = true, description = "pool name.")
private String poolName;
@Parameter(name = ApiConstants.ALGORITHM, type = CommandType.STRING, required = true, description = "algorithm.")
private String algorithm;
@Inject
NetappManager netappMgr;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException {
netappMgr.modifyPool(poolName, algorithm);
ModifyVolumePoolCmdResponse response = new ModifyVolumePoolCmdResponse();
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public String getCommandName() {
// TODO Auto-generated method stub
return s_name;
}
@Override
public long getEntityOwnerId() {
// TODO Auto-generated method stub
return 0;
}
}

View File

@ -1,122 +0,0 @@
// 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.
package com.cloud.netapp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name = "netapp_lun")
public class LunVO implements InternalIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "lun_name")
private String lunName;
@Column(name = "target_iqn")
private String targetIqn;
@Column(name = "path")
private String path;
@Column(name = "volume_id")
private Long volumeId;
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
@Column(name = "size")
private Long size;
public LunVO() {
}
public LunVO(String path, Long volumeId, Long size, String lunName, String targetIqn) {
this.path = path;
this.volumeId = volumeId;
this.size = size;
this.lunName = lunName;
this.targetIqn = targetIqn;
}
public String getLunName() {
return lunName;
}
public void setLunName(String lunName) {
this.lunName = lunName;
}
public LunVO(Long id, String path, Long volumeId, Long size, String lunName, String targetIqn) {
this.id = id;
this.path = path;
this.volumeId = volumeId;
this.size = size;
this.lunName = lunName;
this.targetIqn = targetIqn;
}
@Override
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public Long getVolumeId() {
return volumeId;
}
public void setVolumeId(Long volumeId) {
this.volumeId = volumeId;
}
public void setTargetIqn(String iqn) {
this.targetIqn = iqn;
}
public String getTargetIqn() {
return targetIqn;
}
}

View File

@ -1,24 +0,0 @@
// 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.
package com.cloud.netapp;
public interface NetappAllocator {
public NetappVolumeVO chooseVolumeFromPool(String poolName, long lunSizeGb);
public NetappVolumeVO chooseLeastFullVolumeFromPool(String poolName, long lunSizeGb);
}

View File

@ -1,124 +0,0 @@
// 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.
package com.cloud.netapp;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger;
public class NetappDefaultAllocatorImpl implements NetappAllocator {
private static HashMap<String, Integer> s_poolNameToLastVolumeIdAllocated = new HashMap<String, Integer>();
private final NetappManager _netappMgr;
public static final Logger s_logger = Logger.getLogger(NetappDefaultAllocatorImpl.class.getName());
public NetappDefaultAllocatorImpl(NetappManager netappMgr) {
_netappMgr = netappMgr;
}
@Override
public synchronized NetappVolumeVO chooseLeastFullVolumeFromPool(String poolName, long lunSizeGb) {
List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName);
if (volumesOnPoolAscending == null) {
//no pools exist in db
return null;
}
long maxAvailable = 0;
NetappVolumeVO selectedVol = null;
for (NetappVolumeVO vol : volumesOnPoolAscending) {
try {
long availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress());
if (lunSizeGb <= bytesToGb(availableBytes) && availableBytes > maxAvailable) {
maxAvailable = availableBytes; //new max
selectedVol = vol; //new least loaded vol
}
} catch (ServerException se) {
s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName());
continue;
}
}
return selectedVol;
}
/**
* This method does the actual round robin allocation
* @param poolName
* @param lunSizeGb
* @return -- the selected volume to create the lun on
*/
@Override
public synchronized NetappVolumeVO chooseVolumeFromPool(String poolName, long lunSizeGb) {
int pos = 0; //0 by default
List<NetappVolumeVO> volumesOnPoolAscending = _netappMgr.listVolumesAscending(poolName);
if (volumesOnPoolAscending == null) {
//no pools exist in db
return null;
}
//get the index of the record from the map
if (s_poolNameToLastVolumeIdAllocated.get(poolName) == null) {
pos = 0;
} else {
pos = s_poolNameToLastVolumeIdAllocated.get(poolName);
}
//update for RR effect
s_poolNameToLastVolumeIdAllocated.put(poolName, (pos + 1) % volumesOnPoolAscending.size());
//now iterate over the records
Object[] volumesOnPoolAscendingArray = volumesOnPoolAscending.toArray();
int counter = 0;
while (counter < volumesOnPoolAscendingArray.length) {
NetappVolumeVO vol = (NetappVolumeVO)volumesOnPoolAscendingArray[pos];
//check if the volume fits the bill
long availableBytes;
try {
availableBytes = _netappMgr.returnAvailableVolumeSize(vol.getVolumeName(), vol.getUsername(), vol.getPassword(), vol.getIpAddress());
if (lunSizeGb <= bytesToGb(availableBytes)) {
//found one
return vol;
}
pos = (pos + 1) % volumesOnPoolAscendingArray.length;
counter++;
} catch (ServerException e) {
s_logger.debug("Ignoring failure to obtain volume size for volume " + vol.getVolumeName());
continue;
}
}
return null;
}
/**
* This method does the byte to gb conversion
* @param bytes
* @return -- converted gb
*/
private long bytesToGb(long bytes) {
long returnVal = (bytes / (1024 * 1024 * 1024));
return returnVal;
}
}

View File

@ -1,63 +0,0 @@
// 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.
package com.cloud.netapp;
import java.net.UnknownHostException;
import java.rmi.ServerException;
import java.util.List;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.PluggableService;
public interface NetappManager extends Manager, PluggableService {
enum AlgorithmType {
RoundRobin, LeastFull
}
void destroyVolumeOnFiler(String ipAddress, String aggrName, String volName) throws ServerException, InvalidParameterValueException, ResourceInUseException;
void createVolumeOnFiler(String ipAddress, String aggName, String poolName, String volName, String volSize, String snapshotPolicy, Integer snapshotReservation,
String username, String password) throws UnknownHostException, ServerException, InvalidParameterValueException;
public String[] associateLun(String guestIqn, String path) throws ServerException, InvalidParameterValueException;
void disassociateLun(String iGroup, String path) throws ServerException, InvalidParameterValueException;
List<LunVO> listLunsOnFiler(String poolName);
void destroyLunOnFiler(String path) throws ServerException, InvalidParameterValueException;
List<NetappVolumeVO> listVolumesOnFiler(String poolName);
List<NetappVolumeVO> listVolumesAscending(String poolName);
long returnAvailableVolumeSize(String volName, String userName, String password, String serverIp) throws ServerException;
void createPool(String poolName, String algorithm) throws InvalidParameterValueException;
void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException;
void deletePool(String poolName) throws InvalidParameterValueException, ResourceInUseException;
List<PoolVO> listPools();
public String[] createLunOnFiler(String poolName, Long lunSize) throws InvalidParameterValueException, ServerException, ResourceAllocationException;
}

View File

@ -1,186 +0,0 @@
// 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.
package com.cloud.netapp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name = "netapp_volume")
public class NetappVolumeVO implements InternalIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "ip_address")
private String ipAddress;
@Column(name = "aggregate_name")
private String aggregateName;
@Column(name = "pool_id")
private Long poolId;
@Column(name = "pool_name")
private String poolName;
@Column(name = "volume_name")
private String volumeName;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "snapshot_policy")
private String snapshotPolicy;
@Column(name = "snapshot_reservation")
private Integer snapshotReservation;
@Column(name = "volume_size")
private String volumeSize;
@Column(name = "round_robin_marker")
private int roundRobinMarker;
public NetappVolumeVO() {
}
public NetappVolumeVO(String ipAddress, String aggName, Long poolId, String volName, String volSize, String snapshotPolicy, int snapshotReservation, String username,
String password, int roundRobinMarker, String poolName) {
this.ipAddress = ipAddress;
this.aggregateName = aggName;
this.poolId = poolId;
this.username = username;
this.password = password;
this.volumeName = volName;
this.volumeSize = volSize;
this.snapshotPolicy = snapshotPolicy;
this.snapshotReservation = snapshotReservation;
this.roundRobinMarker = roundRobinMarker;
this.poolName = poolName;
}
public String getPoolName() {
return poolName;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public int getRoundRobinMarker() {
return roundRobinMarker;
}
public void setRoundRobinMarker(int roundRobinMarker) {
this.roundRobinMarker = roundRobinMarker;
}
public String getVolumeName() {
return volumeName;
}
public void setVolumeName(String volumeName) {
this.volumeName = volumeName;
}
public String getSnapshotPolicy() {
return snapshotPolicy;
}
public void setSnapshotPolicy(String snapshotPolicy) {
this.snapshotPolicy = snapshotPolicy;
}
public Integer getSnapshotReservation() {
return snapshotReservation;
}
public void setSnapshotReservation(Integer snapshotReservation) {
this.snapshotReservation = snapshotReservation;
}
public String getVolumeSize() {
return volumeSize;
}
public void setVolumeSize(String volumeSize) {
this.volumeSize = volumeSize;
}
@Override
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getAggregateName() {
return aggregateName;
}
public void setAggregateName(String aggregateName) {
this.aggregateName = aggregateName;
}
public Long getPoolId() {
return poolId;
}
public void setPoolId(Long poolId) {
this.poolId = poolId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -1,77 +0,0 @@
// 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.
package com.cloud.netapp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name = "netapp_pool")
public class PoolVO implements InternalIdentity {
@Override
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
@Column(name = "algorithm")
private String algorithm;
public PoolVO() {
}
public PoolVO(String name, String algorithm) {
this.name = name;
this.algorithm = algorithm;
}
}

View File

@ -1,29 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import com.cloud.netapp.LunVO;
import com.cloud.utils.db.GenericDao;
public interface LunDao extends GenericDao<LunVO, Long> {
List<LunVO> listLunsByVolId(Long volId);
LunVO findByName(String name);
}

View File

@ -1,67 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.netapp.LunVO;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
public class LunDaoImpl extends GenericDaoBase<LunVO, Long> implements LunDao {
private static final Logger s_logger = Logger.getLogger(PoolDaoImpl.class);
protected final SearchBuilder<LunVO> LunSearch;
protected final SearchBuilder<LunVO> LunNameSearch;
protected LunDaoImpl() {
LunSearch = createSearchBuilder();
LunSearch.and("volumeId", LunSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
LunSearch.done();
LunNameSearch = createSearchBuilder();
LunNameSearch.and("name", LunNameSearch.entity().getLunName(), SearchCriteria.Op.EQ);
LunNameSearch.done();
}
@Override
public List<LunVO> listLunsByVolId(Long volId) {
Filter searchFilter = new Filter(LunVO.class, "id", Boolean.TRUE, Long.valueOf(0), Long.valueOf(10000));
SearchCriteria sc = LunSearch.create();
sc.setParameters("volumeId", volId);
List<LunVO> lunList = listBy(sc, searchFilter);
return lunList;
}
@Override
public LunVO findByName(String name) {
SearchCriteria sc = LunNameSearch.create();
sc.setParameters("name", name);
return findOneBy(sc);
}
}

View File

@ -1,29 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import com.cloud.netapp.PoolVO;
import com.cloud.utils.db.GenericDao;
public interface PoolDao extends GenericDao<PoolVO, Long> {
PoolVO findPool(String poolName);
List<PoolVO> listPools();
}

View File

@ -1,66 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.netapp.PoolVO;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component
public class PoolDaoImpl extends GenericDaoBase<PoolVO, Long> implements PoolDao {
private static final Logger s_logger = Logger.getLogger(PoolDaoImpl.class);
protected final SearchBuilder<PoolVO> PoolSearch;
protected PoolDaoImpl() {
PoolSearch = createSearchBuilder();
PoolSearch.and("name", PoolSearch.entity().getName(), SearchCriteria.Op.EQ);
PoolSearch.done();
}
@Override
public PoolVO findPool(String poolName) {
SearchCriteria sc = PoolSearch.create();
sc.setParameters("name", poolName);
List<PoolVO> poolList = listBy(sc);
return (poolList.size() > 0 ? poolList.get(0) : null);
}
@Override
public List<PoolVO> listPools() {
// TODO Auto-generated method stub
return null;
}
// @Override
// public List<NetappStoragePoolVO> listVolumes(String poolName) {
// SearchCriteria sc = NetappListVolumeSearch.create();
// sc.setParameters("poolName", poolName);
// return listBy(sc);
// }
}

View File

@ -1,33 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import com.cloud.netapp.NetappVolumeVO;
import com.cloud.utils.db.GenericDao;
public interface VolumeDao extends GenericDao<NetappVolumeVO, Long> {
NetappVolumeVO findVolume(String ipAddress, String aggregateName, String volumeName);
List<NetappVolumeVO> listVolumes(String poolName);
NetappVolumeVO returnRoundRobinMarkerInPool(String poolName, int roundRobinMarker);
List<NetappVolumeVO> listVolumesAscending(String poolName);
}

View File

@ -1,99 +0,0 @@
// 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.
package com.cloud.netapp.dao;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.netapp.NetappVolumeVO;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@Component(value = "netappVolumeDaoImpl")
public class VolumeDaoImpl extends GenericDaoBase<NetappVolumeVO, Long> implements VolumeDao {
private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class);
protected final SearchBuilder<NetappVolumeVO> NetappVolumeSearch;
protected final SearchBuilder<NetappVolumeVO> NetappListVolumeSearch;
protected final SearchBuilder<NetappVolumeVO> NetappRoundRobinMarkerSearch;
@Override
public NetappVolumeVO findVolume(String ipAddress, String aggregateName, String volumeName) {
SearchCriteria<NetappVolumeVO> sc = NetappVolumeSearch.create();
sc.setParameters("ipAddress", ipAddress);
sc.setParameters("aggregateName", aggregateName);
sc.setParameters("volumeName", volumeName);
List<NetappVolumeVO> volList = listBy(sc);
return (volList.size() == 0 ? null : volList.get(0));
}
protected VolumeDaoImpl() {
NetappVolumeSearch = createSearchBuilder();
NetappVolumeSearch.and("ipAddress", NetappVolumeSearch.entity().getIpAddress(), SearchCriteria.Op.EQ);
NetappVolumeSearch.and("aggregateName", NetappVolumeSearch.entity().getAggregateName(), SearchCriteria.Op.EQ);
NetappVolumeSearch.and("volumeName", NetappVolumeSearch.entity().getVolumeName(), SearchCriteria.Op.EQ);
NetappVolumeSearch.done();
NetappListVolumeSearch = createSearchBuilder();
NetappListVolumeSearch.and("poolName", NetappListVolumeSearch.entity().getPoolName(), SearchCriteria.Op.EQ);
NetappListVolumeSearch.done();
NetappRoundRobinMarkerSearch = createSearchBuilder();
NetappRoundRobinMarkerSearch.and("roundRobinMarker", NetappRoundRobinMarkerSearch.entity().getRoundRobinMarker(), SearchCriteria.Op.EQ);
NetappRoundRobinMarkerSearch.and("poolName", NetappRoundRobinMarkerSearch.entity().getPoolName(), SearchCriteria.Op.EQ);
NetappRoundRobinMarkerSearch.done();
}
@Override
public List<NetappVolumeVO> listVolumes(String poolName) {
SearchCriteria<NetappVolumeVO> sc = NetappListVolumeSearch.create();
sc.setParameters("poolName", poolName);
return listBy(sc);
}
@Override
public NetappVolumeVO returnRoundRobinMarkerInPool(String poolName, int roundRobinMarker) {
SearchCriteria<NetappVolumeVO> sc = NetappRoundRobinMarkerSearch.create();
sc.setParameters("roundRobinMarker", roundRobinMarker);
sc.setParameters("poolName", poolName);
List<NetappVolumeVO> marker = listBy(sc);
if (marker.size() > 0)
return marker.get(0);
else
return null;
}
@Override
public List<NetappVolumeVO> listVolumesAscending(String poolName) {
Filter searchFilter = new Filter(NetappVolumeVO.class, "id", Boolean.TRUE, Long.valueOf(0), Long.valueOf(10000));
SearchCriteria<NetappVolumeVO> sc = NetappListVolumeSearch.create();
sc.setParameters("poolName", poolName);
return listBy(sc, searchFilter);
}
}

View File

@ -138,22 +138,11 @@
<artifactId>cloud-api</artifactId> <artifactId>cloud-api</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<profiles> <profiles>
<profile>
<id>netapp</id>
<activation>
<property>
<name>noredist</name>
</property>
</activation>
<modules>
<module>file-systems/netapp</module>
</modules>
</profile>
<profile> <profile>
<id>f5</id> <id>f5</id>
<activation> <activation>

View File

@ -91,7 +91,7 @@ public class ApiXmlDocWriter {
public static void main(String[] args) { public static void main(String[] args) {
Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[] {"org.apache.cloudstack.api", "com.cloud.api", Set<Class<?>> cmdClasses = ReflectUtil.getClassesWithAnnotation(APICommand.class, new String[] {"org.apache.cloudstack.api", "com.cloud.api",
"com.cloud.api.commands", "com.globo.globodns.cloudstack.api", "org.apache.cloudstack.network.opendaylight.api", "com.cloud.api.commands", "com.globo.globodns.cloudstack.api", "org.apache.cloudstack.network.opendaylight.api",
"com.cloud.api.commands.netapp", "org.apache.cloudstack.api.command.admin.zone", "org.apache.cloudstack.network.contrail.api.command"}); "org.apache.cloudstack.api.command.admin.zone", "org.apache.cloudstack.network.contrail.api.command"});
for (Class<?> cmdClass : cmdClasses) { for (Class<?> cmdClass : cmdClasses) {
if(cmdClass.getAnnotation(APICommand.class)==null){ if(cmdClass.getAnnotation(APICommand.class)==null){

View File

@ -1,64 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class AssociateLunCmdResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "the LUN id")
private String lun;
@SerializedName(ApiConstants.IP_ADDRESS)
@Param(description = "the IP address of ")
private String ipAddress;
@SerializedName(ApiConstants.TARGET_IQN)
@Param(description = "the target IQN")
private String targetIQN;
public String getLun() {
return lun;
}
public String getIpAddress() {
return ipAddress;
}
public String getTargetIQN() {
return targetIQN;
}
public void setLun(String lun) {
this.lun = lun;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public void setTargetIQN(String targetIQN) {
this.targetIQN = targetIQN;
}
}

View File

@ -1,63 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class CreateLunCmdResponse extends BaseResponse {
@SerializedName(ApiConstants.PATH)
@Param(description = "pool path")
private String path;
@SerializedName(ApiConstants.IQN)
@Param(description = "iqn")
private String iqn;
@SerializedName(ApiConstants.IP_ADDRESS)
@Param(description = "ip address")
private String ipAddress;
public String getPath() {
return path;
}
public String getIqn() {
return iqn;
}
public String getIpAddress() {
return ipAddress;
}
public void setPath(String path) {
this.path = path;
}
public void setIqn(String iqn) {
this.iqn = iqn;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class CreateVolumeOnFilerCmdResponse extends BaseResponse {
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class CreateVolumePoolCmdResponse extends BaseResponse {
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class DeleteLUNCmdResponse extends BaseResponse {
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class DeleteVolumeOnFilerCmdResponse extends BaseResponse {
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class DeleteVolumePoolCmdResponse extends BaseResponse {
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class DissociateLunCmdResponse extends BaseResponse {
}

View File

@ -1,74 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class ListLunsCmdResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "lun id")
private Long id;
@SerializedName(ApiConstants.IQN)
@Param(description = "lun iqn")
private String iqn;
@SerializedName(ApiConstants.NAME)
@Param(description = "lun name")
private String name;
@SerializedName(ApiConstants.VOLUME_ID)
@Param(description = "volume id")
private Long volumeId;
public Long getId() {
return id;
}
public String getIqn() {
return iqn;
}
public String getName() {
return name;
}
public Long getVolumeId() {
return volumeId;
}
public void setId(Long id) {
this.id = id;
}
public void setIqn(String iqn) {
this.iqn = iqn;
}
public void setName(String name) {
this.name = name;
}
public void setVolumeId(Long id) {
this.volumeId = id;
}
}

View File

@ -1,61 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class ListVolumePoolsCmdResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "pool id")
private Long id;
@SerializedName(ApiConstants.NAME)
@Param(description = "pool name")
private String name;
@SerializedName(ApiConstants.ALGORITHM)
@Param(description = "pool algorithm")
private String algorithm;
public Long getId() {
return id;
}
public String getName() {
return name;
}
public String getAlgorithm() {
return algorithm;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
}

View File

@ -1,123 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import com.cloud.serializer.Param;
public class ListVolumesOnFilerCmdResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "volume id")
private Long id;
@SerializedName(ApiConstants.POOL_NAME)
@Param(description = "pool name")
private String poolName;
@SerializedName(ApiConstants.IP_ADDRESS)
@Param(description = "ip address")
private String ipAddress;
@SerializedName(ApiConstants.AGGREGATE_NAME)
@Param(description = "Aggregate name")
private String aggrName;
@SerializedName(ApiConstants.VOLUME_NAME)
@Param(description = "Volume name")
private String volumeName;
@SerializedName(ApiConstants.SNAPSHOT_POLICY)
@Param(description = "snapshot policy")
private String snapshotPolicy;
@SerializedName(ApiConstants.SNAPSHOT_RESERVATION)
@Param(description = "snapshot reservation")
private Integer snapshotReservation;
@SerializedName(ApiConstants.SIZE)
@Param(description = "volume size")
private String volumeSize;
public Long getId() {
return id;
}
public String getPoolName() {
return poolName;
}
public String getIpAddress() {
return ipAddress;
}
public String getAggrName() {
return aggrName;
}
public String getVolumeName() {
return volumeName;
}
public String getSnapshotPolicy() {
return snapshotPolicy;
}
public Integer getSnapshotReservation() {
return snapshotReservation;
}
public String getVolumeSize() {
return volumeSize;
}
public void setId(Long id) {
this.id = id;
}
public void setPoolName(String poolName) {
this.poolName = poolName;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public void setAggrName(String aggrName) {
this.aggrName = aggrName;
}
public void setVolumeName(String volumeName) {
this.volumeName = volumeName;
}
public void setSnapshotPolicy(String snapshotPolicy) {
this.snapshotPolicy = snapshotPolicy;
}
public void setSnapshotReservation(Integer snapshotReservation) {
this.snapshotReservation = snapshotReservation;
}
public void setVolumeSize(String size) {
this.volumeSize = size;
}
}

View File

@ -1,22 +0,0 @@
// 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.
package com.cloud.server.api.response.netapp;
import org.apache.cloudstack.api.BaseResponse;
public class ModifyVolumePoolCmdResponse extends BaseResponse {
}

View File

@ -285,42 +285,4 @@ ALTER TABLE `cloud_usage`.`usage_security_group` ADD INDEX `i_usage_security_gro
USE `cloud`; USE `cloud`;
CREATE TABLE `cloud`.`netapp_volume` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`ip_address` varchar(255) NOT NULL COMMENT 'ip address/fqdn of the volume',
`pool_id` bigint unsigned NOT NULL COMMENT 'id for the pool',
`pool_name` varchar(255) NOT NULL COMMENT 'name for the pool',
`aggregate_name` varchar(255) NOT NULL COMMENT 'name for the aggregate',
`volume_name` varchar(255) NOT NULL COMMENT 'name for the volume',
`volume_size` varchar(255) NOT NULL COMMENT 'volume size',
`snapshot_policy` varchar(255) NOT NULL COMMENT 'snapshot policy',
`snapshot_reservation` int NOT NULL COMMENT 'snapshot reservation',
`username` varchar(255) NOT NULL COMMENT 'username',
`password` varchar(200) COMMENT 'password',
`round_robin_marker` int COMMENT 'This marks the volume to be picked up for lun creation, RR fashion',
PRIMARY KEY (`id`),
CONSTRAINT `fk_netapp_volume__pool_id` FOREIGN KEY `fk_netapp_volume__pool_id` (`pool_id`) REFERENCES `cloud`.`netapp_pool` (`id`) ON DELETE CASCADE,
INDEX `i_netapp_volume__pool_id`(`pool_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`netapp_pool` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`name` varchar(255) NOT NULL UNIQUE COMMENT 'name for the pool',
`algorithm` varchar(255) NOT NULL COMMENT 'algorithm',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`netapp_lun` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',
`lun_name` varchar(255) NOT NULL COMMENT 'lun name',
`target_iqn` varchar(255) NOT NULL COMMENT 'target iqn',
`path` varchar(255) NOT NULL COMMENT 'lun path',
`size` bigint NOT NULL COMMENT 'lun size',
`volume_id` bigint unsigned NOT NULL COMMENT 'parent volume id',
PRIMARY KEY (`id`),
CONSTRAINT `fk_netapp_lun__volume_id` FOREIGN KEY `fk_netapp_lun__volume_id` (`volume_id`) REFERENCES `cloud`.`netapp_volume` (`id`) ON DELETE CASCADE,
INDEX `i_netapp_lun__volume_id`(`volume_id`),
INDEX `i_netapp_lun__lun_name`(`lun_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET foreign_key_checks = 1; SET foreign_key_checks = 1;

View File

@ -195,9 +195,6 @@ DROP TABLE IF EXISTS `cloud`.`image_data_store`;
DROP TABLE IF EXISTS `cloud`.`vm_compute_tags`; DROP TABLE IF EXISTS `cloud`.`vm_compute_tags`;
DROP TABLE IF EXISTS `cloud`.`vm_root_disk_tags`; DROP TABLE IF EXISTS `cloud`.`vm_root_disk_tags`;
DROP TABLE IF EXISTS `cloud`.`vm_network_map`; DROP TABLE IF EXISTS `cloud`.`vm_network_map`;
DROP TABLE IF EXISTS `cloud`.`netapp_volume`;
DROP TABLE IF EXISTS `cloud`.`netapp_pool`;
DROP TABLE IF EXISTS `cloud`.`netapp_lun`;
CREATE TABLE `cloud`.`version` ( CREATE TABLE `cloud`.`version` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id',

View File

@ -19832,7 +19832,7 @@
select: function (args) { select: function (args) {
/* /*
UI no longer gets providers from "listStorageProviders&type=image" because: UI no longer gets providers from "listStorageProviders&type=image" because:
(1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI). (1) Not all of returned values are handled by UI.
(2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image" (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image"
*/ */
var items =[ { var items =[ {

View File

@ -1908,7 +1908,7 @@
} else { } else {
/* /*
UI no longer gets providers from "listStorageProviders&type=image" because: UI no longer gets providers from "listStorageProviders&type=image" because:
(1) Not all of returned values are handled by UI (e.g. Provider "NetApp" is not handled by UI). (1) Not all of returned values are handled by UI.
(2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image" (2) Provider "SMB" which is handled by UI is not returned from "listStorageProviders&type=image"
*/ */
storageproviders.push({ id: 'NFS', description: 'NFS'}); storageproviders.push({ id: 'NFS', description: 'NFS'});