Explorar o código

AMBARI-8408. Implement the initial layout for the kerberos wizard. (jaimin)

Jaimin Jetly %!s(int64=10) %!d(string=hai) anos
pai
achega
dd87511efa
Modificáronse 59 ficheiros con 3288 adicións e 729 borrados
  1. 148 170
      ambari-web/app/assets/data/stacks/HDP-2.1/recommendations_configs.json
  2. 89 0
      ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json
  3. 372 0
      ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json
  4. 2 1
      ambari-web/app/config.js
  5. 9 0
      ambari-web/app/controllers.js
  6. 1 1
      ambari-web/app/controllers/global/cluster_controller.js
  7. 43 7
      ambari-web/app/controllers/global/configuration_controller.js
  8. 2 1
      ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js
  9. 2 318
      ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
  10. 95 0
      ambari-web/app/controllers/main/admin/kerberos.js
  11. 25 0
      ambari-web/app/controllers/main/admin/kerberos/progress_controller.js
  12. 82 0
      ambari-web/app/controllers/main/admin/kerberos/step1_controller.js
  13. 164 0
      ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
  14. 59 0
      ambari-web/app/controllers/main/admin/kerberos/step3_controller.js
  15. 22 0
      ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
  16. 21 0
      ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
  17. 25 0
      ambari-web/app/controllers/main/admin/kerberos/step6_controller.js
  18. 220 0
      ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js
  19. 21 10
      ambari-web/app/controllers/wizard/step7_controller.js
  20. 10 64
      ambari-web/app/controllers/wizard/step8_controller.js
  21. 198 1
      ambari-web/app/data/HDP2/site_properties.js
  22. 34 2
      ambari-web/app/messages.js
  23. 4 0
      ambari-web/app/mixins.js
  24. 94 0
      ambari-web/app/mixins/wizard/wizardDeployProgressController.js
  25. 96 0
      ambari-web/app/mixins/wizard/wizardDeployProgressView.js
  26. 364 0
      ambari-web/app/mixins/wizard/wizardProgressPageController.js
  27. 121 0
      ambari-web/app/mixins/wizard/wizardProgressPageView.js
  28. 6 1
      ambari-web/app/models/stack_service.js
  29. 3 0
      ambari-web/app/router.js
  30. 255 0
      ambari-web/app/routes/add_kerberos_routes.js
  31. 13 1
      ambari-web/app/routes/main.js
  32. 4 1
      ambari-web/app/templates/main/admin/highAvailability/progress.hbs
  33. 36 0
      ambari-web/app/templates/main/admin/kerberos.hbs
  34. 47 0
      ambari-web/app/templates/main/admin/kerberos/step1.hbs
  35. 35 0
      ambari-web/app/templates/main/admin/kerberos/step2.hbs
  36. 18 0
      ambari-web/app/templates/main/admin/kerberos/step3.hbs
  37. 21 0
      ambari-web/app/templates/main/admin/kerberos/step4.hbs
  38. 18 0
      ambari-web/app/templates/main/admin/kerberos/step5.hbs
  39. 18 0
      ambari-web/app/templates/main/admin/kerberos/step6.hbs
  40. 47 0
      ambari-web/app/templates/main/admin/kerberos/wizard.hbs
  41. 28 5
      ambari-web/app/utils/ajax/ajax.js
  42. 9 5
      ambari-web/app/utils/config.js
  43. 12 0
      ambari-web/app/utils/db.js
  44. 18 1
      ambari-web/app/utils/ember_reopen.js
  45. 11 0
      ambari-web/app/views.js
  46. 13 5
      ambari-web/app/views/main/admin.js
  47. 2 61
      ambari-web/app/views/main/admin/highAvailability/progress_view.js
  48. 28 0
      ambari-web/app/views/main/admin/kerberos.js
  49. 39 0
      ambari-web/app/views/main/admin/kerberos/progress_view.js
  50. 44 0
      ambari-web/app/views/main/admin/kerberos/step1_view.js
  51. 31 0
      ambari-web/app/views/main/admin/kerberos/step2_view.js
  52. 32 0
      ambari-web/app/views/main/admin/kerberos/step3_view.js
  53. 25 0
      ambari-web/app/views/main/admin/kerberos/step4_view.js
  54. 25 0
      ambari-web/app/views/main/admin/kerberos/step5_view.js
  55. 30 0
      ambari-web/app/views/main/admin/kerberos/step6_view.js
  56. 81 0
      ambari-web/app/views/main/admin/kerberos/wizard_view.js
  57. 13 5
      ambari-web/app/views/main/menu.js
  58. 2 69
      ambari-web/app/views/wizard/step8_view.js
  59. 1 0
      ambari-web/package.json

+ 148 - 170
ambari-web/app/assets/data/stacks/HDP-2.1/recommendations_configs.json

@@ -1,175 +1,153 @@
 {
-  "hosts": ["ab2test-5.c.pramod-thangali.internal", "ab2test-6.c.pramod-thangali.internal", "ab2test-7.c.pramod-thangali.internal"],
-  "services": ["HDFS", "MAPREDUCE2", "YARN", "TEZ", "NAGIOS", "GANGLIA", "HIVE", "SQOOP", "OOZIE", "ZOOKEEPER", "FALCON", "STORM", "FLUME", "PIG"],
-  "recommendations": {
-  "blueprint": {
-    "host_groups": [
-      {
-        "name": "host-group-3",
-        "components": [
-          {
-            "name": "NAMENODE"
-          },
-          {
-            "name": "STORM_UI_SERVER"
-          },
-          {
-            "name": "GANGLIA_SERVER"
-          },
-          {
-            "name": "ZOOKEEPER_SERVER"
-          },
-          {
-            "name": "STORM_REST_API"
-          },
-          {
-            "name": "NIMBUS"
-          },
-          {
-            "name": "DRPC_SERVER"
-          },
-          {
-            "name": "MYSQL_SERVER"
-          },
-          {
-            "name": "NAGIOS_SERVER"
-          }
-        ]
+  "resources" : [
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/recommendations/5",
+      "hosts" : [
+        "c6403.ambari.apache.org"
+      ],
+      "services": ["HDFS", "MAPREDUCE2", "YARN", "TEZ", "NAGIOS", "GANGLIA", "HIVE", "SQOOP", "OOZIE", "ZOOKEEPER", "FALCON", "STORM", "FLUME", "PIG"],
+      "Recommendation" : {
+        "id" : 5
       },
-      {
-        "name": "host-group-1",
-        "components": [
-          {
-            "name": "YARN_CLIENT"
-          },
-          {
-            "name": "NODEMANAGER"
-          },
-          {
-            "name": "HDFS_CLIENT"
-          },
-          {
-            "name": "HIVE_CLIENT"
-          },
-          {
-            "name": "SQOOP"
-          },
-          {
-            "name": "GANGLIA_MONITOR"
-          },
-          {
-            "name": "DATANODE"
-          },
-          {
-            "name": "FLUME_HANDLER"
-          },
-          {
-            "name": "MAPREDUCE2_CLIENT"
-          },
-          {
-            "name": "SUPERVISOR"
-          },
-          {
-            "name": "OOZIE_CLIENT"
-          },
-          {
-            "name": "ZOOKEEPER_CLIENT"
-          },
-          {
-            "name": "PIG"
-          },
-          {
-            "name": "ZOOKEEPER_SERVER"
-          },
-          {
-            "name": "JOURNALNODE"
-          },
-          {
-            "name": "ZKFC"
-          },
-          {
-            "name": "TEZ_CLIENT"
-          },
-          {
-            "name": "FALCON_CLIENT"
-          },
-          {
-            "name": "HCAT"
-          }
-        ]
+      "Versions" : {
+        "stack_name" : "HDP",
+        "stack_version" : "2.2"
       },
-      {
-        "name": "host-group-2",
-        "components": [
-          {
-            "name": "FALCON_SERVER"
-          },
-          {
-            "name": "OOZIE_SERVER"
-          },
-          {
-            "name": "HIVE_SERVER"
-          },
-          {
-            "name": "APP_TIMELINE_SERVER"
-          },
-          {
-            "name": "HISTORYSERVER"
-          },
-          {
-            "name": "HIVE_METASTORE"
-          },
-          {
-            "name": "ZOOKEEPER_SERVER"
-          },
-          {
-            "name": "RESOURCEMANAGER"
-          },
-          {
-            "name": "WEBHCAT_SERVER"
-          },
-          {
-            "name": "SECONDARY_NAMENODE"
-          }
-        ]
+      "recommendations" : {
+        "blueprint" : {
+          "host_groups" : [
+            {
+              "name" : "host-group-1",
+              "components" : [
+                {
+                  "name" : "NODEMANAGER"
+                },
+                {
+                  "name" : "HIVE_CLIENT"
+                },
+                {
+                  "name" : "HDFS_CLIENT"
+                },
+                {
+                  "name" : "APP_TIMELINE_SERVER"
+                },
+                {
+                  "name" : "SLIDER"
+                },
+                {
+                  "name" : "RESOURCEMANAGER"
+                },
+                {
+                  "name" : "WEBHCAT_SERVER"
+                },
+                {
+                  "name" : "DATANODE"
+                },
+                {
+                  "name" : "FLUME_HANDLER"
+                },
+                {
+                  "name" : "SUPERVISOR"
+                },
+                {
+                  "name" : "NAMENODE"
+                },
+                {
+                  "name" : "HBASE_CLIENT"
+                },
+                {
+                  "name" : "OOZIE_CLIENT"
+                },
+                {
+                  "name" : "HBASE_REGIONSERVER"
+                },
+                {
+                  "name" : "KAFKA_BROKER"
+                },
+                {
+                  "name" : "HISTORYSERVER"
+                },
+                {
+                  "name" : "PIG"
+                },
+                {
+                  "name" : "KNOX_GATEWAY"
+                },
+                {
+                  "name" : "HCAT"
+                },
+                {
+                  "name" : "YARN_CLIENT"
+                },
+                {
+                  "name" : "SQOOP"
+                },
+                {
+                  "name" : "GANGLIA_SERVER"
+                },
+                {
+                  "name" : "HIVE_METASTORE"
+                },
+                {
+                  "name" : "DRPC_SERVER"
+                },
+                {
+                  "name" : "NIMBUS"
+                },
+                {
+                  "name" : "GANGLIA_MONITOR"
+                },
+                {
+                  "name" : "MYSQL_SERVER"
+                },
+                {
+                  "name" : "MAPREDUCE2_CLIENT"
+                },
+                {
+                  "name" : "OOZIE_SERVER"
+                },
+                {
+                  "name" : "HIVE_SERVER"
+                },
+                {
+                  "name" : "HBASE_MASTER"
+                },
+                {
+                  "name" : "STORM_UI_SERVER"
+                },
+                {
+                  "name" : "ZOOKEEPER_CLIENT"
+                },
+                {
+                  "name" : "ZOOKEEPER_SERVER"
+                },
+                {
+                  "name" : "TEZ_CLIENT"
+                },
+                {
+                  "name" : "SECONDARY_NAMENODE"
+                },
+                {
+                  "name" : "NAGIOS_SERVER"
+                }
+              ]
+            }
+          ],
+          "configurations" : { }
+        },
+        "blueprint_cluster_binding" : {
+          "host_groups" : [
+            {
+              "name" : "host-group-1",
+              "hosts" : [
+                {
+                  "name" : "c6403.ambari.apache.org"
+                }
+              ]
+            }
+          ]
+        }
       }
-    ],
-    "configurations": {
-      "core-site": {},
-      "global": {
-        "properties": {}
-      },
-      "hbase-site": {},
-      "hdfs-site": {},
-      "yarn-site": {}
     }
-  },
-  "blueprint_cluster_binding": {
-    "host_groups": [
-      {
-        "name": "host-group-3",
-        "hosts": [
-          {
-            "fqdn": "ab2test-5.c.pramod-thangali.internal"
-          }
-        ]
-      },
-      {
-        "name": "host-group-1",
-        "hosts": [
-          {
-            "fqdn": "ab2test-7.c.pramod-thangali.internal"
-          }
-        ]
-      },
-      {
-        "name": "host-group-2",
-        "hosts": [
-          {
-            "fqdn": "ab2test-6.c.pramod-thangali.internal"
-          }
-        ]
-      }
-    ]
-  }
-}}
+  ]
+}

+ 89 - 0
ambari-web/app/assets/data/stacks/HDP-2.1/service_components.json

@@ -1451,6 +1451,95 @@
           "dependencies" : [ ]
         }
       ]
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.1/services/KERBEROS",
+      "StackServices" : {
+        "comments" : "A computer network authentication protocol which works on\n        the basis of 'tickets' to allow nodes communicating over a\n        non-secure network to prove their identity to one another in a\n        secure manner.\n      ",
+        "custom_commands" : [ ],
+        "display_name" : "Kerberos",
+        "required_services" : [ ],
+        "service_check_supported" : true,
+        "service_name" : "KERBEROS",
+        "service_version" : "1.10.3-10",
+        "stack_name" : "HDP",
+        "stack_version" : "2.1",
+        "user_name" : null,
+        "config_types" : {
+          "kadm5-acl" : {
+            "supports" : {
+              "adding_forbidden" : "false",
+              "do_not_extend" : "false",
+              "final" : "false"
+            }
+          },
+          "kdc-conf" : {
+            "supports" : {
+              "adding_forbidden" : "false",
+              "do_not_extend" : "false",
+              "final" : "false"
+            }
+          },
+          "krb5-conf" : {
+            "supports" : {
+              "adding_forbidden" : "false",
+              "do_not_extend" : "false",
+              "final" : "false"
+            }
+          }
+        }
+      },
+      "serviceComponents" : [
+        {
+          "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.1/services/KERBEROS/components/KDC_SERVER",
+          "StackServiceComponents" : {
+            "cardinality" : "0-1",
+            "component_category" : "MASTER",
+            "component_name" : "KDC_SERVER",
+            "custom_commands" : [ ],
+            "display_name" : "Kerberos KDC",
+            "is_client" : false,
+            "is_master" : true,
+            "service_name" : "KERBEROS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          },
+          "dependencies" : [
+            {
+              "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.1/services/KERBEROS/components/KDC_SERVER/dependencies/KERBEROS_CLIENT",
+              "Dependencies" : {
+                "component_name" : "KERBEROS_CLIENT",
+                "dependent_component_name" : "KDC_SERVER",
+                "dependent_service_name" : "KERBEROS",
+                "scope" : "cluster",
+                "stack_name" : "HDP",
+                "stack_version" : "2.1"
+              }
+            }
+          ]
+        },
+        {
+          "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.1/services/KERBEROS/components/KERBEROS_CLIENT",
+          "StackServiceComponents" : {
+            "cardinality" : "ALL",
+            "component_category" : "CLIENT",
+            "component_name" : "KERBEROS_CLIENT",
+            "custom_commands" : [
+              "SET_KEYTAB"
+            ],
+            "display_name" : "Kerberos Client",
+            "is_client" : true,
+            "is_master" : false,
+            "service_name" : "KERBEROS",
+            "stack_name" : "HDP",
+            "stack_version" : "2.1"
+          },
+          "auto_deploy" : {
+            "enabled" : true
+          },
+          "dependencies" : [ ]
+        }
+      ]
     }
   ]
 }

+ 372 - 0
ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json

