You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2016/09/09 03:27:02 UTC

[34/52] ignite git commit: Web Console beta-3.

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/connector.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/connector.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/connector.jade
new file mode 100644
index 0000000..baec54f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/connector.jade
@@ -0,0 +1,103 @@
+//-
+    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.jade
+
+-var form = 'connector'
+-var model = 'backupItem.connector'
+-var enabled = model + '.enabled'
+-var sslEnabled = enabled + ' && ' + model + '.sslEnabled'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Connector configuration
+        ignite-form-field-tooltip.tipLabel
+            | Configure HTTP REST configuration to enable HTTP server features
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +checkbox('Enabled', enabled, '"restEnabled"', 'Flag indicating whether to configure connector configuration')
+                .settings-row
+                    +text-enabled('Jetty configuration path:', model + '.jettyPath', '"connectorJettyPath"', enabled, 'false', 'Input path to Jetty configuration',
+                        'Path, either absolute or relative to IGNITE_HOME, to Jetty XML configuration file<br/>\
+                        Jetty is used to support REST over HTTP protocol for accessing Ignite APIs remotely<br/>\
+                        If not provided, Jetty instance with default configuration will be started picking IgniteSystemProperties.IGNITE_JETTY_HOST and IgniteSystemProperties.IGNITE_JETTY_PORT as host and port respectively')
+                .settings-row
+                    +text-ip-address('TCP host:', model + '.host', '"connectorHost"', enabled, 'IgniteConfiguration#getLocalHost()',
+                        'Host for TCP binary protocol server<br/>\
+                        This can be either an IP address or a domain name<br/>\
+                        If not defined, system - wide local address will be used IgniteConfiguration#getLocalHost()<br/>\
+                        You can also use "0.0.0.0" value to bind to all locally - available IP addresses')
+                .settings-row
+                    +number-min-max('TCP port:', model + '.port', '"connectorPort"', enabled, '11211', '1024', '65535', 'Port for TCP binary protocol server')
+                .settings-row
+                    +number('TCP port range:', model + '.portRange', '"connectorPortRange"', enabled, '100', '1', 'Number of ports for TCP binary protocol server to try if configured port is already in use')
+                .settings-row
+                    +number('Idle query cursor timeout:', model + '.idleQueryCursorTimeout', '"connectorIdleQueryCursorTimeout"', enabled, '600000', '0',
+                        'Reject open query cursors that is not used timeout<br/>\
+                        If no fetch query request come within idle timeout, it will be removed on next check for old query cursors')
+                .settings-row
+                    +number('Idle query cursor check frequency:', model + '.idleQueryCursorCheckFrequency', '"connectorIdleQueryCursorCheckFrequency"', enabled, '60000', '0',
+                        'Idle query cursors check frequency<br/>\
+                        This setting is used to reject open query cursors that is not used')
+                .settings-row
+                    +number('Idle timeout:', model + '.idleTimeout', '"connectorIdleTimeout"', enabled, '7000', '0',
+                        'Idle timeout for REST server<br/>\
+                        This setting is used to reject half - opened sockets<br/>\
+                        If no packets come within idle timeout, the connection is closed')
+                .settings-row
+                    +number('Receive buffer size:', model + '.receiveBufferSize', '"connectorReceiveBufferSize"', enabled, '32768', '0', 'REST TCP server receive buffer size')
+                .settings-row
+                    +number('Send buffer size:', model + '.sendBufferSize', '"connectorSendBufferSize"', enabled, '32768', '0', 'REST TCP server send buffer size')
+                .settings-row
+                    +number('Send queue limit:', model + '.sendQueueLimit', '"connectorSendQueueLimit"', enabled, 'unlimited', '0',
+                        'REST TCP server send queue limit<br/>\
+                        If the limit exceeds, all successive writes will block until the queue has enough capacity')
+                .settings-row
+                    +checkbox-enabled('Direct buffer', model + '.directBuffer', '"connectorDirectBuffer"', enabled,
+                        'Flag indicating whether REST TCP server should use direct buffers<br/>\
+                        A direct buffer is a buffer that is allocated and accessed using native system calls, without using JVM heap<br/>\
+                        Enabling direct buffer may improve performance and avoid memory issues(long GC pauses due to huge buffer size)')
+                .settings-row
+                    +checkbox-enabled('TCP_NODELAY option', model + '.noDelay', '"connectorNoDelay"', enabled,
+                        'Flag indicating whether TCP_NODELAY option should be set for accepted client connections<br/>\
+                        Setting this option reduces network latency and should be enabled in majority of cases<br/>\
+                        For more information, see Socket#setTcpNoDelay(boolean)')
+                .settings-row
+                    +number('Selector count:', model + '.selectorCount', '"connectorSelectorCount"', enabled, 'min(4, availableProcessors)', '1',
+                        'Number of selector threads in REST TCP server<br/>\
+                        Higher value for this parameter may increase throughput, but also increases context switching')
+                .settings-row
+                    +number('Thread pool size:', model + '.threadPoolSize', '"connectorThreadPoolSize"', enabled, 'max(8, availableProcessors) * 2', '1',
+                        'Thread pool size to use for processing of client messages (REST requests)')
+                .settings-row
+                    +java-class('Message interceptor:', model + '.messageInterceptor', '"connectorMessageInterceptor"', enabled, 'false',
+                        'Interceptor allows to transform all objects exchanged via REST protocol<br/>\
+                        For example if you use custom serialisation on client you can write interceptor to transform binary representations received from client to Java objects and later access them from java code directly')
+                .settings-row
+                    +text-enabled('Secret key:', model + '.secretKey', '"connectorSecretKey"', enabled, 'false', 'Specify to enable authentication', 'Secret key to authenticate REST requests')
+                .settings-row
+                    +checkbox-enabled('Enable SSL', model + '.sslEnabled', '"connectorSslEnabled"', enabled, 'Enables/disables SSL for REST TCP binary protocol')
+                .settings-row
+                    +checkbox-enabled('Enable SSL client auth', model + '.sslClientAuth', '"connectorSslClientAuth"', sslEnabled, 'Flag indicating whether or not SSL client authentication is required')
+                .settings-row
+                    +java-class('SSL factory:', model + '.sslFactory', '"connectorSslFactory"', sslEnabled, sslEnabled,
+                        'Instance of Factory that will be used to create an instance of SSLContext for Secure Socket Layer on TCP binary protocol')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterConnector')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/deployment.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/deployment.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/deployment.jade
new file mode 100644
index 0000000..6cfa82d
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/deployment.jade
@@ -0,0 +1,113 @@
+//-
+    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.jade
+
+-var form = 'deployment'
+-var model = 'backupItem'
+-var exclude = model + '.peerClassLoadingLocalClassPathExclude'
+-var enabled = 'backupItem.peerClassLoadingEnabled'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Class deployment
+        ignite-form-field-tooltip.tipLabel
+            | Task and resources deployment in cluster
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id='deployment')
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +dropdown('Deployment mode:', model + '.deploymentMode', '"deploymentMode"', 'true', 'SHARED',
+                        '[\
+                            {value: "PRIVATE", label: "PRIVATE"},\
+                            {value: "ISOLATED", label: "ISOLATED"}, \
+                            {value: "SHARED", label: "SHARED"},\
+                            {value: "CONTINUOUS", label: "CONTINUOUS"}\
+                        ]',
+                        'Task classes and resources sharing mode<br/>\
+                        The following deployment modes are supported:\
+                        <ul>\
+                            <li>PRIVATE - in this mode deployed classes do not share resources</li>\
+                            <li>ISOLATED - in this mode tasks or classes deployed within the same class loader will share the same instances of resources</li>\
+                            <li>SHARED - same as ISOLATED, but now tasks from different master nodes with the same user version and same class loader will share the same class loader on remote nodes</li>\
+                            <li>CONTINUOUS - same as SHARED deployment mode, but resources will not be undeployed even after all master nodes left grid</li>\
+                        </ul>')
+                .settings-row
+                    +checkbox('Enable peer class loading', model + '.peerClassLoadingEnabled', '"peerClassLoadingEnabled"', 'Enables/disables peer class loading')
+                .settings-row
+                    +number('Missed resources cache size:', model + '.peerClassLoadingMissedResourcesCacheSize', '"peerClassLoadingMissedResourcesCacheSize"', enabled, '100', '0',
+                        'If size greater than 0, missed resources will be cached and next resource request ignored<br/>\
+                        If size is 0, then request for the resource will be sent to the remote node every time this resource is requested')
+                .settings-row
+                    +number('Pool size:', model + '.peerClassLoadingThreadPoolSize', '"peerClassLoadingThreadPoolSize"', enabled, '2', '1', 'Thread pool size to use for peer class loading')
+                .settings-row
+                    +ignite-form-group(ng-model=exclude ng-form=form)
+                        -var uniqueTip = 'Such package already exists'
+
+                        ignite-form-field-label
+                            | Local class path exclude
+                        ignite-form-group-tooltip
+                            | List of packages from the system classpath that need to be peer-to-peer loaded from task originating node<br/>
+                            | '*' is supported at the end of the package name which means that all sub-packages and their classes are included like in Java package import clause
+                        ignite-form-group-add(ng-show='#{enabled}' ng-click='(group.add = [{}])')
+                            | Add package name.
+
+                        .group-content(ng-if=exclude + '.length')
+                            -var model = 'obj.model';
+                            -var name = '"edit" + $index'
+                            -var valid = form + '[' + name + '].$valid'
+                            -var save = exclude + '[$index] = ' + model
+
+                            div(ng-show=enabled)
+                                div(ng-repeat='model in #{exclude} track by $index' ng-init='obj = {}')
+                                    label.col-xs-12.col-sm-12.col-md-12
+                                        .indexField
+                                            | {{ $index+1 }})
+                                        +table-remove-button(exclude, 'Remove package name')
+                                        span(ng-hide='field.edit')
+                                            a.labelFormField(ng-click='#{enabled} && (field.edit = true) && (#{model} = model)') {{ model }}
+                                        span(ng-if='field.edit')
+                                            +table-java-package-field(name, model, exclude, valid, save, false)
+                                                +table-save-button(valid, save, false)
+                                                +unique-feedback(name, uniqueTip)
+
+                            div(ng-hide=enabled)
+                                div(ng-repeat='model in #{exclude} track by $index')
+                                    label.col-xs-12.col-sm-12.col-md-12
+                                        .labelFormField.labelField
+                                            | {{ $index+1 }})
+                                        span.labelFormField
+                                            | {{ model }}
+
+                        .group-content(ng-repeat='field in group.add')
+                            -var model = 'new';
+                            -var name = '"new"'
+                            -var valid = form + '[' + name + '].$valid'
+                            -var save = exclude + '.push(' + model + ')'
+
+                            div(type='internal' name='Package name')
+                                label.col-xs-12.col-sm-12.col-md-12
+                                    +table-java-package-field(name, model, exclude, valid, save, true)
+                                        +table-save-button(valid, save, true)
+                                        +unique-feedback(name, uniqueTip)
+
+
+                        .group-content-empty(ng-if='!(#{exclude}.length) && !group.add.length')
+                            | Not defined
+            .col-sm-6
+                +preview-xml-java(model, 'clusterDeployment')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/discovery.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/discovery.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/discovery.jade
new file mode 100644
index 0000000..1fdcbec
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/discovery.jade
@@ -0,0 +1,87 @@
+//-
+    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.jade
+
+-var form = 'discovery'
+-var model = 'backupItem.discovery'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Discovery
+        ignite-form-field-tooltip.tipLabel
+            | TCP/IP discovery configuration
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +text-ip-address('Local address:', model + '.localAddress', '"discoLocalAddress"', 'true', '228.1.2.4',
+                        'Local host IP address that discovery SPI uses<br/>\
+                        If not provided a first found non-loopback address will be used')
+                .settings-row
+                    +number-min-max('Local port:', model + '.localPort', '"discoLocalPort"', 'true', '47500', '1024', '65535', 'Local port which node uses')
+                .settings-row
+                    +number('Local port range:', model + '.localPortRange', '"discoLocalPortRange"', 'true', '100', '1', 'Local port range')
+                .settings-row
+                    +java-class('Address resolver:', model + '.addressResolver', '"discoAddressResolver"', 'true', 'false',
+                        'Provides resolution between external and internal addresses')
+                .settings-row
+                    +number('Socket timeout:', model + '.socketTimeout', '"socketTimeout"', 'true', '5000', '0', 'Socket operations timeout')
+                .settings-row
+                    +number('Acknowledgement timeout:', model + '.ackTimeout', '"ackTimeout"', 'true', '5000', '0', 'Message acknowledgement timeout')
+                .settings-row
+                    +number('Max acknowledgement timeout:', model + '.maxAckTimeout', '"maxAckTimeout"', 'true', '600000', '0', 'Maximum message acknowledgement timeout')
+                .settings-row
+                    +number('Network timeout:', model + '.networkTimeout', '"discoNetworkTimeout"', 'true', '5000', '1', 'Timeout to use for network operations')
+                .settings-row
+                    +number('Join timeout:', model + '.joinTimeout', '"joinTimeout"', 'true', '0', '0',
+                        'Join timeout<br/>' +
+                        '0 means wait forever')
+                .settings-row
+                    +number('Thread priority:', model + '.threadPriority', '"threadPriority"', 'true', '10', '1', 'Thread priority for all threads started by SPI')
+                .settings-row
+                    +number('Heartbeat frequency:', model + '.heartbeatFrequency', '"heartbeatFrequency"', 'true', '2000', '1', 'Heartbeat messages issuing frequency')
+                .settings-row
+                    +number('Max heartbeats miss w/o init:', model + '.maxMissedHeartbeats', '"maxMissedHeartbeats"', 'true', '1', '1',
+                        'Max heartbeats count node can miss without initiating status check')
+                .settings-row
+                    +number('Max missed client heartbeats:', model + '.maxMissedClientHeartbeats', '"maxMissedClientHeartbeats"', 'true', '5', '1',
+                        'Max heartbeats count node can miss without failing client node')
+                .settings-row
+                    +number('Topology history:', model + '.topHistorySize', '"topHistorySize"', 'true', '1000', '0', 'Size of topology snapshots history')
+                .settings-row
+                    +java-class('Discovery listener:', model + '.listener', '"discoListener"', 'true', 'false', 'Listener for grid node discovery events')
+                .settings-row
+                    +java-class('Data exchange:', model + '.dataExchange', '"dataExchange"', 'true', 'false', 'Class name of handler for initial data exchange between Ignite nodes')
+                .settings-row
+                    +java-class('Metrics provider:', model + '.metricsProvider', '"metricsProvider"', 'true', 'false', 'Class name of metric provider to discovery SPI')
+                .settings-row
+                    +number('Reconnect count:', model + '.reconnectCount', '"discoReconnectCount"', 'true', '10', '1', 'Reconnect attempts count')
+                .settings-row
+                    +number('Statistics frequency:', model + '.statisticsPrintFrequency', '"statisticsPrintFrequency"', 'true', '0', '1', 'Statistics print frequency')
+                .settings-row
+                    +number('IP finder clean frequency:', model + '.ipFinderCleanFrequency', '"ipFinderCleanFrequency"', 'true', '60000', '1', 'IP finder clean frequency')
+                .settings-row
+                    +java-class('Node authenticator:', model + '.authenticator', '"authenticator"', 'true', 'false', 'Class name of node authenticator implementation')
+                .settings-row
+                    +checkbox('Force server mode', model + '.forceServerMode', '"forceServerMode"', 'Force start TCP/IP discovery in server mode')
+                .settings-row
+                    +checkbox('Client reconnect disabled', model + '.clientReconnectDisabled', '"clientReconnectDisabled"',
+                        'Disable try of client to reconnect after server detected client node failure')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterDiscovery')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/events.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/events.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/events.jade
new file mode 100644
index 0000000..412714c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/events.jade
@@ -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.jade
+
+-var form = 'events'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Events
+        ignite-form-field-tooltip.tipLabel
+            | Grid events are used for notification about what happens within the grid
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +dropdown-multiple('Include type:', model + '.includeEventTypes', '"includeEventTypes"', true, 'Choose recorded event types', '', 'eventGroups',
+                        'Array of event types, which will be recorded by GridEventStorageManager#record(Event)<br/>\
+                        Note, that either the include event types or the exclude event types can be established')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterEvents')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/failover.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/failover.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/failover.jade
new file mode 100644
index 0000000..85f0f54
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/failover.jade
@@ -0,0 +1,72 @@
+//-
+    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.jade
+
+-var model = 'backupItem'
+-var form = 'failoverSpi'
+-var failoverSpi = model + '.failoverSpi'
+-var failoverCustom = 'failover.kind === "Custom"'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label Failover configuration
+        ignite-form-field-tooltip.tipLabel
+            | Failover SPI provides ability to supply custom logic for handling failed execution of a grid job
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row(ng-init='failoverSpiTbl={type: "failoverSpi", model: "failoverSpi", focusId: "kind", ui: "failover-table"}')
+                    +ignite-form-group()
+                        ignite-form-field-label
+                            | Failover SPI configurations
+                        ignite-form-group-tooltip
+                            | Failover SPI configurations
+                        ignite-form-group-add(ng-click='tableNewItem(failoverSpiTbl)')
+                            | Add failover SPI
+                        .group-content-empty(ng-if='!(#{failoverSpi} && #{failoverSpi}.length > 0)')
+                            | Not defined
+                        .group-content(ng-show='#{failoverSpi} && #{failoverSpi}.length > 0' ng-repeat='failover in #{failoverSpi} track by $index')
+                            hr(ng-if='$index != 0')
+                            .settings-row
+                                +dropdown('Failover SPI:', 'failover.kind', '"failoverKind" + $index', 'true', 'Choose Failover SPI', '[\
+                                        {value: "JobStealing", label: "Job stealing"},\
+                                        {value: "Never", label: "Never"},\
+                                        {value: "Always", label: "Always"},\
+                                        {value: "Custom", label: "Custom"}\
+                                    ]', 'Provides ability to supply custom logic for handling failed execution of a grid job\
+                                    <ul>\
+                                        <li>Job stealing - Supports job stealing from over-utilized nodes to under-utilized nodes</li>\
+                                        <li>Never - Jobs are ordered as they arrived</li>\
+                                        <li>Always - Jobs are first ordered by their priority</li>\
+                                        <li>Custom - Jobs are activated immediately on arrival to mapped node</li>\
+                                        <li>Default - Default FailoverSpi implementation</li>\
+                                    </ul>')
+
+                                    +table-remove-button(failoverSpi, 'Remove Failover SPI')
+                            .settings-row(ng-show='failover.kind === "JobStealing"')
+                                +number('Maximum failover attempts:', 'failover.JobStealing.maximumFailoverAttempts', '"jsMaximumFailoverAttempts" + $index', 'true', '5', '0',
+                                    'Maximum number of attempts to execute a failed job on another node')
+                            .settings-row(ng-show='failover.kind === "Always"')
+                                +number('Maximum failover attempts:', 'failover.Always.maximumFailoverAttempts', '"alwaysMaximumFailoverAttempts" + $index', 'true', '5', '0',
+                                    'Maximum number of attempts to execute a failed job on another node')
+                            .settings-row(ng-show=failoverCustom)
+                                +java-class('SPI implementation', 'failover.Custom.class', '"failoverSpiClass" + $index', 'true', failoverCustom,
+                                    'Custom FailoverSpi implementation class name.')
+            .col-sm-6
+                +preview-xml-java(model, 'clusterFailover')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general.jade
new file mode 100644
index 0000000..d0d390f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general.jade
@@ -0,0 +1,73 @@
+//-
+    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.jade
+
+-var form = 'general'
+-var model = 'backupItem'
+-var modelDiscoveryKind = model + '.discovery.kind'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle)
+        ignite-form-panel-chevron
+        label General
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body
+            .col-sm-6
+                .settings-row
+                    +text('Name:', model + '.name', '"clusterName"', 'true', 'Input name', 'Grid name allows to indicate to what grid this particular grid instance belongs to')
+                .settings-row
+                    +caches(model, 'Select caches to start in cluster or add a new cache')
+                .settings-row
+                    +text-ip-address('Local host:', model + '.localHost', '"localHost"', 'true', '0.0.0.0',
+                        'System-wide local address or host for all Ignite components to bind to<br/>\
+                        If not defined then Ignite tries to use local wildcard address<br/>\
+                        That means that all services will be available on all network interfaces of the host machine')
+                .settings-row
+                    +dropdown('Discovery:', model + '.discovery.kind', '"discovery"', 'true', 'Choose discovery', 'discoveries',
+                        'Discovery allows to discover remote nodes in grid\
+                        <ul>\
+                            <li>Static IPs - IP Finder which works only with pre configured list of IP addresses specified</li>\
+                            <li>Multicast - Multicast based IP finder</li>\
+                            <li>AWS S3 - AWS S3 based IP finder that automatically discover cluster nodes on Amazon EC2 cloud</li>\
+                            <li>Apache jclouds - Apache jclouds multi cloud toolkit based IP finder for cloud platforms with unstable IP addresses</li>\
+                            <li>Google cloud storage - Google Cloud Storage based IP finder that automatically discover cluster nodes on Google Compute Engine cluster</li>\
+                            <li>JDBC - JDBC based IP finder that use database to store node IP addres</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>\
+                        </ul>')
+                .settings-row
+                    .panel-details
+                        div(ng-if='#{modelDiscoveryKind} === "Cloud"')
+                            include ./general/discovery/cloud.jade
+                        div(ng-if='#{modelDiscoveryKind} === "GoogleStorage"')
+                            include ./general/discovery/google.jade
+                        div(ng-if='#{modelDiscoveryKind} === "Jdbc"')
+                            include ./general/discovery/jdbc.jade
+                        div(ng-if='#{modelDiscoveryKind} === "Multicast"')
+                            include ./general/discovery/multicast.jade
+                        div(ng-if='#{modelDiscoveryKind} === "S3"')
+                            include ./general/discovery/s3.jade
+                        div(ng-if='#{modelDiscoveryKind} === "SharedFs"')
+                            include ./general/discovery/shared.jade
+                        div(ng-if='#{modelDiscoveryKind} === "Vm"')
+                            include ./general/discovery/vm.jade
+                        div(ng-if='#{modelDiscoveryKind} === "ZooKeeper"')
+                            include ./general/discovery/zookeeper.jade
+            .col-sm-6
+                -var model = 'backupItem'
+                +preview-xml-java(model, 'clusterCaches', 'caches')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/cloud.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/cloud.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/cloud.jade
new file mode 100644
index 0000000..640c78c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/cloud.jade
@@ -0,0 +1,134 @@
+//-
+    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.jade
+
+-var discoveryKind = 'Cloud'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
+-var model = 'backupItem.discovery.Cloud'
+-var regions = model + '.regions'
+-var zones = model + '.zones'
+-var formRegions = 'discoveryCloudRegions'
+-var formZones = 'discoveryCloudZones'
+
+div
+    .details-row
+        +text('Credential:', model + '.credential', '"credential"', 'false', 'Input cloud credential',
+            'Credential that is used during authentication on the cloud<br/>\
+            Depending on a cloud platform it can be a password or access key')
+    .details-row
+        +text('Path to credential:', model + '.credentialPath', '"credentialPath"', 'false', 'Input pathto credential',
+            'Path to a credential that is used during authentication on the cloud<br/>\
+            Access key or private key should be stored in a plain or PEM file without a passphrase')
+    .details-row
+        +text('Identity:', model + '.identity', '"' + discoveryKind + 'Identity"', required, 'Input identity',
+            'Identity that is used as a user name during a connection to the cloud<br/>\
+            Depending on a cloud platform it can be an email address, user name, etc')
+    .details-row
+        +text('Provider:', model + '.provider', '"' + discoveryKind + 'Provider"', required, 'Input provider', 'Cloud provider to use')
+    .details-row
+        -var form = formRegions;
+        +ignite-form-group(ng-model=regions ng-form=form)
+            -var uniqueTip = 'Such region already exists!'
+
+            ignite-form-field-label
+                | Regions
+            ignite-form-group-tooltip
+                | List of regions where VMs are located#[br]
+                | If the regions are not set then every region, that a cloud provider has, will be investigated. This could lead to significant performance degradation#[br]
+                | Note, that some cloud providers, like Google Compute Engine, doesn't have a notion of a region. For such providers regions are redundant
+            ignite-form-group-add(ng-click='group.add = [{}]')
+                | Add new region
+
+            .group-content(ng-if='#{regions}.length')
+                -var model = 'field.model';
+                -var name = '"edit" + $index'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = regions + '[$index] = ' + model
+
+                div(ng-repeat='model in #{regions} track by $index')
+                    label.col-xs-12.col-sm-12.col-md-12(ng-init='field = {}')
+                        .indexField
+                            | {{ $index+1 }})
+                        +table-remove-button(regions, 'Remove region')
+                        span(ng-hide='field.edit')
+                            a.labelFormField(ng-click='field.edit = true; #{model} = model;') {{ model }}
+                        span(ng-if='field.edit')
+                            +table-text-field(name, model, regions, valid, save, 'Region name', false)
+                                +table-save-button(valid, save, false)
+                                +unique-feedback(name, uniqueTip)
+
+            .group-content(ng-repeat='field in group.add')
+                -var model = 'field.new';
+                -var name = '"new"'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = regions + '.push(' + model + ')'
+
+                div
+                    label.col-xs-12.col-sm-12.col-md-12
+                        +table-text-field(name, model, regions, valid, save, 'Region name', true)
+                            +table-save-button(valid, save, false)
+                            +unique-feedback(name, uniqueTip)
+
+            .group-content-empty(ng-if='!(#{regions}.length) && !group.add.length')
+                | Not defined
+    .details-row
+        -var form = formZones;
+        +ignite-form-group(ng-model=zones ng-form=form)
+            -var uniqueTip = 'Such zone already exists!'
+
+            ignite-form-field-label
+                | Zones
+            ignite-form-group-tooltip
+                | List of zones where VMs are located#[br]
+                | If the zones are not set then every zone from specified regions, will be taken into account#[br]
+                | Note, that some cloud providers, like Rackspace, doesn't have a notion of a zone. For such providers zones are redundant
+            ignite-form-group-add(ng-click='group.add = [{}]')
+                | Add new zone
+
+            -var form = formZones;
+            .group-content(ng-if='#{zones}.length')
+                -var model = 'field.model';
+                -var name = '"edit" + $index'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = zones + '[$index] = ' + model
+
+                div(ng-repeat='model in #{zones} track by $index')
+                    label.col-xs-12.col-sm-12.col-md-12(ng-init='field = {}')
+                        .indexField
+                            | {{ $index+1 }})
+                        +table-remove-button(zones, 'Remove zone')
+                        span(ng-hide='field.edit')
+                            a.labelFormField(ng-click='field.edit = true; #{model} = model;') {{ model }}
+                        span(ng-if='field.edit')
+                            +table-text-field(name, model, zones, valid, save, 'Zone name', false)
+                                +table-save-button(valid, save, false)
+                                +unique-feedback(name, uniqueTip)
+
+            .group-content(ng-repeat='field in group.add')
+                -var model = 'field.new';
+                -var name = '"new"'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = zones + '.push(' + model + ')'
+
+                div
+                    label.col-xs-12.col-sm-12.col-md-12
+                        +table-text-field(name, model, zones, valid, save, 'Zone name', true)
+                            +table-save-button(valid, save, true)
+                            +unique-feedback(name, uniqueTip)
+
+            .group-content-empty(ng-if='!(#{zones}.length) && !group.add.length')
+                | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/google.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/google.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/google.jade
new file mode 100644
index 0000000..b1a5958
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/google.jade
@@ -0,0 +1,38 @@
+//-
+    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.jade
+
+
+-var discoveryKind = 'GoogleStorage'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
+-var model = 'backupItem.discovery.GoogleStorage'
+
+div
+    .details-row
+        +text('Project name:', model + '.projectName', '"' + discoveryKind + 'ProjectName"', required, 'Input project name', '' +
+            'Google Cloud Platforms project name<br/>\
+            Usually this is an auto generated project number(ex. 208709979073) that can be found in "Overview" section of Google Developer Console')
+    .details-row
+        +text('Bucket name:', model + '.bucketName', '"' + discoveryKind + 'BucketName"', required, 'Input bucket name',
+            'Google Cloud Storage bucket name<br/>\
+            If the bucket does not exist Ignite will automatically create it<br/>\
+            However the name must be unique across whole Google Cloud Storage and Service Account Id must be authorized to perform this operation')
+    .details-row
+        +text('Private key path:', model + '.serviceAccountP12FilePath', '"' + discoveryKind + 'ServiceAccountP12FilePath"', required, 'Input private key path',
+            'Full path to the private key in PKCS12 format of the Service Account')
+    .details-row
+        +text('Account id:', model + '.serviceAccountId', '"' + discoveryKind + 'ServiceAccountId"', required, 'Input account id', 'Service account ID (typically an e-mail address)')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/jdbc.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
new file mode 100644
index 0000000..42cf697
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/jdbc.jade
@@ -0,0 +1,32 @@
+//-
+    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.jade
+include ../../../../../../../app/helpers/jade/mixins.jade
+
+-var model = 'backupItem.discovery.Jdbc'
+-var required = 'backupItem.discovery.kind === "Jdbc"'
+
+div
+    .details-row
+        +checkbox('DB schema should be initialized by Ignite', model + '.initSchema', '"initSchema"',
+            'Flag indicating whether DB schema should be initialized by Ignite or was explicitly created by user')
+    .details-row
+        +text('Data source bean name:', model + '.dataSourceBean',
+            '"dataSourceBean"', required, 'Input bean name', 'Name of the data source bean in Spring context')
+    .details-row
+        +dialect('Dialect:', model + '.dialect', '"dialect"', required,
+            'Dialect of SQL implemented by a particular RDBMS:', 'Generic JDBC dialect', 'Choose JDBC dialect')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/multicast.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/multicast.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/multicast.jade
new file mode 100644
index 0000000..829fbaa
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/multicast.jade
@@ -0,0 +1,99 @@
+//-
+    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.jade
+
+-var form = 'general'
+-var model = 'backupItem.discovery.Multicast'
+-var addresses = model + '.addresses'
+
+div
+    .details-row
+        +text-ip-address('IP address:', model + '.multicastGroup', '"multicastGroup"', 'true', '228.1.2.4', 'IP address of multicast group')
+    .details-row
+        +number-min-max('Port number:', model + '.multicastPort', '"multicastPort"', 'true', '47400', '0', '65535', 'Port number which multicast messages are sent to')
+    .details-row
+        +number('Waits for reply:', model + '.responseWaitTime', '"responseWaitTime"', 'true', '500', '0',
+            'Time in milliseconds IP finder waits for reply to multicast address request')
+    .details-row
+        +number('Attempts count:', model + '.addressRequestAttempts', '"addressRequestAttempts"', 'true', '2', '0',
+            'Number of attempts to send multicast address request<br/>\
+            IP finder re - sends request only in case if no reply for previous request is received')
+    .details-row
+        +text-ip-address('Local address:', model + '.localAddress', '"localAddress"', 'true', '0.0.0.0',
+            'Local host address used by this IP finder<br/>\
+            If provided address is non - loopback then multicast socket is bound to this interface<br/>\
+            If local address is not set or is any local address then IP finder creates multicast sockets for all found non - loopback addresses')
+    .details-row
+        -var form = 'discoveryMulticastAddresses';
+
+        +ignite-form-group(ng-model=addresses ng-form=form)
+            -var uniqueTip = 'Such IP address already exists!'
+            -var ipAddressTip = 'Invalid IP address!'
+
+            ignite-form-field-label
+                | Addresses
+            ignite-form-group-tooltip
+                | Addresses may be represented as follows:#[br]
+                ul: li IP address (e.g. 127.0.0.1, 9.9.9.9, etc)
+                    li IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc)
+                    li IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc)
+                    li Hostname (e.g. host1.com, host2, etc)
+                    li Hostname and port (e.g. host1.com:47500, host2:47502, etc)
+                    li Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc)
+                | If port is 0 or not provided then default port will be used (depends on discovery SPI configuration)#[br]
+                | If port range is provided (e.g. host:port1..port2) the following should be considered:#[br]
+                ul: li port1 &lt; port2 should be true
+                    li Both port1 and port2 should be greater than 0
+            ignite-form-group-add(ng-click='group.add = [{}]')
+                | Add new address
+
+            .group-content(ng-if='#{addresses}.length')
+                -var model = 'obj.model';
+                -var name = '"edit" + $index'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = addresses + '[$index] = ' + model
+
+                div(ng-repeat='model in #{addresses} track by $index' ng-init='obj = {}')
+                    label.col-xs-12.col-sm-12.col-md-12
+                        .indexField
+                            | {{ $index+1 }})
+                        +table-remove-button(addresses, 'Remove address')
+
+                        +ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+                        +ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+
+                        span(ng-hide='field.edit')
+                            a.labelFormField(ng-click='field.edit = true; #{model} = model;') {{ model }}
+                        span(ng-if='field.edit')
+                            +table-address-field(name, model, addresses, valid, save, false, true)
+                                +table-save-button(valid, save, false)
+                                +unique-feedback(name, uniqueTip)
+
+            .group-content(ng-repeat='field in group.add')
+                -var model = 'new';
+                -var name = '"new"'
+                -var valid = form + '[' + name + '].$valid'
+                -var save = addresses + '.push(' + model + ')'
+
+                div
+                    label.col-xs-12.col-sm-12.col-md-12
+                        +table-address-field(name, model, addresses, valid, save, true, true)
+                            +table-save-button(valid, save, true)
+                            +unique-feedback(name, uniqueTip)
+
+            .group-content-empty(ng-if='!(#{addresses}.length) && !group.add.length')
+                | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/s3.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/s3.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/s3.jade
new file mode 100644
index 0000000..e255f20
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/s3.jade
@@ -0,0 +1,27 @@
+//-
+    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.jade
+
+-var discoveryKind = 'S3'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
+-var model = 'backupItem.discovery.S3'
+
+div
+    .details-row
+        +text('Bucket name:', model + '.bucketName', '"' + discoveryKind + 'BucketName"', required, 'Input bucket name', 'Bucket name for IP finder')
+    .details-row
+        label Note, AWS credentials will be generated as stub

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/shared.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/shared.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/shared.jade
new file mode 100644
index 0000000..2a949a5
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/shared.jade
@@ -0,0 +1,23 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.SharedFs'
+
+div
+    .details-row
+        +text('File path:', model + '.path', '"path"', 'false', 'disco/tcp', 'Shared path')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/vm.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/vm.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/vm.jade
new file mode 100644
index 0000000..6588e6a
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/vm.jade
@@ -0,0 +1,79 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.Vm'
+-var addresses = model + '.addresses'
+-var form = 'discoveryVmAddresses'
+
+.details-row
+    +ignite-form-group(ng-form=form ng-model=addresses)
+        -var uniqueTip = 'Such IP address already exists!'
+
+        ignite-form-field-label
+            | Addresses
+        ignite-form-group-tooltip
+            | Addresses may be represented as follows:
+            ul: li IP address (e.g. 127.0.0.1, 9.9.9.9, etc)
+                li IP address and port (e.g. 127.0.0.1:47500, 9.9.9.9:47501, etc)
+                li IP address and port range (e.g. 127.0.0.1:47500..47510, 9.9.9.9:47501..47504, etc)
+                li Hostname (e.g. host1.com, host2, etc)
+                li Hostname and port (e.g. host1.com:47500, host2:47502, etc)
+                li Hostname and port range (e.g. host1.com:47500..47510, host2:47502..47508, etc)
+            | If port is 0 or not provided then default port will be used (depends on discovery SPI configuration)#[br]
+            | If port range is provided (e.g. host:port1..port2) the following should be considered:
+            ul: li port1 &lt; port2 should be true
+                li Both port1 and port2 should be greater than 0
+        ignite-form-group-add(ng-click='group.add = [{}]')
+            | Add new address
+
+        .group-content(ng-if='#{addresses}.length')
+            -var model = 'obj.model';
+            -var name = '"edit" + $index'
+            -var valid = form + '[' + name + '].$valid'
+            -var save = addresses + '[$index] = ' + model
+
+            div(ng-repeat='model in #{addresses} track by $index' ng-init='obj = {}')
+                label.col-xs-12.col-sm-12.col-md-12
+                    .indexField
+                        | {{ $index+1 }})
+                    +table-remove-button(addresses, 'Remove address')
+
+                    +ignite-form-field-down(ng-if='!$last' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+                    +ignite-form-field-up(ng-if='!$first' ng-hide='field.edit' data-ng-model='model' data-models=addresses)
+
+                    span(ng-hide='field.edit')
+                        a.labelFormField(ng-click='field.edit = true; #{model} = model;') {{ model }}
+                    span(ng-if='field.edit')
+                        +table-address-field(name, model, addresses, valid, save, false, true)
+                            +table-save-button(valid, save, false)
+                            +unique-feedback(name, uniqueTip)
+
+        .group-content(ng-repeat='field in group.add')
+            -var model = 'new';
+            -var name = '"new"'
+            -var valid = form + '[' + name + '].$valid'
+            -var save = addresses + '.push(' + model + ')'
+
+            div
+                label.col-xs-12.col-sm-12.col-md-12
+                    +table-address-field(name, model, addresses, valid, save, true, true)
+                        +table-save-button(valid, save, true)
+                        +unique-feedback(name, uniqueTip)
+
+        .group-content-empty(id='addresses' ng-if='!(#{addresses}.length) && !group.add.length')
+                | Not defined

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
new file mode 100644
index 0000000..afd3ecd
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper.jade
@@ -0,0 +1,83 @@
+//-
+    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.jade
+
+-var form = 'general'
+-var discoveryKind = 'ZooKeeper'
+-var required = 'backupItem.discovery.kind == "' + discoveryKind + '"'
+-var model = 'backupItem.discovery.ZooKeeper'
+-var modelRetryPolicyKind = model + '.retryPolicy.kind'
+
+div
+    .details-row
+        +java-class('Curator:', model + '.curator', '"curator"', 'true', 'false',
+            'The Curator framework in use<br/>\
+            By default generates curator of org.apache.curator. framework.imps.CuratorFrameworkImpl\
+            class with configured connect string, retry policy, and default session and connection timeouts')
+    .details-row
+        +text('Connect string:', model + '.zkConnectionString', '"' + discoveryKind + 'ConnectionString"', required, 'host:port[chroot][,host:port[chroot]]',
+            'When "IGNITE_ZK_CONNECTION_STRING" system property is not configured this property will be used')
+    .details-row
+        +dropdown('Retry policy:', model + '.retryPolicy.kind', '"retryPolicy"', 'true', 'Default',
+            '[\
+                {value: "ExponentialBackoff", label: "Exponential backoff"},\
+                {value: "BoundedExponentialBackoff", label: "Bounded exponential backoff"},\
+                {value: "UntilElapsed", label: "Until elapsed"},\
+                {value: "NTimes", label: "Max number of times"},\
+                {value: "OneTime", label: "Only once"},\
+                {value: "Forever", label: "Always allow retry"},\
+                {value: "Custom", label: "Custom"},\
+                {value: undefined, label: "Default"}\
+            ]',
+            'Available retry policies:\
+            <ul>\
+                <li>Exponential backoff - retries a set number of times with increasing sleep time between retries</li>\
+                <li>Bounded exponential backoff - retries a set number of times with an increasing (up to a maximum bound) sleep time between retries</li>\
+                <li>Until elapsed - retries until a given amount of time elapses</li>\
+                <li>Max number of times - retries a max number of times</li>\
+                <li>Only once - retries only once</li>\
+                <li>Always allow retry - retries infinitely</li>\
+                <li>Custom - custom retry policy implementation</li>\
+                <li>Default - exponential backoff retry policy with configured base sleep time equal to 1000ms and max retry count equal to 10</li>\
+            </ul>')
+    .details-row(ng-show='#{model}.retryPolicy.kind')
+        .panel-details
+                div(ng-show='#{modelRetryPolicyKind} === "ExponentialBackoff"')
+                    include ./zookeeper/retrypolicy/exponential-backoff.jade
+                div(ng-show='#{modelRetryPolicyKind} === "BoundedExponentialBackoff"')
+                    include ./zookeeper/retrypolicy/bounded-exponential-backoff.jade
+                div(ng-show='#{modelRetryPolicyKind} === "UntilElapsed"')
+                    include ./zookeeper/retrypolicy/until-elapsed.jade
+                div(ng-show='#{modelRetryPolicyKind} === "NTimes"')
+                    include ./zookeeper/retrypolicy/n-times.jade
+                div(ng-show='#{modelRetryPolicyKind} === "OneTime"')
+                    include ./zookeeper/retrypolicy/one-time.jade
+                div(ng-show='#{modelRetryPolicyKind} === "Forever"')
+                    include ./zookeeper/retrypolicy/forever.jade
+                div(ng-show='#{modelRetryPolicyKind} === "Custom"')
+                    include ./zookeeper/retrypolicy/custom.jade
+    .details-row
+        +text('Base path:', model + '.basePath', '"basePath"', 'false', '/services', 'Base path for service registration')
+    .details-row
+        +text('Service name:', model + '.serviceName', '"serviceName"', 'false', 'ignite',
+            'Service name to use, as defined by Curator&#39;s ServiceDiscovery recipe<br/>\
+            In physical ZooKeeper terms, it represents the node under basePath, under which services will be registered')
+    .details-row
+        +checkbox('Allow duplicate registrations', model + '.allowDuplicateRegistrations', '"allowDuplicateRegistrations"',
+            'Whether to register each node only once, or if duplicate registrations are allowed<br/>\
+            Nodes will attempt to register themselves, plus those they know about<br/>\
+            By default, duplicate registrations are not allowed, but you might want to set this property to <b>true</b> if you have multiple network interfaces or if you are facing troubles')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
new file mode 100644
index 0000000..5e4bbda
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/bounded-exponential-backoff.jade
@@ -0,0 +1,27 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.BoundedExponentialBackoff'
+
+div
+    .details-row
+        +number('Base interval:', model + '.baseSleepTimeMs', '"beBaseSleepTimeMs"', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
+    .details-row
+        +number('Max interval:', model + '.maxSleepTimeMs', '"beMaxSleepTimeMs"', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')
+    .details-row
+        +number-min-max('Max retries:', model + '.maxRetries', '"beMaxRetries"', 'true', '10', '0', '29', 'Max number of times to retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
new file mode 100644
index 0000000..3dcf514
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/custom.jade
@@ -0,0 +1,24 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy'
+-var retry = model + '.Custom'
+-var required = 'backupItem.discovery.kind === "ZooKeeper" && backupItem.discovery.ZooKeeper.retryPolicy.kind === "Custom"'
+
+.details-row
+    +java-class('Class name:', retry + '.className', '"customClassName"', 'true', required, 'Custom retry policy implementation class name')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
new file mode 100644
index 0000000..618683c
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/exponential-backoff.jade
@@ -0,0 +1,27 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.ExponentialBackoff'
+
+div
+    .details-row
+        +number('Base interval:', model + '.baseSleepTimeMs', '"expBaseSleepTimeMs"', 'true', '1000', '0', 'Initial amount of time in ms to wait between retries')
+    .details-row
+        +number-min-max('Max retries:', model + '.maxRetries', '"expMaxRetries"', 'true', '10', '0', '29', 'Max number of times to retry')
+    .details-row
+        +number('Max interval:', model + '.maxSleepMs', '"expMaxSleepMs"', 'true', 'Integer.MAX_VALUE', '0', 'Max time in ms to sleep on each retry')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
new file mode 100644
index 0000000..10e4fb1
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/forever.jade
@@ -0,0 +1,22 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.Forever'
+
+.details-row
+    +number('Interval:', model + '.retryIntervalMs', '"feRetryIntervalMs"', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
new file mode 100644
index 0000000..329f693
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/n-times.jade
@@ -0,0 +1,25 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.NTimes'
+
+div
+    .details-row
+        +number('Retries:', model + '.n', '"n"', 'true', '10', '0', 'Number of times to retry')
+    .details-row
+        +number('Interval:', model + '.sleepMsBetweenRetries', '"ntSleepMsBetweenRetries"', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
new file mode 100644
index 0000000..938ecea
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/one-time.jade
@@ -0,0 +1,23 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.OneTime'
+
+div
+    .details-row
+        +number('Interval:', model + '.sleepMsBetweenRetry', '"oneSleepMsBetweenRetry"', 'true', '1000', '0', 'Time in ms to retry attempt')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
new file mode 100644
index 0000000..513da6a
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/general/discovery/zookeeper/retrypolicy/until-elapsed.jade
@@ -0,0 +1,25 @@
+//-
+    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.jade
+
+-var model = 'backupItem.discovery.ZooKeeper.retryPolicy.UntilElapsed'
+
+div
+    .details-row
+        +number('Total time:', model + '.maxElapsedTimeMs', '"ueMaxElapsedTimeMs"', 'true', '60000', '0', 'Total time in ms for execution of retry attempt')
+    .details-row
+        +number('Interval:', model + '.sleepMsBetweenRetries', '"ueSleepMsBetweenRetries"', 'true', '1000', '0', 'Time in ms between retry attempts')

http://git-wip-us.apache.org/repos/asf/ignite/blob/6af6560a/modules/web-console/frontend/app/modules/states/configuration/clusters/igfs.jade
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/states/configuration/clusters/igfs.jade b/modules/web-console/frontend/app/modules/states/configuration/clusters/igfs.jade
new file mode 100644
index 0000000..181b44f
--- /dev/null
+++ b/modules/web-console/frontend/app/modules/states/configuration/clusters/igfs.jade
@@ -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.jade
+
+-var form = 'igfs'
+-var model = 'backupItem'
+
+.panel.panel-default(ng-form=form novalidate)
+    .panel-heading(bs-collapse-toggle ng-click='ui.loadPanel("#{form}")')
+        ignite-form-panel-chevron
+        label IGFS
+        ignite-form-field-tooltip.tipLabel
+            | IGFS (Ignite In-Memory File System) configurations assigned to cluster
+        ignite-form-revert
+    .panel-collapse(role='tabpanel' bs-collapse-target id=form)
+        .panel-body(ng-if='ui.isPanelLoaded("#{form}")')
+            .col-sm-6
+                .settings-row
+                    +dropdown-multiple('<span>IGFS:</span><a ui-sref="base.configuration.igfs({linkId: linkId()})"> (add)</a>',
+                        model + '.igfss', '"igfss"', true, 'Choose IGFS', 'No IGFS configured', 'igfss',
+                        'Select IGFS to start in cluster or add a new IGFS')
+            .col-sm-6
+                +preview-xml-java(model, 'igfss', 'igfss')