Beispiel #1
0
    def create(self, request, *args, **kwargs):
        """
        Create project by only admin users.
        """
        self.check_admin_permission()

        project = Project.objects.filter(name=request.data.get('name', None))
        if project:
            raise ValidationError(detail="Already has an project called {}."
                .format(request.data['name']))

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        response = Response(serializer.data, status=status.HTTP_201_CREATED,
            headers=headers)

        # Create the namespace
        try:
            kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
                settings.K8S_PORT, settings.K8S_API_PATH))
            kubeclient.create_namespace(serializer.data['name'])
        except Exception as e:
            logger.error(e)

        logger.info("User {} create a new project {}.".format(
            request.user.username, serializer.data['name']))

        return response
Beispiel #2
0
def get_optimal_external_ip(namespace, app_name):
    """
    Return the optimal external ip from all host ips of the application.
    """
    kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))
    label = "app=" + app_name
    hosts = kubeclient.list_host_ips(namespace=namespace, label=label)
    # logger.debug(hosts)
    index = random.randint(0, len(hosts) - 1)
    return hosts[index]
Beispiel #3
0
    def pod_lists(self, request, *args, **kwargs):
        """
        Return the pods list of the application with json.
        """
        application = self.get_object()

        if not application:
            raise ValidationError(detail="The application doesn't exist.")

        kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))
        pods = kubeclient.list_pods(namespace=application.image.project.name,
            label="app={}".format(get_application_instance_name(application)))
        logger.debug(pods)

        return Response(pods, status=status.HTTP_200_OK)
Beispiel #4
0
    def __init__(self, application, image_name, tcp_ports=None,
        udp_ports=None, commands=None, args=None, envs=None, is_public=False,
        volumes=None, min_replicas=None, max_replicas=None, cpu_target=None):
        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))

        self.application = application
        self.namespace = self.application.image.project.name
        self.application_name = get_application_instance_name(self.application)
        self.image_name = image_name
        self.tcp_ports = tcp_ports
        self.udp_ports = udp_ports
        self.commands = commands
        self.args = args
        self.envs = envs
        self.is_public = is_public
        self.volumes = volumes

        # Compute the resource limit of the application
        resource_limit = self.application.resource_limit
        self.cpu = str(resource_limit.cpu) + resource_limit.cpu_unit
        self.memory = str(resource_limit.memory) + resource_limit.memory_unit

        # autoscaler
        if self.application.is_autoscaler:
            self.min_replicas = int(min_replicas)
            self.max_replicas = int(max_replicas)
            self.cpu_target = int(cpu_target)
            logger.debug(str(self.min_replicas) + " " + str(self.max_replicas)
                + " " + str(self.cpu_target))
Beispiel #5
0
class AutoScalerDestroyer(object):
    """
    AutoScalerDestroyer is to destroy autoscaler instance when deleting
    application.
    """
    def __init__(self, application):
        self.application = application
        self.application_name = get_application_instance_name(self.application)
        self.namespace = self.application.image.project.name

        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_V1BETA1_API_PATH))

    def delete_autoscaler(self):
        """
        Destroy autoscaler for application instance by multiple threading.
        """
        deleting_thread = Thread(target=self._delete_autoscaler_instance)
        deleting_thread.start()

    def _delete_autoscaler_instance(self):
        scalers = AutoScaler.objects.filter(app=self.application)
        for scaler in scalers:
            scaler.delete()

        ok = self.kubeclient.delete_autoscaler(namespace=self.namespace,
            name=self.application_name)
        if not ok:
            logger.error("Delete autoscaler {} failed.".format(
                self.application_name))
        else:
            logger.debug("Delete autoscaler {} successfully.".format(
                self.application_name))
Beispiel #6
0
    def __init__(self, application):
        self.application = application
        self.application_name = get_application_instance_name(self.application)
        self.namespace = self.application.image.project.name

        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_V1BETA1_API_PATH))
