@ossy/deployment-tools 0.0.45 → 0.0.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +30 -4
  2. package/cdk.context.json +37 -0
  3. package/cdk.json +40 -0
  4. package/package.json +17 -6
  5. package/src/aws-credentials/aws-credentials.js +84 -0
  6. package/src/aws-credentials/cli.js +56 -0
  7. package/src/aws-credentials/index.js +1 -0
  8. package/src/config/index.js +1 -0
  9. package/src/{platform-config.js → config/platform-config.js} +20 -2
  10. package/src/{cli-commands/deploy-handler.js → deploy/cli.js} +9 -7
  11. package/src/deploy/platform-deployment.js +74 -0
  12. package/src/{deployment-queue-client.js → deployment-queue/deployment-queue.js} +15 -15
  13. package/src/deployment-queue/index.js +1 -0
  14. package/src/index.js +2 -6
  15. package/src/infrastructure/cli.js +30 -0
  16. package/src/infrastructure/container-server/aws-profile.js +22 -0
  17. package/src/infrastructure/container-server/caddy.service.js +69 -0
  18. package/src/infrastructure/container-server/container-server.js +175 -0
  19. package/src/infrastructure/container-server/deployment-tools.service.js +37 -0
  20. package/src/infrastructure/container-server/index.js +3 -0
  21. package/src/infrastructure/container-server/user-data-commands.js +32 -0
  22. package/src/infrastructure/establish-trust-stack.js +65 -0
  23. package/src/infrastructure/platform-stack.js +53 -0
  24. package/src/{caddy-client.js → server/caddy.js} +9 -9
  25. package/src/server/cli.js +34 -0
  26. package/src/{docker-client.js → server/docker.js} +11 -10
  27. package/src/server/platform-server.js +37 -0
  28. package/src/{ci-rest-api.js → server/rest-api.js} +4 -4
  29. package/src/template/cli.js +22 -0
  30. package/src/template/index.js +1 -0
  31. package/src/{platform-template.js → template/platform-template.js} +2 -1
  32. package/src/types.js +0 -39
  33. package/src/aws-credentials-client.js +0 -47
  34. package/src/cli-commands/index.js +0 -27
  35. package/src/cli-commands/start-handler.js +0 -28
  36. package/src/cli-commands/status-handler.js +0 -11
  37. package/src/cli-commands/stop-handler.js +0 -11
  38. package/src/platform-cli.js +0 -7
  39. package/src/platform-client.js +0 -99