@@ -0,0 +1,372 @@
+
+{
+  "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/stackServices/KERBEROS/configurations?fields=*",
+  "items" : [
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/admin_server_host",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The IP address or FQDN of the administrative Kerberos server, optionally a port number may be\n      provided\n    ",
+        "property_name" : "admin_server_host",
+        "property_type" : [ ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/conf_dir",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The kadm.acl configuration directory",
+        "property_name" : "conf_dir",
+        "property_type" : [ ],
+        "property_value" : "/var/kerberos/krb5kdc",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kadm5-acl.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/conf_dir",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The kdc.conf configuration directory",
+        "property_name" : "conf_dir",
+        "property_type" : [ ],
+        "property_value" : "/var/kerberos/krb5kdc",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kdc-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/conf_dir",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The krb5.conf configuration directory",
+        "property_name" : "conf_dir",
+        "property_type" : [ ],
+        "property_value" : "/etc",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/content",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The jinja template for the kadm5.acl file",
+        "property_name" : "content",
+        "property_type" : [ ],
+        "property_value" : "\n      */admin@{{realm}}\t*\n\n      {# Append additional realm declarations should be placed below #}\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kadm5-acl.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/content",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The jinja template for the kdc.conf file",
+        "property_name" : "content",
+        "property_type" : [ ],
+        "property_value" : "\n      [kdcdefaults]\n        kdc_ports = {{kdcdefaults_kdc_ports}}\n        kdc_tcp_ports = {{kdcdefaults_kdc_tcp_ports}}\n\n      [realms]\n        {{realm}} = {\n          acl_file = {{kadm5_acl_path}}\n          dict_file = /usr/share/dict/words\n          admin_keytab = {{kadm5_acl_dir}}/kadm5.keytab\n          supported_enctypes = {{libdefaults_default_tgs_enctypes}}\n      }\n\n      {# Append additional realm declarations should be placed below #}\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kdc-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/content",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "The jinja template for the krb5.conf file",
+        "property_name" : "content",
+        "property_type" : [ ],
+        "property_value" : "\n[libdefaults]\n  renew_lifetime = {{libdefaults_renew_lifetime}}\n  forwardable = {{libdefaults_forwardable}}\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = {{libdefaults_ticket_lifetime}}\n  dns_lookup_realm = {{libdefaults_dns_lookup_realm}}\n  dns_lookup_kdc = {{libdefaults_dns_lookup_kdc}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = {{logging_default}}\n{#\n# The following options are unused unless a managed KDC is installed\n  admin_server = {{logging_admin_server}}\n  kdc = {{logging_admin_kdc}}\n#}\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations should be placed below #}\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/domains",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      A comma-delimited list of domain names that the realm serves (optional)\n    ",
+        "property_name" : "domains",
+        "property_type" : [ ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_host",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The IP address or FQDN of the KDC or Active Directory server, optionally a port number may be\n      provided\n    ",
+        "property_name" : "kdc_host",
+        "property_type" : [ ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_type",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The type of KDC being used. Either mit-kdc or active-directory\n    ",
+        "property_name" : "kdc_type",
+        "property_type" : [ ],
+        "property_value" : "mit-kdc",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdcdefaults_kdc_ports",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "kdcdefaults_kdc_ports",
+        "property_type" : [ ],
+        "property_value" : "88",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kdc-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdcdefaults_kdc_tcp_ports",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "kdcdefaults_kdc_tcp_ports",
+        "property_type" : [ ],
+        "property_value" : "88",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "kdc-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_default_tgs_enctypes",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      a space-delimited list of session key encryption types supported by the KDC or Active\n      Directory\n    ",
+        "property_name" : "libdefaults_default_tgs_enctypes",
+        "property_type" : [ ],
+        "property_value" : "\n      aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 des3-cbc-sha1 arcfour-hmac-md5\n      camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_default_tkt_enctypes",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      a space-delimited list of session key encryption types supported by the KDC or Active\n      Directory\n    ",
+        "property_name" : "libdefaults_default_tkt_enctypes",
+        "property_type" : [ ],
+        "property_value" : "\n      aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 des3-cbc-sha1 arcfour-hmac-md5\n      camellia256-cts-cmac camellia128-cts-cmac des-cbc-crc des-cbc-md5 des-cbc-md4\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_dns_lookup_kdc",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "libdefaults_dns_lookup_kdc",
+        "property_type" : [ ],
+        "property_value" : "false",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_dns_lookup_realm",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "libdefaults_dns_lookup_realm",
+        "property_type" : [ ],
+        "property_value" : "false",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_forwardable",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "libdefaults_forwardable",
+        "property_type" : [ ],
+        "property_value" : "true",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_renew_lifetime",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "libdefaults_renew_lifetime",
+        "property_type" : [ ],
+        "property_value" : "7d",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/libdefaults_ticket_lifetime",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "libdefaults_ticket_lifetime",
+        "property_type" : [ ],
+        "property_value" : "24h",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/logging_admin_server",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "logging_admin_server",
+        "property_type" : [ ],
+        "property_value" : "FILE:/var/log/kadmind.log",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/logging_default",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "logging_default",
+        "property_type" : [ ],
+        "property_value" : "FILE:/var/log/krb5libs.log",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/logging_kdc",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : null,
+        "property_name" : "logging_kdc",
+        "property_type" : [ ],
+        "property_value" : "FILE:/var/log/krb5kdc.log",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/realm",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The realm to use when creating service principals\n    ",
+        "property_name" : "realm",
+        "property_type" : [ ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/test_keytab",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The base64-encoded keytab for the test principal (either this value or the password\n      value is required to be set, neither is expected to be retained)\n    ",
+        "property_name" : "test_keytab",
+        "property_type" : [ ],
+        "property_value" : "\n\n    ",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/test_password",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The password for the administrative principal (either this value or the keytab value is\n      required to be set, neither is expected to be retained)\n    ",
+        "property_name" : "test_password",
+        "property_type" : [
+          "PASSWORD"
+        ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    },
+    {
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/test_principal",
+      "StackConfigurations" : {
+        "final" : "false",
+        "property_description" : "\n      The principal that may be used to test the Kerberos configuration (this will not be retained)\n    ",
+        "property_name" : "test_principal",
+        "property_type" : [ ],
+        "property_value" : "",
+        "service_name" : "KERBEROS",
+        "stack_name" : "HDP",
+        "stack_version" : "2.2",
+        "type" : "krb5-conf.xml"
+      }
+    }
+  ]
+}

+ 2 - 1
ambari-web/app/config.js

@@ -60,7 +60,8 @@ App.supports = {
   stackUpgrade: false,
   autoRollbackHA: false,
   alerts: true,
-  alwaysEnableManagedMySQLForHive: false
+  alwaysEnableManagedMySQLForHive: false,
+  automatedKerberos: false
 };
 
 if (App.enableExperimental) {

+ 9 - 0
ambari-web/app/controllers.js

@@ -58,6 +58,15 @@ require('controllers/main/admin/stack_versions/stack_version_details_controller'
 require('controllers/main/admin/serviceAccounts_controller');
 require('controllers/main/admin/advanced');
 require('utils/polling');
+require('controllers/main/admin/kerberos');
+require('controllers/main/admin/kerberos/wizard_controller');
+require('controllers/main/admin/kerberos/progress_controller');
+require('controllers/main/admin/kerberos/step1_controller');
+require('controllers/main/admin/kerberos/step2_controller');
+require('controllers/main/admin/kerberos/step3_controller');
+require('controllers/main/admin/kerberos/step4_controller');
+require('controllers/main/admin/kerberos/step5_controller');
+require('controllers/main/admin/kerberos/step6_controller');
 require('controllers/main/admin/security');
 require('controllers/main/admin/security/security_progress_controller');
 require('controllers/main/admin/security/disable');

+ 1 - 1
ambari-web/app/controllers/global/cluster_controller.js

@@ -321,7 +321,7 @@ App.ClusterController = Em.Controller.extend({
         service.StackServices.is_installed = false;
       }, self);
       App.stackServiceMapper.mapStackServices(data);
-      App.config.setPreDefinedServiceConfigs();
+      App.config.setPreDefinedServiceConfigs(true);
       var updater = App.router.get('updateController');
       self.updateLoadStatus('stackComponents');
       updater.updateServices(function () {

+ 43 - 7
ambari-web/app/controllers/global/configuration_controller.js

@@ -24,7 +24,9 @@ App.ConfigurationController = Em.Controller.extend({
   /**
    * get configs by tags
    * return Deferred object with configs as argument
-   * @param tags
+   * @param tags {Object}
+   * ** siteName
+   * ** tagName (optional)
    * @return {object}
    */
   getConfigsByTags: function (tags) {
@@ -74,10 +76,34 @@ App.ConfigurationController = Em.Controller.extend({
    * @return {Array}
    */
   loadFromServer: function (tags) {
-    var dfd = $.Deferred();
-    var loadedConfigs = [];
     var self = this;
+    var dfd = $.Deferred();
+    if (!tags.everyProperty('tagName')) {
+      var configTags;
+      var jqXhr =  this.loadConfigTags();
+      jqXhr.done(function (data) {
+        configTags = data.Clusters.desired_configs;
+        tags.forEach(function (_tag) {
+          if (_tag.siteName && !_tag.tagName) {
+            _tag.tagName = configTags[_tag.siteName].tag;
+          }
+        }, self);
+        self.loadConfigsByTags(tags,dfd);
+      });
+    } else {
+      self.loadConfigsByTags(tags,dfd);
+    }
+    return dfd.promise();
+  },
 
+  /**
+   *  loadConfigsByTags: Loads properties for a config tag
+   *  @params tags
+   *  @params dfd jqXhr promise
+   */
+  loadConfigsByTags: function (tags,dfd) {
+    var self = this;
+    var loadedConfigs = [];
     App.config.loadConfigsByTags(tags).done(function (data) {
       if (data.items) {
         data.items.forEach(function (item) {
@@ -86,10 +112,20 @@ App.ConfigurationController = Em.Controller.extend({
         });
       }
     }).complete(function () {
-        self.saveToDB(loadedConfigs);
-        dfd.resolve(loadedConfigs);
-      });
-    return dfd.promise();
+      self.saveToDB(loadedConfigs);
+      dfd.resolve(loadedConfigs);
+    });
+  },
+
+  /**
+   * loadConfigTags: Loads all config tags applied to the cluster
+   * @return: jqXhr promise
+   */
+  loadConfigTags: function () {
+    return App.ajax.send({
+      name: 'config.tags',
+      sender: this
+    });
   },
 
   /**

+ 2 - 1
ambari-web/app/controllers/main/admin/highAvailability/nameNode/wizard_controller.js

@@ -41,7 +41,8 @@ App.HighAvailabilityWizardController = App.WizardController.extend({
     serviceName: 'MISC',
     hdfsUser:"hdfs",
     nameServiceId: '',
-    failedTask : null
+    failedTask : null,
+    requestIds: null
   }),
 
   setCurrentStep: function (currentStep, completed) {

+ 2 - 318
ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js

@@ -19,93 +19,12 @@
 var App = require('app');
 var installedComponents = [];
 
-App.HighAvailabilityProgressPageController = App.HighAvailabilityWizardController.extend({
+App.HighAvailabilityProgressPageController = App.HighAvailabilityWizardController.extend(App.wizardProgressPageControllerMixin, {
 
   name: 'highAvailabilityProgressPageController',
-
-  status: 'IN_PROGRESS',
   clusterDeployState: 'HIGH_AVAILABILITY_DEPLOY',
-  tasks: [],
-  commands: [],
-  currentRequestIds: [], //todo: replace with using requestIds from tasks
-  logs: [],
-  currentTaskId: null,
-  POLL_INTERVAL: 4000,
-  isSubmitDisabled: true,
-  isRollback: false,
   tasksMessagesPrefix: 'admin.highAvailability.wizard.step',
-
-  loadStep: function () {
-    this.clearStep();
-    this.initializeTasks();
-    this.loadTasks();
-    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
-    this.onTaskStatusChange();
-  },
-
-  clearStep: function () {
-    this.set('isSubmitDisabled', true);
-    this.set('tasks', []);
-    this.set('currentRequestIds', []);
-  },
-
-  initializeTasks: function () {
-    var commands = this.get('commands');
-    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
-    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
-    for (var i = 0; i < commands.length; i++) {
-      this.get('tasks').pushObject(Ember.Object.create({
-        title: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
-        status: 'PENDING',
-        id: i,
-        command: commands[i],
-        showRetry: false,
-        showRollback: false,
-        name: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
-        displayName: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
-        progress: 0,
-        isRunning: false,
-        requestIds: []
-      }));
-    }
-  },
-
-  loadTasks: function () {
-    var self = this;
-    var loadedStatuses = this.get('content.tasksStatuses');
-    var loadedRequestIds = this.get('content.tasksRequestIds');
-    if (loadedStatuses && loadedStatuses.length === this.get('tasks').length) {
-      this.get('tasks').forEach(function (task, i) {
-        self.setTaskStatus(task.get('id'), loadedStatuses[i]);
-        self.setRequestIds(task.get('id'), loadedRequestIds[i]);
-      });
-      if (loadedStatuses.contains('IN_PROGRESS')) {
-        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('IN_PROGRESS')].get('id');
-        this.set('currentRequestIds', this.get('content.requestIds'));
-        this.set('currentTaskId', curTaskId);
-        this.doPolling();
-      } else if (loadedStatuses.contains('QUEUED')) {
-        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('QUEUED')].get('id');
-        this.set('currentTaskId', curTaskId);
-        this.runTask(curTaskId);
-      }
-    }
-  },
-
-  setTaskStatus: function (taskId, status) {
-    this.get('tasks').findProperty('id', taskId).set('status', status);
-  },
-
-  setRequestIds: function (taskId, requestIds) {
-    this.get('tasks').findProperty('id', taskId).set('requestIds', requestIds);
-  },
-
-  retryTask: function () {
-    var task = this.get('tasks').findProperty('status', 'FAILED');
-    task.set('showRetry', false);
-    task.set('showRollback', false);
-    task.set('status', 'PENDING');
-  },
+  isRollback: false,
 
   manualRollback: function () {
     App.ModalPopup.show({
@@ -152,241 +71,6 @@ App.HighAvailabilityProgressPageController = App.HighAvailabilityWizardControlle
     });
   },
 
-  onTaskStatusChange: function () {
-    var statuses = this.get('tasks').mapProperty('status');
-    var tasksRequestIds = this.get('tasks').mapProperty('requestIds');
-    var requestIds = this.get('currentRequestIds');
-    // save task info
-    App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
-    App.router.get(this.get('content.controllerName')).saveTasksRequestIds(tasksRequestIds);
-    App.router.get(this.get('content.controllerName')).saveRequestIds(requestIds);
-    // call saving of cluster status asynchronous
-    // synchronous executing cause problems in Firefox
-    App.clusterStatus.setClusterStatus({
-      clusterName: this.get('content.cluster.name'),
-      clusterState: this.get('clusterDeployState'),
-      wizardControllerName: this.get('content.controllerName'),
-      localdb: App.db.data
-    }, {successCallback: this.statusChangeCallback, sender: this});
-  },
-  /**
-   * Method that called after saving persist data to server.
-   * Switch task according its status.
-   */
-  statusChangeCallback: function () {
-    if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
-      var nextTask = this.get('tasks').findProperty('status', 'PENDING');
-      if (nextTask) {
-        this.set('status', 'IN_PROGRESS');
-        this.setTaskStatus(nextTask.get('id'), 'QUEUED');
-        this.set('currentTaskId', nextTask.get('id'));
-        this.runTask(nextTask.get('id'));
-      } else {
-        this.set('status', 'COMPLETED');
-        this.set('isSubmitDisabled', false);
-      }
-    } else if (this.get('tasks').someProperty('status', 'FAILED')) {
-      this.set('status', 'FAILED');
-      this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
-      if (App.supports.autoRollbackHA) {
-        this.get('tasks').findProperty('status', 'FAILED').set('showRollback', true);
-      }
-    }
-    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRetry', false);
-    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRollback', false);
-  },
-
-  /**
-   * Run command of appropriate task
-   */
-  runTask: function (taskId) {
-    this[this.get('tasks').findProperty('id', taskId).get('command')]();
-  },
-
-  onTaskError: function () {
-    this.setTaskStatus(this.get('currentTaskId'), 'FAILED');
-  },
-
-  onTaskCompleted: function () {
-    this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
-  },
-
-  /**
-   * check whether component installed on specified hosts
-   * @param componentName
-   * @param hostNames
-   * @return {$.ajax}
-   */
-  checkInstalledComponents: function (componentName, hostNames) {
-    return App.ajax.send({
-      name: 'host_component.installed.on_hosts',
-      sender: this,
-      data: {
-        componentName: componentName,
-        hostNames: hostNames.join(',')
-      },
-      success: 'checkInstalledComponentsSuccessCallback'
-    });
-  },
-
-  checkInstalledComponentsSuccessCallback: function (data, opt, params) {
-    installedComponents = data.items;
-  },
-
-  createComponent: function (componentName, hostName, serviceName) {
-    var hostNames = (Array.isArray(hostName)) ? hostName : [hostName];
-    var self = this;
-
-    this.checkInstalledComponents(componentName, hostNames).complete(function () {
-      var result = [];
-
-      hostNames.forEach(function (hostName) {
-        result.push({
-          componentName: componentName,
-          hostName: hostName,
-          hasComponent: installedComponents.someProperty('HostRoles.host_name', hostName)
-        });
-      });
-
-      result.forEach(function (host, index, array) {
-        if (!host.hasComponent) {
-          App.ajax.send({
-            name: 'admin.high_availability.create_component',
-            sender: this,
-            data: {
-              hostName: host.hostName,
-              componentName: host.componentName,
-              serviceName: serviceName,
-              taskNum: array.length
-            },
-            success: 'onCreateComponent',
-            error: 'onCreateComponentError'
-          });
-        } else {
-          // Simulates format returned from ajax.send
-          this.onCreateComponent(null, null, {hostName: host.hostName, componentName: host.componentName, taskNum: array.length});
-        }
-      }, self)
-    });
-  },
-
-  onCreateComponent: function () {
-    var hostName = arguments[2].hostName;
-    var componentName = arguments[2].componentName;
-    var taskNum = arguments[2].taskNum;
-    var serviceName = arguments[2].serviceName;
-    this.updateComponent(componentName, hostName, serviceName, "Install", taskNum);
-  },
-
-  onCreateComponentError: function (error) {
-    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException') !== -1) {
-      this.onCreateComponent();
-    } else {
-      this.onTaskError();
-    }
-  },
-
-  updateComponent: function (componentName, hostName, serviceName, context, taskNum) {
-    if (!(hostName instanceof Array)) {
-      hostName = [hostName];
-    }
-    var state = context.toLowerCase() == "start" ? "STARTED" : "INSTALLED";
-    for (var i = 0; i < hostName.length; i++) {
-      App.ajax.send({
-        name: 'common.host.host_component.update',
-        sender: this,
-        data: {
-          context: context + " " + App.format.role(componentName),
-          hostName: hostName[i],
-          serviceName: serviceName,
-          componentName: componentName,
-          taskNum: taskNum || hostName.length,
-          HostRoles: {
-            state: state
-          }
-        },
-        success: 'startPolling',
-        error: 'onTaskError'
-      });
-    }
-  },
-
-  startPolling: function (data) {
-    if (data) {
-      this.get('currentRequestIds').push(data.Requests.id);
-      var tasksCount = arguments[2].taskNum || 1;
-      if (tasksCount === this.get('currentRequestIds').length) {
-        this.setRequestIds(this.get('currentTaskId'), this.get('currentRequestIds'));
-        this.doPolling();
-      }
-    } else {
-      this.onTaskCompleted();
-    }
-  },
-
-  doPolling: function () {
-    this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
-    var requestIds = this.get('currentRequestIds');
-    this.set('logs', []);
-    for (var i = 0; i < requestIds.length; i++) {
-      App.ajax.send({
-        name: 'admin.high_availability.polling',
-        sender: this,
-        data: {
-          requestId: requestIds[i]
-        },
-        success: 'parseLogs',
-        error: 'onTaskError'
-      });
-    }
-  },
-
-  parseLogs: function (logs) {
-    this.get('logs').pushObject(logs.tasks);
-    if (this.get('currentRequestIds').length === this.get('logs').length) {
-      var tasks = [];
-      this.get('logs').forEach(function (logs) {
-        tasks.pushObjects(logs);
-      }, this);
-      var self = this;
-      var currentTaskId = this.get('currentTaskId');
-      if (!tasks.someProperty('Tasks.status', 'PENDING') && !tasks.someProperty('Tasks.status', 'QUEUED') && !tasks.someProperty('Tasks.status', 'IN_PROGRESS')) {
-        this.set('currentRequestIds', []);
-        if (tasks.someProperty('Tasks.status', 'FAILED') || tasks.someProperty('Tasks.status', 'TIMEDOUT') || tasks.someProperty('Tasks.status', 'ABORTED')) {
-          this.setTaskStatus(currentTaskId, 'FAILED');
-        } else {
-          this.setTaskStatus(currentTaskId, 'COMPLETED');
-        }
-      } else {
-        var actionsPerHost = tasks.length;
-        var completedActions = tasks.filterProperty('Tasks.status', 'COMPLETED').length
-            + tasks.filterProperty('Tasks.status', 'FAILED').length
-            + tasks.filterProperty('Tasks.status', 'ABORTED').length
-            + tasks.filterProperty('Tasks.status', 'TIMEDOUT').length;
-        var queuedActions = tasks.filterProperty('Tasks.status', 'QUEUED').length;
-        var inProgressActions = tasks.filterProperty('Tasks.status', 'IN_PROGRESS').length;
-        var progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsPerHost * 100);
-        this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
-        window.setTimeout(function () {
-          self.doPolling()
-        }, self.POLL_INTERVAL);
-      }
-    }
-  },
-
-  showHostProgressPopup: function (event) {
-    var popupTitle = event.contexts[0].title;
-    var requestIds = event.contexts[0].requestIds;
-    var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
-    hostProgressPopupController.initPopup(popupTitle, requestIds, this, true);
-  },
-
-  done: function () {
-    if (!this.get('isSubmitDisabled')) {
-      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
-      App.router.send('next');
-    }
-  },
   /**
    *
    * @param siteNames Array

+ 95 - 0
ambari-web/app/controllers/main/admin/kerberos.js

@@ -0,0 +1,95 @@
+/**
+ * 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.
+ */
+
+
+var App = require('app');
+App.MainAdminKerberosController = Em.Controller.extend({
+  name: 'mainAdminKerberosController',
+  securityEnabled: false,
+  dataIsLoaded: false,
+  isRecommendedLoaded: true,
+  getAddSecurityWizardStatus: function () {
+    return App.db.getSecurityWizardStatus();
+  },
+  setAddSecurityWizardStatus: function (status) {
+    App.db.setSecurityWizardStatus(status);
+  },
+
+  setDisableSecurityStatus: function (status) {
+    App.db.setDisableSecurityStatus(status);
+  },
+  getDisableSecurityStatus: function (status) {
+    return App.db.getDisableSecurityStatus();
+  },
+
+  notifySecurityOff: false,
+  notifySecurityAdd: false,
+
+  notifySecurityOffPopup: function () {
+    var self = this;
+    App.ModalPopup.show({
+      header: Em.I18n.t('popup.confirmation.commonHeader'),
+      primary: Em.I18n.t('ok'),
+      onPrimary: function () {
+        App.db.setSecurityDeployCommands(undefined);
+        self.setDisableSecurityStatus("RUNNING");
+        App.router.transitionTo('disableSecurity');
+        this.hide();
+      },
+      bodyClass: Ember.View.extend({
+        isMapReduceInstalled: App.Service.find().mapProperty('serviceName').contains('MAPREDUCE'),
+        templateName: require('templates/main/admin/security/notify_security_off_popup')
+      })
+    })
+  },
+
+  getUpdatedSecurityStatus: function () {
+    this.setSecurityStatus();
+    return this.get('securityEnabled');
+  },
+
+  startKerberosWizard: function () {
+    this.setAddSecurityWizardStatus('RUNNING');
+    App.router.transitionTo('adminAddKerberos');
+  },
+
+  /**
+   * Loads the security status from server (security_enabled property in cluster-env configuration)
+   */
+  loadSecurityStatusFromServer: function () {
+    if (App.get('testMode')) {
+      this.set('securityEnabled', !App.get('testEnableSecurity'));
+      this.set('dataIsLoaded', true);
+    } else {
+      //get Security Status From Server
+      var self = this;
+      var tags = [{siteName: 'cluster-env'}];
+      App.router.get('configurationController').getConfigsByTags(tags).done(function (data) {
+        var configs = data[0].properties;
+        if (configs) {
+          self.set('securityEnabled', configs['security_enabled'] === 'true');
+        }
+        self.set('dataIsLoaded', true);
+      });
+    }
+  }
+});
+
+
+
+

+ 25 - 0
ambari-web/app/controllers/main/admin/kerberos/progress_controller.js

@@ -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.
+ */
+
+App.KerberosProgressPageController = App.KerberosWizardController.extend(App.wizardProgressPageControllerMixin, {
+
+  name: 'kerberosProgressPageController',
+  clusterDeployState: 'KERBEROS__DEPLOY',
+  tasksMessagesPrefix: 'admin.kerberos.wizard.step',
+  isRollback: false
+});

+ 82 - 0
ambari-web/app/controllers/main/admin/kerberos/step1_controller.js

@@ -0,0 +1,82 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.KerberosWizardStep1Controller = Em.Controller.extend({
+  name: "kerberosWizardStep1Controller",
+
+  selectedItem: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
+
+  isSubmitDisabled: function() {
+    return this.get('selectedOption.preConditions').someProperty('checked',false);
+  }.property('selectedOption', 'selectedOption.preConditions.@each.checked'),
+
+  options: [
+    Em.Object.create({
+      displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
+      value: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
+      preConditions: [
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc.condition.1'),
+          checked: false
+        }),
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc.condition.2'),
+          checked: false
+        })
+      ]
+    }),
+    Em.Object.create({
+      displayName: Em.I18n.t('admin.kerberos.wizard.step1.option.ad'),
+      value: Em.I18n.t('admin.kerberos.wizard.step1.option.ad'),
+      preConditions: [
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ad.condition.1'),
+          checked: false
+        }),
+        Em.Object.create({
+          displayText: Em.I18n.t('admin.kerberos.wizard.step1.option.ad.condition.2'),
+          checked: false
+        })
+      ]
+    })
+  ],
+
+  /**
+   * precondition for the selected KDC option
+   */
+  selectedOption: function () {
+    var options = this.get('options');
+    var selectedItem = this.get('selectedItem');
+    return options.findProperty('value', selectedItem);
+  }.property('selectedItem'),
+
+
+
+  loadStep: function () {
+    this.set('selectedItem', Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'));
+  },
+
+  next: function () {
+    if (!this.get('isSubmitDisabled')) {
+      App.router.send('next');
+    }
+  }
+});
+

+ 164 - 0
ambari-web/app/controllers/main/admin/kerberos/step2_controller.js

@@ -0,0 +1,164 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+require('controllers/wizard/step7_controller');
+
+App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
+  name: "kerberosWizardStep2Controller",
+  isKerberosWizard: true,
+
+  selectedServiceNames: ['KERBEROS'],
+
+  allSelectedServiceNames: ['KERBEROS'],
+
+  installedServiceNames: [],
+
+  servicesInstalled: false,
+
+  addMiscTabToPage: false,
+
+  hostNames: function() {
+    return this.get('content.hosts');
+  }.property('content.hosts'),
+
+  serviceConfigTags: [],
+
+
+  clearStep: function () {
+    this._super();
+    this.get('serviceConfigTags').clear();
+    this.set('servicesInstalled', false);
+  },
+
+
+  /**
+   * On load function
+   * @method loadStep
+   */
+  loadStep: function () {
+    console.log("TRACE: Loading step7: Configure Services");
+    this.clearStep();
+    var kerberosStackService = App.StackService.find().findProperty('serviceName', 'KERBEROS');
+    if (!kerberosStackService) return;
+    //STEP 1: Load advanced configs
+    var advancedConfigs = this.get('content.advancedServiceConfig');
+    //STEP 2: Load on-site configs by service from local DB
+    var storedConfigs = this.get('content.serviceConfigProperties');
+    //STEP 3: Merge pre-defined configs with loaded on-site configs
+    var configs = App.config.mergePreDefinedWithStored(
+      storedConfigs,
+      advancedConfigs,
+      this.get('selectedServiceNames'));
+    App.config.setPreDefinedServiceConfigs(this.get('addMiscTabToPage'));
+    //STEP 4: Add advanced configs
+    App.config.addAdvancedConfigs(configs, advancedConfigs);
+    this.applyServicesConfigs(configs, storedConfigs);
+  },
+
+  submit: function () {
+    this.set('isSubmitDisabled', true);
+    var self = this;
+    this.deleteKerberosService().always(function (data) {
+      self.createKerberosResources();
+    });
+  },
+
+  createKerberosResources: function () {
+    var self = this;
+    this.createKerberosService().done(function() {
+      self.createConfigurations().done(function() {
+        App.router.send('next');
+      });
+    });
+  },
+
+  /**
+   * Delete Kerberos service if it exists
+   */
+  deleteKerberosService: function () {
+    var serviceName = this.selectedServiceNames[0];
+    return App.ajax.send({
+      name: 'common.delete.service',
+      sender: this,
+      data: {
+        serviceName: serviceName
+      }
+    });
+  },
+
+  createKerberosService: function () {
+    return App.ajax.send({
+      name: 'wizard.step8.create_selected_services',
+      sender: this,
+      data: {
+        data: '{"ServiceInfo": { "service_name": "KERBEROS"}}',
+        cluster: App.get('clusterName') || App.clusterStatus.get('clusterName')
+      }
+    });
+  },
+
+  createConfigurations: function () {
+    var service = App.StackService.find().findProperty('serviceName', 'KERBEROS');
+    var serviceConfigTags = [];
+    var tag = 'version' + (new Date).getTime();
+    Object.keys(service.get('configTypes')).forEach(function (type) {
+      if (!serviceConfigTags.someProperty('type', type)) {
+        var obj = this.createKerberosSiteObj(type, tag);
+        obj.service_config_version_note = Em.I18n.t('admin.kerberos.wizard.configuration.note');
+        serviceConfigTags.pushObject(obj);
+      }
+    }, this);
+    var allConfigData = [];
+    var serviceConfigData = [];
+    Object.keys(service.get('configTypesRendered')).forEach(function (type) {
+      var serviceConfigTag = serviceConfigTags.findProperty('type', type);
+      if (serviceConfigTag) {
+        serviceConfigData.pushObject(serviceConfigTag);
+      }
+    }, this);
+    if (serviceConfigData.length) {
+      allConfigData.pushObject(JSON.stringify({
+        Clusters: {
+          desired_config: serviceConfigData
+        }
+      }));
+    }
+    return App.ajax.send({
+      name: 'common.across.services.configurations',
+      sender: this,
+      data: {
+        data: '[' + allConfigData.toString() + ']'
+      }
+    });
+  },
+
+  createKerberosSiteObj: function (site, tag) {
+    var properties = {};
+    var content = this.get('stepConfigs')[0].get('configs');
+    var configs = content.filterProperty('filename', site + '.xml');
+    configs.forEach(function (_configProperty) {
+      // do not pass any globals whose name ends with _host or _hosts
+      if (_configProperty.isRequiredByAgent !== false) {
+        properties[_configProperty.name] = _configProperty.value;
+      }
+    }, this);
+    return {"type": site, "tag": tag, "properties": properties};
+  }
+});
+

+ 59 - 0
ambari-web/app/controllers/main/admin/kerberos/step3_controller.js

@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+App.KerberosWizardStep3Controller = App.KerberosProgressPageController.extend({
+  name: 'kerberosWizardStep3Controller',
+  clusterDeployState: 'KERBEROS_DEPLOY',
+  serviceName: 'KERBEROS',
+  componentName: 'KERBEROS_CLIENT',
+
+  commands: ['installKerberos', 'testKerberos'],
+
+  installKerberos: function() {
+    App.ajax.send({
+      name: 'common.create_component',
+      sender: this,
+      data: {
+        serviceName: this.serviceName,
+        componentName: this.componentName
+      },
+      success: 'onKerberosCreate',
+      error: 'onKerberosCreate'
+    });
+  },
+
+  onKerberosCreate: function() {
+    var hostNames = this.get('content.hosts');
+    this.createComponent(this.componentName, hostNames, this.serviceName);
+  },
+
+  testKerberos: function() {
+    App.ajax.send({
+      'name': 'service.item.smoke',
+      'sender': this,
+      'success': 'startPolling',
+      'error': 'onTaskError',
+      'data': {
+        'serviceName': this.serviceName,
+        'displayName': App.format.role(this.serviceName),
+        'actionName': this.serviceName + '_SERVICE_CHECK'
+      }
+    });
+  }
+});
+

+ 22 - 0
ambari-web/app/controllers/main/admin/kerberos/step4_controller.js

@@ -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.
+ */
+
+App.KerberosWizardStep4Controller = Em.Controller.extend({
+  name: 'kerberosWizardStep4Controller'
+});
+

+ 21 - 0
ambari-web/app/controllers/main/admin/kerberos/step5_controller.js

@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+
+App.KerberosWizardStep5Controller = Em.Controller.extend({
+  name: 'kerberosWizardStep5Controller'
+});

+ 25 - 0
ambari-web/app/controllers/main/admin/kerberos/step6_controller.js

@@ -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.
+ */
+
+App.KerberosWizardStep6Controller = App.KerberosProgressPageController.extend({
+  name: 'kerberosWizardStep6Controller',
+  clusterDeployState: 'KERBEROS_DEPLOY',
+  commands: ['stopServices','startServices']
+});
+
+

+ 220 - 0
ambari-web/app/controllers/main/admin/kerberos/wizard_controller.js

@@ -0,0 +1,220 @@
+/**
+ * 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.
+ */
+
+
+var App = require('app');
+
+App.KerberosWizardController = App.WizardController.extend({
+
+  name: 'kerberosWizardController',
+
+  totalSteps: 6,
+
+  isKerberosWizard: true,
+
+  /**
+   * Used for hiding back button in wizard
+   */
+  hideBackButton: true,
+
+  content: Em.Object.create({
+    controllerName: 'kerberosWizardController',
+    serviceName: 'KERBEROS',
+    hosts: '',
+    kerberosOption: null,
+    cluster: null,
+    services: null,
+    advancedServiceConfig: null,
+    serviceConfigProperties: [],
+    failedTask: null
+  }),
+
+  setCurrentStep: function (currentStep, completed) {
+    this._super(currentStep, completed);
+    if (App.testMode) {
+      return;
+    }
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('content.cluster.name'),
+      clusterState: 'KERBEROS_DEPLOY',
+      wizardControllerName: 'kerberosWizardController',
+      localdb: App.db.data
+    });
+  },
+
+  /**
+   * return new object extended from clusterStatusTemplate
+   * @return Object
+   */
+  getCluster: function () {
+    return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
+  },
+
+  /**
+   * save status of the cluster.
+   * @param clusterStatus object with status,requestId fields.
+   */
+  saveClusterStatus: function (clusterStatus) {
+    var oldStatus = this.toObject(this.get('content.cluster'));
+    clusterStatus = jQuery.extend(oldStatus, clusterStatus);
+    if (clusterStatus.requestId) {
+      clusterStatus.requestId.forEach(function (requestId) {
+        if (clusterStatus.oldRequestsId.indexOf(requestId) === -1) {
+          clusterStatus.oldRequestsId.push(requestId)
+        }
+      }, this);
+    }
+    this.set('content.cluster', clusterStatus);
+    this.save('cluster');
+  },
+
+
+  saveTasksStatuses: function (statuses) {
+    this.setDBProperty('tasksStatuses',statuses);
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  saveConfigTag: function (tag) {
+    App.db.setKerberosWizardConfigTag(tag);
+    this.set('content.' + [tag.name], tag.value);
+  },
+
+  saveKerberosOption: function (stepController) {
+    this.setDBProperty('kerberosOption', stepController.get('selectedItem'));
+    this.set('content.kerberosOption', stepController.get('selectedItem'));
+  },
+
+  loadConfigTag: function (tag) {
+    var tagVal = App.db.getKerberosWizardConfigTag(tag);
+    this.set('content.' + tag, tagVal);
+  },
+
+
+  loadTasksStatuses: function () {
+    var statuses = this.getDBProperty('tasksStatuses');
+    this.set('content.tasksStatuses', statuses);
+  },
+
+  /**
+   * Load serviceConfigProperties to model
+   */
+  loadServiceConfigProperties: function () {
+    var serviceConfigProperties = this.getDBProperty('serviceConfigProperties');
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  },
+
+  /**
+   * load advanced configs from server
+   */
+  loadAdvancedConfigs: function (dependentController) {
+    var self = this;
+    var loadAdvancedConfigResult = [];
+    dependentController.set('isAdvancedConfigLoaded', false);
+    var serviceName = this.get('content.serviceName');
+    App.config.loadAdvancedConfig(serviceName, function (properties) {
+      loadAdvancedConfigResult.pushObjects(properties);
+      self.set('content.advancedServiceConfig', loadAdvancedConfigResult);
+      self.setDBProperty('advancedServiceConfig', loadAdvancedConfigResult);
+      dependentController.set('isAdvancedConfigLoaded', true);
+    });
+  },
+
+
+  saveRequestIds: function (requestIds) {
+    this.setDBProperty('requestIds',requestIds);
+    this.set('content.requestIds', requestIds);
+  },
+
+  loadKerberosOption: function () {
+    this.set('content.kerberosOption', this.getDBProperty('kerberosOption'));
+  },
+
+  loadRequestIds: function () {
+    var requestIds = this.getDBProperty('requestIds');
+    this.set('content.requestIds', requestIds);
+  },
+
+  saveTasksRequestIds: function (requestIds) {
+    this.setDBProperty('tasksRequestIds',requestIds);
+    this.set('content.tasksRequestIds', requestIds);
+  },
+
+  loadTasksRequestIds: function () {
+    var requestIds = this.getDBProperty('tasksRequestIds');
+    this.set('content.tasksRequestIds', requestIds);
+  },
+
+  loadMap: {
+    '1': [
+      {
+        type: 'sync',
+        callback: function () {
+          this.loadKerberosOption();
+        }
+      }
+    ],
+    '2': [
+      {
+        type: 'sync',
+        callback: function () {
+          var kerberosStep2controller = App.router.get('kerberosWizardStep2Controller');
+          this.loadAdvancedConfigs(kerberosStep2controller);
+          this.loadServiceConfigProperties();
+          this.load('hosts');
+        }
+      }
+    ],
+    '3': [
+      {
+        type: 'sync',
+        callback: function () {
+          this.loadTasksStatuses();
+          this.loadTasksRequestIds();
+          this.loadRequestIds();
+        }
+      }
+    ]
+  },
+
+  /**
+   * Remove all loaded data.
+   * Created as copy for App.router.clearAllSteps
+   */
+  clearAllSteps: function () {
+    this.clearInstallOptions();
+    // clear temporary information stored during the install
+    this.set('content.cluster', this.getCluster());
+  },
+
+  clearTasksData: function () {
+    this.saveTasksStatuses(undefined);
+    this.saveRequestIds(undefined);
+    this.saveTasksRequestIds(undefined);
+  },
+
+  /**
+   * Clear all temporary data
+   */
+  finish: function () {
+    // The in-memory variable for currentstep should be reset to 1st step.
+    this.setCurrentStep('1');
+    // kerberos wizard namespace in the localStorage should be emptied
+    this.resetDbNamespace();
+    App.router.get('updateController').updateAll();
+  }
+});

+ 21 - 10
ambari-web/app/controllers/wizard/step7_controller.js

@@ -41,6 +41,8 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
 
   slaveHostToGroup: null,
 
+  addMiscTabToPage: true,
+
   /**
    * Is Submit-click processing now
    * @type {bool}
@@ -623,7 +625,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
       advancedConfigs,
       this.get('selectedServiceNames').concat(this.get('installedServiceNames'))
     );
-    App.config.setPreDefinedServiceConfigs();
+    App.config.setPreDefinedServiceConfigs(this.get('addMiscTabToPage'));
     //STEP 4: Add advanced configs
     App.config.addAdvancedConfigs(configs, advancedConfigs);
     //STEP 5: Add custom configs
@@ -670,7 +672,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
    * @method checkHostOverrideInstaller
    */
   checkHostOverrideInstaller: function () {
-    this.loadConfigGroups(this.get('content.configGroups'));
+    if (this.get('wizardController.name') !== 'kerberosWizardController') {
+      this.loadConfigGroups(this.get('content.configGroups'));
+    }
     if (this.get('installedServiceNames').length > 0) {
       this.loadInstalledServicesConfigGroups(this.get('installedServiceNames'));
     }
@@ -887,15 +891,15 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
     });
     serviceNames.forEach(function (serviceName) {
       var propertyPrefix = serviceName.toLowerCase();
-      if(/HDFS/gi.test(serviceName)) propertyPrefix = 'sink';
+      if (/HDFS/gi.test(serviceName)) propertyPrefix = 'sink';
       var dbTypeConfig = configs.findProperty('name', propertyPrefix + '_database');
       if (!/existing/gi.test(dbTypeConfig.value)) return;
       var dbHostName = propertyPrefix + '_hostname';
       var database = dbTypeConfig.value.match(/MySQL|PostgreSQL|Oracle|Derby|MSSQL/gi)[0];
       var dbPrefix = database.toLowerCase();
-      if(database.toLowerCase() == 'mssql') {
+      if (database.toLowerCase() == 'mssql') {
         dbHostName = 'sink.dbservername';
-        if(/integrated/gi.test(dbTypeConfig.value)) {
+        if (/integrated/gi.test(dbTypeConfig.value)) {
           dbPrefix = 'mssql_server';
         } else {
           dbPrefix = 'mssql_server_2';
@@ -1127,12 +1131,19 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
    * @method activateSpecialConfigs
    */
   activateSpecialConfigs: function () {
-    var miscConfigs = this.get('stepConfigs').findProperty('serviceName', 'MISC').configs;
-    if (this.get('wizardController.name') == "addServiceController") {
-      miscConfigs.findProperty('name', 'smokeuser').set('value', this.get('content.smokeuser')).set('isEditable', false);
-      miscConfigs.findProperty('name', 'user_group').set('value', this.get('content.group')).set('isEditable', false);
+    if (this.get('addMiscTabToPage')) {
+      var miscConfigs = this.get('stepConfigs').findProperty('serviceName', 'MISC').configs;
+      if (this.get('wizardController.name') == "addServiceController") {
+        miscConfigs.findProperty('name', 'smokeuser').set('value', this.get('content.smokeuser')).set('isEditable', false);
+        miscConfigs.findProperty('name', 'user_group').set('value', this.get('content.group')).set('isEditable', false);
+      }
+      App.config.miscConfigVisibleProperty(miscConfigs, this.get('selectedServiceNames'));
+    }
+    var wizardController = this.get('wizardController');
+    if (wizardController.get('name') === "kerberosWizardController")  {
+      var kerberosConfigs =  this.get('stepConfigs').findProperty('serviceName', 'KERBEROS').configs;
+      kerberosConfigs.findProperty('name', 'kdc_type').set('value', wizardController.get('content.kerberosOption'));
     }
-    App.config.miscConfigVisibleProperty(miscConfigs, this.get('selectedServiceNames'));
   },
 
   /**

+ 10 - 64
ambari-web/app/controllers/wizard/step8_controller.js

@@ -19,7 +19,7 @@
 var App = require('app');
 var stringUtils = require('utils/string_utils');
 
-App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
+App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, {
 
   name: 'wizardStep8Controller',
 
@@ -92,6 +92,13 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
    */
   isBackBtnDisabled: false,
 
+  /**
+   * This flag when turned to true launches deploy progress bar
+   */
+  isDeployStarted: function() {
+    this.get('isSubmitDisabled');
+  }.property('isSubmitDisabled'),
+
   /**
    * Is error appears while <code>ajaxQueue</code> executes
    * @type {bool}
@@ -111,12 +118,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
    */
   serviceConfigTags: [],
 
-  /**
-   * Ajax-requests queue
-   * @type {App.ajaxQueue}
-   */
-  ajaxRequestsQueue: null,
-
   /**
    * Is cluster security enabled
    * @type {bool}
@@ -153,12 +154,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
     return this.get('content.services').filterProperty('isInstalled');
   }.property('content.services').cacheable(),
 
-  /**
-   * Ajax-requests count
-   * @type {number}
-   */
-  ajaxQueueLength: 0,
-
   /**
    * Current cluster name
    * @type {string}
@@ -964,8 +959,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
       return App.showConfirmationPopup(function () {
         self.submitProceed();
       }, Em.I18n.t('installer.step8.securityConfirmationPopupBody'));
-    }
-    else {
+    } else {
       return this.submitProceed();
     }
   },
@@ -1535,7 +1529,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
           if (service.get('serviceName') === 'MAPREDUCE' && (type === 'capacity-scheduler' || type === 'mapred-queue-acls')) {
             return;
           } else if (type === 'core-site') {
-            coreSiteObject.service_config_version_note = serviceVersionNotes
+            coreSiteObject.service_config_version_note = serviceVersionNotes;
             this.get('serviceConfigTags').pushObject(coreSiteObject);
           } else if (type === 'storm-site') {
             var obj = this.createStormSiteObj(tag);
@@ -1826,53 +1820,5 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
       }
     }, this);
     return {type: 'storm-site', tag: tag, properties: stormProperties};
-  },
-
-  /**
-   * Navigate to next step after all requests are sent
-   * @method ajaxQueueFinished
-   */
-  ajaxQueueFinished: function () {
-    console.log('everything is loaded');
-    App.router.send('next');
-  },
-
-  /**
-   * We need to do a lot of ajax calls async in special order. To do this,
-   * generate array of ajax objects and then send requests step by step. All
-   * ajax objects are stored in <code>ajaxRequestsQueue</code>
-   *
-   * @param {Object} params object with ajax-request parameters like url, type, data etc
-   * @method addRequestToAjaxQueue
-   */
-  addRequestToAjaxQueue: function (params) {
-    if (App.get('testMode')) return;
-
-    params = jQuery.extend({
-      sender: this,
-      error: 'ajaxQueueRequestErrorCallback'
-    }, params);
-    params.data['cluster'] = this.get('clusterName');
-
-    this.get('ajaxRequestsQueue').addRequest(params);
-  },
-
-  /**
-   * Error callback for each queued ajax-request
-   * @param {object} xhr
-   * @param {string} status
-   * @param {string} error
-   * @method ajaxQueueRequestErrorCallback
-   */
-  ajaxQueueRequestErrorCallback: function (xhr, status, error) {
-    var responseText = JSON.parse(xhr.responseText);
-    var controller = App.router.get(App.clusterStatus.wizardControllerName);
-    controller.registerErrPopup(Em.I18n.t('common.error'), responseText.message);
-    this.set('hasErrorOccurred', true);
-    // an error will break the ajax call chain and allow submission again
-    this.set('isSubmitDisabled', false);
-    this.set('isBackBtnDisabled', false);
-    App.router.get(this.get('content.controllerName')).setStepsEnable();
   }
-
 });

+ 198 - 1
ambari-web/app/data/HDP2/site_properties.js

@@ -2159,7 +2159,204 @@ module.exports =
       "index": 0
     },
 
-
+  /********************************************* kerberos ********************************/
+    {
+      "id": "puppet var",
+      "name": "kdc_type",
+      "displayName": "KDC type",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "masterHost",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "kdc_host",
+      "displayName": "KDC host",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "admin_server_host",
+      "displayName": "Kadmin host",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "realm",
+      "displayName": "Realm name",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 2
+    },
+    {
+      "id": "puppet var",
+      "name": "domains",
+      "displayName": "Domains",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 3
+    },
+    {
+      "id": "puppet var",
+      "name": "test_principal",
+      "displayName": "Test principal",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 4
+    },
+    {
+      "id": "puppet var",
+      "name": "test_password",
+      "displayName": "Test password",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 5
+    },
+    {
+      "id": "puppet var",
+      "name": "test_keytab",
+      "displayName": "Test keytab",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 5
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "krb5-conf directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "Advanced krb5-conf",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "krb5-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "Advanced krb5-conf",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "kadm5-acl directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "kadm5-acl.xml",
+      "category": "Advanced kadm5-acl",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "kadm5-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "kadm5-acl.xml",
+      "category": "Advanced kadm5-acl",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "kdc-conf directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "kdc-conf.xml",
+      "category": "Advanced kdc-conf",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "kdc-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "kdc-conf.xml",
+      "category": "Advanced kdc-conf",
+      "index": 1
+    },
   /********************************************* flume-agent *****************************/
     {
       "id": "site property",

+ 34 - 2
ambari-web/app/messages.js

@@ -154,6 +154,7 @@ Em.I18n.translations = {
   'common.upgrade': 'Upgrade',
   'common.reUpgrade': 'Retry Upgrade',
   'common.security':'Security',
+  'common.kerberos':'Kerberos',
   'common.cluster':'Cluster',
   'common.repositories':'Repositories',
   'common.stack.versions':'Stack Versions',
@@ -237,6 +238,7 @@ Em.I18n.translations = {
   'common.unknown': "Unknown",
   'common.install': "Install",
   'common.alertDefinition': "Alert Definition",
+  'common.prerequisites': 'Prerequisites',
 
   'passiveState.turnOn':'Turn On Maintenance Mode',
   'passiveState.turnOff':'Turn Off Maintenance Mode',
@@ -861,6 +863,10 @@ Em.I18n.translations = {
   'alerts.definition.details.notification': 'Notification',
   'alerts.definition.details.noAlerts': 'No alert instances to show',
 
+
+  'wizard.progressPage.notice.completed':'Please proceed to the next step.',
+  'wizard.progressPage.notice.failed':'You can click on the Retry button to retry failed tasks.',
+
   'admin.advanced.caution':'This section is for advanced user only.<br/>Proceed with caution.',
   'admin.advanced.button.uninstallIncludingData':'Uninstall cluster including all data.',
   'admin.advanced.button.uninstallKeepData':'Uninstall cluster but keep data.',
@@ -893,6 +899,34 @@ Em.I18n.translations = {
   'admin.authentication.form.test.success':'The configuration passes the test',
   'admin.authentication.form.test.fail':'The configuration fails the test',
 
+  'admin.kerberos.wizard.configuration.note': 'This is the initial configuration created by Enable Kerberos wizard.',
+  'admin.kerberos.wizard.header':'Enable Kerberos Wizard',
+  'admin.kerberos.button.enable': 'Enable Kerberos',
+  'admin.kerberos.wizard.step1.header': 'Get Started',
+  'admin.kerberos.wizard.step2.header': 'Configure Kerberos',
+  'admin.kerberos.wizard.step3.header': 'Install and Test Kerberos',
+  'admin.kerberos.wizard.step4.header': 'Configure Identities',
+  'admin.kerberos.wizard.step5.header': 'Kerberize Cluster',
+  'admin.kerberos.wizard.step6.header': 'Test Services',
+  'admin.kerberos.wizard.step1.info.body': 'Welcome to the Ambari Security Wizard. Use this wizard to enable kerberos security in your cluster. </br>Let\'s get started.',
+  'admin.kerberos.wizard.step1.alert.body': 'Note: This process requires services to be restarted and cluster downtime. As well, depending on the options you select, might require support from your Security administrators. Please plan accordingly.',
+  'admin.kerberos.wizard.step1.body.text': 'What type of KDC do you plan on using?',
+  'admin.kerberos.wizard.step1.option.kdc': 'Existing MIT KDC',
+  'admin.kerberos.wizard.step1.option.kdc.condition.1': 'An administrative principal is created in the MIT KDC to be shared with Ambari when prompted.',
+  'admin.kerberos.wizard.step1.option.kdc.condition.2': 'Java Cryptography Extension (JCE) is installed on all hosts.',
+  'admin.kerberos.wizard.step1.option.ad': 'Existing Active Directory',
+  'admin.kerberos.wizard.step1.option.ad.condition.1': 'An administrative principal is created in the Active Directory to be shared with Ambari when prompted.',
+  'admin.kerberos.wizard.step1.option.ad.condition.2': 'Java Cryptography Extension (JCE) is installed on all hosts.',
+  'admin.kerberos.wizard.step1.prerequisites.label': 'Following prerequisites needs to be checked to progress ahead in the wizard.',
+  'admin.kerberos.wizard.step2.info.body': 'Please configure kerberos related properties.',
+  'admin.kerberos.wizard.step3.task0.title': 'Install Kerberos',
+  'admin.kerberos.wizard.step3.task1.title': 'Test Kerberos',
+  'admin.kerberos.wizard.step3.notice.inProgress': 'Please wait while kerberos service is being installed and tested.',
+  'admin.kerberos.wizard.step3.notice.completed': 'Kerberos service has been installed and tested successfully.',
+  'admin.kerberos.wizard.progressPage.notice.inProgress': 'Please wait while cluster is being kerberized',
+  'admin.kerberos.wizard.step4.info.body': 'Configure principal name and keytab location for service users and hadoop service components.',
+  'admin.kerberos.wizard.step6.notice.completed': 'Cluster has been successfully kerberized.',
+
   'admin.highAvailability':' High Availability',
   'admin.highAvailability.button.enable':'Enable NameNode HA',
   'admin.highAvailability.button.disable':'Disable NameNode HA',
@@ -915,8 +949,6 @@ Em.I18n.translations = {
 
   'admin.highAvailability.wizard.header':'Enable NameNode HA Wizard',
   'admin.highAvailability.wizard.progressPage.notice.inProgress':'Please wait while NameNode HA is being deployed.',
-  'admin.highAvailability.wizard.progressPage.notice.completed':'Please proceed to the next step.',
-  'admin.highAvailability.wizard.progressPage.notice.failed':'You can click on the Retry button to retry failed tasks.',
   'admin.highAvailability.wizard.progressPage.header':'Deploy',
   'admin.highAvailability.wizard.step1.header':'Get Started',
   'admin.highAvailability.wizard.step1.nameserviceid.tooltip.title':'Nameservice ID',

+ 4 - 0
ambari-web/app/mixins.js

@@ -26,5 +26,9 @@ require('mixins/common/serverValidator');
 require('mixins/common/table_server_view_mixin');
 require('mixins/common/table_server_mixin');
 require('mixins/main/host/details/host_components/decommissionable');
+require('mixins/wizard/wizardProgressPageController');
+require('mixins/wizard/wizardDeployProgressController');
+require('mixins/wizard/wizardProgressPageView');
+require('mixins/wizard/wizardDeployProgressView');
 require('mixins/wizard/selectHost');
 require('mixins/wizard/addSecurityConfigs');

+ 94 - 0
ambari-web/app/mixins/wizard/wizardDeployProgressController.js

@@ -0,0 +1,94 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard controller for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardDeployProgressControllerMixin = Em.Mixin.create({
+
+  /**
+   * Ajax-requests count
+   * @type {number}
+   */
+  ajaxQueueLength: 0,
+
+  /**
+   * Ajax-requests queue
+   * @type {App.ajaxQueue}
+   */
+  ajaxRequestsQueue: null,
+
+  /**
+   * This flag when turned to true launches deploy progress bar
+   */
+  isDeployStarted: '',
+
+
+  /**
+   * We need to do a lot of ajax calls async in special order. To do this,
+   * generate array of ajax objects and then send requests step by step. All
+   * ajax objects are stored in <code>ajaxRequestsQueue</code>
+   *
+   * @param {Object} params object with ajax-request parameters like url, type, data etc
+   * @method addRequestToAjaxQueue
+   */
+  addRequestToAjaxQueue: function (params) {
+    if (App.get('testMode')) return;
+
+    params = jQuery.extend({
+      sender: this,
+      error: 'ajaxQueueRequestErrorCallback'
+    }, params);
+    params.data['cluster'] = this.get('clusterName');
+
+    this.get('ajaxRequestsQueue').addRequest(params);
+  },
+
+  /**
+   * Navigate to next step after all requests are sent
+   * @method ajaxQueueFinished
+   */
+  ajaxQueueFinished: function () {
+    console.log('everything is loaded');
+    App.router.send('next');
+  },
+
+  /**
+   * Error callback for each queued ajax-request
+   * @param {object} xhr
+   * @param {string} status
+   * @param {string} error
+   * @method ajaxQueueRequestErrorCallback
+   */
+  ajaxQueueRequestErrorCallback: function (xhr, status, error) {
+    var responseText = JSON.parse(xhr.responseText);
+    var controller = App.router.get(App.clusterStatus.wizardControllerName);
+    controller.registerErrPopup(Em.I18n.t('common.error'), responseText.message);
+    this.set('hasErrorOccurred', true);
+    // an error will break the ajax call chain and allow submission again
+    this.set('isSubmitDisabled', false);
+    this.set('isBackBtnDisabled', false);
+    App.router.get(this.get('content.controllerName')).setStepsEnable();
+  }
+});
+
+

+ 96 - 0
ambari-web/app/mixins/wizard/wizardDeployProgressView.js

@@ -0,0 +1,96 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard view for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardDeployProgressViewMixin = Em.Mixin.create({
+
+  /**
+   * Should ajax-queue progress bar be displayed
+   * @method showLoadingIndicator
+   */
+  showLoadingIndicator: function () {
+    if (!this.get('controller.isSubmitDisabled') || App.get('testMode')) {
+      if (this.get('modalPopup')) {
+        this.get('modalPopup').hide();
+        this.set('modalPopup', null);
+      }
+      return;
+    }
+    // don't create popup if it already exists
+    if (this.get('modalPopup')) {
+      return;
+    }
+    this.set('modalPopup', App.ModalPopup.show({
+
+      header: '',
+
+      showFooter: false,
+
+      showCloseButton: false,
+
+      bodyClass: Em.View.extend({
+
+        templateName: require('templates/wizard/step8/step8_log_popup'),
+
+        controllerBinding: 'App.router.wizardStep8Controller',
+
+        /**
+         * Css-property for progress-bar
+         * @type {string}
+         */
+        barWidth: '',
+
+        /**
+         * Popup-message
+         * @type {string}
+         */
+        message: '',
+
+        /**
+         * Set progress bar width and popup message when ajax-queue requests are proccessed
+         * @method ajaxQueueChangeObs
+         */
+        ajaxQueueChangeObs: function () {
+          var length = this.get('controller.ajaxQueueLength');
+          var left = this.get('controller.ajaxRequestsQueue.queue.length');
+          this.set('barWidth', 'width: ' + ((length - left) / length * 100) + '%;');
+          this.set('message', Em.I18n.t('installer.step8.deployPopup.message').format((length - left), length));
+        }.observes('controller.ajaxQueueLength', 'controller.ajaxRequestsQueue.queue.length'),
+
+        /**
+         * Hide popup when ajax-queue is finished
+         * @method autoHide
+         */
+        autoHide: function () {
+          if (this.get('controller.servicesInstalled')) {
+            this.get('parentView').hide();
+          }
+        }.observes('controller.servicesInstalled')
+      })
+
+    }));
+  }.observes('controller.isDeployStarted')
+
+});
+

+ 364 - 0
ambari-web/app/mixins/wizard/wizardProgressPageController.js

@@ -0,0 +1,364 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard controller for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardProgressPageControllerMixin = Em.Mixin.create({
+  controllerName: '',
+  clusterDeployState: 'WIZARD_DEPLOY',
+  status: 'IN_PROGRESS',
+  tasks: [],
+  commands: [],
+  currentRequestIds: [], //todo: replace with using requestIds from tasks
+  logs: [],
+  currentTaskId: null,
+  POLL_INTERVAL: 4000,
+  isSubmitDisabled: true,
+  isBackButtonDisabled: true,
+  /**
+   *  tasksMessagesPrefix should be overloaded by any controller including the mixin
+   */
+  tasksMessagesPrefix: '',
+
+  loadStep: function () {
+    this.clearStep();
+    this.initializeTasks();
+    this.loadTasks();
+    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
+    this.onTaskStatusChange();
+  },
+
+  clearStep: function () {
+    this.set('isSubmitDisabled', true);
+    this.set('isBackButtonDisabled', true);
+    this.set('tasks', []);
+    this.set('currentRequestIds', []);
+  },
+
+  initializeTasks: function () {
+    var commands = this.get('commands');
+    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
+    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
+    for (var i = 0; i < commands.length; i++) {
+      this.get('tasks').pushObject(Ember.Object.create({
+        title: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        status: 'PENDING',
+        id: i,
+        command: commands[i],
+        showRetry: false,
+        showRollback: false,
+        name: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        displayName: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        progress: 0,
+        isRunning: false,
+        requestIds: []
+      }));
+    }
+  },
+
+  loadTasks: function () {
+    var self = this;
+    var loadedStatuses = this.get('content.tasksStatuses');
+    var loadedRequestIds = this.get('content.tasksRequestIds');
+    if (loadedStatuses && loadedStatuses.length === this.get('tasks').length) {
+      this.get('tasks').forEach(function (task, i) {
+        self.setTaskStatus(task.get('id'), loadedStatuses[i]);
+        self.setRequestIds(task.get('id'), loadedRequestIds[i]);
+      });
+      if (loadedStatuses.contains('IN_PROGRESS')) {
+        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('IN_PROGRESS')].get('id');
+        this.set('currentRequestIds', this.get('content.requestIds'));
+        this.set('currentTaskId', curTaskId);
+        this.doPolling();
+      } else if (loadedStatuses.contains('QUEUED')) {
+        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('QUEUED')].get('id');
+        this.set('currentTaskId', curTaskId);
+        this.runTask(curTaskId);
+      }
+    }
+  },
+
+  setTaskStatus: function (taskId, status) {
+    this.get('tasks').findProperty('id', taskId).set('status', status);
+  },
+
+  setRequestIds: function (taskId, requestIds) {
+    this.get('tasks').findProperty('id', taskId).set('requestIds', requestIds);
+  },
+
+  retryTask: function () {
+    var task = this.get('tasks').findProperty('status', 'FAILED');
+    task.set('showRetry', false);
+    task.set('showRollback', false);
+    task.set('status', 'PENDING');
+  },
+
+  onTaskStatusChange: function () {
+    var statuses = this.get('tasks').mapProperty('status');
+    var tasksRequestIds = this.get('tasks').mapProperty('requestIds');
+    var requestIds = this.get('currentRequestIds');
+    // save task info
+    App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
+    App.router.get(this.get('content.controllerName')).saveTasksRequestIds(tasksRequestIds);
+    App.router.get(this.get('content.controllerName')).saveRequestIds(requestIds);
+    // call saving of cluster status asynchronous
+    // synchronous executing cause problems in Firefox
+    App.clusterStatus.setClusterStatus({
+      clusterName: App.router.getClusterName(),
+      clusterState: this.get('clusterDeployState'),
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    }, {successCallback: this.statusChangeCallback, sender: this});
+  },
+
+  /**
+   * Method that called after saving persist data to server.
+   * Switch task according its status.
+   */
+  statusChangeCallback: function () {
+    if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
+      var nextTask = this.get('tasks').findProperty('status', 'PENDING');
+      if (nextTask) {
+        this.set('status', 'IN_PROGRESS');
+        this.setTaskStatus(nextTask.get('id'), 'QUEUED');
+        this.set('currentTaskId', nextTask.get('id'));
+        this.runTask(nextTask.get('id'));
+      } else {
+        this.set('status', 'COMPLETED');
+        this.set('isSubmitDisabled', false);
+        this.set('isBackButtonDisabled', false);
+      }
+    } else if (this.get('tasks').someProperty('status', 'FAILED')) {
+      this.set('status', 'FAILED');
+      this.set('isBackButtonDisabled', false);
+      this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
+      if (App.supports.autoRollbackHA) {
+        this.get('tasks').findProperty('status', 'FAILED').set('showRollback', true);
+      }
+    }
+    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRetry', false);
+    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRollback', false);
+  },
+
+  /**
+   * Run command of appropriate task
+   */
+  runTask: function (taskId) {
+    this[this.get('tasks').findProperty('id', taskId).get('command')]();
+  },
+
+  onTaskError: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'FAILED');
+  },
+
+  onTaskCompleted: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
+  },
+
+  /**
+   * check whether component installed on specified hosts
+   * @param componentName
+   * @param hostNames
+   * @return {$.ajax}
+   */
+  checkInstalledComponents: function (componentName, hostNames) {
+    return App.ajax.send({
+      name: 'host_component.installed.on_hosts',
+      sender: this,
+      data: {
+        componentName: componentName,
+        hostNames: hostNames.join(',')
+      },
+      success: 'checkInstalledComponentsSuccessCallback'
+    });
+  },
+
+  checkInstalledComponentsSuccessCallback: function (data, opt, params) {
+    installedComponents = data.items;
+  },
+
+  createComponent: function (componentName, hostName, serviceName) {
+    var hostNames = (Array.isArray(hostName)) ? hostName : [hostName];
+    var self = this;
+
+    this.checkInstalledComponents(componentName, hostNames).complete(function () {
+      var result = [];
+
+      hostNames.forEach(function (hostName) {
+        result.push({
+          componentName: componentName,
+          hostName: hostName,
+          hasComponent: installedComponents.someProperty('HostRoles.host_name', hostName)
+        });
+      });
+
+      result.forEach(function (host, index, array) {
+        if (!host.hasComponent) {
+          App.ajax.send({
+            name: 'admin.high_availability.create_component',
+            sender: this,
+            data: {
+              hostName: host.hostName,
+              componentName: host.componentName,
+              serviceName: serviceName,
+              taskNum: array.length
+            },
+            success: 'onCreateComponent',
+            error: 'onCreateComponentError'
+          });
+        } else {
+          // Simulates format returned from ajax.send
+          this.onCreateComponent(null, null, {hostName: host.hostName, componentName: host.componentName, taskNum: array.length});
+        }
+      }, self)
+    });
+  },
+
+  onCreateComponent: function () {
+    var hostName = arguments[2].hostName;
+    var componentName = arguments[2].componentName;
+    var taskNum = arguments[2].taskNum;
+    var serviceName = arguments[2].serviceName;
+    this.updateComponent(componentName, hostName, serviceName, "Install", taskNum);
+  },
+
+  onCreateComponentError: function (error) {
+    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException') !== -1) {
+      this.onCreateComponent();
+    } else {
+      this.onTaskError();
+    }
+  },
+
+  updateComponent: function (componentName, hostName, serviceName, context, taskNum) {
+    if (!(hostName instanceof Array)) {
+      hostName = [hostName];
+    }
+    var state = context.toLowerCase() == "start" ? "STARTED" : "INSTALLED";
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'common.host.host_component.update',
+        sender: this,
+        data: {
+          context: context + " " + App.format.role(componentName),
+          hostName: hostName[i],
+          serviceName: serviceName,
+          componentName: componentName,
+          taskNum: taskNum || hostName.length,
+          HostRoles: {
+            state: state
+          }
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  startPolling: function (data) {
+    if (data) {
+      this.get('currentRequestIds').push(data.Requests.id);
+      var tasksCount = arguments[2].taskNum || 1;
+      if (tasksCount === this.get('currentRequestIds').length) {
+        this.setRequestIds(this.get('currentTaskId'), this.get('currentRequestIds'));
+        this.doPolling();
+      }
+    } else {
+      this.onTaskCompleted();
+    }
+  },
+
+  doPolling: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
+    var requestIds = this.get('currentRequestIds');
+    this.set('logs', []);
+    for (var i = 0; i < requestIds.length; i++) {
+      App.ajax.send({
+        name: 'admin.high_availability.polling',
+        sender: this,
+        data: {
+          requestId: requestIds[i]
+        },
+        success: 'parseLogs',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  parseLogs: function (logs) {
+    this.get('logs').pushObject(logs.tasks);
+    if (this.get('currentRequestIds').length === this.get('logs').length) {
+      var tasks = [];
+      this.get('logs').forEach(function (logs) {
+        tasks.pushObjects(logs);
+      }, this);
+      var self = this;
+      var currentTaskId = this.get('currentTaskId');
+      if (!tasks.someProperty('Tasks.status', 'PENDING') && !tasks.someProperty('Tasks.status', 'QUEUED') && !tasks.someProperty('Tasks.status', 'IN_PROGRESS')) {
+        this.set('currentRequestIds', []);
+        if (tasks.someProperty('Tasks.status', 'FAILED') || tasks.someProperty('Tasks.status', 'TIMEDOUT') || tasks.someProperty('Tasks.status', 'ABORTED')) {
+          this.setTaskStatus(currentTaskId, 'FAILED');
+        } else {
+          this.setTaskStatus(currentTaskId, 'COMPLETED');
+        }
+      } else {
+        var actionsPerHost = tasks.length;
+        var completedActions = tasks.filterProperty('Tasks.status', 'COMPLETED').length
+          + tasks.filterProperty('Tasks.status', 'FAILED').length
+          + tasks.filterProperty('Tasks.status', 'ABORTED').length
+          + tasks.filterProperty('Tasks.status', 'TIMEDOUT').length;
+        var queuedActions = tasks.filterProperty('Tasks.status', 'QUEUED').length;
+        var inProgressActions = tasks.filterProperty('Tasks.status', 'IN_PROGRESS').length;
+        var progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsPerHost * 100);
+        this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
+        window.setTimeout(function () {
+          self.doPolling()
+        }, self.POLL_INTERVAL);
+      }
+    }
+  },
+
+  showHostProgressPopup: function (event) {
+    var popupTitle = event.contexts[0].title;
+    var requestIds = event.contexts[0].requestIds;
+    var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
+    hostProgressPopupController.initPopup(popupTitle, requestIds, this, true);
+  },
+
+  done: function () {
+    if (!this.get('isSubmitDisabled')) {
+      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
+      App.router.send('next');
+    }
+  },
+
+  back: function () {
+    if (!this.get('isBackButtonDisabled')) {
+      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
+      App.router.send('back');
+    }
+  }
+
+});
+
+

+ 121 - 0
ambari-web/app/mixins/wizard/wizardProgressPageView.js

@@ -0,0 +1,121 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard view for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardProgressPageViewMixin = Em.Mixin.create({
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+
+  currentStep: '',
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+
+  headerTitle: function () {
+
+  }.property(),
+
+  submitButtonText: Em.I18n.t('common.next'),
+
+  noticeCompleted: Em.I18n.t('wizard.progressPage.notice.completed'),
+
+  noticeFailed: Em.I18n.t('wizard.progressPage.notice.failed'),
+
+  /**
+   * @noticeInProgress: Following computed property needs to be overridden to show the label text while the commands
+   * on the page are progressing
+   */
+  noticeInProgress: function () {
+
+  }.property(),
+
+  /**
+   * @showBackButton: Override this property to show back button on the wizard progress page
+   */
+  showBackButton: false,
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+  notice: '',
+
+  noticeClass: 'alert alert-info',
+
+  onStatusChange: function () {
+    var status = this.get('controller.status');
+    if (status === 'COMPLETED') {
+      this.set('notice', this.get('noticeCompleted'));
+      this.set('noticeClass', 'alert alert-success');
+    } else if (status === 'FAILED') {
+      this.set('notice', this.get('noticeFailed'));
+      this.set('noticeClass', 'alert alert-error');
+    } else {
+      this.set('notice', this.get('noticeInProgress'));
+      this.set('noticeClass', 'alert alert-info');
+    }
+  }.observes('controller.status'),
+
+  taskView: Em.View.extend({
+    icon: '',
+    iconColor: '',
+    linkClass: '',
+
+    didInsertElement: function () {
+      this.onStatus();
+    },
+
+    barWidth: function () {
+      return 'width: ' + this.get('content.progress') + '%;';
+    }.property('content.progress'),
+
+    onStatus: function () {
+      var linkClass = !!this.get('content.requestIds.length') ? 'active-link' : 'active-text';
+      this.set('linkClass', linkClass);
+      if (this.get('content.status') === 'IN_PROGRESS') {
+        this.set('icon', 'icon-cog');
+        this.set('iconColor', 'text-info');
+      } else if (this.get('content.status') === 'FAILED') {
+        this.set('icon', 'icon-exclamation-sign');
+        this.set('iconColor', 'text-error');
+      } else if (this.get('content.status') === 'COMPLETED') {
+        this.set('icon', 'icon-ok');
+        this.set('iconColor', 'text-success');
+      } else {
+        this.set('icon', 'icon-cog');
+        this.set('iconColor', '');
+        this.set('linkClass', 'not-active-link');
+      }
+    }.observes('content.status', 'content.hosts.length'),
+
+    showProgressBar: function () {
+      return this.get('content.status') === "IN_PROGRESS";
+    }.property('content.status')
+  })
+
+});
+
+

+ 6 - 1
ambari-web/app/models/stack_service.js

@@ -153,7 +153,7 @@ App.StackService = DS.Model.extend({
     var configTypes = this.get('configTypes');
     var serviceComponents = this.get('serviceComponents');
     if (configTypes && Object.keys(configTypes).length) {
-      var pattern = ["MetricsSink", "General", "CapacityScheduler", "FaultTolerance", "Isolation", "Performance", "^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
+      var pattern = ["MetricsSink", "General", "CapacityScheduler", "FaultTolerance", "Isolation", "Performance", "KDC","^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
       configCategories = App.StackService.configCategories.call(this).filter(function (_configCategory) {
         var serviceComponentName = _configCategory.get('name');
         var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
@@ -335,6 +335,11 @@ App.StackService.configCategories = function () {
         App.ServiceConfigCategory.create({ name: 'KAFKA_BROKER', displayName: 'Kafka Broker'})
       ]);
       break;
+    case 'KERBEROS':
+      serviceConfigCategories.pushObjects([
+        App.ServiceConfigCategory.create({ name: 'KDC', displayName: 'KDC and Kadmin'})
+      ]);
+      break;
     case 'PIG':
       break;
     case 'SQOOP':

+ 3 - 0
ambari-web/app/router.js

@@ -322,6 +322,9 @@ App.Router = Em.Router.extend({
           } else if (clusterStatusOnServer && (clusterStatusOnServer.wizardControllerName === App.router.get('addSecurityController.name') || clusterStatusOnServer.wizardControllerName === App.router.get('mainAdminSecurityDisableController.name'))) {
             // if wizardControllerName == "addSecurityController", then it means someone closed the browser or the browser was crashed when we were last in Add Security wizard
             route = 'main.admin.adminSecurity';
+          } else if (clusterStatusOnServer && (clusterStatusOnServer.wizardControllerName === App.router.get('kerberosWizardController.name'))) {
+            // if wizardControllerName == "adminKerberosController", then it means someone closed the browser or the browser was crashed when we were last in Add Kerberos wizard
+            route = 'main.admin.adminKerberos';
           } else if (clusterStatusOnServer && clusterStatusOnServer.wizardControllerName === App.router.get('addServiceController.name')) {
             // if wizardControllerName == "addHostController", then it means someone closed the browser or the browser was crashed when we were last in Add Hosts wizard
             route = 'main.serviceAdd';

+ 255 - 0
ambari-web/app/routes/add_kerberos_routes.js

@@ -0,0 +1,255 @@
+/**
+ * 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.
+ */
+var App = require('app');
+
+module.exports = App.WizardRoute.extend({
+  route: '/enable',
+  enter: function (router) {
+    Em.run.next(function () {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      App.router.get('updateController').set('isWorking', false);
+      var popup = App.ModalPopup.show({
+        classNames: ['full-width-modal'],
+        header: Em.I18n.t('admin.kerberos.wizard.header'),
+        bodyClass: App.KerberosWizardView.extend({
+          controller: kerberosWizardController
+        }),
+        primary: Em.I18n.t('form.cancel'),
+        showFooter: false,
+        secondary: null,
+
+        onClose: function () {
+          var self = this;
+          var kerberosProgressPageController = App.router.get('kerberosProgressPageController');
+          var controller = App.router.get('kerberosWizardController');
+          controller.clearTasksData();
+          controller.finish();
+          App.router.get('updateController').set('isWorking', true);
+          if(App.get('testMode')){
+            App.router.transitionTo('adminKerberos.index');
+            location.reload();
+          }
+          App.clusterStatus.setClusterStatus({
+            clusterName: App.router.getClusterName(),
+            clusterState: 'DEFAULT',
+            localdb: App.db.data
+          }, {alwaysCallback: function () {
+            self.hide();
+            App.router.transitionTo('adminKerberos.index');
+          }});
+
+        },
+        didInsertElement: function () {
+          this.fitHeight();
+        }
+      });
+      kerberosWizardController.set('popup', popup);
+      var currentClusterStatus = App.clusterStatus.get('value');
+      if (currentClusterStatus) {
+        if (App.testMode) {
+          kerberosWizardController.setCurrentStep(App.db.data.KerberosWizard.currentStep);
+        } else {
+          switch (currentClusterStatus.clusterState) {
+            case 'KERBEROS_DEPLOY' :
+              kerberosWizardController.setCurrentStep(currentClusterStatus.localdb.KerberosWizard.currentStep);
+              break;
+            default:
+              var currStep = App.router.get('kerberosWizardController.currentStep');
+              kerberosWizardController.setCurrentStep(currStep);
+              break;
+          }
+        }
+
+      }
+      router.transitionTo('step' + kerberosWizardController.get('currentStep'));
+    });
+  },
+
+  step1: Em.Route.extend({
+    route: '/step1',
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('1');
+    },
+
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step1:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep1', controller.get('content'));
+      })
+    },
+
+    unroutePath: function () {
+      return false;
+    },
+
+    next: function (router) {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      var kerberosStep1controller = router.get('kerberosWizardStep1Controller');
+      kerberosWizardController.saveKerberosOption(kerberosStep1controller);
+      kerberosWizardController.setDBProperty('serviceConfigProperties', null);
+      kerberosWizardController.setDBProperty('advancedServiceConfig', null);
+      router.transitionTo('step2');
+    }
+  }),
+
+  step2: Em.Route.extend({
+    route: '/step2',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('2');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step2:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
+        kerberosWizardStep2Controller.set('wizardController', controller);
+        controller.connectOutlet('kerberosWizardStep2', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step1'),
+    next: function (router) {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
+      kerberosWizardController.saveServiceConfigProperties(kerberosWizardStep2Controller);
+      kerberosWizardController.clearTasksData();
+      router.transitionTo('step3');
+    }
+  }),
+  step3: Em.Route.extend({
+    route: '/step3',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('3');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step3:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep3', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step2'),
+    next: function (router) {
+      // load kerberos descriptor for all services
+      router.transitionTo('step4');
+    }
+  }),
+
+  step4: Em.Route.extend({
+    route: '/step4',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('4');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step4:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep4', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step3'),
+    next: function (router) {
+      router.transitionTo('step5');
+    }
+  }),
+
+  step5: Em.Route.extend({
+    route: '/step5',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('5');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step5:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step4'),
+    next: function (router) {
+      router.transitionTo('step6');
+    }
+  }),
+
+  step6: Em.Route.extend({
+    route: '/step6',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('6');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step6:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      var controller = router.get('kerberosWizardController');
+      controller.finish();
+      App.clusterStatus.setClusterStatus({
+        clusterName: App.router.getClusterName(),
+        clusterState: 'DEFAULT',
+        localdb: App.db.data
+      }, {alwaysCallback: function () {
+        self.hide();
+        App.router.transitionTo('adminKerberos.index');
+      }});
+
+    }
+  }),
+
+
+  gotoStep1: Em.Router.transitionTo('step1'),
+
+  gotoStep2: Em.Router.transitionTo('step2'),
+
+  gotoStep3: Em.Router.transitionTo('step3'),
+
+  gotoStep4: Em.Router.transitionTo('step4'),
+
+  gotoStep5: Em.Router.transitionTo('step5'),
+
+  gotoStep6: Em.Router.transitionTo('step6')
+
+});

+ 13 - 1
ambari-web/app/routes/main.js

@@ -408,7 +408,7 @@ module.exports = Em.Route.extend({
         }
       },
 
-      index: Ember.Route.extend({
+      index: Em.Route.extend({
         route: '/',
         connectOutlets: function (router, context) {
           var controller = router.get('mainAdminController');
@@ -499,6 +499,18 @@ module.exports = Em.Route.extend({
       adminAddSecurity: require('routes/add_security')
     }),
 
+    adminKerberos: Em.Route.extend({
+      route: '/kerberos',
+      index: Em.Route.extend({
+        route: '/',
+        connectOutlets: function (router, context) {
+          router.set('mainAdminController.category', "kerberos");
+          router.get('mainAdminController').connectOutlet('mainAdminKerberos');
+        }
+      }),
+      adminAddKerberos:  require('routes/add_kerberos_routes')
+    }),
+
     stackAndUpgrade: Em.Route.extend({
       route: '/stack',
       connectOutlets: function (router) {

+ 4 - 1
ambari-web/app/templates/main/admin/highAvailability/progress.hbs

@@ -22,7 +22,7 @@
   {{#each task in controller.tasks}}
   {{#view view.taskView contentBinding="task"}}
     <div class="item">
-      <div {{bindAttr class=":pull-left view.linkClass controller.isHA:span4 controller.isRMHA:span5 controller.isRollback:span3 controller.isReassign:span5"}}>
+      <div {{bindAttr class=":pull-left view.linkClass isKerberosWizard:span4 controller.isHA:span4 controller.isRMHA:span5 controller.isRollback:span3 controller.isReassign:span5"}}>
         <i {{bindAttr class="view.icon view.iconColor"}}></i>
         <a {{action "showHostProgressPopup" task target="controller"}} >{{task.title}}</a>
       </div>
@@ -58,6 +58,9 @@
   {{/view}}
   {{/each}}
   <div class="btn-area">
+    {{#if view.showBackButton}}
+       <button class="btn pull-left" {{bindAttr disabled="controller.isBackButtonDisabled"}} {{action back target="controller"}}>&larr; {{t common.back}}</button>
+    {{/if}}
     <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{view.submitButtonText}}</button>
   </div>
 </div>

+ 36 - 0
ambari-web/app/templates/main/admin/kerberos.hbs

@@ -0,0 +1,36 @@
+{{!
+* 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.
+}}
+{{#if dataIsLoaded}}
+  {{#if securityEnabled}}
+    <div>
+      <p class="text-success">{{t admin.security.enabled}}
+        <a class="btn btn-padding btn-warning" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.security.button.disable}} </a>
+        <br/>
+      </p>
+    </div>
+  {{else}}
+    <div>
+      <p class="muted">{{t admin.security.disabled}}
+        <a class="btn btn-padding btn-success" {{action startKerberosWizard target="controller"}}>{{t admin.kerberos.button.enable}} </a>
+        <br/>
+      </p>
+    </div>
+  {{/if}}
+{{else}}
+  <div class="spinner"></div>
+{{/if}}

+ 47 - 0
ambari-web/app/templates/main/admin/kerberos/step1.hbs

@@ -0,0 +1,47 @@
+{{!
+* 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.
+}}
+
+<h2>{{t admin.kerberos.wizard.step1.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.kerberos.wizard.step1.info.body}}
+</p>
+<div class="alert">
+  {{t admin.kerberos.wizard.step1.alert.body}}
+</div>
+
+<div class="step1-options-body">
+  {{t admin.kerberos.wizard.step1.body.text}}
+  {{#each option in options}}
+    <label>
+      {{view Ember.RadioButton name="option.displayName" selectionBinding="selectedItem" valueBinding="option.value"}}  {{option.displayName}}
+    </label>
+  {{/each}}
+  <br/>
+</div>
+<div class="alert alert-info step1-prerequisites-body">
+  <h5>{{selectedOption.displayName}}:</h5>
+  <b>{{t admin.kerberos.wizard.step1.prerequisites.label}}</b> <br/> <br/>
+  {{#each condition in selectedOption.preConditions}}
+    <label class="checkbox"> {{view Ember.Checkbox  checkedBinding="condition.checked"}} {{condition.displayText}} </label>
+  {{/each}}
+</div>
+
+
+<div class="btn-area">
+  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action "next" target="controller"}}>{{t common.next}} &rarr;</a>
+</div>

+ 35 - 0
ambari-web/app/templates/main/admin/kerberos/step2.hbs

@@ -0,0 +1,35 @@
+{{!
+* 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.
+}}
+
+<div id="serviceConfig">
+  <h2>{{t admin.kerberos.wizard.step2.header}}</h2>
+  <div class="alert alert-info">
+    {{t admin.kerberos.wizard.step2.info.body}}
+  </div>
+  {{#if isConfigsLoaded}}
+    {{view App.ServicesConfigView}}
+  {{else}}
+    <div class="spinner"></div>
+  {{/if}}
+
+  <div class="btn-area">
+    <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
+    <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+      {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
+  </div>
+</div>

+ 18 - 0
ambari-web/app/templates/main/admin/kerberos/step3.hbs

@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+{{template "templates/main/admin/highAvailability/progress"}}

+ 21 - 0
ambari-web/app/templates/main/admin/kerberos/step4.hbs

@@ -0,0 +1,21 @@
+{{!
+* 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.
+}}
+<h2>{{t admin.kerberos.wizard.step4.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.kerberos.wizard.step4.info.body}}
+</p>

+ 18 - 0
ambari-web/app/templates/main/admin/kerberos/step5.hbs

@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+<h2>{{t admin.kerberos.wizard.step5.header}}</h2>

+ 18 - 0
ambari-web/app/templates/main/admin/kerberos/step6.hbs

@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+{{template "templates/main/admin/highAvailability/progress"}}

+ 47 - 0
ambari-web/app/templates/main/admin/kerberos/wizard.hbs

@@ -0,0 +1,47 @@
+{{!
+* 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.
+}}
+
+<div class="wizard">
+  <div class="container">
+    <div class="container-fluid">
+      <div class="row-fluid">
+        <div class="span3">
+          <!--Sidebar content-->
+          <div class="well">
+            <ul class="nav nav-pills nav-stacked">
+              <li class="nav-header"> <i class="icon-lock"></i>&nbsp;{{t admin.kerberos.wizard.header}}</li>
+              <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t admin.kerberos.wizard.step1.header}}</a></li>
+              <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t admin.kerberos.wizard.step2.header}}</a></li>
+              <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t admin.kerberos.wizard.step3.header}}</a></li>
+              <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t admin.kerberos.wizard.step4.header}}</a></li>
+              <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t admin.kerberos.wizard.step5.header}}</a></li>
+              <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t admin.kerberos.wizard.step6.header}}</a></li>
+            </ul>
+          </div>
+        </div>
+        <div class="wizard-content well span9">
+          {{#if view.isLoaded}}
+            {{outlet}}
+          {{else}}
+            <div class="spinner"></div>
+          {{/if}}
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 28 - 5
ambari-web/app/utils/ajax/ajax.js

@@ -121,7 +121,7 @@ var urls = {
 
   'common.host.host_component.update': {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}?{urlParams}',
-    'mock': '/data/wizard/deploy/poll_1.json',
+    'mock': '/data/wizard/deploy/2_hosts/poll_9.json',
     'type': 'PUT',
     'format': function (data) {
       return {
@@ -159,11 +159,11 @@ var urls = {
   },
 
   'common.across.services.configurations': {
+    'type': 'PUT',
     'real':'/clusters/{clusterName}',
-    'mock':'',
+    'mock':'/data/services/ambari.json',
     'format': function(data) {
       return {
-        type: 'PUT',
         dataType: 'text',
         data: data.data
       }
@@ -290,6 +290,11 @@ var urls = {
     'real': '/clusters/{name}',
     'type': 'DELETE'
   },
+  'common.delete.service': {
+    'real': '/clusters/{clusterName}/services/{serviceName}',
+    'mock': '/data/services/ambari.json',
+    'type': 'DELETE'
+  },
   'common.delete.request_schedule': {
     'real': '/clusters/{clusterName}/request_schedules/{request_schedule_id}',
     'type': 'DELETE'
@@ -1145,6 +1150,24 @@ var urls = {
       }
     }
   },
+  'common.create_component': {
+    'real': '/clusters/{clusterName}/services?ServiceInfo/service_name={serviceName}',
+    'mock': '',
+    'type': 'POST',
+    'format': function(data) {
+      return {
+        data: JSON.stringify({
+          "components": [
+            {
+              "ServiceComponentInfo": {
+                "component_name": data.componentName
+              }
+            }
+          ]
+        })
+      }
+    }
+  },
   'admin.high_availability.create_zkfc': {
     'real': '/clusters/{clusterName}/services?ServiceInfo/service_name=HDFS',
     'mock': '',
@@ -1321,11 +1344,11 @@ var urls = {
   },
 
   'wizard.step8.create_selected_services': {
+    'type': 'POST',
     'real':'/clusters/{cluster}/services',
-    'mock':'',
+    'mock':'/data/stacks/HDP-2.1/recommendations.json',
     'format': function(data) {
       return {
-        type: 'POST',
         dataType: 'text',
         data: data.data
       }

+ 9 - 5
ambari-web/app/utils/config.js

@@ -72,20 +72,24 @@ App.config = Em.Object.create({
     return fileName.endsWith('.xml') ? fileName.slice(0, -4) : fileName;
   },
 
-  setPreDefinedServiceConfigs: function () {
+  setPreDefinedServiceConfigs: function (isMiscTabToBeAdded) {
     var configs = this.get('preDefinedSiteProperties');
     var services = [];
-    var nonServiceTab = require('data/service_configs');
     var stackServices = App.StackService.find().filterProperty('id');
     // Only include services that has configTypes related to them for service configuration page
-    // Also Remove HCatalog from this list. HCatalog has hive-site affiliated to it but none of the properties of it should be exposed under HCatalog Service
-    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
     var servicesWithConfigTypes = stackServices.filter(function (service) {
       var configtypes = service.get('configTypes');
       return configtypes && !!Object.keys(configtypes).length;
     }, this);
 
-    var allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    var allTabs;
+    if (isMiscTabToBeAdded) {
+      var nonServiceTab = require('data/service_configs');
+      allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    } else {
+      allTabs = servicesWithConfigTypes;
+    }
+
     allTabs.forEach(function (service) {
       var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
       service.set('configs', serviceConfigs);

+ 12 - 0
ambari-web/app/utils/db.js

@@ -34,6 +34,7 @@ var InitialData =  {
   'Installer' : {},
   'AddHost' : {},
   'AddService' : {},
+  'KerberosWizard': {},
   'StackUpgrade' : {},
   'ReassignMaster' : {},
   'AddSecurity': {},
@@ -526,6 +527,12 @@ App.db.setReassignMasterWizardReassignHosts = function (reassignHosts) {
   localStorage.setObject('ambari', App.db.data);
 };
 
+App.db.setKerberosWizardConfigTag = function (tag) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.KerberosWizard[tag.name] = tag.value;
+  localStorage.setObject('ambari', App.db.data);
+};
+
 /*
  *  getter methods
  */
@@ -842,4 +849,9 @@ App.db.getReassignMasterWizardReassignHosts = function () {
   return App.db.data.ReassignMaster.reassignHosts;
 };
 
+App.db.getKerberosWizardConfigTag = function (tag) {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.KerberosWizard[tag];
+};
+
 module.exports = App.db;

+ 18 - 1
ambari-web/app/utils/ember_reopen.js

@@ -114,6 +114,23 @@ Ember.isBlank = function(obj) {
   return Ember.isEmpty(obj) || (typeof obj === 'string' && obj.match(/\S/) === null);
 };
 
+/**
+ *
+ */
+Ember.RadioButton = Ember.Checkbox.extend({
+  tagName : "input",
+  type : "radio",
+  attributeBindings : [ "type", "name", "value", "checked", "style" ],
+  style: "vertical-align: middle; margin: 0px;" ,
+  click : function() {
+    this.set("selection", this.$().val())
+  },
+  checked : function() {
+    return this.get("value") == this.get("selection");
+  }.property('value','selection')
+});
+
+
 Em.View.reopen({
   /**
    * overwritten set method of Ember.View to avoid uncaught errors
@@ -126,4 +143,4 @@ Em.View.reopen({
       console.debug('Calling set on destroyed view');
     }
   }
-});
+});

+ 11 - 0
ambari-web/app/views.js

@@ -107,6 +107,17 @@ require('views/main/admin/advanced');
 require('views/main/admin/advanced/password');
 require('views/main/admin/audit');
 require('views/main/admin/authentication');
+
+require('views/main/admin/kerberos');
+require('views/main/admin/kerberos/wizard_view');
+require('views/main/admin/kerberos/progress_view');
+require('views/main/admin/kerberos/step1_view');
+require('views/main/admin/kerberos/step2_view');
+require('views/main/admin/kerberos/step3_view');
+require('views/main/admin/kerberos/step4_view');
+require('views/main/admin/kerberos/step5_view');
+require('views/main/admin/kerberos/step6_view');
+
 require('views/main/admin/security');
 require('views/main/admin/security/disable');
 require('views/main/admin/security/add/menu');

+ 13 - 5
ambari-web/app/views/main/admin.js

@@ -41,11 +41,19 @@ App.MainAdminView = Em.View.extend({
       label: Em.I18n.t('common.serviceAccounts')
     });
     if (!App.get('isHadoopWindowsStack')) {
-      items.push({
-        name: 'security',
-        url: 'adminSecurity.index',
-        label: Em.I18n.t('common.security')
-      });
+      if (App.get('supports.automatedKerberos')) {
+        items.push({
+          name: 'kerberos',
+          url: 'adminKerberos.index',
+          label: Em.I18n.t('common.kerberos')
+        });
+      } else {
+        items.push({
+          name: 'security',
+          url: 'adminSecurity.index',
+          label: Em.I18n.t('common.security')
+        });
+      }
     }
     return items;
   }.property(''),

+ 2 - 61
ambari-web/app/views/main/admin/highAvailability/progress_view.js

@@ -19,7 +19,7 @@
 
 var App = require('app');
 
-App.HighAvailabilityProgressPageView = Em.View.extend({
+App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageViewMixin, {
 
   didInsertElement: function () {
     this.get('controller').loadStep();
@@ -34,12 +34,6 @@ App.HighAvailabilityProgressPageView = Em.View.extend({
     }
   }.property(),
 
-  submitButtonText: Em.I18n.t('common.next'),
-
-  noticeCompleted: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.completed'),
-
-  noticeFailed: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.failed'),
-
   noticeInProgress: function () {
     var currentStep = App.router.get('highAvailabilityWizardController.currentStep');
     if (currentStep == 1) {
@@ -49,58 +43,5 @@ App.HighAvailabilityProgressPageView = Em.View.extend({
     }
   }.property(),
 
-  notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress'),
-
-  noticeClass: 'alert alert-info',
-
-  onStatusChange: function () {
-    var status = this.get('controller.status');
-    if (status === 'COMPLETED') {
-      this.set('notice', this.get('noticeCompleted'));
-      this.set('noticeClass', 'alert alert-success');
-    } else if (status === 'FAILED') {
-      this.set('notice', this.get('noticeFailed'));
-      this.set('noticeClass', 'alert alert-error');
-    } else {
-      this.set('notice', this.get('noticeInProgress'));
-      this.set('noticeClass', 'alert alert-info');
-    }
-  }.observes('controller.status'),
-
-  taskView: Em.View.extend({
-    icon: '',
-    iconColor: '',
-    linkClass: '',
-
-    didInsertElement: function () {
-      this.onStatus();
-    },
-
-    barWidth: function () {
-      return 'width: ' + this.get('content.progress') + '%;';
-    }.property('content.progress'),
-
-    onStatus: function () {
-      var linkClass = !!this.get('content.requestIds.length') ? 'active-link' : 'active-text';
-      this.set('linkClass', linkClass);
-      if (this.get('content.status') === 'IN_PROGRESS') {
-        this.set('icon', 'icon-cog');
-        this.set('iconColor', 'text-info');
-      } else if (this.get('content.status') === 'FAILED') {
-        this.set('icon', 'icon-exclamation-sign');
-        this.set('iconColor', 'text-error');
-      } else if (this.get('content.status') === 'COMPLETED') {
-        this.set('icon', 'icon-ok');
-        this.set('iconColor', 'text-success');
-      } else {
-        this.set('icon', 'icon-cog');
-        this.set('iconColor', '');
-        this.set('linkClass', 'not-active-link');
-      }
-    }.observes('content.status', 'content.hosts.length'),
-
-    showProgressBar: function () {
-      return this.get('content.status') === "IN_PROGRESS";
-    }.property('content.status')
-  })
+  notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress')
 });

+ 28 - 0
ambari-web/app/views/main/admin/kerberos.js

@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.MainAdminKerberosView = Em.View.extend({
+  templateName: require('templates/main/admin/kerberos'),
+  didInsertElement: function() {
+    var controller = this.get('controller');
+    controller.set('dataIsLoaded',false);
+    controller.loadSecurityStatusFromServer();
+  }
+});

+ 39 - 0
ambari-web/app/views/main/admin/kerberos/progress_view.js

@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+
+var App = require('app');
+
+App.KerberosProgressPageView = Em.View.extend(App.wizardProgressPageViewMixin, {
+
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  },
+
+  headerTitle: function () {
+    var currentStep = App.router.get('kerberosWizardController.currentStep');
+    return  Em.I18n.t('admin.kerberos.wizard.step' + currentStep + '.header');
+  }.property(),
+
+  noticeInProgress: function () {
+    var currentStep = App.router.get('kerberosWizardController.currentStep');
+    return  Em.I18n.t('admin.kerberos.wizard.step' + currentStep + '.notice.inProgress');
+  }.property(),
+
+  notice: Em.I18n.t('admin.kerberos.wizard.progressPage.notice.inProgress')
+});

+ 44 - 0
ambari-web/app/views/main/admin/kerberos/step1_view.js

@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.KerberosWizardStep1View = Em.View.extend({
+
+  templateName: require('templates/main/admin/kerberos/step1'),
+
+  didInsertElement: function () {
+    var controller = this.get('controller');
+    controller.loadStep();
+  },
+
+  /**
+   * whenever the KDC type is changed, all checkboxes for the precondition should be unchecked
+   */
+  resetCheckBoxes: function () {
+    var options = this.get('controller.options');
+    options.forEach(function (option) {
+      option.preConditions.forEach(function (_condition) {
+        _condition.set('checked', false);
+      });
+    }, this)
+  }.observes('controller.selectedItem')
+
+});
+
+

+ 31 - 0
ambari-web/app/views/main/admin/kerberos/step2_view.js

@@ -0,0 +1,31 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+require('views/wizard/step7_view');
+
+App.KerberosWizardStep2View = App.WizardStep7View.extend({
+
+  templateName: require('templates/main/admin/kerberos/step2'),
+
+  didInsertElement: function() {
+    var controller =  this.get('controller');
+    controller.loadStep();
+  }
+});

+ 32 - 0
ambari-web/app/views/main/admin/kerberos/step3_view.js

@@ -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.
+ */
+
+
+var App = require('app');
+
+App.KerberosWizardStep3View = App.KerberosProgressPageView.extend({
+
+  templateName: require('templates/main/admin/kerberos/step3'),
+
+  noticeCompleted: Em.I18n.t('admin.kerberos.wizard.step3.notice.completed'),
+
+  submitButtonText: Em.I18n.t('common.next'),
+
+  showBackButton: true
+
+});

+ 25 - 0
ambari-web/app/views/main/admin/kerberos/step4_view.js

@@ -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.
+ */
+
+var App = require('app');
+
+App.KerberosWizardStep4View = Em.View.extend({
+
+  templateName: require('templates/main/admin/kerberos/step4')
+
+});

+ 25 - 0
ambari-web/app/views/main/admin/kerberos/step5_view.js

@@ -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.
+ */
+
+var App = require('app');
+
+App.KerberosWizardStep5View = Em.View.extend({
+
+  templateName: require('templates/main/admin/kerberos/step5')
+
+});

+ 30 - 0
ambari-web/app/views/main/admin/kerberos/step6_view.js

@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+var App = require('app');
+
+App.KerberosWizardStep6View = App.KerberosProgressPageView.extend({
+
+  templateName: require('templates/main/admin/kerberos/step6'),
+
+  noticeCompleted: Em.I18n.t('admin.kerberos.wizard.step6.notice.completed'),
+
+  submitButtonText: Em.I18n.t('common.complete'),
+
+  showBackButton: false
+
+});

+ 81 - 0
ambari-web/app/views/main/admin/kerberos/wizard_view.js

@@ -0,0 +1,81 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.KerberosWizardView = Em.View.extend({
+
+  templateName: require('templates/main/admin/kerberos/wizard'),
+
+  isStep1Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',1).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep2Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',2).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep3Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',3).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep4Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',4).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep5Disabled: true,
+
+  isStep6Disabled: true,
+
+  isLoaded: false,
+
+  willInsertElement: function () {
+    if (this.get('controller').getDBProperty('hosts')) {
+      this.set('isLoaded', true);
+    } else {
+      this.loadHosts();
+    }
+  },
+
+  loadHosts: function () {
+    App.ajax.send({
+      name: 'hosts.confirmed',
+      sender: this,
+      data: {},
+      success: 'loadHostsSuccessCallback',
+      error: 'loadHostsErrorCallback'
+    });
+  },
+
+  loadHostsSuccessCallback: function (response) {
+    var installedHostNames = [];
+
+    response.items.forEach(function (item) {
+      installedHostNames.push(item.Hosts.host_name);
+    });
+    this.get('controller').setDBProperty('hosts', installedHostNames);
+    this.set('controller.content.hosts', installedHostNames);
+    this.set('isLoaded', true);
+  },
+
+  loadHostsErrorCallback: function(){
+    this.set('isLoaded', true);
+  }
+});
+
+

+ 13 - 5
ambari-web/app/views/main/menu.js

@@ -142,11 +142,19 @@ App.MainMenuView = Em.CollectionView.extend({
           label: Em.I18n.t('common.serviceAccounts')
         });
         if (!App.get('isHadoopWindowsStack')) {
-          categories.push({
-            name: 'security',
-            url: 'security/',
-            label: Em.I18n.t('common.security')
-          });
+          if (App.get('supports.automatedKerberos')) {
+            categories.push({
+              name: 'kerberos',
+              url: 'kerberos/',
+              label: Em.I18n.t('common.kerberos')
+            });
+          } else {
+            categories.push({
+              name: 'security',
+              url: 'security/',
+              label: Em.I18n.t('common.security')
+            });
+          }
         }
       }
       return categories;

+ 2 - 69
ambari-web/app/views/wizard/step8_view.js

@@ -19,7 +19,7 @@
 
 var App = require('app');
 
-App.WizardStep8View = Em.View.extend({
+App.WizardStep8View = Em.View.extend(App.wizardDeployProgressViewMixin, {
 
   templateName: require('templates/wizard/step8'),
 
@@ -40,73 +40,6 @@ App.WizardStep8View = Em.View.extend({
    * Reference to modalPopup to make sure only one instance is created
    * @type {App.ModalPopup|null}
    */
-  modalPopup: null,
-
-  /**
-   * Should ajax-queue progress bar be displayed
-   * @method showLoadingIndicator
-   */
-  showLoadingIndicator: function () {
-    if (!this.get('controller.isSubmitDisabled') || App.get('testMode')) {
-      if (this.get('modalPopup')) {
-        this.get('modalPopup').hide();
-        this.set('modalPopup', null);
-      }
-      return;
-    }
-    // don't create popup if it already exists
-    if (this.get('modalPopup')) {
-      return;
-    }
-    this.set('modalPopup', App.ModalPopup.show({
-
-      header: '',
-
-      showFooter: false,
-
-      showCloseButton: false,
-
-      bodyClass: Em.View.extend({
-
-        templateName: require('templates/wizard/step8/step8_log_popup'),
-
-        controllerBinding: 'App.router.wizardStep8Controller',
-
-        /**
-         * Css-property for progress-bar
-         * @type {string}
-         */
-        barWidth: '',
-
-        /**
-         * Popup-message
-         * @type {string}
-         */
-        message: '',
-
-        /**
-         * Set progress bar width and popup message when ajax-queue requests are proccessed
-         * @method ajaxQueueChangeObs
-         */
-        ajaxQueueChangeObs: function () {
-          var length = this.get('controller.ajaxQueueLength');
-          var left = this.get('controller.ajaxRequestsQueue.queue.length');
-          this.set('barWidth', 'width: ' + ((length - left) / length * 100) + '%;');
-          this.set('message', Em.I18n.t('installer.step8.deployPopup.message').format((length - left), length));
-        }.observes('controller.ajaxQueueLength', 'controller.ajaxRequestsQueue.queue.length'),
-
-        /**
-         * Hide popup when ajax-queue is finished
-         * @method autoHide
-         */
-        autoHide: function () {
-          if (this.get('controller.servicesInstalled')) {
-            this.get('parentView').hide();
-          }
-        }.observes('controller.servicesInstalled')
-      })
-
-    }));
-  }.observes('controller.isSubmitDisabled')
+  modalPopup: null
 });
 

+ 1 - 0
ambari-web/package.json

@@ -13,6 +13,7 @@
     "uglify-js-brunch": ">= 1.0 < 1.5",
     "clean-css-brunch": ">= 1.0 < 1.5",
     "ember-precompiler-brunch": ">= 1.0 < 1.5",
+    "ember-radio-button": "0.1.2",
     "less-brunch": ">= 1.0 < 1.5",
     "cssstyle": "0.2.3"
   },