Beispiel #7
0
    def destroy(self, request, *args, **kwargs):
        """
        Destroy an Project instance.
        """
        self.check_admin_permission()

        project = self.get_object()

        # Delete the namespace
        try:
            kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
                settings.K8S_PORT, settings.K8S_API_PATH))
            kubeclient.delete_namespace(project.name)
        except Exception as e:
            logger.error(e)

        logger.info("User {} delete the project {}.".format(
            request.user.username, project.name))

        return super(ProjectViewSet, self).destroy(request, *args, **kwargs)
Beispiel #8
0
    def __init__(self, application, min_replicas=-1, max_replicas=-1,
        cpu_target=-1):
        self.application = application
        self.application_name = get_application_instance_name(self.application)
        self.namespace = self.application.image.project.name
        self.min_replicas = min_replicas
        self.max_replicas = max_replicas
        self.cpu_target = cpu_target

        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_V1BETA1_API_PATH))
Beispiel #9
0
    def destroy(self, request, *args, **kwargs):
        """
        Destroy an Project instance.
        """
        self.check_admin_permission()

        project = self.get_object()

        # Delete the namespace
        try:
            kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
                settings.K8S_PORT, settings.K8S_API_PATH))
            kubeclient.delete_namespace(project.name)
        except Exception as e:
            logger.error(e)

        logger.info("User {} delete the project {}.".format(
            request.user.username, project.name))

        return super(ProjectViewSet, self).destroy(request, *args, **kwargs)
Beispiel #10
0
    def __init__(self,
                 application,
                 image_name,
                 tcp_ports=None,
                 udp_ports=None,
                 commands=None,
                 args=None,
                 envs=None,
                 is_public=False,
                 volumes=None,
                 min_replicas=None,
                 max_replicas=None,
                 cpu_target=None):
        self.kubeclient = KubeClient("http://{}:{}{}".format(
            settings.MASTER_IP, settings.K8S_PORT, settings.K8S_API_PATH))

        self.application = application
        self.namespace = self.application.image.project.name
        self.application_name = get_application_instance_name(self.application)
        self.image_name = image_name
        self.tcp_ports = tcp_ports
        self.udp_ports = udp_ports
        self.commands = commands
        self.args = args
        self.envs = envs
        self.is_public = is_public
        self.volumes = volumes

        # Compute the resource limit of the application
        resource_limit = self.application.resource_limit
        self.cpu = str(resource_limit.cpu) + resource_limit.cpu_unit
        self.memory = str(resource_limit.memory) + resource_limit.memory_unit

        # autoscaler
        if self.application.is_autoscaler:
            self.min_replicas = int(min_replicas)
            self.max_replicas = int(max_replicas)
            self.cpu_target = int(cpu_target)
            logger.debug(
                str(self.min_replicas) + " " + str(self.max_replicas) + " " +
                str(self.cpu_target))
Beispiel #11
0
    def __init__(self, volume):
        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))

        self.volume = volume
        self.namespace = self.volume.project.name
        self.project_name = self.volume.project.name
        self.volume_name = self.volume.name
        self.capacity = str(self.volume.capacity) + self.volume.capacity_unit
        self.nfs_path = get_volume_nfs_dir(settings.NFS_BASE_DIR,
            self.namespace, self.volume.name)
        self.nfs_server = settings.NFS_IP
Beispiel #12
0
    def list_pods(self, request, *args, **kwargs):
        """
        AdminUser search pods for application id.
        """
        user = self.request.user
        if not user.is_staff:
            raise PermissionDenied()

        app_id = request.GET.get('app', 0)
        try:
            application = Application.objects.get(id=app_id)
        except Exception:
            return Response(status=status.HTTP_200_OK)

        kubeclient = KubeClient("http://{}:{}{}".format(
            settings.MASTER_IP, settings.K8S_PORT, settings.K8S_API_PATH))
        pods = kubeclient.list_pods(
            namespace=application.image.project.name,
            label="app={}".format(get_application_instance_name(application)))
        logger.debug(pods)

        return Response(pods, status=status.HTTP_200_OK)
Beispiel #13
0
    def list_pods(self, request, *args, **kwargs):
        """
        AdminUser search pods for application id.
        """
        user = self.request.user
        if not user.is_staff:
            raise PermissionDenied()

        app_id = request.GET.get('app', 0)
        try:
            application = Application.objects.get(id=app_id)
        except Exception:
            return Response(status=status.HTTP_200_OK)

        kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))
        pods = kubeclient.list_pods(
            namespace=application.image.project.name,
            label="app={}".format(get_application_instance_name(application)))
        logger.debug(pods)

        return Response(pods, status=status.HTTP_200_OK)
