Skip to content

Commit

Permalink
Merge pull request #125 from sebastienc/work
Browse files Browse the repository at this point in the history
Testing on Kubernetes 1.10 and fixing some bugs.
  • Loading branch information
sebastienc committed Jul 23, 2018
2 parents accbe52 + 86fc9a2 commit 99f2472
Show file tree
Hide file tree
Showing 28 changed files with 249 additions and 214 deletions.
7 changes: 3 additions & 4 deletions kubernetes/K8sConfigMap.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sConfigMap, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sConfigMap, self).list(labels=labels)
cm = list(map(lambda x: ConfigMap(x), ls))
if pattern is not None:
cm = list(filter(lambda x: pattern in x.name, cm))
k8s = []
for x in cm:
j = K8sConfigMap(config=self.config, name=x.name)
j.model = x
j = K8sConfigMap(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
7 changes: 3 additions & 4 deletions kubernetes/K8sCronJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sCronJob, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sCronJob, self).list(labels=labels)
jobs = list(map(lambda x: CronJob(x), ls))
if pattern is not None:
jobs = list(filter(lambda x: pattern in x.name, jobs))
k8s = []
for x in jobs:
j = K8sCronJob(config=self.config, name=x.name)
j.model = x
j = K8sCronJob(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
7 changes: 3 additions & 4 deletions kubernetes/K8sDaemonSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sDaemonSet, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sDaemonSet, self).list(labels=labels)
daemons = list(map(lambda x: DaemonSet(x), ls))
if pattern is not None:
daemons = list(filter(lambda x: pattern in x.name, daemons))
k8s = []
for x in daemons:
j = K8sDaemonSet(config=self.config, name=x.name)
j.model = x
j = K8sDaemonSet(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
48 changes: 23 additions & 25 deletions kubernetes/K8sDeployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from kubernetes.K8sReplicaSet import K8sReplicaSet
from kubernetes.models.v1beta1.Deployment import Deployment
from kubernetes.models.v1beta1.DeploymentRollback import DeploymentRollback
from kubernetes.models.v1beta1.RollbackConfig import RollbackConfig
from kubernetes.models.v1beta1.LabelSelector import LabelSelector
from kubernetes.utils import is_valid_list

Expand Down Expand Up @@ -68,15 +69,14 @@ def update(self):
self._wait_for_desired_replicas()
return self

def list(self, pattern=None):
ls = super(K8sDeployment, self).list()
deploys = list(map(lambda x: Deployment(x), ls))
def list(self, pattern=None, labels=None):
ls = super(K8sDeployment, self).list(labels=labels)
deploys = list(map(lambda d: Deployment(d), ls))
if pattern is not None:
deploys = list(filter(lambda x: pattern in x.name, deploys))
k8s = []
deploys = list(filter(lambda dep: pattern in dep.name, deploys))
k8s = list()
for x in deploys:
j = K8sDeployment(config=self.config, name=x.name)
j.model = x
j = K8sDeployment(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down Expand Up @@ -331,12 +331,13 @@ def volumes(self, v=None):
# ------------------------------------------------------------------------------------- get by name

@staticmethod
def get_by_name(config=None, name=None):
def get_by_name(config=None, name=None, name_label='name'):
"""
Fetches a K8sDeployment by name.
:param config: A K8sConfig object.
:param name: The name we want.
:param name_label: The label key to use for name.
:return: A list of K8sDeployment objects.
"""

Expand All @@ -351,19 +352,11 @@ def get_by_name(config=None, name=None):
raise SyntaxError(
'Deployment: config: [ {0} ] must be a K8sConfig'.format(config))

dep_list = list()
data = {'labelSelector': 'name={0}'.format(name)}
deps = K8sDeployment(config=config, name=name).get_with_params(data=data)
deps = K8sDeployment(config=config, name=name).list(labels={
name_label: name
})

for dep in deps:
try:
d = Deployment(dep)
dep_name = d.metadata.name
dep_list.append(K8sDeployment(config=config, name=dep_name).get())
except NotFoundException:
pass

return dep_list
return deps

# ------------------------------------------------------------------------------------- rollback

Expand All @@ -383,14 +376,18 @@ def rollback(self, revision=None, annotations=None):
rollback = DeploymentRollback()
rollback.name = self.name

rollback_config = RollbackConfig()

# to the specified revision
if revision is not None:
rollback.rollback_to.revision = revision
rollback_config.revision = revision
# to the revision immediately preceding the current revision
else:
current_revision = int(self.get_annotation(self.REVISION_ANNOTATION))
rev = max(current_revision - 1, 0)
rollback.rollback_to.revision = rev
rollback_config.revision = rev

rollback.rollback_to = rollback_config

if annotations is not None:
rollback.updated_annotations = annotations
Expand All @@ -401,15 +398,16 @@ def rollback(self, revision=None, annotations=None):
url=url,
data=rollback.serialize())

self.get()
self._wait_for_desired_replicas()

if not state.get('success'):
status = state.get('status', '')
reason = state.get('data', dict()).get('message', None)
message = 'K8sDeployment: ROLLBACK failed : HTTP {0} : {1}'.format(status, reason)
raise BadRequestException(message)

time.sleep(0.2)
self._wait_for_desired_replicas()
self.get()

return self

# ------------------------------------------------------------------------------------- scale
Expand Down
10 changes: 4 additions & 6 deletions kubernetes/K8sHorizontalPodAutoscaler.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sHorizontalPodAutoscaler, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sHorizontalPodAutoscaler, self).list(labels=labels)
hpas = list(map(lambda x: HorizontalPodAutoscaler(x), ls))
if pattern is not None:
hpas = list(filter(lambda x: pattern in x.name, hpas))
k8s = []
for x in hpas:
z = K8sHorizontalPodAutoscaler(config=self.config, name=x.name)
z.model = x
z = K8sHorizontalPodAutoscaler(config=self.config, name=x.name).from_model(m=x)
k8s.append(z)
return k8s