@@ -0,0 +1,69 @@
1
+ const systemdServiceFile = `
2
+ # caddy-api.service
3
+ #
4
+ # For using Caddy with its API.
5
+ #
6
+ # This unit is "durable" in that it will automatically resume
7
+ # the last active configuration if the service is restarted.
8
+ #
9
+ # See https://caddyserver.com/docs/install for instructions.
10
+
11
+ [Unit]
12
+ Description=Caddy
13
+ Documentation=https://caddyserver.com/docs/
14
+ After=network.target network-online.target
15
+ Requires=network-online.target
16
+
17
+ [Service]
18
+ Type=notify
19
+ User=caddy
20
+ Group=caddy
21
+ ExecStart=/usr/bin/caddy.route53 run --environ --resume
22
+ TimeoutStopSec=5s
23
+ LimitNOFILE=1048576
24
+ LimitNPROC=512
25
+ PrivateTmp=true
26
+ ProtectSystem=full
27
+ AmbientCapabilities=CAP_NET_BIND_SERVICE
28
+
29
+ [Install]
30
+ WantedBy=multi-user.target cloud-init.target
31
+ `
32
+
33
+ class CaddyService {
34
+
35
+ static install() {
36
+ return [
37
+ `sudo echo "${systemdServiceFile}" >> /etc/systemd/system/caddy-route53.service`,
38
+ 'sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https',
39
+ 'sudo curl -1sLf \'https://dl.cloudsmith.io/public/caddy/stable/gpg.key\' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg',
40
+ 'sudo curl -1sLf \'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt\' | sudo tee /etc/apt/sources.list.d/caddy-stable.list',
41
+ 'sudo curl -1sLf \'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key\' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg',
42
+ 'sudo curl -1sLf \'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt\' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list',
43
+ 'sudo add-apt-repository ppa:longsleep/golang-backports -y',
44
+ 'sudo apt update',
45
+ 'sudo apt install caddy xcaddy golang-go -y',
46
+ 'sudo xcaddy build --with github.com/caddy-dns/route53',
47
+ 'sudo mv ./caddy /usr/bin/caddy.route53'
48
+ ]
49
+ }
50
+
51
+ static enable() {
52
+ return [
53
+ 'sudo systemctl disable caddy.service',
54
+ 'sudo systemctl enable caddy-route53.service'
55
+ ]
56
+ }
57
+
58
+ static start() {
59
+ return [
60
+ 'sudo systemctl stop caddy.service',
61
+ 'sudo systemctl start caddy-route53.service'
62
+ ]
63
+ }
64
+
65
+ }
66
+
67
+ module.exports = {
68
+ CaddyService
69
+ }
@@ -0,0 +1,175 @@
1
+ const { CfnOutput } = require('aws-cdk-lib')
2
+ const { Construct } = require('constructs')
3
+ const {
4
+ Instance,
5
+ InstanceType,
6
+ InstanceClass,
7
+ InstanceSize,
8
+ GenericLinuxImage,
9
+ Vpc,
10
+ SecurityGroup,
11
+ Peer,
12
+ Port,
13
+ UserData
14
+ } = require('aws-cdk-lib/aws-ec2')
15
+ const { HostedZone, ARecord, RecordTarget } = require('aws-cdk-lib/aws-route53')
16
+ const { Role, ServicePrincipal, Policy, PolicyStatement, Effect } = require('aws-cdk-lib/aws-iam')
17
+ const {
18
+ getInstallNodeJs,
19
+ getInstallNpm,
20
+ getInstallDocker
21
+ } = require('./user-data-commands')
22
+ const { CaddyService } = require('./caddy.service')
23
+ const { DeploymentToolsService } = require('./deployment-tools.service')
24
+ const { AwsProfile } = require('./aws-profile')
25
+ const { SupportedRegions } = require('../../config')
26
+
27
+ /**
28
+ * Platform template definition
29
+ * @namespace ContainerServer
30
+ * @typedef {Object} ContainerServerProps
31
+ * @property {PlatformConfig} platformConfig - platform config
32
+ * @property {Bucket} platformConfigBucket - aws bucket
33
+ */
34
+ const InstanceImages = {
35
+ UBUNTU: 'ami-092cce4a19b438926'
36
+ }
37
+
38
+ class ContainerServer extends Construct {
39
+
40
+ /**
41
+ * EC2 Instance that docker containers are served on
42
+ *
43
+ * @param {object} scope - scope
44
+ * @param {string} id - id
45
+ * @param {ContainerServerProps} props - ContainerServerProps
46
+ */
47
+ constructor(scope, id, props) {
48
+ super(scope, id)
49
+
50
+ const hostedZone = HostedZone.fromLookup(this, 'HostedZone', { domainName: props.platformConfig.domain })
51
+
52
+ const vpc = Vpc.fromLookup(this, 'VPC', {
53
+ isDefault: true
54
+ })
55
+
56
+ const securityGroup = new SecurityGroup(this, 'SecurityGroup', {
57
+ vpc,
58
+ allowAllOutbound: true
59
+ })
60
+
61
+ securityGroup.addIngressRule(
62
+ Peer.anyIpv4(),
63
+ Port.tcp(22),
64
+ 'allow SSH access from anywhere'
65
+ )
66
+
67
+ securityGroup.addIngressRule(
68
+ Peer.anyIpv4(),
69
+ Port.tcp(80),
70
+ 'allow HTTP traffic from anywhere'
71
+ )
72
+
73
+ securityGroup.addIngressRule(
74
+ Peer.anyIpv4(),
75
+ Port.tcp(443),
76
+ 'allow HTTPS traffic from anywhere'
77
+ )
78
+
79
+ const role = new Role(this, 'role', {
80
+ assumedBy: new ServicePrincipal('ec2.amazonaws.com')
81
+ })
82
+
83
+ role.attachInlinePolicy(new Policy(this, 'policy', {
84
+ statements: [
85
+ new PolicyStatement({
86
+ effect: Effect.ALLOW,
87
+ actions: [
88
+ 'route53:ListResourceRecordSets',
89
+ 'route53:GetChange',
90
+ 'route53:ChangeResourceRecordSets'
91
+ ],
92
+ resources: [
93
+ `arn:aws:route53:::hostedzone/${hostedZone.hostedZoneId}`,
94
+ 'arn:aws:route53:::change/*'
95
+ ]
96
+ }),
97
+ new PolicyStatement({
98
+ effect: Effect.ALLOW,
99
+ actions: [
100
+ 'route53:ListHostedZonesByName',
101
+ 'route53:ListHostedZones'
102
+ ],
103
+ resources: ['*']
104
+ })
105
+ ]
106
+ }))
107
+
108
+ const userData = UserData.forLinux()
109
+
110
+ userData.addCommands(
111
+ 'sudo apt update -y',
112
+ ...getInstallNodeJs(),
113
+ ...getInstallNpm(),
114
+ ...getInstallDocker(),
115
+ 'sudo apt-get install awscli --yes',
116
+ ...AwsProfile.writeFile(role.roleArn, SupportedRegions.North),
117
+ ...CaddyService.install(),
118
+ ...DeploymentToolsService.install()
119
+ )
120
+
121
+ userData.addS3DownloadCommand({
122
+ bucket: props.platformConfigBucket,
123
+ bucketKey: 'platform-config.json',
124
+ localFile: '/home/ubuntu/platform-config.json'
125
+ })
126
+
127
+ userData.addCommands(
128
+ 'sudo systemctl daemon-reload',
129
+ ...CaddyService.enable(),
130
+ ...DeploymentToolsService.enable(),
131
+ ...CaddyService.start(),
132
+ ...DeploymentToolsService.start()
133
+ )
134
+
135
+ const ec2Instance = new Instance(this, 'Ec2Instance', {
136
+ vpc,
137
+ securityGroup,
138
+ userData,
139
+ role,
140
+ instanceType: InstanceType.of(
141
+ InstanceClass.T3,
142
+ InstanceSize.MICRO
143
+ ),
144
+ machineImage: new GenericLinuxImage({
145
+ [SupportedRegions.North]: InstanceImages.UBUNTU
146
+ }),
147
+ keyName: props.platformConfig.awsKeyPairName
148
+ })
149
+
150
+ props.platformConfigBucket.grantRead(ec2Instance, '*')
151
+
152
+ // const hostedZone = !!props.createNewHostedZone
153
+ // ? new PublicHostedZone(this, 'HostedZone', { zoneName: props.domain })
154
+ // : HostedZone.fromLookup(this, 'HostedZone', { domainName: props.domain });
155
+
156
+ // eslint-disable-next-line no-new
157
+ new ARecord(this, 'WildcardRecord', {
158
+ zone: hostedZone,
159
+ recordName: `*.${props.platformConfig.activeEnvironment}.${props.platformConfig.domain}`,
160
+ target: RecordTarget.fromIpAddresses(ec2Instance.instancePublicIp)
161
+ })
162
+
163
+ // eslint-disable-next-line no-new
164
+ new CfnOutput(this, 'Intance Ip', {
165
+ value: ec2Instance.instancePublicIp,
166
+ description: 'Public ip of the ec2 instance',
167
+ exportName: 'instanceIp'
168
+ })
169
+
170
+ }
171
+ }
172
+
173
+ module.exports = {
174
+ ContainerServer
175
+ }
@@ -0,0 +1,37 @@
1
+ const systemdServiceFile = `
2
+ [Unit]
3
+ Description=D
4
+ After=network.target caddy-route53.service
5
+
6
+ [Service]
7
+ EnvironmentFile=/etc/environment
8
+ User=caddy
9
+ Group=caddy
10
+ AmbientCapabilities=CAP_NET_BIND_SERVICE
11
+ CapabilityBoundingSet=CAP_NET_BIND_SERVICE
12
+ ExecStart=/usr/bin/npx --yes @ossy/deployment-tools start --platforms /home/ubuntu/deployment-platform.json
13
+ Restart=on-failure
14
+
15
+ [Install]
16
+ WantedBy=multi-user.target cloud-init.target
17
+ `
18
+
19
+ class DeploymentToolsService {
20
+
21
+ static install() {
22
+ return [`sudo echo "${systemdServiceFile}" >> /etc/systemd/system/deployment-tools.service`]
23
+ }
24
+
25
+ static enable() {
26
+ return ['sudo systemctl enable deployment-tools.service']
27
+ }
28
+
29
+ static start() {
30
+ return ['sudo systemctl start deployment-tools.service']
31
+ }
32
+
33
+ }
34
+
35
+ module.exports = {
36
+ DeploymentToolsService
37
+ }
@@ -0,0 +1,3 @@
1
+ const { ContainerServer } = require('./container-server')
2
+
3
+ module.exports = { ContainerServer }
@@ -0,0 +1,32 @@
1
+
2
+ const getInstallDocker = () => [
3
+ 'apt-get remove docker docker-engine docker.io containerd runc',
4
+ `apt-get install \
5
+ apt-transport-https \
6
+ ca-certificates \
7
+ curl \
8
+ gnupg-agent \
9
+ software-properties-common -y`,
10
+ 'curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -',
11
+ `sudo add-apt-repository \
12
+ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
13
+ $(lsb_release -cs) \
14
+ stable"`,
15
+ 'sudo apt-get update',
16
+ 'sudo apt-get install docker-ce docker-ce-cli containerd.io -y'
17
+ ]
18
+
19
+ const getInstallNodeJs = () => [
20
+ 'curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -',
21
+ 'sudo apt-get -y install nodejs'
22
+ ]
23
+
24
+ const getInstallNpm = () => [
25
+ 'sudo apt install npm'
26
+ ]
27
+
28
+ module.exports = {
29
+ getInstallDocker,
30
+ getInstallNodeJs,
31
+ getInstallNpm
32
+ }
@@ -0,0 +1,65 @@
1
+ const { Stack, Duration } = require('aws-cdk-lib')
2
+ const {
3
+ OpenIdConnectProvider,
4
+ OpenIdConnectPrincipal,
5
+ Role,
6
+ Effect,
7
+ PolicyDocument,
8
+ PolicyStatement
9
+ } = require('aws-cdk-lib/aws-iam')
10
+
11
+ class EstablishTrustStack extends Stack {
12
+ /**
13
+ * Establishes trust between GithHub and Amazon Web Services.
14
+ * This is needed so that we can interact with Amazon Web Services through
15
+ * GitHub Actions without having to manually provide credentials every time we
16
+ * run a workflow
17
+ *
18
+ * @param {object} scope - scope
19
+ * @param {string} id - id
20
+ * @param {PlatformTemplate} props - PlatformTemplate
21
+ */
22
+ constructor(scope, id, props) {
23
+ super(scope, id, props)
24
+
25
+ const provider = new OpenIdConnectProvider(this, 'GitHubProvider', {
26
+ url: 'https://token.actions.githubusercontent.com',
27
+ clientIds: ['sts.amazonaws.com']
28
+ })
29
+
30
+ const GitHubPrincipal = new OpenIdConnectPrincipal(provider)
31
+ .withConditions({
32
+ StringLike: {
33
+ 'token.actions.githubusercontent.com:sub':
34
+ `repo:${props.config.ciGithubActionsRepo}:*`
35
+ }
36
+ })
37
+
38
+ // eslint-disable-next-line no-new
39
+ new Role(this, 'GitHubActionsRole', {
40
+ assumedBy: GitHubPrincipal,
41
+ description: 'Role assumed by GitHubPrincipal for deploying from CI using aws cdk',
42
+ roleName: props.config.awsRoleToAssume,
43
+ maxSessionDuration: Duration.hours(1),
44
+ inlinePolicies: {
45
+ CdkDeploymentPolicy: new PolicyDocument({
46
+ assignSids: true,
47
+ statements: [
48
+ new PolicyStatement({
49
+ effect: Effect.ALLOW,
50
+ actions: ['sts:AssumeRole'],
51
+ resources: [
52
+ `arn:aws:iam::${props.config.awsAccountId}:role/cdk-*`,
53
+ `arn:aws:sqs:${props.config.awsRegion}:${props.config.awsAccountId}:*`
54
+ ]
55
+ })
56
+ ]
57
+ })
58
+ }
59
+ })
60
+ }
61
+ }
62
+
63
+ module.exports = {
64
+ EstablishTrustStack
65
+ }
@@ -0,0 +1,53 @@
1
+ /* eslint-disable no-new */
2
+ const { Stack, Duration, RemovalPolicy } = require('aws-cdk-lib')
3
+ const { Queue } = require('aws-cdk-lib/aws-sqs')
4
+ const { Bucket, BucketEncryption, BlockPublicAccess } = require('aws-cdk-lib/aws-s3')
5
+ const { Source, BucketDeployment } = require('aws-cdk-lib/aws-s3-deployment')
6
+
7
+ const { ContainerServer } = require('./container-server')
8
+
9
+ const { SupportedDeploymentTypes } = require('../config')
10
+
11
+ class PlatformStack extends Stack {
12
+ constructor(scope, id, props) {
13
+ super(scope, id, props)
14
+
15
+ if (!props?.config) {
16
+ throw ('[PlatformStack] No template config provided')
17
+ }
18
+
19
+ const isContainerDeploymentsEnabled = props.config.supportedDeploymentTypes.includes(SupportedDeploymentTypes.Container)
20
+
21
+ if (isContainerDeploymentsEnabled) {
22
+
23
+ new Queue(this, 'DeploymentQueue', {
24
+ queueName: `${props.config.platformName}-${props.config.activeEnvironment}`,
25
+ receiveMessageWaitTime: Duration.seconds(20)
26
+ })
27
+
28
+ const platformConfigBucket = new Bucket(this, 'PlatformConfig', {
29
+ bucketName: `${props.config.platformName}-${props.config.activeEnvironment}`,
30
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
31
+ encryption: BucketEncryption.S3_MANAGED,
32
+ removalPolicy: RemovalPolicy.DESTROY,
33
+ autoDeleteObjects: true
34
+ })
35
+
36
+ const platformConfigDeployment = new BucketDeployment(this, 'PlatformConfigDeployment', {
37
+ sources: [Source.jsonData('platform-config.json', props.config)],
38
+ destinationBucket: platformConfigBucket
39
+ })
40
+
41
+ new ContainerServer(this, 'ContainerServer', {
42
+ platformConfig: props.config,
43
+ platformConfigBucket: platformConfigDeployment.deployedBucket
44
+ })
45
+
46
+ }
47
+
48
+ }
49
+ }
50
+
51
+ module.exports = {
52
+ PlatformStack
53
+ }
@@ -1,5 +1,5 @@
1
1
  const fetch = require('node-fetch')