Beispiel #14
0
class AutoScalerBuilder(object):
    """
    AutoScalerBuilder is a builder to create an autoscaler for application. You
    should offer many necessary arguments.

    Parameters:
    min_replicas, max_replicas, cpu_target: integer parameters, -1 represents
    infinite big value.
    """
    def __init__(self,
                 application,
                 min_replicas=-1,
                 max_replicas=-1,
                 cpu_target=-1):
        self.application = application
        self.application_name = get_application_instance_name(self.application)
        self.namespace = self.application.image.project.name
        self.min_replicas = min_replicas
        self.max_replicas = max_replicas
        self.cpu_target = cpu_target

        self.kubeclient = KubeClient("http://{}:{}{}".format(
            settings.MASTER_IP, settings.K8S_PORT,
            settings.K8S_V1BETA1_API_PATH))

    def create_autoscaler(self):
        """
        Create autoscaler instance for application by multiple threading.
        """
        creating_thread = Thread(target=self._create_autoscaler_instance)
        creating_thread.start()

    def _create_autoscaler_instance(self):
        ok = self.kubeclient.create_autoscaler(namespace=self.namespace,
                                               name=self.application_name,
                                               minReplicas=self.min_replicas,
                                               maxReplicas=self.max_replicas,
                                               cpu_target=self.cpu_target)
        if not ok:
            logger.error("Create autoscaler {} failed.".format(
                self.application_name))
            return None
        logger.debug("Create autoscaler {} successfully.".format(
            self.application_name))

        scaler = AutoScaler(app=self.application,
                            min_replicas=self.min_replicas,
                            max_replicas=self.max_replicas,
                            cpu_target=self.cpu_target)
        scaler.save()
Beispiel #15
0
    def logs_pod(self, request, *args, **kwargs):
        """
        Return the tail n lines logs of pod.
        """
        user = request.user

        assert 'pid' in self.kwargs
        pid = self.kwargs['pid']
        project = Project.objects.get(id=pid)

        if not check_member_in_project(project, user):
            raise PermissionDenied(detail="User {} is not in project {}."
                .format(user.username, project.name))

        assert 'pod' in self.kwargs
        pod = self.kwargs['pod']
        tailLine = int(request.query_params['tail'])

        kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))
        logs = kubeclient.get_logs_of_pod(project.name, pod, tailLine)
        # print(logs)

        return Response(data=logs, status=status.HTTP_200_OK)
Beispiel #16
0
    def logs_pod(self, request, *args, **kwargs):
        """
        Return the tail n lines logs of pod.
        """
        user = request.user

        assert 'pid' in self.kwargs
        pid = self.kwargs['pid']
        project = Project.objects.get(id=pid)

        if not check_member_in_project(project, user):
            raise PermissionDenied(detail="User {} is not in project {}."
                .format(user.username, project.name))

        assert 'pod' in self.kwargs
        pod = self.kwargs['pod']
        tailLine = int(request.query_params['tail'])

        kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))
        logs = kubeclient.get_logs_of_pod(project.name, pod, tailLine)
        # print(logs)

        return Response(data=logs, status=status.HTTP_200_OK)
Beispiel #17
0
class AutoScalerBuilder(object):
    """
    AutoScalerBuilder is a builder to create an autoscaler for application. You
    should offer many necessary arguments.

    Parameters:
    min_replicas, max_replicas, cpu_target: integer parameters, -1 represents
    infinite big value.
    """
    def __init__(self, application, min_replicas=-1, max_replicas=-1,
        cpu_target=-1):
        self.application = application
        self.application_name = get_application_instance_name(self.application)
        self.namespace = self.application.image.project.name
        self.min_replicas = min_replicas
        self.max_replicas = max_replicas
        self.cpu_target = cpu_target

        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_V1BETA1_API_PATH))

    def create_autoscaler(self):
        """
        Create autoscaler instance for application by multiple threading.
        """
        creating_thread = Thread(target=self._create_autoscaler_instance)
        creating_thread.start()

    def _create_autoscaler_instance(self):
        ok = self.kubeclient.create_autoscaler(
            namespace=self.namespace,
            name=self.application_name,
            minReplicas=self.min_replicas,
            maxReplicas=self.max_replicas,
            cpu_target=self.cpu_target)
        if not ok:
            logger.error("Create autoscaler {} failed.".format(
                self.application_name))
            return None
        logger.debug("Create autoscaler {} successfully.".format(
            self.application_name))

        scaler = AutoScaler(app=self.application,
            min_replicas=self.min_replicas,
            max_replicas=self.max_replicas,
            cpu_target=self.cpu_target)
        scaler.save()
