Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checking garms connectivity #1758

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ services:
ISSUE_PERMIT_LIMIT: ${ISSUE_PERMIT_LIMIT}
DOC_GEN_LIMIT: ${DOC_GEN_LIMIT}
PERMIT_SCHEDULE_POLLING_INTERVAL: ${PERMIT_SCHEDULE_POLLING_INTERVAL}
GARMS_HOST: ${GARMS_HOST}
GARMS_USER: ${GARMS_USER}
GARMS_PWD: ${GARMS_PWD}
healthcheck:
test: "curl --silent --fail http://localhost:5050/ > /dev/null || exit 1"
interval: 1m30s
Expand Down
9 changes: 9 additions & 0 deletions scheduler/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Build container
FROM node:20.15.1-alpine AS builder
RUN apk update && apk add lftp

# Set the working directory to /app inside the container
WORKDIR /app
Expand All @@ -19,11 +20,15 @@

# Deployment container
FROM node:20.15.1-alpine

RUN apk update && apk add lftp

RUN npm cache clean --force

# Create and Assign permissions to npm folder
RUN mkdir /.npm && chmod 777 /.npm


# Set the working directory to /app inside the deployment container
WORKDIR /app

Expand All @@ -31,11 +36,11 @@
ENV NODE_ENV ${NODE_ENV}

# Set environment variables
ENV DB_TYPE ${DB_TYPE}

Check warning on line 39 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
ENV SCHEDULER_API_LOG_LEVEL ${SCHEDULER_API_LOG_LEVEL}
ENV SCHEDULER_API_TYPEORM_LOG_LEVEL ${SCHEDULER_API_TYPEORM_LOG_LEVEL}
ENV SCHEDULER_API_MAX_QUERY_EXECUTION_TIME_MS ${SCHEDULER_API_MAX_QUERY_EXECUTION_TIME_MS}
ENV SCHEDULER_API_MSSQL_MAX_CONNECTION ${SCHEDULER_API_MSSQL_MAX_CONNECTION}

Check warning on line 43 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$SCHEDULER_API_MSSQL_MAX_CONNECTION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV MSSQL_HOST ${MSSQL_HOST}
ENV MSSQL_PORT ${MSSQL_PORT}
ENV MSSQL_DB ${MSSQL_DB}
Expand All @@ -45,18 +50,18 @@
ENV KEYCLOAK_ISSUER_URL ${KEYCLOAK_ISSUER_URL}
ENV KEYCLOAK_AUDIENCE ${KEYCLOAK_AUDIENCE}
ENV KEYCLOAK_IGNORE_EXP ${KEYCLOAK_IGNORE_EXP}
ENV OCIO_S3_ACCESSKEYID ${OCIO_S3_ACCESSKEYID}

Check warning on line 53 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$OCIO_S3_ACCESSKEYID' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV OCIO_S3_BUCKET ${OCIO_S3_BUCKET}

Check warning on line 54 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$OCIO_S3_BUCKET' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV OCIO_S3_PRESIGNED_URL_EXPIRY ${OCIO_S3_PRESIGNED_URL_EXPIRY}
ENV OCIO_S3_ENDPOINT ${OCIO_S3_ENDPOINT}
ENV OCIO_S3_KEY ${OCIO_S3_KEY}
ENV OCIO_S3_SECRETACCESSKEY ${OCIO_S3_SECRETACCESSKEY}
ENV TPS_POLL_LIMIT ${TPS_POLL_LIMIT}
ENV TPS_PENDING_POLLING_INTERVAL ${TPS_PENDING_POLLING_INTERVAL}

Check warning on line 60 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
ENV TPS_ERROR_POLLING_INTERVAL ${TPS_ERROR_POLLING_INTERVAL}

Check warning on line 61 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/
ENV TPS_MONITORING_POLLING_INTERVAL ${TPS_MONITORING_POLLING_INTERVAL}
ENV CFS_PRIVATE_KEY ${CFS_PRIVATE_KEY}
ENV CFS_PRIVATE_KEY_PASSPHRASE ${CFS_PRIVATE_KEY_PASSPHRASE}

