ignite-1219 Added SSL configuration.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/09de108c Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/09de108c Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/09de108c Branch: refs/heads/ignite-843 Commit: 09de108c624549f6fbca2c9d4872778b4babdb0f Parents: 4f34437 Author: Vasiliy Sisko <[email protected]> Authored: Mon Sep 28 17:38:21 2015 +0700 Committer: Andrey <[email protected]> Committed: Mon Sep 28 17:38:21 2015 +0700 ---------------------------------------------------------------------- .../main/js/controllers/clusters-controller.js | 13 ++- .../main/js/controllers/models/clusters.json | 94 ++++++++++++++++++++ .../main/js/controllers/models/metadata.json | 3 +- modules/control-center-web/src/main/js/db.js | 11 ++- .../js/routes/generator/generator-common.js | 15 ++++ .../main/js/routes/generator/generator-java.js | 34 +++++++ .../js/routes/generator/generator-properties.js | 45 ++++++++-- .../main/js/routes/generator/generator-xml.js | 26 ++++++ .../src/main/js/routes/summary.js | 10 ++- .../src/main/js/views/includes/controls.jade | 4 +- 10 files changed, 239 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/controllers/clusters-controller.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/clusters-controller.js b/modules/control-center-web/src/main/js/controllers/clusters-controller.js index 5adca57..a1c9537 100644 --- a/modules/control-center-web/src/main/js/controllers/clusters-controller.js +++ b/modules/control-center-web/src/main/js/controllers/clusters-controller.js @@ -97,7 +97,8 @@ consoleModule.controller('clustersController', [ swap: {xml: '', java: '', allDefaults: true}, time: {xml: '', java: '', allDefaults: true}, pools: {xml: '', java: '', allDefaults: true}, - transactions: {xml: '', java: '', allDefaults: true} + transactions: {xml: '', java: '', allDefaults: true}, + sslConfiguration: {xml: '', java: '', allDefaults: true} }; $scope.cacheModes = $common.mkOptions(['LOCAL', 'REPLICATED', 'PARTITIONED']); @@ -112,6 +113,12 @@ consoleModule.controller('clustersController', [ $scope.marshallers = $common.mkOptions(['OptimizedMarshaller', 'JdkMarshaller']); + $scope.sslKeyAlgorithms = ['SumX509', 'X509']; + + $scope.sslStoreType = ['JKS', 'PCKS11', 'PCKS12']; + + $scope.sslProtocols = ['TSL', 'SSL']; + $scope.toggleExpanded = function () { $scope.ui.expanded = !$scope.ui.expanded; @@ -259,6 +266,10 @@ consoleModule.controller('clustersController', [ $scope.preview.transactions.xml = $generatorXml.clusterTransactions(val).asString(); $scope.preview.transactions.java = $generatorJava.clusterTransactions(val).asString(); $scope.preview.transactions.allDefaults = $common.isEmptyString($scope.preview.transactions.xml); + + $scope.preview.sslConfiguration.xml = $generatorXml.clusterSsl(val).asString(); + $scope.preview.sslConfiguration.java = $generatorJava.clusterSsl(val).asString(); + $scope.preview.sslConfiguration.allDefaults = $common.isEmptyString($scope.preview.sslConfiguration.xml); } }, true); }) http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/controllers/models/clusters.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/models/clusters.json b/modules/control-center-web/src/main/js/controllers/models/clusters.json index f314c55..c8cf8d8 100644 --- a/modules/control-center-web/src/main/js/controllers/models/clusters.json +++ b/modules/control-center-web/src/main/js/controllers/models/clusters.json @@ -990,6 +990,100 @@ ] } ] + }, + { + "label": "SSL configuration", + "group": "sslConfiguration", + "tip": [ + "Settings for SSL configuration" + ], + "fields": [ + { + "label": "Enabled", + "id": "sslEnabled", + "type": "check", + "model": "sslEnabled", + "tip": [ + "Flag indicating whether to configure SSL configuration" + ] + }, + { + "label": "Algorithm to create a key manager", + "id": "keyAlgorithm", + "type": "typeahead", + "path": "sslContextFactory", + "model": "keyAlgorithm", + "placeholder": "SumX509", + "items": "sslKeyAlgorithms", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Sets key manager algorithm that will be used to create a key manager", + "Notice that in most cased default value suites well, however, on Android platform this value need to be set to X509" + ] + }, + { + "label": "Key store file", + "id": "keyStoreFilePath", + "type": "text", + "path": "sslContextFactory", + "model": "keyStoreFilePath", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Path to the key store file", + "This is a mandatory parameter since ssl context could not be initialized without key manager" + ] + }, + { + "label": "Key store type", + "id": "keyStoreType", + "type": "typeahead", + "path": "sslContextFactory", + "model": "keyStoreType", + "placeholder": "JKS", + "items": "sslStoreType", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Key store type used in context initialization" + ] + }, + { + "label": "Protocol", + "id": "protocol", + "type": "typeahead", + "path": "sslContextFactory", + "model": "protocol", + "placeholder": "TSL", + "items": "sslProtocols", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Protocol for secure transport" + ] + }, + { + "label": "Trust store file", + "id": "trustStoreFilePath", + "type": "text", + "path": "sslContextFactory", + "model": "trustStoreFilePath", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Path to the trust store file" + ] + }, + { + "label": "Trust store type", + "id": "trustStoreType", + "type": "typeahead", + "path": "sslContextFactory", + "model": "trustStoreType", + "placeholder": "JKS", + "items": "sslStoreType", + "hide": "!backupItem.sslEnabled", + "tip": [ + "Trust store type used in context initialization" + ] + } + ] } ] } http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/controllers/models/metadata.json ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json index eb75d83..7ef0e20 100644 --- a/modules/control-center-web/src/main/js/controllers/models/metadata.json +++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json @@ -46,7 +46,8 @@ { "label": "Key type", "id": "keyType", - "type": "withJavaBuildInTypes", + "type": "typeahead", + "items": "javaBuildInClasses", "model": "keyType", "required": true, "placeholder": "Full class name for Key", http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/db.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/db.js b/modules/control-center-web/src/main/js/db.js index 8d86bc7..874aa82 100644 --- a/modules/control-center-web/src/main/js/db.js +++ b/modules/control-center-web/src/main/js/db.js @@ -326,7 +326,16 @@ var ClusterSchema = new Schema({ txSerializableEnabled: Boolean, txManagerLookupClassName: String }, - waitForSegmentOnStart: Boolean + waitForSegmentOnStart: Boolean, + sslEnabled: Boolean, + sslContextFactory: { + keyAlgorithm: String, + keyStoreFilePath: String, + keyStoreType: String, + protocol: String, + trustStoreFilePath: String, + trustStoreType: String + } }); // Install deep populate plugin. http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/routes/generator/generator-common.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-common.js b/modules/control-center-web/src/main/js/routes/generator/generator-common.js index 20e4673..6f20dab 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-common.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-common.js @@ -317,6 +317,21 @@ $generatorCommon.TRANSACTION_CONFIGURATION = { } }; +// SSL configuration code generation descriptor. +$generatorCommon.SSL_CONFIGURATION_FACTORY = { + className: 'org.apache.ignite.ssl.SslContextFactory', + fields: { + keyAlgorithm: null, + keyStoreFilePath: {type: 'path'}, + keyStorePassword: {type: 'raw'}, + keyStoreType: null, + protocol: null, + trustStoreFilePath: {type: 'path'}, + keyTrustPassword: {type: 'raw'}, + trustStoreType: null, + } +}; + // For server side we should export Java code generation entry point. if (typeof window === 'undefined') { module.exports = $generatorCommon; http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/routes/generator/generator-java.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-java.js b/modules/control-center-web/src/main/js/routes/generator/generator-java.js index dc4eebc..0676ca2 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-java.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-java.js @@ -38,6 +38,9 @@ $generatorJava.toJavaCode = function (val, type) { if (val == null) return 'null'; + if (type == 'raw') + return val; + if (type == 'class') return val + '.class'; @@ -259,6 +262,10 @@ $generatorJava.beanProperty = function (res, varName, bean, beanPropName, beanVa $generatorJava.property(res, beanVarName, bean, propName, 'path', descr.setterName); break; + case 'raw': + $generatorJava.property(res, beanVarName, bean, propName, 'raw', descr.setterName); + break; + case 'propertiesAsList': var val = bean[propName]; @@ -1385,6 +1392,31 @@ $generatorJava.javaTypeName = function(type) { }; /** + * Java code generator for cluster's SSL configuration. + * + * @param cluster Cluster to get SSL configuration. + * @param res Optional configuration presentation builder object. + * @returns Configuration presentation builder object + */ +$generatorJava.clusterSsl = function(cluster, res) { + if (!res) + res = $generatorCommon.builder(); + + if (cluster.sslEnabled && $commonUtils.isDefined(cluster.sslContextFactory)) { + cluster.sslContextFactory.keyStorePassword = + ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.keyStoreFilePath)) ? '_Key_Storage_Password_' : undefined; + + cluster.sslContextFactory.keyTrustPassword = ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.trustStoreFilePath)) ? + '_Trust_Storage_Password_' : undefined; + + $generatorJava.beanProperty(res, 'cfg', cluster.sslContextFactory, 'sslContextFactory', 'sslContextFactory', + 'org.apache.ignite.ssl.SslContextFactory', $generatorCommon.SSL_CONFIGURATION_FACTORY.fields, false); + } + + return res; +} + +/** * Function to generate java code for cluster configuration. * * @param cluster Cluster to process. @@ -1432,6 +1464,8 @@ $generatorJava.cluster = function (cluster, javaClass, clientNearCfg) { $generatorJava.clusterCaches(cluster.caches, res); + $generatorJava.clusterSsl(cluster, res); + if (javaClass) { res.line('return cfg;'); res.endBlock('}'); http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/routes/generator/generator-properties.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-properties.js b/modules/control-center-web/src/main/js/routes/generator/generator-properties.js index c935b93..b499634 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-properties.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-properties.js @@ -31,9 +31,7 @@ $generatorProperties = {}; * @param cluster Configuration to process. * @returns {string} Generated content. */ -$generatorProperties.dataSourcesProperties = function (cluster) { - var res = $generatorCommon.builder(); - +$generatorProperties.dataSourcesProperties = function (cluster, res) { var datasources = []; if (cluster.caches && cluster.caches.length > 0) { @@ -47,6 +45,14 @@ $generatorProperties.dataSourcesProperties = function (cluster) { if (!_.contains(datasources, beanId)) { datasources.push(beanId); + if (!res) { + res = $generatorCommon.builder(); + + res.line('# ' + $generatorCommon.mainComment()); + } + + res.needEmptyLine = true; + switch (storeFactory.dialect) { case 'DB2': res.line(beanId + '.jdbc.server_name=YOUR_JDBC_SERVER_NAME'); @@ -58,6 +64,7 @@ $generatorProperties.dataSourcesProperties = function (cluster) { default: res.line(beanId + '.jdbc.url=YOUR_JDBC_URL'); } + res.line(beanId + '.jdbc.username=YOUR_USER_NAME'); res.line(beanId + '.jdbc.password=YOUR_PASSWORD'); res.line(); @@ -67,12 +74,36 @@ $generatorProperties.dataSourcesProperties = function (cluster) { }); } - if (datasources.length > 0) - return '# ' + $generatorCommon.mainComment() + '\n\n' + res.join('\n'); - - return undefined; + return res; }; +/** + * Generate properties file with properties stubs for cluster SSL configuration. + * + * @param cluster Cluster to get SSL configuration. + * @param res Optional configuration presentation builder object. + * @returns Configuration presentation builder object + */ +$generatorProperties.sslProperties = function (cluster, res) { + if (cluster.sslEnabled && cluster.sslContextFactory) { + if (!res) { + res = $generatorCommon.builder(); + + res.line('# ' + $generatorCommon.mainComment()); + } + + res.needEmptyLine = true; + + if ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.keyStoreFilePath)) + res.line('ssl.key.storage.password=YOUR_SSL_KEY_STORAGE_PASSWORD'); + + if ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.trustStoreFilePath)) + res.line('ssl.trust.storage.password=YOUR_SSL_TRUST_STORAGE_PASSWORD'); + } + + return res; +} + // For server side we should export properties generation entry point. if (typeof window === 'undefined') { module.exports = $generatorProperties; http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/routes/generator/generator-xml.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js index 71bc81e..8b956ff 100644 --- a/modules/control-center-web/src/main/js/routes/generator/generator-xml.js +++ b/modules/control-center-web/src/main/js/routes/generator/generator-xml.js @@ -536,6 +536,30 @@ $generatorXml.clusterTransactions = function (cluster, res) { return res; }; +/** + * XML generator for cluster's SSL configuration. + * + * @param cluster Cluster to get SSL configuration. + * @param res Optional configuration presentation builder object. + * @returns Configuration presentation builder object + */ +$generatorXml.clusterSsl = function(cluster, res) { + if (!res) + res = $generatorCommon.builder(); + + if (cluster.sslEnabled && $commonUtils.isDefined(cluster.sslContextFactory)) { + cluster.sslContextFactory.keyStorePassword = + ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.keyStoreFilePath)) ? '${ssl.key.storage.password}' : undefined; + + cluster.sslContextFactory.keyTrustPassword = + ($commonUtils.isDefinedAndNotEmpty(cluster.sslContextFactory.trustStoreFilePath)) ? '${ssl.trust.storage.password}' : undefined; + + $generatorXml.beanProperty(res, cluster.sslContextFactory, 'sslContextFactory', $generatorCommon.SSL_CONFIGURATION_FACTORY, false); + } + + return res; +} + // Generate cache general group. $generatorXml.cacheGeneral = function(cache, res) { if (!res) @@ -1038,6 +1062,8 @@ $generatorXml.cluster = function (cluster, clientNearCfg) { $generatorXml.clusterCaches(cluster.caches, res); + $generatorXml.clusterSsl(cluster, res); + res.endBlock('</bean>'); // Build final XML: http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/routes/summary.js ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/routes/summary.js b/modules/control-center-web/src/main/js/routes/summary.js index 941a5e7..53a1286 100644 --- a/modules/control-center-web/src/main/js/routes/summary.js +++ b/modules/control-center-web/src/main/js/routes/summary.js @@ -65,15 +65,17 @@ router.post('/download', function (req, res) { // Send the file to the page output. zip.pipe(res); + var builder = $generatorProperties.sslProperties(cluster); + if (!clientNearConfiguration) { zip.append($generatorDocker.clusterDocker(cluster, req.body.os), {name: 'Dockerfile'}); - var props = $generatorProperties.dataSourcesProperties(cluster); - - if (props) - zip.append(props, {name: 'secret.properties'}); + builder = $generatorProperties.dataSourcesProperties(cluster, builder); } + if (builder) + zip.append(builder.asString(), {name: 'secret.properties'}); + zip.append($generatorXml.cluster(cluster, clientNearConfiguration), {name: cluster.name + '.xml'}) .append($generatorJava.cluster(cluster, false, clientNearConfiguration), {name: cluster.name + '.snippet.java'}) http://git-wip-us.apache.org/repos/asf/ignite/blob/09de108c/modules/control-center-web/src/main/js/views/includes/controls.jade ---------------------------------------------------------------------- diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade index 3136542..ae66e2b 100644 --- a/modules/control-center-web/src/main/js/views/includes/controls.jade +++ b/modules/control-center-web/src/main/js/views/includes/controls.jade @@ -288,12 +288,12 @@ mixin form-row-custom(lblClasses, fieldClasses, dataSource) +tipField('field.tip') .input-tip input.form-control(id='{{::field.id}}' type='text' ng-disabled=fieldDisabled placeholder='{{::field.placeholder}}' ng-focus='tableReset()')&attributes(fieldCommon) - div(ng-switch-when='withJavaBuildInTypes' ng-hide=fieldHide) + div(ng-switch-when='typeahead' ng-hide=fieldHide) label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}: div(class=fieldClasses) +tipField('field.tip') .input-tip - input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}' ng-focus='tableReset()' bs-typeahead container='body' retain-selection data-min-length='1' bs-options='javaClass for javaClass in javaBuildInClasses')&attributes(fieldCommon) + input.form-control(id='{{::field.id}}' type='text' placeholder='{{::field.placeholder}}' ng-focus='tableReset()' bs-typeahead container='body' retain-selection data-min-length='1' bs-options='item for item in {{::field.items}}')&attributes(fieldCommon) div(ng-switch-when='password' ng-hide=fieldHide) label(class=lblClasses ng-class=fieldRequiredClass) {{::field.label}}: div(class=fieldClasses)