Beispiel #18
0
 def test_add_slash(self):
     url = "http://192.168.0.10:8080"
     self.assertEqual(KubeClient.add_slash(url),
                      "http://192.168.0.10:8080/")
Beispiel #19
0
 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)
Beispiel #20
0
 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/")
Beispiel #21
0
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)
Beispiel #22
0
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()
Beispiel #23
0
 def setUp(self):
     self.client = KubeClient("http://192.168.0.10:8080/api/v1/")
Beispiel #24
0
 def setUp(self):
     self.client = KubeClient("http://192.168.0.10:8080/api/v1/")
Beispiel #25
0
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)
Beispiel #26
0
 def test_add_slash(self):
     url = "http://192.168.0.10:8080"
     self.assertEqual(KubeClient.add_slash(url), "http://192.168.0.10:8080/")
Beispiel #27
0
class VolumeDestroyer(object):
    """
    VolumeDestroyer is to destroy volume instance, including volume direction,
    persistentvolume and persistentvolumeclaim.
    """
    volume = None

    def __init__(self, volume):
        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))

        self.volume = volume
        self.namespace = self.volume.project.name
        self.project_name = self.volume.project.name
        self.volume_name = self.volume.name
        self.capacity = str(self.volume.capacity) + self.volume.capacity_unit
        self.nfs_path = get_volume_nfs_dir(settings.NFS_BASE_DIR,
            self.namespace, self.volume.name)
        self.nfs_server = settings.NFS_IP

    def destroy_volume(self):
        """
        Destroy volume instance by multiple threading.
        """
        deleting_thread = Thread(target=self._destroy_volume_instance)
        deleting_thread.start()

    def _destroy_volume_instance(self):
        logger.info('User {} delete volume {} in project {}.'.format(
            self.volume.user.username, self.volume.name, self.project_name))

        self._update_volume_status(status='deleting')

        if not self._remove_volume_dir_on_nfs():
            logger.debug("remove direction {} on nfs server failed.".format(
                self.nfs_path))
        else:
            logger.info("remove direction {} on nfs server successfully."
                .format(self.nfs_path))

        if not self._delete_persistentvolumeclaim():
            logger.debug("delete persistentvolumeclaim {} failed.".format(
                self.volume_name))
        else:
            logger.debug("delete persistentvolumeclaim {} successfully."
                .format(self.volume_name))

        if not self._delete_persistentvolume():
            logger.debug("delete persistentvolume {}-{} failed.".format(
                self.namespace, self.volume_name))
        else:
            logger.debug("delete persistentvolume {}-{} successfully.".format(
                self.namespace, self.volume_name))

        # self._update_volume_status(status='deleted')
        self._delete_volume_metadata()

    def _remove_volume_dir_on_nfs(self):
        """
        Remove direction on nfs server.
        """
        client = NFSLocalClient()
        client.removedir(self.nfs_path)
        return True

    def _delete_persistentvolumeclaim(self):
        return self.kubeclient.delete_persistentvolumeclaim(
            namespace=self.namespace, name=self.volume_name)

    def _delete_persistentvolume(self):
        return self.kubeclient.delete_persistentvolume(
            namespace=self.namespace, name=self.volume_name)

    def _update_volume_status(self, status):
        self.volume.status = status
        self.volume.save()

    def _delete_volume_metadata(self):
        logger.debug("delete volume {} metadata.".format(self.volume_name))
        self.volume.delete()
