test_ec2.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Nicole Thomas <nicole@saltstack.com>
  4. '''
  5. # Import Python Libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. import os
  8. import yaml
  9. # Import Salt Libs
  10. import salt.utils.cloud
  11. import salt.utils.files
  12. import salt.utils.yaml
  13. # Import Salt Testing Libs
  14. from tests.support.runtime import RUNTIME_VARS
  15. from tests.support.unit import skipIf
  16. from tests.support import win_installer
  17. # Create the cloud instance name to be used throughout the tests
  18. from tests.integration.cloud.helpers.cloud_test_base import CloudTest
  19. HAS_WINRM = salt.utils.cloud.HAS_WINRM and salt.utils.cloud.HAS_SMB
  20. # THis test needs a longer timeout than other cloud tests
  21. TIMEOUT = 1200
  22. class EC2Test(CloudTest):
  23. '''
  24. Integration tests for the EC2 cloud provider in Salt-Cloud
  25. '''
  26. PROVIDER = 'ec2'
  27. REQUIRED_PROVIDER_CONFIG_ITEMS = ('id', 'key', 'keyname', 'private_key', 'location')
  28. @staticmethod
  29. def __fetch_installer():
  30. # Determine the downloaded installer name by searching the files
  31. # directory for the first file that looks like an installer.
  32. for path, dirs, files in os.walk(RUNTIME_VARS.FILES):
  33. for file in files:
  34. if file.startswith(win_installer.PREFIX):
  35. return file
  36. # If the installer wasn't found in the previous steps, download the latest Windows installer executable
  37. name = win_installer.latest_installer_name()
  38. path = os.path.join(RUNTIME_VARS.FILES, name)
  39. with salt.utils.files.fopen(path, 'wb') as fp:
  40. win_installer.download_and_verify(fp, name)
  41. return name
  42. @property
  43. def installer(self):
  44. '''
  45. Make sure the testing environment has a Windows installer executable.
  46. '''
  47. if not hasattr(self, '_installer'):
  48. self._installer = self.__fetch_installer()
  49. return self._installer
  50. def setUp(self):
  51. '''
  52. Sets up the test requirements
  53. '''
  54. group_or_subnet = self.provider_config.get('securitygroup')
  55. if not group_or_subnet:
  56. group_or_subnet = self.provider_config.get('subnetid')
  57. if not group_or_subnet:
  58. self.skipTest('securitygroup or subnetid missing for {} config'.format(self.PROVIDER))
  59. super(EC2Test, self).setUp()
  60. def override_profile_config(self, name, data):
  61. conf_path = os.path.join(self.config_dir, 'cloud.profiles.d', 'ec2.conf')
  62. with salt.utils.files.fopen(conf_path, 'r') as fp:
  63. conf = yaml.safe_load(fp)
  64. conf[name].update(data)
  65. with salt.utils.files.fopen(conf_path, 'w') as fp:
  66. salt.utils.yaml.safe_dump(conf, fp)
  67. def copy_file(self, name):
  68. '''
  69. Copy a file from tests/integration/files to a test's temporary
  70. configuration directory. The path to the file which is created will be
  71. returned.
  72. '''
  73. src = os.path.join(RUNTIME_VARS.FILES, name)
  74. dst = os.path.join(self.config_dir, name)
  75. with salt.utils.files.fopen(src, 'rb') as sfp:
  76. with salt.utils.files.fopen(dst, 'wb') as dfp:
  77. dfp.write(sfp.read())
  78. return dst
  79. def _test_instance(self, profile, debug):
  80. '''
  81. Tests creating and deleting an instance on EC2 (classic)
  82. '''
  83. # create the instance
  84. cmd = ['-p', profile]
  85. if debug:
  86. cmd.extend(['-l', 'debug'])
  87. cmd.append(self.instance_name)
  88. ret_val = self.run_cloud(' '.join(cmd), timeout=TIMEOUT)
  89. # check if instance returned with salt installed
  90. self.assertInstanceExists(ret_val)
  91. self.assertDestroyInstance()
  92. def test_instance_rename(self):
  93. '''
  94. Tests creating and renaming an instance on EC2 (classic)
  95. '''
  96. # create the instance
  97. ret_val = self.run_cloud('-p ec2-test {0} --no-deploy'.format(self.instance_name), timeout=TIMEOUT)
  98. # check if instance returned
  99. self.assertInstanceExists(ret_val)
  100. changed_name = self.instance_name + '-changed'
  101. rename_result = self.run_cloud(
  102. '-a rename {0} newname={1} --assume-yes'.format(self.instance_name, changed_name), timeout=TIMEOUT)
  103. self.assertFalse(self._instance_exists(), 'Instance wasn\'t renamed: |\n{}'.format(rename_result))
  104. self.assertInstanceExists(instance_name=changed_name)
  105. self.assertDestroyInstance(changed_name)
  106. def test_instance(self):
  107. '''
  108. Tests creating and deleting an instance on EC2 (classic)
  109. '''
  110. self._test_instance('ec2-test', debug=False)
  111. def test_win2012r2_psexec(self):
  112. '''
  113. Tests creating and deleting a Windows 2012r2instance on EC2 using
  114. psexec (classic)
  115. '''
  116. # TODO: psexec calls hang and the test fails by timing out. The same
  117. # same calls succeed when run outside of the test environment.
  118. # FIXME? Does this override need to be undone at the end of the test?
  119. self.override_profile_config(
  120. 'ec2-win2012r2-test',
  121. {
  122. 'use_winrm': False,
  123. 'userdata_file': self.copy_file('windows-firewall-winexe.ps1'),
  124. 'win_installer': self.copy_file(self.installer),
  125. },
  126. )
  127. self._test_instance('ec2-win2012r2-test', debug=True)
  128. @skipIf(not HAS_WINRM, 'Skip when winrm dependencies are missing')
  129. def test_win2012r2_winrm(self):
  130. '''
  131. Tests creating and deleting a Windows 2012r2 instance on EC2 using
  132. winrm (classic)
  133. '''
  134. self.override_profile_config(
  135. 'ec2-win2012r2-test',
  136. {
  137. 'userdata_file': self.copy_file('windows-firewall.ps1'),
  138. 'win_installer': self.copy_file(self.installer),
  139. 'winrm_ssl_verify': False,
  140. 'use_winrm': True,
  141. }
  142. )
  143. self._test_instance('ec2-win2012r2-test', debug=True)
  144. def test_win2016_psexec(self):
  145. '''
  146. Tests creating and deleting a Windows 2016 instance on EC2 using winrm
  147. (classic)
  148. '''
  149. # TODO: winexe calls hang and the test fails by timing out. The
  150. # same calls succeed when run outside of the test environment.
  151. self.override_profile_config(
  152. 'ec2-win2016-test',
  153. {
  154. 'use_winrm': False,
  155. 'userdata_file': self.copy_file('windows-firewall-winexe.ps1'),
  156. 'win_installer': self.copy_file(self.installer),
  157. },
  158. )
  159. self._test_instance('ec2-win2016-test', debug=True)
  160. @skipIf(not HAS_WINRM, 'Skip when winrm dependencies are missing')
  161. def test_win2016_winrm(self):
  162. '''
  163. Tests creating and deleting a Windows 2016 instance on EC2 using winrm
  164. (classic)
  165. '''
  166. self.override_profile_config(
  167. 'ec2-win2016-test',
  168. {
  169. 'userdata_file': self.copy_file('windows-firewall.ps1'),
  170. 'win_installer': self.copy_file(self.installer),
  171. 'winrm_ssl_verify': False,
  172. 'use_winrm': True,
  173. }
  174. )
  175. self._test_instance('ec2-win2016-test', debug=True)