Add apigw method and update frontend

This commit is contained in:
Santiago Lo Coco 2022-10-29 09:17:44 -03:00
parent a606aa0d40
commit e6399c8d30
14 changed files with 312 additions and 195 deletions

View File

@ -9,11 +9,18 @@ resource "aws_api_gateway_rest_api" "this" {
}
resource "aws_api_gateway_resource" "this" {
path_part = "resource"
path_part = "products"
parent_id = aws_api_gateway_rest_api.this.root_resource_id
rest_api_id = aws_api_gateway_rest_api.this.id
}
resource "aws_api_gateway_method" "stock_get" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_method" "this" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
@ -28,6 +35,15 @@ resource "aws_api_gateway_method" "options" {
authorization = "NONE"
}
resource "aws_api_gateway_integration" "stock_get" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.stock_get.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = var.lambda[1].lambda_function_arn
}
resource "aws_api_gateway_integration" "this" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
@ -67,7 +83,6 @@ resource "aws_api_gateway_integration" "options" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.options.http_method
# integration_http_method = "OPTIONS"
type = "MOCK"
request_parameters = {}
@ -90,8 +105,10 @@ resource "aws_api_gateway_deployment" "this" {
aws_api_gateway_resource.this.id,
aws_api_gateway_method.this.id,
aws_api_gateway_method.options.id,
aws_api_gateway_method.stock_get.id,
aws_api_gateway_integration.this.id,
aws_api_gateway_integration.options.id,
aws_api_gateway_integration.stock_get.id,
]))
}
@ -102,8 +119,16 @@ resource "aws_api_gateway_deployment" "this" {
depends_on = [
aws_api_gateway_integration.options,
aws_api_gateway_integration.this,
aws_api_gateway_integration.stock_get,
aws_api_gateway_method.options,
aws_api_gateway_method.this
aws_api_gateway_method.this,
aws_api_gateway_method.stock_get,
aws_api_gateway_method_response.options200,
aws_api_gateway_method_response.http200,
aws_api_gateway_method_response.stock200,
aws_api_gateway_integration_response.options200,
aws_api_gateway_integration_response.http200,
aws_api_gateway_integration_response.stock200,
]
}
@ -120,12 +145,25 @@ resource "aws_api_gateway_method_response" "http200" {
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "false"
"method.response.header.Access-Control-Allow-Origin" = "true"
}
depends_on = [aws_api_gateway_method.this]
}
resource "aws_api_gateway_method_response" "stock200" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.stock_get.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "true"
}
depends_on = [aws_api_gateway_method.stock_get]
}
resource "aws_api_gateway_method_response" "options200" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
@ -136,9 +174,9 @@ resource "aws_api_gateway_method_response" "options200" {
}
response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = false,
"method.response.header.Access-Control-Allow-Methods" = false,
"method.response.header.Access-Control-Allow-Origin" = false
"method.response.header.Access-Control-Allow-Headers" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Origin" = true
}
depends_on = [aws_api_gateway_method.options]
@ -157,6 +195,19 @@ resource "aws_api_gateway_integration_response" "http200" {
depends_on = [aws_api_gateway_method_response.http200]
}
resource "aws_api_gateway_integration_response" "stock200" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.stock_get.http_method
status_code = aws_api_gateway_method_response.stock200.status_code
selection_pattern = "^2[0-9][0-9]"
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "'*'"
}
depends_on = [aws_api_gateway_method_response.stock200]
}
resource "aws_api_gateway_integration_response" "options200" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
@ -164,9 +215,17 @@ resource "aws_api_gateway_integration_response" "options200" {
status_code = aws_api_gateway_method_response.http200.status_code
response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
"method.response.header.Access-Control-Allow-Methods" = "'OPTIONS,POST'",
"method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS,POST'",
"method.response.header.Access-Control-Allow-Origin" = "'*'"
}
depends_on = [aws_api_gateway_method_response.options200]
}
resource "aws_lambda_permission" "this" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = var.lambda[1].lambda_function_name
principal = "apigateway.amazonaws.com"
source_arn = "${var.lambda[1].lambda_source_arn}:${aws_api_gateway_rest_api.this.id}/*/${aws_api_gateway_method.stock_get.http_method}${aws_api_gateway_resource.this.path}"
}

View File