Beispiel #28
0
class ApplicationBuilder(object):
    """
    ApplicationBuilder is a builder to create an appliction from an image. You
    should offer many necessary arguments.

    Parameters:
    image_name: the image name for the container.
    tcp_ports: a dict, the tcp ports of the containers. For example: {
        "http": 80, "https": 443}
    udp_ports: a dict, the udp ports of the containers.
    commands: the commands which the container runs when start.
    envs: a dict for example: {"MYSQL_HOST": "localhost", "PORT": "3306"}
    volumes: a dict, for example: [{"volume": id, "mount_path": path}]
    """
    namespace = None
    application = None
    image_name = None
    tcp_ports = None
    udp_ports = None
    commands = None
    args = None
    envs = None
    is_public = False
    volumes = None

    def __init__(self, application, image_name, tcp_ports=None,
        udp_ports=None, commands=None, args=None, envs=None, is_public=False,
        volumes=None, min_replicas=None, max_replicas=None, cpu_target=None):
        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))

        self.application = application
        self.namespace = self.application.image.project.name
        self.application_name = get_application_instance_name(self.application)
        self.image_name = image_name
        self.tcp_ports = tcp_ports
        self.udp_ports = udp_ports
        self.commands = commands
        self.args = args
        self.envs = envs
        self.is_public = is_public
        self.volumes = volumes

        # Compute the resource limit of the application
        resource_limit = self.application.resource_limit
        self.cpu = str(resource_limit.cpu) + resource_limit.cpu_unit
        self.memory = str(resource_limit.memory) + resource_limit.memory_unit

        # autoscaler
        if self.application.is_autoscaler:
            self.min_replicas = int(min_replicas)
            self.max_replicas = int(max_replicas)
            self.cpu_target = int(cpu_target)
            logger.debug(str(self.min_replicas) + " " + str(self.max_replicas)
                + " " + str(self.cpu_target))

    def create_application(self):
        """
        Create application by multiple threading.
        """
        creating_thread = Thread(target=self._create_application)
        creating_thread.start()

    def _create_application(self):
        """
        First create a replicationcontroller, then create a service, update
        database at last.
        """
        logger.info('Create an application {} in namespace {} by image {}.'
            .format(self.application_name, self.namespace, self.image_name))

        if not self._create_controller():
            logger.debug('Create controller {} failed.'.format(
                self.application_name))
            logger.info('Create an application {} in namespace {} failed.'
            .format(self.application_name, self.namespace, self.image_name))

            self._update_application_metadata(status='error')
            return None

        if self.tcp_ports or self.udp_ports:
            if not self._create_service():
                logger.debug('Create service {} failed.'.format(
                    self.application_name))
                logger.info('Create an application {} in namespace {} failed.'
                .format(self.application_name, self.namespace, self.image_name))

                self._update_application_metadata(status='error')
                return None
            internal_ip, ports = self._get_service_ip_and_ports()
        else:
            internal_ip = None
            ports = None

        # update metadata
        if self.is_public:
            external_ip = get_optimal_external_ip(namespace=self.namespace,
                app_name=self.application_name)
            self._update_application_metadata(status='active',
                internal_ip=internal_ip,
                external_ip=external_ip
            )
        else:
            self._update_application_metadata(status='active',
                internal_ip=internal_ip
            )

        # mount volume
        self._mount_volume_onto_application()

        # create port metadata
        self._create_ports_metadata(ports)

        # create environment metadata
        self._create_environments_metadata()

        # create autoscaler
        if self.application.is_autoscaler:
            scaler_builder = AutoScalerBuilder(
                application=self.application,
                min_replicas=self.min_replicas,
                max_replicas=self.max_replicas,
                cpu_target=self.cpu_target
            )
            scaler_builder.create_autoscaler()

    def _create_controller(self):
        """
        Create a replicationcontroller by provided image.
        """
        return self.kubeclient.create_controller(namespace=self.namespace,
            name=self.application_name,
            image_name=self.image_name,
            cpu=self.cpu,
            memory=self.memory,
            replicas=self.application.replicas,
            tcp_ports=self.tcp_ports,
            udp_ports=self.udp_ports,
            commands=self.commands,
            args=self.args,
            envs=self.envs,
            volumes=self._get_volume_names_and_path()
        )

    def _create_service(self):
        """
        Create a service on the replicationcontroller.
        """
        return self.kubeclient.create_service(namespace=self.namespace,
            name=self.application_name,
            tcp_ports=self.tcp_ports,
            udp_ports=self.udp_ports,
            is_public=self.is_public,
            session_affinity=self.application.session_affinity
        )

    def _get_service_ip_and_ports(self):
        """
        Get internal_ip and ports of the service.
        """
        response = self.kubeclient.get_service_details(self.namespace,
            self.application_name)
        return (response['spec']['clusterIP'], response['spec']['ports'])

    def _update_application_metadata(self, status=None, internal_ip=None,
        external_ip=None):
        """
        Update the application metadata.
        """
        if status:
            self.application.status = status
        if internal_ip:
            self.application.internal_ip = internal_ip
        if external_ip:
            self.application.external_ip = external_ip

        self.application.save()

    def _create_ports_metadata(self, ports):
        """
        Create ports metadata for application.
        """
        if not ports:
            return None

        for port_dict in ports:
            port = Port(app=self.application,
                name=port_dict['name'],
                protocol=port_dict['protocol'],
                external_port=port_dict.get('nodePort', None),
                internal_port=port_dict['port']
            )
            port.save()

    def _create_environments_metadata(self):
        """
        Create environment metadata for application.
        """
        if not self.envs:
            return None

        for name, value in self.envs.items():
            env = Environment(app=self.application,
                name=name, value=value)
            env.save()

    def _mount_volume_onto_application(self):
        """
        Edit the metadata, Mount volumes onto this application.
        """
        if not self.volumes:
            return None
        for volume_item in self.volumes:
            volume = Volume.objects.get(id=volume_item['volume'])
            logger.debug("mount volume {} onto application {}.".format(
                volume.name, self.application_name))
            volume.app = self.application
            volume.mount_path = volume_item['mount_path']
            volume.save()

    def _get_volume_names_and_path(self):
        """
        Return the volume names from volume ids. The true volume instance name
        is "project_name-volume_name".
        """
        if not self.volumes:
            return None
        volume_name_path = {}
        for volume_item in self.volumes:
            volume = Volume.objects.get(id=int(volume_item['volume']))
            volume_name = "{}-{}".format(self.namespace, volume.name)
            volume_name_path[volume_name] = volume_item['mount_path']
        logger.debug(volume_name_path)
        return volume_name_path