2
- const { logInfo, logError } = require('./log')
2
+ const { logInfo, logError } = require('../log')
3
3
 
4
4
  const Matchers = {
5
5
  host: host => ({ host: [host] }),
@@ -17,13 +17,13 @@ const Handlers = {
17
17
  })
18
18
  }
19
19
 
20
- class CaddyClient {
20
+ class CaddyService {
21
21
 
22
- static deploy(platformConfig, deploymentRequest) {
22
+ static addDeployment(platformConfig, deploymentRequest) {
23
23
 
24
24
  const url = `${deploymentRequest.subdomain}.${platformConfig.activeEnvironment}.${platformConfig.domain}`
25
25
 
26
- logInfo({ message: `[CaddyClient] Updating caddy config to route ${url} to localhost:${deploymentRequest.hostPort}` })
26
+ logInfo({ message: `[CaddyService] Updating caddy config to route ${url} to localhost:${deploymentRequest.hostPort}` })
27
27
 
28
28
  return fetch(`http://localhost:2019/config/apps/http/servers/${platformConfig.ciServerName}/routes/0/handle`, {
29
29
  method: 'POST',
@@ -35,11 +35,11 @@ class CaddyClient {
35
35
  }
36
36
  ]))
37
37
  })
38
- .catch(error => logError({ message: `[CaddyClient] Could not update caddy config to include ${url}`, error }))
38
+ .catch(error => logError({ message: `[CaddyService] Could not update caddy config to include ${url}`, error }))
39
39
  }
