openshift_ansible.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. # TODO: Temporarily disabled due to importing old code into openshift-ansible
  2. # repo. We will work on these over time.
  3. # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned
  4. import socket
  5. import subprocess
  6. import sys
  7. import os
  8. import yaml
  9. from ooinstall.variants import find_variant
  10. CFG = None
  11. def set_config(cfg):
  12. global CFG
  13. CFG = cfg
  14. def generate_inventory(hosts):
  15. global CFG
  16. masters = [host for host in hosts if host.master]
  17. nodes = [host for host in hosts if host.node]
  18. proxy = next((host for host in hosts if host.master_lb), None)
  19. multiple_masters = len(masters) > 1
  20. base_inventory_path = CFG.settings['ansible_inventory_path']
  21. base_inventory = open(base_inventory_path, 'w')
  22. write_inventory_children(base_inventory, multiple_masters, proxy)
  23. write_inventory_vars(base_inventory, multiple_masters, proxy)
  24. # Find the correct deployment type for ansible:
  25. ver = find_variant(CFG.settings['variant'],
  26. version=CFG.settings.get('variant_version', None))[1]
  27. base_inventory.write('deployment_type={}\n'.format(ver.ansible_key))
  28. if 'OO_INSTALL_ADDITIONAL_REGISTRIES' in os.environ:
  29. base_inventory.write('cli_docker_additional_registries={}\n'
  30. .format(os.environ['OO_INSTALL_ADDITIONAL_REGISTRIES']))
  31. if 'OO_INSTALL_INSECURE_REGISTRIES' in os.environ:
  32. base_inventory.write('cli_docker_insecure_registries={}\n'
  33. .format(os.environ['OO_INSTALL_INSECURE_REGISTRIES']))
  34. if 'OO_INSTALL_PUDDLE_REPO' in os.environ:
  35. # We have to double the '{' here for literals
  36. base_inventory.write("openshift_additional_repos=[{{'id': 'ose-devel', "
  37. "'name': 'ose-devel', "
  38. "'baseurl': '{}', "
  39. "'enabled': 1, 'gpgcheck': 0}}]\n".format(os.environ['OO_INSTALL_PUDDLE_REPO']))
  40. base_inventory.write('\n[masters]\n')
  41. for master in masters:
  42. write_host(master, base_inventory)
  43. if len(masters) > 1:
  44. base_inventory.write('\n[etcd]\n')
  45. for master in masters:
  46. write_host(master, base_inventory)
  47. base_inventory.write('\n[nodes]\n')
  48. for node in nodes:
  49. # TODO: Until the Master can run the SDN itself we have to configure the Masters
  50. # as Nodes too.
  51. scheduleable = True
  52. # If there's only one Node and it's also a Master we want it to be scheduleable:
  53. if node in masters and len(masters) != len(nodes):
  54. scheduleable = False
  55. write_host(node, base_inventory, scheduleable)
  56. if getattr(proxy, 'run_on', False):
  57. base_inventory.write('\n[lb]\n')
  58. write_host(proxy, base_inventory)
  59. base_inventory.close()
  60. return base_inventory_path
  61. def write_inventory_children(base_inventory, multiple_masters, proxy):
  62. global CFG
  63. base_inventory.write('\n[OSEv3:children]\n')
  64. base_inventory.write('masters\n')
  65. base_inventory.write('nodes\n')
  66. if multiple_masters:
  67. base_inventory.write('etcd\n')
  68. if getattr(proxy, 'run_on', False):
  69. base_inventory.write('lb\n')
  70. def write_inventory_vars(base_inventory, multiple_masters, proxy):
  71. global CFG
  72. base_inventory.write('\n[OSEv3:vars]\n')
  73. base_inventory.write('ansible_ssh_user={}\n'.format(CFG.settings['ansible_ssh_user']))
  74. if CFG.settings['ansible_ssh_user'] != 'root':
  75. base_inventory.write('ansible_become=true\n')
  76. if multiple_masters:
  77. base_inventory.write('openshift_master_cluster_method=native\n')
  78. base_inventory.write("openshift_master_cluster_hostname={}\n".format(proxy.hostname))
  79. base_inventory.write("openshift_master_cluster_public_hostname={}\n".format(proxy.public_hostname))
  80. def write_host(host, inventory, scheduleable=True):
  81. global CFG
  82. facts = ''
  83. if host.ip:
  84. facts += ' openshift_ip={}'.format(host.ip)
  85. if host.public_ip:
  86. facts += ' openshift_public_ip={}'.format(host.public_ip)
  87. if host.hostname:
  88. facts += ' openshift_hostname={}'.format(host.hostname)
  89. if host.public_hostname:
  90. facts += ' openshift_public_hostname={}'.format(host.public_hostname)
  91. # TODO: For not write_host is handles both master and nodes.
  92. # Technically only nodes will ever need this.
  93. if not scheduleable:
  94. facts += ' openshift_scheduleable=False'
  95. installer_host = socket.gethostname()
  96. if installer_host in [host.connect_to, host.hostname, host.public_hostname]:
  97. facts += ' ansible_connection=local'
  98. if os.geteuid() != 0:
  99. no_pwd_sudo = subprocess.call(['sudo', '-n', 'echo', 'openshift'])
  100. if no_pwd_sudo == 1:
  101. print 'The atomic-openshift-installer requires sudo access without a password.'
  102. sys.exit(1)
  103. facts += ' ansible_become=true'
  104. inventory.write('{} {}\n'.format(host.connect_to, facts))
  105. def load_system_facts(inventory_file, os_facts_path, env_vars, verbose=False):
  106. """
  107. Retrieves system facts from the remote systems.
  108. """
  109. FNULL = open(os.devnull, 'w')
  110. args = ['ansible-playbook', '-v'] if verbose \
  111. else ['ansible-playbook']
  112. args.extend([
  113. '--inventory-file={}'.format(inventory_file),
  114. os_facts_path])
  115. status = subprocess.call(args, env=env_vars, stdout=FNULL)
  116. if not status == 0:
  117. return [], 1
  118. callback_facts_file = open(CFG.settings['ansible_callback_facts_yaml'], 'r')
  119. callback_facts = yaml.load(callback_facts_file)
  120. callback_facts_file.close()
  121. return callback_facts, 0
  122. def default_facts(hosts, verbose=False):
  123. global CFG
  124. inventory_file = generate_inventory(hosts)
  125. os_facts_path = '{}/playbooks/byo/openshift_facts.yml'.format(CFG.ansible_playbook_directory)
  126. facts_env = os.environ.copy()
  127. facts_env["OO_INSTALL_CALLBACK_FACTS_YAML"] = CFG.settings['ansible_callback_facts_yaml']
  128. facts_env["ANSIBLE_CALLBACK_PLUGINS"] = CFG.settings['ansible_plugins_directory']
  129. facts_env["OPENSHIFT_MASTER_CLUSTER_METHOD"] = 'native'
  130. if 'ansible_log_path' in CFG.settings:
  131. facts_env["ANSIBLE_LOG_PATH"] = CFG.settings['ansible_log_path']
  132. if 'ansible_config' in CFG.settings:
  133. facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config']
  134. return load_system_facts(inventory_file, os_facts_path, facts_env, verbose)
  135. def run_main_playbook(hosts, hosts_to_run_on, verbose=False):
  136. global CFG
  137. inventory_file = generate_inventory(hosts_to_run_on)
  138. if len(hosts_to_run_on) != len(hosts):
  139. main_playbook_path = os.path.join(CFG.ansible_playbook_directory,
  140. 'playbooks/common/openshift-cluster/scaleup.yml')
  141. else:
  142. main_playbook_path = os.path.join(CFG.ansible_playbook_directory,
  143. 'playbooks/byo/config.yml')
  144. facts_env = os.environ.copy()
  145. if 'ansible_log_path' in CFG.settings:
  146. facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path']
  147. if 'ansible_config' in CFG.settings:
  148. facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config']
  149. return run_ansible(main_playbook_path, inventory_file, facts_env, verbose)
  150. def run_ansible(playbook, inventory, env_vars, verbose=False):
  151. args = ['ansible-playbook', '-v'] if verbose \
  152. else ['ansible-playbook']
  153. args.extend([
  154. '--inventory-file={}'.format(inventory),
  155. playbook])
  156. return subprocess.call(args, env=env_vars)
  157. def run_uninstall_playbook(verbose=False):
  158. playbook = os.path.join(CFG.settings['ansible_playbook_directory'],
  159. 'playbooks/adhoc/uninstall.yml')
  160. inventory_file = generate_inventory(CFG.hosts)
  161. facts_env = os.environ.copy()
  162. if 'ansible_log_path' in CFG.settings:
  163. facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path']
  164. if 'ansible_config' in CFG.settings:
  165. facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config']
  166. return run_ansible(playbook, inventory_file, facts_env, verbose)
  167. def run_upgrade_playbook(verbose=False):
  168. # TODO: do not hardcode the upgrade playbook, add ability to select the
  169. # right playbook depending on the type of upgrade.
  170. playbook = os.path.join(CFG.settings['ansible_playbook_directory'],
  171. 'playbooks/byo/openshift-cluster/upgrades/v3_0_to_v3_1/upgrade.yml')
  172. # TODO: Upgrade inventory for upgrade?
  173. inventory_file = generate_inventory(CFG.hosts)
  174. facts_env = os.environ.copy()
  175. if 'ansible_log_path' in CFG.settings:
  176. facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path']
  177. if 'ansible_config' in CFG.settings:
  178. facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config']
  179. return run_ansible(playbook, inventory_file, facts_env, verbose)