diff --git a/fsx-ontap-aws-cli-scripts/create_fsxn_filesystem b/fsx-ontap-aws-cli-scripts/create_fsxn_filesystem new file mode 100755 index 0000000..c3fad37 --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/create_fsxn_filesystem @@ -0,0 +1,158 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to create an FSxN filesystem. +################################################################################ + +################################################################################ +# This function just outputs the usage information and exits. +################################################################################ +usage () { +cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands are required to run this script." 1>&2 + exit 1 +fi +# +# Set some defaults. +size=1024 +throughput=128 +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +securityGroupOption="" +endpointips="" +azType="MULTI_AZ_1" +# +# Process command line arguments. +while [ ! -z "$1" ]; do + case $(echo "$1" | tr [A-Z] [a-z]) in + -name|--name) fileSystemName="$2" + shift + ;; + -region|--region) region="$2" + shift + ;; + -size|--size) size="$2" + if ! [[ "$size" =~ '^[0-9]+$' ]]; then + echo "-size must be an integer." + usage + fi + if [ "$size" -le 1024 ]; then + usage + fi + shift + ;; + -subnetid1|--subnetid1) subnetID1="$2" + shift + ;; + -subnetid2|--subnetid2) subnetID2="$2" + shift + ;; + -security-group-id|--security-group-id) securityGroupOption="--security-group-ids $2" + shift + ;; + -type|--type) + if [ "$(echo $2 | tr [A-Z] [a-z])" == "single" ]; then + azType="SINGLE_AZ_1" + elif [ "$(echo $2 | tr [A-Z] [a-z])" == "multi" ]; then + azType="MULTI_AZ_1" + else + echo "Error, known availability type '$2'." + usage + fi + shift + ;; + -throughput|--throughput) throughput="$2" + if ! [[ "$throughput" =~ '^[0-9]+$' ]]; then + echo "-throughput must be an integer." + usage + fi + if [ "$througput" != "128" -a "$througput" != "256" -a "$throughput" != "512" -a "$throughput" != "1024" -a "$throughput" != "2048" -a "$throughput" != "4096" ]; then + echo "-throughput must be 128 or 256 or 512 or 1024 or 2048 or 4096." + usage + fi + shift + ;; + -endpointiprange|--endpointiprange) + endpointips='"EndpointIpAddressRange": "'$2'",' + shift + ;; + *) echo "Error, unknow options $1." + usage + ;; + esac + shift +done +# +# Ensure all the required parameters have been provided. +if [ -z "$fileSystemName" -o -z "$subnetID1" -o "$azType" == "MULTI_AZ_1" -a -z "$subnetID2" ]; then + echo "Missing arguments." 1>&2 + usage + exit 1 +fi +if [ $azType == "SINGLE_AZ_1" ]; then + if [ ! -z "$endpointips" ]; then + echo "Error, you can not specify Endpoint IP address range when deploying in a single availability zone." 1>&2 + exit 1 + fi + + if [ ! -z "$subnetID2" ]; then + echo "Error, you can't specify a second subnet with deploying in a single availability zone." 1>&2 + exit 1 + fi +fi + +aws fsx create-file-system --output=json --file-system-type ONTAP --storage-capacity $size --subnet-ids $subnetID1 $subnetID2 --storage-type SSD --tags "Key=Name,Value=$fileSystemName" $securityGroupOption --ontap-configuration '{ + "PreferredSubnetId": "'$subnetID1'", + '$endpointips' + "DeploymentType": "'$azType'", + "ThroughputCapacity": '$throughput'}' --region=$region > $tmpout 2>&1 + +if [ $? != "0" ]; then + echo "Failed to create FSxN file system." 1>&2 + cat $tmpout 1>&2 + exit 1 +else + status=$(jq -r .FileSystem.Lifecycle $tmpout 2> /dev/null) + if [ "$status" == "CREATING" -o "$status" == "PENDING" ]; then + echo "File system '$fileSystemName' ($(jq -r .FileSystem.FileSystemId $tmpout)) is being created." + exit 0 + else + echo "Unknown status '$status'. Complete output returned from the AWS api:" 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/create_fsxn_svm b/fsx-ontap-aws-cli-scripts/create_fsxn_svm new file mode 100755 index 0000000..78396f5 --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/create_fsxn_svm @@ -0,0 +1,106 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to create an FSxN virtual storage machine under the +# specified FSxN "filesystem". +################################################################################ + +################################################################################ +# This function just outputs the usage information and exits. +################################################################################ +usage () { +cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands are required to run this script." 1>&2 + exit 1 +fi +# +# Set some defaults. +size=20 +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +# +# Process command line arguments. +while getopts "n:r:f:i:" option; do + case $option in + n) svmName=$OPTARG + ;; + r) region=$OPTARG + ;; + f) fileSystemName=$OPTARG + ;; + i) fsid=$OPTARG + ;; + *) echo "Unknown option '$option'." 1>&2 + usage + ;; + esac +done + +if [ ! -z "$fileSystemName" -a ! -z "$fsid" ]; then + echo "Error, you can only specify the -i OR the -f option. Not both." 1>&2 + usage +fi +# +# Ensure all the required parameters have been provided. +if [ -z "$svmName" -o -z "$fileSystemName" -a -z "$fsid" ]; then + echo "Error, missing required arguments." 1>&2 + usage +fi +# +# Get the file system id from the file system name. +if [ -z "$fsid" ]; then + fsid=$(aws fsx describe-file-systems --output=json 2> /dev/null | jq -r ".FileSystems[] | if((.Tags[] | select(.Key == \"Name\") .Value) == \"${fileSystemName}\") then .FileSystemId else empty end" 2> /dev/null) +fi + +if [ -z "$fsid" ]; then + echo "Error, could not find the file system with name '$fileSystemName}' in region $region." 1>&2 + exit 1 +fi +# +# Create the SVM +aws fsx create-storage-virtual-machine --name $svmName --region=$region --file-system-id $fsid --output=json > $tmpout 2>&1 + +if [ $? != "0" ]; then + echo "Failed to create storage virtual machine." 1>&2 + cat $tmpout 1>&2 + exit 1 +else + status=$(jq -r .StorageVirtualMachine.Lifecycle $tmpout 2> /dev/null) + if [ "$status" == "CREATING" -o "$status" == "PENDING" ]; then + echo "Stroage Virtaul Machine '$svmName'($(jq -r '.StorageVirtualMachine.StorageVirtualMachineId' $tmpout)) is being created." + exit 0 + else + echo "Unknown status '$status'. Complete output returned from the AWS api:" 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/create_fsxn_volume b/fsx-ontap-aws-cli-scripts/create_fsxn_volume new file mode 100755 index 0000000..4dfe028 --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/create_fsxn_volume @@ -0,0 +1,90 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to create an FSxN volume under the specified SVM. The +# FSxN "filesystem" is implied by the SVM ID. +################################################################################ + +################################################################################ +# This function just outputs the usage information and exits. +################################################################################ +usage () { +cat 1>&2 <&2 + usage +fi + +aws fsx create-volume --volume-type ONTAP --name $volumeName --ontap-configuration "{ + \"JunctionPath\": \"/$volumeName\", + \"SecurityStyle\": \"UNIX\", + \"SizeInMegabytes\" : $size, + \"StorageEfficiencyEnabled\": true, + \"StorageVirtualMachineId\": \"$svmId\", + \"TieringPolicy\" : {\"CoolingPeriod\": 31, \"Name\": \"SNAPSHOT_ONLY\"}, + \"OntapVolumeType\": \"RW\", + \"SnapshotPolicy\": \"default\"}" --region=$region --output=json > $tmpout 2>&1 + +if [ $? != "0" ]; then + echo "Failed to create the FSxN volume." 1>&2 + cat $tmpout 1>&2 + exit 1 +else + status=$(jq -r .Volume.Lifecycle $tmpout 2> /dev/null) + if [ "$status" == "CREATING" -o "$status" == "PENDING" ]; then + echo "FSxN volume '$volumeName'($(jq -r .Volume.VolumeId $tmpout)) is being created." + exit 0 + else + echo "Unknown status '$status'. Complete output returned from the AWS api:" 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/delete_fsxn_filesystem b/fsx-ontap-aws-cli-scripts/delete_fsxn_filesystem new file mode 100755 index 0000000..7e9847d --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/delete_fsxn_filesystem @@ -0,0 +1,356 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to delete a FSxN filesystem. +################################################################################ + +################################################################################ +# This function just outputs the usage information and forces the script to +# exit. +################################################################################ +usage () { +cat 1>&2 < $tmpout 2>&1 + if [ $? != "0" ]; then + printf "\nError, failed to delete a volume with volumeId: '$volumeId'.\n" 1>&2 + cat $tmpout 1>&2 + return 1 + fi + # + # Wait for the volume to be deleted. + i=0 + while [ $i -lt $MaxIterations ]; do + aws fsx describe-volumes --volume-ids $volumeId --output=json --region=$region > $tmpout 2>&1 + if [ $? -eq 0 ]; then + status=$(jq -r .Volumes[0].Lifecycle $tmpout 2> /dev/null) + if [ "$status" != "DELETING" -a "$status" != "PENDING" ]; then + printf "\nError, failed to delete volume with volume ID '$volumeId'. Status = ${status}.\n" 1>&2 + cat $tmpout 1>&2 + return 1 + fi + else + # Assume if it failed, it is because the volume was deleted and doesn't exist anymore. + break + fi + sleep $SleepTime + let i+=1 + done + if [ $i -ge $MaxIterations ]; then + echo "Failed to delete volume with volume ID of '$volumeId'. Taking too long." 1>&2 + return 1 + fi + return 0 +} + +################################################################################ +# This function is used to delete an FSxN SVM. It waits for the SVM to be +# deleted. It assumes the SVM has been deleted when the API call to display +# its status returns an error. +################################################################################ +delete_svm() { + + local tmpout=/tmp/delete_fsxn_delete_svm.$BASHPID + trap 'rm -f $tmpout' RETURN + + local svmId=$1 + aws fsx delete-storage-virtual-machine --region=$region --output=json --storage-virtual-machine-id $svmId > $tmpout 2>&1 + if [ $? != "0" ]; then + printf "\nError, failed to delete a SVM with svmID: '$svmId'.\n" 1>&2 + cat $tmpout 1>&2 + return 1 + fi + # + # Wait for the svm to be deleted. + i=0 + while [ $i -lt $MaxIterations ]; do + aws fsx describe-storage-virtual-machines --storage-virtual-machine-ids $svmId --output=json --region=$region > $tmpout 2>&1 + if [ $? -eq 0 ]; then + status=$(jq -r '.StorageVirtualMachines[0].Lifecycle' $tmpout 2> /dev/null) + if [ "$status" != "DELETING" -a "$status" != "PENDING" ]; then + printf "\nError, failed to delete SVM with SVM ID '$svmId'. Status = $status\n" 1>&2 + cat $tmpout 1>&2 + return 1 + fi + else + # Assume if it failed, it is because the SVM was delted and therefore doesn't exist anymore. + break + fi + sleep $SleepTime + let i+=1 + done + if [ $i -ge $MaxIterations ]; then + printf "\nFailed to delete SVM with SVM ID of '$svmID'. Taking too long.\n" 1>&2 + return 1 + fi + return 0 +} + +################################################################################ +# Main logic starts here. +################################################################################ +tmpout=/tmp/fsx_fs_delete.$$ +svmsFile=/tmp/fsx_fs_delete_svms.$$ +volumesFile=/tmp/fsx_fs_delete_volumes.$$ +trap 'rm -f $tmpout $svmsFile $volumesFile' exit +# +# Set the maximum number of times to check that a volume and/or SVM has been +# deleted. Multiple it by the SleepTime set below to the total amount of +# time allowed. Note, it takes at least 4 minutes to delete a volume. +MaxIterations=120 +# +# Set the number of seconds to wait between checks that a volume and/or SVM has been deleted. +SleepTime=5 +# +# Set the maximum number of "volume deletes" that can be running at the same time. +MaxDeletesRunning=20 +# +# Check that the required commands are available. +if which jq aws > /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands is required to run this script." 1>&2 + exit 1 +fi +# +# Get the default region. +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +# +# Process command line arguments. +while getopts "r:f:i:" option; do + case $option in + f) fileSystemName=$OPTARG + ;; + r) region=$OPTARG + ;; + i) fsid=$OPTARG + ;; + *) echo "Error, unknown option '$option'." 1>&2 + usage # implied exit + ;; + esac +done + +if [ ! -z "$fsid" -a ! -z "$fileSystemName" ]; then + echo "Error, you can only specify the -i OR the -f option, not both." 1>&2 + usage # implied exit +fi +# +# Ensure all the required parameters have been provided. +if [ -z "$fileSystemName" -a -z "$fsid" ]; then + echo "Error, missing required arguments." 1>&2 + usage # implied exit +fi +# +# Get the file system id based on the name. +if [ -z "$fsid" ]; then + fsid=($(aws fsx describe-file-systems --region=$region --output=json 2> $tmpout | jq -r '.FileSystems[] | if((.Tags[] | select(.Key == "Name") .Value) == "'"${fileSystemName}"'") then .FileSystemId else empty end' 2> /dev/null)) + + if [ ${#fsid[*]} -gt 1 ]; then + echo "Error, more than one file system matched the file system name '$fileSystemName'." 1>&2 + echo "Please use the -i option to specify the exact file system you want to delete." 1>&2 + exit 1 + fi + + if [ -z "$fsid" ]; then + echo "Error, could not find the file system with name '$fileSystemName'." 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +else + # + # Get the file system name based on the fsid. + fileSystemName=$(aws fsx describe-file-systems --file-system-ids $fsid --region=$region --output=json 2> /dev/null | jq -r '.FileSystems[0].Tags[] | select(.Key == "Name") .Value' 2> /dev/null) + if [ -z "$fileSystemName" ]; then + echo "Error, failed to get the file system name based on the ID ($fsid)." 1>&2 + exit 1 + fi +fi +# +# Create a JSON file with all the FSxN SVMs in the region. +aws fsx describe-storage-virtual-machines --region=$region --output=json > $svmsFile 2>&1 +if [ $? -ne 0 ]; then + echo "Error, failed to get the list of SVMs." 1>&2 + cat $svmsFile 1>&2 + exit 1 +fi +# +# Create a JSON file with all the FSXN volumes in the region. +aws fsx describe-volumes --region=$region --output=json > $volumesFile 2>&1 +if [ $? -ne 0 ]; then + echo "Error, failed to get the list of volumes." 1>&2 + cat $volumesFile 1>&2 + exit 1 +fi +# +# Make sure the user really wants to delete the file system. +echo "Here are the current contents of the '$fileSystemName'($fsid) file system you have indicated you want to delete:" +displayFileSystemContents $fsid +read -p "Are you sure you want to delete this file system, with all the above volumes (yes/no)? " response +if [ "$response" != "yes" ]; then + echo "Aborted." + exit 1 +fi +# +# Before you can delete a file system, you have to first delete all the volumes, +# and then all the SVMs. So, first get the list of SVMs: +declare -a svms +declare -a volumes +svms=($(jq -r '.StorageVirtualMachines[] | if(.FileSystemId == "'$fsid'") then .StorageVirtualMachineId else empty end' $svmsFile)) +# +# Now delete all the volumes for each SVM. I could just deleted all the volumes +# associated with the fsid, but I wanted the extra check on the volumeId to be +# associated with one of the SVMs that is associated with the fsid. +for svmId in ${svms[*]}; do + # + # Create an array with all the non-root volume IDs for this SVM. + volumes=($(jq -r '.Volumes[] | if(.OntapConfiguration.StorageVirtualMachineId == "'$svmId'" and (.OntapConfiguration.StorageVirtualMachineRoot | not) and .FileSystemId == "'$fsid'") then .VolumeId else empty end' $volumesFile)) + if [ ! -z "${volumes[*]}" ]; then + # + # Since it can take a while for a single volume to be deleted (e.g. 4 minutes + # for a small empty volume) and you can do multiple deletes in parallel, + # spawn them in the background and wait for them to finish. Although, since + # we don't want to overwhelm either AWS or ONTAP, only allow a certain + # number at a time. + i=0 + numRunning=0 + numVolumes=${#volumes[*]} + maxNumRunning=1 # Only do one initially, if it completes successfully, then do the rest concurrently. + printf "\nDeleting all the volumes associated with ${svmId}.\n" + while [ $i -lt $numVolumes ]; do + delete_volume ${volumes[$i]} & + let i+=1 + let numRunning+=1 + printf "\rTotal number of volumes to delete: ${numVolumes}. Number of deletes currently running: ${numRunning}. Number waiting to be started: $((numVolumes-i)). " + if [ $numRunning -ge $maxNumRunning ]; then + # + # Wait for a job to complete. + wait -n + rc=$? + if [ $rc -eq 127 ]; then + # + # 127 means there were no background jobs. Since we just deployed one, that shouldn't happen. + printf "\nError, got an expected response from 'wait'. Aborting.\n" 1>&2 + exit 1 + fi + if [ $rc -ne 0 ]; then + printf "\nError, one of the volume deletes failed. Aborting!\n" 1>&2 + exit 1 + fi + let numRunning-=1 + if [ $i -eq 1 ]; then + # The first one succeeded, open up the flood gates. + maxNumRunning=$MaxDeletesRunning + fi + fi + done + # + # Now that we have queued them all up, wait for them to finish. + wait -n + rc=$? + let numRunning-=1 + while [ "$rc" != 127 ]; do + printf "\rTotal number of volumes to delete: ${numVolumes}. Number of deletes currently running: ${numRunning}. Number waiting to be started: $((numVolumes-i)). " + if [ "$rc" != 0 ]; then + printf "\nError, one of the volume deletes failed. Aborting!\n" 1>&2 + exit 1 + fi + wait -n + rc=$? + let numRunning-=1 + done + fi +done # for svmId in ${svms[*]}; do +# +# Now that all the volumes are deleted, delete the SVMs. +# Since there can only be 24 SVMs, don't really have to worry about spawning +# too many at a time. +printf "\nDeleting SVMs.\n" +for svmId in ${svms[*]}; do + delete_svm $svmId & +done +# +# Now wait for them to finish. +if [ ! -z "$svms" ]; then + numRunning=${#svms[*]} + printf "\rTotal number of SVMs to delete: ${#svms[*]}. Number of deletes currently running: ${numRunning}. Number waiting to be started: 0. " + wait -n + rs=$? + let numRunning-=1 + while [ "$rs" != 127 ]; do + if [ "$rs" != 0 ]; then + printf "\nError, one of the SVM deletes failed. Aborting!\n" 1>&2 + exit 1 + fi + printf "\rTotal number of SVMs to delete: ${#svms[*]}. Number of deletes currently running: ${numRunning}. Number waiting to be started: 0. " + wait -n + rs=$? + let numRunning-=1 + done +fi +# +# Now that all the volumes and all the SVMs have been deleted, we can delete the filesystem. +aws fsx delete-file-system --file-system-id $fsid --output=json --region=$region > $tmpout 2>&1 +if [ $? != "0" ]; then + printf "\nError, failed to delete file system.\n" 1>&2 + cat $tmpout 1>&2 + exit 1 +else + status=$(jq -r .Lifecycle $tmpout) + if [ "$status" == "DELETING" -o "$status" == "PENDING" ]; then + printf "\nFile system '$fileSystemName' is being deleted.\n" + exit 0 + else + printf "\nUnknown status '$status'. Complete output returned from the AWS api:\n" 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/delete_fsxn_svm b/fsx-ontap-aws-cli-scripts/delete_fsxn_svm new file mode 100755 index 0000000..0c78dcc --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/delete_fsxn_svm @@ -0,0 +1,86 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to delete a storage virtual machine from a +# FSxN filesystem. +################################################################################ + +################################################################################ +# This function just outputs the usage information and exits. +################################################################################ +usage () { +cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands are required to run this script." 1>&2 + exit 1 +fi +# +# Set any defaults. +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +# +# Process command line arguments. +while getopts "i:r:" option; do + case $option in + i) svmID=$OPTARG + ;; + r) region=$OPTARG + ;; + *) echo "Error, unknown option '$option'." 1>&2 + usage + ;; + esac + shift +done +# +# Ensure all the required parameters have been provided. +if [ -z "$svmID" ]; then + echo "Error, missing reuqired arguments." 1>&2 + usage + exit 1 +fi + +aws fsx delete-storage-virtual-machine --region=$region --storage-virtual-machine-id $svmID > $tmpout 2>&1 + +if [ $? != "0" ]; then + echo "Failed to delete storage virtual machine." 1>&2 + cat $tmpout + exit 1 +else + status=$(jq -r .Lifecycle $tmpout) + if [ "$status" == "DELETING" ]; then + echo "Storage Virtual Machine with an id of '$svmID' is being deleted." + exit 0 + else + echo "Unknown status '$status'. Complete output returned from the AWS api:" + cat $tmpout + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/delete_fsxn_volume b/fsx-ontap-aws-cli-scripts/delete_fsxn_volume new file mode 100755 index 0000000..38c43c3 --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/delete_fsxn_volume @@ -0,0 +1,74 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to delete an FSxN volume. +################################################################################ + +################################################################################ +# This function just outputs the usage information and exits. +################################################################################ +usage () { +cat 1>&2 <&2 + usage +fi + +aws fsx delete-volume --volume-id $volumeId --region=$region --output=json > $tmpout 2>&1 + +if [ $? != "0" ]; then + echo "Failed to delete volume." 1>&2 + cat $tmpout 1>&2 + exit 1 +else + status=$(jq -r .Lifecycle $tmpout 2> /dev/null) + if [ "$status" == "DELETING" -o "$status" == "PENDING" ]; then + echo "Volume '$volumeId' is being deleted." + exit 0 + else + echo "Unknown status '$status'. Complete output returned from the AWS api:" 1>&2 + cat $tmpout 1>&2 + exit 1 + fi +fi diff --git a/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems b/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems new file mode 100755 index 0000000..7596a9f --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems @@ -0,0 +1,180 @@ +#!/bin/bash +# +################################################################################# +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +################################################################################ +# This script will list all the AWS FSxN file systems the user has access to. +# It will list: +# o Region +# o File System ID +# o File Systesm "name" +# o Status +# o Management IP +# o VPC ID - optional +# o Subnet ID - optional +# +# In the case of the Management IP and Subnet ID, it will only show the first +# one defined. Based on the potential output from the API call, there could +# be more than one. +# +# If the '-c' option is provided, instead of providing the information above +# it will display a hierarchical view of each file system, meaning it will +# display all the SVMs, and under each SVM, all the volumes that are under it. +################################################################################ + +################################################################################ +# This function is used to output the usage information for the script and exit. +################################################################################ +usage () { + cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands are required to run this script." 1>&2 + exit 1 +fi +# +# Set defaults. +allRegions=false +includeNetworking=false +contents=false +showStatus=false +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +# +# Process command line arguments. +while getopts "csanr:i:f:" option; do + case "$option" in + r) region="$OPTARG" + ;; + a) allRegions=true + ;; + n) includeNetworking=true + ;; + c) contents=true + ;; + i) fsid=$OPTARG + ;; + f) fileSystemName="$OPTARG" + ;; + s) showStatus=true + ;; + *) echo "Error, unknown option '$option'." 1>&2 + usage + ;; + esac +done + +if [ "$allRegions" = "true" ]; then + regions=$(aws ec2 describe-regions --query "Regions[].RegionName" --output=json | jq -r '.[]') +else + regions=$region +fi + +if [ ! -z "$fsid" -a ! -z "$fileSystemName" ]; then + echo "Error, you can't specify both a file system ID and file system name." 1>&2 + exit 1 +fi +# +# Loop on all the requested regions. +for region in $regions; do + # + # Check that the fsx service is supported in thie region + if [ ! -z "$(getent hosts fsx.$region.amazonaws.com)" ]; then + if [ ! -z "$fileSystemName" ]; then + fsid=$(aws fsx describe-file-systems --region=$region --output=json 2> /dev/null | jq -r '.FileSystems[] | if((.Tags[] | select(.Key == "Name") .Value) == "'"${fileSystemName}"'") then .FileSystemId else empty end' 2> /dev/null) + if [ ! -z "$fsid" ]; then + aws fsx describe-file-systems --file-system-ids $fsid --region=$region --output=json > $fileSystemsFile 2>&1 + else + echo "Error, failed to get the file system ID based on a file system name of '$fileSystemName'." 1>&2 + exit 1 + fi + else + if [ -z "$fsid" ]; then + aws fsx describe-file-systems --region=$region --output=json > $fileSystemsFile 2>&1 + else + aws fsx describe-file-systems --file-system-ids $fsid --region=$region --output=json > $fileSystemsFile 2>&1 + fi + fi + + if [ $? -ne 0 ]; then + echo "Error, failed to get the list of file systems." 1>&2 + cat $fileSystemsFile 1>&2 + exit 1 + fi + + if [ $contents == "true" ]; then + aws fsx describe-storage-virtual-machines --region=$region --output=json > $svmsFile 2>&1 + if [ $? -ne 0 ]; then + echo "Error, failed to get the list of SVMs." 1>&2 + cat $svmsFile 1>&2 + exit 1 + fi + + aws fsx describe-volumes --region=$region --output=json > $volumesFile 2>&1 + if [ $? -ne 0 ]; then + echo "Error, failed to get the list of volumes." 1>&2 + cat $volumesFile 1>&2 + exit 1 + fi + + printf "$region\n" + jq -r '.FileSystems[] | .FileSystemId + " " + .Lifecycle + " " + (.Tags[] | select(.Key == "Name") .Value)' $fileSystemsFile | while read fs fsStatus fsName; do + [ "$showStatus" == "true" ] && printf "\t$fs($fsStatus) - '$fsName'\n" + [ "$showStatus" != "true" ] && printf "\t$fs - '$fsName'\n" + jq -r '.StorageVirtualMachines[] | if(.FileSystemId == "'$fs'") then .StorageVirtualMachineId + " " + .Lifecycle + " " + .Name else empty end' $svmsFile | while read svm svmStatus svmName; do + [ "$showStatus" == "true" ] && printf "\t\t$svm($svmStatus) - '$svmName'\n" + [ "$showStatus" != "true" ] && printf "\t\t$svm - '$svmName'\n" + jq -r '.Volumes[] | if(.FileSystemId == "'$fs'" and .OntapConfiguration.StorageVirtualMachineId == "'$svm'") then .VolumeId + " " + .Lifecycle + " " + .Name else empty end' $volumesFile | while read volume volStatus volumeName; do + [ "$showStatus" == "true" ] && printf "\t\t\t$volume($volStatus) - '$volumeName'\n" + [ "$showStatus" != "true" ] && printf "\t\t\t$volume - '$volumeName'\n" + done + done + done + else + jq -r '.FileSystems[] | .FileSystemId + "," + (.Tags[] | select(.Key == "Name") .Value) + "," + .Lifecycle + "," + .OntapConfiguration.Endpoints.Management.IpAddresses[0] + "," + .VpcId + "," + .SubnetIds[0]' $fileSystemsFile > $tmpout + + if [ "$includeNetworking" == "true" ]; then + awk -F, -v region=$region 'BEGIN {first=1; formatStr="%12s %23s %35s %10s %15s %21s %24s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "Name", "Status", "Managment IP", "VPC ID", "Subnet ID"; first=0}; printf formatStr, region, $1, $2, $3, $4, $5, $6}' < $tmpout + else + awk -F, -v region=$region 'BEGIN {first=1; formatStr="%12s %23s %35s %10s %15s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "Name", "Status", "Managment IP", "VPC ID", "Subnet ID"; first=0}; printf formatStr, region, $1, $2, $3, $4}' < $tmpout + fi + fi + else + if [ $allRegions != "true" ]; then + printf "The fsx service is currently not supported in the $region region.\n" + fi + fi +done diff --git a/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems.ps1 b/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems.ps1 new file mode 100644 index 0000000..fd03c0e --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/list_fsxn_filesystems.ps1 @@ -0,0 +1,71 @@ +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +# This script is used to list all the FSxN File Systems a user has access to. +# It accepts two optional parameters: +# -region +# -all +# Where: +# is the region you want to list the file systems from. By default it +# list all the file systems from the default region set by the +# "aws configuration" command. +# -all means you want to list the file systems from all the known AWS regions. +# -network means you want the network informaiton associated with the filesystem. +# +################################################################################## + +param ([switch]$all, [string]$region, [switch]$network) + +if($region -eq "") { + $region=(get-content ~/.aws/config | select-string "region") -replace "region = ","" +} + +if ($all.IsPresent) { + $regions=(aws ec2 describe-regions --query "Regions[].RegionName" --output=json | ConvertFrom-Json) +} else { + $regions=@($region) +} + +foreach ($region in $regions) { + $first=$true + $fss=(aws fsx describe-file-systems --region=$region --output=json | ConvertFrom-Json) + + foreach ($fs in $fss.FileSystems) { + if($first) { + #%12s %23s %35s %10s %15s %21s %24s + if ($network.IsPresent) { + "`n{0,12} {1,23} {2,35} {3,10} {4, 15} {5, 21} {6, 24}" -f "Region", "File System ID", "Name", "Status", "Management IP", "VPC ID", "Subnet ID" + } else { + "`n{0,12} {1,23} {2,35} {3,10} {4, 15}" -f "Region", "File System ID", "Name", "Status", "Management IP" + } + $first=$false + } + + $name="N/A" + foreach ($tag in $fs.tags) { + if($tag.Key -eq "Name") { + $name=$tag.Value + } + } + if ($null -ne $fs.OntapConfiguration.Endpoints.Management.IpAddresses) { + $manIP = $fs.OntapConfiguration.Endpoints.Management.IpAddresses[0] + } else { + $manIP = "N/A" + } + if ($network.IsPresent) { + "{0,12} {1,23} {2,35} {3,10} {4, 15} {5, 21} {6, 24}" -f $region, $fs.FileSystemId, $name, $fs.Lifecycle, $manIP, $fs.VpcId, $fs.SubnetIds[0] + } else { + "{0,12} {1,23} {2,35} {3,10} {4, 15}" -f $region, $fs.FileSystemId, $name, $fs.Lifecycle, $manIP + } + } +} diff --git a/fsx-ontap-aws-cli-scripts/list_fsxn_svms b/fsx-ontap-aws-cli-scripts/list_fsxn_svms new file mode 100755 index 0000000..11a590b --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/list_fsxn_svms @@ -0,0 +1,114 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +################################################################################ +# This script will list all the AWS FSxN storage virtual machines (SVMs) that +# the user has access to. It will list: +# o Region +# o File system ID +# o File System Name - optional +# o SVM ID +# o SVM Name +################################################################################ + +################################################################################ +# This function outputs the usage information and exists. +################################################################################ +usage () { + cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, both the 'aws' and 'jq' commands are required to run this script." 1>&2 + exit 1 +fi +# +# Process command line arguments. +allRegions=false +includeFsName=false +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +while getopts "anr:i:f:" option; do + case "$option" in + r) region="$OPTARG" + ;; + a) allRegions=true + ;; + n) includeFsName=true + ;; + i) fileSystemID="$OPTARG" + ;; + f) fileSystemName="$OPTARG" + ;; + *) echo "Error, unknown option '$option'." 1>&2 + usage + ;; + esac +done + +if [ ! -z "$fileSystemID" -a ! -z "$fileSystemName" ]; then + echo "Error, you can't specify both a file system ID and a file system name." 1>&2 + exit 1 +fi + +if [ "$allRegions" = "true" ]; then + regions=$(aws ec2 describe-regions --query "Regions[].RegionName" --output=json | jq -r '.[]') +else + regions=$region +fi + +if [ ! -z "$fileSystenName" ]; then + fileSystemID=$(aws fsx describe-file-systems --output=json 2> /dev/null | jq -r '.FileSystems[] | if((.Tags[] | select(.Key == "Name") .Value) == "'"${fileSystemName}"'") then .FileSystemId else empty end' 2> /dev/null) +fi +# +# Loop on all the regions. +for region in $regions; do + # + # Check that the fsx service is supported in thie region + if [ ! -z "$(getent hosts fsx.$region.amazonaws.com)" ]; then + if [ -z "$fileSystemID" ]; then + aws fsx describe-storage-virtual-machines --region=$region | jq -r '.StorageVirtualMachines[] | .FileSystemId + "," + .StorageVirtualMachineId + "," + .Name' | sort > $tmpout + else + aws fsx describe-storage-virtual-machines --region=$region | jq -r '.StorageVirtualMachines[] | if(.FileSystemId == "'$fileSystemID'") then .FileSystemId + "," + .StorageVirtualMachineId + "," + .Name else empty end' | sort > $tmpout + fi + + if [ $includeFsName == "true" ]; then + aws fsx describe-file-systems --region=$region | jq -r '.FileSystems[] | .FileSystemId + "," + (.Tags[] | select(.Key == "Name") .Value)' > $tmpout2 + awk -F, -v region=$region 'BEGIN {first=1; maxNameLen=0; while(getline < "'$tmpout2'") {fss[$1]=$2; if(length($2) > maxNameLen) {maxNameLen=length($2)}}; maxNameLen +=2; formatStr="%12s %20s%-"maxNameLen"s %23s %s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "(Name)", "SVM ID", "SVM Name"; first=0}; name="("fss[$1]")"; printf formatStr, region, $1, name, $2, $3}' < $tmpout + else + awk -F, -v region=$region 'BEGIN {first=1; formatStr="%12s %23s %23s %s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "SVM ID", "SVM Name"; first=0}; printf formatStr, region, $1, $2, $3}' < $tmpout + fi + else + if [ $allRegions != "true" ]; then + printf "The fsx service is currently not supported in the $region region.\n" + fi + fi +done diff --git a/fsx-ontap-aws-cli-scripts/list_fsxn_volumes b/fsx-ontap-aws-cli-scripts/list_fsxn_volumes new file mode 100755 index 0000000..e4bf48c --- /dev/null +++ b/fsx-ontap-aws-cli-scripts/list_fsxn_volumes @@ -0,0 +1,137 @@ +#!/bin/bash +################################################################################ +# THIS SOFTWARE IS PROVIDED BY NETAPP "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL NETAPP BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR' +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# +################################################################################ +# This script will list all the AWS FSx volumes that a user has access to. +# It will list: +# o Region +# o File System ID +# o File System Name - optional +# o Volume ID +# o Volume Name +# +################################################################################ + +################################################################################ +# This function outputs the usage information and exists. +################################################################################ +usage () { + cat 1>&2 < /dev/null 2>&1; then + : +else + echo "Error, this script requires both the 'aws' and 'jq' commands to run." 1>&2 + exit 1 +fi +# +# Process command line arguments. +allRegions=false +region=$(aws configure list | egrep '^.*egion ' | awk '{print $2}') +includeFsName=false +excludeRoot=false +filter="" +fsid="" +fileSystemName="" +while getopts "r:af:i:nos:" option; do + case "$option" in + r) region="$OPTARG" + ;; + a) allRegions=true + ;; + f) fileSystemName="$OPTARG" + fsid=$(aws fsx describe-file-systems --output=json 2> /dev/null | jq -r ".FileSystems[] | if((.Tags[] | select(.Key == \"Name\") .Value) == \"${fileSystemName}\") then .FileSystemId else empty end" 2> /dev/null) + if [ -z "$fsid" ]; then + echo "Error, failed to find the file system with the file system name of '$OPTARG'." 1>&2 + exit 1 + fi + filter='--filters [{"Name":"file-system-id","Values":["'$fsid'"]}]' + ;; + i) fileSystemName=$(aws fsx describe-file-systems --output=json 2> /dev/null | jq -r ".FileSystems[] | if(.FileSystemId == \"$OPTARG\") then (.Tags[] | select(.Key == \"Name\") .Value) else empty end" 2> /dev/null) + if [ -z "$fileSystemName" ]; then + echo "Error, failed to find the file system with the file system ID of '$OPTARG'." 1>&2 + exit 1 + fi + filter='--filters [{"Name":"file-system-id","Values":["'$OPTARG'"]}]' + ;; + n) includeFsName=true + ;; + o) excludeRoot=true + er="and (.OntapConfiguration.StorageVirtualMachineRoot | not)" + ;; + s) svmID="$OPTARG" + ;; + *) echo "Error, unknown option '$option'." 1>&2 + usage + ;; + esac +done + +if [ "$allRegions" = "true" ]; then + regions=$(aws ec2 describe-regions --query "Regions[].RegionName" --output=json | jq -r '.[]') +else + regions=$region +fi +# +# Loop on all the regions. +for region in $regions; do + # + # Check that the fsx service is supported in thie region + if [ ! -z "$(getent hosts fsx.$region.amazonaws.com)" ]; then + if [ -z "$svmID" ]; then + if [ "$excludeRoot" != "true" ]; then + aws fsx describe-volumes $filter --region=$region --output=json | jq -r '.Volumes[] | .FileSystemId + "," + .Name + "," + .VolumeId' | sort > $tmpout + else + aws fsx describe-volumes $filter --region=$region --output=json | jq -r '.Volumes[] | if(.OntapConfiguration.StorageVirtualMachineRoot | not) then .FileSystemId + "," + .Name + "," + .VolumeId else empty end' | sort > $tmpout + fi + else + if [ "$excludeRoot" != "true" ]; then + aws fsx describe-volumes $filter --region=$region --output=json | jq -r ".Volumes[] | if(.OntapConfiguration.StorageVirtualMachineId == \"$svmID\") then .FileSystemId + \",\" + .Name + \",\" + .VolumeId else empty end" | sort > $tmpout + else + aws fsx describe-volumes $filter --region=$region --output=json | jq -r ".Volumes[] | if(.OntapConfiguration.StorageVirtualMachineId == \"$svmID\" and (.OntapConfiguration.StorageVirtualMachineRoot | not)) then .FileSystemId + \",\" + .Name + \",\" + .VolumeId else empty end" | sort > $tmpout + fi + fi + + if [ $includeFsName == "true" ]; then + aws fsx describe-file-systems --region=$region --output=json | jq -r '.FileSystems[] | .FileSystemId + "," + (.Tags[] | select(.Key == "Name") .Value)' | fgrep "$fileSystemName" > $tmpout2 + awk -F, -v region=$region 'BEGIN {first=1; maxNameLen=0; while(getline < "'$tmpout2'") {fss[$1]=$2; if(length($2) > maxNameLen) {maxNameLen=length($2)}}; maxNameLen +=2; formatStr="%12s %20s%-"maxNameLen"s %23s %s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "(Name)", "Volume ID", "Volume Name"; first=0}; name="("fss[$1]")"; printf formatStr, region, $1, name, $3, $2}' < $tmpout + else + awk -F, -v region=$region 'BEGIN {first=1; formatStr="%12s %23s %23s %s\n"}; {if(first) {printf "\n"; printf formatStr, "Region", "FileSystem ID", "Volume ID", "Volume Name"; first=0}; printf formatStr, region, $1, $3, $2}' < $tmpout + fi + else + if [ $allRegions != "true" ]; then + printf "The fsx service is currently not supported in the $region region.\n" + fi + fi +done