Skip to content

Commit 2d758fe

Browse files
authored
Merge pull request #98 from roahoki/development
Initial release: Version 1.1.0
2 parents a8ce9b5 + a135263 commit 2d758fe

20 files changed

+1495
-63
lines changed

Diff for: README.md

+104
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ MQTT_PORT = 9000
3131
MQTT_USER = students
3232
MQTT_PASSWORD = iic2173-2024-2-students
3333
MQTT_PROTOCOL = mqtt
34+
35+
CELERY_BROKER_URL=redis://redis-broker:6379/0
36+
CELERY_RESULT_BACKEND=redis://redis-broker:6379/0
3437
```
3538

3639
2. Bajar contenedores de docker si están arriba:
@@ -328,3 +331,104 @@ En nuestro caso, en el frontend cuando se presiona Generar Boleta se hace una ll
328331
# Pasos Workers
329332

330333
Redis y celery hace una abstracción del uso de encolamiento y el acceso de los consumers vía polling para la realización de las tareas, por lo que al levantar el back las recomendaciones se realizarán accediendo al back
334+
335+
336+
# Flujos y pasos en la configuración de IaaC
337+
338+
La configuración de **Infrastructure as Code (IaaC)** se realiza utilizando AWS CDK (Cloud Development Kit) en un stack llamado `my-cdk-project-stack`. Este stack crea y configura automáticamente los recursos de AWS necesarios para la operación del backend de la aplicación **The Goat BACKEND**.
339+
340+
#### Flujo de Configuración del Código
341+
1. **Inicialización del App**
342+
- El archivo principal `bin/my-cdk-project.ts` contiene la inicialización de la aplicación CDK.
343+
- Configura la cuenta y la región donde se desplegarán los recursos:
344+
```typescript
345+
const app = new cdk.App();
346+
new BackendInfrastructureStack(app, 'BackendInfrastructureStack', {
347+
env: {
348+
account: '577638367697',
349+
region: 'us-east-2'
350+
},
351+
description: 'Infrastructure stack for existing backend instance'
352+
});
353+
```
354+
355+
2. **Referenciar Recursos Existentes**
356+
- Se reutilizan recursos como la **VPC** y una instancia **EC2** existentes, lo que garantiza eficiencia y consistencia en la infraestructura.
357+
358+
3. **Creación de Recursos**
359+
- Se definen y configuran nuevos recursos, como un bucket **S3** para registros y respaldos, alarmas de **CloudWatch** para monitoreo, un tópico **SNS** para notificaciones, y un **Security Group** adicional para el control del tráfico de red.
360+
361+
4. **Asignación de Roles y Políticas**
362+
- Se crea un rol **IAM** con permisos específicos para acceder al bucket de S3 y a **AWS Systems Manager**, asegurando que la instancia EC2 tenga los privilegios necesarios para gestionar la infraestructura de manera segura.
363+
364+
5. **Alertas y Monitoreo**
365+
- Se configuran alarmas de **CloudWatch** para supervisar la utilización de CPU y los fallos en los checks de estado de la instancia EC2, enviando notificaciones al tópico SNS en caso de problemas.
366+
367+
6. **Salida de Información**
368+
- Se generan outputs útiles (como el ARN del tópico SNS, el nombre del bucket S3 y el ID de la instancia EC2) para facilitar el acceso a los recursos configurados.
369+
370+
#### Pasos de Implementación
371+
372+
1. **Instalar AWS CDK y Configurar el Entorno**
373+
- Instala AWS CDK con `npm install -g aws-cdk`.
374+
- Configura las credenciales de AWS utilizando `aws configure`.
375+
376+
2. **Definir el Stack**
377+
- El código de configuración se encuentra en `lib/my-cdk-project-stack.ts` y la inicialización del app en `bin/my-cdk-project.ts`.
378+
379+
3. **Inicializar y Desplegar el Stack**
380+
- Asegúrate de instalar las dependencias del proyecto:
381+
```bash
382+
npm install
383+
```
384+
- Ejecuta el comando para sintetizar el stack:
385+
```bash
386+
cdk synth
387+
```
388+
- Despliega el stack en tu cuenta de AWS:
389+
```bash
390+
cdk deploy
391+
```
392+
- Confirma los cambios durante el despliegue si es necesario.
393+
394+
4. **Detalles del Código**
395+
- **Inicializar el App:**
396+
```typescript
397+
const app = new cdk.App();
398+
new BackendInfrastructureStack(app, 'BackendInfrastructureStack', {
399+
env: {
400+
account: '577638367697',
401+
region: 'us-east-2'
402+
},
403+
description: 'Infrastructure stack for existing backend instance'
404+
});
405+
```
406+
- **Referenciar VPC e Instancia EC2 existentes:**
407+
```typescript
408+
const existingVpc = ec2.Vpc.fromLookup(this, 'CDKVPC', {
409+
vpcId: 'vpc-033aded37d02f7e0a',
410+
});
411+
const instanceId = 'i-0bb10936c1c1fb634';
412+
```
413+
- **Crear un Bucket S3 para Logs:**
414+
```typescript
415+
const logsBucket = new s3.Bucket(this, 'BackendLogsBucket', {
416+
bucketName: `backend-logs-${this.account}-${this.region}`,
417+
removalPolicy: cdk.RemovalPolicy.RETAIN,
418+
encryption: s3.BucketEncryption.S3_MANAGED,
419+
});
420+
```
421+
- **Configurar Roles y Permisos:**
422+
```typescript
423+
const backendRole = new iam.Role(this, 'BackendInstanceRole', {
424+
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
425+
roleName: 'backend-instance-role'
426+
});
427+
backendRole.addManagedPolicy(
428+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore')
429+
);
430+
```
431+
432+
5. **Verificar la Configuración**
433+
- Usa la consola de AWS para confirmar que los recursos se han creado correctamente (S3, alarmas, tópico SNS, etc.).
434+
- Verifica los logs y notificaciones para asegurar que las alarmas y los flujos de datos funcionan como se espera.

Diff for: api/src/app.js

-9
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ app.use(KoaLogger());
1515
// Use bodyParser middleware
1616
app.use(bodyParser());
1717

18-
// app.use(async (ctx, next) => {
19-
// ctx.set('Access-Control-Allow-Origin', 'http://localhost:5173');
20-
// ctx.set('Access-Control-Allow-Credentials', 'true');
21-
// ctx.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
22-
// ctx.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
23-
// await next();
24-
// });
25-
// =======
26-
// Use CORS middleware
2718
app.use(cors());
2819

2920

Diff for: api/src/config/checkAdmin.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const { User } = require('../models'); // Ajusta la ruta al modelo de usuario
2+
3+
const checkAdmin = async (ctx, next) => {
4+
console.log(ctx, "ctx");
5+
const user = await User.findOne({ where: { email: ctx.state.user.email } });
6+
if (user && user.isAdmin) {
7+
return next();
8+
}
9+
ctx.status = 403;
10+
ctx.body = { error: 'Access denied: Admins only.' };
11+
};
12+
13+
module.exports = checkAdmin;
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict';
2+
3+
module.exports = {
4+
async up(queryInterface, Sequelize) {
5+
await queryInterface.createTable('AdminRequests', {
6+
request_id: {
7+
type: Sequelize.UUID,
8+
defaultValue: Sequelize.UUIDV4,
9+
allowNull: false,
10+
primaryKey: true,
11+
},
12+
group_id: {
13+
type: Sequelize.STRING,
14+
allowNull: false,
15+
},
16+
fixture_id: {
17+
type: Sequelize.INTEGER,
18+
allowNull: false,
19+
},
20+
league_name: {
21+
type: Sequelize.STRING,
22+
allowNull: false,
23+
},
24+
round: {
25+
type: Sequelize.STRING,
26+
allowNull: false,
27+
},
28+
date: {
29+
type: Sequelize.DATEONLY,
30+
allowNull: false,
31+
},
32+
result: {
33+
type: Sequelize.STRING,
34+
allowNull: true,
35+
},
36+
deposit_token: {
37+
type: Sequelize.STRING,
38+
defaultValue: "",
39+
allowNull: true,
40+
},
41+
datetime: {
42+
type: Sequelize.STRING,
43+
allowNull: false,
44+
},
45+
quantity: {
46+
type: Sequelize.INTEGER,
47+
allowNull: false,
48+
},
49+
seller: {
50+
type: Sequelize.INTEGER,
51+
allowNull: false,
52+
defaultValue: 15, // Valor por defecto
53+
},
54+
status: {
55+
type: Sequelize.STRING,
56+
allowNull: false,
57+
defaultValue: 'pending',
58+
},
59+
ip_address: {
60+
type: Sequelize.STRING,
61+
allowNull: true,
62+
},
63+
location: {
64+
type: Sequelize.STRING,
65+
allowNull: true,
66+
},
67+
wallet: {
68+
type: Sequelize.BOOLEAN,
69+
allowNull: false,
70+
},
71+
createdAt: {
72+
allowNull: false,
73+
type: Sequelize.DATE,
74+
},
75+
updatedAt: {
76+
allowNull: false,
77+
type: Sequelize.DATE,
78+
},
79+
});
80+
},
81+
82+
async down(queryInterface) {
83+
await queryInterface.dropTable('AdminRequests');
84+
},
85+
};
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"use strict";
2+
3+
module.exports = {
4+
async up(queryInterface, Sequelize) {
5+
await queryInterface.createTable("AuctionOffers", {
6+
id: {
7+
allowNull: false,
8+
autoIncrement: true,
9+
primaryKey: true,
10+
type: Sequelize.INTEGER,
11+
},
12+
auction_id: {
13+
type: Sequelize.UUID,
14+
allowNull: false,
15+
},
16+
proposal_id: {
17+
type: Sequelize.UUID,
18+
allowNull: true,
19+
},
20+
fixture_id: {
21+
type: Sequelize.INTEGER,
22+
allowNull: false,
23+
},
24+
league_name: {
25+
type: Sequelize.STRING,
26+
allowNull: false,
27+
},
28+
round: {
29+
type: Sequelize.STRING,
30+
allowNull: false,
31+
},
32+
result: {
33+
type: Sequelize.STRING,
34+
allowNull: false,
35+
},
36+
quantity: {
37+
type: Sequelize.INTEGER,
38+
allowNull: false,
39+
},
40+
group_id: {
41+
type: Sequelize.INTEGER,
42+
allowNull: false,
43+
},
44+
createdAt: {
45+
allowNull: false,
46+
type: Sequelize.DATE,
47+
},
48+
updatedAt: {
49+
allowNull: false,
50+
type: Sequelize.DATE,
51+
},
52+
});
53+
},
54+
async down(queryInterface, Sequelize) {
55+
await queryInterface.dropTable("AuctionOffers");
56+
},
57+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = {
2+
up: async (queryInterface, Sequelize) => {
3+
await queryInterface.addColumn('AuctionOffers', 'type', {
4+
type: Sequelize.STRING,
5+
allowNull: false
6+
});
7+
},
8+
down: async (queryInterface, Sequelize) => {
9+
await queryInterface.removeColumn('AuctionOffers', 'type');
10+
}
11+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
module.exports = {
4+
async up(queryInterface, Sequelize) {
5+
await queryInterface.addColumn('AuctionOffers', 'request_id', {
6+
type: Sequelize.UUID,
7+
allowNull: true, // Puede ser nulo para ofertas de otros equipos
8+
});
9+
},
10+
11+
async down(queryInterface, Sequelize) {
12+
await queryInterface.removeColumn('AuctionOffers', 'request_id');
13+
},
14+
};
15+
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
module.exports = {
4+
up: async (queryInterface, Sequelize) => {
5+
await queryInterface.addColumn('Users', 'isAdmin', {
6+
type: Sequelize.BOOLEAN,
7+
allowNull: false,
8+
defaultValue: false,
9+
});
10+
},
11+
12+
down: async (queryInterface, Sequelize) => {
13+
await queryInterface.removeColumn('Users', 'isAdmin');
14+
},
15+
};
16+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
module.exports = {
4+
up: async (queryInterface, Sequelize) => {
5+
await queryInterface.addColumn('AdminRequests', 'discount', {
6+
type: Sequelize.FLOAT,
7+
defaultValue: 0,
8+
allowNull: false,
9+
});
10+
},
11+
12+
down: async (queryInterface, Sequelize) => {
13+
await queryInterface.removeColumn('AdminRequests', 'discount');
14+
},
15+
};
16+

0 commit comments

Comments
 (0)