class ApplicationDestroyer(object): """ ApplicationDestroyer is to destroy application instance, including controller and service. """ application = None def __init__(self, application): self.application = application self.application_name = get_application_instance_name(self.application) self.namespace = self.application.image.project.name self.service_name = self.application_name self.controller_name = self.application_name self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP, settings.K8S_PORT, settings.K8S_API_PATH)) def destroy_application_instance(self): """ Destroy application instance by multiple threading. """ deleting_thread = Thread(target=self._destroy_application_instance) deleting_thread.start() def _destroy_application_instance(self): self._update_application_status(status='deleting') if not self._destroy_service_instance(): logger.debug("Delete service {} failed.".format(self.service_name)) if not self._destroy_controller_instance(): logger.debug("Delete controller {} failed.".format( self.controller_name)) if not self._destroy_pods_instance(): logger.debug("Delete pods with label 'app={}' failed.".format( self.controller_name)) self._update_application_status(status='deleted') self._umount_volume() # delete autoscaler if self.application.is_autoscaler: autoscaler_destroyer = AutoScalerDestroyer(self.application) autoscaler_destroyer.delete_autoscaler() self._delete_application_metadata() self._delete_port_metadata() self._delete_environments() def _destroy_service_instance(self): return self.kubeclient.delete_service(namespace=self.namespace, name=self.service_name) def _destroy_controller_instance(self): return self.kubeclient.delete_controller(namespace=self.namespace, name=self.controller_name) def _destroy_pods_instance(self): pods = self.kubeclient.list_pods(namespace=self.namespace, label="app={}".format(self.controller_name)) logger.debug(pods) res = True for pod in pods: flag = self.kubeclient.delete_pod(namespace=self.namespace, name=pod) if not flag: res = False return res def _update_application_status(self, status): self.application.status = status self.application.save() def _delete_application_metadata(self): logger.debug("delete application medatada.") self.application.delete() def _delete_port_metadata(self): logger.debug("delete port metadata.") ports = Port.objects.filter(app=self.application) for port in ports: logger.debug("delete port {} metadata.".format(port.name)) port.delete() def _delete_environments(self): envs = Environment.objects.filter(app=self.application) for env in envs: env.delete() def _umount_volume(self): """ Umount volumes which mounted on application. """ volumes = Volume.objects.filter(app=self.application) for volume in volumes: logger.debug("umount volume {}-{} from application {}.".format( volume.project.name, volume.name, self.application_name)) volume.app = None volume.mount_path = None volume.save()
class KubeClientTestCase(unittest.TestCase): def setUp(self): self.client = KubeClient("http://192.168.0.10:8080/api/v1/") def tearDown(self): self.client = None def test_add_slash(self): url = "http://192.168.0.10:8080" self.assertEqual(KubeClient.add_slash(url), "http://192.168.0.10:8080/") def test_create_instance(self): url = "http://192.168.0.10:8080" client = KubeClient(url) self.assertEqual(client.base_url, "http://192.168.0.10:8080/") def test_send_request(self): res = self.client.send_request("get", "namespaces", labels={ 'a': 1, 'name': 'wangtao' }) self.assertEqual(isinstance(res, dict), True) def test_list_namespaces(self): namespaces = self.client.list_namespces() print(namespaces) self.assertEqual(True, True) def test_list_nodes(self): nodes = self.client.list_nodes() print(nodes) self.assertEqual(True, True) def test_create_namespace(self): self.client.create_namespace('user') def test_delete_namespace(self): self.client.delete_namespace('abcd') def test_list_controllers(self): controllers = self.client.list_controllers('user') print(controllers) def test_create_controller_1(self): image_name = '192.168.0.15:5000/user/nginx:1.9.9' res = self.client.create_controller('user', 'test-nginx', image_name, replicas=2, tcp_ports={"http": 80}) print(res) def test_create_controller_2(self): image_name = '192.168.0.15:5000/admin/ubuntu:14.04' self.client.create_controller('test-space', 'test-nginx', image_name, replicas=1, commands=['sleep', '3600'], envs={"MYSQL": "192.168.0.100"}) def test_create_controller_3(self): image_name = '192.168.0.15:5000/admin/nginx:1.9.9' self.client.create_controller('test-space', 'test-nginx', image_name, replicas=1, tcp_ports={ "http": 80, "https": 443 }) def test_create_controller_volume(self): image_name = '192.168.0.15:5000/user/nginx:1.9.9' self.client.create_controller( 'user', 'test-nginx', image_name, cpu="100m", memory="64Mi", replicas=1, tcp_ports={"http": 80}, volumes={"project0-volume0": "/var/www/html"}) def test_delete_controller(self): self.client.delete_controller('test-space', 'test-nginx') def test_list_services(self): services = self.client.list_services('test-space') print(services) def test_create_service_internal(self): res = self.client.create_service('user', 'test-nginx', tcp_ports={"http": 80}, is_public=False) print(res) def test_create_service_external(self): res = self.client.create_service('test-space', 'test-nginx', tcp_ports={"http": 80}, is_public=True) print(res) def test_create_service_session(self): self.client.create_service('test-space', 'nginx', tcp_ports={"http": 80}, is_public=True, session_affinity=True) def test_delete_service(self): self.client.delete_service('test-space', 'nginx') def test_get_service_details(self): res = self.client.get_service_details('test-space', 'test-nginx') print(res) def test_create_persistentvolume(self): res = self.client.create_persistentvolume( 'default', 'project0-volume0', '10Mi', '/hummer/user/project0/volume0', '192.168.0.15') print(res) def test_delete_persistentvolume(self): res = self.client.delete_persistentvolume('default', 'project0-volume0') print(res) def test_create_persistentvolumeclaim(self): res = self.client.create_persistentvolumeclaim('default', 'project0-volume0', '10Mi') print(res) def test_delete_persistentvolumeclaim(self): res = self.client.delete_persistentvolumeclaim('default', 'project0-volume0') print(res) def test_list_pods(self): res = self.client.list_pods('user', label="app=project0-nginx-test") print(res) def test_get_logs_of_pod(self): res = self.client.get_logs_of_pod('user', 'project0-nginx-test-3uhej', 20) lines = res.split('\n') print(lines) def test_create_autoscaler(self): beta_client = KubeClient( "http://192.168.0.10:8080/apis/extensions/v1beta1/") res = beta_client.create_autoscaler('user', 'project0-nginx-test', 1, 5, 50) print(res) def test_delete_autoscaler(self): beta_client = KubeClient( "http://192.168.0.10:8080/apis/extensions/v1beta1/") res = beta_client.delete_autoscaler('user', 'project0-nginx-test') print(res) def test_list_host_ips(self): hosts = self.client.list_host_ips('user', "app=project0-2048") print(hosts)
class ApplicationDestroyer(object): """ ApplicationDestroyer is to destroy application instance, including controller and service. """ application = None def __init__(self, application): self.application = application self.application_name = get_application_instance_name(self.application) self.namespace = self.application.image.project.name self.service_name = self.application_name self.controller_name = self.application_name self.kubeclient = KubeClient("http://{}:{}{}".format( settings.MASTER_IP, settings.K8S_PORT, settings.K8S_API_PATH)) def destroy_application_instance(self): """ Destroy application instance by multiple threading. """ deleting_thread = Thread(target=self._destroy_application_instance) deleting_thread.start() def _destroy_application_instance(self): self._update_application_status(status='deleting') if not self._destroy_service_instance(): logger.debug("Delete service {} failed.".format(self.service_name)) if not self._destroy_controller_instance(): logger.debug("Delete controller {} failed.".format( self.controller_name)) if not self._destroy_pods_instance(): logger.debug("Delete pods with label 'app={}' failed.".format( self.controller_name)) self._update_application_status(status='deleted') self._umount_volume() # delete autoscaler if self.application.is_autoscaler: autoscaler_destroyer = AutoScalerDestroyer(self.application) autoscaler_destroyer.delete_autoscaler() self._delete_application_metadata() self._delete_port_metadata() self._delete_environments() def _destroy_service_instance(self): return self.kubeclient.delete_service(namespace=self.namespace, name=self.service_name) def _destroy_controller_instance(self): return self.kubeclient.delete_controller(namespace=self.namespace, name=self.controller_name) def _destroy_pods_instance(self): pods = self.kubeclient.list_pods(namespace=self.namespace, label="app={}".format( self.controller_name)) logger.debug(pods) res = True for pod in pods: flag = self.kubeclient.delete_pod(namespace=self.namespace, name=pod) if not flag: res = False return res def _update_application_status(self, status): self.application.status = status self.application.save() def _delete_application_metadata(self): logger.debug("delete application medatada.") self.application.delete() def _delete_port_metadata(self): logger.debug("delete port metadata.") ports = Port.objects.filter(app=self.application) for port in ports: logger.debug("delete port {} metadata.".format(port.name)) port.delete() def _delete_environments(self): envs = Environment.objects.filter(app=self.application) for env in envs: env.delete() def _umount_volume(self): """ Umount volumes which mounted on application. """ volumes = Volume.objects.filter(app=self.application) for volume in volumes: logger.debug("umount volume {}-{} from application {}.".format( volume.project.name, volume.name, self.application_name)) volume.app = None volume.mount_path = None volume.save()
class KubeClientTestCase(unittest.TestCase): def setUp(self): self.client = KubeClient("http://192.168.0.10:8080/api/v1/") def tearDown(self): self.client = None def test_add_slash(self): url = "http://192.168.0.10:8080" self.assertEqual(KubeClient.add_slash(url), "http://192.168.0.10:8080/") def test_create_instance(self): url = "http://192.168.0.10:8080" client = KubeClient(url) self.assertEqual(client.base_url, "http://192.168.0.10:8080/") def test_send_request(self): res = self.client.send_request("get", "namespaces", labels={'a': 1, 'name': 'wangtao'}) self.assertEqual(isinstance(res, dict), True) def test_list_namespaces(self): namespaces = self.client.list_namespces() print(namespaces) self.assertEqual(True, True) def test_list_nodes(self): nodes = self.client.list_nodes() print(nodes) self.assertEqual(True, True) def test_create_namespace(self): self.client.create_namespace('user') def test_delete_namespace(self): self.client.delete_namespace('abcd') def test_list_controllers(self): controllers = self.client.list_controllers('user') print(controllers) def test_create_controller_1(self): image_name = '192.168.0.15:5000/user/nginx:1.9.9' res = self.client.create_controller('user', 'test-nginx', image_name, replicas=2, tcp_ports={"http": 80}) print(res) def test_create_controller_2(self): image_name = '192.168.0.15:5000/admin/ubuntu:14.04' self.client.create_controller('test-space', 'test-nginx', image_name, replicas=1, commands=['sleep', '3600'], envs={"MYSQL": "192.168.0.100"} ) def test_create_controller_3(self): image_name = '192.168.0.15:5000/admin/nginx:1.9.9' self.client.create_controller('test-space', 'test-nginx', image_name, replicas=1, tcp_ports={"http": 80, "https": 443}) def test_create_controller_volume(self): image_name = '192.168.0.15:5000/user/nginx:1.9.9' self.client.create_controller('user', 'test-nginx', image_name, cpu="100m", memory="64Mi", replicas=1, tcp_ports={"http": 80}, volumes={"project0-volume0": "/var/www/html"}) def test_delete_controller(self): self.client.delete_controller('test-space', 'test-nginx') def test_list_services(self): services = self.client.list_services('test-space') print(services) def test_create_service_internal(self): res = self.client.create_service('user', 'test-nginx', tcp_ports={"http": 80}, is_public=False ) print(res) def test_create_service_external(self): res = self.client.create_service('test-space', 'test-nginx', tcp_ports={"http": 80}, is_public=True ) print(res) def test_create_service_session(self): self.client.create_service('test-space', 'nginx', tcp_ports={"http": 80}, is_public=True, session_affinity=True ) def test_delete_service(self): self.client.delete_service('test-space', 'nginx') def test_get_service_details(self): res = self.client.get_service_details('test-space', 'test-nginx') print(res) def test_create_persistentvolume(self): res = self.client.create_persistentvolume('default', 'project0-volume0', '10Mi', '/hummer/user/project0/volume0', '192.168.0.15') print(res) def test_delete_persistentvolume(self): res = self.client.delete_persistentvolume('default', 'project0-volume0') print(res) def test_create_persistentvolumeclaim(self): res = self.client.create_persistentvolumeclaim('default', 'project0-volume0', '10Mi') print(res) def test_delete_persistentvolumeclaim(self): res = self.client.delete_persistentvolumeclaim('default', 'project0-volume0') print(res) def test_list_pods(self): res = self.client.list_pods('user', label="app=project0-nginx-test") print(res) def test_get_logs_of_pod(self): res = self.client.get_logs_of_pod('user', 'project0-nginx-test-3uhej', 20) lines = res.split('\n') print(lines) def test_create_autoscaler(self): beta_client = KubeClient("http://192.168.0.10:8080/apis/extensions/v1beta1/") res = beta_client.create_autoscaler('user', 'project0-nginx-test', 1, 5, 50) print(res) def test_delete_autoscaler(self): beta_client = KubeClient("http://192.168.0.10:8080/apis/extensions/v1beta1/") res = beta_client.delete_autoscaler('user', 'project0-nginx-test') print(res) def test_list_host_ips(self): hosts = self.client.list_host_ips('user', "app=project0-2048") print(hosts)