|
@@ -0,0 +1,339 @@
|
|
|
+# pylint: skip-file
|
|
|
+# flake8: noqa
|
|
|
+
|
|
|
+
|
|
|
+# pylint: disable=too-many-public-methods
|
|
|
+class DeploymentConfig(Yedit):
|
|
|
+ ''' Class to wrap the oc command line tools '''
|
|
|
+ default_deployment_config = '''
|
|
|
+apiVersion: v1
|
|
|
+kind: DeploymentConfig
|
|
|
+metadata:
|
|
|
+ name: default_dc
|
|
|
+ namespace: default
|
|
|
+spec:
|
|
|
+ replicas: 0
|
|
|
+ selector:
|
|
|
+ default_dc: default_dc
|
|
|
+ strategy:
|
|
|
+ resources: {}
|
|
|
+ rollingParams:
|
|
|
+ intervalSeconds: 1
|
|
|
+ maxSurge: 0
|
|
|
+ maxUnavailable: 25%
|
|
|
+ timeoutSeconds: 600
|
|
|
+ updatePercent: -25
|
|
|
+ updatePeriodSeconds: 1
|
|
|
+ type: Rolling
|
|
|
+ template:
|
|
|
+ metadata:
|
|
|
+ spec:
|
|
|
+ containers:
|
|
|
+ - env:
|
|
|
+ - name: default
|
|
|
+ value: default
|
|
|
+ image: default
|
|
|
+ imagePullPolicy: IfNotPresent
|
|
|
+ name: default_dc
|
|
|
+ ports:
|
|
|
+ - containerPort: 8000
|
|
|
+ hostPort: 8000
|
|
|
+ protocol: TCP
|
|
|
+ name: default_port
|
|
|
+ resources: {}
|
|
|
+ terminationMessagePath: /dev/termination-log
|
|
|
+ dnsPolicy: ClusterFirst
|
|
|
+ hostNetwork: true
|
|
|
+ nodeSelector:
|
|
|
+ type: compute
|
|
|
+ restartPolicy: Always
|
|
|
+ securityContext: {}
|
|
|
+ serviceAccount: default
|
|
|
+ serviceAccountName: default
|
|
|
+ terminationGracePeriodSeconds: 30
|
|
|
+ triggers:
|
|
|
+ - type: ConfigChange
|
|
|
+'''
|
|
|
+
|
|
|
+ replicas_path = "spec.replicas"
|
|
|
+ env_path = "spec.template.spec.containers[0].env"
|
|
|
+ volumes_path = "spec.template.spec.volumes"
|
|
|
+ container_path = "spec.template.spec.containers"
|
|
|
+ volume_mounts_path = "spec.template.spec.containers[0].volumeMounts"
|
|
|
+
|
|
|
+ def __init__(self, content=None):
|
|
|
+ ''' Constructor for deploymentconfig '''
|
|
|
+ if not content:
|
|
|
+ content = DeploymentConfig.default_deployment_config
|
|
|
+
|
|
|
+ super(DeploymentConfig, self).__init__(content=content)
|
|
|
+
|
|
|
+ # pylint: disable=no-member
|
|
|
+ def add_env_value(self, key, value):
|
|
|
+ ''' add key, value pair to env array '''
|
|
|
+ rval = False
|
|
|
+ env = self.get_env_vars()
|
|
|
+ if env:
|
|
|
+ env.append({'name': key, 'value': value})
|
|
|
+ rval = True
|
|
|
+ else:
|
|
|
+ result = self.put(DeploymentConfig.env_path, {'name': key, 'value': value})
|
|
|
+ rval = result[0]
|
|
|
+
|
|
|
+ return rval
|
|
|
+
|
|
|
+ def exists_env_value(self, key, value):
|
|
|
+ ''' return whether a key, value pair exists '''
|
|
|
+ results = self.get_env_vars()
|
|
|
+ if not results:
|
|
|
+ return False
|
|
|
+
|
|
|
+ for result in results:
|
|
|
+ if result['name'] == key and result['value'] == value:
|
|
|
+ return True
|
|
|
+
|
|
|
+ return False
|
|
|
+
|
|
|
+ def exists_env_key(self, key):
|
|
|
+ ''' return whether a key, value pair exists '''
|
|
|
+ results = self.get_env_vars()
|
|
|
+ if not results:
|
|
|
+ return False
|
|
|
+
|
|
|
+ for result in results:
|
|
|
+ if result['name'] == key:
|
|
|
+ return True
|
|
|
+
|
|
|
+ return False
|
|
|
+
|
|
|
+ def get_env_vars(self):
|
|
|
+ '''return a environment variables '''
|
|
|
+ return self.get(DeploymentConfig.env_path) or []
|
|
|
+
|
|
|
+ def delete_env_var(self, keys):
|
|
|
+ '''delete a list of keys '''
|
|
|
+ if not isinstance(keys, list):
|
|
|
+ keys = [keys]
|
|
|
+
|
|
|
+ env_vars_array = self.get_env_vars()
|
|
|
+ modified = False
|
|
|
+ idx = None
|
|
|
+ for key in keys:
|
|
|
+ for env_idx, env_var in enumerate(env_vars_array):
|
|
|
+ if env_var['name'] == key:
|
|
|
+ idx = env_idx
|
|
|
+ break
|
|
|
+
|
|
|
+ if idx:
|
|
|
+ modified = True
|
|
|
+ del env_vars_array[idx]
|
|
|
+
|
|
|
+ if modified:
|
|
|
+ return True
|
|
|
+
|
|
|
+ return False
|
|
|
+
|
|
|
+ def update_env_var(self, key, value):
|
|
|
+ '''place an env in the env var list'''
|
|
|
+
|
|
|
+ env_vars_array = self.get_env_vars()
|
|
|
+ idx = None
|
|
|
+ for env_idx, env_var in enumerate(env_vars_array):
|
|
|
+ if env_var['name'] == key:
|
|
|
+ idx = env_idx
|
|
|
+ break
|
|
|
+
|
|
|
+ if idx:
|
|
|
+ env_vars_array[idx]['value'] = value
|
|
|
+ else:
|
|
|
+ self.add_env_value(key, value)
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+ def exists_volume_mount(self, volume_mount):
|
|
|
+ ''' return whether a volume mount exists '''
|
|
|
+ exist_volume_mounts = self.get_volume_mounts()
|
|
|
+
|
|
|
+ if not exist_volume_mounts:
|
|
|
+ return False
|
|
|
+
|
|
|
+ volume_mount_found = False
|
|
|
+ for exist_volume_mount in exist_volume_mounts:
|
|
|
+ if exist_volume_mount['name'] == volume_mount['name']:
|
|
|
+ volume_mount_found = True
|
|
|
+ break
|
|
|
+
|
|
|
+ return volume_mount_found
|
|
|
+
|
|
|
+ def exists_volume(self, volume):
|
|
|
+ ''' return whether a volume exists '''
|
|
|
+ exist_volumes = self.get_volumes()
|
|
|
+
|
|
|
+ volume_found = False
|
|
|
+ for exist_volume in exist_volumes:
|
|
|
+ if exist_volume['name'] == volume['name']:
|
|
|
+ volume_found = True
|
|
|
+ break
|
|
|
+
|
|
|
+ return volume_found
|
|
|
+
|
|
|
+ def find_volume_by_name(self, volume, mounts=False):
|
|
|
+ ''' return the index of a volume '''
|
|
|
+ volumes = []
|
|
|
+ if mounts:
|
|
|
+ volumes = self.get_volume_mounts()
|
|
|
+ else:
|
|
|
+ volumes = self.get_volumes()
|
|
|
+ for exist_volume in volumes:
|
|
|
+ if exist_volume['name'] == volume['name']:
|
|
|
+ return exist_volume
|
|
|
+
|
|
|
+ return None
|
|
|
+
|
|
|
+ def get_replicas(self):
|
|
|
+ ''' return replicas setting '''
|
|
|
+ return self.get(DeploymentConfig.replicas_path)
|
|
|
+
|
|
|
+ def get_volume_mounts(self):
|
|
|
+ '''return volume mount information '''
|
|
|
+ return self.get_volumes(mounts=True)
|
|
|
+
|
|
|
+ def get_volumes(self, mounts=False):
|
|
|
+ '''return volume mount information '''
|
|
|
+ if mounts:
|
|
|
+ return self.get(DeploymentConfig.volume_mounts_path) or []
|
|
|
+
|
|
|
+ return self.get(DeploymentConfig.volumes_path) or []
|
|
|
+
|
|
|
+ def delete_volume_by_name(self, volume):
|
|
|
+ '''delete a volume '''
|
|
|
+ modified = False
|
|
|
+ exist_volume_mounts = self.get_volume_mounts()
|
|
|
+ exist_volumes = self.get_volumes()
|
|
|
+ del_idx = None
|
|
|
+ for idx, exist_volume in enumerate(exist_volumes):
|
|
|
+ if 'name' in exist_volume and exist_volume['name'] == volume['name']:
|
|
|
+ del_idx = idx
|
|
|
+ break
|
|
|
+
|
|
|
+ if del_idx != None:
|
|
|
+ del exist_volumes[del_idx]
|
|
|
+ modified = True
|
|
|
+
|
|
|
+ del_idx = None
|
|
|
+ for idx, exist_volume_mount in enumerate(exist_volume_mounts):
|
|
|
+ if 'name' in exist_volume_mount and exist_volume_mount['name'] == volume['name']:
|
|
|
+ del_idx = idx
|
|
|
+ break
|
|
|
+
|
|
|
+ if del_idx != None:
|
|
|
+ del exist_volume_mounts[idx]
|
|
|
+ modified = True
|
|
|
+
|
|
|
+ return modified
|
|
|
+
|
|
|
+ def add_volume_mount(self, volume_mount):
|
|
|
+ ''' add a volume or volume mount to the proper location '''
|
|
|
+ exist_volume_mounts = self.get_volume_mounts()
|
|
|
+
|
|
|
+ if not exist_volume_mounts and volume_mount:
|
|
|
+ self.put(DeploymentConfig.volume_mounts_path, [volume_mount])
|
|
|
+ else:
|
|
|
+ exist_volume_mounts.append(volume_mount)
|
|
|
+
|
|
|
+ def add_volume(self, volume):
|
|
|
+ ''' add a volume or volume mount to the proper location '''
|
|
|
+ exist_volumes = self.get_volumes()
|
|
|
+ if not volume:
|
|
|
+ return
|
|
|
+
|
|
|
+ if not exist_volumes:
|
|
|
+ self.put(DeploymentConfig.volumes_path, [volume])
|
|
|
+ else:
|
|
|
+ exist_volumes.append(volume)
|
|
|
+
|
|
|
+ def update_replicas(self, replicas):
|
|
|
+ ''' update replicas value '''
|
|
|
+ self.put(DeploymentConfig.replicas_path, replicas)
|
|
|
+
|
|
|
+ def update_volume(self, volume):
|
|
|
+ '''place an env in the env var list'''
|
|
|
+ exist_volumes = self.get_volumes()
|
|
|
+
|
|
|
+ if not volume:
|
|
|
+ return False
|
|
|
+
|
|
|
+ # update the volume
|
|
|
+ update_idx = None
|
|
|
+ for idx, exist_vol in enumerate(exist_volumes):
|
|
|
+ if exist_vol['name'] == volume['name']:
|
|
|
+ update_idx = idx
|
|
|
+ break
|
|
|
+
|
|
|
+ if update_idx != None:
|
|
|
+ exist_volumes[update_idx] = volume
|
|
|
+ else:
|
|
|
+ self.add_volume(volume)
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+ def update_volume_mount(self, volume_mount):
|
|
|
+ '''place an env in the env var list'''
|
|
|
+ modified = False
|
|
|
+
|
|
|
+ exist_volume_mounts = self.get_volume_mounts()
|
|
|
+
|
|
|
+ if not volume_mount:
|
|
|
+ return False
|
|
|
+
|
|
|
+ # update the volume mount
|
|
|
+ for exist_vol_mount in exist_volume_mounts:
|
|
|
+ if exist_vol_mount['name'] == volume_mount['name']:
|
|
|
+ if 'mountPath' in exist_vol_mount and \
|
|
|
+ str(exist_vol_mount['mountPath']) != str(volume_mount['mountPath']):
|
|
|
+ exist_vol_mount['mountPath'] = volume_mount['mountPath']
|
|
|
+ modified = True
|
|
|
+ break
|
|
|
+
|
|
|
+ if not modified:
|
|
|
+ self.add_volume_mount(volume_mount)
|
|
|
+ modified = True
|
|
|
+
|
|
|
+ return modified
|
|
|
+
|
|
|
+ def needs_update_volume(self, volume, volume_mount):
|
|
|
+ ''' verify a volume update is needed '''
|
|
|
+ exist_volume = self.find_volume_by_name(volume)
|
|
|
+ exist_volume_mount = self.find_volume_by_name(volume, mounts=True)
|
|
|
+ results = []
|
|
|
+ results.append(exist_volume['name'] == volume['name'])
|
|
|
+
|
|
|
+ if 'secret' in volume:
|
|
|
+ results.append('secret' in exist_volume)
|
|
|
+ results.append(exist_volume['secret']['secretName'] == volume['secret']['secretName'])
|
|
|
+ results.append(exist_volume_mount['name'] == volume_mount['name'])
|
|
|
+ results.append(exist_volume_mount['mountPath'] == volume_mount['mountPath'])
|
|
|
+
|
|
|
+ elif 'emptyDir' in volume:
|
|
|
+ results.append(exist_volume_mount['name'] == volume['name'])
|
|
|
+ results.append(exist_volume_mount['mountPath'] == volume_mount['mountPath'])
|
|
|
+
|
|
|
+ elif 'persistentVolumeClaim' in volume:
|
|
|
+ pvc = 'persistentVolumeClaim'
|
|
|
+ results.append(pvc in exist_volume)
|
|
|
+ if results[-1]:
|
|
|
+ results.append(exist_volume[pvc]['claimName'] == volume[pvc]['claimName'])
|
|
|
+
|
|
|
+ if 'claimSize' in volume[pvc]:
|
|
|
+ results.append(exist_volume[pvc]['claimSize'] == volume[pvc]['claimSize'])
|
|
|
+
|
|
|
+ elif 'hostpath' in volume:
|
|
|
+ results.append('hostPath' in exist_volume)
|
|
|
+ results.append(exist_volume['hostPath']['path'] == volume_mount['mountPath'])
|
|
|
+
|
|
|
+ return not all(results)
|
|
|
+
|
|
|
+ def needs_update_replicas(self, replicas):
|
|
|
+ ''' verify whether a replica update is needed '''
|
|
|
+ current_reps = self.get(DeploymentConfig.replicas_path)
|
|
|
+ return not current_reps == replicas
|