Пример #1
0
    def patch(self, cluster_id):
        """
        """

        cluster_schema = ClusterSchema(partial=True)

        new_cluster_data = request.get_json()

        validated_cluster_data, errors = cluster_schema.load(new_cluster_data)

        if errors:
            return dict(status='fail', messgae=errors), 400

        cluster = Cluster.get_by_id(cluster_id)

        if not cluster:
            return dict(
                status='fail',
                message=f'Cluster with id {cluster_id} does not exist'), 404

        cluster_updated = Cluster.update(cluster, **validated_cluster_data)

        if not cluster_updated:
            return dict(status='fail', message='Internal Server Error'), 500

        return dict(status='success',
                    message='Cluster updated successfully'), 200
Пример #2
0
    def get(self, cluster_id, storage_class_name):
        """
        """
        try:
            cluster = Cluster.get_by_id(cluster_id)

            if not cluster:
                return dict(
                    status='fail',
                    message=f'cluster with id {cluster_id} does not exist'
                ), 404

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            storage_class =\
                kube_client.storageV1Api.read_storage_class(storage_class_name)

            storage_class =\
                kube_client.api_client.sanitize_for_serialization(storage_class)

            storage_class_json = json.dumps(storage_class)

            return dict(
                status='success',
                data=dict(storage_class=json.loads(storage_class_json))), 200

        except client.rest.ApiException as e:
            return dict(status='fail', message=e.reason), e.status

        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #3
0
    def get(self, cluster_id, namespace_name, job_name):
        """
        """
        try:
            cluster = Cluster.get_by_id(cluster_id)

            if not cluster:
                return dict(
                    status='fail',
                    message=f'cluster with id {cluster_id} does not exist'
                ), 404

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            job = kube_client.batchv1_api.read_namespaced_job(
                job_name, namespace_name)

            job = kube_client.api_client.sanitize_for_serialization(job)

            job_json = json.dumps(job)

            return dict(status='success',
                        data=dict(job=json.loads(job_json))), 200

        except client.rest.ApiException as e:
            return dict(status='fail', message=e.reason), e.status

        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #4
0
    def get(self, cluster_id):
        """
        """
        try:
            cluster = Cluster.get_by_id(cluster_id)

            jobs = []

            if not cluster:
                return dict(
                    status='fail',
                    message=f'cluster with id {cluster_id} does not exist'
                ), 404

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            jobs_resp = kube_client.batchv1_api.list_job_for_all_namespaces()

            for item in jobs_resp.items:
                item = kube_client.api_client.sanitize_for_serialization(item)
                jobs.append(item)

            jobs_json = json.dumps(jobs)

            return dict(status='success',
                        data=dict(jobs=json.loads(jobs_json))), 200

        except client.rest.ApiException as e:
            return dict(status='fail', message=e.reason), e.status

        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #5
0
    def get(self, cluster_id):
        """
        """
        try:
            cluster = Cluster.get_by_id(cluster_id)

            nodes = []

            if not cluster:
                return dict(
                    status='fail',
                    message=f'cluster with id {cluster_id} does not exist'
                ), 404

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            # get all nodes in the cluster
            node_resp = kube_client.kube.list_node()

            for item in node_resp.items:
                item = kube_client.api_client.sanitize_for_serialization(item)
                nodes.append(item)

            nodes_json = json.dumps(nodes)

            return dict(status='success',
                        data=dict(nodes=json.loads(nodes_json))), 200
        except client.rest.ApiException as e:
            return dict(status='fail', message=e.reason), e.status

        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #6
0
    def delete(self, project_id):
        """
        """

        try:
            current_user_id = get_jwt_identity()
            current_user_roles = get_jwt_claims()['roles']

            project = Project.get_by_id(project_id)

            if not project:
                return dict(status='fail',
                            message=f'project {project_id} not found'), 404

            if not is_owner_or_admin(project, current_user_id,
                                     current_user_roles):
                return dict(status='fail', message='unauthorised'), 403

            # get cluster for the project
            cluster = Cluster.get_by_id(project.cluster_id)

            if not cluster:
                return dict(status='fail', message='cluster not found'), 500

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            # get corresponding namespace

            namespace = kube_client.kube.read_namespace(project.alias)

            # delete namespace if it exists
            if namespace:
                kube_client.kube.delete_namespace(project.alias)

            # To do; change delete to a soft delete
            deleted = project.delete()

            if not deleted:
                return dict(status='fail', message='deletion failed'), 500

            return dict(
                status='success',
                message=f'project {project_id} deleted successfully'), 200

        except client.rest.ApiException as e:
            return dict(status='fail', message=e.reason), e.status

        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #7
