params.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #!/usr/bin/env python
  2. """
  3. Licensed to the Apache Software Foundation (ASF) under one
  4. or more contributor license agreements. See the NOTICE file
  5. distributed with this work for additional information
  6. regarding copyright ownership. The ASF licenses this file
  7. to you under the Apache License, Version 2.0 (the
  8. "License"); you may not use this file except in compliance
  9. with the License. You may obtain a copy of the License at
  10. http://www.apache.org/licenses/LICENSE-2.0
  11. Unless required by applicable law or agreed to in writing, software
  12. distributed under the License is distributed on an "AS IS" BASIS,
  13. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. See the License for the specific language governing permissions and
  15. limitations under the License.
  16. """
  17. # Python Imports
  18. import os
  19. import sys
  20. # Local Imports
  21. from resource_management import get_bare_principal
  22. from status_params import *
  23. from resource_management import format_stack_version, Script
  24. from resource_management.libraries.functions import format
  25. from resource_management.libraries.functions.default import default
  26. from resource_management.libraries.functions.stack_features import check_stack_feature
  27. from resource_management.libraries.functions import StackFeature
  28. from resource_management.libraries.functions.is_empty import is_empty
  29. from resource_management.libraries.functions.expect import expect
  30. def configs_for_ha(atlas_hosts, metadata_port, is_atlas_ha_enabled):
  31. """
  32. Return a dictionary of additional configs to merge if Atlas HA is enabled.
  33. :param atlas_hosts: List of hostnames that contain Atlas
  34. :param metadata_port: Port number
  35. :param is_atlas_ha_enabled: None, True, or False
  36. :return: Dictionary with additional configs to merge to application-properties if HA is enabled.
  37. """
  38. additional_props = {}
  39. if atlas_hosts is None or len(atlas_hosts) == 0 or metadata_port is None:
  40. return additional_props
  41. # Sort to guarantee each host sees the same values, assuming restarted at the same time.
  42. atlas_hosts = sorted(atlas_hosts)
  43. # E.g., id1,id2,id3,...,idn
  44. _server_id_list = ["id" + str(i) for i in range(1, len(atlas_hosts) + 1)]
  45. atlas_server_ids = ",".join(_server_id_list)
  46. additional_props["atlas.server.ids"] = atlas_server_ids
  47. i = 0
  48. for curr_hostname in atlas_hosts:
  49. id = _server_id_list[i]
  50. prop_name = "atlas.server.address." + id
  51. prop_value = curr_hostname + ":" + metadata_port
  52. additional_props[prop_name] = prop_value
  53. i += 1
  54. # This may override the existing property
  55. if i == 1 or (i > 1 and is_atlas_ha_enabled is False):
  56. additional_props["atlas.server.ha.enabled"] = "false"
  57. elif i > 1:
  58. additional_props["atlas.server.ha.enabled"] = "true"
  59. return additional_props
  60. # server configurations
  61. config = Script.get_config()
  62. exec_tmp_dir = Script.get_tmp_dir()
  63. stack_root = Script.get_stack_root()
  64. # Needed since this is an Atlas Hook service.
  65. cluster_name = config['clusterName']
  66. java_version = expect("/hostLevelParams/java_version", int)
  67. if security_enabled:
  68. _hostname_lowercase = config['hostname'].lower()
  69. _atlas_principal_name = config['configurations']['application-properties']['atlas.authentication.principal']
  70. atlas_jaas_principal = _atlas_principal_name.replace('_HOST',_hostname_lowercase)
  71. atlas_keytab_path = config['configurations']['application-properties']['atlas.authentication.keytab']
  72. # New Cluster Stack Version that is defined during the RESTART of a Stack Upgrade
  73. version = default("/commandParams/version", None)
  74. # stack version
  75. stack_version_unformatted = config['hostLevelParams']['stack_version']
  76. stack_version_formatted = format_stack_version(stack_version_unformatted)
  77. metadata_home = os.environ['METADATA_HOME_DIR'] if 'METADATA_HOME_DIR' in os.environ else format('{stack_root}/current/atlas-server')
  78. metadata_bin = format("{metadata_home}/bin")
  79. python_binary = os.environ['PYTHON_EXE'] if 'PYTHON_EXE' in os.environ else sys.executable
  80. metadata_start_script = format("{metadata_bin}/atlas_start.py")
  81. metadata_stop_script = format("{metadata_bin}/atlas_stop.py")
  82. # metadata local directory structure
  83. log_dir = config['configurations']['atlas-env']['metadata_log_dir']
  84. # service locations
  85. hadoop_conf_dir = os.path.join(os.environ["HADOOP_HOME"], "conf") if 'HADOOP_HOME' in os.environ else '/etc/hadoop/conf'
  86. # some commands may need to supply the JAAS location when running as atlas
  87. atlas_jaas_file = format("{conf_dir}/atlas_jaas.conf")
  88. # user
  89. user_group = config['configurations']['cluster-env']['user_group']
  90. # metadata env
  91. java64_home = config['hostLevelParams']['java_home']
  92. env_sh_template = config['configurations']['atlas-env']['content']
  93. # credential provider
  94. credential_provider = format( "jceks://file@{conf_dir}/atlas-site.jceks")
  95. # command line args
  96. ssl_enabled = default("/configurations/application-properties/atlas.enableTLS", False)
  97. http_port = default("/configurations/application-properties/atlas.server.http.port", "21000")
  98. https_port = default("/configurations/application-properties/atlas.server.https.port", "21443")
  99. if ssl_enabled:
  100. metadata_port = https_port
  101. metadata_protocol = 'https'
  102. else:
  103. metadata_port = http_port
  104. metadata_protocol = 'http'
  105. metadata_host = config['hostname']
  106. atlas_hosts = sorted(default('/clusterHostInfo/atlas_server_hosts', []))
  107. metadata_server_host = atlas_hosts[0] if len(atlas_hosts) > 0 else "UNKNOWN_HOST"
  108. # application properties
  109. application_properties = dict(config['configurations']['application-properties'])
  110. application_properties["atlas.server.bind.address"] = metadata_host
  111. # trimming knox_key
  112. if 'atlas.sso.knox.publicKey' in application_properties:
  113. knox_key = application_properties['atlas.sso.knox.publicKey']
  114. knox_key_without_new_line = knox_key.replace("\n","")
  115. application_properties['atlas.sso.knox.publicKey'] = knox_key_without_new_line
  116. if check_stack_feature(StackFeature.ATLAS_UPGRADE_SUPPORT, version_for_stack_feature_checks):
  117. metadata_server_url = application_properties["atlas.rest.address"]
  118. else:
  119. # In HDP 2.3 and 2.4 the property was computed and saved to the local config but did not exist in the database.
  120. metadata_server_url = format('{metadata_protocol}://{metadata_server_host}:{metadata_port}')
  121. application_properties["atlas.rest.address"] = metadata_server_url
  122. # Atlas HA should populate
  123. # atlas.server.ids = id1,id2,...,idn
  124. # atlas.server.address.id# = host#:port
  125. # User should not have to modify this property, but still allow overriding it to False if multiple Atlas servers exist
  126. # This can be None, True, or False
  127. is_atlas_ha_enabled = default("/configurations/application-properties/atlas.server.ha.enabled", None)
  128. additional_ha_props = configs_for_ha(atlas_hosts, metadata_port, is_atlas_ha_enabled)
  129. for k,v in additional_ha_props.iteritems():
  130. application_properties[k] = v
  131. metadata_env_content = config['configurations']['atlas-env']['content']
  132. metadata_opts = config['configurations']['atlas-env']['metadata_opts']
  133. metadata_classpath = config['configurations']['atlas-env']['metadata_classpath']
  134. data_dir = format("{stack_root}/current/atlas-server/data")
  135. expanded_war_dir = os.environ['METADATA_EXPANDED_WEBAPP_DIR'] if 'METADATA_EXPANDED_WEBAPP_DIR' in os.environ else format("{stack_root}/current/atlas-server/server/webapp")
  136. metadata_log4j_content = config['configurations']['atlas-log4j']['content']
  137. metadata_solrconfig_content = default("/configurations/atlas-solrconfig/content", None)
  138. atlas_log_level = config['configurations']['atlas-log4j']['atlas_log_level']
  139. audit_log_level = config['configurations']['atlas-log4j']['audit_log_level']
  140. atlas_log_max_backup_size = default("/configurations/atlas-log4j/atlas_log_max_backup_size", 256)
  141. atlas_log_number_of_backup_files = default("/configurations/atlas-log4j/atlas_log_number_of_backup_files", 20)
  142. # smoke test
  143. smoke_test_user = config['configurations']['cluster-env']['smokeuser']
  144. smoke_test_password = 'smoke'
  145. smokeuser_principal = config['configurations']['cluster-env']['smokeuser_principal_name']
  146. smokeuser_keytab = config['configurations']['cluster-env']['smokeuser_keytab']
  147. security_check_status_file = format('{log_dir}/security_check.status')
  148. # hbase
  149. hbase_conf_dir = "/etc/hbase/conf"
  150. atlas_search_backend = default("/configurations/application-properties/atlas.graph.index.search.backend", "")
  151. search_backend_solr = atlas_search_backend.startswith('solr')
  152. # infra solr
  153. infra_solr_znode = default("/configurations/infra-solr-env/infra_solr_znode", None)
  154. infra_solr_hosts = default("/clusterHostInfo/infra_solr_hosts", [])
  155. infra_solr_replication_factor = 2 if len(infra_solr_hosts) > 1 else 1
  156. atlas_solr_shards = default("/configurations/atlas-env/atlas_solr-shards", 1)
  157. has_infra_solr = len(infra_solr_hosts) > 0
  158. # zookeeper
  159. zookeeper_hosts = config['clusterHostInfo']['zookeeper_hosts']
  160. zookeeper_port = default('/configurations/zoo.cfg/clientPort', None)
  161. # get comma separated lists of zookeeper hosts from clusterHostInfo
  162. index = 0
  163. zookeeper_quorum = ""
  164. for host in zookeeper_hosts:
  165. zookeeper_host = host
  166. if zookeeper_port is not None:
  167. zookeeper_host = host + ":" + str(zookeeper_port)
  168. zookeeper_quorum += zookeeper_host
  169. index += 1
  170. if index < len(zookeeper_hosts):
  171. zookeeper_quorum += ","
  172. # Atlas Ranger plugin configurations
  173. stack_supports_atlas_ranger_plugin = check_stack_feature(StackFeature.ATLAS_RANGER_PLUGIN_SUPPORT, version_for_stack_feature_checks)
  174. stack_supports_ranger_kerberos = check_stack_feature(StackFeature.RANGER_KERBEROS_SUPPORT, version_for_stack_feature_checks)
  175. retry_enabled = default("/commandParams/command_retry_enabled", False)
  176. ranger_admin_hosts = default("/clusterHostInfo/ranger_admin_hosts", [])
  177. has_ranger_admin = not len(ranger_admin_hosts) == 0
  178. xml_configurations_supported = config['configurations']['ranger-env']['xml_configurations_supported']
  179. enable_ranger_atlas = False
  180. atlas_server_xmx = default("configurations/atlas-env/atlas_server_xmx", 2048)
  181. atlas_server_max_new_size = default("configurations/atlas-env/atlas_server_max_new_size", 614)
  182. hbase_master_hosts = default('/clusterHostInfo/hbase_master_hosts', [])
  183. has_hbase_master = not len(hbase_master_hosts) == 0
  184. ranger_admin_hosts = default('/clusterHostInfo/ranger_admin_hosts', [])
  185. has_ranger_admin = not len(ranger_admin_hosts) == 0
  186. atlas_hbase_setup = format("{exec_tmp_dir}/atlas_hbase_setup.rb")
  187. atlas_kafka_setup = format("{exec_tmp_dir}/atlas_kafka_acl.sh")
  188. atlas_graph_storage_hbase_table = default('/configurations/application-properties/atlas.graph.storage.hbase.table', None)
  189. atlas_audit_hbase_tablename = default('/configurations/application-properties/atlas.audit.hbase.tablename', None)
  190. hbase_user_keytab = default('/configurations/hbase-env/hbase_user_keytab', None)
  191. hbase_principal_name = default('/configurations/hbase-env/hbase_principal_name', None)
  192. enable_ranger_hbase = False
  193. # ToDo: Kafka port to Atlas
  194. # Used while upgrading the stack in a kerberized cluster and running kafka-acls.sh
  195. hosts_with_kafka = default('/clusterHostInfo/kafka_broker_hosts', [])
  196. host_with_kafka = hostname in hosts_with_kafka
  197. ranger_tagsync_hosts = default("/clusterHostInfo/ranger_tagsync_hosts", [])
  198. has_ranger_tagsync = len(ranger_tagsync_hosts) > 0
  199. rangertagsync_user = "rangertagsync"
  200. kafka_keytab = default('/configurations/kafka-env/kafka_keytab', None)
  201. kafka_principal_name = default('/configurations/kafka-env/kafka_principal_name', None)
  202. default_replication_factor = default('/configurations/application-properties/atlas.notification.replicas', None)
  203. if check_stack_feature(StackFeature.ATLAS_UPGRADE_SUPPORT, version_for_stack_feature_checks):
  204. default_replication_factor = default('/configurations/application-properties/atlas.notification.replicas', None)
  205. kafka_env_sh_template = config['configurations']['kafka-env']['content']
  206. kafka_home = os.path.join(stack_root, "current", "kafka-broker")
  207. kafka_conf_dir = os.path.join(kafka_home, "config")
  208. kafka_zk_endpoint = default("/configurations/kafka-broker/zookeeper.connect", None)
  209. kafka_kerberos_enabled = (('security.inter.broker.protocol' in config['configurations']['kafka-broker']) and
  210. ((config['configurations']['kafka-broker']['security.inter.broker.protocol'] == "PLAINTEXTSASL") or
  211. (config['configurations']['kafka-broker']['security.inter.broker.protocol'] == "SASL_PLAINTEXT")))
  212. if security_enabled and stack_version_formatted != "" and 'kafka_principal_name' in config['configurations']['kafka-env'] \
  213. and check_stack_feature(StackFeature.KAFKA_KERBEROS, stack_version_formatted):
  214. _hostname_lowercase = config['hostname'].lower()
  215. _kafka_principal_name = config['configurations']['kafka-env']['kafka_principal_name']
  216. kafka_jaas_principal = _kafka_principal_name.replace('_HOST', _hostname_lowercase)
  217. kafka_keytab_path = config['configurations']['kafka-env']['kafka_keytab']
  218. kafka_bare_jaas_principal = get_bare_principal(_kafka_principal_name)
  219. kafka_kerberos_params = "-Djava.security.auth.login.config={0}/kafka_jaas.conf".format(kafka_conf_dir)
  220. else:
  221. kafka_kerberos_params = ''
  222. kafka_jaas_principal = None
  223. kafka_keytab_path = None
  224. if has_ranger_admin and stack_supports_atlas_ranger_plugin:
  225. # for create_hdfs_directory
  226. namenode_host = set(default("/clusterHostInfo/namenode_host", []))
  227. has_namenode = not len(namenode_host) == 0
  228. hdfs_user = config['configurations']['hadoop-env']['hdfs_user'] if has_namenode else None
  229. hdfs_user_keytab = config['configurations']['hadoop-env']['hdfs_user_keytab'] if has_namenode else None
  230. hdfs_principal_name = config['configurations']['hadoop-env']['hdfs_principal_name'] if has_namenode else None
  231. hdfs_site = config['configurations']['hdfs-site']
  232. default_fs = config['configurations']['core-site']['fs.defaultFS']
  233. dfs_type = default("/commandParams/dfs_type", "")
  234. import functools
  235. from resource_management.libraries.resources.hdfs_resource import HdfsResource
  236. from resource_management.libraries.functions.get_not_managed_resources import get_not_managed_resources
  237. #create partial functions with common arguments for every HdfsResource call
  238. #to create hdfs directory we need to call params.HdfsResource in code
  239. HdfsResource = functools.partial(
  240. HdfsResource,
  241. user = hdfs_user,
  242. hdfs_resource_ignore_file = "/var/lib/ambari-agent/data/.hdfs_resource_ignore",
  243. security_enabled = security_enabled,
  244. keytab = hdfs_user_keytab,
  245. kinit_path_local = kinit_path_local,
  246. hadoop_bin_dir = hadoop_bin_dir,
  247. hadoop_conf_dir = hadoop_conf_dir,
  248. principal_name = hdfs_principal_name,
  249. hdfs_site = hdfs_site,
  250. default_fs = default_fs,
  251. immutable_paths = get_not_managed_resources(),
  252. dfs_type = dfs_type
  253. )
  254. repo_name = str(config['clusterName']) + '_atlas'
  255. repo_name_value = config['configurations']['ranger-atlas-security']['ranger.plugin.atlas.service.name']
  256. if not is_empty(repo_name_value) and repo_name_value != "{{repo_name}}":
  257. repo_name = repo_name_value
  258. ssl_keystore_password = unicode(config['configurations']['ranger-atlas-policymgr-ssl']['xasecure.policymgr.clientssl.keystore.password'])
  259. ssl_truststore_password = unicode(config['configurations']['ranger-atlas-policymgr-ssl']['xasecure.policymgr.clientssl.truststore.password'])
  260. credential_file = format('/etc/ranger/{repo_name}/cred.jceks')
  261. xa_audit_hdfs_is_enabled = default('/configurations/ranger-atlas-audit/xasecure.audit.destination.hdfs', False)
  262. enable_ranger_atlas = config['configurations']['ranger-atlas-plugin-properties']['ranger-atlas-plugin-enabled']
  263. enable_ranger_atlas = not is_empty(enable_ranger_atlas) and enable_ranger_atlas.lower() == 'yes'
  264. enable_ranger_hbase = config['configurations']['ranger-hbase-plugin-properties']['ranger-hbase-plugin-enabled']
  265. enable_ranger_hbase = not is_empty(enable_ranger_hbase) and enable_ranger_hbase.lower() == 'yes'
  266. policymgr_mgr_url = config['configurations']['admin-properties']['policymgr_external_url']
  267. downloaded_custom_connector = None
  268. driver_curl_source = None
  269. driver_curl_target = None
  270. ranger_env = config['configurations']['ranger-env']
  271. ranger_plugin_properties = config['configurations']['ranger-atlas-plugin-properties']
  272. ranger_atlas_audit = config['configurations']['ranger-atlas-audit']
  273. ranger_atlas_audit_attrs = config['configuration_attributes']['ranger-atlas-audit']
  274. ranger_atlas_security = config['configurations']['ranger-atlas-security']
  275. ranger_atlas_security_attrs = config['configuration_attributes']['ranger-atlas-security']
  276. ranger_atlas_policymgr_ssl = config['configurations']['ranger-atlas-policymgr-ssl']
  277. ranger_atlas_policymgr_ssl_attrs = config['configuration_attributes']['ranger-atlas-policymgr-ssl']
  278. policy_user = config['configurations']['ranger-atlas-plugin-properties']['policy_user']
  279. atlas_repository_configuration = {
  280. 'username' : config['configurations']['ranger-atlas-plugin-properties']['REPOSITORY_CONFIG_USERNAME'],
  281. 'password' : unicode(config['configurations']['ranger-atlas-plugin-properties']['REPOSITORY_CONFIG_PASSWORD']),
  282. 'atlas.rest.address' : metadata_server_url,
  283. 'commonNameForCertificate' : config['configurations']['ranger-atlas-plugin-properties']['common.name.for.certificate'],
  284. 'ambari.service.check.user' : policy_user
  285. }
  286. if security_enabled:
  287. atlas_repository_configuration['policy.download.auth.users'] = metadata_user
  288. atlas_repository_configuration['tag.download.auth.users'] = metadata_user
  289. atlas_ranger_plugin_repo = {
  290. 'isEnabled': 'true',
  291. 'configs': atlas_repository_configuration,
  292. 'description': 'atlas repo',
  293. 'name': repo_name,
  294. 'type': 'atlas',
  295. }