Bladeren bron

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

Jaimin Jetly 10 jaren geleden
bovenliggende
commit
dd87511efa
59 gewijzigde bestanden met toevoegingen van 3288 en 729 verwijderingen
  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"
   },