0
    def post(self):
        """
        """

        cluster_schema = ClusterSchema()

        cluster_data = request.get_json()

        validated_cluster_data, errors = cluster_schema.load(cluster_data)

        if errors:
            return dict(status='fail', message=errors), 400

        try:
            kube_host = validated_cluster_data['host']
            kube_token = validated_cluster_data['token']

            kube_client = create_kube_clients(kube_host, kube_token)

            # test connection by getting namespaces
            kube_client.kube.list_namespace(_preload_content=False)

            new_cluster = Cluster(**validated_cluster_data)

            saved = new_cluster.save()

            if not saved:
                return dict(
                    status='fail',
                    message='Internal Server Error, possible duplicates'), 500

            new_cluster_data, errors = cluster_schema.dump(new_cluster)

            return dict(status='success',
                        data=dict(cluster=new_cluster_data)), 201

        except Exception:
            return dict(status='fail',
                        message='Connection to cluster failed'), 500
Пример #8
0
    def get(self):
        """
        """
        cluster_schema = ClusterSchema(many=True)

        clusters = Cluster.find_all()

        validated_cluster_data, errors = cluster_schema.dumps(clusters)

        if errors:
            return dict(status='fail', message='Internal Server Error'), 500

        return dict(
            status='Success',
            data=dict(clusters=json.loads(validated_cluster_data))), 200
Пример #9
0
    def delete(self, cluster_id):
        """
        """
        cluster = Cluster.get_by_id(cluster_id)

        if not cluster:
            return dict(status='fail', message='Cluster not found'), 404

        deleted = cluster.delete()

        if not deleted:
            return dict(status='fail', message='Internal Server Error'), 500

        return dict(
            status='success',
            message=f'Cluster with id {cluster_id} deleted successfully'), 200
Пример #10
0
    def get(self, cluster_id):
        """
        """
        try:

            cluster_schema = ClusterSchema()

            resource_count = []

            cluster = Cluster.get_by_id(cluster_id)

            if not cluster:
                return dict(
                    status='fail',
                    message=f'Cluster with id {cluster_id} does not exist'
                ), 404

            validated_cluster_data, errors = cluster_schema.dumps(cluster)

            if errors:
                return dict(status='fail', message=errors), 500

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            # get number of nodes in the cluster
            node_count = len(kube_client.kube.list_node().items)

            resource_count.append(dict(name='nodes', count=node_count))

            # get count of pvcs in the cluster
            pvc_count = len(
                kube_client.kube.
                list_persistent_volume_claim_for_all_namespaces().items)

            resource_count.append(dict(name='PVCs', count=pvc_count))

            # get count of all pods in the cluster
            pod_count = len(
                kube_client.kube.list_pod_for_all_namespaces().items)

            resource_count.append(dict(name='pods', count=pod_count))

            # get count of all services
            service_count = len(
                kube_client.kube.list_service_for_all_namespaces().items)

            resource_count.append(dict(name='services', count=service_count))

            # get count of all deployments
            deployment_count = len(kube_client.appsv1_api.
                                   list_deployment_for_all_namespaces().items)

            resource_count.append(
                dict(name='deployments', count=deployment_count))

            # get count of all namespaces in the cluster
            namespace_count = len(kube_client.kube.list_namespace().items)

            resource_count.append(
                dict(name='namespaces', count=namespace_count))

            resource_count_json = json.dumps(resource_count)

            return dict(
                status='succcess',
                data=dict(cluster=json.loads(validated_cluster_data),
                          resource_count=json.loads(resource_count_json))), 200
        except Exception as e:
            return dict(status='fail', message=str(e)), 500