40
40
 
41
- static applyDefaultServerConfig(platformConfig) {
42
- logInfo({ message: '[CaddyClient] Applying default caddy config' })
41
+ static applyDefaultConfig(platformConfig) {
42
+ logInfo({ message: '[CaddyService] Applying default caddy config' })
43
43
  return fetch('http://localhost:2019/load', {
44
44
  method: 'POST',
45
45
  headers: { 'Content-Type': 'application/json' },
@@ -101,11 +101,11 @@ class CaddyClient {
101
101
  }
102
102
  })
103
103
  })
104
- .catch(error => logError({ message: '[CaddyClient] Could not apply default caddy config', error }))
104
+ .catch(error => logError({ message: '[CaddyService] Could not apply default caddy config', error }))
105
105
  }
106
106
 
107
107
  }
108
108
 
109
109
  module.exports = {
110
- CaddyClient
110
+ CaddyService
111
111
  }
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ const arg = require('arg')
3
+ const { exec } = require('child_process')
4
+ const { PlatformClient } = require('./platform-server')
5
+
6
+ const { logInfo, logError } = require('../log')
7
+
8
+ //eslint-disable-next-line no-unused-vars
9
+ const [_, __, command, ...restArgs] = process.argv
10
+
11
+ const start = cliArgs => {
12
+ logInfo({ message: 'Running start command' })
13
+
14
+ const parsedArgs = arg({
15
+ '--platforms': String,
16
+ '-p': '--platforms'
17
+ }, { argv: cliArgs })
18
+
19
+ PlatformClient.start(parsedArgs['--platforms'])
20
+ }
21
+
22
+ const status = () => {
23
+ logInfo({ message: 'Running status command' })
24
+ exec('systemctl status deployment-tools.service')
25
+ }
26
+
27
+ const stop = () => {
28
+ logInfo({ message: 'Running stop command' })
29
+ exec('systemctl stop deployment-tools.service')
30
+ }
31
+
32
+ !!command
33
+ ? { start, status, stop }[command]()
34
+ : logError({ message: 'No command provided' })
@@ -1,12 +1,13 @@
1
1
  const { exec } = require('child_process')
