Repository: ambari Updated Branches: refs/heads/trunk 97c4bc5ec -> 60d3a7613
AMBARI-12872. Add SQL Anywhere database support for Ranger and Ranger KMS (Gautam Borad via alejandro) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/60d3a761 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/60d3a761 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/60d3a761 Branch: refs/heads/trunk Commit: 60d3a7613b0c011f987a6c18aa6ee376a40f5461 Parents: 97c4bc5 Author: Alejandro Fernandez <[email protected]> Authored: Thu Aug 27 17:05:24 2015 -0700 Committer: Alejandro Fernandez <[email protected]> Committed: Thu Aug 27 17:05:24 2015 -0700 ---------------------------------------------------------------------- .../functions/setup_ranger_plugin_xml.py | 19 +++--- .../0.96.0.2.0/package/scripts/params_linux.py | 12 +++- .../2.1.0.2.0/package/scripts/params_linux.py | 11 +++- .../0.12.0.2.0/package/scripts/params_linux.py | 11 +++- .../KAFKA/0.8.1.2.2/package/scripts/params.py | 11 +++- .../0.5.0.2.2/package/scripts/params_linux.py | 11 +++- .../RANGER/0.4.0/package/scripts/params.py | 14 +++- .../0.4.0/package/scripts/ranger_service.py | 10 ++- .../0.4.0/package/scripts/setup_ranger_xml.py | 61 ++++++++++++++---- .../RANGER_KMS/0.5.0.2.3/package/scripts/kms.py | 68 ++++++++++++++------ .../0.5.0.2.3/package/scripts/kms_server.py | 7 +- .../0.5.0.2.3/package/scripts/kms_service.py | 18 +++--- .../0.5.0.2.3/package/scripts/params.py | 24 ++++++- .../0.9.1.2.1/package/scripts/params_linux.py | 11 +++- .../2.1.0.2.0/package/scripts/params_linux.py | 11 +++- .../RANGER/configuration/ranger-admin-site.xml | 2 +- 16 files changed, 238 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-common/src/main/python/resource_management/libraries/functions/setup_ranger_plugin_xml.py ---------------------------------------------------------------------- diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/setup_ranger_plugin_xml.py b/ambari-common/src/main/python/resource_management/libraries/functions/setup_ranger_plugin_xml.py index cf40a75..0b404a9 100644 --- a/ambari-common/src/main/python/resource_management/libraries/functions/setup_ranger_plugin_xml.py +++ b/ambari-common/src/main/python/resource_management/libraries/functions/setup_ranger_plugin_xml.py @@ -46,17 +46,18 @@ def setup_ranger_plugin(component_select_name, service_name, xa_audit_db_password, ssl_truststore_password, ssl_keystore_password, api_version=None, hdp_version_override = None): - File(component_downloaded_custom_connector, - content = DownloadSource(component_driver_curl_source), - mode = 0644 - ) + if audit_db_is_enabled: + File(component_downloaded_custom_connector, + content = DownloadSource(component_driver_curl_source), + mode = 0644 + ) - Execute(('cp', '--remove-destination', component_downloaded_custom_connector, component_driver_curl_target), - path=["/bin", "/usr/bin/"], - sudo=True - ) + Execute(('cp', '--remove-destination', component_downloaded_custom_connector, component_driver_curl_target), + path=["/bin", "/usr/bin/"], + sudo=True + ) - File(component_driver_curl_target, mode=0644) + File(component_driver_curl_target, mode=0644) hdp_version = get_hdp_version(component_select_name) if hdp_version_override is not None: http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py index d515dad..ae4dcda 100644 --- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/package/scripts/params_linux.py @@ -240,7 +240,7 @@ if has_ranger_admin: elif xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -252,6 +252,11 @@ if has_ranger_admin: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{exec_tmp_dir}/{jdbc_jar_name}") driver_curl_source = format("{jdk_location}/{jdbc_symlink_name}") @@ -284,6 +289,10 @@ if has_ranger_admin: ssl_truststore_password = unicode(config['configurations']['ranger-hbase-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False + # Used to dynamically set the hbase-site props that are referenced during Kerbenization if security_enabled: if not enable_ranger_hbase: # Default props, no ranger plugin @@ -295,3 +304,4 @@ if security_enabled: else: # HDP Stack 2.2 and less / ranger plugin enabled hbase_coprocessor_master_classes = "com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor" hbase_coprocessor_region_classes = "org.apache.hadoop.hbase.security.token.TokenProvider,org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint,com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor" + http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/params_linux.py index 4d8ac0b..3160af2 100644 --- a/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/package/scripts/params_linux.py @@ -412,7 +412,7 @@ if has_ranger_admin: elif xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -424,6 +424,11 @@ if has_ranger_admin: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") driver_curl_source = format("{jdk_location}/{jdbc_symlink_name}") @@ -457,3 +462,7 @@ if has_ranger_admin: ssl_keystore_password = unicode(config['configurations']['ranger-hdfs-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password']) if xml_configurations_supported else None ssl_truststore_password = unicode(config['configurations']['ranger-hdfs-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py index a5abcb5..affee98 100644 --- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py @@ -517,7 +517,7 @@ if has_ranger_admin: elif xa_audit_db_flavor and xa_audit_db_flavor == 'oracle': ranger_jdbc_jar_name = "ojdbc6.jar" ranger_jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor and xa_audit_db_flavor == 'postgres': ranger_jdbc_jar_name = "postgresql.jar" @@ -529,6 +529,11 @@ if has_ranger_admin: ranger_jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor and xa_audit_db_flavor == 'sqla': + ranger_jdbc_jar_name = "sajdbc4.jar" + ranger_jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" ranger_downloaded_custom_connector = format("{tmp_dir}/{ranger_jdbc_jar_name}") @@ -559,3 +564,7 @@ if has_ranger_admin: ssl_truststore_password = unicode(config['configurations']['ranger-hive-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False + http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/package/scripts/params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/package/scripts/params.py b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/package/scripts/params.py index 455bd00..26ea3e2 100644 --- a/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/package/scripts/params.py +++ b/ambari-server/src/main/resources/common-services/KAFKA/0.8.1.2.2/package/scripts/params.py @@ -183,7 +183,7 @@ if has_ranger_admin and is_supported_kafka_ranger: elif xa_audit_db_flavor and xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor and xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -195,6 +195,11 @@ if has_ranger_admin and is_supported_kafka_ranger: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor and xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") @@ -211,3 +216,7 @@ if has_ranger_admin and is_supported_kafka_ranger: setup_ranger_env_sh_source = format('/usr/hdp/{hdp_version}/ranger-kafka-plugin/install/conf.templates/enable/kafka-ranger-env.sh') setup_ranger_env_sh_target = format("{conf_dir}/kafka-ranger-env.sh") + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False + http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/package/scripts/params_linux.py index 5b520ef..b39e780 100644 --- a/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/KNOX/0.5.0.2.2/package/scripts/params_linux.py @@ -238,7 +238,7 @@ if has_ranger_admin: elif xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -250,6 +250,11 @@ if has_ranger_admin: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") @@ -277,3 +282,7 @@ if has_ranger_admin: ssl_keystore_password = unicode(config['configurations']['ranger-knox-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password']) if xml_configurations_supported else None ssl_truststore_password = unicode(config['configurations']['ranger-knox-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/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 8e84587..7c69e57 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 @@ -111,7 +111,7 @@ if db_flavor.lower() == 'mysql': elif db_flavor.lower() == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{db_host}') jdbc_dialect = "org.eclipse.persistence.platform.database.OraclePlatform" elif db_flavor.lower() == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -123,12 +123,24 @@ elif db_flavor.lower() == 'mssql': jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{db_host};databaseName={ranger_auditdb_name}') jdbc_dialect = "org.eclipse.persistence.platform.database.SQLServerPlatform" +elif db_flavor.lower() == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={ranger_auditdb_name};host={db_host}') + jdbc_dialect = "org.eclipse.persistence.platform.database.SQLAnywherePlatform" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") driver_curl_source = format("{jdk_location}/{jdbc_symlink_name}") driver_curl_target = format("{java_share_dir}/{jdbc_jar_name}") +if db_flavor.lower() == 'sqla': + downloaded_custom_connector = format("{tmp_dir}/sqla-client-jdbc.tar.gz") + jar_path_in_archive = format("{tmp_dir}/sqla-client-jdbc/java/{jdbc_jar_name}") + libs_path_in_archive = format("{tmp_dir}/sqla-client-jdbc/native/lib64/*") + jdbc_libs_dir = format("{ranger_home}/native/lib64") + ld_lib_path = format("{jdbc_libs_dir}") + #for db connection check_db_connection_jar_name = "DBConnectionVerification.jar" check_db_connection_jar = format("/usr/lib/ambari-agent/{check_db_connection_jar_name}") http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py index 8ad2627..4f711c3 100644 --- a/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py +++ b/ambari-server/src/main/resources/common-services/RANGER/0.4.0/package/scripts/ranger_service.py @@ -21,10 +21,14 @@ from resource_management import * def ranger_service(name, action=None): import params + + env_dict = {'JAVA_HOME': params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'JAVA_HOME': params.java_home, 'LD_LIBRARY_PATH': params.ld_lib_path} if name == 'ranger_admin': no_op_test = format('ps -ef | grep proc_rangeradmin | grep -v grep') - Execute(params.ranger_start, environment={'JAVA_HOME': params.java_home}, user=params.unix_user, not_if=no_op_test) + Execute(params.ranger_start, environment=env_dict, user=params.unix_user, not_if=no_op_test) elif name == 'ranger_usersync': no_op_test = format('ps -ef | grep proc_rangerusersync | grep -v grep') @@ -32,14 +36,14 @@ def ranger_service(name, action=None): if params.stack_is_hdp23_or_further: Execute(('chown','-R', format('{unix_user}:{unix_group}'), format('{usersync_log_dir}/')), sudo=True) Execute(params.usersync_start, - environment={'JAVA_HOME': params.java_home}, + environment=env_dict, not_if=no_op_test, user=params.unix_user, ) else: # Usersync requires to be run as root for 2.2 Execute((params.usersync_start,), - environment={'JAVA_HOME': params.java_home}, + environment={'JAVA_HOME': params.java_home}, not_if=no_op_test, sudo=True, ) http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/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 de7726a..a2fe1f0 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 @@ -27,6 +27,7 @@ from resource_management.core.exceptions import Fail from resource_management.libraries.functions.format import format from resource_management.libraries.functions.is_empty import is_empty from resource_management.core.utils import PasswordString +from resource_management.core.shell import as_sudo # This file contains functions used for setup/configure of Ranger Admin and Ranger Usersync. # The design is to mimic what is done by the setup.sh script bundled by Ranger component currently. @@ -63,13 +64,20 @@ def setup_ranger_admin(rolling_upgrade=False): ) cp = format("{check_db_connection_jar}") - cp = cp + os.pathsep + format("{driver_curl_target}") + if params.db_flavor.lower() == 'sqla': + cp = cp + os.pathsep + format("{ranger_home}/ews/lib/{jdbc_jar_name}") + else: + cp = cp + os.pathsep + format("{driver_curl_target}") cp = cp + os.pathsep + format("{ranger_home}/ews/webapp/WEB-INF/lib/*") db_connection_check_command = format( "{java_home}/bin/java -cp {cp} org.apache.ambari.server.DBConnectionVerification '{ranger_jdbc_connection_url}' {ranger_db_user} {ranger_db_password!p} {ranger_jdbc_driver}") - Execute(db_connection_check_command, path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin', tries=5, try_sleep=10) + env_dict = {} + if params.db_flavor.lower() == 'sqla': + env_dict = {'LD_LIBRARY_PATH':params.ld_lib_path} + + Execute(db_connection_check_command, path='/usr/sbin:/sbin:/usr/local/bin:/bin:/usr/bin', tries=5, try_sleep=10, environment=env_dict) Execute(('ln','-sf', format('{ranger_home}/ews/webapp/WEB-INF/classes/conf'), format('{ranger_home}/conf')), not_if=format("ls {ranger_home}/conf"), @@ -132,19 +140,34 @@ def setup_ranger_db(rolling_upgrade=False): cd_access="a" ) - Execute(('cp', '--remove-destination', params.downloaded_custom_connector, params.driver_curl_target), - path=["/bin", "/usr/bin/"], - sudo=True) + if params.db_flavor.lower() != 'sqla': + Execute(('cp', '--remove-destination', params.downloaded_custom_connector, params.driver_curl_target), + path=["/bin", "/usr/bin/"], + sudo=True) - File(params.driver_curl_target, mode=0644) + File(params.driver_curl_target, mode=0644) ranger_home = params.ranger_home if rolling_upgrade: ranger_home = format("/usr/hdp/{version}/ranger-admin") - Execute(('cp', '--remove-destination', params.downloaded_custom_connector, os.path.join(params.ranger_home, 'ews', 'lib')), - path=["/bin", "/usr/bin/"], - sudo=True) + if params.db_flavor.lower() == 'sqla': + Execute(('tar', '-xvf', params.downloaded_custom_connector, '-C', params.tmp_dir), sudo = True) + + Execute(('cp', '--remove-destination', params.jar_path_in_archive, os.path.join(params.ranger_home, 'ews', 'lib')), + path=["/bin", "/usr/bin/"], + sudo=True) + + Directory(params.jdbc_libs_dir, + cd_access="a", + recursive=True) + + Execute(as_sudo(['yes', '|', 'cp', params.libs_path_in_archive, params.jdbc_libs_dir], auto_escape=False), + path=["/bin", "/usr/bin/"]) + else: + Execute(('cp', '--remove-destination', params.downloaded_custom_connector, os.path.join(params.ranger_home, 'ews', 'lib')), + path=["/bin", "/usr/bin/"], + sudo=True) File(os.path.join(params.ranger_home, 'ews', 'lib',params.jdbc_jar_name), mode=0644) @@ -153,12 +176,22 @@ def setup_ranger_db(rolling_upgrade=False): owner = params.unix_user, ) + if params.db_flavor.lower() == 'sqla': + ModifyPropertiesFile(format("{ranger_home}/install.properties"), + properties = {'SQL_CONNECTOR_JAR': format('{ranger_home}/ews/lib/{jdbc_jar_name}')}, + owner = params.unix_user, + ) + + env_dict = {'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME':params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME':params.java_home, 'LD_LIBRARY_PATH':params.ld_lib_path} + # User wants us to setup the DB user and DB? if params.create_db_dbuser: Logger.info('Setting up Ranger DB and DB User') dba_setup = format('python {ranger_home}/dba_script.py -q') Execute(dba_setup, - environment={'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME': params.java_home}, + environment=env_dict, logoutput=True, user=params.unix_user, ) @@ -167,7 +200,7 @@ def setup_ranger_db(rolling_upgrade=False): db_setup = format('python {ranger_home}/db_setup.py') Execute(db_setup, - environment={'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME': params.java_home}, + environment=env_dict, logoutput=True, user=params.unix_user, ) @@ -180,9 +213,13 @@ def setup_java_patch(rolling_upgrade=False): if rolling_upgrade: ranger_home = format("/usr/hdp/{version}/ranger-admin") + env_dict = {'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME':params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME':params.java_home, 'LD_LIBRARY_PATH':params.ld_lib_path} + setup_java_patch = format('python {ranger_home}/db_setup.py -javapatch') Execute(setup_java_patch, - environment={'RANGER_ADMIN_HOME':ranger_home, 'JAVA_HOME': params.java_home}, + environment=env_dict, logoutput=True, user=params.unix_user, ) http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms.py b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms.py index 1ed28c4..fafe1ec 100755 --- a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms.py +++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms.py @@ -34,6 +34,7 @@ from resource_management.core.logger import Logger from resource_management.libraries.functions.format import format from resource_management.libraries.functions.ranger_functions import Rangeradmin from resource_management.core.utils import PasswordString +from resource_management.core.shell import as_sudo def setup_kms_db(): import params @@ -51,19 +52,34 @@ def setup_kms_db(): cd_access="a" ) - Execute(('cp', '--remove-destination', params.downloaded_custom_connector, params.driver_curl_target), - path=["/bin", "/usr/bin/"], - sudo=True) + if params.db_flavor.lower() != 'sqla': + Execute(('cp', '--remove-destination', params.downloaded_custom_connector, params.driver_curl_target), + path=["/bin", "/usr/bin/"], + sudo=True) - File(params.driver_curl_target, mode=0644) + File(params.driver_curl_target, mode=0644) Directory(os.path.join(params.kms_home, 'ews', 'lib'), mode=0755 ) - Execute(('cp', '--remove-destination', params.downloaded_custom_connector, os.path.join(params.kms_home, 'ews', 'webapp', 'lib')), - path=["/bin", "/usr/bin/"], - sudo=True) + if params.db_flavor.lower() == 'sqla': + Execute(('tar', '-xvf', params.downloaded_custom_connector, '-C', params.tmp_dir), sudo = True) + + Execute(('cp', '--remove-destination', params.jar_path_in_archive, os.path.join(params.kms_home, 'ews', 'webapp', 'lib')), + path=["/bin", "/usr/bin/"], + sudo=True) + + Directory(params.jdbc_libs_dir, + cd_access="a", + recursive=True) + + Execute(as_sudo(['yes', '|', 'cp', params.libs_path_in_archive, params.jdbc_libs_dir], auto_escape=False), + path=["/bin", "/usr/bin/"]) + else: + Execute(('cp', '--remove-destination', params.downloaded_custom_connector, os.path.join(params.kms_home, 'ews', 'webapp', 'lib')), + path=["/bin", "/usr/bin/"], + sudo=True) File(os.path.join(params.kms_home, 'ews', 'webapp', 'lib', params.jdbc_jar_name), mode=0644) @@ -72,11 +88,21 @@ def setup_kms_db(): owner = params.kms_user ) + if params.db_flavor.lower() == 'sqla': + ModifyPropertiesFile(format("{kms_home}/install.properties"), + properties = {'SQL_CONNECTOR_JAR': format('{kms_home}/ews/webapp/lib/{jdbc_jar_name}')}, + owner = params.kms_user, + ) + + env_dict = {'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home, 'LD_LIBRARY_PATH':params.ld_library_path} + dba_setup = format('python {kms_home}/dba_script.py -q') db_setup = format('python {kms_home}/db_setup.py') - Execute(dba_setup, environment={'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home}, logoutput=True, user=params.kms_user) - Execute(db_setup, environment={'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home}, logoutput=True, user=params.kms_user) + Execute(dba_setup, environment=env_dict, logoutput=True, user=params.kms_user) + Execute(db_setup, environment=env_dict, logoutput=True, user=params.kms_user) def setup_java_patch(): import params @@ -84,7 +110,12 @@ def setup_java_patch(): if params.has_ranger_admin: setup_java_patch = format('python {kms_home}/db_setup.py -javapatch') - Execute(setup_java_patch, environment={'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home}, logoutput=True, user=params.kms_user) + + env_dict = {'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'RANGER_KMS_HOME':params.kms_home, 'JAVA_HOME': params.java_home, 'LD_LIBRARY_PATH':params.ld_library_path} + + Execute(setup_java_patch, environment=env_dict, logoutput=True, user=params.kms_user) kms_lib_path = format('{kms_home}/ews/webapp/lib/') files = os.listdir(kms_lib_path) @@ -130,16 +161,17 @@ def kms(): recursive = True ) - File(params.downloaded_connector_path, - content = DownloadSource(params.driver_source), - mode = 0644 - ) + if params.xa_audit_db_is_enabled: + File(params.downloaded_connector_path, + content = DownloadSource(params.driver_source), + mode = 0644 + ) - Execute(('cp', '--remove-destination', params.downloaded_connector_path, params.driver_target), - path=["/bin", "/usr/bin/"], - sudo=True) + Execute(('cp', '--remove-destination', params.downloaded_connector_path, params.driver_target), + path=["/bin", "/usr/bin/"], + sudo=True) - File(params.driver_target, mode=0644) + File(params.driver_target, mode=0644) Directory(os.path.join(params.kms_home, 'ews', 'webapp', 'WEB-INF', 'classes', 'lib'), mode=0755, http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_server.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_server.py b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_server.py index 5c3790e..18d1ba1 100755 --- a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_server.py +++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_server.py @@ -56,7 +56,12 @@ class KmsServer(Script): kms_service(action = 'start') def status(self, env): - kms_service(action = 'status') + cmd = 'ps -ef | grep proc_rangerkms | grep -v grep' + code, output = shell.call(cmd, timeout=20) + if code != 0: + Logger.debug('KMS process not running') + raise ComponentIsNotRunning() + pass def configure(self, env): import params http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_service.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_service.py b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_service.py index 5c4d7e7..f5b0c83 100644 --- a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_service.py +++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/kms_service.py @@ -25,18 +25,16 @@ from resource_management.core.exceptions import ComponentIsNotRunning from resource_management.core.logger import Logger def kms_service(action='start'): - # Note: params/status_params should already be imported before calling kms_service() + import params + + env_dict = {'JAVA_HOME': params.java_home} + if params.db_flavor.lower() == 'sqla': + env_dict = {'JAVA_HOME': params.java_home, 'LD_LIBRARY_PATH': params.ld_library_path} + if action == 'start': no_op_test = format('ps -ef | grep proc_rangerkms | grep -v grep') cmd = format('{kms_home}/ranger-kms start') - Execute(cmd, not_if=no_op_test, environment={'JAVA_HOME': format('{java_home}')}, user=format('{kms_user}')) + Execute(cmd, not_if=no_op_test, environment=env_dict, user=format('{kms_user}')) elif action == 'stop': cmd = format('{kms_home}/ranger-kms stop') - Execute(cmd, environment={'JAVA_HOME': format('{java_home}')}, user=format('{kms_user}')) - elif action == 'status': - cmd = 'ps -ef | grep proc_rangerkms | grep -v grep' - code, output = shell.call(cmd, timeout=20) - if code != 0: - Logger.debug('KMS process not running') - raise ComponentIsNotRunning() - pass + Execute(cmd, environment=env_dict, user=format('{kms_user}')) http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/params.py b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/params.py index 1dbf3b1..85db00b 100755 --- a/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/params.py +++ b/ambari-server/src/main/resources/common-services/RANGER_KMS/0.5.0.2.3/package/scripts/params.py @@ -93,7 +93,7 @@ if db_flavor == 'mysql': elif db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - db_jdbc_url = format('jdbc:oracle:thin:\@//{db_host}') + db_jdbc_url = format('jdbc:oracle:thin:@//{db_host}') db_jdbc_driver = "oracle.jdbc.OracleDriver" jdbc_dialect = "org.eclipse.persistence.platform.database.OraclePlatform" elif db_flavor == 'postgres': @@ -108,12 +108,25 @@ elif db_flavor == 'mssql': db_jdbc_url = format('jdbc:sqlserver://{db_host};databaseName={db_name}') db_jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" jdbc_dialect = "org.eclipse.persistence.platform.database.SQLServerPlatform" +elif db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + db_jdbc_url = format('jdbc:sqlanywhere:database={db_name};host={db_host}') + db_jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" + jdbc_dialect = "org.eclipse.persistence.platform.database.SQLAnywherePlatform" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") driver_curl_source = format("{jdk_location}/{jdbc_symlink_name}") driver_curl_target = format("{java_share_dir}/{jdbc_jar_name}") +if db_flavor == 'sqla': + downloaded_custom_connector = format("{tmp_dir}/sqla-client-jdbc.tar.gz") + jar_path_in_archive = format("{tmp_dir}/sqla-client-jdbc/java/{jdbc_jar_name}") + libs_path_in_archive = format("{tmp_dir}/sqla-client-jdbc/native/lib64/*") + jdbc_libs_dir = format("{kms_home}/native/lib64") + ld_library_path = format("{jdbc_libs_dir}") + if has_ranger_admin: if xa_audit_db_flavor == 'mysql': jdbc_symlink = "mysql-jdbc-driver.jar" @@ -135,6 +148,11 @@ if has_ranger_admin: jdbc_symlink = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor == 'sqla': + jdbc_jar = "sajdbc4.jar" + jdbc_symlink = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_connector_path = format("{tmp_dir}/{jdbc_jar}") @@ -161,3 +179,7 @@ kms_ranger_plugin_repo = { xa_audit_db_is_enabled = config['configurations']['ranger-kms-audit']['xasecure.audit.destination.db'] ssl_keystore_password = unicode(config['configurations']['ranger-kms-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password']) ssl_truststore_password = unicode(config['configurations']['ranger-kms-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) + +#For SQLA explicitly disable audit to DB for Ranger +if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/package/scripts/params_linux.py index e7d524d..3bec0d8 100644 --- a/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/STORM/0.9.1.2.1/package/scripts/params_linux.py @@ -210,7 +210,7 @@ if has_ranger_admin: elif xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -222,6 +222,11 @@ if has_ranger_admin: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") @@ -249,3 +254,7 @@ if has_ranger_admin: ssl_keystore_password = unicode(config['configurations']['ranger-storm-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password']) if xml_configurations_supported else None ssl_truststore_password = unicode(config['configurations']['ranger-storm-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py index 9857d03..3d45d21 100644 --- a/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py +++ b/ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/package/scripts/params_linux.py @@ -341,7 +341,7 @@ if has_ranger_admin: elif xa_audit_db_flavor and xa_audit_db_flavor == 'oracle': jdbc_jar_name = "ojdbc6.jar" jdbc_symlink_name = "oracle-jdbc-driver.jar" - audit_jdbc_url = format('jdbc:oracle:thin:\@//{xa_db_host}') + audit_jdbc_url = format('jdbc:oracle:thin:@//{xa_db_host}') jdbc_driver = "oracle.jdbc.OracleDriver" elif xa_audit_db_flavor and xa_audit_db_flavor == 'postgres': jdbc_jar_name = "postgresql.jar" @@ -353,6 +353,11 @@ if has_ranger_admin: jdbc_symlink_name = "mssql-jdbc-driver.jar" audit_jdbc_url = format('jdbc:sqlserver://{xa_db_host};databaseName={xa_audit_db_name}') jdbc_driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver" + elif xa_audit_db_flavor and xa_audit_db_flavor == 'sqla': + jdbc_jar_name = "sajdbc4.jar" + jdbc_symlink_name = "sqlanywhere-jdbc-driver.tar.gz" + audit_jdbc_url = format('jdbc:sqlanywhere:database={xa_audit_db_name};host={xa_db_host}') + jdbc_driver = "sap.jdbc4.sqlanywhere.IDriver" downloaded_custom_connector = format("{tmp_dir}/{jdbc_jar_name}") @@ -364,3 +369,7 @@ if has_ranger_admin: ssl_keystore_password = unicode(config['configurations']['ranger-yarn-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password']) if xml_configurations_supported else None ssl_truststore_password = unicode(config['configurations']['ranger-yarn-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password']) if xml_configurations_supported else None credential_file = format('/etc/ranger/{repo_name}/cred.jceks') if xml_configurations_supported else None + + #For SQLA explicitly disable audit to DB for Ranger + if xa_audit_db_flavor == 'sqla': + xa_audit_db_is_enabled = False http://git-wip-us.apache.org/repos/asf/ambari/blob/60d3a761/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-admin-site.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-admin-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-admin-site.xml index 6878db4..3ccfaa1 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-admin-site.xml +++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-admin-site.xml @@ -118,7 +118,7 @@ <property> <name>ranger.audit.source.type</name> - <value>db</value> + <value>solr</value> <description></description> </property>