Пример #11
0
    def post(self):
        """
        """

        current_user_id = get_jwt_identity()
        current_user_roles = get_jwt_claims()['roles']

        project_schema = ProjectSchema()

        project_data = request.get_json()

        validated_project_data, errors = project_schema.load(project_data)

        if errors:
            return dict(status='fail', message=errors), 400

        if not has_role(current_user_roles, 'administrator'):
            validated_project_data['owner_id'] = current_user_id

        # check if project already exists
        existing_project = Project.find_first(
            name=validated_project_data['name'],
            owner_id=validated_project_data['owner_id'])

        if existing_project:
            return dict(
                status='fail',
                message=
                f'project with name {validated_project_data["name"]} already exists'
            ), 409

        try:
            validated_project_data['alias'] =\
                create_alias(validated_project_data['name'])
            namespace_name = validated_project_data['alias']
            cluster_id = validated_project_data['cluster_id']
            cluster = Cluster.get_by_id(cluster_id)

            if not cluster:
                return dict(status='fail',
                            message=f'cluster {cluster_id} not found'), 404

            kube_host = cluster.host
            kube_token = cluster.token

            kube_client = create_kube_clients(kube_host, kube_token)

            # create namespace in cluster
            cluster_namespace = kube_client.kube.create_namespace(
                client.V1Namespace(metadata=client.V1ObjectMeta(
                    name=namespace_name)))
            # create project in database
            if cluster_namespace:

                ingress_name = f"{validated_project_data['alias']}-ingress"

                ingress_meta = client.V1ObjectMeta(name=ingress_name)

                ingress_default_rule = client.ExtensionsV1beta1IngressRule(
                    host="traefik-ui.cranecloud.io",
                    http=client.ExtensionsV1beta1HTTPIngressRuleValue(paths=[
                        client.ExtensionsV1beta1HTTPIngressPath(
                            path="/*",
                            backend=client.ExtensionsV1beta1IngressBackend(
                                service_name="traefik-web-ui-ext",
                                service_port=80))
                    ]))

                ingress_spec = client.ExtensionsV1beta1IngressSpec(
                    rules=[ingress_default_rule])

                ingress_body = client.ExtensionsV1beta1Ingress(
                    metadata=ingress_meta, spec=ingress_spec)

                kube_client.extension_api.create_namespaced_ingress(
                    namespace=namespace_name, body=ingress_body)

                project = Project(**validated_project_data)

                saved = project.save()

                if not saved:
                    # delete the namespace
                    kube_client.kube.delete_namespace(namespace_name)
                    return dict(status='fail',
                                message='Internal Server Error'), 500

            new_project_data, errors = project_schema.dump(project)

            return dict(status='success',
                        data=dict(project=new_project_data)), 201

        except client.rest.ApiException as e:
            return dict(status='fail', message=e.body), e.status

        except Exception as err:
            return dict(status='fail', message=str(err)), 500
Пример #12
0
    def get(self, app_id):
        """
        """
        try:
            current_user_id = get_jwt_identity()
            current_user_roles = get_jwt_claims()['roles']

            app_schema = AppSchema()

            app = App.get_by_id(app_id)

            if not app:
                return dict(status='fail',
                            message=f'App {app_id} not found'), 404

            project = app.project

            if not project:
                return dict(status='fail',
                            message='Internal server error'), 500

            if not is_owner_or_admin(project, current_user_id,
                                     current_user_roles):
                return dict(status='fail', message='Unauthorised'), 403

            app_data, errors = app_schema.dumps(app)

            if errors:
                return dict(status='fail', message=errors), 500

            app_list = json.loads(app_data)

            cluster = Cluster.get_by_id(project.cluster_id)

            if not cluster:
                return dict(
                    status='fail',
                    message=
                    f'cluster with id {project.cluster_id} does not exist'
                ), 404

            kube_host = cluster.host
            kube_token = cluster.token
            kube_client = create_kube_clients(kube_host, kube_token)

            app_status_object = \
                kube_client.appsv1_api.read_namespaced_deployment_status(
                    app_list['alias']+"-deployment", project.alias)

            app_deployment_status_conditions = app_status_object.status.conditions

            for deplyoment_status_condition in app_deployment_status_conditions:
                if deplyoment_status_condition.type == "Available":
                    app_deployment_status = deplyoment_status_condition.status

            try:
                app_db_status_object = \
                    kube_client.appsv1_api.read_namespaced_deployment_status(
                        app_list['alias']+"-postgres-db", project.alias)

                app_db_state_conditions = app_db_status_object.status.conditions

                for app_db_condition in app_db_state_conditions:
                    if app_db_condition.type == "Available":
                        app_db_status = app_db_condition.status

            except client.rest.ApiException:
                app_db_status = None

            if app_deployment_status and not app_db_status:
                if app_deployment_status == "True":
                    app_list['app_running_status'] = "running"
                else:
                    app_list['app_running_status'] = "failed"
            elif app_deployment_status and app_db_status:
                if app_deployment_status == "True" and app_db_status == "True":
                    app_list['app_running_status'] = "running"
                else:
                    app_list['app_running_status'] = "failed"
            else:
                app_list['app_running_status'] = "unknown"

            return dict(status='success', data=dict(apps=app_list)), 200

        except client.rest.ApiException as exc:
            return dict(status='fail', message=exc.reason), exc.status

        except Exception as exc:
            return dict(status='fail', message=str(exc)), 500