2
2
  const fs = require('fs')
3
3
  const { nanoid } = require('nanoid')
4
- const { logInfo, logError } = require('./log')
5
4
 
6
- class DockerClient {
5
+ const { logInfo, logError } = require('../log')
6
+
7
+ class DockerService {
7
8
 
8
9
  static createDockerNetworkForContainerManagerServer(platformConfig) {
9
- logInfo({ message: '[DockerClient] Creating docker network for comunication between containers' })
10
+ logInfo({ message: '[DockerService] Creating docker network for comunication between containers' })
10
11
  exec(`sudo docker network create ${platformConfig.ciDockerNetworkName}`)
11
12
  }
12
13
 
@@ -41,9 +42,9 @@ class DockerClient {
41
42
  logInfo({ message: 'Starting docker deployment sequence' })
42
43
 
43
44
  const dockerCommandScript = `'#!/bin/bash'
44
- ${DockerClient.stopContainer(deploymentRequest)}
45
- ${DockerClient.resolveCredentials(deploymentRequest)}
46
- ${DockerClient.startContainer(platformConfig, deploymentRequest)}`
45
+ ${DockerService.stopContainer(deploymentRequest)}
46
+ ${DockerService.resolveCredentials(deploymentRequest)}
47
+ ${DockerService.startContainer(platformConfig, deploymentRequest)}`
47
48
 
48
49
  const deploymentId = nanoid()
49
50
 
@@ -55,15 +56,15 @@ ${DockerClient.startContainer(platformConfig, deploymentRequest)}`
55
56
  const command = exec(`bash ${FilePaths.DeploymentScript}`)
56
57
 
57
58
  command.stdout.on('data', data => {
58
- logInfo({ message: `[DockerClient]: ${data}` })
59
+ logInfo({ message: `[DockerService]: ${data}` })
59
60
  })
60
61
 
61
62
  command.stderr.on('data', (data) => {
62
- logError({ message: `[DockerClient]: ${data}` })
63
+ logError({ message: `[DockerService]: ${data}` })
63
64
  })
64
65
 
65
66
  command.on('close', code => {
66
- logInfo({ message: `[DockerClient] command exited with code ${code}` })
67
+ logInfo({ message: `[DockerService] command exited with code ${code}` })
67
68
  fs.unlinkSync(FilePaths.DeploymentScript)
68
69
  resolve()
69
70
  })
@@ -74,5 +75,5 @@ ${DockerClient.startContainer(platformConfig, deploymentRequest)}`
74
75
  }
75
76
 
76
77
  module.exports = {
77
- DockerClient
78
+ DockerService
78
79
  }
@@ -0,0 +1,37 @@
1
+ const { CaddyService } = require('./caddy')
2
+ const { DockerService } = require('./docker')
3
+ const { RestApiService } = require('./rest-api')
4
+
5
+ const { PlatformTemplateService } = require('../template')
6
+ const { PlatformConfigService } = require('../config')
7
+ const { DeploymentQueueClient } = require('../deployment-queue')
8
+ const { logError } = require('../log')
9
+
10
+ // journalctl -u service-name.service
11
+ class PlatformServerService {
12
+
13
+ static start(platformTemplatesFilePath) {
14
+ PlatformTemplateService.readFromFile(platformTemplatesFilePath).then(([firstPlatformTemplateFound]) => {
15
+ const platformConfig = PlatformConfigService.from(firstPlatformTemplateFound)
16
+
17
+ RestApiService.start(platformConfig)
18
+ CaddyService.applyDefaultConfig(platformConfig)
19
+
20
+ DeploymentQueueClient.pollForDeploymentRequests(
21
+ platformConfig,
22
+ deploymentRequest => {
23
+ DockerService.deploy(platformConfig, deploymentRequest)
24
+ CaddyService.addDeployment(platformConfig, deploymentRequest)
25
+ return Promise.resolve()
26
+ }
27
+ )
28
+
29
+ })
30
+ .catch(error => logError({ message: '[PlatformServerService] Could not start the platform server', error }))
31
+ }
32
+
33
+ }
34
+
35
+ module.exports = {
36
+ PlatformServerService
37
+ }
@@ -1,7 +1,7 @@
1
1
  const express = require('express')
2
- const { logInfo } = require('./log')
2
+ const { logInfo } = require('../log')
3
3
 
4
- class CiRestApi {
4
+ class RestApiService {
5
5
 
6
6
  static start(platformConfig) {
7
7
  const server = express()
@@ -17,12 +17,12 @@ class CiRestApi {
17
17
  })
18
18
 
19
19
  server.listen(platformConfig.ciInternalServerPort, () => {
20
- logInfo({ message: `[ContainerManagerServer] API is live on port ${platformConfig.ciInternalServerPort}`})
20
+ logInfo({ message: `[RestApiService] API is live on port ${platformConfig.ciInternalServerPort}`})
21
21
  })
22
22
  }
23
23
 
24
24
  }
25
25
 
26
26
  module.exports = {
27
- CiRestApi
27
+ RestApiService
28
28
  }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ const arg = require('arg')
3
+ const { PlatformTemplateService } = require('./platform-template')
4
+
5
+ const { logInfo, logError } = require('../log')
6
+
7
+ //eslint-disable-next-line no-unused-vars
8
+ const [_, __, command, ...options] = process.argv
9
+
10
+ const validate = () => {
11
+ logInfo({ message: 'Running validate command' })
12
+
13
+ const parsedArgs = arg({
14
+ '--platforms': String,
15
+ '-p': '--platforms'
16
+ }, { argv: options })
17
+
18
+ PlatformTemplateService.readFromFile(parsedArgs['--platforms'])
19
+ .then(() => logInfo({ message: 'Template is valid' }))
20
+ }
21
+
22
+ command === 'validate' ? validate() : logError({ message: 'No command provided' })
@@ -0,0 +1 @@
1
+ module.exports = require('./platform-template')
@@ -1,6 +1,6 @@
1
1
  const { resolve } = require('path')
2
2
  const { readFileSync } = require('fs')
3
- const { logError, logInfo } = require('./log')
3
+ const { logError, logInfo } = require('../log')
4
4
 
5
5
  /**
6
6
  * Platform template definition
@@ -19,6 +19,7 @@ const { logError, logInfo } = require('./log')
19
19
  * @property {string} ciInternalServerPort- ? | number;
20
20
  * @property {string} ciServerName - ?
21
21
  * @property {string} ciDockerNetworkName - ?
22
+ * @property {string} ciGithubActionsRepo - organisation/repoName
22
23
  */
23
24
  class PlatformTemplateService {
24
25