Beispiel #29
0
class VolumeBuilder(object):
    """
    VolumeBuilder is a builder to create an volume for persistent data storagy.

    """
    volume = None

    def __init__(self, volume):
        self.kubeclient = KubeClient("http://{}:{}{}".format(settings.MASTER_IP,
            settings.K8S_PORT, settings.K8S_API_PATH))

        self.volume = volume
        self.namespace = self.volume.project.name
        self.project_name = self.volume.project.name
        self.volume_name = self.volume.name
        self.capacity = str(self.volume.capacity) + self.volume.capacity_unit
        self.nfs_path = get_volume_nfs_dir(settings.NFS_BASE_DIR,
            self.namespace, self.volume.name)
        self.nfs_server = settings.NFS_IP

    def create_volume(self):
        """
        Create volume by multiple threading.
        """
        creating_thread = Thread(target=self._create_volume)
        creating_thread.start()

    def _create_volume(self):
        """
        First create a persistentvolume, then create a persistentvolumeclaim.
        """
        logger.info('User {} create a volume {} in project {}.'.format(
            self.volume.user.username, self.volume.name, self.project_name))

        # create volume dir on nfs server
        if self._create_volume_dir_on_nfs():
            logger.info("Create dir {} on nfs server {} successfully.".format(
                self.nfs_path, self.nfs_server))
        else:
            logger.info("Create dir {} on nfs server {} failed.".format(
                self.nfs_path, self.nfs_server))
            self._update_volume_status(status='error')
            return None

        # create persistentvolume
        if self._create_persistentvolume():
            logger.info("Create persistentvolume {}-{} successfully.".format(
                self.namespace, self.volume_name))
        else:
            logger.info("Create persistentvolume {}-{} failed.".format(
                self.namespace, self.volume_name))
            self._update_volume_status(status='error')
            return None

        # create persistentvolumeclaim
        if self._create_persistentvolumeclaim():
            logger.info("Create persistentvolumeclaim {} successfully.".format(
                self.volume_name))
        else:
            logger.info("Create persistentvolumeclaim {} failed.".format(
                self.volume_name))
            self._update_volume_status(status='error')
            return None

        self._update_volume_status(status='active')

    def _create_volume_dir_on_nfs(self):
        """
        Create direction on nfs server to store volume data.
        """
        client = NFSLocalClient()
        client.removedir(self.nfs_path)
        client.makedir(self.nfs_path)
        return True

    def _create_persistentvolume(self):
        return self.kubeclient.create_persistentvolume(
            namespace=self.namespace,
            name=self.volume_name,
            capacity=self.capacity,
            nfs_path=self.nfs_path,
            nfs_server=self.nfs_server
            )

    def _create_persistentvolumeclaim(self):
        return self.kubeclient.create_persistentvolumeclaim(
            namespace=self.namespace,
            name=self.volume_name,
            capacity=self.capacity
            )

    def _update_volume_status(self, status):
        self.volume.status = status
        self.volume.save()