Expand Down Expand Up @@ -119,8 +118,7 @@ def from_json(j=None, cfg=None):
try:
d = convert(json.loads(j))
model = HorizontalPodAutoscaler(model=d)
k8s = K8sHorizontalPodAutoscaler(config=cfg, name="yo")
k8s.model = model
k8s = K8sHorizontalPodAutoscaler(config=cfg, name="yo").from_model(m=model)
return k8s

except TypeError as err:
Expand Down
7 changes: 3 additions & 4 deletions kubernetes/K8sJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sJob, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sJob, self).list(labels=labels)
jobs = list(map(lambda x: Job(x), ls))
if pattern is not None:
jobs = list(filter(lambda x: pattern in x.name, jobs))
k8s = []
for x in jobs:
j = K8sJob(config=self.config, name=x.name)
j.model = x
j = K8sJob(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
7 changes: 3 additions & 4 deletions kubernetes/K8sNamespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ def update(self):
self.get()
return self

def list(self, pattern=None):
ls = super(K8sNamespace, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sNamespace, self).list(labels=labels)
names = list(map(lambda x: Namespace(x), ls))
if pattern is not None:
names = list(filter(lambda x: pattern in x.name, names))
k8s = []
for x in names:
j = K8sNamespace(config=self.config, name=x.name)
j.model = x
j = K8sNamespace(config=self.config, name=x.name).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
45 changes: 42 additions & 3 deletions kubernetes/K8sNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import json
import time

from kubernetes.K8sExceptions import DrainNodeException, TimedOutException
from kubernetes.K8sExceptions import DrainNodeException, TimedOutException, NotFoundException
from kubernetes.K8sNamespace import K8sNamespace
from kubernetes.K8sObject import K8sObject
from kubernetes.K8sPod import K8sPod
from kubernetes.K8sConfig import K8sConfig
from kubernetes.models.v1.Node import Node
from kubernetes.models.v1.NodeCondition import NodeCondition
from kubernetes.utils import is_valid_string, is_valid_list
from kubernetes.models.v1.Taint import Taint

Expand Down Expand Up @@ -48,8 +50,7 @@ def list(self, pattern=None):
nodes = list(filter(lambda x: pattern in x.name, nodes))
k8s = []
for x in nodes:
j = K8sNode(config=self.config, name=x.name)
j.model = x
j = K8sNode(config=self.config, name=x.name).from_model(x)
k8s.append(j)
return k8s

Expand Down Expand Up @@ -125,6 +126,21 @@ def name(self):
def name(self, name=None):
self.model.metadata.name = name

# ------------------------------------------------------------------------------------- is_ready

@property
def is_ready(self):
rc = False
if self.model.status.conditions is not None:
for c in self.model.status.conditions:
assert isinstance(c, NodeCondition)
if c.condition_type == 'Ready' and c.status == 'True':
rc = True
break
else:
continue
return rc

# ------------------------------------------------------------------------------------- filter

@staticmethod
Expand All @@ -135,6 +151,29 @@ def get_by_name(config=None, name=None):
return filtered[0]
return None

@staticmethod
def get_by_labels(config=None, labels=None):

if config is not None and not isinstance(config, K8sConfig):
raise SyntaxError(
'K8sNode.get_by_labels(): config: [ {0} ] is invalid.'.format(config))
if not isinstance(labels, dict):
raise SyntaxError(
'K8sNode.get_by_labels() labels: [ {0} ] is invalid.'.format(labels))

node_list = list()
nodes = K8sObject(config=config, name='whatever').list(labels=labels)

for n in nodes:
try:
model = Node(n)
obj = K8sNode(config=config, name=model.metadata.name).from_model(n)
node_list.append(obj.get())
except NotFoundException:
pass

return node_list

# ------------------------------------------------------------------------------------- pods

@property
Expand Down
26 changes: 22 additions & 4 deletions kubernetes/K8sObject.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,18 @@ def request(self, method='GET', host=None, url=None, auth=None, cert=None,
except IOError as err:
raise BadRequestException('K8sObject: IOError: {0}'.format(err))

def list(self):
state = self.request(method='GET')
def list(self, labels=None):
if labels is not None and isinstance(labels, dict):
filter_list = list()
for k, v in labels.items():
filter_list.append('{0}={1}'.format(k, v))
if len(filter_list) > 1:
data = {'labelSelector': ','.join(filter_list)}
else:
data = {'labelSelector': filter_list[0]}
state = self.request(method='GET', data=data)
else:
state = self.request(method='GET')
if not state.get('status'):
raise Exception('K8sObject: Could not fetch list of objects of type: [ {0} ]'.format(self.obj_type))
if not state.get('success'):
Expand All @@ -272,7 +282,7 @@ def list(self):
raise UnprocessableEntityException(message)
raise BadRequestException(message)
items = state.get('data', dict()).get('items', list())
return items if items is not None else []
return items if items is not None else list()

def get_model(self):
if self.name is None:
Expand All @@ -298,7 +308,7 @@ def get_with_params(self, data=None):
state = self.request(method='GET', url=url, data=data)
items = state.get('data', None).get('items', list())
if items is None:
return []
return list()
return items

def get_exportable(self):
Expand All @@ -318,6 +328,14 @@ def get_exportable(self):
data = state.get('data')
return data

def from_model(self, m=None):
if m is not None:
if isinstance(m, type(self.model)):
self.model = m
else:
raise SyntaxError('Wrong data structure. We need an object of type [ {} ].'.format(type(self.model)))
return self

def create(self):
if self.name is None:
raise SyntaxError('K8sObject: name: [ {0} ] must be set to CREATE the object.'.format(self.name))
Expand Down
7 changes: 3 additions & 4 deletions kubernetes/K8sPersistentVolume.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ def get(self):
self.model = PersistentVolume(self.get_model())
return self

def list(self, pattern=None):
ls = super(K8sPersistentVolume, self).list()
def list(self, pattern=None, labels=None):
ls = super(K8sPersistentVolume, self).list(labels=labels)
vols = list(map(lambda x: PersistentVolume(x), ls))
if pattern is not None:
vols = list(filter(lambda x: pattern in x.name, vols))
k8s = []
for x in vols:
_types = list(filter(lambda z: z in PersistentVolumeSpec.VOLUME_TYPES_TO_SOURCE_MAP, dir(x.spec)))
j = K8sPersistentVolume(config=self.config, name=self.name, type=_types[0])
j.model = x
j = K8sPersistentVolume(config=self.config, name=self.name, type=_types[0]).from_model(m=x)
k8s.append(j)
return k8s

Expand Down
Loading

0 comments on commit 99f2472

Please sign in to comment.