deploymentconfig.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. # pylint: skip-file
  2. # flake8: noqa
  3. # pylint: disable=too-many-public-methods
  4. class DeploymentConfig(Yedit):
  5. ''' Class to model an openshift DeploymentConfig'''
  6. default_deployment_config = '''
  7. apiVersion: v1
  8. kind: DeploymentConfig
  9. metadata:
  10. name: default_dc
  11. namespace: default
  12. spec:
  13. replicas: 0
  14. selector:
  15. default_dc: default_dc
  16. strategy:
  17. resources: {}
  18. rollingParams:
  19. intervalSeconds: 1
  20. maxSurge: 0
  21. maxUnavailable: 25%
  22. timeoutSeconds: 600
  23. updatePercent: -25
  24. updatePeriodSeconds: 1
  25. type: Rolling
  26. template:
  27. metadata:
  28. spec:
  29. containers:
  30. - env:
  31. - name: default
  32. value: default
  33. image: default
  34. imagePullPolicy: IfNotPresent
  35. name: default_dc
  36. ports:
  37. - containerPort: 8000
  38. hostPort: 8000
  39. protocol: TCP
  40. name: default_port
  41. resources: {}
  42. terminationMessagePath: /dev/termination-log
  43. dnsPolicy: ClusterFirst
  44. hostNetwork: true
  45. nodeSelector:
  46. type: compute
  47. restartPolicy: Always
  48. securityContext: {}
  49. serviceAccount: default
  50. serviceAccountName: default
  51. terminationGracePeriodSeconds: 30
  52. triggers:
  53. - type: ConfigChange
  54. '''
  55. replicas_path = "spec.replicas"
  56. env_path = "spec.template.spec.containers[0].env"
  57. volumes_path = "spec.template.spec.volumes"
  58. container_path = "spec.template.spec.containers"
  59. volume_mounts_path = "spec.template.spec.containers[0].volumeMounts"
  60. def __init__(self, content=None):
  61. ''' Constructor for deploymentconfig '''
  62. if not content:
  63. content = DeploymentConfig.default_deployment_config
  64. super(DeploymentConfig, self).__init__(content=content)
  65. def add_env_value(self, key, value):
  66. ''' add key, value pair to env array '''
  67. rval = False
  68. env = self.get_env_vars()
  69. if env:
  70. env.append({'name': key, 'value': value})
  71. rval = True
  72. else:
  73. result = self.put(DeploymentConfig.env_path, {'name': key, 'value': value})
  74. rval = result[0]
  75. return rval
  76. def exists_env_value(self, key, value):
  77. ''' return whether a key, value pair exists '''
  78. results = self.get_env_vars()
  79. if not results:
  80. return False
  81. for result in results:
  82. if result['name'] == key and result['value'] == value:
  83. return True
  84. return False
  85. def exists_env_key(self, key):
  86. ''' return whether a key, value pair exists '''
  87. results = self.get_env_vars()
  88. if not results:
  89. return False
  90. for result in results:
  91. if result['name'] == key:
  92. return True
  93. return False
  94. def get_env_vars(self):
  95. '''return a environment variables '''
  96. return self.get(DeploymentConfig.env_path) or []
  97. def delete_env_var(self, keys):
  98. '''delete a list of keys '''
  99. if not isinstance(keys, list):
  100. keys = [keys]
  101. env_vars_array = self.get_env_vars()
  102. modified = False
  103. idx = None
  104. for key in keys:
  105. for env_idx, env_var in enumerate(env_vars_array):
  106. if env_var['name'] == key:
  107. idx = env_idx
  108. break
  109. if idx:
  110. modified = True
  111. del env_vars_array[idx]
  112. if modified:
  113. return True
  114. return False
  115. def update_env_var(self, key, value):
  116. '''place an env in the env var list'''
  117. env_vars_array = self.get_env_vars()
  118. idx = None
  119. for env_idx, env_var in enumerate(env_vars_array):
  120. if env_var['name'] == key:
  121. idx = env_idx
  122. break
  123. if idx:
  124. env_vars_array[idx]['value'] = value
  125. else:
  126. self.add_env_value(key, value)
  127. return True
  128. def exists_volume_mount(self, volume_mount):
  129. ''' return whether a volume mount exists '''
  130. exist_volume_mounts = self.get_volume_mounts()
  131. if not exist_volume_mounts:
  132. return False
  133. volume_mount_found = False
  134. for exist_volume_mount in exist_volume_mounts:
  135. if exist_volume_mount['name'] == volume_mount['name']:
  136. volume_mount_found = True
  137. break
  138. return volume_mount_found
  139. def exists_volume(self, volume):
  140. ''' return whether a volume exists '''
  141. exist_volumes = self.get_volumes()
  142. volume_found = False
  143. for exist_volume in exist_volumes:
  144. if exist_volume['name'] == volume['name']:
  145. volume_found = True
  146. break
  147. return volume_found
  148. def find_volume_by_name(self, volume, mounts=False):
  149. ''' return the index of a volume '''
  150. volumes = []
  151. if mounts:
  152. volumes = self.get_volume_mounts()
  153. else:
  154. volumes = self.get_volumes()
  155. for exist_volume in volumes:
  156. if exist_volume['name'] == volume['name']:
  157. return exist_volume
  158. return None
  159. def get_env_var(self, key):
  160. '''return a environment variables '''
  161. results = self.get(DeploymentConfig.env_path) or []
  162. if not results:
  163. return None
  164. for env_var in results:
  165. if env_var['name'] == key:
  166. return env_var
  167. return None
  168. def get_replicas(self):
  169. ''' return replicas setting '''
  170. return self.get(DeploymentConfig.replicas_path)
  171. def get_volume_mounts(self):
  172. '''return volume mount information '''
  173. return self.get_volumes(mounts=True)
  174. def get_volumes(self, mounts=False):
  175. '''return volume mount information '''
  176. if mounts:
  177. return self.get(DeploymentConfig.volume_mounts_path) or []
  178. return self.get(DeploymentConfig.volumes_path) or []
  179. def delete_volume_by_name(self, volume):
  180. '''delete a volume '''
  181. modified = False
  182. exist_volume_mounts = self.get_volume_mounts()
  183. exist_volumes = self.get_volumes()
  184. del_idx = None
  185. for idx, exist_volume in enumerate(exist_volumes):
  186. if 'name' in exist_volume and exist_volume['name'] == volume['name']:
  187. del_idx = idx
  188. break
  189. if del_idx != None:
  190. del exist_volumes[del_idx]
  191. modified = True
  192. del_idx = None
  193. for idx, exist_volume_mount in enumerate(exist_volume_mounts):
  194. if 'name' in exist_volume_mount and exist_volume_mount['name'] == volume['name']:
  195. del_idx = idx
  196. break
  197. if del_idx != None:
  198. del exist_volume_mounts[idx]
  199. modified = True
  200. return modified
  201. def add_volume_mount(self, volume_mount):
  202. ''' add a volume or volume mount to the proper location '''
  203. exist_volume_mounts = self.get_volume_mounts()
  204. if not exist_volume_mounts and volume_mount:
  205. self.put(DeploymentConfig.volume_mounts_path, [volume_mount])
  206. else:
  207. exist_volume_mounts.append(volume_mount)
  208. def add_volume(self, volume):
  209. ''' add a volume or volume mount to the proper location '''
  210. exist_volumes = self.get_volumes()
  211. if not volume:
  212. return
  213. if not exist_volumes:
  214. self.put(DeploymentConfig.volumes_path, [volume])
  215. else:
  216. exist_volumes.append(volume)
  217. def update_replicas(self, replicas):
  218. ''' update replicas value '''
  219. self.put(DeploymentConfig.replicas_path, replicas)
  220. def update_volume(self, volume):
  221. '''place an env in the env var list'''
  222. exist_volumes = self.get_volumes()
  223. if not volume:
  224. return False
  225. # update the volume
  226. update_idx = None
  227. for idx, exist_vol in enumerate(exist_volumes):
  228. if exist_vol['name'] == volume['name']:
  229. update_idx = idx
  230. break
  231. if update_idx != None:
  232. exist_volumes[update_idx] = volume
  233. else:
  234. self.add_volume(volume)
  235. return True
  236. def update_volume_mount(self, volume_mount):
  237. '''place an env in the env var list'''
  238. modified = False
  239. exist_volume_mounts = self.get_volume_mounts()
  240. if not volume_mount:
  241. return False
  242. # update the volume mount
  243. for exist_vol_mount in exist_volume_mounts:
  244. if exist_vol_mount['name'] == volume_mount['name']:
  245. if 'mountPath' in exist_vol_mount and \
  246. str(exist_vol_mount['mountPath']) != str(volume_mount['mountPath']):
  247. exist_vol_mount['mountPath'] = volume_mount['mountPath']
  248. modified = True
  249. break
  250. if not modified:
  251. self.add_volume_mount(volume_mount)
  252. modified = True
  253. return modified
  254. def needs_update_volume(self, volume, volume_mount):
  255. ''' verify a volume update is needed '''
  256. exist_volume = self.find_volume_by_name(volume)
  257. exist_volume_mount = self.find_volume_by_name(volume, mounts=True)
  258. results = []
  259. results.append(exist_volume['name'] == volume['name'])
  260. if 'secret' in volume:
  261. results.append('secret' in exist_volume)
  262. results.append(exist_volume['secret']['secretName'] == volume['secret']['secretName'])
  263. results.append(exist_volume_mount['name'] == volume_mount['name'])
  264. results.append(exist_volume_mount['mountPath'] == volume_mount['mountPath'])
  265. elif 'emptyDir' in volume:
  266. results.append(exist_volume_mount['name'] == volume['name'])
  267. results.append(exist_volume_mount['mountPath'] == volume_mount['mountPath'])
  268. elif 'persistentVolumeClaim' in volume:
  269. pvc = 'persistentVolumeClaim'
  270. results.append(pvc in exist_volume)
  271. if results[-1]:
  272. results.append(exist_volume[pvc]['claimName'] == volume[pvc]['claimName'])
  273. if 'claimSize' in volume[pvc]:
  274. results.append(exist_volume[pvc]['claimSize'] == volume[pvc]['claimSize'])
  275. elif 'hostpath' in volume:
  276. results.append('hostPath' in exist_volume)
  277. results.append(exist_volume['hostPath']['path'] == volume_mount['mountPath'])
  278. return not all(results)
  279. def needs_update_replicas(self, replicas):
  280. ''' verify whether a replica update is needed '''
  281. current_reps = self.get(DeploymentConfig.replicas_path)
  282. return not current_reps == replicas