@ -28,16 +28,6 @@ variable "role_arn" {
type = string
}
variable "lambda_function_arn" {
description = "The ARN of the Lambda function."
type = string
}
variable "lambda_source_arn" {
type = string
}
variable "lambda_function_name" {
description = "Name of the lambda function"
type = string
variable "lambda" {
type = list(any)
}

View File

@ -11,11 +11,20 @@ module "apigw" {
name = "AWSAPIGateway-g3"
description = "..."
lambda_function_arn = module.lambda["lambda"].lambda_function_arn
lambda_function_name = module.lambda["lambda"].lambda_function_name
lambda_source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}"
lambda = [
{
lambda_function_arn = module.lambda["lambdaSQS"].lambda_function_arn
lambda_function_name = module.lambda["lambdaSQS"].lambda_function_name
lambda_source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}"
},
{
lambda_function_arn = module.lambda["lambdaDB"].lambda_function_arn
lambda_function_name = module.lambda["lambdaDB"].lambda_function_name
lambda_source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}"
}
]
role_arn = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/LabRole"
# sqs_arn = "arn:aws:sqs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:AWS-SQS-g3"
sqs_arn = "arn:aws:apigateway:${data.aws_region.current.name}:sqs:path/AWS-SQS-g3"
tags = {

View File

@ -20,11 +20,16 @@ data "template_file" "userdata" {
data "aws_iam_policy_document" "this" {
statement {
effect = "Allow"
actions = ["dynamodb:PutItem"]
actions = [
"dynamodb:PutItem",
"dynamodb:Scan",
"dynamodb:GetItem",
"dynamodb:UpdateItem"
]
principals {
type = "AWS"
identifiers = ["*"]
}
resources = ["arn:aws:dynamodb:us-east-1:478157316333:table/AWSDynamoDB-g3"]
resources = ["arn:aws:dynamodb:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:table/AWSDynamoDB-g3"]
}
}

View File

@ -1,35 +1,39 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
<title>BSMSapp</title>
<div align="center">
</head>
<div class="d-flex flex-column justify-content-center w-100 h-100">
<head>
<title>BSMSapp</title>
<div align="center">
</head>
<div class="d-flex flex-column justify-content-center w-100 h-100">
<br><br>
<body bgcolor="#FFFFFF" text="Black">
<header>
<h1><span id="replace">BSMSapp</span></h1>
</header>
<form id="myForm" class="form-style">
<ul>
<li>
<input value="0" name="id" type="number" />
<span>Enter the product identifier.</span>
</li>
<li>
<input value="0" name="stock" type="number" />
<span>Enter the new stock number.</span>
</li>
<li>
<input type="submit" value="Upload" />
</li>
</ul>
</form>
<button class="style" onclick="get_table()">Get table</button>
<br><br>
<body bgcolor="#FFFFFF" text="Black">
<header>
<h1><span id="replace">BSMSapp</span></h1>
</header>
<form id="myForm" class="form-style">
<ul>
<li>
<input value="0" name="id" type="number"/>
<span>Enter the product identifier.</span>
</li>
<li>
<input value="0" name="stock" type="number"/>
<span>Enter the new stock number.</span>
</li>
<li>
<input type="submit" value="Upload"/>
</li>
</ul>
</form>
</body>
</div>
<table id="table" align="center" border="1px"></table>
</body>
</div>
</html>
@ -39,46 +43,86 @@
e.preventDefault();
const formData = new FormData(thisForm).entries()
const str = JSON.stringify(Object.fromEntries(formData))
console.log(str.replace(/\"/g, ''))
const response = await fetch("${ENDPOINT}/resource", {
const response = await fetch("${ENDPOINT}/products", {
method: 'POST',
headers: {
headers: {
'Content-Type': 'application/json'
},
body: str.replace(/\"/g, '')
});
const result = await response.json();
console.log(result)
});
function adjust_textarea(h) {
h.style.height = "20px";
h.style.height = (h.scrollHeight)+"px";
h.style.height = (h.scrollHeight) + "px";
}
async function get_table() {
const request = await fetch("${ENDPOINT}/products", {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const list = await request.json();
var cols = [];
for (var i = 0; i < list.length; i++) {
for (var k in list[i]) {
if (cols.indexOf(k) === -1) {
cols.push(k);
}
}
}
var table = document.createElement("table");
var tr = table.insertRow(-1);
for (var i = 0; i < cols.length; i++) {
var theader = document.createElement("th");
theader.innerHTML = cols[i];
tr.appendChild(theader);
}
for (var i = 0; i < list.length; i++) {
trow = table.insertRow(-1);
for (var j = 0; j < cols.length; j++) {
var cell = trow.insertCell(-1);
cell.innerHTML = list[i][cols[j]];
}
}
var el = document.getElementById("table");
el.innerHTML = "";
el.appendChild(table);
}
</script>
<style type="text/css">
body {
background: linear-gradient(-45deg, #ee7752, #df6493, #23a6d5, #23d5ab);
/* background-color: rgba(0, 0, 0, 0.1); */
background-size: 400% 400%;
animation: gradient 15s ease infinite;
height: 100vh;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
header h1 {
font-size: 70px;
font-weight: 600;
@ -87,40 +131,46 @@
background-clip: text;
-webkit-background-clip: text;
}
.form-style{
max-width:400px;
margin:50px auto;
background:#fff;
border-radius:2px;
padding:20px;
.form-style {
max-width: 400px;
margin: 50px auto;
background: #fff;
border-radius: 2px;
padding: 20px;
font-family: Georgia, "Times New Roman", Times, serif;
}
.form-style h1{
.form-style h1 {
display: block;
text-align: center;
padding: 0;
margin: 0px 0px 20px 0px;
color: #5C5C5C;
font-size:x-large;
font-size: x-large;
}
.form-style ul{
list-style:none;
padding:0;
margin:0;
.form-style ul {
list-style: none;
padding: 0;
margin: 0;
}
.form-style li{
.form-style li {
display: block;
padding: 9px;
border:1px solid #DDDDDD;
border: 1px solid #DDDDDD;
margin-bottom: 30px;
border-radius: 3px;
}
.form-style li:last-child{
border:none;
.form-style li:last-child {
border: none;
margin-bottom: 0px;
text-align: center;
}
.form-style li > label{
.form-style li>label {
display: block;
float: left;
margin-top: -19px;
@ -132,6 +182,7 @@
overflow: hidden;
font-family: Arial, Helvetica, sans-serif;
}
.form-style input[type="text"],
.form-style input[type="date"],
.form-style input[type="datetime"],
@ -142,8 +193,7 @@
.form-style input[type="url"],
.form-style input[type="password"],
.form-style textarea,
.form-style select
{
.form-style select {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
@ -157,6 +207,7 @@
padding: 0;
font-family: Georgia, "Times New Roman", Times, serif;
}
.form-style input[type="text"]:focus,
.form-style input[type="date"]:focus,
.form-style input[type="datetime"]:focus,
@ -167,24 +218,25 @@
.form-style input[type="url"]:focus,
.form-style input[type="password"]:focus,
.form-style textarea:focus,
.form-style select:focus
{
}
.form-style li > span{
.form-style select:focus {}
.form-style li>span {
background: #F3F3F3;
display: block;
padding: 3px;
margin: 0 -9px -9px -9px;
text-align: center;
color: #C0C0C0;
color: #838383;
font-family: Arial, Helvetica, sans-serif;
font-size: 11px;
}
.form-style textarea{
resize:none;
.form-style textarea {
resize: none;
}
.form-style input[type="submit"],
.form-style input[type="button"]{
.form-style input[type="button"] {
background: #2471FF;
border: none;
padding: 10px 20px 10px 20px;
@ -192,11 +244,36 @@
border-radius: 3px;
color: #D2E2FF;
}
.form-style input[type="submit"]:hover,
.form-style input[type="button"]:hover{
background: #6B9FFF;
color:#fff;
/* .style {
max-width: 400px;
margin: 50px auto;
background: #fff;
border-radius: 2px;
padding: 20px;
font-family: Georgia, "Times New Roman", Times, serif;
} */
.style {
background: #2471FF;
border: none;
padding: 10px 20px 10px 20px;
border-bottom: 3px solid #5994FF;
border-radius: 3px;
color: #D2E2FF;
}
.style:hover {
background: #6B9FFF;
color: #fff;
}
.form-style input[type="submit"]:hover,
.form-style input[type="button"]:hover {
background: #6B9FFF;
color: #fff;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
@ -206,4 +283,34 @@
input[type=number] {
-moz-appearance: textfield;
}
table {
border-collapse: collapse;
font-family: Georgia, "Times New Roman", Times, serif;
}
table td {
padding: 15px;
}
table thead td {
background-color: #54585d;
color: #ffffff;
font-weight: bold;
font-size: 13px;
border: 1px solid #54585d;
}
table tbody td {
color: #636363;
border: 1px solid #dddfe1;
}
table tbody tr {
background-color: #f9fafb;
}
table tbody tr:nth-child(odd) {
background-color: #ffffff;
}
</style>

View File

@ -16,6 +16,6 @@ module "lambda" {
package = each.value.package
iam_role = each.value.role
vpc_subnet_ids = module.vpc.public_subnets
vpc_security_group_ids = [module.vpc.default_security_group_id]
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [aws_security_group.dynamodb_sg.id]
}

View File

@ -1,5 +1,5 @@
locals {
bucket_name = "b123123123123-itba-cloud-computing-g3-test"
bucket_name = "bsmsapp-itba-cloud-computing-g3-test"
path = "../resources"
s3 = {
@ -33,9 +33,16 @@ locals {
}
lambdas = {
lambda = {
package = "${local.path}/lambda/lambda.zip"
function_name = "AWSLambdaHandler-${replace(local.bucket_name, "-", "")}"
lambdaSQS = {
package = "${local.path}/lambda/lambdaSQS.zip"
function_name = "AWSLambdaHandlerAPISQSDBg3test"
role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/LabRole"
handler = "lambda_handler.main"
runtime = "python3.9"
},
lambdaDB = {
package = "${local.path}/lambda/lambdaDB.zip"
function_name = "AWSLambdaHandlerAPIDBg3test"
role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/LabRole"
handler = "lambda_handler.main"
runtime = "python3.9"

View File

@ -10,7 +10,7 @@ module "sqs" {
]
name = "AWS-SQS-g3"
lambda_name = "AWSLambdaHandler-${replace(local.bucket_name, "-", "")}"
lambda_name = module.lambda["lambdaSQS"].lambda_function_name
tags = {
name = "SQS"

View File

@ -3,19 +3,11 @@ locals {
{
rule_number = 100
rule_action = "allow"
from_port = 80
to_port = 80
from_port = 1024
to_port = 65535
protocol = "tcp"
cidr_block = "10.0.1.0/24"
},
{
rule_number = 110
rule_action = "allow"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_block = "10.0.2.0/24"
},
cidr_block = "0.0.0.0/0"
}
]
private_outbound = [
{
@ -24,16 +16,8 @@ locals {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "10.0.1.0/24"
},
{
rule_number = 110
rule_action = "allow"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_block = "10.0.2.0/24"
},
cidr_block = "0.0.0.0/0"
}
]
}
@ -142,32 +126,6 @@ resource "aws_security_group" "dynamodb_sg" {
}
}
# resource "aws_network_acl" "private_nacl" {
# vpc_id = module.vpc.vpc_id
# egress {
# protocol = "tcp"
# rule_no = 200
# action = "allow"
# cidr_block = ["10.0.1.0/24", "10.0.2.0/24"]
# from_port = 443
# to_port = 443
# }
# ingress {
# protocol = "tcp"
# rule_no = 100
# action = "allow"
# cidr_block = ["10.0.1.0/24", "10.0.2.0/24"]
# from_port = 80
# to_port = 80
# }
# tags = {
# Name = "vpc-g3-bsmsapp"
# }
# }
data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
statement {
effect = "Deny"
@ -226,3 +184,6 @@ resource "aws_security_group" "vpc_tls" {
}
}
# output "aws_security_group_dynamodb" {
# value = aws_security_group.dynamodb_sg.id
# }

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
<title>BSMSapp</title>
<div align="center">
</head>
<br><br>
<body bgcolor="#FFFFFF" text="Black">
<h1><span id="replace">BSMSapp</span></h1>
<form id="myForm">
<input value="0" name="id"/>
<br>
<input value="0" name="stock"/>
<br><br>
<input type="submit" value="Upload"/>
</form>
</body>
</div>
</html>
<script>
const thisForm = document.getElementById('myForm');
thisForm.addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(thisForm).entries()
const str = JSON.stringify(Object.fromEntries(formData))
console.log(str.replace(/\"/g, ''))
// let test = {
// id: 212311111,
// stock: 131211
// }
const response = await fetch("${ENDPOINT}/resource", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: str.replace(/\"/g, '')
// body: JSON.stringify(test)
});
const result = await response.json();
console.log(result)
});
</script>

Binary file not shown.

View File

@ -0,0 +1,26 @@
import json
import boto3
from decimal import *
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return str(obj)
return json.JSONEncoder.default(self, obj)
def main (event, context):
client = boto3.resource('dynamodb', region_name="us-east-1")
table = client.Table("AWSDynamoDB-g3")
data = table.scan()["Items"]
resp = {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
},
"body": json.dumps(data, cls=DecimalEncoder)
}
return resp