openshift_upgrade_config.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """Ansible module for modifying OpenShift configs during an upgrade"""
  4. import os
  5. import yaml
  6. DOCUMENTATION = '''
  7. ---
  8. module: openshift_upgrade_config
  9. short_description: OpenShift Upgrade Config
  10. author: Jason DeTiberus
  11. requirements: [ ]
  12. '''
  13. EXAMPLES = '''
  14. '''
  15. def modify_api_levels(level_list, remove, ensure, msg_prepend='',
  16. msg_append=''):
  17. """ modify_api_levels """
  18. changed = False
  19. changes = []
  20. if not isinstance(remove, list):
  21. remove = []
  22. if not isinstance(ensure, list):
  23. ensure = []
  24. if not isinstance(level_list, list):
  25. new_list = []
  26. changed = True
  27. changes.append("%s created missing %s" % (msg_prepend, msg_append))
  28. else:
  29. new_list = level_list
  30. for level in remove:
  31. if level in new_list:
  32. new_list.remove(level)
  33. changed = True
  34. changes.append("%s removed %s %s" % (msg_prepend, level, msg_append))
  35. for level in ensure:
  36. if level not in new_list:
  37. new_list.append(level)
  38. changed = True
  39. changes.append("%s added %s %s" % (msg_prepend, level, msg_append))
  40. return {'new_list': new_list, 'changed': changed, 'changes': changes}
  41. def upgrade_master_3_0_to_3_1(ansible_module, config_base, backup):
  42. """Main upgrade method for 3.0 to 3.1."""
  43. changes = []
  44. # Facts do not get transferred to the hosts where custom modules run,
  45. # need to make some assumptions here.
  46. master_config = os.path.join(config_base, 'master/master-config.yaml')
  47. master_cfg_file = open(master_config, 'r')
  48. config = yaml.safe_load(master_cfg_file.read())
  49. master_cfg_file.close()
  50. # Remove unsupported api versions and ensure supported api versions from
  51. # master config
  52. unsupported_levels = ['v1beta1', 'v1beta2', 'v1beta3']
  53. supported_levels = ['v1']
  54. result = modify_api_levels(config.get('apiLevels'), unsupported_levels,
  55. supported_levels, 'master-config.yaml:', 'from apiLevels')
  56. if result['changed']:
  57. config['apiLevels'] = result['new_list']
  58. changes.append(result['changes'])
  59. if 'kubernetesMasterConfig' in config and 'apiLevels' in config['kubernetesMasterConfig']:
  60. config['kubernetesMasterConfig'].pop('apiLevels')
  61. changes.append('master-config.yaml: removed kubernetesMasterConfig.apiLevels')
  62. # Add masterCA to serviceAccountConfig
  63. if 'serviceAccountConfig' in config and 'masterCA' not in config['serviceAccountConfig']:
  64. config['serviceAccountConfig']['masterCA'] = config['oauthConfig'].get('masterCA', 'ca.crt')
  65. # Add proxyClientInfo to master-config
  66. if 'proxyClientInfo' not in config['kubernetesMasterConfig']:
  67. config['kubernetesMasterConfig']['proxyClientInfo'] = {
  68. 'certFile': 'master.proxy-client.crt',
  69. 'keyFile': 'master.proxy-client.key'
  70. }
  71. changes.append("master-config.yaml: added proxyClientInfo")
  72. if len(changes) > 0:
  73. if backup:
  74. # TODO: Check success:
  75. ansible_module.backup_local(master_config)
  76. # Write the modified config:
  77. out_file = open(master_config, 'w')
  78. out_file.write(yaml.safe_dump(config, default_flow_style=False))
  79. out_file.close()
  80. return changes
  81. def upgrade_master(ansible_module, config_base, from_version, to_version, backup):
  82. """Upgrade entry point."""
  83. if from_version == '3.0':
  84. if to_version == '3.1':
  85. return upgrade_master_3_0_to_3_1(ansible_module, config_base, backup)
  86. def main():
  87. """ main """
  88. # disabling pylint errors for global-variable-undefined and invalid-name
  89. # for 'global module' usage, since it is required to use ansible_facts
  90. # pylint: disable=global-variable-undefined, invalid-name,
  91. # redefined-outer-name
  92. global module
  93. module = AnsibleModule( # noqa: F405
  94. argument_spec=dict(
  95. config_base=dict(required=True),
  96. from_version=dict(required=True, choices=['3.0']),
  97. to_version=dict(required=True, choices=['3.1']),
  98. role=dict(required=True, choices=['master']),
  99. backup=dict(required=False, default=True, type='bool')
  100. ),
  101. supports_check_mode=True,
  102. )
  103. from_version = module.params['from_version']
  104. to_version = module.params['to_version']
  105. role = module.params['role']
  106. backup = module.params['backup']
  107. config_base = module.params['config_base']
  108. try:
  109. changes = []
  110. if role == 'master':
  111. changes = upgrade_master(module, config_base, from_version,
  112. to_version, backup)
  113. changed = len(changes) > 0
  114. return module.exit_json(changed=changed, changes=changes)
  115. # ignore broad-except error to avoid stack trace to ansible user
  116. # pylint: disable=broad-except
  117. except Exception as e:
  118. return module.fail_json(msg=str(e))
  119. # ignore pylint errors related to the module_utils import
  120. # pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-position
  121. # import module snippets
  122. from ansible.module_utils.basic import * # noqa: E402,F403
  123. if __name__ == '__main__':
  124. main()