From 677c792b44db8baf4714e7f26bc06a33e9074022 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 23 Oct 2024 12:23:06 +0200 Subject: [PATCH 01/23] EW-1047: Add TSP System on Dev Environments --- .../templates/configmap_file_init.yml.j2 | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 index 238b44226e4..b76b3e54edd 100644 --- a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 +++ b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 @@ -559,5 +559,43 @@ data: # ========== End of the Instance seed data configuration section. + # ========== Start of TSP system creation + if [[ $SC_THEME == "thr" ]]; then + echo "Adding TSP system to systems collection" + + TSP_SYSTEM_OAUTH_CLIENT_SECRET=$(node scripts/secret.js -s $AES_KEY -e $TSP_SYSTEM_OAUTH_CLIENT_SECRET) + mongosh $DATABASE__URL --quiet --eval 'db.systems.insertOne( + { + "_id": ObjectId("66d707f5c5202ba10c5e6256"), + "alias": "TSP", + "displayName": "Thüringer Schulportal", + "type": "oauth", + "provisioningStrategy": "tsp", + "oauthConfig": { + "clientId": "'$TSP_SYSTEM_OAUTH_CLIENT_ID'", + "clientSecret": "'$TSP_SYSTEM_OAUTH_CLIENT_SECRET'", + "tokenEndpoint": "https://test2.schulportal-thueringen.de/auth/realms/TIS/protocol/openid-connect/token", + "grantType": "authorization_code", + "scope": "openid", + "responseType": "code", + "redirectUri": "https://{{ NAMESPACE }}.thr.dbildungscloud.dev/api/v3/sso/oauth", + "authEndpoint": "https://test2.schulportal-thueringen.de/auth/realms/TIS/protocol/openid-connect/auth", + "provider": "tsp", + "jwksEndpoint": "https://test2.schulportal-thueringen.de/auth/realms/TIS/protocol/openid-connect/certs", + "issuer": "https://test2.schulportal-thueringen.de/auth/realms/TIS" + } + } + );' + + echo "Successfully added TSP system" + + echo "Running TSP Sync" + npm run nest:start:sync tsp + + echo "Successfully ran TSP sync" + fi + + # ========== End of TSP system creation + # Database indexes synchronization, it's crucial until we have all the entities in NestJS app. npm run syncIndexes From 98063b3e12fbe9a2a01af7a6aecc1ad94b38bf5c Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 23 Oct 2024 14:18:57 +0200 Subject: [PATCH 02/23] include dev dependencies to run nest cli. --- .../schulcloud-server-init/templates/configmap_file_init.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 index b76b3e54edd..b79426cbc8d 100644 --- a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 +++ b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 @@ -12,7 +12,7 @@ data: git clone https://github.com/hpi-schul-cloud/schulcloud-server.git cd /schulcloud-server git checkout {{ SCHULCLOUD_SERVER_IMAGE_TAG }} - npm install + npm install --include=dev until mongosh $DATABASE__URL --eval "print(\"waited for connection\")" do sleep 1 From f0285a349eca1749c19729455d776dd87672bd38 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 23 Oct 2024 16:49:32 +0200 Subject: [PATCH 03/23] Use encryption service to decrypt client secret if AES key is set. --- apps/server/src/infra/sync/sync.module.ts | 11 ++++++++++- .../src/infra/sync/tsp/tsp-sync.service.spec.ts | 9 +++++++++ apps/server/src/infra/sync/tsp/tsp-sync.service.ts | 8 +++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/server/src/infra/sync/sync.module.ts b/apps/server/src/infra/sync/sync.module.ts index 40e02c83966..b8ddbe21778 100644 --- a/apps/server/src/infra/sync/sync.module.ts +++ b/apps/server/src/infra/sync/sync.module.ts @@ -14,13 +14,22 @@ import { TspOauthDataMapper } from './tsp/tsp-oauth-data.mapper'; import { TspSyncService } from './tsp/tsp-sync.service'; import { TspSyncStrategy } from './tsp/tsp-sync.strategy'; import { SyncUc } from './uc/sync.uc'; +import { EncryptionModule } from '../encryption'; @Module({ imports: [ LoggerModule, ConsoleWriterModule, ...((Configuration.get('FEATURE_TSP_SYNC_ENABLED') as boolean) - ? [TspClientModule, SystemModule, SchoolModule, LegacySchoolModule, RabbitMQWrapperModule, ProvisioningModule] + ? [ + TspClientModule, + SystemModule, + SchoolModule, + LegacySchoolModule, + RabbitMQWrapperModule, + ProvisioningModule, + EncryptionModule, + ] : []), ], providers: [ diff --git a/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts b/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts index fe8bcc4c4a3..3aabb27c67d 100644 --- a/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts +++ b/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts @@ -13,6 +13,7 @@ import { SystemService, SystemType } from '@modules/system'; import { Test, TestingModule } from '@nestjs/testing'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { federalStateFactory, schoolYearFactory } from '@shared/testing'; +import { DefaultEncryptionService, EncryptionService } from '@src/infra/encryption'; import { FederalStateService, SchoolYearService } from '@src/modules/legacy-school'; import { SchoolProps } from '@src/modules/school/domain'; import { FederalStateEntityMapper, SchoolYearEntityMapper } from '@src/modules/school/repo/mikro-orm/mapper'; @@ -29,6 +30,7 @@ describe(TspSyncService.name, () => { let schoolService: DeepMocked; let federalStateService: DeepMocked; let schoolYearService: DeepMocked; + let encryptionService: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -54,6 +56,10 @@ describe(TspSyncService.name, () => { provide: SchoolYearService, useValue: createMock(), }, + { + provide: DefaultEncryptionService, + useValue: createMock(), + }, ], }).compile(); @@ -63,6 +69,7 @@ describe(TspSyncService.name, () => { schoolService = module.get(SchoolService); federalStateService = module.get(FederalStateService); schoolYearService = module.get(SchoolYearService); + encryptionService = module.get(DefaultEncryptionService); }); afterEach(() => { @@ -175,6 +182,8 @@ describe(TspSyncService.name, () => { tspClientFactory.createExportClient.mockReturnValueOnce(exportApiMock); + encryptionService.decrypt.mockImplementation((secret) => secret); + return { clientId, clientSecret, tokenEndpoint, system, exportApiMock, schools, teachers, students, classes }; }; diff --git a/apps/server/src/infra/sync/tsp/tsp-sync.service.ts b/apps/server/src/infra/sync/tsp/tsp-sync.service.ts index 084990d8f8e..d9d5248c03e 100644 --- a/apps/server/src/infra/sync/tsp/tsp-sync.service.ts +++ b/apps/server/src/infra/sync/tsp/tsp-sync.service.ts @@ -2,9 +2,10 @@ import { TspClientFactory } from '@infra/tsp-client'; import { FederalStateService, SchoolYearService } from '@modules/legacy-school'; import { School, SchoolService } from '@modules/school'; import { System, SystemService, SystemType } from '@modules/system'; -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { SchoolFeature } from '@shared/domain/types'; +import { DefaultEncryptionService, EncryptionService } from '@src/infra/encryption'; import { FederalStateNames } from '@src/modules/legacy-school/types'; import { FederalState } from '@src/modules/school/domain'; import { SchoolFactory } from '@src/modules/school/domain/factory'; @@ -22,7 +23,8 @@ export class TspSyncService { private readonly systemService: SystemService, private readonly schoolService: SchoolService, private readonly federalStateService: FederalStateService, - private readonly schoolYearService: SchoolYearService + private readonly schoolYearService: SchoolYearService, + @Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService ) {} public async findTspSystemOrFail(): Promise { @@ -150,7 +152,7 @@ export class TspSyncService { private createClient(system: System) { const client = this.tspClientFactory.createExportClient({ clientId: system.oauthConfig?.clientId ?? '', - clientSecret: system.oauthConfig?.clientSecret ?? '', + clientSecret: this.encryptionService.decrypt(system.oauthConfig?.clientSecret ?? ''), tokenEndpoint: system.oauthConfig?.tokenEndpoint ?? '', }); From 8030d76e8494619baf9a9867fb1cd1bd9d4e04c3 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Thu, 24 Oct 2024 15:34:33 +0200 Subject: [PATCH 04/23] Move decryption to client factory. --- apps/server/src/infra/sync/sync.module.ts | 11 +---------- .../src/infra/sync/tsp/tsp-sync.service.spec.ts | 9 --------- apps/server/src/infra/sync/tsp/tsp-sync.service.ts | 8 +++----- .../src/infra/tsp-client/tsp-client-factory.spec.ts | 8 ++++++++ .../server/src/infra/tsp-client/tsp-client-factory.ts | 9 ++++++--- apps/server/src/infra/tsp-client/tsp-client.module.ts | 3 ++- 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/apps/server/src/infra/sync/sync.module.ts b/apps/server/src/infra/sync/sync.module.ts index b8ddbe21778..40e02c83966 100644 --- a/apps/server/src/infra/sync/sync.module.ts +++ b/apps/server/src/infra/sync/sync.module.ts @@ -14,22 +14,13 @@ import { TspOauthDataMapper } from './tsp/tsp-oauth-data.mapper'; import { TspSyncService } from './tsp/tsp-sync.service'; import { TspSyncStrategy } from './tsp/tsp-sync.strategy'; import { SyncUc } from './uc/sync.uc'; -import { EncryptionModule } from '../encryption'; @Module({ imports: [ LoggerModule, ConsoleWriterModule, ...((Configuration.get('FEATURE_TSP_SYNC_ENABLED') as boolean) - ? [ - TspClientModule, - SystemModule, - SchoolModule, - LegacySchoolModule, - RabbitMQWrapperModule, - ProvisioningModule, - EncryptionModule, - ] + ? [TspClientModule, SystemModule, SchoolModule, LegacySchoolModule, RabbitMQWrapperModule, ProvisioningModule] : []), ], providers: [ diff --git a/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts b/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts index 3aabb27c67d..fe8bcc4c4a3 100644 --- a/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts +++ b/apps/server/src/infra/sync/tsp/tsp-sync.service.spec.ts @@ -13,7 +13,6 @@ import { SystemService, SystemType } from '@modules/system'; import { Test, TestingModule } from '@nestjs/testing'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { federalStateFactory, schoolYearFactory } from '@shared/testing'; -import { DefaultEncryptionService, EncryptionService } from '@src/infra/encryption'; import { FederalStateService, SchoolYearService } from '@src/modules/legacy-school'; import { SchoolProps } from '@src/modules/school/domain'; import { FederalStateEntityMapper, SchoolYearEntityMapper } from '@src/modules/school/repo/mikro-orm/mapper'; @@ -30,7 +29,6 @@ describe(TspSyncService.name, () => { let schoolService: DeepMocked; let federalStateService: DeepMocked; let schoolYearService: DeepMocked; - let encryptionService: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -56,10 +54,6 @@ describe(TspSyncService.name, () => { provide: SchoolYearService, useValue: createMock(), }, - { - provide: DefaultEncryptionService, - useValue: createMock(), - }, ], }).compile(); @@ -69,7 +63,6 @@ describe(TspSyncService.name, () => { schoolService = module.get(SchoolService); federalStateService = module.get(FederalStateService); schoolYearService = module.get(SchoolYearService); - encryptionService = module.get(DefaultEncryptionService); }); afterEach(() => { @@ -182,8 +175,6 @@ describe(TspSyncService.name, () => { tspClientFactory.createExportClient.mockReturnValueOnce(exportApiMock); - encryptionService.decrypt.mockImplementation((secret) => secret); - return { clientId, clientSecret, tokenEndpoint, system, exportApiMock, schools, teachers, students, classes }; }; diff --git a/apps/server/src/infra/sync/tsp/tsp-sync.service.ts b/apps/server/src/infra/sync/tsp/tsp-sync.service.ts index d9d5248c03e..084990d8f8e 100644 --- a/apps/server/src/infra/sync/tsp/tsp-sync.service.ts +++ b/apps/server/src/infra/sync/tsp/tsp-sync.service.ts @@ -2,10 +2,9 @@ import { TspClientFactory } from '@infra/tsp-client'; import { FederalStateService, SchoolYearService } from '@modules/legacy-school'; import { School, SchoolService } from '@modules/school'; import { System, SystemService, SystemType } from '@modules/system'; -import { Inject, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { SystemProvisioningStrategy } from '@shared/domain/interface/system-provisioning.strategy'; import { SchoolFeature } from '@shared/domain/types'; -import { DefaultEncryptionService, EncryptionService } from '@src/infra/encryption'; import { FederalStateNames } from '@src/modules/legacy-school/types'; import { FederalState } from '@src/modules/school/domain'; import { SchoolFactory } from '@src/modules/school/domain/factory'; @@ -23,8 +22,7 @@ export class TspSyncService { private readonly systemService: SystemService, private readonly schoolService: SchoolService, private readonly federalStateService: FederalStateService, - private readonly schoolYearService: SchoolYearService, - @Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService + private readonly schoolYearService: SchoolYearService ) {} public async findTspSystemOrFail(): Promise { @@ -152,7 +150,7 @@ export class TspSyncService { private createClient(system: System) { const client = this.tspClientFactory.createExportClient({ clientId: system.oauthConfig?.clientId ?? '', - clientSecret: this.encryptionService.decrypt(system.oauthConfig?.clientSecret ?? ''), + clientSecret: system.oauthConfig?.clientSecret ?? '', tokenEndpoint: system.oauthConfig?.tokenEndpoint ?? '', }); diff --git a/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts b/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts index 2efc2437934..84e8c168c1e 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts @@ -5,6 +5,7 @@ import { ServerConfig } from '@modules/server'; import { ConfigService } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; import axios from 'axios'; +import { DefaultEncryptionService, EncryptionService } from '../encryption'; import { TspClientFactory } from './tsp-client-factory'; describe('TspClientFactory', () => { @@ -12,6 +13,7 @@ describe('TspClientFactory', () => { let sut: TspClientFactory; let configServiceMock: DeepMocked>; let oauthAdapterServiceMock: DeepMocked; + let encryptionService: DeepMocked; beforeAll(async () => { module = await Test.createTestingModule({ @@ -36,12 +38,17 @@ describe('TspClientFactory', () => { }, }), }, + { + provide: DefaultEncryptionService, + useValue: createMock(), + }, ], }).compile(); sut = module.get(TspClientFactory); configServiceMock = module.get(ConfigService); oauthAdapterServiceMock = module.get(OauthAdapterService); + encryptionService = module.get(DefaultEncryptionService); }); afterAll(async () => { @@ -118,6 +125,7 @@ describe('TspClientFactory', () => { expect(response).toBeDefined(); expect(configServiceMock.getOrThrow).toHaveBeenCalledTimes(0); + expect(encryptionService.decrypt).toHaveBeenCalled(); }); }); diff --git a/apps/server/src/infra/tsp-client/tsp-client-factory.ts b/apps/server/src/infra/tsp-client/tsp-client-factory.ts index b4d54208269..e62109a9af5 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-factory.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-factory.ts @@ -1,9 +1,10 @@ -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { OauthAdapterService } from '@src/modules/oauth'; import { OAuthGrantType } from '@src/modules/oauth/interface/oauth-grant-type.enum'; import { ClientCredentialsGrantTokenRequest } from '@src/modules/oauth/service/dto'; import * as jwt from 'jsonwebtoken'; +import { DefaultEncryptionService, EncryptionService } from '../encryption'; import { Configuration, ExportApiFactory, ExportApiInterface } from './generated'; import { TspClientConfig } from './tsp-client-config'; @@ -25,7 +26,8 @@ export class TspClientFactory { constructor( private readonly oauthAdapterService: OauthAdapterService, - configService: ConfigService + configService: ConfigService, + @Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService ) { this.baseUrl = configService.getOrThrow('TSP_API_BASE_URL'); this.tokenLifetime = configService.getOrThrow('TSP_API_TOKEN_LIFETIME_MS'); @@ -51,9 +53,10 @@ export class TspClientFactory { return this.cachedToken; } + const clientSecret = this.encryptionService.decrypt(params.clientSecret); const payload = new ClientCredentialsGrantTokenRequest({ client_id: params.clientId, - client_secret: params.clientSecret, + client_secret: clientSecret, grant_type: OAuthGrantType.CLIENT_CREDENTIALS_GRANT, }); diff --git a/apps/server/src/infra/tsp-client/tsp-client.module.ts b/apps/server/src/infra/tsp-client/tsp-client.module.ts index b7dd40df24d..2c874fbf7c2 100644 --- a/apps/server/src/infra/tsp-client/tsp-client.module.ts +++ b/apps/server/src/infra/tsp-client/tsp-client.module.ts @@ -1,9 +1,10 @@ import { OauthModule } from '@modules/oauth'; import { Module } from '@nestjs/common'; +import { EncryptionModule } from '../encryption'; import { TspClientFactory } from './tsp-client-factory'; @Module({ - imports: [OauthModule], + imports: [OauthModule, EncryptionModule], providers: [TspClientFactory], exports: [TspClientFactory], }) From f45c53775093d67390247084775af67eb8f737b1 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Fri, 25 Oct 2024 14:44:08 +0200 Subject: [PATCH 05/23] Change config of tsp client to differ from old sync. --- apps/server/src/infra/tsp-client/tsp-client-config.ts | 4 ++-- .../tsp-client/tsp-client-factory.integration.spec.ts | 4 ++-- .../server/src/infra/tsp-client/tsp-client-factory.spec.ts | 4 ++-- apps/server/src/infra/tsp-client/tsp-client-factory.ts | 4 ++-- apps/server/src/modules/server/server.config.ts | 4 ++-- config/default.schema.json | 7 ++++++- 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/apps/server/src/infra/tsp-client/tsp-client-config.ts b/apps/server/src/infra/tsp-client/tsp-client-config.ts index 1ca78959cbe..efe8d1cdad4 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-config.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-config.ts @@ -1,4 +1,4 @@ export interface TspClientConfig { - TSP_API_BASE_URL: string; - TSP_API_TOKEN_LIFETIME_MS: number; + TSP_API_CLIENT_BASE_URL: string; + TSP_API_CLIENT_TOKEN_LIFETIME_MS: number; } diff --git a/apps/server/src/infra/tsp-client/tsp-client-factory.integration.spec.ts b/apps/server/src/infra/tsp-client/tsp-client-factory.integration.spec.ts index 90d798ea650..45d5bf7d04d 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-factory.integration.spec.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-factory.integration.spec.ts @@ -20,9 +20,9 @@ describe('TspClientFactory Integration', () => { createMock({ getOrThrow: (key: string) => { switch (key) { - case 'TSP_API_BASE_URL': + case 'TSP_API_CLIENT_BASE_URL': return 'https://test2.schulportal-thueringen.de/tip-ms/api'; - case 'TSP_API_TOKEN_LIFETIME_MS': + case 'TSP_API_CLIENT_TOKEN_LIFETIME_MS': return 30_000; default: throw new Error(`Unknown key: ${key}`); diff --git a/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts b/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts index 84e8c168c1e..f4922ebec0b 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-factory.spec.ts @@ -28,9 +28,9 @@ describe('TspClientFactory', () => { useValue: createMock>({ getOrThrow: (key: string) => { switch (key) { - case 'TSP_API_BASE_URL': + case 'TSP_API_CLIENT_BASE_URL': return faker.internet.url(); - case 'TSP_API_TOKEN_LIFETIME_MS': + case 'TSP_API_CLIENT_TOKEN_LIFETIME_MS': return faker.number.int(); default: throw new Error(`Unknown key: ${key}`); diff --git a/apps/server/src/infra/tsp-client/tsp-client-factory.ts b/apps/server/src/infra/tsp-client/tsp-client-factory.ts index e62109a9af5..e9890403541 100644 --- a/apps/server/src/infra/tsp-client/tsp-client-factory.ts +++ b/apps/server/src/infra/tsp-client/tsp-client-factory.ts @@ -29,8 +29,8 @@ export class TspClientFactory { configService: ConfigService, @Inject(DefaultEncryptionService) private readonly encryptionService: EncryptionService ) { - this.baseUrl = configService.getOrThrow('TSP_API_BASE_URL'); - this.tokenLifetime = configService.getOrThrow('TSP_API_TOKEN_LIFETIME_MS'); + this.baseUrl = configService.getOrThrow('TSP_API_CLIENT_BASE_URL'); + this.tokenLifetime = configService.getOrThrow('TSP_API_CLIENT_TOKEN_LIFETIME_MS'); } public createExportClient(params: FactoryParams): ExportApiInterface { diff --git a/apps/server/src/modules/server/server.config.ts b/apps/server/src/modules/server/server.config.ts index c3594739d84..c47e655a858 100644 --- a/apps/server/src/modules/server/server.config.ts +++ b/apps/server/src/modules/server/server.config.ts @@ -315,8 +315,8 @@ const config: ServerConfig = { FEATURE_SANIS_GROUP_PROVISIONING_ENABLED: Configuration.get('FEATURE_SANIS_GROUP_PROVISIONING_ENABLED') as boolean, FEATURE_AI_TUTOR_ENABLED: Configuration.get('FEATURE_AI_TUTOR_ENABLED') as boolean, FEATURE_ROOMS_ENABLED: Configuration.get('FEATURE_ROOMS_ENABLED') as boolean, - TSP_API_BASE_URL: Configuration.get('TSP_API_BASE_URL') as string, - TSP_API_TOKEN_LIFETIME_MS: Configuration.get('TSP_API_TOKEN_LIFETIME_MS') as number, + TSP_API_CLIENT_BASE_URL: Configuration.get('TSP_API_CLIENT_BASE_URL') as string, + TSP_API_CLIENT_TOKEN_LIFETIME_MS: Configuration.get('TSP_API_CLIENT_TOKEN_LIFETIME_MS') as number, TSP_SYNC_SCHOOL_LIMIT: Configuration.get('TSP_SYNC_SCHOOL_LIMIT') as number, TSP_SYNC_SCHOOL_DAYS_TO_FETCH: Configuration.get('TSP_SYNC_SCHOOL_DAYS_TO_FETCH') as number, TSP_SYNC_DATA_LIMIT: Configuration.get('TSP_SYNC_DATA_LIMIT') as number, diff --git a/config/default.schema.json b/config/default.schema.json index 272c2e5bce2..afd480d1035 100644 --- a/config/default.schema.json +++ b/config/default.schema.json @@ -174,7 +174,12 @@ "default": "", "description": "The key used to sign/verify TSP request tokens." }, - "TSP_API_TOKEN_LIFETIME_MS": { + "TSP_API_CLIENT_BASE_URL": { + "type": "string", + "default": "", + "description": "The TSP API base URL." + }, + "TSP_API_CLIENT_TOKEN_LIFETIME_MS": { "type": "number", "default": "30000", "description": "The TSP token lifetime in milliseconds." From 441974d82c35e4ba48329f2b5ade90eac11d0ae7 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 11:20:49 +0100 Subject: [PATCH 06/23] add debug log. --- apps/server/src/infra/sync/console/sync.console.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/server/src/infra/sync/console/sync.console.ts b/apps/server/src/infra/sync/console/sync.console.ts index fd40c5a9a5a..997b0d11dca 100644 --- a/apps/server/src/infra/sync/console/sync.console.ts +++ b/apps/server/src/infra/sync/console/sync.console.ts @@ -14,5 +14,6 @@ export class SyncConsole { }) public async startSync(target: string): Promise { await this.syncUc.startSync(target); + console.log('End of sync reached'); } } From 61df3cf555d65a7ef62b04a460fb8c8b6424596b Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 11:50:16 +0100 Subject: [PATCH 07/23] Add rabbitmq shutdown. --- apps/server/src/infra/rabbitmq/rabbitmq.module.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/server/src/infra/rabbitmq/rabbitmq.module.ts b/apps/server/src/infra/rabbitmq/rabbitmq.module.ts index 2600e0e2136..49c6c067f71 100644 --- a/apps/server/src/infra/rabbitmq/rabbitmq.module.ts +++ b/apps/server/src/infra/rabbitmq/rabbitmq.module.ts @@ -46,7 +46,15 @@ const imports = [ imports, exports: [RabbitMQModule], }) -export class RabbitMQWrapperModule {} +export class RabbitMQWrapperModule implements OnModuleDestroy { + constructor(private readonly amqpConnectionManager: AmqpConnectionManager) {} + + async onModuleDestroy() { + await Promise.all( + this.amqpConnectionManager.getConnections().map((connection) => connection.managedConnection.close()) + ); + } +} @Global() @Module({ From 29a6336b1c79e54c24ba1e5d4d7578bac54398f8 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 12:32:29 +0100 Subject: [PATCH 08/23] more logging. --- apps/server/src/console/console.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/server/src/console/console.ts b/apps/server/src/console/console.ts index 29ff141a8fc..8bf7c0609eb 100644 --- a/apps/server/src/console/console.ts +++ b/apps/server/src/console/console.ts @@ -14,8 +14,11 @@ const bootstrap = new BootstrapConsole({ void bootstrap.init().then(async (app) => { try { await app.init(); + console.log('init'); await bootstrap.boot(); + console.log('boot'); await app.close(); + console.log('closed'); } catch (e) { // eslint-disable-next-line no-console console.error(e); From c8830e9736bb538334f4ec7133d1fd1529b03f10 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 12:52:19 +0100 Subject: [PATCH 09/23] Add process.exit(0) --- apps/server/src/console/console.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/server/src/console/console.ts b/apps/server/src/console/console.ts index 8bf7c0609eb..e9ef789fdb9 100644 --- a/apps/server/src/console/console.ts +++ b/apps/server/src/console/console.ts @@ -19,6 +19,7 @@ void bootstrap.init().then(async (app) => { console.log('boot'); await app.close(); console.log('closed'); + process.exit(0); } catch (e) { // eslint-disable-next-line no-console console.error(e); From 4f8d0034c6f585ccb4e935377df8d68d45aebc7c Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 13:36:39 +0100 Subject: [PATCH 10/23] cleanup --- apps/server/src/console/console.ts | 3 --- apps/server/src/infra/rabbitmq/rabbitmq.module.ts | 10 +--------- apps/server/src/infra/sync/console/sync.console.ts | 1 - 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/apps/server/src/console/console.ts b/apps/server/src/console/console.ts index e9ef789fdb9..56a3b26f5c2 100644 --- a/apps/server/src/console/console.ts +++ b/apps/server/src/console/console.ts @@ -14,11 +14,8 @@ const bootstrap = new BootstrapConsole({ void bootstrap.init().then(async (app) => { try { await app.init(); - console.log('init'); await bootstrap.boot(); - console.log('boot'); await app.close(); - console.log('closed'); process.exit(0); } catch (e) { // eslint-disable-next-line no-console diff --git a/apps/server/src/infra/rabbitmq/rabbitmq.module.ts b/apps/server/src/infra/rabbitmq/rabbitmq.module.ts index 49c6c067f71..2600e0e2136 100644 --- a/apps/server/src/infra/rabbitmq/rabbitmq.module.ts +++ b/apps/server/src/infra/rabbitmq/rabbitmq.module.ts @@ -46,15 +46,7 @@ const imports = [ imports, exports: [RabbitMQModule], }) -export class RabbitMQWrapperModule implements OnModuleDestroy { - constructor(private readonly amqpConnectionManager: AmqpConnectionManager) {} - - async onModuleDestroy() { - await Promise.all( - this.amqpConnectionManager.getConnections().map((connection) => connection.managedConnection.close()) - ); - } -} +export class RabbitMQWrapperModule {} @Global() @Module({ diff --git a/apps/server/src/infra/sync/console/sync.console.ts b/apps/server/src/infra/sync/console/sync.console.ts index 997b0d11dca..fd40c5a9a5a 100644 --- a/apps/server/src/infra/sync/console/sync.console.ts +++ b/apps/server/src/infra/sync/console/sync.console.ts @@ -14,6 +14,5 @@ export class SyncConsole { }) public async startSync(target: string): Promise { await this.syncUc.startSync(target); - console.log('End of sync reached'); } } From 0cf07b9d3a7126378b579e61e432d28e7e9e3f1b Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Mon, 28 Oct 2024 13:58:36 +0100 Subject: [PATCH 11/23] add console to sonar exclusion --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index d8f2f98ccd8..806c37a8056 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -4,7 +4,7 @@ sonar.sources=. sonar.tests=. sonar.test.inclusions=**/*.spec.ts sonar.exclusions=**/*.js,jest.config.ts,globalSetup.ts,globalTeardown.ts,**/*.app.ts,**/seed-data/*.ts,**/migrations/mikro-orm/*.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts,**/lessons-api-client/**/*.ts -sonar.coverage.exclusions=**/board-management.uc.ts,**/*.module.ts,**/*.factory.ts,**/migrations/mikro-orm/*.ts,**/globalSetup.ts,**/globalTeardown.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts +sonar.coverage.exclusions=**/board-management.uc.ts,**/*.module.ts,**/*.factory.ts,**/migrations/mikro-orm/*.ts,**/globalSetup.ts,**/globalTeardown.ts,**/etherpad-api-client/**/*.ts,**/authorization-api-client/**/*.ts, **/course-api-client/**/*.ts,**/board-api-client/**/*.ts,**/generated/**/*.ts,**/room-api-client/**/*.ts,apps/server/src/console/console.ts sonar.cpd.exclusions=**/controller/dto/**/*.ts,**/api/dto/**/*.ts,**/shared/testing/factory/*.factory.ts sonar.javascript.lcov.reportPaths=merged-lcov.info sonar.typescript.tsconfigPaths=tsconfig.json,src/apps/server/tsconfig.app.json From 4ca2e95b35eb2275336a19ed20e82324a25751ca Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Tue, 29 Oct 2024 16:24:49 +0100 Subject: [PATCH 12/23] Add initial tsp sync job --- .../templates/configmap_file_init.yml.j2 | 8 +--- .../schulcloud-server-tspsync/tasks/main.yml | 9 +++++ .../api-tsp-sync-cronjob-configmap.yml.j2 | 5 ++- .../templates/api-tsp-sync-init.yml.j2 | 38 +++++++++++++++++++ 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 diff --git a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 index b79426cbc8d..0d3fbd01792 100644 --- a/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 +++ b/ansible/roles/schulcloud-server-init/templates/configmap_file_init.yml.j2 @@ -12,7 +12,7 @@ data: git clone https://github.com/hpi-schul-cloud/schulcloud-server.git cd /schulcloud-server git checkout {{ SCHULCLOUD_SERVER_IMAGE_TAG }} - npm install --include=dev + npm install until mongosh $DATABASE__URL --eval "print(\"waited for connection\")" do sleep 1 @@ -588,13 +588,7 @@ data: );' echo "Successfully added TSP system" - - echo "Running TSP Sync" - npm run nest:start:sync tsp - - echo "Successfully ran TSP sync" fi - # ========== End of TSP system creation # Database indexes synchronization, it's crucial until we have all the entities in NestJS app. diff --git a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml index 05ea93d07ef..ecd760ff33a 100644 --- a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml +++ b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml @@ -111,3 +111,12 @@ state: "{{ 'present' if WITH_TSP_SYNC|bool else 'absent'}}" tags: - configmap + + - name: API TSP Sync Init Job + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: api-tsp-sync-init.yml.j2 + state: "{{ 'present' if WITH_TSP_SYNC|bool else 'absent'}}" + tags: + - job diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 index c93af4d7c2e..1459a65ceab 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 @@ -15,4 +15,7 @@ data: IDENTITY_MANAGEMENT__INTERNAL_URI: "{{ IDENTITY_MANAGEMENT__INTERNAL_URI }}" IDENTITY_MANAGEMENT__EXTERNAL_URI: "{{ IDENTITY_MANAGEMENT__EXTERNAL_URI }}" IDENTITY_MANAGEMENT__TENANT: "{{ IDENTITY_MANAGEMENT__TENANT }}" - IDENTITY_MANAGEMENT__CLIENTID: "{{ IDENTITY_MANAGEMENT__CLIENTID }}" \ No newline at end of file + IDENTITY_MANAGEMENT__CLIENTID: "{{ IDENTITY_MANAGEMENT__CLIENTID }}" + FEATURE_TSP_SYNC_ENABLED: "{{ FEATURE_TSP_SYNC_ENABLED }}" + TSP_API_CLIENT_BASE_URL: "{{ TSP_API_CLIENT_BASE_URL }}" + TSP_SYNC_SCHOOL_DAYS_TO_FETCH: "{{ TSP_SYNC_SCHOOL_DAYS_TO_FETCH }}" \ No newline at end of file diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 new file mode 100644 index 00000000000..56db5c59a9e --- /dev/null +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 @@ -0,0 +1,38 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: api-tsp-sync-init + namespace: {{ NAMESPACE }} + labels: + app: api-tsp-sync-init +spec: + template: + metadata: + labels: + app: api-tsp-sync-init + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + runAsNonRoot: true + containers: + - name: api-tsp-sync-init + image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }} + imagePullPolicy: IfNotPresent + envFrom: + - configMapRef: + name: api-tsp-sync-cronjob-configmap + - secretRef: + name: api-secret + command: ['/bin/sh', '-c'] + args: ['npm run nest:start:sync tsp'] + resources: + limits: + cpu: {{ API_CPU_LIMITS|default("2000m", true) }} + memory: {{ API_MEMORY_LIMITS|default("2Gi", true) }} + requests: + cpu: {{ API_CPU_REQUESTS|default("100m", true) }} + memory: {{ API_MEMORY_REQUESTS|default("150Mi", true) }} + restartPolicy: Never + backoffLimit: 5 From ca2e5a1979f663a04a4d5234a4157c6f88600c85 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 30 Oct 2024 09:58:52 +0100 Subject: [PATCH 13/23] Add config for sync to configmap. --- .../templates/api-tsp-sync-cronjob-configmap.yml.j2 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 index 1459a65ceab..528da3322bf 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 @@ -18,4 +18,8 @@ data: IDENTITY_MANAGEMENT__CLIENTID: "{{ IDENTITY_MANAGEMENT__CLIENTID }}" FEATURE_TSP_SYNC_ENABLED: "{{ FEATURE_TSP_SYNC_ENABLED }}" TSP_API_CLIENT_BASE_URL: "{{ TSP_API_CLIENT_BASE_URL }}" - TSP_SYNC_SCHOOL_DAYS_TO_FETCH: "{{ TSP_SYNC_SCHOOL_DAYS_TO_FETCH }}" \ No newline at end of file + TSP_API_CLIENT_TOKEN_LIFETIME_MS: "{{ TSP_API_CLIENT_TOKEN_LIFETIME_MS }}" + TSP_SYNC_SCHOOL_LIMIT: "{{ TSP_SYNC_SCHOOL_LIMIT }}" + TSP_SYNC_DATA_LIMIT: "{{ TSP_SYNC_DATA_LIMIT }}" + TSP_SYNC_SCHOOL_DAYS_TO_FETCH: "{{ TSP_SYNC_SCHOOL_DAYS_TO_FETCH }}" + TSP_SYNC_DATA_DAYS_TO_FETCH: "{{ TSP_SYNC_DATA_DAYS_TO_FETCH }}" \ No newline at end of file From 4690f47f1622796e1543bf8b9255b292bcfba8a2 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 30 Oct 2024 12:24:29 +0100 Subject: [PATCH 14/23] Add config map of api to tsp sync. --- .../templates/api-tsp-sync-cronjob.yml.j2 | 2 ++ .../templates/api-tsp-sync-init.yml.j2 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 index 0a526e4028c..abaa4ca7018 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 @@ -50,6 +50,8 @@ spec: envFrom: - configMapRef: name: api-tsp-sync-cronjob-configmap + - configMapRef: + name: api-configmap - secretRef: name: api-secret command: ['/bin/sh', '-c'] diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 index 56db5c59a9e..6ae7cd0de87 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 @@ -23,6 +23,8 @@ spec: envFrom: - configMapRef: name: api-tsp-sync-cronjob-configmap + - configMapRef: + name: api-configmap - secretRef: name: api-secret command: ['/bin/sh', '-c'] From e8c726d2e2cc552535954ac63a3c284eedb1e879 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 30 Oct 2024 13:38:09 +0100 Subject: [PATCH 15/23] add removal of tsp init job --- .../schulcloud-server-tspsync/tasks/main.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml index ecd760ff33a..413b4a57515 100644 --- a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml +++ b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml @@ -112,11 +112,23 @@ tags: - configmap + - name: remove old API TSP Sync Init Job + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + api_version: batch/v1 + kind: Job + name: api-tsp-sync-init + state: absent + wait: yes + tags: + - job + - name: API TSP Sync Init Job kubernetes.core.k8s: kubeconfig: ~/.kube/config namespace: "{{ NAMESPACE }}" template: api-tsp-sync-init.yml.j2 - state: "{{ 'present' if WITH_TSP_SYNC|bool else 'absent'}}" + state: present tags: - - job + - job \ No newline at end of file From 8f46b48b45eb00f5bc1c4e2a7fcf23d3878f3941 Mon Sep 17 00:00:00 2001 From: mkreuzkam-cap <144103168+mkreuzkam-cap@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:57:16 +0100 Subject: [PATCH 16/23] Apply suggestions from code review Co-authored-by: mamutmk5 <3045922+mamutmk5@users.noreply.github.com> --- ansible/roles/schulcloud-server-tspsync/tasks/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml index 413b4a57515..0859a301008 100644 --- a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml +++ b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml @@ -120,7 +120,7 @@ kind: Job name: api-tsp-sync-init state: absent - wait: yes + when: not WITH_TSP_SYNC tags: - job @@ -130,5 +130,6 @@ namespace: "{{ NAMESPACE }}" template: api-tsp-sync-init.yml.j2 state: present + when: WITH_TSP_SYNC tags: - job \ No newline at end of file From 5ea496e8cbf2147b33d898fa147f4747c9448d71 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Tue, 5 Nov 2024 15:00:10 +0100 Subject: [PATCH 17/23] add labels for init job --- .../templates/api-tsp-sync-init.yml.j2 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 index 6ae7cd0de87..a8537afbb04 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 @@ -5,11 +5,25 @@ metadata: namespace: {{ NAMESPACE }} labels: app: api-tsp-sync-init + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_SERVER_IMAGE_TAG }} + app.kubernetes.io/name: api-tsp-sync-init + app.kubernetes.io/component: sync + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_SERVER_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_SERVER_REPO_NAME }} spec: template: metadata: labels: app: api-tsp-sync-init + app.kubernetes.io/part-of: schulcloud-verbund + app.kubernetes.io/version: {{ SCHULCLOUD_SERVER_IMAGE_TAG }} + app.kubernetes.io/name: api-tsp-sync-init + app.kubernetes.io/component: sync + app.kubernetes.io/managed-by: ansible + git.branch: {{ SCHULCLOUD_SERVER_BRANCH_NAME }} + git.repo: {{ SCHULCLOUD_SERVER_REPO_NAME }} spec: securityContext: runAsUser: 1000 From 6d4f32f6c965f6baec646ff4f5678606cd3dc06d Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Tue, 5 Nov 2024 15:16:41 +0100 Subject: [PATCH 18/23] Job has to be removed. --- ansible/roles/schulcloud-server-tspsync/tasks/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml index 0859a301008..741c1a6663a 100644 --- a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml +++ b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml @@ -120,7 +120,6 @@ kind: Job name: api-tsp-sync-init state: absent - when: not WITH_TSP_SYNC tags: - job From 5c3ba565a4f0b19d71c93072d3e979896e8206d0 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 6 Nov 2024 10:28:27 +0100 Subject: [PATCH 19/23] Split cronjob and init job configmap. --- .../schulcloud-server-tspsync/tasks/main.yml | 31 ++++++++++++++++--- .../api-tsp-sync-cronjob-configmap.yml.j2 | 2 +- .../api-tsp-sync-init-configmap.yml.j2 | 25 +++++++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 diff --git a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml index 741c1a6663a..5426e01d905 100644 --- a/ansible/roles/schulcloud-server-tspsync/tasks/main.yml +++ b/ansible/roles/schulcloud-server-tspsync/tasks/main.yml @@ -111,15 +111,24 @@ state: "{{ 'present' if WITH_TSP_SYNC|bool else 'absent'}}" tags: - configmap - - - name: remove old API TSP Sync Init Job + + - name: API TSP Sync Init ConfigMap kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + template: api-tsp-sync-init-configmap.yml.j2 + state: "{{ 'present' if WITH_TSP_SYNC|bool else 'absent'}}" + tags: + - configmap + + - name: Test if TSP Init Job exit + kubernetes.core.k8s_info: kubeconfig: ~/.kube/config namespace: "{{ NAMESPACE }}" api_version: batch/v1 kind: Job name: api-tsp-sync-init - state: absent + register: api_tsp_sync_init_present tags: - job @@ -129,6 +138,20 @@ namespace: "{{ NAMESPACE }}" template: api-tsp-sync-init.yml.j2 state: present - when: WITH_TSP_SYNC + when: + - WITH_TSP_SYNC + - api_tsp_sync_init_present.resources|length == 0 + tags: + - job + + - name: remove API TSP Sync Init Job + kubernetes.core.k8s: + kubeconfig: ~/.kube/config + namespace: "{{ NAMESPACE }}" + api_version: batch/v1 + kind: Job + name: api-tsp-sync-init + state: absent + when: not WITH_TSP_SYNC tags: - job \ No newline at end of file diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 index 528da3322bf..e59817acd58 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob-configmap.yml.j2 @@ -7,7 +7,7 @@ metadata: app: api-tsp-sync-cronjob data: NODE_OPTIONS: "--max-old-space-size=3072" - NEST_LOG_LEVEL: "error" + NEST_LOG_LEVEL: "{{ NEST_LOG_LEVEL }}" EXIT_ON_ERROR: "true" FEATURE_IDENTITY_MANAGEMENT_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_ENABLED }}" FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED }}" diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 new file mode 100644 index 00000000000..11e990fd303 --- /dev/null +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: {{ NAMESPACE }} + name: api-tsp-sync-init-configmap + labels: + app: api-tsp-sync-init +data: + NODE_OPTIONS: "--max-old-space-size=3072" + NEST_LOG_LEVEL: "{{ NEST_LOG_LEVEL }}" + EXIT_ON_ERROR: "true" + FEATURE_IDENTITY_MANAGEMENT_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_ENABLED }}" + FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_STORE_ENABLED }}" + FEATURE_IDENTITY_MANAGEMENT_LOGIN_ENABLED: "{{ FEATURE_IDENTITY_MANAGEMENT_LOGIN_ENABLED }}" + IDENTITY_MANAGEMENT__INTERNAL_URI: "{{ IDENTITY_MANAGEMENT__INTERNAL_URI }}" + IDENTITY_MANAGEMENT__EXTERNAL_URI: "{{ IDENTITY_MANAGEMENT__EXTERNAL_URI }}" + IDENTITY_MANAGEMENT__TENANT: "{{ IDENTITY_MANAGEMENT__TENANT }}" + IDENTITY_MANAGEMENT__CLIENTID: "{{ IDENTITY_MANAGEMENT__CLIENTID }}" + FEATURE_TSP_SYNC_ENABLED: "{{ FEATURE_TSP_SYNC_ENABLED }}" + TSP_API_CLIENT_BASE_URL: "{{ TSP_API_CLIENT_BASE_URL }}" + TSP_API_CLIENT_TOKEN_LIFETIME_MS: "{{ TSP_API_CLIENT_TOKEN_LIFETIME_MS }}" + TSP_SYNC_SCHOOL_LIMIT: "{{ TSP_SYNC_SCHOOL_LIMIT }}" + TSP_SYNC_DATA_LIMIT: "{{ TSP_SYNC_DATA_LIMIT }}" + TSP_SYNC_SCHOOL_DAYS_TO_FETCH: {{ ((ansible_date_time.date | to_datetime('%Y-%m-%d')) - ("1970-01-01" | to_datetime('%Y-%m-%d'))).days }} + TSP_SYNC_DATA_DAYS_TO_FETCH: "{{ TSP_SYNC_DATA_DAYS_TO_FETCH }}" \ No newline at end of file From e4bba92e88decdc6b53602a5661817b2ef1f8f3c Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 6 Nov 2024 10:39:38 +0100 Subject: [PATCH 20/23] add " to var --- .../templates/api-tsp-sync-init-configmap.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 index 11e990fd303..e486543ea32 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 @@ -21,5 +21,5 @@ data: TSP_API_CLIENT_TOKEN_LIFETIME_MS: "{{ TSP_API_CLIENT_TOKEN_LIFETIME_MS }}" TSP_SYNC_SCHOOL_LIMIT: "{{ TSP_SYNC_SCHOOL_LIMIT }}" TSP_SYNC_DATA_LIMIT: "{{ TSP_SYNC_DATA_LIMIT }}" - TSP_SYNC_SCHOOL_DAYS_TO_FETCH: {{ ((ansible_date_time.date | to_datetime('%Y-%m-%d')) - ("1970-01-01" | to_datetime('%Y-%m-%d'))).days }} + TSP_SYNC_SCHOOL_DAYS_TO_FETCH: "{{ ((ansible_date_time.date | to_datetime('%Y-%m-%d')) - ("1970-01-01" | to_datetime('%Y-%m-%d'))).days }}" TSP_SYNC_DATA_DAYS_TO_FETCH: "{{ TSP_SYNC_DATA_DAYS_TO_FETCH }}" \ No newline at end of file From b44fd67221b6ed9166ee6eacf833221d9d159601 Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 6 Nov 2024 11:07:58 +0100 Subject: [PATCH 21/23] use correct configmap in init job. --- .../templates/api-tsp-sync-init.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 index a8537afbb04..f88ee634b41 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 @@ -36,7 +36,7 @@ spec: imagePullPolicy: IfNotPresent envFrom: - configMapRef: - name: api-tsp-sync-cronjob-configmap + name: api-tsp-sync-init-configmap - configMapRef: name: api-configmap - secretRef: From 4b328fb2d8080ae99d9af2345f0c425c0e9972ad Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 6 Nov 2024 11:33:03 +0100 Subject: [PATCH 22/23] change order of configmaps --- .../templates/api-tsp-sync-cronjob.yml.j2 | 4 ++-- .../templates/api-tsp-sync-init.yml.j2 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 index abaa4ca7018..d2495657f72 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-cronjob.yml.j2 @@ -48,10 +48,10 @@ spec: - name: api-tsp-sync-cronjob image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }} envFrom: - - configMapRef: - name: api-tsp-sync-cronjob-configmap - configMapRef: name: api-configmap + - configMapRef: + name: api-tsp-sync-cronjob-configmap - secretRef: name: api-secret command: ['/bin/sh', '-c'] diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 index f88ee634b41..3ec8144a7d8 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init.yml.j2 @@ -35,10 +35,10 @@ spec: image: {{ SCHULCLOUD_SERVER_IMAGE }}:{{ SCHULCLOUD_SERVER_IMAGE_TAG }} imagePullPolicy: IfNotPresent envFrom: - - configMapRef: - name: api-tsp-sync-init-configmap - configMapRef: name: api-configmap + - configMapRef: + name: api-tsp-sync-init-configmap - secretRef: name: api-secret command: ['/bin/sh', '-c'] From ec39bcb0cf23b8bc94bd972538dd6cbd2f1e1d8f Mon Sep 17 00:00:00 2001 From: Maximilian Kreuzkam Date: Wed, 6 Nov 2024 14:16:03 +0100 Subject: [PATCH 23/23] increase data days to fetch. --- .../templates/api-tsp-sync-init-configmap.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 index e486543ea32..a79860325fa 100644 --- a/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 +++ b/ansible/roles/schulcloud-server-tspsync/templates/api-tsp-sync-init-configmap.yml.j2 @@ -22,4 +22,4 @@ data: TSP_SYNC_SCHOOL_LIMIT: "{{ TSP_SYNC_SCHOOL_LIMIT }}" TSP_SYNC_DATA_LIMIT: "{{ TSP_SYNC_DATA_LIMIT }}" TSP_SYNC_SCHOOL_DAYS_TO_FETCH: "{{ ((ansible_date_time.date | to_datetime('%Y-%m-%d')) - ("1970-01-01" | to_datetime('%Y-%m-%d'))).days }}" - TSP_SYNC_DATA_DAYS_TO_FETCH: "{{ TSP_SYNC_DATA_DAYS_TO_FETCH }}" \ No newline at end of file + TSP_SYNC_DATA_DAYS_TO_FETCH: "{{ ((ansible_date_time.date | to_datetime('%Y-%m-%d')) - ("1970-01-01" | to_datetime('%Y-%m-%d'))).days }}" \ No newline at end of file