ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlun...@apache.org
Subject ambari git commit: AMBARI-16285 Ranger Tagsync stack changes to sync tags from Atlas (Mugdha Varadkar via jluniya)
Date Fri, 13 May 2016 21:15:01 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 14303394d -> 69b7d2742


AMBARI-16285 Ranger Tagsync stack changes to sync tags from Atlas (Mugdha Varadkar via jluniya)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/69b7d274
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/69b7d274
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/69b7d274

Branch: refs/heads/trunk
Commit: 69b7d2742895221696723f15373fe61140529f94
Parents: 1430339
Author: Jayush Luniya <jluniya@hortonworks.com>
Authored: Fri May 13 14:14:56 2016 -0700
Committer: Jayush Luniya <jluniya@hortonworks.com>
Committed: Fri May 13 14:14:56 2016 -0700

----------------------------------------------------------------------
 .../libraries/functions/constants.py            |   1 +
 .../libraries/functions/stack_features.py       |   5 +
 .../alerts/alert_ranger_admin_passwd_check.py   |   7 +-
 .../RANGER/0.4.0/package/scripts/params.py      |   9 +-
 .../0.4.0/package/scripts/ranger_tagsync.py     |  11 +-
 .../0.4.0/package/scripts/ranger_usersync.py    |  15 +-
 .../0.4.0/package/scripts/setup_ranger_xml.py   |  47 ++---
 .../HDP/2.0.6/properties/stack_features.json    |   5 +
 .../stacks/HDP/2.5/services/RANGER/alerts.json  |   4 +-
 .../configuration/ranger-tagsync-site.xml       | 139 ++++++---------
 .../RANGER/configuration/ranger-ugsync-site.xml |  18 ++
 .../tagsync-application-properties.xml          |  24 ---
 .../services/RANGER/themes/theme_version_3.json | 177 ++++++++++---------
 .../stacks/HDP/2.5/services/stack_advisor.py    |  22 ++-
 ambari-web/app/styles/widgets.less              |   1 -
 15 files changed, 235 insertions(+), 250 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-common/src/main/python/resource_management/libraries/functions/constants.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/constants.py b/ambari-common/src/main/python/resource_management/libraries/functions/constants.py
index abd2212..2e18443 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/constants.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/constants.py
@@ -81,3 +81,4 @@ class StackFeature:
   RANGER_LOG4J_SUPPORT = "ranger_log4j_support"
   RANGER_KERBEROS_SUPPORT = "ranger_kerberos_support"
   HIVE_METASTORE_SITE_SUPPORT = "hive_metastore_site_support"
+  RANGER_USERSYNC_PASSWORD_JCEKS = "ranger_usersync_password_jceks"

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
index daa97de..9e9cadc 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_features.py
@@ -233,6 +233,11 @@ _DEFAULT_STACK_FEATURES = {
       "name": "ranger_kerberos_support",
       "description": "Ranger Kerberos support",
       "min_version": "2.5.0.0"
+    },
+    {
+      "name": "ranger_usersync_password_jceks",
+      "description": "Saving Ranger Usersync credentials in jceks",
+      "min_version": "2.5.0.0"
     }
   ]
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/alerts/alert_ranger_admin_passwd_check.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/alerts/alert_ranger_admin_passwd_check.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/alerts/alert_ranger_admin_passwd_check.py
index a0a9162..8ea8070 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/alerts/alert_ranger_admin_passwd_check.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/alerts/alert_ranger_admin_passwd_check.py
@@ -24,6 +24,8 @@ import ambari_simplejson as json # simplejson is much faster comparing to Python
 import logging
 from resource_management.core.environment import Environment
 from resource_management.libraries.script import Script
+from resource_management.libraries.functions.stack_features import check_stack_feature
+from resource_management.libraries.functions import StackFeature
 
 logger = logging.getLogger()
 RANGER_ADMIN_URL = '{{admin-properties/policymgr_external_url}}'
@@ -65,7 +67,8 @@ def execute(configurations={}, parameters={}, host_name=None):
   ranger_admin_password = None
   security_enabled = False
 
-  stack_is_hdp25_or_further = Script.is_stack_greater_or_equal("2.5")
+  stack_version_formatted = Script.get_stack_version()
+  stack_supports_ranger_kerberos = stack_version_formatted and check_stack_feature(StackFeature.RANGER_KERBEROS_SUPPORT, stack_version_formatted)
 
   if RANGER_ADMIN_URL in configurations:
     ranger_link = configurations[RANGER_ADMIN_URL]
@@ -93,7 +96,7 @@ def execute(configurations={}, parameters={}, host_name=None):
   result_code = 'OK'
 
   try:
-    if security_enabled and stack_is_hdp25_or_further:
+    if security_enabled and stack_supports_ranger_kerberos:
       result_code = 'UNKNOWN'
       label = 'This alert will get skipped for Ranger Admin on kerberos env'
     else:

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/params.py
index 59190fe..408418c 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/params.py
@@ -62,6 +62,7 @@ stack_supports_ranger_tagsync =  stack_version_formatted and check_stack_feature
 stack_supports_ranger_audit_db = stack_version_formatted and check_stack_feature(StackFeature.RANGER_AUDIT_DB_SUPPORT, stack_version_formatted)
 stack_supports_ranger_log4j =  stack_version_formatted and check_stack_feature(StackFeature.RANGER_LOG4J_SUPPORT, stack_version_formatted)
 stack_supports_ranger_kerberos = stack_version_formatted and check_stack_feature(StackFeature.RANGER_KERBEROS_SUPPORT, stack_version_formatted)
+stack_supports_usersync_passwd = stack_version_formatted and check_stack_feature(StackFeature.RANGER_USERSYNC_PASSWORD_JCEKS, stack_version_formatted)
 
 downgrade_from_version = default("/commandParams/downgrade_from_version", None)
 upgrade_direction = default("/commandParams/upgrade_direction", None)
@@ -196,6 +197,7 @@ ranger_jpa_audit_jdbc_credential_alias = config["configurations"]["ranger-admin-
 ranger_ambari_audit_db_password = unicode(config["configurations"]["admin-properties"]["audit_db_password"]) if stack_supports_ranger_audit_db else None
 
 ugsync_jceks_path = config["configurations"]["ranger-ugsync-site"]["ranger.usersync.credstore.filename"]
+ugsync_cred_lib = os.path.join(usersync_home,"lib","*")
 cred_lib_path = os.path.join(ranger_home,"cred","lib","*")
 cred_setup_prefix = (format('{ranger_home}/ranger_credential_helper.py'), '-l', cred_lib_path)
 ranger_audit_source_type = config["configurations"]["ranger-admin-site"]["ranger.audit.source.type"]
@@ -225,10 +227,10 @@ has_ranger_tagsync = len(ranger_tagsync_hosts) > 0
 
 tagsync_enabled = config["configurations"]["ranger-tagsync-site"]['ranger.tagsync.enabled']
 tagsync_log_dir = default("/configurations/ranger-tagsync-site/ranger.tagsync.logdir", "/var/log/ranger/tagsync")
-ranger_tagsync_tagadmin_password = unicode(config["configurations"]["ranger-tagsync-site"]["ranger.tagsync.tagadmin.password"]) if has_ranger_tagsync else None
-tagsync_jceks_path = config["configurations"]["ranger-tagsync-site"]["ranger.tagsync.tagadmin.keystore"]
+tagsync_jceks_path = config["configurations"]["ranger-tagsync-site"]["ranger.tagsync.keystore.filename"]
 tagsync_application_properties = dict(config["configurations"]["tagsync-application-properties"]) if has_ranger_tagsync else None
 tagsync_pid_file = format('{ranger_pid_dir}/tagsync.pid')
+tagsync_cred_lib = os.path.join(ranger_tagsync_home, "lib", "*")
 
 # ranger log4j.properties
 admin_log4j = config['configurations']['admin-log4j']['content']
@@ -239,3 +241,6 @@ tagsync_log4j = config['configurations']['tagsync-log4j']['content']
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 namenode_hosts = default("/clusterHostInfo/namenode_host", [])
 has_namenode = len(namenode_hosts) > 0
+
+ugsync_policymgr_alias = config["configurations"]["ranger-ugsync-site"]["ranger.usersync.policymgr.alias"]
+ugsync_policymgr_keystore = config["configurations"]["ranger-ugsync-site"]["ranger.usersync.policymgr.keystore"]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_tagsync.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_tagsync.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_tagsync.py
index 1b56044..1efa7e9 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_tagsync.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_tagsync.py
@@ -27,13 +27,22 @@ from resource_management.libraries.functions.format import format
 from resource_management.core.logger import Logger
 from resource_management.core import shell
 from ranger_service import ranger_service
-from setup_ranger_xml import ranger
+from setup_ranger_xml import ranger, ranger_credential_helper
 import upgrade
 
 class RangerTagsync(Script):
 
   def install(self, env):
     self.install_packages(env)
+    import params
+    env.set_params(params)
+
+    ranger_credential_helper(params.tagsync_cred_lib, 'tagadmin.user.password', 'rangertagsync', params.tagsync_jceks_path)
+    File(params.tagsync_jceks_path,
+       owner = params.unix_user,
+       group = params.unix_group,
+       mode = 0640
+    )
     self.configure(env)
 
   def configure(self, env, upgrade_type=None):

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py
index d013371..8313b18 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_usersync.py
@@ -18,7 +18,7 @@ limitations under the License.
 
 """
 from resource_management.libraries.script import Script
-from resource_management.core.resources.system import Execute
+from resource_management.core.resources.system import Execute, File
 from resource_management.core.exceptions import ComponentIsNotRunning
 from resource_management.libraries.functions.format import format
 from resource_management.core.logger import Logger
@@ -30,6 +30,19 @@ class RangerUsersync(Script):
   
   def install(self, env):
     self.install_packages(env)
+    import params
+    env.set_params(params)
+
+    if params.stack_supports_usersync_passwd:
+      from setup_ranger_xml import ranger_credential_helper
+      ranger_credential_helper(params.ugsync_cred_lib, params.ugsync_policymgr_alias, 'rangerusersync', params.ugsync_policymgr_keystore)
+
+      File(params.ugsync_policymgr_keystore,
+        owner = params.unix_user,
+        group = params.unix_group,
+        mode = 0640
+      )
+
     self.configure(env)
     
   def configure(self, env, upgrade_type=None):

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger_xml.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger_xml.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger_xml.py
index ec0eea1..fabe2fb 100644
--- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger_xml.py
+++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/setup_ranger_xml.py
@@ -386,14 +386,12 @@ def setup_usersync(upgrade_type=None):
   if os.path.isfile(params.cred_validator_file):
     File(params.cred_validator_file, group=params.unix_group, mode=04555)
 
-  cred_lib = os.path.join(usersync_home,"lib","*")
-
-  ranger_credential_helper(cred_lib, 'usersync.ssl.key.password', params.ranger_usersync_keystore_password, params.ugsync_jceks_path)
+  ranger_credential_helper(params.ugsync_cred_lib, 'usersync.ssl.key.password', params.ranger_usersync_keystore_password, params.ugsync_jceks_path)
 
   if not is_empty(params.ranger_usersync_ldap_ldapbindpassword) and params.ug_sync_source == 'org.apache.ranger.ldapusersync.process.LdapUserGroupBuilder':
-    ranger_credential_helper(cred_lib, 'ranger.usersync.ldap.bindalias', params.ranger_usersync_ldap_ldapbindpassword, params.ugsync_jceks_path)
+    ranger_credential_helper(params.ugsync_cred_lib, 'ranger.usersync.ldap.bindalias', params.ranger_usersync_ldap_ldapbindpassword, params.ugsync_jceks_path)
 
-  ranger_credential_helper(cred_lib, 'usersync.ssl.truststore.password', params.ranger_usersync_truststore_password, params.ugsync_jceks_path)
+  ranger_credential_helper(params.ugsync_cred_lib, 'usersync.ssl.truststore.password', params.ranger_usersync_truststore_password, params.ugsync_jceks_path)
 
   File(params.ugsync_jceks_path,
        owner = params.unix_user,
@@ -435,8 +433,6 @@ def setup_tagsync(upgrade_type=None):
   ranger_home = params.ranger_home
   ranger_tagsync_conf = params.ranger_tagsync_conf
 
-  tagsync_log4j_file = format('{ranger_tagsync_conf}/log4j.xml')
-
   Directory(format("{ranger_tagsync_conf}"),
     owner = params.unix_user,
     group = params.unix_group,
@@ -474,42 +470,19 @@ def setup_tagsync(upgrade_type=None):
     group=params.unix_group,
     mode=0644)
 
-  PropertiesFile(format('{ranger_tagsync_conf}/application.properties'),
+  PropertiesFile(format('{ranger_tagsync_conf}/atlas-application.properties'),
     properties = params.tagsync_application_properties,
     mode=0755,
     owner=params.unix_user,
     group=params.unix_group
   )
 
-  if params.stack_supports_ranger_log4j:
-    File(format('{ranger_tagsync_conf}/log4j.properties'),
-      owner=params.unix_user,
-      group=params.unix_group,
-      content=params.tagsync_log4j,
-      mode=0644
-    )
-    src_file = format('{ranger_tagsync_home}/conf.dist/log4j.xml')
-    dst_file = format('{tagsync_log4j_file}')
-    Execute(('cp', '-f', src_file, dst_file), sudo=True)
-
-  if os.path.isfile(tagsync_log4j_file):
-    File(tagsync_log4j_file, owner=params.unix_user, group=params.unix_group)
-  else:
-    Logger.warning('Required file {0} does not exist, copying the file to {1} path'.format(tagsync_log4j_file, ranger_tagsync_conf))
-    src_file = format('{ranger_tagsync_home}/conf.dist/log4j.xml')
-    dst_file = format('{tagsync_log4j_file}')
-    Execute(('cp', '-f', src_file, dst_file), sudo=True)
-    File(tagsync_log4j_file, owner=params.unix_user, group=params.unix_group)
-
-  cred_lib = os.path.join(ranger_tagsync_home,"lib","*")
-
-  if not is_empty(params.tagsync_jceks_path) and not is_empty(params.ranger_tagsync_tagadmin_password) and params.tagsync_enabled:
-    ranger_credential_helper(cred_lib, 'tagadmin.user.password', params.ranger_tagsync_tagadmin_password, params.tagsync_jceks_path)
-    File(params.tagsync_jceks_path,
-         owner = params.unix_user,
-         group = params.unix_group,
-         mode = 0640
-    )
+  File(format('{ranger_tagsync_conf}/log4j.properties'),
+    owner=params.unix_user,
+    group=params.unix_group,
+    content=params.tagsync_log4j,
+    mode=0644
+  )
 
   File(params.tagsync_services_file,
     mode = 0755,

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
index aabc37d..3ec5d05 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_features.json
@@ -215,6 +215,11 @@
       "name": "hive_metastore_site_support",
       "description": "Hive Metastore site support",
       "min_version": "2.5.0.0"
+    },
+    {
+      "name": "ranger_usersync_password_jceks",
+      "description": "Saving Ranger Usersync credentials in jceks",
+      "min_version": "2.5.0.0"
     }
   ]
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/alerts.json
index f1f76e8..0bced55 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/alerts.json
@@ -11,8 +11,8 @@
         "source": {
           "type": "WEB",
           "uri": {
-              "http": "{{admin-properties/policymgr_external_url}}",
-              "https": "{{admin-properties/policymgr_external_url}}",
+              "http": "{{admin-properties/policymgr_external_url}}/login.jsp",
+              "https": "{{admin-properties/policymgr_external_url}}/login.jsp",
               "kerberos_keytab": "{{ranger-admin-site/ranger.spnego.kerberos.keytab}}",
               "kerberos_principal": "{{ranger-admin-site/ranger.spnego.kerberos.principal}}",
               "https_property": "{{ranger-admin-site/ranger.service.https.attrib.ssl.enabled}}",

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-tagsync-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-tagsync-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-tagsync-site.xml
index 08f6235..ebdae9d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-tagsync-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-tagsync-site.xml
@@ -22,36 +22,18 @@
 <configuration supports_final="true">
 
   <property>
-    <name>ranger.tagsync.enabled</name>
-    <display-name>Enable Tagsync</display-name>
-    <value>false</value>
-    <description>Enable/Disable Ranger Tagsync</description>
-    <value-attributes>
-      <empty-value-valid>true</empty-value-valid>
-      <type>value-list</type>
-      <overridable>false</overridable>
-      <entries>
-        <entry>
-          <value>true</value>
-          <label>Yes</label>
-        </entry>
-        <entry>
-          <value>false</value>
-          <label>No</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
-    </value-attributes>
-  </property>
-
-  <property>
     <name>ranger.tagsync.logdir</name>
     <value>/var/log/ranger/tagsync</value>
     <description>Ranger Log dir</description>
+    <value-attributes>
+      <type>directory</type>
+      <overridable>false</overridable>
+      <editable-only-at-install>true</editable-only-at-install>
+    </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.tagadmin.rest.url</name>
+    <name>ranger.tagsync.dest.ranger.endpoint</name>
     <value>{{ranger_external_url}}</value>
     <description>Ranger TagAdmin REST URL</description>
     <value-attributes>
@@ -60,114 +42,97 @@
   </property>
 
   <property>
-    <name>ranger.tagsync.filesource.modtime.check.interval</name>
-    <display-name>File Source: File update polling interval</display-name>
-    <value></value>
+    <name>ranger.tagsync.source.atlas</name>
+    <display-name>Enable Atlas Tag Source</display-name>
+    <value>false</value>
     <description></description>
     <value-attributes>
-      <empty-value-valid>true</empty-value-valid>
+      <type>boolean</type>
     </value-attributes>
+    <depends-on>
+      <property>
+        <type>application-properties</type>
+        <name>atlas.server.bind.address</name>
+      </property>
+    </depends-on>
   </property>
 
   <property>
-    <name>ranger.tagsync.atlasrestsource.download.interval</name>
-    <display-name>AtlasREST Source: Atlas source download interval</display-name>
-    <value></value>
+    <name>ranger.tagsync.source.atlasrest</name>
+    <display-name>Enable AtlasRest Tag Source</display-name>
+    <value>false</value>
+    <description></description>
     <value-attributes>
-      <empty-value-valid>true</empty-value-valid>
+      <type>boolean</type>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.tagadmin.rest.ssl.config.file</name>
-    <value>/usr/hdp/current/ranger-tagsync/conf/mytruststore.jks</value>
-    <description>Truststore used for tagsync, required if tagsync -&gt; ranger admin communication is SSL enabled</description>
-  </property>
-
-  <property>
-    <name>ranger.tagsync.filesource.filename</name>
-    <display-name>File Source: Filename</display-name>
-    <value></value>
-    <description>File Source Filename</description>
+    <name>ranger.tagsync.source.file</name>
+    <display-name>Enable File Tag Source</display-name>
+    <value>false</value>
+    <description></description>
     <value-attributes>
-      <empty-value-valid>true</empty-value-valid>
+      <type>boolean</type>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.source.impl.class</name>
-    <display-name>Tag Source</display-name>
-    <value>atlas</value>
-    <description>Tagsync Source IMPL class</description>
+    <name>ranger.tagsync.source.file.check.interval.millis</name>
+    <display-name>File Source: File update polling interval</display-name>
+    <value></value>
+    <description></description>
     <value-attributes>
-      <type>value-list</type>
       <empty-value-valid>true</empty-value-valid>
-      <overridable>false</overridable>
-      <entries>
-        <entry>
-          <value>atlas</value>
-          <label>ATLAS</label>
-        </entry>
-        <entry>
-          <value>file</value>
-          <label>FILE</label>
-        </entry>
-        <entry>
-          <value>atlasrest</value>
-          <label>ATLASREST</label>
-        </entry>
-      </entries>
-      <selection-cardinality>1</selection-cardinality>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.tagadmin.keystore</name>
-    <value>/usr/hdp/current/ranger-tagsync/conf/rangertagsync.jceks</value>
-    <description>Keystore file</description>
+    <name>ranger.tagsync.source.atlasrest.download.interval.millis</name>
+    <display-name>AtlasREST Source: Atlas source download interval</display-name>
+    <value></value>
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.tagadmin.alias</name>
-    <value>tagsync.tagadmin</value>
-    <description></description>
+    <name>ranger.tagsync.dest.ranger.ssl.config.filename</name>
+    <value>/usr/hdp/current/ranger-tagsync/conf/mytruststore.jks</value>
+    <description>Truststore used for tagsync, required if tagsync -&gt; ranger admin communication is SSL enabled</description>
   </property>
 
   <property>
-    <name>ranger.tagsync.tagadmin.password</name>
-    <display-name>Tagsync admin password</display-name>
+    <name>ranger.tagsync.source.file.filename</name>
+    <display-name>File Source: Filename</display-name>
     <value></value>
-    <description>Tagadmin password</description>
+    <description>File Source Filename</description>
     <value-attributes>
-      <type>password</type>
+      <empty-value-valid>true</empty-value-valid>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.atlas.to.service.mapping</name>
-    <display-name>Tagsync Atlas to Ranger service mapping</display-name>
-    <value></value>
-    <description>Service Mapping</description>
+    <name>ranger.tagsync.keystore.filename</name>
+    <value>/usr/hdp/current/ranger-tagsync/conf/rangertagsync.jceks</value>
+    <description>Keystore file</description>
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.atlasrestsource.endpoint</name>
-    <display-name>AtlasREST Source: Atlas endpoint</display-name>
+    <name>ranger.tagsync.atlas.to.ranger.service.mapping</name>
     <value></value>
-    <description></description>
+    <description>Service Mapping</description>
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
     </value-attributes>
   </property>
 
   <property>
-    <name>ranger.tagsync.source.atlas.custom.resource.mappers</name>
+    <name>ranger.tagsync.source.atlasrest.endpoint</name>
+    <display-name>AtlasREST Source: Atlas endpoint</display-name>
     <value></value>
     <description></description>
     <value-attributes>
@@ -176,8 +141,8 @@
   </property>
 
   <property>
-    <name>ranger.tagsync.sink.impl.class</name>
-    <value>org.apache.ranger.tagsync.sink.tagadmin.TagAdminRESTSink</value>
+    <name>ranger.tagsync.atlas.custom.resource.mappers</name>
+    <value></value>
     <description></description>
     <value-attributes>
       <empty-value-valid>true</empty-value-valid>
@@ -202,4 +167,10 @@
     </value-attributes>
   </property>
 
+  <property>
+    <name>ranger.tagsync.dest.ranger.username</name>
+    <value>rangertagsync</value>
+    <description></description>
+  </property>
+
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-ugsync-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-ugsync-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-ugsync-site.xml
index 10ef1a8..3d3dc31 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-ugsync-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/ranger-ugsync-site.xml
@@ -36,4 +36,22 @@
     </value-attributes>
   </property>
 
+  <property>
+    <name>ranger.usersync.policymgr.username</name>
+    <value>rangerusersync</value>
+    <description></description>
+  </property>
+
+  <property>
+    <name>ranger.usersync.policymgr.alias</name>
+    <value>ranger.usersync.policymgr.password</value>
+    <description></description>
+  </property>
+
+  <property>
+    <name>ranger.usersync.policymgr.keystore</name>
+    <value>/usr/hdp/current/ranger-usersync/conf/ugsync.jceks</value>
+    <description></description>
+  </property>
+
 </configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/tagsync-application-properties.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/tagsync-application-properties.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/tagsync-application-properties.xml
index d369098..ea00fbe 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/tagsync-application-properties.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/configuration/tagsync-application-properties.xml
@@ -68,28 +68,4 @@
     </value-attributes>
   </property>
 
-  <property>
-    <name>atlas.notification.embedded</name>
-    <value>false</value>
-    <description></description>
-  </property>
-
-  <property>
-    <name>atlas.kafka.acks</name>
-    <value>1</value>
-    <description></description>
-  </property>
-
-  <property>
-    <name>atlas.kafka.data</name>
-    <value>/usr/hdp/current/atlas-server/data/kafka</value>
-    <description></description>
-  </property>
-
-  <property>
-    <name>atlas.kafka.hook.group.id</name>
-    <value>atlas</value>
-    <description></description>
-  </property>
-
 </configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/themes/theme_version_3.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/themes/theme_version_3.json b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/themes/theme_version_3.json
index 19411d4..d5efca4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/themes/theme_version_3.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/RANGER/themes/theme_version_3.json
@@ -8,18 +8,18 @@
             "name": "ranger_tagsync",
             "display-name": "Ranger Tagsync",
             "layout": {
-              "tab-columns": "1",
-              "tab-rows": "1",
+              "tab-columns": "2",
+              "tab-rows": "2",
               "sections": [
                 {
-                  "name": "section-tagsync",
-                  "display-name": "Ranger Tagsync",
+                  "name": "section-tagsync-atlas",
+                  "display-name": "Atlas Tag Source",
                   "row-index": "0",
                   "column-index": "0",
-                  "row-span": "2",
+                  "row-span": "1",
                   "column-span": "1",
                   "section-columns": "1",
-                  "section-rows": "2",
+                  "section-rows": "1",
                   "subsections": [
                     {
                       "name": "subsection-ranger-tagsync-row1-col1",
@@ -27,31 +27,44 @@
                       "column-index": "0",
                       "row-span": "1",
                       "column-span": "1"
-                    },
+                    }
+                  ]
+                },
+                {
+                  "name": "section-tagsync-atlasrest",
+                  "display-name": "AtlasRest Tag Source",
+                  "row-index": "0",
+                  "column-index": "1",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
+                    {
+                      "name": "subsection-ranger-tagsync-row1-col2",
+                      "row-index": "0",
+                      "column-index": "0",
+                      "row-span": "1",
+                      "column-span": "1"
+                    }
+                  ]
+                },
+                {
+                  "name": "section-tagsync-file",
+                  "display-name": "File Tag Source",
+                  "row-index": "1",
+                  "column-index": "0",
+                  "row-span": "1",
+                  "column-span": "1",
+                  "section-columns": "1",
+                  "section-rows": "1",
+                  "subsections": [
                     {
                       "name": "subsection-ranger-tagsync-row2-col1",
-                      "row-index": "1",
+                      "row-index": "0",
                       "column-index": "0",
                       "row-span": "1",
-                      "column-span": "1",
-                      "depends-on": [
-                        {
-                          "configs": [
-                            "ranger-tagsync-site/ranger.tagsync.enabled"
-                          ],
-                          "if": "${ranger-tagsync-site/ranger.tagsync.enabled}",
-                          "then": {
-                            "property_value_attributes": {
-                              "visible": true
-                            }
-                          },
-                          "else": {
-                            "property_value_attributes": {
-                              "visible": false
-                            }
-                          }
-                        }
-                      ]
+                      "column-span": "1"
                     }
                   ]
                 }
@@ -65,26 +78,18 @@
       "configuration-layout": "default",
       "configs": [
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.enabled",
+          "config": "ranger-tagsync-site/ranger.tagsync.source.atlas",
           "subsection-name": "subsection-ranger-tagsync-row1-col1"
         },
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.tagadmin.password",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1"
-        },
-        {
-          "config": "ranger-tagsync-site/ranger.tagsync.source.impl.class",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1"
-        },
-        {
-          "config": "ranger-tagsync-site/ranger.tagsync.filesource.modtime.check.interval",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1",
+          "config": "tagsync-application-properties/atlas.kafka.bootstrap.servers",
+          "subsection-name": "subsection-ranger-tagsync-row1-col1",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.atlas"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === file",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.atlas}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -99,14 +104,14 @@
           ]
         },
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.filesource.filename",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1",
+          "config": "tagsync-application-properties/atlas.kafka.zookeeper.connect",
+          "subsection-name": "subsection-ranger-tagsync-row1-col1",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.atlas"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === file",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.atlas}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -121,14 +126,14 @@
           ]
         },
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.atlasrestsource.endpoint",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1",
+          "config": "tagsync-application-properties/atlas.kafka.entities.group.id",
+          "subsection-name": "subsection-ranger-tagsync-row1-col1",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.atlas"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === atlasrest",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.atlas}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -143,14 +148,18 @@
           ]
         },
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.atlasrestsource.download.interval",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1",
+          "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest",
+          "subsection-name": "subsection-ranger-tagsync-row1-col2"
+        },
+        {
+          "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest.endpoint",
+          "subsection-name": "subsection-ranger-tagsync-row1-col2",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.atlasrest"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === atlasrest",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.atlasrest}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -165,18 +174,14 @@
           ]
         },
         {
-          "config": "ranger-tagsync-site/ranger.tagsync.atlas.to.service.mapping",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1"
-        },
-        {
-          "config": "tagsync-application-properties/atlas.kafka.entities.group.id",
-          "subsection-name": "subsection-ranger-tagsync-row2-col1",
+          "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest.download.interval.millis",
+          "subsection-name": "subsection-ranger-tagsync-row1-col2",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.atlasrest"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === atlas",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.atlasrest}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -191,14 +196,18 @@
           ]
         },
         {
-          "config": "tagsync-application-properties/atlas.kafka.bootstrap.servers",
+          "config": "ranger-tagsync-site/ranger.tagsync.source.file",
+          "subsection-name": "subsection-ranger-tagsync-row2-col1"
+        },
+        {
+          "config": "ranger-tagsync-site/ranger.tagsync.source.file.check.interval.millis",
           "subsection-name": "subsection-ranger-tagsync-row2-col1",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.file"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === atlas",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.file}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -213,14 +222,14 @@
           ]
         },
         {
-          "config": "tagsync-application-properties/atlas.kafka.zookeeper.connect",
+          "config": "ranger-tagsync-site/ranger.tagsync.source.file.filename",
           "subsection-name": "subsection-ranger-tagsync-row2-col1",
           "depends-on": [
             {
               "configs":[
-                "ranger-tagsync-site/ranger.tagsync.source.impl.class"
+                "ranger-tagsync-site/ranger.tagsync.source.file"
               ],
-              "if": "${ranger-tagsync-site/ranger.tagsync.source.impl.class} === atlas",
+              "if": "${ranger-tagsync-site/ranger.tagsync.source.file}",
               "then": {
                 "property_value_attributes": {
                   "visible": true
@@ -238,69 +247,63 @@
     },
     "widgets": [
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.enabled",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.file.check.interval.millis",
         "widget": {
-          "type": "toggle"
-        }
-      },
-      {
-        "config": "ranger-tagsync-site/ranger.tagsync.tagadmin.password",
-        "widget": {
-          "type": "password"
+          "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.source.impl.class",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.file.filename",
         "widget": {
-          "type": "combo"
+          "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.atlas.to.service.mapping",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest.download.interval.millis",
         "widget": {
           "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.filesource.modtime.check.interval",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest.endpoint",
         "widget": {
           "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.filesource.filename",
+        "config": "tagsync-application-properties/atlas.kafka.entities.group.id",
         "widget": {
           "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.atlasrestsource.download.interval",
+        "config": "tagsync-application-properties/atlas.kafka.bootstrap.servers",
         "widget": {
           "type": "text-field"
         }
       },
       {
-        "config": "ranger-tagsync-site/ranger.tagsync.atlasrestsource.endpoint",
+        "config": "tagsync-application-properties/atlas.kafka.zookeeper.connect",
         "widget": {
           "type": "text-field"
         }
       },
       {
-        "config": "tagsync-application-properties/atlas.kafka.entities.group.id",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.atlas",
         "widget": {
-          "type": "text-field"
+          "type": "checkbox"
         }
       },
       {
-        "config": "tagsync-application-properties/atlas.kafka.bootstrap.servers",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.atlasrest",
         "widget": {
-          "type": "text-field"
+          "type": "checkbox"
         }
       },
       {
-        "config": "tagsync-application-properties/atlas.kafka.zookeeper.connect",
+        "config": "ranger-tagsync-site/ranger.tagsync.source.file",
         "widget": {
-          "type": "text-field"
+          "type": "checkbox"
         }
       }
     ]

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
index b954c5f..689e1fd 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/stack_advisor.py
@@ -1043,12 +1043,17 @@ class HDP25StackAdvisor(HDP24StackAdvisor):
       ranger_tagsync_host = self.__getHostsForComponent(services, "RANGER", "RANGER_TAGSYNC")
       has_ranger_tagsync = len(ranger_tagsync_host) > 0
 
+    if 'ATLAS' in servicesList:
+      putTagsyncSiteProperty('ranger.tagsync.source.atlas', 'true')
+    else:
+      putTagsyncSiteProperty('ranger.tagsync.source.atlas', 'false')
+
     zookeeper_host_port = self.getZKHostPortString(services)
     if zookeeper_host_port and has_ranger_tagsync:
       zookeeper_host_list = zookeeper_host_port.split(',')
       putTagsyncAppProperty('atlas.kafka.zookeeper.connect', zookeeper_host_list[0])
     else:
-      putTagsyncAppProperty('atlas.kafka.zookeeper.connect', 'localhost:6667')
+      putTagsyncAppProperty('atlas.kafka.zookeeper.connect', 'localhost:2181')
 
     if 'KAFKA' in servicesList and has_ranger_tagsync:
       kafka_hosts = self.getHostNamesWithComponent("KAFKA", "KAFKA_BROKER", services)
@@ -1063,23 +1068,22 @@ class HDP25StackAdvisor(HDP24StackAdvisor):
       final_kafka_host = ",".join(kafka_host_port)
       putTagsyncAppProperty('atlas.kafka.bootstrap.servers', final_kafka_host)
     else:
-      putTagsyncAppProperty('atlas.kafka.bootstrap.servers', 'localhost:2181')
+      putTagsyncAppProperty('atlas.kafka.bootstrap.servers', 'localhost:6667')
 
   def validateRangerTagsyncConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):
     ranger_tagsync_properties = getSiteProperties(configurations, "ranger-tagsync-site")
     validationItems = []
     servicesList = [service["StackServices"]["service_name"] for service in services["services"]]
 
-    has_ranger_tagsync = False
+    has_atlas = False
     if "RANGER" in servicesList:
-      ranger_tagsync_host = self.__getHostsForComponent(services, "RANGER", "RANGER_TAGSYNC")
-      has_ranger_tagsync = len(ranger_tagsync_host) == 0
+      has_atlas = not "ATLAS" in servicesList
 
-      if has_ranger_tagsync and 'ranger.tagsync.enabled' in ranger_tagsync_properties and \
-        ranger_tagsync_properties['ranger.tagsync.enabled'].lower() == 'true':
-        validationItems.append({"config-name": "ranger.tagsync.enabled",
+      if has_atlas and 'ranger.tagsync.source.atlas' in ranger_tagsync_properties and \
+        ranger_tagsync_properties['ranger.tagsync.source.atlas'].lower() == 'true':
+        validationItems.append({"config-name": "ranger.tagsync.source.atlas",
                                   "item": self.getWarnItem(
-                                    "Need to Install RANGER TAGSYNC component to set ranger.tagsync.enabled as true.")})
+                                    "Need to Install ATLAS service to set ranger.tagsync.source.atlas as true.")})
 
     return self.toConfigurationValidationProblems(validationItems, "ranger-tagsync-site")
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/69b7d274/ambari-web/app/styles/widgets.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/widgets.less b/ambari-web/app/styles/widgets.less
index f385449..4f04108 100644
--- a/ambari-web/app/styles/widgets.less
+++ b/ambari-web/app/styles/widgets.less
@@ -461,7 +461,6 @@
   .bootstrap-checkbox {
     &>button.btn {
       padding: 0;
-      margin-top: -7px;
       color: @green;
       &:focus {
         border-color: none;


Mime
View raw message