Guest User

Untitled

a guest
Sep 19th, 2018
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.62 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3.  
  4. helper(){
  5. : '<helper>
  6. - Prints argument input options per arg call
  7. or upon incorrect argument input
  8. <helper>'
  9.  
  10. cat <<-EOF
  11. netsuiteLambda.sh:
  12. -----------
  13.  
  14. REQUIREMENTS:
  15. --------------------------------------------------------------------------
  16. ./netsuiteLambda.sh --inventoryBaseUrl <inventory_server>
  17. --s3_bucket <s3-bucket-name>
  18. --username <user_name>
  19. --password <pass_word>
  20. --subnets <subnet1,subnet2,subnet3..> (no space btwn ,)
  21. --vpc <vpc-name>
  22. --email <email_group_address>
  23. --------------------------------------------------------------------------
  24.  
  25. OPTIONAL:
  26. --------------------------------------------------------------------------
  27. ./netsuiteLambda.sh --help
  28. --------------------------------------------------------------------------
  29.  
  30. --help: Shows usage examples, and explanation of arguments
  31.  
  32. EOF
  33. exit
  34. }
  35.  
  36.  
  37. exit_test(){
  38. : '<exit_test>
  39. - Checks exit status of last process ($1)
  40. - If success: echo $2
  41. - If error: echo $3
  42. - If $4 == `exit`: exit program upon error
  43. <exit_test>'
  44.  
  45. if [[ $1 == 0 ]]; then
  46. echo "$2"
  47. else
  48. echo "$3"
  49. [[ ${4} == "EXIT" ]] && exit
  50. fi
  51. }
  52.  
  53.  
  54. get_args(){
  55. : '<get_args>
  56. - Gathers argument inputs and creates necessary variables
  57. Necessary Arguments:
  58. -------------------
  59. - inventory_url
  60. - s3_bucket
  61. - password
  62. - username
  63. - vpc
  64. - subnets
  65. - email
  66. <get_args>'
  67.  
  68. inventoryBaseUrl=''
  69. outputBucketName=''
  70. password=''
  71. username=''
  72. vpc=''
  73. subnets=''
  74. email=''
  75. epoch=$(date +"%s")
  76.  
  77. topicArn='' #will be added to by sub-routine
  78. s3_arn='' #will be added to by sub-routine
  79.  
  80. counter=0
  81. for arg in "$@";do
  82. arrval="${@:$((counter+2)):1}"
  83. case "$arg" in
  84. --inventory_url)
  85. inventoryBaseUrl+="${arrval}";;
  86. --s3_bucket)
  87. outputBucketName+="${arrval}";;
  88. --password)
  89. password+="${arrval}";;
  90. --username)
  91. username+="${arrval}";;
  92. --vpc)
  93. vpc+="${arrval}";;
  94. --subnets)
  95. subnets+="${arrval}";;
  96. --email)
  97. email+="${arrval}";;
  98. --help)
  99. helper;;
  100. esac
  101. (( counter++ ))
  102. done
  103.  
  104. #All args != `--help` are required
  105. for i in "${inventoryBaseUrl}" "${outputBucketName}" "${password}" "${username}" "${vpc}" "${subnets}" "${email}";do
  106. [[ "${i}" == "" ]] && echo "helper"
  107. done
  108.  
  109. #populate IAM role name to be used
  110. role_name="inventory_netsuite_lambda_s3_role"
  111. #utilizing policy name
  112. policy_name="inventory_netsuite_lambda_s3_policy"
  113.  
  114. : 'COMMENT
  115. echo "inventoryBaseUrl = ${inventoryBaseUrl}"
  116. echo "outputBucketName = ${outputBucketName}"
  117. echo "password = ${password}"
  118. echo "username = ${username}"
  119. echo "vpc = ${vpc}"
  120. echo "subnets = ${subnets}"
  121. echo "email = ${email}"
  122. #COMMENT'
  123. }
  124. get_args "$@"
  125.  
  126.  
  127. create_SNS(){
  128. : '<create_SNS>
  129. - Function will create SNS topic `inventory_netsuite_lambda_notification`
  130. - Function will add email group dictated by `email` argument
  131. <create_SNS>'
  132.  
  133. topic=$(aws sns create-topic --name inventory_netsuite_lambda_notification)
  134. topicArn+=$(echo $topic | sed 's/{.*: "\(.*\)".*/\1/')
  135.  
  136. aws sns subscribe --topic-arn ${topicArn} \
  137. --protocol email \
  138. --notification-endpoint ${email}
  139. #exit test the SNS creation, do not terminate program if SNS not created successfully
  140. exit_test $? "SNS notification created successfully" "!!!SNS notification creation failure. Please create manually."
  141. }
  142. create_SNS
  143.  
  144.  
  145. create_S3(){
  146. : '<create_S3>
  147. - Creates an S3 bucket to house Netsuite CSV dumps (if one does not exist)
  148. - Bucket serves as a trigger for the Lambda function
  149. <create_S3>'
  150.  
  151. mk_bucket(){
  152. aws s3api create-bucket --bucket ${outputBucketName} \
  153. --region us-west-2 \
  154. --create-bucket-configuration LocationConstraint=us-west-2
  155. exit_test $? "Successfully created S3 bucket" "!!!Failed to create bucket" "EXIT"
  156. }
  157.  
  158. #test to see whether or not the bucket already exists
  159. aws s3 ls s3://${outputBucketName} > /dev/null 2>&1
  160. if [[ $? != 0 ]]; then
  161. aws s3 mb s3://${outputBucketName}
  162. exit_test $? "Successfully created S3 bucket" "!!!Failed to create bucket" "EXIT"
  163.  
  164. #create test folder structure within bucket
  165. touch testFile
  166. aws s3 mv testFile s3://${outputBucketName}/testingFolder/testFile
  167. else
  168. echo "Using S3 bucket ${outputBucketName}"
  169. fi
  170. #arn of the s3 bucket, to be used as Lambda target later
  171. s3_arn+="arn:aws:s3:::${outputBucketName}"
  172. echo ${s3_arn}
  173. }
  174. create_S3
  175.  
  176.  
  177. #Permissions data for IAM role:
  178. policy=$(cat <<- EOF
  179. {
  180. "Version": "2012-10-17",
  181. "Statement": [
  182. {
  183. "Sid": "inventoryLambda0",
  184. "Effect": "Allow",
  185. "Action": [
  186. "s3:PutBucketAcl",
  187. "s3:ListBucket"
  188. ],
  189. "Resource": "${s3_arn}"
  190. },
  191. {
  192. "Sid": "inventoryLambda1",
  193. "Effect": "Allow",
  194. "Action": "s3:PutObjectAcl",
  195. "Resource": "${s3_arn}/*"
  196. },
  197. {
  198. "Sid": "inventoryLambda2",
  199. "Effect": "Allow",
  200. "Action": [
  201. "s3:ListAllMyBuckets",
  202. "s3:HeadBucket"
  203. ],
  204. "Resource": "*"
  205. },
  206. {
  207. "Sid": "inventoryLambda3",
  208. "Effect": "Allow",
  209. "Action": "s3:*",
  210. "Resource": [
  211. "${s3_arn}",
  212. "${s3_arn}/*"
  213. ]
  214. },
  215. {
  216. "Sid": "inventoryLambda4",
  217. "Effect": "Allow",
  218. "Action": "sns:Publish",
  219. "Resource": "${topicArn}"
  220. },
  221. {
  222. "Sid": "inventoryLambda5",
  223. "Effect": "Allow",
  224. "Action": [
  225. "ec2:CreateNetworkInterface",
  226. "ec2:DescribeNetworkInterfaces",
  227. "ec2:DeleteNetworkInterface"
  228. ],
  229. "Resource": "*"
  230. },
  231. {
  232. "Sid": "inventoryLambda6",
  233. "Effect": "Allow",
  234. "Action": [
  235. "logs:CreateLogGroup",
  236. "logs:CreateLogStream",
  237. "logs:PutLogEvents"
  238. ],
  239. "Resource": "*"
  240. }
  241. ]
  242. }
  243. EOF
  244. )
  245.  
  246. #Policy file for creating the role:
  247. role=$(cat <<-EOF
  248. {
  249. "Version": "2012-10-17",
  250. "Statement": [
  251. {
  252. "Effect": "Allow",
  253. "Principal": {
  254. "Service": "lambda.amazonaws.com"
  255. },
  256. "Action": "sts:AssumeRole"
  257. }
  258. ]
  259. }
  260. EOF
  261. )
  262.  
  263.  
  264. create_IAM(){
  265. : '<create_IAM>
  266. - Function will create IAM role `inventory_netsuite_lambda_s3_role`,
  267. utilizing a created policy `inventory_netsuite_lambda_s3_policy`
  268. (if the IAM role and policy don`t already exist)
  269. <create_IAM>'
  270.  
  271. echo "${policy}" > snapPolicy.json
  272. echo "${role}" > snapRole.json
  273.  
  274. for file in snapPolicy.json snapRole.json; do
  275. chmod a+r ${file}
  276. done
  277.  
  278. #test to see whether or not role is already created
  279. aws iam get-role --role-name ${role_name} > /dev/null 2>&1
  280.  
  281. if [[ $? == 0 ]]; then
  282. delim=''
  283. for ((i=0;i<64;i++));do
  284. delim+='#'
  285. done
  286. echo -e "\n${delim} \n IAM role ${role_name} already exists"
  287. echo " Please confirm that role has proper Lambda and S3 permissions"
  288. echo -e " Role will be applied to Lambda function\n${delim}\n"
  289. else
  290. #create role:
  291. aws iam create-role --role-name ${role_name} --assume-role-policy-document file://snapRole.json
  292. exit_test $? "IAM role creation succeeded" "!!!IAM role creation failed; exiting" "EXIT"
  293.  
  294. #attach new policy to role:
  295. aws iam put-role-policy --role-name ${role_name} --policy-name ${policy_name} --policy-document file://snapPolicy.json
  296.  
  297. echo "Waiting 30 seconds for new role to be made available within AWS"
  298. for ((i=0;i<31;i++));do
  299. echo $((i-30))
  300. sleep 1
  301. done
  302.  
  303. exit_test $? "Policy attachment succeeded" "!!!Policy attachment failed; exiting" "EXIT"
  304. fi
  305. rm snapPolicy.json
  306. rm snapRole.json
  307. }
  308. create_IAM
  309.  
  310.  
  311. create_SG(){
  312. : '<create_SG>
  313. - Creates a VPC security group, handling traffice on port 53
  314. across TCP and UDP (for CIDR block 10.240.0/16)
  315. <create_SG>'
  316.  
  317. sg_name='lambda-netsuite-inventory-group'
  318.  
  319. #test to see whether or not security group exists, will exit w/ status 1 if group exists
  320. sg_data=$(aws ec2 describe-security-groups --filters Name=group-name,Values=${sg_name})
  321. sg_data=$(echo ${sg_data} | sed 's/ //g')
  322.  
  323. if [[ ${sg_data} == '{"SecurityGroups":[]}' ]]; then
  324. #create the new security group if the json parameter is empty
  325. sg=$(aws ec2 create-security-group --description "Netsuite csv access" --group-name ${sg_name} --vpc-id ${vpc})
  326. exit_test $? "Successfully created Security Group ${sg_name}" "!!!Failed to create Security Group" "EXIT"
  327.  
  328. sg=$(echo ${sg} | sed 's/ //'g)
  329. sg_id=$(echo ${sg} | sed 's/{.*:"\(.*\)".*/\1/')
  330. #add TCP and UDP parameters (specific to Netsuite requirements) to the SG
  331. aws ec2 authorize-security-group-ingress --group-id ${sg_id} --protocol tcp --port 53 --cidr "10.240.0.0/16"
  332. aws ec2 authorize-security-group-ingress --group-id ${sg_id} --protocol udp --port 53 --cidr "10.240.0.0/16"
  333.  
  334. #add name tag to security group
  335. aws ec2 create-tags --resources ${sg_id} --tags Key="Name",Value="${sg_name}"
  336. else
  337. #if security group exists,
  338. echo "security group exists"
  339. sg_id=$(echo ${sg_data} | sed -e 's/{.*"GroupId":"\(.*[0-9a-z]*\)",.*/\1/' -e 's/".*//')
  340. fi
  341. }
  342. create_SG
  343.  
  344.  
  345. create_lambda(){
  346. : '<create_lambda>
  347. - Creates a Lambda function, targetting the S3 bucket
  348. identified by the `outputBucketName` variable
  349. <create_lambda>'
  350.  
  351. role_arn=$(aws iam get-role --role-name ${role_name} | grep "Arn" | awk '{print $2}' | sed 's/,//' | sed 's/"//g')
  352.  
  353. lambda_name="inventory-netsuite-s3-lambda-function"
  354.  
  355. env_string="Variables={inventoryBaseUrl=${inventoryBaseUrl},outputBucketName=${outputBucketName},"
  356. env_string+="password=${password},topicArn=${topicArn},username=${username}}"
  357.  
  358. lambda_mk(){
  359. #subproc to create lambda function
  360. aws lambda create-function \
  361. --function-name ${lambda_name} \
  362. --runtime nodejs8.10 \
  363. --role ${role_arn} \
  364. --zip-file fileb://Archive.zip \
  365. --handler index.handler \
  366. --environment ${env_string} \
  367. --timeout 150 \
  368. --memory-size 256 \
  369. --vpc-config SubnetIds=${subnets},SecurityGroupIds=${sg_id}
  370. }
  371.  
  372. lambda_s3_perm(){
  373. #subproc to add s3 permissions to Lambda function
  374. aws lambda add-permission \
  375. --function-name ${lambda_name} \
  376. --action lambda:InvokeFunction \
  377. --principal s3.amazonaws.com \
  378. --source-arn ${s3_arn} \
  379. --statement-id 1
  380. }
  381.  
  382.  
  383.  
  384. #test current existence of Lambda function
  385. aws lambda get-function --function-name ${lambda_name} > /dev/null 2>&1
  386. if [[ $? != 0 ]]; then
  387. lambda_mk
  388.  
  389. lambda_arn=$(aws lambda get-function --function-name ${lambda_name} | grep "FunctionArn" | awk '{print $2}' | sed 's/,//' | sed 's/"//g')
  390. #Trigger policy for Lambda S3 targetting
  391. s3_trigger=$(cat << EOF
  392. {
  393. "LambdaFunctionConfigurations": [
  394. {
  395. "Id": "lambda-s3-event-configuration",
  396. "LambdaFunctionArn": "${lambda_arn}",
  397. "Events": [ "s3:ObjectCreated:Put" ],
  398. "Filter": {
  399. "Key": {
  400. "FilterRules": [
  401. {
  402. "Name": "suffix",
  403. "Value": ".csv"
  404. },
  405. {
  406. "Name": "prefix",
  407. "Value": "testingFolder/netsuite"
  408. }
  409. ]
  410. }
  411. }
  412. }
  413. ]
  414. }
  415. EOF
  416. )
  417.  
  418. #add S3 bucket as a target to the Lambda function
  419. lambda_s3_perm
  420.  
  421. echo ${s3_trigger} > s3.json
  422. chmod 755 s3.json
  423. aws s3api put-bucket-notification-configuration --bucket ${outputBucketName} --notification-configuration file://s3.json
  424. rm s3.json
  425. else
  426. echo "${lambda_name} already exists!! Exiting"
  427. fi
  428. }
  429. create_lambda
Add Comment
Please, Sign In to add comment