Beispiel #30
0
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()
Beispiel #31
0
 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)
Beispiel #32
0
class ApplicationBuilder(object):
    """
    ApplicationBuilder is a builder to create an appliction from an image. You
    should offer many necessary arguments.

    Parameters:
    image_name: the image name for the container.
    tcp_ports: a dict, the tcp ports of the containers. For example: {
        "http": 80, "https": 443}
    udp_ports: a dict, the udp ports of the containers.
    commands: the commands which the container runs when start.
    envs: a dict for example: {"MYSQL_HOST": "localhost", "PORT": "3306"}
    volumes: a dict, for example: [{"volume": id, "mount_path": path}]
    """
    namespace = None
    application = None
    image_name = None
    tcp_ports = None
    udp_ports = None
    commands = None
    args = None
    envs = None
    is_public = False
    volumes = None

    def __init__(self,
                 application,
                 image_name,
                 tcp_ports=None,
                 udp_ports=None,
                 commands=None,
                 args=None,
                 envs=None,
                 is_public=False,
                 volumes=None,
                 min_replicas=None,
                 max_replicas=None,
                 cpu_target=None):
        self.kubeclient = KubeClient("http://{}:{}{}".format(
            settings.MASTER_IP, settings.K8S_PORT, settings.K8S_API_PATH))

        self.application = application
        self.namespace = self.application.image.project.name
        self.application_name = get_application_instance_name(self.application)
        self.image_name = image_name
        self.tcp_ports = tcp_ports
        self.udp_ports = udp_ports
        self.commands = commands
        self.args = args
        self.envs = envs
        self.is_public = is_public
        self.volumes = volumes

        # Compute the resource limit of the application
        resource_limit = self.application.resource_limit
        self.cpu = str(resource_limit.cpu) + resource_limit.cpu_unit
        self.memory = str(resource_limit.memory) + resource_limit.memory_unit

        # autoscaler
        if self.application.is_autoscaler:
            self.min_replicas = int(min_replicas)
            self.max_replicas = int(max_replicas)
            self.cpu_target = int(cpu_target)
            logger.debug(
                str(self.min_replicas) + " " + str(self.max_replicas) + " " +
                str(self.cpu_target))

    def create_application(self):
        """
        Create application by multiple threading.
        """
        creating_thread = Thread(target=self._create_application)
        creating_thread.start()

    def _create_application(self):
        """
        First create a replicationcontroller, then create a service, update
        database at last.
        """
        logger.info(
            'Create an application {} in namespace {} by image {}.'.format(
                self.application_name, self.namespace, self.image_name))

        if not self._create_controller():
            logger.debug('Create controller {} failed.'.format(
                self.application_name))
            logger.info(
                'Create an application {} in namespace {} failed.'.format(
                    self.application_name, self.namespace, self.image_name))

            self._update_application_metadata(status='error')
            return None

        if self.tcp_ports or self.udp_ports:
            if not self._create_service():
                logger.debug('Create service {} failed.'.format(
                    self.application_name))
                logger.info(
                    'Create an application {} in namespace {} failed.'.format(
                        self.application_name, self.namespace,
                        self.image_name))

                self._update_application_metadata(status='error')
                return None
            internal_ip, ports = self._get_service_ip_and_ports()
        else:
            internal_ip = None
            ports = None

        # update metadata
        if self.is_public:
            external_ip = get_optimal_external_ip(
                namespace=self.namespace, app_name=self.application_name)
            self._update_application_metadata(status='active',
                                              internal_ip=internal_ip,
                                              external_ip=external_ip)
        else:
            self._update_application_metadata(status='active',
                                              internal_ip=internal_ip)

        # mount volume
        self._mount_volume_onto_application()

        # create port metadata
        self._create_ports_metadata(ports)

        # create environment metadata
        self._create_environments_metadata()

        # create autoscaler
        if self.application.is_autoscaler:
            scaler_builder = AutoScalerBuilder(application=self.application,
                                               min_replicas=self.min_replicas,
                                               max_replicas=self.max_replicas,
                                               cpu_target=self.cpu_target)
            scaler_builder.create_autoscaler()

    def _create_controller(self):
        """
        Create a replicationcontroller by provided image.
        """
        return self.kubeclient.create_controller(
            namespace=self.namespace,
            name=self.application_name,
            image_name=self.image_name,
            cpu=self.cpu,
            memory=self.memory,
            replicas=self.application.replicas,
            tcp_ports=self.tcp_ports,
            udp_ports=self.udp_ports,
            commands=self.commands,
            args=self.args,
            envs=self.envs,
            volumes=self._get_volume_names_and_path())

    def _create_service(self):
        """
        Create a service on the replicationcontroller.
        """
        return self.kubeclient.create_service(
            namespace=self.namespace,
            name=self.application_name,
            tcp_ports=self.tcp_ports,
            udp_ports=self.udp_ports,
            is_public=self.is_public,
            session_affinity=self.application.session_affinity)

    def _get_service_ip_and_ports(self):
        """
        Get internal_ip and ports of the service.
        """
        response = self.kubeclient.get_service_details(self.namespace,
                                                       self.application_name)
        return (response['spec']['clusterIP'], response['spec']['ports'])

    def _update_application_metadata(self,
                                     status=None,
                                     internal_ip=None,
                                     external_ip=None):
        """
        Update the application metadata.
        """
        if status:
            self.application.status = status
        if internal_ip:
            self.application.internal_ip = internal_ip
        if external_ip:
            self.application.external_ip = external_ip

        self.application.save()

    def _create_ports_metadata(self, ports):
        """
        Create ports metadata for application.
        """
        if not ports:
            return None

        for port_dict in ports:
            port = Port(app=self.application,
                        name=port_dict['name'],
                        protocol=port_dict['protocol'],
                        external_port=port_dict.get('nodePort', None),
                        internal_port=port_dict['port'])
            port.save()

    def _create_environments_metadata(self):
        """
        Create environment metadata for application.
        """
        if not self.envs:
            return None

        for name, value in self.envs.items():
            env = Environment(app=self.application, name=name, value=value)
            env.save()

    def _mount_volume_onto_application(self):
        """
        Edit the metadata, Mount volumes onto this application.
        """
        if not self.volumes:
            return None
        for volume_item in self.volumes:
            volume = Volume.objects.get(id=volume_item['volume'])
            logger.debug("mount volume {} onto application {}.".format(
                volume.name, self.application_name))
            volume.app = self.application
            volume.mount_path = volume_item['mount_path']
            volume.save()

    def _get_volume_names_and_path(self):
        """
        Return the volume names from volume ids. The true volume instance name
        is "project_name-volume_name".
        """
        if not self.volumes:
            return None
        volume_name_path = {}
        for volume_item in self.volumes:
            volume = Volume.objects.get(id=int(volume_item['volume']))
            volume_name = "{}-{}".format(self.namespace, volume.name)
            volume_name_path[volume_name] = volume_item['mount_path']
        logger.debug(volume_name_path)
        return volume_name_path