Check warning on line 64 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Legacy key/value format with whitespace separator should not be used

LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format More info: https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/

Check warning on line 64 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "CFS_PRIVATE_KEY_PASSPHRASE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV CFS_SFTP_USERNAME ${CFS_SFTP_USERNAME}
ENV CFS_SFTP_HOST ${CFS_SFTP_HOST}
ENV CFS_SFTP_PORT ${CFS_SFTP_PORT}
Expand All @@ -65,9 +70,13 @@
ENV ORBC_SERVICE_ACCOUNT_CLIENT_SECRET ${ORBC_SERVICE_ACCOUNT_CLIENT_SECRET}
ENV ORBC_SERVICE_ACCOUNT_TOKEN_URL ${ORBC_SERVICE_ACCOUNT_TOKEN_URL}
ENV ACCESS_API_URL ${ACCESS_API_URL}
ENV ISSUE_PERMIT_LIMIT ${ISSUE_PERMIT_LIMIT}

Check warning on line 73 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$ISSUE_PERMIT_LIMIT' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV DOC_GEN_LIMIT ${DOC_GEN_LIMIT}
ENV PERMIT_SCHEDULE_POLLING_INTERVAL ${PERMIT_SCHEDULE_POLLING_INTERVAL}
ENV GARMS_HOST ${GARMS_HOST}

Check warning on line 76 in scheduler/Dockerfile

View workflow job for this annotation

GitHub Actions / Builds (scheduler)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$GARMS_HOST' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
ENV GARMS_USER ${GARMS_USER}
ENV GARMS_PWD ${GARMS_PWD}


# Copy production files from build
COPY --from=builder /app/package*.json ./
Expand Down
57 changes: 57 additions & 0 deletions scheduler/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions scheduler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@
"@nestjs/testing": "^10.4.15",
"@nestjs/typeorm": "^10.0.2",
"@types/crypto-js": "^4.2.2",
"@types/ftps": "^1.2.2",
"basic-ftp": "^5.0.5",
"cache-manager": "^5.7.6",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"dotenv": "^16.4.7",
"ftps": "^1.2.0",
"jwks-rsa": "^3.1.0",
"mssql": "^10.0.4",
"nest-winston": "^1.10.0",
Expand Down
2 changes: 2 additions & 0 deletions scheduler/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getTypeormLogLevel } from './common/helper/logger.helper';
import { CacheModule } from '@nestjs/cache-manager';
import { CgiSftpModule } from './modules/cgi-sftp/cgi-sftp.module';
import { PermitModule } from './modules/permit/permit.module';
import { GarmsModule } from './modules/garms/garms.module';

