11#! /bin/bash
22
33# user data
4- # Set the secret name and region
5- SECRET_NAME=[Secret name has it been saved in AWS secret manager]
6- AWS_REGION=[AWS region]
7-
8- FSXN_ADMIN_IP=[Fsx admin ip, e.g. 172.25.45.32]
9- # Volume name
10- VOLUME_NAME=[Fsx volume name, e.g. iscsiVol]
11- # Volume size in GB
12- VOLUME_SIZE=[volume size in GB, e.g 100]
4+ # Secret name has it been saved in AWS secret manager
5+ SECRET_NAME=
6+ AWS_REGION=
7+ # Fsx admin ip, e.g. 172.25.45.32
8+ FSXN_ADMIN_IP=
9+ # FSxN Volume name , e.g. iscsiVol
10+ VOLUME_NAME=
11+ # Volume size in GB e.g 100
12+ VOLUME_SIZE=
1313# Default value is fsx, but you can change it to any other value according to yours FSx for ONTAP SVM name
1414SVM_NAME=fsx
1515# Default value is fsxadmin, but you can change it to any other value according to yours FSx for ONTAP admin user name
1616ONTAP_USER=fsxadmin
1717# end - user data
1818
19+ SECRET_NAME=" ${SECRET_NAME:= $1 } "
20+ AWS_REGION=" ${AWS_REGION:= $2 } "
21+ FSXN_ADMIN_IP=" ${FSXN_ADMIN_IP:= $3 } "
22+ VOLUME_NAME=" ${VOLUME_NAME:= $4 } "
23+ VOLUME_SIZE=" ${VOLUME_SIZE:= $5 } "
24+
1925min=100
2026max=999
2127LUN_NAME=${VOLUME_NAME} _$(( $RANDOM % ($max - $min + 1 )+ $min ))
2228
2329# defaults
2430# The script will create a log file in the ec2-user home directory
2531LOG_FILE=/home/ec2-user/install.log
32+ TIMEOUT=5
2633
2734LUN_SIZE=$( bc -l <<< " 0.90*$VOLUME_SIZE" )
2835
@@ -91,7 +98,6 @@ if [ "$isIscsciServiceRunning" -eq 1 ]; then
9198 addUndoCommand " systemctl --now disable iscsid.service"
9299else
93100 logMessage " iscsi service is not running, aborting"
94- # now we have to rollback and exit
95101 ./uninstall.sh
96102fi
97103
@@ -106,94 +112,175 @@ name=$(cat /etc/iscsi/initiatorname.iscsi)
106112initiatorName=" ${name: 14} "
107113logMessage " initiatorName is: ${initiatorName} "
108114
109- # Configure iSCSI on the FSx for ONTAP file system
110- commandDescription=" Install sshpass which will allow to connect FSXn using SSH"
111- logMessage " ${commandDescription} "
112- yum install -y sshpass
113- checkCommand " ${commandDescription} "
114- addUndoCommand " yum remove -y sshpass"
115-
116115# Test connection to ONTAP
117- commandDescription=" Testing connection to ONTAP."
118- logMessage " ${commandDescription} "
119- sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " version"
120- checkCommand " ${commandDescription} "
116+ logMessage " Testing connection to ONTAP."
117+
118+ versionResponse=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/cluster?fields=version" )
119+ if [[ " $versionResponse " == * " version" * ]]; then
120+ logMessage " Connection to ONTAP is successful."
121+ else
122+ logMessage " Connection to ONTAP failed, aborting."
123+ ./uninstall.sh
124+ fi
121125
122126# group name should be the hostname of the linux host
123127groupName=$( hostname)
124128
125- commandDescription=" Create initiator group for vserver: ${SVM_NAME} group name: ${groupName} and intiator name: ${initiatorName} "
129+ iGroupResult=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/protocols/san/igroups?svm.name=$SVM_NAME &name=$groupName &initiators.name=$initiatorName &protocol=iscsi&os_type=linux" )
130+ initiatorExists=$( echo " ${iGroupResult} " | jq ' .num_records' )
126131
127- lunGroupresult=$( sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun igroup show -vserver $SVM_NAME -igroup $groupName -initiator $initiatorName -protocol iscsi -ostype linux" )
128- if [[ " $lunGroupresult " == * " There are no entries matching your query." * ]]; then
132+ if [ " $initiatorExists " -eq 0 ]; then
129133 logMessage " Initiator ${initiatorName} with group ${groupName} does not exist, creating it."
130- logMessage " ${commandDescription} "
131- sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun igroup create -vserver $SVM_NAME -igroup $groupName -initiator $initiatorName -protocol iscsi -ostype linux"
132- checkCommand " ${commandDescription} "
133- addUndoCommand " sshpass -p \" ${FSXN_PASSWORD} \" ssh -o StrictHostKeyChecking=no ${ONTAP_USER} @${FSXN_ADMIN_IP} lun igroup delete -vserver ${SVM_NAME} -igroup ${groupName} -force"
134+ logMessage " Create initiator group for vserver: ${SVM_NAME} group name: ${groupName} and intiator name: ${initiatorName} "
135+ createGroupResult=$( curl -m $TIMEOUT -X POST -u " $ONTAP_USER " :" $FSXN_PASSWORD " -H " Content-Type: application/json" -k " https://$FSXN_ADMIN_IP /api/protocols/san/igroups" -d ' {
136+ "protocol": "iscsi",
137+ "initiators": [
138+ {
139+ "name": "' $initiatorName ' "
140+ }
141+ ],
142+ "os_type": "linux",
143+ "name": "' $groupName ' ",
144+ "svm": {
145+ "name": "' $SVM_NAME ' "
146+ }
147+ }' )
148+ iGroupResult=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/protocols/san/igroups?svm.name=$SVM_NAME &name=$groupName &initiators.name=$initiatorName &protocol=iscsi&os_type=linux" )
149+ iGroupUuid=$( echo ${iGroupResult} | jq -r ' .records[] | select(.name == "' $groupName ' " ) | .uuid' )
150+ # Check if iGroup was created successfully
151+ if [ -n " $iGroupUuid " ]; then
152+ logMessage " Initiator group ${groupName} was created successfully with UUID: ${iGroupUuid} "
153+ else
154+ logMessage " Initiator group ${groupName} was not created, aborting"
155+ ./uninstall.sh
156+ fi
157+ # Add undo command for iGroup creation
158+ addUndoCommand " curl -m $TIMEOUT -X DELETE -u \" $ONTAP_USER \" :\" $FSXN_PASSWORD \" -k \" https://$FSXN_ADMIN_IP /api/protocols/san/igroups/$iGroupUuid \" "
134159else
135160 logMessage " Initiator ${initiatorName} with group ${groupName} already exists, skipping creation."
136161fi
137162
138- # confirm that igroup was created
139- isInitiatorGroupCreadted=$( sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun igroup show -igroup $groupName -protocol iscsi" | grep $groupName | wc -l)
140- if [ " $isInitiatorGroupCreadted " -eq 1 ]; then
141- logMessage " Initiator group ${groupName} was created"
142- else
143- logMessage " Initiator group ${groupName} was not created, aborting"
144- # now we have to rollback and exit
163+ instance_id=$( ec2-metadata -i | awk ' {print $2}' )
164+ if [ -z " $instance_id " ]; then
165+ instance_id=" unknown"
166+ fi
167+
168+ logMessage " Create volume for vserver: ${SVM_NAME} volume name: ${VOLUME_NAME} and size: ${VOLUME_SIZE} g"
169+ createVolumeResult=$( curl -m $TIMEOUT -X POST -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/storage/volumes" -d ' {
170+ "name": "' $VOLUME_NAME ' ",
171+ "size": "' $VOLUME_SIZE ' g",
172+ "state": "online",
173+ "svm": {
174+ "name": "' $SVM_NAME ' "
175+ },
176+ "aggregates": [{
177+ "name": "aggr1"
178+ }],
179+ "_tags": [
180+ "instanceId:' $instance_id ' ",
181+ "hostName:' $( hostname) ' ",
182+ "mountPoint:' $VOLUME_NAME ' "
183+ ]
184+ }' )
185+ sleep 10
186+ jobId=$( echo " ${createVolumeResult} " | jq -r ' .job.uuid' )
187+ jobStatus=$( curl -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/cluster/jobs/$jobId " )
188+ jobState=$( echo " $jobStatus " | jq -r ' .state' )
189+ if [ " $jobState " != " success" ]; then
190+ logMessage " Volume creation job did not complete successfully, aborting"
191+ jobError=$( echo " $jobStatus " | jq -r ' .error' )
192+ logMessage " Error details: $jobError "
145193 ./uninstall.sh
146194fi
147195
148- commandDescription=" Create volume for vserver: ${SVM_NAME} volume name: ${VOLUME_NAME} and size: ${VOLUME_SIZE} g"
149- logMessage " ${commandDescription} "
150- sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " volume create -vserver ${SVM_NAME} -volume ${VOLUME_NAME} -aggregate aggr1 -size ${VOLUME_SIZE} g -state online"
151- checkCommand " ${commandDescription} "
152- addUndoCommand " sshpass -p \" $FSXN_PASSWORD \" ssh -o StrictHostKeyChecking=no ${ONTAP_USER} @${FSXN_ADMIN_IP} volume delete -vserver ${SVM_NAME} -volume ${VOLUME_NAME} -force"
196+ # validate if volume was created successfully
197+ volumeResult=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/storage/volumes?name=${VOLUME_NAME} &svm.name=${SVM_NAME} " )
198+ volumeUUid=$( echo " ${volumeResult} " | jq -r ' .records[] | select(.name == "' $VOLUME_NAME ' " ) | .uuid' )
199+ if [ -n " $volumeUUid " ]; then
200+ logMessage " Volume ${VOLUME_NAME} was created successfully with UUID: ${volumeUUid} "
201+ else
202+ logMessage " Volume ${VOLUME_NAME} was not created, aborting"
203+ ./uninstall.sh
204+ fi
205+ addUndoCommand " curl -m $TIMEOUT -X DELETE -u \" $ONTAP_USER \" :\" $FSXN_PASSWORD \" -k \" https://$FSXN_ADMIN_IP /api/storage/volumes/${volumeUUid} \" "
206+
207+ logMessage " Create iscsi lun for vserver: ${SVM_NAME} volume name: ${VOLUME_NAME} and lun name: ${LUN_NAME} and size: ${LUN_SIZE} g which is 90% of the volume size"
208+ createLunResult=$( curl -m $TIMEOUT -X POST -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/storage/luns" -d ' {
209+ "name": "' /vol/${VOLUME_NAME} /$LUN_NAME ' ",
210+ "space": {
211+ "size": "' $LUN_SIZE ' GB",
212+ "scsi_thin_provisioning_support_enabled": true
213+ },
214+ "svm": {
215+ "name": "' $SVM_NAME ' "
216+ },
217+ "os_type": "linux"
218+ }' )
219+ lunResult=$( curl -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/storage/luns?fields=uuid&name=/vol/${VOLUME_NAME} /$LUN_NAME " )
220+ # Validate if LUN was created successfully
221+ lunUuid=$( echo " ${lunResult} " | jq -r ' .records[] | select(.name == "' /vol/${VOLUME_NAME} /$LUN_NAME ' " ) | .uuid' )
222+ if [ -n " $lunUuid " ]; then
223+ logMessage " LUN ${LUN_NAME} was created successfully with UUID: ${lunUuid} "
224+ else
225+ logMessage " LUN ${LUN_NAME} was not created, aborting"
226+ ./uninstall.sh
227+ fi
153228
154- commandDescription=" Create iscsi lun for vserver: ${SVM_NAME} volume name: ${VOLUME_NAME} and lun name: ${LUN_NAME} and size: ${LUN_SIZE} g which is 90% of the volume size"
155- logMessage " ${commandDescription} "
156- sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun create -vserver ${SVM_NAME} -path /vol/${VOLUME_NAME} /$LUN_NAME -size ${LUN_SIZE} g -ostype linux -space-allocation enabled"
157- checkCommand " ${commandDescription} "
158- addUndoCommand " sshpass -p \" $FSXN_PASSWORD \" ssh -o StrictHostKeyChecking=no ${ONTAP_USER} @${FSXN_ADMIN_IP} lun delete -vserver ${SVM_NAME} -path /vol/${VOLUME_NAME} /${LUN_NAME} -force"
229+ addUndoCommand " curl -m $TIMEOUT -X DELETE -u \" $ONTAP_USER \" :\" $FSXN_PASSWORD \" -k \" https://$FSXN_ADMIN_IP /api/storage/luns/${lunUuid} \" "
159230
160- # Create a mapping from the LUN you created to the igroup you created
161231# The LUN ID integer is specific to the mapping, not to the LUN itself.
162- # This is used by the initiators in the igroup as the Logical Unit Number use this value for the initiator when accessing the storage.
163- commandDescription=" Create a mapping from the LUN you created to the igroup you created"
164- logMessage " ${commandDescription} "
165- lun_id=0
166- sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun mapping create -vserver ${SVM_NAME} -path /vol/${VOLUME_NAME} /${LUN_NAME} -igroup ${groupName} -lun-id 0"
167- checkCommand " ${commandDescription} "
168-
169- commandDescription=" Validate the lun mapping was created"
170- logMessage " ${commandDescription} "
171- serialHex=$( sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " lun show -path /vol/${VOLUME_NAME} /${LUN_NAME} -fields state,mapped,serial-hex" | grep $SVM_NAME | awk ' {print $3}' )
172- if [ -n " $serialHex " ]; then
173- logMessage " Lun mapping was created"
232+ # This is used by the initiators in the igroup as the Logical Unit Number. Use this value for the initiator when accessing the storage.
233+ logMessage " Create a mapping from the LUN you created to the igroup you created"
234+
235+ lunMapResult=$( curl -m $TIMEOUT -X POST -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/protocols/san/lun-maps" -d ' {
236+ "lun": {
237+ "name": "/vol/' ${VOLUME_NAME} ' /' ${LUN_NAME} ' "
238+ },
239+ "igroup": {
240+ "name": "' ${groupName} ' "
241+ },
242+ "svm": {
243+ "name": "' ${SVM_NAME} ' "
244+ },
245+ "logical_unit_number": 0
246+ }' )
247+ logMessage " Validate the lun mapping was created"
248+
249+ getLunMap=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/protocols/san/lun-maps?lun.name=/vol/${VOLUME_NAME} /${LUN_NAME} &igroup.name=${groupName} &svm.name=${SVM_NAME} " )
250+ lunGroupCreated=$( echo " ${getLunMap} " | jq -r ' .num_records' )
251+ if [ " $lunGroupCreated " -eq 0 ]; then
252+ logMessage " LUN mapping was not created, aborting"
253+ ./uninstall.sh
174254else
175- logMessage " Lun mapping was not created, aborting"
176- addUndoCommand " sshpass -p \" ${FSXN_PASSWORD} \" ssh -o StrictHostKeyChecking=no ${ONTAP_USER} @${FSXN_ADMIN_IP} lun mapping delete -vserver ${SVM_NAME} -path /vol/${VOLUME_NAME} /${LUN_NAME} -igroup ${groupName} "
255+ logMessage " LUN mapping was created successfully"
177256fi
178257
179- # The serail hex in needed for creating readable name for the block device.
180- commandDescription=" Get the iscsi interface addresses for the svm ${SVM_NAME} "
181- logMessage " ${commandDescription} "
182- iscsi1IP=$( sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " network interface show -vserver ${SVM_NAME} " | grep -e iscsi_1 | awk ' {print $3}' )
183- iscsi2IP=$( sshpass -p " $FSXN_PASSWORD " ssh -o StrictHostKeyChecking=no $ONTAP_USER @$FSXN_ADMIN_IP " network interface show -vserver ${SVM_NAME} " | grep -e iscsi_2 | awk ' {print $3}' )
258+ addUndoCommand " curl -m $TIMEOUT -X DELETE -u \" $ONTAP_USER \" :\" $FSXN_PASSWORD \" -k \" https://$FSXN_ADMIN_IP /api/protocols/san/lun-maps?lun.name=/vol/${VOLUME_NAME} /${LUN_NAME} &igroup.name=${groupName} &svm.name=${SVM_NAME} \" "
259+
260+ # The serial hex in needed for creating readable name for the block device.
261+ getLunSerialNumberResult=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/storage/luns?fields=serial_number" )
262+ serialNumber=$( echo " ${getLunSerialNumberResult} " | jq -r ' .records[] | select(.name == "' /vol/$VOLUME_NAME /$LUN_NAME ' " ) | .serial_number' )
263+ serialHex=$( echo -n " ${serialNumber} " | xxd -p)
264+ if [ -z " $serialHex " ]; then
265+ logMessage " Serial number for the LUN is not available, aborting"
266+ ./uninstall.sh
267+ fi
268+
269+ logMessage " Get the iscsi interface addresses for the svm ${SVM_NAME} "
270+ getInterfacesResult=$( curl -m $TIMEOUT -X GET -u " $ONTAP_USER " :" $FSXN_PASSWORD " -k " https://$FSXN_ADMIN_IP /api/network/ip/interfaces?svm.name=$SVM_NAME &fields=ip" )
271+ iscsi1IP=$( echo " $getInterfacesResult " | jq -r ' .records[] | select(.name == "iscsi_1") | .ip.address' )
272+ iscsi2IP=$( echo " $getInterfacesResult " | jq -r ' .records[] | select(.name == "iscsi_2") | .ip.address' )
184273
185- if [ -n " $i$ iscsi1IP " ] && [ -n " $iscsi2IP " ]; then
274+ if [ -n " $iscsi1IP " ] && [ -n " $iscsi2IP " ]; then
186275 iscsi1IP=$( echo ${iscsi1IP%/* } )
187276 iscsi2IP=$( echo ${iscsi2IP%/* } )
188277 logMessage " iscsi interface addresses for the svm ${SVM_NAME} are: ${iscsi1IP} and ${iscsi2IP} "
189278else
190279 logMessage " iscsi interface addresses for the svm ${SVM_NAME} are not available, aborting"
191- # now we have to rollback and exit
192280 ./uninstall.sh
193281fi
194282
195- commandDescription=" Discover the target iSCSI nodes, iscsi IP: ${iscsi1IP} "
196- logMessage " ${commandDescription} "
283+ logMessage " Discover the target iSCSI nodes, iscsi IP: ${iscsi1IP} "
197284iscsiadm --mode discovery --op update --type sendtargets --portal $iscsi1IP
198285checkCommand " ${commandDescription} "
199286addUndoCommand " iscsiadm --mode discovery --op delete --type sendtargets --portal ${iscsi1IP} "
@@ -219,8 +306,7 @@ addUndoCommand "iscsiadm --mode node -T $targetInitiator --logout"
219306# }
220307# }
221308# Assign name to block device, this should be function that will get serial hex and device name
222- commandDescription=" Update /etc/multipath.conf file, Assign name to block device."
223- logMessage " ${commandDescription} "
309+ logMessage " Update /etc/multipath.conf file, Assign name to block device."
224310cp /etc/multipath.conf /etc/multipath.conf_backup
225311
226312SERIAL_HEX=$serialHex
266352
267353# Partition the LUN
268354# mount the LUN on the Linux client
269-
270355# Create a directory directory_path as the mount point for your file system.
271356directory_path=mnt
272357mount_point=$VOLUME_NAME
@@ -277,8 +362,7 @@ mkdir /$directory_path/$mount_point
277362checkCommand " ${commandDescription} "
278363addUndoCommand " rm -rf /$directory_path /$mount_point "
279364
280- # check this command
281- # volume_name=the friendly device name as we set it in the multipath.conf file
365+ # volume_name = the friendly device name as we set it in the multipath.conf file
282366commandDescription=" Creating the file system for the new partition: /dev/mapper/${ALIAS} "
283367logMessage " ${commandDescription} "
284368mkfs.ext4 /dev/mapper/$ALIAS
@@ -310,5 +394,4 @@ addUndoCommand "sed -i '/\/dev\/mapper\/$ALIAS \/mnt\/$mount_point ext4 defaults
310394# End of script
311395logMessage " Script completed successfully."
312396
313-
314- rm -f uninstall.sh
397+ rm -f uninstall.sh
0 commit comments