diff --git a/.gitea/workflows/docker_nottags.yaml b/.gitea/workflows/docker_nottags.yaml new file mode 100644 index 0000000..5154a0e --- /dev/null +++ b/.gitea/workflows/docker_nottags.yaml @@ -0,0 +1,71 @@ +name: Docker (tags) + +on: + push: + tags-ignore: + - '**' + +env: + IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci + NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git + NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} + NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} + NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} + NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }} + NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }} + +jobs: + security: + runs-on: ubuntu-latest + container: + image: ${{ env.IMAGE }} + continue-on-error: true + + steps: + - uses: actions/checkout@v3 + + - name: Install pnpm and npmci + run: | + pnpm install -g pnpm + pnpm install -g @ship.zone/npmci + npmci npm prepare + + - name: Audit production dependencies + run: | + npmci command npm config set registry https://registry.npmjs.org + npmci command pnpm audit --audit-level=high --prod + continue-on-error: true + + - name: Audit development dependencies + run: | + npmci command npm config set registry https://registry.npmjs.org + npmci command pnpm audit --audit-level=high --dev + continue-on-error: true + + test: + needs: security + runs-on: ubuntu-latest + container: + image: ${{ env.IMAGE }} + + steps: + - uses: actions/checkout@v3 + + - name: Prepare + run: | + pnpm install -g pnpm + pnpm install -g @ship.zone/npmci + npmci npm prepare + + - name: Test stable + run: | + npmci node install stable + npmci npm install + npmci npm test + + - name: Test build + run: | + npmci npm prepare + npmci node install stable + npmci npm install + npmci command npm run build diff --git a/.gitea/workflows/docker_tags.yaml b/.gitea/workflows/docker_tags.yaml new file mode 100644 index 0000000..74684e0 --- /dev/null +++ b/.gitea/workflows/docker_tags.yaml @@ -0,0 +1,106 @@ +name: Docker (tags) + +on: + push: + tags: + - '*' + +env: + IMAGE: code.foss.global/hosttoday/ht-docker-node:npmci + NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git + NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}} + NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} + NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} + NPMCI_LOGIN_DOCKER_GITEA: ${{ github.server_url }}|${{ gitea.repository_owner }}|${{ secrets.GITEA_TOKEN }} + NPMCI_LOGIN_DOCKER_DOCKERREGISTRY: ${{ secrets.NPMCI_LOGIN_DOCKER_DOCKERREGISTRY }} + +jobs: + security: + runs-on: ubuntu-latest + container: + image: ${{ env.IMAGE }} + continue-on-error: true + + steps: + - uses: actions/checkout@v3 + + - name: Prepare + run: | + pnpm install -g pnpm + pnpm install -g @ship.zone/npmci + npmci npm prepare + + - name: Audit production dependencies + run: | + npmci command npm config set registry https://registry.npmjs.org + npmci command pnpm audit --audit-level=high --prod + continue-on-error: true + + - name: Audit development dependencies + run: | + npmci command npm config set registry https://registry.npmjs.org + npmci command pnpm audit --audit-level=high --dev + continue-on-error: true + + test: + needs: security + runs-on: ubuntu-latest + container: + image: ${{ env.IMAGE }} + + steps: + - uses: actions/checkout@v3 + + - name: Prepare + run: | + pnpm install -g pnpm + pnpm install -g @ship.zone/npmci + npmci npm prepare + + - name: Test stable + run: | + npmci node install stable + npmci npm install + npmci npm test + + - name: Test build + run: | + npmci node install stable + npmci npm install + npmci command npm run build + + release: + needs: test + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + container: + image: code.foss.global/hosttoday/ht-docker-dbase:npmci + + steps: + - uses: actions/checkout@v3 + + - name: Prepare + run: | + pnpm install -g pnpm + pnpm install -g @ship.zone/npmci + + - name: Release + run: | + npmci docker login + npmci docker build + npmci docker test + # npmci docker push + npmci docker push + + metadata: + needs: test + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + container: + image: ${{ env.IMAGE }} + + steps: + - uses: actions/checkout@v3 + + - name: Trigger + run: npmci trigger diff --git a/.gitignore b/.gitignore index ef13c79..0b26089 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ # artifacts coverage/ public/ -pages/ # installs node_modules/ @@ -17,4 +16,4 @@ node_modules/ dist/ dist_*/ -# custom \ No newline at end of file +#------# custom \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6a0424c..472ae2f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN rm -rf node_modules/ && pnpm install --prod ## STAGE 3 // rebuild dependencies for alpine -FROM code.foss.global/host.today/ht-docker-node:alpine_npmci as node3 +FROM code.foss.global/host.today/ht-docker-node:alpinenpmci as node3 WORKDIR /app COPY --from=node2 /app /app ARG NPMCI_TOKEN_NPM2 diff --git a/changelog.md b/changelog.md index db882d9..589b34d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2024-12-29 - 1.1.0 - feat(.gitea/workflows) +Add GitHub Actions workflows for Docker build and test + +- Added .gitea/workflows/docker_nottags.yaml for handling Docker builds on non-tagged commits. +- Added .gitea/workflows/docker_tags.yaml for handling Docker builds on tagged commits. +- Both workflows include steps for security audits, testing, and build preparation. + ## 2024-12-29 - 1.0.135 - fix(core) Fix image retrieval and service deployment process for workload services diff --git a/npmextra.json b/npmextra.json index 5bf2a8f..ae52ba0 100644 --- a/npmextra.json +++ b/npmextra.json @@ -13,12 +13,12 @@ "gitzone": { "projectType": "service", "module": { - "githost": "gitlab.com", - "gitscope": "losslessone/services/servezone", + "githost": "code.foss.global", + "gitscope": "serve.zone", "gitrepo": "coreflow", "description": "A comprehensive tool for managing Docker-based applications and services, enabling efficient scaling, network management, and integration with cloud services.", "npmPackagename": "@serve.zone/coreflow", - "license": "UNLICENSED", + "license": "MIT", "keywords": [ "Docker", "Service scaling", diff --git a/package.json b/package.json index 28cd144..25353a7 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "repository": { "type": "git", - "url": "git+https://gitlab.com/pushrocks/coreflow.git" + "url": "https://code.foss.global/serve.zone/coreflow.git" }, "keywords": [ "Docker", @@ -49,9 +49,9 @@ "author": "Lossless GmbH", "license": "MIT", "bugs": { - "url": "https://gitlab.com/pushrocks/coreflow/issues" + "url": "https://gitlab.com/losslessone/services/servezone/coreflow/issues" }, - "homepage": "https://gitlab.com/pushrocks/coreflow#readme", + "homepage": "https://gitlab.com/losslessone/services/servezone/coreflow#readme", "devDependencies": { "@git.zone/tsbuild": "^2.2.0", "@git.zone/tsrun": "^1.3.3", @@ -100,4 +100,4 @@ "browserslist": [ "last 1 chrome versions" ] -} +} \ No newline at end of file diff --git a/readme.md b/readme.md index 3c54f37..72bb55c 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ # @serve.zone/coreflow + A comprehensive solution for managing Docker and scaling applications across servers, handling tasks from service provisioning to network traffic management. ## Install @@ -42,6 +43,7 @@ await coreflowInstance.stop(); ``` In the above example: + - The Coreflow instance is initialized. - Coreflow is started, which internally initializes various managers and connectors. - The method `handleDockerEvents` is used to handle Docker events. @@ -54,8 +56,8 @@ Coreflow manages applications and services, often requiring direct interactions ```typescript // Assuming coreflowInstance is already started as per previous examples const serviceConnection = coreflowInstance.createServiceConnection({ - serviceName: "myDatabaseService", - servicePort: 3306 + serviceName: 'myDatabaseService', + servicePort: 3306, }); serviceConnection.connect().then(() => { @@ -69,7 +71,7 @@ Coreflow excels in scaling applications across multiple servers. This involves n ```typescript const scalingPolicy = { - serviceName: "apiService", + serviceName: 'apiService', replicaCount: 5, // Target number of replicas maxReplicaCount: 10, // Maximum number of replicas minReplicaCount: 2, // Minimum number of replicas @@ -81,6 +83,7 @@ coreflowInstance.applyScalingPolicy(scalingPolicy).then(() => { ``` In the above example: + - A scaling policy is defined with target, maximum, and minimum replica counts for the `apiService`. - The `applyScalingPolicy` method of the Coreflow instance is used to apply this scaling policy. @@ -92,10 +95,10 @@ One of Coreflow's key features is its ability to manage network traffic, ensurin import { TrafficRule } from '@serve.zone/coreflow'; const rule: TrafficRule = { - serviceName: "webService", + serviceName: 'webService', externalPort: 80, internalPort: 3000, - protocol: "http", + protocol: 'http', }; coreflowInstance.applyTrafficRule(rule).then(() => { @@ -104,6 +107,7 @@ coreflowInstance.applyTrafficRule(rule).then(() => { ``` In the above example: + - A traffic rule is defined for the `webService`, redirecting external traffic from port 80 to the service's internal port 3000. - The `applyTrafficRule` method is used to enforce this rule. @@ -113,9 +117,9 @@ Coreflow integrates continuous integration and deployment processes, allowing se ```typescript const deploymentConfig = { - serviceName: "userAuthService", - image: "myregistry.com/userauthservice:latest", - updatePolicy: "rolling" // or "recreate" + serviceName: 'userAuthService', + image: 'myregistry.com/userauthservice:latest', + updatePolicy: 'rolling', // or "recreate" }; coreflowInstance.deployService(deploymentConfig).then(() => { @@ -124,6 +128,7 @@ coreflowInstance.deployService(deploymentConfig).then(() => { ``` In the above example: + - A deployment configuration is created for the `userAuthService` using the latest image from the specified registry. - The `deployService` method is then used to deploy the service using the specified update policy (e.g., rolling updates or recreating the service). @@ -132,12 +137,13 @@ In the above example: To keep track of your applications' health and performance, Coreflow provides tools for logging, monitoring, and alerting. ```typescript -coreflowInstance.monitorService("webService").on('serviceHealthUpdate', (healthStatus) => { +coreflowInstance.monitorService('webService').on('serviceHealthUpdate', (healthStatus) => { console.log(`Received health update for webService: ${healthStatus}`); }); ``` In the above example: + - The `monitorService` method is used to monitor the health status of the `webService`. - When a health update event is received, it is logged to the console. @@ -175,8 +181,8 @@ coreflowInstance.handleDockerEvents().then(() => { ```typescript const serviceConnection = coreflowInstance.createServiceConnection({ - serviceName: "databaseService", - servicePort: 5432 + serviceName: 'databaseService', + servicePort: 5432, }); serviceConnection.connect().then(() => { @@ -188,7 +194,7 @@ serviceConnection.connect().then(() => { ```typescript const scalingPolicy = { - serviceName: "microserviceA", + serviceName: 'microserviceA', replicaCount: 3, // Starting with 3 replicas maxReplicaCount: 10, // Allowing up to 10 replicas minReplicaCount: 2, // Ensuring at least 2 replicas @@ -206,17 +212,17 @@ import { TrafficRule } from '@serve.zone/coreflow'; const trafficRules: TrafficRule[] = [ { - serviceName: "frontendService", + serviceName: 'frontendService', externalPort: 80, internalPort: 3000, - protocol: "http", + protocol: 'http', }, { - serviceName: "apiService", + serviceName: 'apiService', externalPort: 443, internalPort: 4000, - protocol: "https", - } + protocol: 'https', + }, ]; Promise.all(trafficRules.map((rule) => coreflowInstance.applyTrafficRule(rule))).then(() => { @@ -228,9 +234,9 @@ Promise.all(trafficRules.map((rule) => coreflowInstance.applyTrafficRule(rule))) ```typescript const deploymentConfig = { - serviceName: "authService", - image: "myregistry.com/authservice:latest", - updatePolicy: "rolling", // Performing rolling updates + serviceName: 'authService', + image: 'myregistry.com/authservice:latest', + updatePolicy: 'rolling', // Performing rolling updates }; coreflowInstance.deployService(deploymentConfig).then(() => { @@ -241,7 +247,7 @@ coreflowInstance.deployService(deploymentConfig).then(() => { #### Step 7: Monitoring a Service ```typescript -coreflowInstance.monitorService("frontendService").on('serviceHealthUpdate', (healthStatus) => { +coreflowInstance.monitorService('frontendService').on('serviceHealthUpdate', (healthStatus) => { console.log(`Health update for frontendService: ${healthStatus}`); }); ``` @@ -262,7 +268,7 @@ const checkinTask = new Task({ buffered: true, taskFunction: async () => { console.log('Running checkin task...'); - } + }, }); const taskManager = coreflowInstance.taskManager; @@ -284,18 +290,18 @@ const coretrafficConnector = new CoretrafficConnector(coreflowInstance); const reverseProxyConfigs = [ { - hostName: "example.com", - destinationIp: "192.168.1.100", - destinationPort: "3000", - privateKey: "", - publicKey: "", + hostName: 'example.com', + destinationIp: '192.168.1.100', + destinationPort: '3000', + privateKey: '', + publicKey: '', }, { - hostName: "api.example.com", - destinationIp: "192.168.1.101", - destinationPort: "4000", - privateKey: "", - publicKey: "", + hostName: 'api.example.com', + destinationIp: '192.168.1.101', + destinationPort: '4000', + privateKey: '', + publicKey: '', }, ]; @@ -323,7 +329,7 @@ cloudlyConnector.start().then(() => { ```typescript cloudlyConnector.getConfigFromCloudly().then((config) => { console.log('Received configuration from Cloudly:', config); - + coreflowInstance.clusterManager.provisionWorkloadServices(config).then(() => { console.log('Workload services provisioned based on Cloudly config.'); }); @@ -335,4 +341,4 @@ cloudlyConnector.getConfigFromCloudly().then((config) => { Coreflow is a powerful and flexible tool for managing Docker-based applications, scaling services, configuring network traffic, handling continuous deployments, and ensuring observability of your infrastructure. The examples provided aim to give a comprehensive understanding of how to use Coreflow in various scenarios, ensuring it meets your DevOps and CI/CD needs. By leveraging Coreflow's rich feature set, you can optimize your infrastructure for high availability, scalability, and efficient operation across multiple servers and environments. -undefined \ No newline at end of file +undefined diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 7ffc8c8..0c90d50 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/coreflow', - version: '1.0.135', + version: '1.1.0', description: 'A comprehensive tool for managing Docker-based applications and services, enabling efficient scaling, network management, and integration with cloud services.' } diff --git a/ts/coreflow.classes.clustermanager.ts b/ts/coreflow.classes.clustermanager.ts index a7bf641..6202492 100644 --- a/ts/coreflow.classes.clustermanager.ts +++ b/ts/coreflow.classes.clustermanager.ts @@ -34,7 +34,7 @@ export class ClusterManager { this.coreflowRef.cloudlyConnector.cloudlyApiClient.configUpdateSubject.subscribe( async (dataArg) => { this.coreflowRef.taskManager.updateBaseServicesTask.trigger(); - } + }, ); } @@ -60,14 +60,17 @@ export class ClusterManager { // make sure there is a network for the webgateway let sznWebgatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName( this.coreflowRef.dockerHost, - this.commonDockerData.networkNames.sznWebgateway + this.commonDockerData.networkNames.sznWebgateway, ); if (!sznWebgatewayNetwork) { logger.log('info', 'Creating network: ' + this.commonDockerData.networkNames.sznWebgateway); - sznWebgatewayNetwork = await plugins.docker.DockerNetwork.createNetwork(this.coreflowRef.dockerHost, { - Name: this.commonDockerData.networkNames.sznWebgateway, - }); + sznWebgatewayNetwork = await plugins.docker.DockerNetwork.createNetwork( + this.coreflowRef.dockerHost, + { + Name: this.commonDockerData.networkNames.sznWebgateway, + }, + ); } else { logger.log('ok', 'sznWebgateway is already present'); } @@ -75,12 +78,15 @@ export class ClusterManager { // corechat network so base services can talk to each other let sznCorechatNetwork = await plugins.docker.DockerNetwork.getNetworkByName( this.coreflowRef.dockerHost, - this.commonDockerData.networkNames.sznCorechat + this.commonDockerData.networkNames.sznCorechat, ); if (!sznCorechatNetwork) { - sznCorechatNetwork = await plugins.docker.DockerNetwork.createNetwork(this.coreflowRef.dockerHost, { - Name: this.commonDockerData.networkNames.sznCorechat, - }); + sznCorechatNetwork = await plugins.docker.DockerNetwork.createNetwork( + this.coreflowRef.dockerHost, + { + Name: this.commonDockerData.networkNames.sznCorechat, + }, + ); } else { logger.log('ok', 'sznCorechat is already present'); } @@ -93,17 +99,23 @@ export class ClusterManager { // Images logger.log('info', `now updating docker images of base services...`); - const coretrafficImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, { - creationObject: { - imageUrl: 'code.foss.global/serve.zone/coretraffic', - } - }); + const coretrafficImage = await plugins.docker.DockerImage.createFromRegistry( + this.coreflowRef.dockerHost, + { + creationObject: { + imageUrl: 'code.foss.global/serve.zone/coretraffic', + }, + }, + ); - const corelogImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, { - creationObject: { - imageUrl: 'code.foss.global/serve.zone/corelog', - } - }); + const corelogImage = await plugins.docker.DockerImage.createFromRegistry( + this.coreflowRef.dockerHost, + { + creationObject: { + imageUrl: 'code.foss.global/serve.zone/corelog', + }, + }, + ); // SERVICES // lets deploy the base services @@ -111,7 +123,7 @@ export class ClusterManager { let coretrafficService: plugins.docker.DockerService; coretrafficService = await plugins.docker.DockerService.getServiceByName( this.coreflowRef.dockerHost, - 'coretraffic' + 'coretraffic', ); if (coretrafficService && (await coretrafficService.needsUpdate())) { @@ -123,19 +135,22 @@ export class ClusterManager { } if (!coretrafficService) { - coretrafficService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, { - image: coretrafficImage, - labels: {}, - name: 'coretraffic', - networks: [sznCorechatNetwork, sznWebgatewayNetwork], - networkAlias: 'coretraffic', - ports: ['80:7999', '443:8000'], - secrets: [], - resources: { - memorySizeMB: 1100, - volumeMounts: [], + coretrafficService = await plugins.docker.DockerService.createService( + this.coreflowRef.dockerHost, + { + image: coretrafficImage, + labels: {}, + name: 'coretraffic', + networks: [sznCorechatNetwork, sznWebgatewayNetwork], + networkAlias: 'coretraffic', + ports: ['80:7999', '443:8000'], + secrets: [], + resources: { + memorySizeMB: 1100, + volumeMounts: [], + }, }, - }); + ); } else { logger.log('ok', 'coretraffic service is already present'); } @@ -146,7 +161,7 @@ export class ClusterManager { let corelogService: plugins.docker.DockerService; corelogService = await plugins.docker.DockerService.getServiceByName( this.coreflowRef.dockerHost, - 'corelog' + 'corelog', ); if (corelogService && (await corelogService.needsUpdate())) { @@ -157,19 +172,22 @@ export class ClusterManager { } if (!corelogService) { - corelogService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, { - image: corelogImage, - labels: {}, - name: 'corelog', - networks: [sznCorechatNetwork], - networkAlias: 'corelog', - ports: [], - secrets: [], - resources: { - memorySizeMB: 120, - volumeMounts: [], + corelogService = await plugins.docker.DockerService.createService( + this.coreflowRef.dockerHost, + { + image: corelogImage, + labels: {}, + name: 'corelog', + networks: [sznCorechatNetwork], + networkAlias: 'corelog', + ports: [], + secrets: [], + resources: { + memorySizeMB: 120, + volumeMounts: [], + }, }, - }); + ); } else { logger.log('ok', 'corelog service is already present'); } @@ -178,30 +196,48 @@ export class ClusterManager { } public async provisionWorkloadService( - serviceArgFromCloudly: plugins.servezoneInterfaces.data.IService + serviceArgFromCloudly: plugins.servezoneInterfaces.data.IService, ) { - logger.log('info', `deploying service ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}...`); + logger.log( + 'info', + `deploying service ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}...`, + ); // get the image from cloudly - logger.log('info', `getting image for ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}`); - const containerImageFromCloudly = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.image.getImageById(serviceArgFromCloudly.data.imageId); - let localDockerImage: plugins.docker.DockerImage - + logger.log( + 'info', + `getting image for ${serviceArgFromCloudly.data.name}@${serviceArgFromCloudly.data.imageVersion}`, + ); + const containerImageFromCloudly = + await this.coreflowRef.cloudlyConnector.cloudlyApiClient.image.getImageById( + serviceArgFromCloudly.data.imageId, + ); + let localDockerImage: plugins.docker.DockerImage; + // lets get the docker image for the service if (containerImageFromCloudly.data.location.internal) { - const imageStream = await containerImageFromCloudly.pullImageVersion(serviceArgFromCloudly.data.imageVersion); - localDockerImage= await plugins.docker.DockerImage.createFromTarStream(this.coreflowRef.dockerHost, { - creationObject: { - imageUrl: containerImageFromCloudly.id, - imageTag: serviceArgFromCloudly.data.imageVersion, + const imageStream = await containerImageFromCloudly.pullImageVersion( + serviceArgFromCloudly.data.imageVersion, + ); + localDockerImage = await plugins.docker.DockerImage.createFromTarStream( + this.coreflowRef.dockerHost, + { + creationObject: { + imageUrl: containerImageFromCloudly.id, + imageTag: serviceArgFromCloudly.data.imageVersion, + }, + tarStream: + plugins.smartstream.nodewebhelpers.convertWebReadableToNodeReadable(imageStream), }, - tarStream: plugins.smartstream.nodewebhelpers.convertWebReadableToNodeReadable(imageStream) - }); + ); } else if ( - containerImageFromCloudly.data.location.externalRegistryId - && containerImageFromCloudly.data.location.externalImageTag + containerImageFromCloudly.data.location.externalRegistryId && + containerImageFromCloudly.data.location.externalImageTag ) { - const externalRegistry = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.externalRegistry.getRegistryById(containerImageFromCloudly.data.location.externalRegistryId); + const externalRegistry = + await this.coreflowRef.cloudlyConnector.cloudlyApiClient.externalRegistry.getRegistryById( + containerImageFromCloudly.data.location.externalRegistryId, + ); // Lets authenticate against the external registry // TODO: deduplicate this, check wether we are already authenticated await this.coreflowRef.dockerHost.auth({ @@ -209,12 +245,15 @@ export class ClusterManager { password: externalRegistry.data.password, serveraddress: externalRegistry.data.url, }); - localDockerImage = await plugins.docker.DockerImage.createFromRegistry(this.coreflowRef.dockerHost, { - creationObject: { - imageUrl: containerImageFromCloudly.id, - imageTag: serviceArgFromCloudly.data.imageVersion, + localDockerImage = await plugins.docker.DockerImage.createFromRegistry( + this.coreflowRef.dockerHost, + { + creationObject: { + imageUrl: containerImageFromCloudly.id, + imageTag: serviceArgFromCloudly.data.imageVersion, + }, }, - }); + ); await localDockerImage.pullLatestImageFromRegistry(); } else { throw new Error('Invalid image location'); @@ -222,20 +261,20 @@ export class ClusterManager { let containerService = await plugins.docker.DockerService.getServiceByName( this.coreflowRef.dockerHost, - serviceArgFromCloudly.data.name + serviceArgFromCloudly.data.name, ); this.coreflowRef.cloudlyConnector.cloudlyApiClient; - + const dockerSecretName = `${serviceArgFromCloudly.id}_${serviceArgFromCloudly.data.name}_Secret`; let containerSecret = await plugins.docker.DockerSecret.getSecretByName( this.coreflowRef.dockerHost, - dockerSecretName + dockerSecretName, ); // existing network to connect to const webGatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName( this.coreflowRef.dockerHost, - this.commonDockerData.networkNames.sznWebgateway + this.commonDockerData.networkNames.sznWebgateway, ); if (containerService && (await containerService.needsUpdate())) { @@ -250,43 +289,55 @@ export class ClusterManager { if (!containerService) { containerSecret = await plugins.docker.DockerSecret.getSecretByName( this.coreflowRef.dockerHost, - dockerSecretName + dockerSecretName, ); if (containerSecret) { await containerSecret.remove(); } - const secretBundle = await this.coreflowRef.cloudlyConnector.cloudlyApiClient.secretbundle.getSecretBundleById(serviceArgFromCloudly.data.secretBundleId); + const secretBundle = + await this.coreflowRef.cloudlyConnector.cloudlyApiClient.secretbundle.getSecretBundleById( + serviceArgFromCloudly.data.secretBundleId, + ); // lets create the relevant stuff on the docker side - containerSecret = await plugins.docker.DockerSecret.createSecret(this.coreflowRef.dockerHost, { - name: dockerSecretName, - contentArg: JSON.stringify(await secretBundle.getFlatKeyValueObjectForEnvironment()), - labels: {}, - version: await containerImageFromCloudly.data.versions[serviceArgFromCloudly.data.imageVersion], - }); - containerService = await plugins.docker.DockerService.createService(this.coreflowRef.dockerHost, { - name: serviceArgFromCloudly.data.name, - image: localDockerImage, - networks: [webGatewayNetwork], - secrets: [containerSecret], - ports: [], - labels: {}, - resources: serviceArgFromCloudly.data.resources, - // TODO: introduce a clean name here, that is guaranteed to work with APIs. - networkAlias: serviceArgFromCloudly.data.name, - }); + containerSecret = await plugins.docker.DockerSecret.createSecret( + this.coreflowRef.dockerHost, + { + name: dockerSecretName, + contentArg: JSON.stringify(await secretBundle.getFlatKeyValueObjectForEnvironment()), + labels: {}, + version: + await containerImageFromCloudly.data.versions[serviceArgFromCloudly.data.imageVersion], + }, + ); + containerService = await plugins.docker.DockerService.createService( + this.coreflowRef.dockerHost, + { + name: serviceArgFromCloudly.data.name, + image: localDockerImage, + networks: [webGatewayNetwork], + secrets: [containerSecret], + ports: [], + labels: {}, + resources: serviceArgFromCloudly.data.resources, + // TODO: introduce a clean name here, that is guaranteed to work with APIs. + networkAlias: serviceArgFromCloudly.data.name, + }, + ); } } /** * update traffic routing */ - public async updateTrafficRouting(clusterConfigArg: plugins.servezoneInterfaces.data.IClusterConfig) { + public async updateTrafficRouting( + clusterConfigArg: plugins.servezoneInterfaces.data.IClusterConfig, + ) { const services = await this.coreflowRef.dockerHost.getServices(); const webGatewayNetwork = await plugins.docker.DockerNetwork.getNetworkByName( this.coreflowRef.dockerHost, - this.commonDockerData.networkNames.sznWebgateway + this.commonDockerData.networkNames.sznWebgateway, ); const reverseProxyConfigs: plugins.servezoneInterfaces.data.IReverseProxyConfig[] = []; @@ -294,7 +345,7 @@ export class ClusterManager { serviceNameArg: string, hostNameArg: string, containerDestinationIp: string, - webDestinationPort: string + webDestinationPort: string, ) => { logger.log('ok', `trying to obtain a certificate for ${hostNameArg}`); const certificate = @@ -308,7 +359,7 @@ export class ClusterManager { }); logger.log( 'success', - `pushed routing config for ${hostNameArg} on workload service ${serviceNameArg}` + `pushed routing config for ${hostNameArg} on workload service ${serviceNameArg}`, ); }; @@ -330,7 +381,7 @@ export class ClusterManager { if (!containersOfServicesOnNetwork[0]) { logger.log( 'error', - `There seems to be no container available for service ${service.Spec.Name}` + `There seems to be no container available for service ${service.Spec.Name}`, ); continue; } @@ -344,7 +395,7 @@ export class ClusterManager { workloadConfig.name, hostName, containerDestinationIp, - webDestinationPort + webDestinationPort, ); } @@ -356,14 +407,14 @@ export class ClusterManager { workloadConfig.name, customDomainKey, containerDestinationIp, - workloadConfig.ports.custom[customDomainKey] + workloadConfig.ports.custom[customDomainKey], ); } } } else { logger.log( 'ok', - `service ${service.Spec.Name} is not a workload service and won't receive traffic` + `service ${service.Spec.Name} is not a workload service and won't receive traffic`, ); } } diff --git a/ts/coreflow.classes.internalserver.ts b/ts/coreflow.classes.internalserver.ts index 1497514..0d50fd1 100644 --- a/ts/coreflow.classes.internalserver.ts +++ b/ts/coreflow.classes.internalserver.ts @@ -11,7 +11,7 @@ export class InternalServer { public async start() { this.typedsocketServer = await plugins.typedsocket.TypedSocket.createServer( - this.coreflowRef.typedrouter + this.coreflowRef.typedrouter, ); } diff --git a/ts/coreflow.classes.taskmanager.ts b/ts/coreflow.classes.taskmanager.ts index 375edd2..8161f84 100644 --- a/ts/coreflow.classes.taskmanager.ts +++ b/ts/coreflow.classes.taskmanager.ts @@ -77,7 +77,7 @@ export class CoreflowTaskmanager { await this.updateBaseServicesTask.trigger(); logger.log( 'success', - 'initial tasks successfully executed! Now handing over to longterm taskmanager!' + 'initial tasks successfully executed! Now handing over to longterm taskmanager!', ); } catch (e) { console.log(e); diff --git a/ts/coreflow.connector.cloudlyconnector.ts b/ts/coreflow.connector.cloudlyconnector.ts index bfb7148..6148931 100644 --- a/ts/coreflow.connector.cloudlyconnector.ts +++ b/ts/coreflow.connector.cloudlyconnector.ts @@ -18,7 +18,7 @@ export class CloudlyConnector { public async start() { this.cloudlyApiClient = new plugins.servezoneApi.CloudlyApiClient({ registerAs: 'coreflow', - cloudlyUrl: await this.coreflowRef.serviceQenv.getEnvVarOnDemand('CLOUDLY_URL') + cloudlyUrl: await this.coreflowRef.serviceQenv.getEnvVarOnDemand('CLOUDLY_URL'), }); await this.cloudlyApiClient.start(); this.coreflowJumpCode = await this.coreflowRef.serviceQenv.getEnvVarOnDemand('JUMPCODE'); @@ -35,14 +35,12 @@ export class CloudlyConnector { } public async getConfigFromCloudly(): Promise { - const config = await this.cloudlyApiClient.getClusterConfigFromCloudlyByIdentity( - this.identity - ); + const config = await this.cloudlyApiClient.getClusterConfigFromCloudlyByIdentity(this.identity); return config; } public async getCertificateForDomainFromCloudly( - domainNameArg: string + domainNameArg: string, ): Promise { const certificate = await this.cloudlyApiClient.getCertificateForDomain({ identity: this.identity, diff --git a/ts/coreflow.connector.coretrafficconnector.ts b/ts/coreflow.connector.coretrafficconnector.ts index 4ef420d..8b56f9c 100644 --- a/ts/coreflow.connector.coretrafficconnector.ts +++ b/ts/coreflow.connector.coretrafficconnector.ts @@ -16,15 +16,15 @@ export class CoretrafficConnector { } public async setReverseConfigs( - reverseConfigsArg: plugins.servezoneInterfaces.data.IReverseProxyConfig[] + reverseConfigsArg: plugins.servezoneInterfaces.data.IReverseProxyConfig[], ) { await this.start(); const reactionRequest = this.coreflowRef.internalServer.typedsocketServer.createTypedRequest( 'updateRouting', await this.coreflowRef.internalServer.typedsocketServer.findTargetConnection( - async (targetConnection) => targetConnection.alias === 'coretraffic' - ) + async (targetConnection) => targetConnection.alias === 'coretraffic', + ), ); const response = await reactionRequest.fire({ reverseConfigs: reverseConfigsArg, diff --git a/ts/coreflow.paths.ts b/ts/coreflow.paths.ts index 4391fee..2434719 100644 --- a/ts/coreflow.paths.ts +++ b/ts/coreflow.paths.ts @@ -2,5 +2,5 @@ import * as plugins from './coreflow.plugins.js'; export const packageDir = plugins.path.join( plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), - '../' + '../', ); diff --git a/ts/index.ts b/ts/index.ts index c7f362b..051ccfb 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -18,7 +18,7 @@ export const runCli = async () => { 'info', `trying to start coreflow@v${projectInfoNpm.version} on ${ (await smartnetworkInstance.getPublicIps()).v4 - }` + }`, ); coreflowInstance = new Coreflow(); await coreflowInstance.start(); diff --git a/tsconfig.json b/tsconfig.json index dfe5a55..2413b93 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,9 +6,11 @@ "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true, - "verbatimModuleSyntax": true + "verbatimModuleSyntax": true, + "baseUrl": ".", + "paths": {} }, "exclude": [ "dist_*/**/*.d.ts" ] -} +} \ No newline at end of file