const envPath = path.resolve(process.cwd() + '/../');
@Module({
Expand Down Expand Up @@ -44,6 +45,7 @@ const envPath = path.resolve(process.cwd() + '/../');
FeatureFlagsModule,
CgiSftpModule,
PermitModule,
GarmsModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
22 changes: 22 additions & 0 deletions scheduler/src/modules/garms/garms.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { GarmsService } from './garms.service';

@ApiTags('Health Check')
@Controller('garms')
export class GarmsController {
constructor(private readonly garmsService: GarmsService) {}

@Get()
async getHello(): Promise<string> {
return await this.garmsService.ftpsFile();
}
@Get('getHello2')
getHello2() {
this.garmsService.ftpsFile2();
}
@Get('getHello3')
async getHello3() {
console.log(await this.garmsService.ftpsFile3());
}
}
9 changes: 9 additions & 0 deletions scheduler/src/modules/garms/garms.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { GarmsController } from './garms.controller';
import { GarmsService } from './garms.service';

@Module({
controllers: [GarmsController],
providers: [GarmsService],
})
export class GarmsModule {}
107 changes: 107 additions & 0 deletions scheduler/src/modules/garms/garms.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Injectable } from '@nestjs/common';
import { Client } from 'basic-ftp';
import * as FTPS from 'ftps';
import { exec } from 'child_process';

import * as fs from 'fs';
import { promisify } from 'util';

@Injectable()
export class GarmsService {
private client: Client;


constructor() {
this.client = new Client();
this.client.ftp.verbose = true;
}

async ftpsFile(): Promise<string> {
try {
console.log('GARMS HOST : ', process.env.GARMS_HOST);
console.log('GARMS USER : ', process.env.GARMS_USER);
console.log('GARMS PWD : ', process.env.GARMS_PWD);
// Connect to FTP server
await this.connectToFtp();
console.log('Current working directory', await this.client.pwd());
await this.client.cd('GARMSD.GA4701.WS.BATCH');
console.log('pwd: ', await this.client.pwd());
// await this.client.uploadFrom('Hello world', 'GARMD.GA4701.WS.BATCH(+1)');

// Upload file
// await this.client.uploadFrom(filePath, remotePath);
// console.log(`File uploaded: ${filePath} -> ${remotePath}`);
} catch (error) {
console.error('Error uploading file', error);
throw error;
} finally {
// Close the connection after uploading
this.client.close();
}
return 'Vehicles Healthcheck!';
}
async connectToFtp() {
try {
await this.client.access({
host: process.env.GARMS_HOST, // Replace with your FTPS server host
user: process.env.GARMS_USER, // Your username for the FTPS server
password: process.env.GARMS_PASSWROD, // Your password
secure: true, // Enabling FTPS (SSL/TLS encryption)
secureOptions: {
rejectUnauthorized: false, // Depending on your certificate, this can be true or false
},
});
console.log('Connected to FTPS server');
} catch (error) {
console.error('Error connecting to FTPS server', error);
throw error;
}
}
ftpsFile2() {
console.log('file data from hello2: ', fs.readFileSync('./dist/orbctest.txt', 'utf-8'));
const ftps = new FTPS({
host: process.env.GARMS_HOST, // required
username: process.env.GARMS_USER, // Optional. Use empty username for anonymous access.
password: process.env.GARMS_PWD, // Required if username is not empty, except when requiresPassword: false
// protocol is added on beginning of host, ex : sftp://domain.com in this case
additionalLftpCommands:
'set cache:enable no;set ftp:passive-mode on;set ftp:use-size no;set ftp:ssl-protect-data yes;set ftp:ssl-force yes;set ftps:initial-prot "P";set net:connection-limit 1;set net:max-retries 1;debug 3;', // Additional commands to pass to lftp, splitted by ';'
});
const remoteFilePath = 'GARMD.GA4701.WS.BATCH(+1)';
const localFilePath = './dist/orbctest.txt'
console.log('executing quote');
ftps.raw('quote SITE LRecl=140')
console.log('executed quote');
ftps.pwd().exec(console.log);
const remoteFile = "'GARMD.GA4701.WS.BATCH(+1)'";
console.log('Remote file is: ',remoteFile)
ftps.raw(`put -a ${localFilePath} -o "'${remoteFilePath}'"`);
ftps.raw('quit')
ftps.pwd().exec(console.log);
}

async ftpsFile3() {
const execPromise = promisify(exec);
try {
const remoteFilePath = 'GARMD.GA4701.WS.BATCH(+1)';
const localFilePath = './dist/orbctest.txt'
const additionalParams = 'set cache:enable no;set ftp:passive-mode on;set ftp:use-size no;set ftp:ssl-protect-data yes;set ftp:ssl-force yes;set ftps:initial-prot P;set net:connection-limit 1;set net:max-retries 1;debug 5';

// Construct the lftp command
const command = `
lftp -u ${process.env.GARMS_USER},${process.env.GARMS_PWD} ${process.env.GARMS_HOST} -e ${additionalParams} put -a ${localFilePath} -o "'${remoteFilePath}'"; quit;`

// Execute the command using child_process
const { stdout, stderr } = await execPromise(command);

if (stderr) {
throw new Error(`Error transferring file: ${stderr}`);
}

return stdout;
} catch (error) {
console.error('Error:', error.message);
throw new Error(`File transfer failed: ${error.message}`);
}
}
}
Loading