oc_obj.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. # pylint: skip-file
  2. # flake8: noqa
  3. # pylint: disable=too-many-instance-attributes
  4. class OCObject(OpenShiftCLI):
  5. ''' Class to wrap the oc command line tools '''
  6. # pylint allows 5. we need 6
  7. # pylint: disable=too-many-arguments
  8. def __init__(self,
  9. kind,
  10. namespace,
  11. name=None,
  12. selector=None,
  13. kubeconfig='/etc/origin/master/admin.kubeconfig',
  14. verbose=False,
  15. all_namespaces=False):
  16. ''' Constructor for OpenshiftOC '''
  17. super(OCObject, self).__init__(namespace, kubeconfig=kubeconfig, verbose=verbose,
  18. all_namespaces=all_namespaces)
  19. self.kind = kind
  20. self.name = name
  21. self.selector = selector
  22. def get(self):
  23. '''return a kind by name '''
  24. results = self._get(self.kind, name=self.name, selector=self.selector)
  25. if (results['returncode'] != 0 and 'stderr' in results and
  26. '\"{}\" not found'.format(self.name) in results['stderr']):
  27. results['returncode'] = 0
  28. return results
  29. def delete(self):
  30. '''delete the object'''
  31. return self._delete(self.kind, name=self.name, selector=self.selector)
  32. def create(self, files=None, content=None):
  33. '''
  34. Create a config
  35. NOTE: This creates the first file OR the first conent.
  36. TODO: Handle all files and content passed in
  37. '''
  38. if files:
  39. return self._create(files[0])
  40. content['data'] = yaml.dump(content['data'])
  41. content_file = Utils.create_tmp_files_from_contents(content)[0]
  42. return self._create(content_file['path'])
  43. # pylint: disable=too-many-function-args
  44. def update(self, files=None, content=None, force=False):
  45. '''update a current openshift object
  46. This receives a list of file names or content
  47. and takes the first and calls replace.
  48. TODO: take an entire list
  49. '''
  50. if files:
  51. return self._replace(files[0], force)
  52. if content and 'data' in content:
  53. content = content['data']
  54. return self.update_content(content, force)
  55. def update_content(self, content, force=False):
  56. '''update an object through using the content param'''
  57. return self._replace_content(self.kind, self.name, content, force=force)
  58. def needs_update(self, files=None, content=None, content_type='yaml'):
  59. ''' check to see if we need to update '''
  60. objects = self.get()
  61. if objects['returncode'] != 0:
  62. return objects
  63. data = None
  64. if files:
  65. data = Utils.get_resource_file(files[0], content_type)
  66. elif content and 'data' in content:
  67. data = content['data']
  68. else:
  69. data = content
  70. # if equal then no need. So not equal is True
  71. return not Utils.check_def_equal(data, objects['results'][0], skip_keys=None, debug=False)
  72. # pylint: disable=too-many-return-statements,too-many-branches
  73. @staticmethod
  74. def run_ansible(params, check_mode=False):
  75. '''perform the ansible idempotent code'''
  76. ocobj = OCObject(params['kind'],
  77. params['namespace'],
  78. params['name'],
  79. params['selector'],
  80. kubeconfig=params['kubeconfig'],
  81. verbose=params['debug'],
  82. all_namespaces=params['all_namespaces'])
  83. state = params['state']
  84. api_rval = ocobj.get()
  85. #####
  86. # Get
  87. #####
  88. if state == 'list':
  89. return {'changed': False, 'results': api_rval, 'state': state}
  90. ########
  91. # Delete
  92. ########
  93. if state == 'absent':
  94. # if we were passed a name, verify its not in our results
  95. if params['name'] is not None and not Utils.exists(api_rval['results'], params['name']):
  96. return {'changed': False, 'state': state}
  97. # verify results are empty for the selector
  98. if params['selector'] is not None and len(api_rval['results']) == 0:
  99. return {'changed': False, 'state': state}
  100. if check_mode:
  101. return {'changed': True, 'msg': 'CHECK_MODE: Would have performed a delete'}
  102. api_rval = ocobj.delete()
  103. if api_rval['returncode'] != 0:
  104. return {'failed': True, 'msg': api_rval}
  105. return {'changed': True, 'results': api_rval, 'state': state}
  106. # create/update: Must define a name beyond this point
  107. if not params['name']:
  108. return {'failed': True, 'msg': 'Please specify a name when state is present.'}
  109. if state == 'present':
  110. ########
  111. # Create
  112. ########
  113. if not Utils.exists(api_rval['results'], params['name']):
  114. if check_mode:
  115. return {'changed': True, 'msg': 'CHECK_MODE: Would have performed a create'}
  116. # Create it here
  117. api_rval = ocobj.create(params['files'], params['content'])
  118. if api_rval['returncode'] != 0:
  119. return {'failed': True, 'msg': api_rval}
  120. # return the created object
  121. api_rval = ocobj.get()
  122. if api_rval['returncode'] != 0:
  123. return {'failed': True, 'msg': api_rval}
  124. # Remove files
  125. if params['files'] and params['delete_after']:
  126. Utils.cleanup(params['files'])
  127. return {'changed': True, 'results': api_rval, 'state': state}
  128. ########
  129. # Update
  130. ########
  131. # if a file path is passed, use it.
  132. update = ocobj.needs_update(params['files'], params['content'])
  133. if not isinstance(update, bool):
  134. return {'failed': True, 'msg': update}
  135. # No changes
  136. if not update:
  137. if params['files'] and params['delete_after']:
  138. Utils.cleanup(params['files'])
  139. return {'changed': False, 'results': api_rval['results'][0], 'state': state}
  140. if check_mode:
  141. return {'changed': True, 'msg': 'CHECK_MODE: Would have performed an update.'}
  142. api_rval = ocobj.update(params['files'],
  143. params['content'],
  144. params['force'])
  145. if api_rval['returncode'] != 0:
  146. return {'failed': True, 'msg': api_rval}
  147. # return the created object
  148. api_rval = ocobj.get()
  149. if api_rval['returncode'] != 0:
  150. return {'failed': True, 'msg': api_rval}
  151. return {'changed': True, 'results': api_rval, 'state': state}