Compare commits

..
Author SHA1 Message Date
Rafael Santana 3f910f851a Merge pull request #411 from dadosfera/fix/redis-tls-configurable
Fix/redis tls configurable
2025-12-16 16:58:41 -03:00
Rafael Santana 9c1979e17a Merge pull request #405 from dadosfera/fix/redis-tls-configurable
Fix/redis tls configurable
2025-12-16 16:41:04 -03:00
5 changed files with 35 additions and 84 deletions
+2
View File
@@ -2,6 +2,8 @@
<image src="./assets/maestro.svg" style="width:10rem"> <image src="./assets/maestro.svg" style="width:10rem">
</p> </p>
# Maestro # Maestro
Maestro é a API principal da Dadosfera. É responsável pela comunicação do Frontend com nossos microsserviços. Maestro é a API principal da Dadosfera. É responsável pela comunicação do Frontend com nossos microsserviços.
@@ -128,14 +128,3 @@ spec:
secretKeyRef: secretKeyRef:
name: prd-{{ .Values.app_name }} name: prd-{{ .Values.app_name }}
key: AWS_DEFAULT_REGION key: AWS_DEFAULT_REGION
# Elasticsearch
- name: ELASTICSEARCH_URL
valueFrom:
secretKeyRef:
name: prd-{{ .Values.app_name }}
key: ELASTICSEARCH_URL
- name: ELASTICSEARCH_API_KEY
valueFrom:
secretKeyRef:
name: prd-{{ .Values.app_name }}
key: ELASTICSEARCH_API_KEY
-12
View File
@@ -38,15 +38,3 @@ spec:
version: "AWSCURRENT" version: "AWSCURRENT"
property: token property: token
- secretKey: ELASTICSEARCH_URL
remoteRef:
key: {{ .Values.maestro.env }}/microservices/elasticsearch
version: "AWSCURRENT"
property: ELASTICSEARCH_URL
- secretKey: ELASTICSEARCH_API_KEY
remoteRef:
key: {{ .Values.maestro.env }}/microservices/elasticsearch
version: "AWSCURRENT"
property: ELASTICSEARCH_API_KEY
@@ -22,7 +22,7 @@ import { User, RequestUser } from '../../decorators/user.decorator';
import { PlatformApiService } from './platform-api.service'; import { PlatformApiService } from './platform-api.service';
import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum'; import { PERMISSIONS_GROUPS } from '../../authentication/permissions.enum';
import { ElasticsearchService } from '../../services/elasticsearch'; import { ElasticsearchService } from '../../services/elasticsearch';
import { DynamoDBService, ReferenceColumn } from '../../services/dynamodb'; import { DynamoDBService } from '../../services/dynamodb';
import { CustomersService } from '../customers/customers.service'; import { CustomersService } from '../customers/customers.service';
import { validateCronAgainstScheduleLimit } from '../../utils/cron-validation'; import { validateCronAgainstScheduleLimit } from '../../utils/cron-validation';
@@ -155,7 +155,7 @@ export class PlatformApiController {
* Extract and transform tables from jobs for DynamoDB input. * Extract and transform tables from jobs for DynamoDB input.
* Maps connector-specific fields to a common table format. * Maps connector-specific fields to a common table format.
* *
* - JDBC: load_type, table_name, column_include_list (columns), incremental_column_name/type (reference_column object) * - JDBC: load_type, table_name, column_include_list (columns), incremental_column_name (reference_column)
* - Singer: type maps replication_method (FULL_TABLE -> full_load, INCREMENTAL -> incremental), no columns * - Singer: type maps replication_method (FULL_TABLE -> full_load, INCREMENTAL -> incremental), no columns
* - S3: same mapping as Singer, no columns * - S3: same mapping as Singer, no columns
*/ */
@@ -163,7 +163,7 @@ export class PlatformApiController {
name: string; name: string;
type: string; type: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn; reference_column?: string;
}> { }> {
if (!jobs || jobs.length === 0) return []; if (!jobs || jobs.length === 0) return [];
@@ -171,7 +171,7 @@ export class PlatformApiController {
name: string; name: string;
type: string; type: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn; reference_column?: string;
}> = []; }> = [];
for (const job of jobs) { for (const job of jobs) {
@@ -179,12 +179,12 @@ export class PlatformApiController {
if (!input) continue; if (!input) continue;
if (connector === 'jdbc') { if (connector === 'jdbc') {
// JDBC: table_name, load_type, column_include_list, incremental_column_name/type // JDBC: table_name, load_type, column_include_list, incremental_column_name
const table: { const table: {
name: string; name: string;
type: string; type: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn; reference_column?: string;
} = { } = {
name: input.table_name || '', name: input.table_name || '',
type: input.load_type || 'full_load', type: input.load_type || 'full_load',
@@ -193,11 +193,8 @@ export class PlatformApiController {
table.columns = input.column_include_list; table.columns = input.column_include_list;
} }
if (input.incremental_column_name) { if (input.incremental_column_name) {
// reference_column is stored as an object with name and type // reference_column is stored as a string (column name)
table.reference_column = { table.reference_column = input.incremental_column_name;
name: input.incremental_column_name,
type: input.incremental_column_type || 'unknown',
};
} }
tables.push(table); tables.push(table);
} else if (connector === 'singer' || connector === 's3') { } else if (connector === 'singer' || connector === 's3') {
@@ -320,11 +317,11 @@ export class PlatformApiController {
} }
// Build changes for DynamoDB table entry // Build changes for DynamoDB table entry
// reference_column is stored as an object with name and type // reference_column is stored as a string (column name), not an object
const changes: { const changes: {
type?: string; type?: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn | null; reference_column?: string | null;
} = {}; } = {};
@@ -335,15 +332,8 @@ export class PlatformApiController {
changes.columns = body.column_include_list; changes.columns = body.column_include_list;
} }
if ('incremental_column_name' in body) { if ('incremental_column_name' in body) {
// reference_column is stored as an object with name and type // reference_column is just the column name as a string
if (body.incremental_column_name) { changes.reference_column = body.incremental_column_name || null;
changes.reference_column = {
name: body.incremental_column_name,
type: body.incremental_column_type || 'unknown',
};
} else {
changes.reference_column = null;
}
} }
// Update DynamoDB if there are changes // Update DynamoDB if there are changes
@@ -476,13 +466,11 @@ export class PlatformApiController {
}); });
} }
const pipelineType = this.mapConnectorToDynamoType(connectorType);
this.logger.info('Syncing pipeline to Elasticsearch', { this.logger.info('Syncing pipeline to Elasticsearch', {
customerName: user.customer_name, customerName: user.customer_name,
pipelineId: body.id, pipelineId: body.id,
plugin, plugin,
connector: connectorType, connector: connectorType,
type: pipelineType,
properties, properties,
inputId, inputId,
}); });
@@ -502,7 +490,6 @@ export class PlatformApiController {
cron: body.cron, cron: body.cron,
tables: inputId, tables: inputId,
properties, properties,
type: pipelineType,
}, },
connector, connector,
); );
@@ -630,39 +617,21 @@ export class PlatformApiController {
@ApiOperation({ summary: 'Execute a pipeline' }) @ApiOperation({ summary: 'Execute a pipeline' })
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE) @RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
async executePipeline(@Body() body: any, @User() user: RequestUser) { async executePipeline(@Body() body: any, @User() user: RequestUser) {
// Inject customer_id (actually customer_name) into body for Platform-API return this.platformApiService.proxy('POST', '/pipeline/execute', user, body);
// Note: Platform-API was created before customer_id existed, so it expects customer_name in the customer_id field
const enrichedBody = {
...body,
customer_id: user.customer_name,
};
return this.platformApiService.proxy('POST', '/pipeline/execute', user, enrichedBody);
} }
@Post('pipeline/pause') @Post('pipeline/pause')
@ApiOperation({ summary: 'Pause a pipeline' }) @ApiOperation({ summary: 'Pause a pipeline' })
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE) @RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
async pausePipeline(@Body() body: any, @User() user: RequestUser) { async pausePipeline(@Body() body: any, @User() user: RequestUser) {
// Inject customer_id (actually customer_name) into body for Platform-API return this.platformApiService.proxy('POST', '/pipeline/pause', user, body);
// Note: Platform-API was created before customer_id existed, so it expects customer_name in the customer_id field
const enrichedBody = {
...body,
customer_id: user.customer_name,
};
return this.platformApiService.proxy('POST', '/pipeline/pause', user, enrichedBody);
} }
@Post('pipeline/unpause') @Post('pipeline/unpause')
@ApiOperation({ summary: 'Unpause a pipeline' }) @ApiOperation({ summary: 'Unpause a pipeline' })
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE) @RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
async unpausePipeline(@Body() body: any, @User() user: RequestUser) { async unpausePipeline(@Body() body: any, @User() user: RequestUser) {
// Inject customer_id (actually customer_name) into body for Platform-API return this.platformApiService.proxy('POST', '/pipeline/unpause', user, body);
// Note: Platform-API was created before customer_id existed, so it expects customer_name in the customer_id field
const enrichedBody = {
...body,
customer_id: user.customer_name,
};
return this.platformApiService.proxy('POST', '/pipeline/unpause', user, enrichedBody);
} }
@Put('pipeline/:pipelineId/memory') @Put('pipeline/:pipelineId/memory')
@@ -722,6 +691,18 @@ export class PlatformApiController {
// ==================== PIPELINE RUN ROUTES ==================== // ==================== PIPELINE RUN ROUTES ====================
@Post('pipeline/pipeline_run')
@ApiOperation({ summary: 'Create a pipeline run' })
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.UPDATE)
async createPipelineRun(@Body() body: any, @User() user: RequestUser) {
return this.platformApiService.proxy(
'POST',
'/pipeline/pipeline_run',
user,
body,
);
}
@Get('pipeline/:pipelineId/pipeline_run') @Get('pipeline/:pipelineId/pipeline_run')
@ApiOperation({ summary: 'Get pipeline runs for a pipeline' }) @ApiOperation({ summary: 'Get pipeline runs for a pipeline' })
@RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.GET) @RequireAllPermissions(PERMISSIONS_GROUPS.PIPELINE.permissions.GET)
@@ -730,10 +711,9 @@ export class PlatformApiController {
@User() user: RequestUser, @User() user: RequestUser,
@Query() query: Record<string, string>, @Query() query: Record<string, string>,
) { ) {
const normalizedId = this.normalizePipelineId(pipelineId);
return this.platformApiService.proxy( return this.platformApiService.proxy(
'GET', 'GET',
`/pipeline/${normalizedId}/pipeline_run`, `/pipeline/${pipelineId}/pipeline_run`,
user, user,
undefined, undefined,
query, query,
@@ -748,11 +728,9 @@ export class PlatformApiController {
@Param('runId') runId: string, @Param('runId') runId: string,
@User() user: RequestUser, @User() user: RequestUser,
) { ) {
const normalizedPipelineId = this.normalizePipelineId(pipelineId);
const normalizedRunId = this.normalizePipelineId(runId);
return this.platformApiService.proxy( return this.platformApiService.proxy(
'GET', 'GET',
`/pipeline/${normalizedPipelineId}/pipeline_run/${normalizedRunId}`, `/pipeline/${pipelineId}/pipeline_run/${runId}`,
user, user,
); );
} }
@@ -765,10 +743,9 @@ export class PlatformApiController {
@User() user: RequestUser, @User() user: RequestUser,
@Query() query: Record<string, string>, @Query() query: Record<string, string>,
) { ) {
const normalizedRunId = this.normalizePipelineId(runId);
return this.platformApiService.proxy( return this.platformApiService.proxy(
'GET', 'GET',
`/pipeline/pipeline_run/${normalizedRunId}/logs`, `/pipeline/pipeline_run/${runId}/logs`,
user, user,
undefined, undefined,
query, query,
+3 -8
View File
@@ -11,11 +11,6 @@ import { DadosferaLogger } from '@dadosfera/dadosfera-logs';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { DYNAMODB_CONFIG } from './dynamodb.config'; import { DYNAMODB_CONFIG } from './dynamodb.config';
export interface ReferenceColumn {
name: string;
type: string;
}
export interface InputDocument { export interface InputDocument {
id: string; id: string;
client_id: string; client_id: string;
@@ -29,7 +24,7 @@ export interface InputDocument {
name: string; name: string;
type: string; type: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn; reference_column?: string;
}>; }>;
credentials?: Record<string, any>; credentials?: Record<string, any>;
} }
@@ -67,7 +62,7 @@ export class DynamoDBService {
name: string; name: string;
type: string; type: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn; reference_column?: string;
}>; }>;
}, },
): Promise<InputDocument> { ): Promise<InputDocument> {
@@ -162,7 +157,7 @@ export class DynamoDBService {
changes: { changes: {
type?: string; type?: string;
columns?: string[]; columns?: string[];
reference_column?: ReferenceColumn | null; reference_column?: string | null;
}, },
): Promise<void> { ): Promise<void> {
const dynamoTableName = DYNAMODB_CONFIG.inputsTable(); const dynamoTableName = DYNAMODB_CONFIG.inputsTable();