IGNITE-4871 Added Kubernetes IP finder to Cluster configuration screen.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/f978ff20 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/f978ff20 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/f978ff20 Branch: refs/heads/ignite-4986 Commit: f978ff20ae42f99561018d84ce252f1d86739572 Parents: 59c6178 Author: vsisko <[email protected]> Authored: Fri Apr 14 18:32:30 2017 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Fri Apr 14 18:32:30 2017 +0700 ---------------------------------------------------------------------- modules/web-console/backend/app/mongo.js | 8 +++- .../frontend/app/data/pom-dependencies.json | 1 + .../app/helpers/jade/form/form-field-text.pug | 40 ++++++++++++-------- .../frontend/app/helpers/jade/mixins.pug | 8 +++- .../generator/ConfigurationGenerator.js | 12 ++++++ .../generator/defaults/Cluster.service.js | 6 +++ .../states/configuration/clusters/general.pug | 3 ++ .../clusters/general/discovery/kubernetes.pug | 37 ++++++++++++++++++ .../configuration/summary/summary.controller.js | 3 ++ .../configuration/summary/summary.worker.js | 22 +++++++++++ .../frontend/controllers/clusters-controller.js | 3 +- 11 files changed, 124 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/backend/app/mongo.js ---------------------------------------------------------------------- diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js index 2d252b9..f4a62b1 100644 --- a/modules/web-console/backend/app/mongo.js +++ b/modules/web-console/backend/app/mongo.js @@ -407,7 +407,7 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose authenticator: String, forceServerMode: Boolean, clientReconnectDisabled: Boolean, - kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs', 'ZooKeeper']}, + kind: {type: String, enum: ['Vm', 'Multicast', 'S3', 'Cloud', 'GoogleStorage', 'Jdbc', 'SharedFs', 'ZooKeeper', 'Kubernetes']}, Vm: { addresses: [String] }, @@ -528,6 +528,12 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose basePath: String, serviceName: String, allowDuplicateRegistrations: Boolean + }, + Kubernetes: { + serviceName: String, + namespace: String, + masterUrl: String, + accountToken: String } }, atomicConfiguration: { http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/data/pom-dependencies.json ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/data/pom-dependencies.json b/modules/web-console/frontend/app/data/pom-dependencies.json index 7d2bed0..3e0543b 100644 --- a/modules/web-console/frontend/app/data/pom-dependencies.json +++ b/modules/web-console/frontend/app/data/pom-dependencies.json @@ -3,6 +3,7 @@ "S3": {"artifactId": "ignite-aws"}, "GoogleStorage": {"artifactId": "ignite-gce"}, "ZooKeeper": {"artifactId": "ignite-zookeeper"}, + "Kubernetes": {"artifactId": "ignite-kubernetes"}, "Log4j": {"artifactId": "ignite-log4j"}, "Log4j2": {"artifactId": "ignite-log4j2"}, http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/helpers/jade/form/form-field-text.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/helpers/jade/form/form-field-text.pug b/modules/web-console/frontend/app/helpers/jade/form/form-field-text.pug index bac455f..8444eb4 100644 --- a/modules/web-console/frontend/app/helpers/jade/form/form-field-text.pug +++ b/modules/web-console/frontend/app/helpers/jade/form/form-field-text.pug @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. -mixin ignite-form-field-input(name, model, disabled, required, placeholder) +mixin ignite-field-input(type, name, model, disabled, required, placeholder) input.form-control( id=`{{ ${name} }}Input` name=`{{ ${name} }}` placeholder=placeholder - type='text' + type=type data-ng-model=model @@ -30,21 +30,11 @@ mixin ignite-form-field-input(name, model, disabled, required, placeholder) data-ignite-form-panel-field='' )&attributes(attributes ? attributes.attributes ? attributes.attributes : attributes: {}) -mixin ignite-form-field-url-input(name, model, disabled, required, placeholder) - input.form-control( - id=`{{ ${name} }}Input` - name=`{{ ${name} }}` - placeholder=placeholder - type='url' - - data-ng-model=model - - data-ng-required=required && `${required}` - data-ng-disabled=disabled && `${disabled}` - data-ng-focus='tableReset()' +mixin ignite-form-field-input(name, model, disabled, required, placeholder) + +ignite-field-input('text', name, model, disabled, required, placeholder) - data-ignite-form-panel-field='' - )&attributes(attributes ? attributes.attributes ? attributes.attributes : attributes: {}) +mixin ignite-form-field-url-input(name, model, disabled, required, placeholder) + +ignite-field-input('url', name, model, disabled, required, placeholder) mixin ignite-form-field-text(label, model, name, disabled, required, placeholder, tip) -var errLbl = label.substring(0, label.length - 1) @@ -61,3 +51,21 @@ mixin ignite-form-field-text(label, model, name, disabled, required, placeholder .input-tip +ignite-form-field-input(name, model, disabled, required, placeholder)(attributes=attributes) + +mixin ignite-form-field-url(label, model, name, required, placeholder, tip) + -var errLbl = label.substring(0, label.length - 1) + + .ignite-form-field + +ignite-form-field__label(label, name, required) + .ignite-form-field__control + if tip + i.tipField.icon-help(bs-tooltip='' data-title=tip) + + if block + block + + +form-field-feedback(name, 'required', errLbl + ' could not be empty!') + +form-field-feedback(name, 'url', errLbl + ' should be a valid URL!') + + .input-tip + +ignite-form-field-url-input(name, model, false, required, placeholder)(attributes=attributes) http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/helpers/jade/mixins.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/helpers/jade/mixins.pug b/modules/web-console/frontend/app/helpers/jade/mixins.pug index 21468cc..e6990f6 100644 --- a/modules/web-console/frontend/app/helpers/jade/mixins.pug +++ b/modules/web-console/frontend/app/helpers/jade/mixins.pug @@ -203,6 +203,12 @@ mixin text(lbl, model, name, required, placeholder, tip) if block block +//- Mixin for text field. +mixin url(lbl, model, name, required, placeholder, tip) + +ignite-form-field-url(lbl, model, name, required, placeholder, tip) + if block + block + //- Mixin for password field. mixin password(lbl, model, name, required, placeholder, tip) +ignite-form-field-password(lbl, model, name, false, required, placeholder, tip) @@ -354,7 +360,7 @@ mixin table-java-package-field(name, model, items, valid, save, newItem) ignite-on-escape=onEscape ) -//- Mixin for table java package field. +//- Mixin for table url field. mixin table-url-field(name, model, items, valid, save, newItem) -var resetOnEnter = newItem ? '(stopblur = true) && (group.add = [{}])' : '(field.edit = false)' -var onEnter = `${valid} && (${save}); ${valid} && ${resetOnEnter};` http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js index dfb0669..3751f5c 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js @@ -320,6 +320,18 @@ export default class IgniteConfigurationGenerator { .boolProperty('allowDuplicateRegistrations'); break; + + case 'Kubernetes': + ipFinder = new Bean('org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes.TcpDiscoveryKubernetesIpFinder', + 'ipFinder', cluster.discovery.Kubernetes, clusterDflts.discovery.Kubernetes); + + ipFinder.stringProperty('serviceName') + .stringProperty('namespace') + .stringProperty('masterUrl') + .pathProperty('accountToken'); + + break; + default: // No-op. } http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/configuration/generator/defaults/Cluster.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/defaults/Cluster.service.js b/modules/web-console/frontend/app/modules/configuration/generator/defaults/Cluster.service.js index 6333ef9..b2e91c8 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/defaults/Cluster.service.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/defaults/Cluster.service.js @@ -75,6 +75,12 @@ const DFLT_CLUSTER = { Forever: { retryIntervalMs: 1000 } + }, + Kubernetes: { + serviceName: 'ignite', + namespace: 'default', + masterUrl: 'https://kubernetes.default.svc.cluster.local:443', + accountToken: '/var/run/secrets/kubernetes.io/serviceaccount/token' } }, atomics: { http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/states/configuration/clusters/general.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general.pug b/modules/web-console/frontend/app/modules/states/configuration/clusters/general.pug index dfc49d6..62cc23d 100644 --- a/modules/web-console/frontend/app/modules/states/configuration/clusters/general.pug +++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general.pug @@ -52,6 +52,7 @@ include /app/helpers/jade/mixins <li>JDBC - JDBC based IP finder that use database to store node IP address</li>\ <li>Shared filesystem - Shared filesystem based IP finder that use file to store node IP address</li>\ <li>Apache ZooKeeper - Apache ZooKeeper based IP finder when you use ZooKeeper to coordinate your distributed environment</li>\ + <li>Kubernetes - IP finder for automatic lookup of Ignite nodes running in Kubernetes environment</li>\ </ul>') .settings-row .panel-details @@ -71,6 +72,8 @@ include /app/helpers/jade/mixins include ./general/discovery/vm div(ng-if=`${modelDiscoveryKind} === 'ZooKeeper'`) include ./general/discovery/zookeeper + div(ng-if=`${modelDiscoveryKind} === 'Kubernetes'`) + include ./general/discovery/kubernetes .col-sm-6 -var model = 'backupItem' +preview-xml-java(model, 'clusterCaches', 'caches') http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/kubernetes.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/kubernetes.pug b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/kubernetes.pug new file mode 100644 index 0000000..c4e6398 --- /dev/null +++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/kubernetes.pug @@ -0,0 +1,37 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +include /app/helpers/jade/mixins + +-var discoveryKind = 'Kubernetes' +-var model = 'backupItem.discovery.Kubernetes' + +div + .details-row + +text('Service name:', `${model}.serviceName`, `'${discoveryKind}ServiceName'`, 'false', 'ignite', + "The name of Kubernetes service for Ignite pods' IP addresses lookup.<br/>\ + The name of the service must be equal to the name set in service's Kubernetes configuration.<br/>\ + If this parameter is not changed then the name of the service has to be set to 'ignite' in the corresponding Kubernetes configuration.") + .details-row + +text('Namespace:', `${model}.namespace`, `'${discoveryKind}Namespace'`, 'false', 'default', + "The namespace the Kubernetes service belongs to.<br/>\ + By default, it's supposed that the service is running under Kubernetes `default` namespace.") + .details-row + +url('Kubernetes server:', `${model}.masterUrl`, `'${discoveryKind}MasterUrl'`, 'false', 'https://kubernetes.default.svc.cluster.local:443', + 'The host name of the Kubernetes API server') + .details-row + +text('Service token file:', `${model}.accountToken`, `'${discoveryKind}AccountToken'`, 'false', '/var/run/secrets/kubernetes.io/serviceaccount/token', + 'The path to the service token file') http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js index 25203b3..0089528 100644 --- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js +++ b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.controller.js @@ -264,6 +264,9 @@ export default [ if (cluster.discovery.kind === 'Jdbc' && cluster.discovery.Jdbc.dialect) $scope.dialects[cluster.discovery.Jdbc.dialect] = true; + if (cluster.discovery.kind === 'Kubernetes') + resourcesFolder.children.push({ type: 'file', name: 'ignite-service.yaml' }); + _.forEach(cluster.caches, (cache) => { if (cache.cacheStoreFactory) { const store = cache.cacheStoreFactory[cache.cacheStoreFactory.kind]; http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js index 7ea1d5a..5933f6c 100644 --- a/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js +++ b/modules/web-console/frontend/app/modules/states/configuration/summary/summary.worker.js @@ -38,6 +38,25 @@ const generator = IgniteConfigurationGenerator; const escapeFileName = (name) => name.replace(/[\\\/*\"\[\],\.:;|=<>?]/g, '-').replace(/ /g, '_'); +const kubernetesConfig = (cluster) => { + if (!cluster.discovery.Kubernetes) + cluster.discovery.Kubernetes = { serviceName: 'ignite' }; + + return `apiVersion: v1\n\ +kind: Service\n\ +metadata:\n\ + # Name of Ignite Service used by Kubernetes IP finder for IP addresses lookup.\n\ + name: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }\n\ +spec:\n\ + clusterIP: None # custom value.\n\ + ports:\n\ + - port: 9042 # custom value.\n\ + selector:\n\ + # Must be equal to one of the labels set in Ignite pods'\n\ + # deployement configuration.\n\ + app: ${ cluster.discovery.Kubernetes.serviceName || 'ignite' }`; +}; + // eslint-disable-next-line no-undef onmessage = function(e) { const {cluster, data, demo} = e.data; @@ -67,6 +86,9 @@ onmessage = function(e) { const metaPath = `${resourcesPath}/META-INF`; + if (cluster.discovery.kind === 'Kubernetes') + zip.file(`${metaPath}/ignite-service.yaml`, kubernetesConfig(cluster)); + zip.file(`${metaPath}/${serverXml}`, spring.igniteConfiguration(cfg).asString()); zip.file(`${metaPath}/${clientXml}`, spring.igniteConfiguration(clientCfg, clientNearCaches).asString()); http://git-wip-us.apache.org/repos/asf/ignite/blob/f978ff20/modules/web-console/frontend/controllers/clusters-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/clusters-controller.js b/modules/web-console/frontend/controllers/clusters-controller.js index c8392cf..e936955 100644 --- a/modules/web-console/frontend/controllers/clusters-controller.js +++ b/modules/web-console/frontend/controllers/clusters-controller.js @@ -228,7 +228,8 @@ export default ['clustersController', [ {value: 'GoogleStorage', label: 'Google cloud storage'}, {value: 'Jdbc', label: 'JDBC'}, {value: 'SharedFs', label: 'Shared filesystem'}, - {value: 'ZooKeeper', label: 'Apache ZooKeeper'} + {value: 'ZooKeeper', label: 'Apache ZooKeeper'}, + {value: 'Kubernetes', label: 'Kubernetes'} ]; $scope.swapSpaceSpis = [
