From e99a2a8127c0dfbedd149e48cf173537bdcd5089 Mon Sep 17 00:00:00 2001 From: Kasra Bigdeli Date: Mon, 19 Nov 2018 20:22:09 -0800 Subject: [PATCH] Dockerregistry converted --- app-backend/built/user/DockerRegistry.js | 148 ++++++---- app-backend/built/user/DockerRegistry.js.map | 2 +- app-backend/src/user/DockerRegistry.js | 245 ---------------- app-backend/src/user/DockerRegistry.ts | 287 +++++++++++++++++++ 4 files changed, 374 insertions(+), 308 deletions(-) delete mode 100644 app-backend/src/user/DockerRegistry.js create mode 100644 app-backend/src/user/DockerRegistry.ts diff --git a/app-backend/built/user/DockerRegistry.js b/app-backend/built/user/DockerRegistry.js index 605c139..d5a8d27 100644 --- a/app-backend/built/user/DockerRegistry.js +++ b/app-backend/built/user/DockerRegistry.js @@ -1,10 +1,9 @@ -const CaptainConstants = require('../utils/CaptainConstants'); -const Logger = require('../utils/Logger'); -const EnvVars = require('../utils/EnvVars'); -const fs = require('fs-extra'); -const uuid = require('uuid/v4'); -const ApiStatusCodes = require('../api/ApiStatusCodes'); -const bcrypt = require('bcryptjs'); +"use strict"; +const CaptainConstants = require("../utils/CaptainConstants"); +const Logger = require("../utils/Logger"); +const fs = require("fs-extra"); +const ApiStatusCodes = require("../api/ApiStatusCodes"); +const bcrypt = require("bcryptjs"); class DockerRegistry { constructor(dockerApi, dataStore, certbotManager, loadBalancerManager, captainManager) { this.dockerApi = dockerApi; @@ -12,11 +11,15 @@ class DockerRegistry { this.certbotManager = certbotManager; this.loadBalancerManager = loadBalancerManager; this.captainManager = captainManager; + // this.dockerApi = dockerApi; + // this.dataStore = dataStore; + // this.certbotManager = certbotManager; + // this.loadBalancerManager = loadBalancerManager; + // this.captainManager = captainManager; } enableLocalDockerRegistry() { const self = this; - return Promise.resolve() - .then(function () { + return Promise.resolve().then(function () { return self.dataStore.setHasLocalRegistry(true); }); } @@ -28,9 +31,11 @@ class DockerRegistry { }) .then(function (rootHasSsl) { if (!rootHasSsl) { - throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, 'Root must have SSL before enabling ssl for docker registry.'); + throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, "Root must have SSL before enabling ssl for docker registry."); } - return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain + '.' + self.dataStore.getRootDomain()); + return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain + + "." + + self.dataStore.getRootDomain()); }) .then(function () { return self.dataStore.setHasRegistrySsl(true); @@ -44,9 +49,11 @@ class DockerRegistry { } getLocalRegistryDomainAndPort() { const self = this; - return CaptainConstants.registrySubDomain + '.' + + return (CaptainConstants.registrySubDomain + + "." + self.dataStore.getRootDomain() + - ':' + CaptainConstants.registrySubDomainPort; + ":" + + CaptainConstants.registrySubDomainPort); } ensureDockerRegistryRunningOnThisNode() { const dockerApi = this.dockerApi; @@ -54,72 +61,86 @@ class DockerRegistry { const myNodeId = this.captainManager.getMyNodeId(); const captainSalt = this.captainManager.getCaptainSalt(); function createRegistryServiceOnNode() { - return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [{ - protocol: 'tcp', + return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [ + { + protocol: "tcp", containerPort: 5000, - hostPort: CaptainConstants.registrySubDomainPort - }], myNodeId, [{ - containerPath: '/cert-files', - hostPath: CaptainConstants.letsEncryptEtcPath + hostPort: CaptainConstants.registrySubDomainPort, + }, + ], myNodeId, [ + { + containerPath: "/cert-files", + hostPath: CaptainConstants.letsEncryptEtcPath, }, { - containerPath: '/var/lib/registry', - hostPath: CaptainConstants.registryPathOnHost + containerPath: "/var/lib/registry", + hostPath: CaptainConstants.registryPathOnHost, }, { - containerPath: '/etc/auth', - hostPath: CaptainConstants.registryAuthPathOnHost - } - ], [{ - key: 'REGISTRY_HTTP_TLS_CERTIFICATE', - value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/fullchain.pem' - }, { - key: 'REGISTRY_HTTP_TLS_KEY', - value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/privkey.pem' - }, { - key: 'REGISTRY_AUTH', - value: 'htpasswd' - }, { - key: 'REGISTRY_AUTH_HTPASSWD_REALM', - value: 'Registry Realm' - }, { - key: 'REGISTRY_AUTH_HTPASSWD_PATH', - value: '/etc/auth' - }]); + containerPath: "/etc/auth", + hostPath: CaptainConstants.registryAuthPathOnHost, + }, + ], [ + { + key: "REGISTRY_HTTP_TLS_CERTIFICATE", + value: "/cert-files/live/" + + CaptainConstants.registrySubDomain + + "." + + dataStore.getRootDomain() + + "/fullchain.pem", + }, + { + key: "REGISTRY_HTTP_TLS_KEY", + value: "/cert-files/live/" + + CaptainConstants.registrySubDomain + + "." + + dataStore.getRootDomain() + + "/privkey.pem", + }, + { + key: "REGISTRY_AUTH", + value: "htpasswd", + }, + { + key: "REGISTRY_AUTH_HTPASSWD_REALM", + value: "Registry Realm", + }, + { + key: "REGISTRY_AUTH_HTPASSWD_PATH", + value: "/etc/auth", + }, + ], undefined); } return Promise.resolve() .then(function () { - let authContent = CaptainConstants.captainRegistryUsername + ':' + + const authContent = CaptainConstants.captainRegistryUsername + + ":" + bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5)); return fs.outputFile(CaptainConstants.registryAuthPathOnHost, authContent); }) .then(function () { - return dockerApi - .isServiceRunningByName(CaptainConstants.registryServiceName); + return dockerApi.isServiceRunningByName(CaptainConstants.registryServiceName); }) .then(function (isRunning) { if (isRunning) { - Logger.d('Captain Registry is already running.. '); - return dockerApi - .getNodeIdByServiceName(CaptainConstants.registryServiceName); + Logger.d("Captain Registry is already running.. "); + return dockerApi.getNodeIdByServiceName(CaptainConstants.registryServiceName); } else { - Logger.d('No Captain Registry service is running. Creating one...'); - return createRegistryServiceOnNode(myNodeId) - .then(function () { + Logger.d("No Captain Registry service is running. Creating one..."); + return createRegistryServiceOnNode().then(function () { return myNodeId; }); } }) .then(function (nodeId) { if (nodeId !== myNodeId) { - Logger.d('Captain Registry is running on a different node. Removing...'); + Logger.d("Captain Registry is running on a different node. Removing..."); return dockerApi .removeServiceByName(CaptainConstants.registryServiceName) .then(function () { - Logger.d('Creating Registry on this node...'); - return createRegistryServiceOnNode(myNodeId) - .then(function () { + Logger.d("Creating Registry on this node..."); + return createRegistryServiceOnNode().then(function () { return true; }); }); @@ -132,9 +153,9 @@ class DockerRegistry { updateRegistryAuthHeader(username, password, domain, currentVersion) { const self = this; const dockerApi = this.dockerApi; - let nextVersion = null; - let secretName = null; - let userEmailAddress; + let nextVersion = undefined; + let secretName = undefined; + let userEmailAddress = undefined; return Promise.resolve() .then(function () { return self.dataStore.getUserEmailAddress(); @@ -148,15 +169,17 @@ class DockerRegistry { }) .then(function (versionSaved) { nextVersion = versionSaved + 1; - secretName = CaptainConstants.captainRegistryAuthHeaderSecretPrefix + nextVersion; + secretName = + CaptainConstants.captainRegistryAuthHeaderSecretPrefix + + nextVersion; if (!username || !password || !domain) { - throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'user, pass and domain are all required'); + throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, "user, pass and domain are all required"); } return dockerApi.checkIfSecretExist(secretName); }) .then(function (secretExist) { if (secretExist) { - Logger.d('WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated.'); + Logger.d("WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated."); return self.updateRegistryAuthHeader(username, password, domain, nextVersion); } else { @@ -164,11 +187,12 @@ class DockerRegistry { .ensureSecret(secretName, JSON.stringify({ username: username, password: password, - email: userEmailAddress || CaptainConstants.defaultEmail, - serveraddress: domain + email: userEmailAddress || + CaptainConstants.defaultEmail, + serveraddress: domain, })) .then(function () { - Logger.d('Updating EnvVars to update docker registry auth.'); + Logger.d("Updating EnvVars to update docker registry auth."); return self.dataStore.setRegistryAuthSecretVersion(nextVersion); }); } diff --git a/app-backend/built/user/DockerRegistry.js.map b/app-backend/built/user/DockerRegistry.js.map index 7c32ece..6c42bbb 100644 --- a/app-backend/built/user/DockerRegistry.js.map +++ b/app-backend/built/user/DockerRegistry.js.map @@ -1 +1 @@ -{"version":3,"file":"DockerRegistry.js","sourceRoot":"","sources":["../../src/user/DockerRegistry.js"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"DockerRegistry.js","sourceRoot":"","sources":["../../src/user/DockerRegistry.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/app-backend/src/user/DockerRegistry.js b/app-backend/src/user/DockerRegistry.js deleted file mode 100644 index 1a80f1a..0000000 --- a/app-backend/src/user/DockerRegistry.js +++ /dev/null @@ -1,245 +0,0 @@ -const CaptainConstants = require('../utils/CaptainConstants'); -const Logger = require('../utils/Logger'); -const EnvVars = require('../utils/EnvVars'); -const fs = require('fs-extra'); -const uuid = require('uuid/v4'); -const ApiStatusCodes = require('../api/ApiStatusCodes'); -const bcrypt = require('bcryptjs'); - -class DockerRegistry { - - constructor(dockerApi, dataStore, certbotManager, loadBalancerManager, captainManager) { - this.dockerApi = dockerApi; - this.dataStore = dataStore; - this.certbotManager = certbotManager; - this.loadBalancerManager = loadBalancerManager; - this.captainManager = captainManager; - } - - enableLocalDockerRegistry() { - - const self = this; - - return Promise.resolve() - .then(function () { - - return self.dataStore.setHasLocalRegistry(true); - - }); - } - - enableRegistrySsl() { - - const self = this; - - return Promise.resolve() - .then(function () { - return self.dataStore.getHasRootSsl(); - }) - .then(function (rootHasSsl) { - - if (!rootHasSsl) { - throw ApiStatusCodes.createError(ApiStatusCodes.ILLEGAL_OPERATION, 'Root must have SSL before enabling ssl for docker registry.'); - } - - return self.certbotManager.enableSsl(CaptainConstants.registrySubDomain + '.' + self.dataStore.getRootDomain()); - }) - .then(function () { - - return self.dataStore.setHasRegistrySsl(true); - }) - .then(function () { - - return self.loadBalancerManager.rePopulateNginxConfigFile(self.dataStore); - }) - .then(function () { - - return self.loadBalancerManager.sendReloadSignal(); - - }); - - } - - getLocalRegistryDomainAndPort() { - - const self = this; - - return CaptainConstants.registrySubDomain + '.' + - self.dataStore.getRootDomain() + - ':' + CaptainConstants.registrySubDomainPort; - } - - ensureDockerRegistryRunningOnThisNode() { - - const dockerApi = this.dockerApi; - const dataStore = this.dataStore; - - const myNodeId = this.captainManager.getMyNodeId(); - const captainSalt = this.captainManager.getCaptainSalt(); - - - function createRegistryServiceOnNode() { - - return dockerApi.createServiceOnNodeId(CaptainConstants.registryImageName, CaptainConstants.registryServiceName, [{ - protocol: 'tcp', - containerPort: 5000, - hostPort: CaptainConstants.registrySubDomainPort - }], myNodeId, [{ - containerPath: '/cert-files', - hostPath: CaptainConstants.letsEncryptEtcPath - }, - { - containerPath: '/var/lib/registry', - hostPath: CaptainConstants.registryPathOnHost - }, - { - containerPath: '/etc/auth', - hostPath: CaptainConstants.registryAuthPathOnHost - } - ], [{ - key: 'REGISTRY_HTTP_TLS_CERTIFICATE', - value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/fullchain.pem' - }, { - key: 'REGISTRY_HTTP_TLS_KEY', - value: '/cert-files/live/' + CaptainConstants.registrySubDomain + '.' + dataStore.getRootDomain() + '/privkey.pem' - }, { - key: 'REGISTRY_AUTH', - value: 'htpasswd' - }, { - key: 'REGISTRY_AUTH_HTPASSWD_REALM', - value: 'Registry Realm' - }, { - key: 'REGISTRY_AUTH_HTPASSWD_PATH', - value: '/etc/auth' - }]); - - } - - return Promise.resolve() - .then(function () { - - let authContent = CaptainConstants.captainRegistryUsername + ':' + - bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5)); - - return fs.outputFile(CaptainConstants.registryAuthPathOnHost, authContent); - }) - .then(function () { - - return dockerApi - .isServiceRunningByName(CaptainConstants.registryServiceName); - - }) - .then(function (isRunning) { - - if (isRunning) { - - Logger.d('Captain Registry is already running.. '); - - return dockerApi - .getNodeIdByServiceName(CaptainConstants.registryServiceName); - - } else { - - Logger.d('No Captain Registry service is running. Creating one...'); - - return createRegistryServiceOnNode(myNodeId) - .then(function () { - return myNodeId; - }) - } - - }) - .then(function (nodeId) { - - if (nodeId !== myNodeId) { - - Logger.d('Captain Registry is running on a different node. Removing...'); - - return dockerApi - .removeServiceByName(CaptainConstants.registryServiceName) - .then(function () { - - Logger.d('Creating Registry on this node...'); - - return createRegistryServiceOnNode(myNodeId) - .then(function () { - - return true; - - }); - }); - - } else { - - return true; - - } - }) - - } - - updateRegistryAuthHeader(username, password, domain, currentVersion) { - - const self = this; - const dockerApi = this.dockerApi; - - let nextVersion = null; - - let secretName = null; - - let userEmailAddress; - - return Promise.resolve() - .then(function () { - - return self.dataStore.getUserEmailAddress(); - - }) - .then(function (emailAddress) { - - userEmailAddress = emailAddress; - - if (currentVersion) { - return currentVersion - } - - return self.dataStore.getRegistryAuthSecretVersion(); - - }) - .then(function (versionSaved) { - - nextVersion = versionSaved + 1; - secretName = CaptainConstants.captainRegistryAuthHeaderSecretPrefix + nextVersion; - - if (!username || !password || !domain) { - throw ApiStatusCodes.createError(ApiStatusCodes.STATUS_ERROR_GENERIC, 'user, pass and domain are all required'); - } - - return dockerApi.checkIfSecretExist(secretName); - - }) - .then(function (secretExist) { - - if (secretExist) { - Logger.d('WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated.'); - return self.updateRegistryAuthHeader(username, password, domain, nextVersion); - } else { - return dockerApi - .ensureSecret(secretName, JSON.stringify({ - username: username, - password: password, - email: userEmailAddress || CaptainConstants.defaultEmail, - serveraddress: domain - })) - .then(function () { - Logger.d('Updating EnvVars to update docker registry auth.'); - return self.dataStore.setRegistryAuthSecretVersion(nextVersion); - }); - } - - }); - } - -} - -module.exports = DockerRegistry; \ No newline at end of file diff --git a/app-backend/src/user/DockerRegistry.ts b/app-backend/src/user/DockerRegistry.ts new file mode 100644 index 0000000..3600257 --- /dev/null +++ b/app-backend/src/user/DockerRegistry.ts @@ -0,0 +1,287 @@ +import CaptainConstants = require("../utils/CaptainConstants"); +import Logger = require("../utils/Logger"); +import EnvVars = require("../utils/EnvVars"); +import fs = require("fs-extra"); +import uuid = require("uuid/v4"); +import ApiStatusCodes = require("../api/ApiStatusCodes"); +import bcrypt = require("bcryptjs"); +import DockerApi = require("../docker/DockerApi"); +import DataStore = require("../datastore/DataStoreImpl"); +import CertbotManager = require("../user/CertbotManager"); +import LoadBalancerManager = require("../user/LoadBalancerManager"); +import CaptainManager = require("../user/CaptainManager"); + +class DockerRegistry { + constructor( + private dockerApi: DockerApi, + private dataStore: DataStore, + private certbotManager: CertbotManager, + private loadBalancerManager: LoadBalancerManager, + private captainManager: CaptainManager + ) { + // this.dockerApi = dockerApi; + // this.dataStore = dataStore; + // this.certbotManager = certbotManager; + // this.loadBalancerManager = loadBalancerManager; + // this.captainManager = captainManager; + } + + enableLocalDockerRegistry() { + const self = this; + + return Promise.resolve().then(function() { + return self.dataStore.setHasLocalRegistry(true); + }); + } + + enableRegistrySsl() { + const self = this; + + return Promise.resolve() + .then(function() { + return self.dataStore.getHasRootSsl(); + }) + .then(function(rootHasSsl) { + if (!rootHasSsl) { + throw ApiStatusCodes.createError( + ApiStatusCodes.ILLEGAL_OPERATION, + "Root must have SSL before enabling ssl for docker registry." + ); + } + + return self.certbotManager.enableSsl( + CaptainConstants.registrySubDomain + + "." + + self.dataStore.getRootDomain() + ); + }) + .then(function() { + return self.dataStore.setHasRegistrySsl(true); + }) + .then(function() { + return self.loadBalancerManager.rePopulateNginxConfigFile( + self.dataStore + ); + }) + .then(function() { + return self.loadBalancerManager.sendReloadSignal(); + }); + } + + getLocalRegistryDomainAndPort() { + const self = this; + + return ( + CaptainConstants.registrySubDomain + + "." + + self.dataStore.getRootDomain() + + ":" + + CaptainConstants.registrySubDomainPort + ); + } + + ensureDockerRegistryRunningOnThisNode() { + const dockerApi = this.dockerApi; + const dataStore = this.dataStore; + + const myNodeId = this.captainManager.getMyNodeId(); + const captainSalt = this.captainManager.getCaptainSalt(); + + function createRegistryServiceOnNode() { + return dockerApi.createServiceOnNodeId( + CaptainConstants.registryImageName, + CaptainConstants.registryServiceName, + [ + { + protocol: "tcp", + containerPort: 5000, + hostPort: CaptainConstants.registrySubDomainPort, + }, + ], + myNodeId, + [ + { + containerPath: "/cert-files", + hostPath: CaptainConstants.letsEncryptEtcPath, + }, + { + containerPath: "/var/lib/registry", + hostPath: CaptainConstants.registryPathOnHost, + }, + { + containerPath: "/etc/auth", + hostPath: CaptainConstants.registryAuthPathOnHost, + }, + ], + [ + { + key: "REGISTRY_HTTP_TLS_CERTIFICATE", + value: + "/cert-files/live/" + + CaptainConstants.registrySubDomain + + "." + + dataStore.getRootDomain() + + "/fullchain.pem", + }, + { + key: "REGISTRY_HTTP_TLS_KEY", + value: + "/cert-files/live/" + + CaptainConstants.registrySubDomain + + "." + + dataStore.getRootDomain() + + "/privkey.pem", + }, + { + key: "REGISTRY_AUTH", + value: "htpasswd", + }, + { + key: "REGISTRY_AUTH_HTPASSWD_REALM", + value: "Registry Realm", + }, + { + key: "REGISTRY_AUTH_HTPASSWD_PATH", + value: "/etc/auth", + }, + ] + , undefined); + } + + return Promise.resolve() + .then(function() { + const authContent = + CaptainConstants.captainRegistryUsername + + ":" + + bcrypt.hashSync(captainSalt, bcrypt.genSaltSync(5)); + + return fs.outputFile( + CaptainConstants.registryAuthPathOnHost, + authContent + ); + }) + .then(function() { + return dockerApi.isServiceRunningByName( + CaptainConstants.registryServiceName + ); + }) + .then(function(isRunning) { + if (isRunning) { + Logger.d("Captain Registry is already running.. "); + + return dockerApi.getNodeIdByServiceName( + CaptainConstants.registryServiceName + ); + } else { + Logger.d( + "No Captain Registry service is running. Creating one..." + ); + + return createRegistryServiceOnNode().then( + function() { + return myNodeId; + } + ); + } + }) + .then(function(nodeId) { + if (nodeId !== myNodeId) { + Logger.d( + "Captain Registry is running on a different node. Removing..." + ); + + return dockerApi + .removeServiceByName( + CaptainConstants.registryServiceName + ) + .then(function() { + Logger.d("Creating Registry on this node..."); + + return createRegistryServiceOnNode().then( + function() { + return true; + } + ); + }); + } else { + return true; + } + }); + } + + updateRegistryAuthHeader(username: string, password: string, domain: string, currentVersion: number): Promise { + const self = this; + const dockerApi = this.dockerApi; + + let nextVersion: number|undefined = undefined; + + let secretName: string|undefined = undefined; + + let userEmailAddress: string|undefined = undefined; + + return Promise.resolve() + .then(function() { + return self.dataStore.getUserEmailAddress(); + }) + .then(function(emailAddress) { + userEmailAddress = emailAddress; + + if (currentVersion) { + return currentVersion; + } + + return self.dataStore.getRegistryAuthSecretVersion(); + }) + .then(function(versionSaved) { + nextVersion = versionSaved + 1; + secretName = + CaptainConstants.captainRegistryAuthHeaderSecretPrefix + + nextVersion; + + if (!username || !password || !domain) { + throw ApiStatusCodes.createError( + ApiStatusCodes.STATUS_ERROR_GENERIC, + "user, pass and domain are all required" + ); + } + + return dockerApi.checkIfSecretExist(secretName); + }) + .then(function(secretExist) { + if (secretExist) { + Logger.d( + "WARNING! Unexpected secret exist! Perhaps secret was created but Captain was not updated." + ); + return self.updateRegistryAuthHeader( + username, + password, + domain, + nextVersion! + ); + } else { + return dockerApi + .ensureSecret( + secretName, + JSON.stringify({ + username: username, + password: password, + email: + userEmailAddress || + CaptainConstants.defaultEmail, + serveraddress: domain, + }) + ) + .then(function() { + Logger.d( + "Updating EnvVars to update docker registry auth." + ); + return self.dataStore.setRegistryAuthSecretVersion( + nextVersion + ); + }); + } + }); + } +} + +export = DockerRegistry; \ No newline at end of file