From 2a12adeaba3df948f820a843c5a0fd3d81b24576 Mon Sep 17 00:00:00 2001
From: FreakyGranny
Date: Mon, 3 Jun 2019 15:48:40 +0700
Subject: [PATCH] change sync-mode logic with hpa support (#98)
---
k8s_handle/k8s/mocks.py | 57 ++++++++++++++++--------------
k8s_handle/k8s/provisioner.py | 20 ++++++-----
k8s_handle/k8s/test_provisioner.py | 12 ++-----
3 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/k8s_handle/k8s/mocks.py b/k8s_handle/k8s/mocks.py
index f57b13a..47fa798 100644
--- a/k8s_handle/k8s/mocks.py
+++ b/k8s_handle/k8s/mocks.py
@@ -16,24 +16,26 @@ def read_namespaced_deployment(self, name, namespace):
if self.name == '404' or name == '404':
raise ApiException(reason='Not Found')
- my_response = namedtuple('my_response', 'metadata status')
+ my_response = namedtuple('my_response', 'metadata status spec')
my_status = namedtuple('my_status',
'replicas available_replicas ready_replicas updated_replicas unavailable_replicas')
-
+ my_spec = namedtuple('my_spec', 'replicas')
if self.name == 'test1':
- return my_response(metadata={}, status=my_status(replicas=3,
- available_replicas=2,
- ready_replicas=1,
- updated_replicas=None,
- unavailable_replicas=1))
+ return my_response(metadata={}, spec=my_spec(replicas=3),
+ status=my_status(replicas=3,
+ available_replicas=2,
+ ready_replicas=1,
+ updated_replicas=None,
+ unavailable_replicas=1))
if self.name == 'test2' or name == 'test2':
- return my_response(metadata={}, status=my_status(replicas=1,
- available_replicas=1,
- ready_replicas=1,
- updated_replicas=1,
- unavailable_replicas=None))
+ return my_response(metadata={}, spec=my_spec(replicas=1),
+ status=my_status(replicas=1,
+ available_replicas=1,
+ ready_replicas=1,
+ updated_replicas=1,
+ unavailable_replicas=None))
- return my_response(metadata={'key1': 'value1'}, status={'key1': 'value1'})
+ return my_response(metadata={'key1': 'value1'}, status={'key1': 'value1'}, spec={'key1': 'value1'})
def create_namespaced_deployment(self, body, namespace):
if self.name == 'fail':
@@ -113,25 +115,28 @@ def read_namespaced_stateful_set(self, name, namespace):
if self.name == '404':
raise ApiException(reason='Not Found')
- my_response = namedtuple('my_response', 'metadata status')
+ my_response = namedtuple('my_response', 'metadata status spec')
my_status = namedtuple('my_status',
'current_replicas current_revision ready_replicas replicas update_revision')
+ my_spec = namedtuple('my_spec', 'replicas')
if self.name == 'test1':
- return my_response(metadata={}, status=my_status(current_replicas=2,
- current_revision='revision-123',
- ready_replicas=1,
- replicas=3,
- update_revision='revision-321'))
+ return my_response(metadata={}, spec=my_spec(replicas=3),
+ status=my_status(current_replicas=2,
+ current_revision='revision-123',
+ ready_replicas=1,
+ replicas=3,
+ update_revision='revision-321'))
if self.name == 'test2':
- return my_response(metadata={}, status=my_status(current_replicas=3,
- current_revision='revision-123',
- ready_replicas=3,
- replicas=3,
- update_revision='revision-123'))
-
- return my_response(metadata={'key1': 'value1'}, status={'key1': 'value1'})
+ return my_response(metadata={}, spec=my_spec(replicas=3),
+ status=my_status(current_replicas=3,
+ current_revision='revision-123',
+ ready_replicas=3,
+ replicas=3,
+ update_revision='revision-123'))
+
+ return my_response(metadata={'key1': 'value1'}, status={'key1': 'value1'}, spec={'key1': 'value1'})
# DaemonSet
def read_namespaced_daemon_set(self, name, namespace):
diff --git a/k8s_handle/k8s/provisioner.py b/k8s_handle/k8s/provisioner.py
index eabab55..c739ebf 100644
--- a/k8s_handle/k8s/provisioner.py
+++ b/k8s_handle/k8s/provisioner.py
@@ -20,9 +20,9 @@ def __init__(self, command, sync_mode, show_logs):
self.show_logs = show_logs
@staticmethod
- def _replicas_count_are_greater_or_equal(replicas):
+ def _replicas_count_are_equal(replicas):
replicas = [0 if r is None else r for r in replicas] # replace all None to 0
- return all(r >= replicas[0] for r in replicas)
+ return all(r == replicas[0] for r in replicas)
@staticmethod
def _ports_are_equal(old_port, new_port):
@@ -326,14 +326,15 @@ def _get_pod_name_and_containers_by_selector(kube_client, selector, tries, timeo
def _wait_deployment_complete(self, kube_client, tries, timeout):
for i in range(0, tries):
sleep(timeout)
- status = kube_client.get().status
+ deployment = kube_client.get()
+ status = deployment.status
- replicas = [kube_client.replicas, status.replicas, status.available_replicas,
+ replicas = [deployment.spec.replicas, status.replicas, status.available_replicas,
status.ready_replicas, status.updated_replicas]
log.info('desiredReplicas = {}, updatedReplicas = {}, availableReplicas = {}'.
format(replicas[0], replicas[4], replicas[2]))
- if self._replicas_count_are_greater_or_equal(replicas) and status.unavailable_replicas is None:
+ if self._replicas_count_are_equal(replicas) and status.unavailable_replicas is None:
log.info('Deployment completed on {} attempt'.format(i + 1))
return
else:
@@ -344,17 +345,18 @@ def _wait_deployment_complete(self, kube_client, tries, timeout):
def _wait_statefulset_complete(self, kube_client, tries, timeout):
for i in range(0, tries):
sleep(timeout)
- status = kube_client.get().status
+ statefulset = kube_client.get()
+ status = statefulset.status
current_revision = status.current_revision
update_revision = status.update_revision
- replicas = [kube_client.replicas, status.current_replicas, status.ready_replicas]
+ replicas = [statefulset.spec.replicas, status.current_replicas, status.ready_replicas]
log.info('Current revision {}, should be {}'.format(current_revision, update_revision))
if current_revision == update_revision:
log.info('desiredReplicas = {}, updatedReplicas = {}, availableReplicas = {}'.
format(replicas[0], replicas[1], replicas[2]))
- if self._replicas_count_are_greater_or_equal(replicas):
+ if self._replicas_count_are_equal(replicas):
log.info('StatefulSet completed on {} attempt'.format(i))
return
else:
@@ -371,7 +373,7 @@ def _wait_daemonset_complete(self, kube_client, tries, timeout):
status.number_ready, status.updated_number_scheduled]
log.info('desiredNodes = {}, availableNodes = {}, readyNodes = {}, updatedNodes = {}'.
format(replicas[0], replicas[1], replicas[2], replicas[3]))
- if self._replicas_count_are_greater_or_equal(replicas) and status.number_unavailable is None:
+ if self._replicas_count_are_equal(replicas) and status.number_unavailable is None:
log.info('DaemonSet completed on {} attempt'.format(i))
return
else:
diff --git a/k8s_handle/k8s/test_provisioner.py b/k8s_handle/k8s/test_provisioner.py
index 4df954e..95c1a39 100644
--- a/k8s_handle/k8s/test_provisioner.py
+++ b/k8s_handle/k8s/test_provisioner.py
@@ -375,16 +375,8 @@ def test_get_template_contexts(self):
class TestKubeObject(unittest.TestCase):
def test_replicas_equal(self):
replicas = (1, 1, 1)
- self.assertTrue(Provisioner._replicas_count_are_greater_or_equal(replicas))
-
- def test_replicas_greater(self):
- replicas = (2, 3, 3)
- self.assertTrue(Provisioner._replicas_count_are_greater_or_equal(replicas))
+ self.assertTrue(Provisioner._replicas_count_are_equal(replicas))
def test_replicas_not_equal(self):
replicas = (1, 1, 0)
- self.assertFalse(Provisioner._replicas_count_are_greater_or_equal(replicas))
-
- def test_replicas_with_hpa_not_equal(self):
- replicas = (6, 7, 5)
- self.assertFalse(Provisioner._replicas_count_are_greater_or_equal(replicas))
+ self.assertFalse(Provisioner._replicas_count_are_equal(replicas))