From 3c7234a89c9cea821cd94f38b6de32acc71bfe74 Mon Sep 17 00:00:00 2001 From: lombardofr Date: Tue, 3 Dec 2019 11:23:17 +0100 Subject: [PATCH] k8sClusters; k8sRepos Change-Id: Ife3ea193ec9479f685ff8e969335c1343a2ad1ac Signed-off-by: lombardofr --- build-debpkg.sh | 2 +- k8sclusterhandler/__init__.py | 15 ++ k8sclusterhandler/apps.py | 22 ++ .../template/k8scluster_list.html | 198 ++++++++++++++++++ .../template/modal/k8scluster_details.html | 39 ++++ .../template/modal/k8scluster_register.html | 85 ++++++++ .../template/modal/k8scluster_update.html | 15 ++ k8sclusterhandler/urls.py | 26 +++ k8sclusterhandler/views.py | 113 ++++++++++ k8srepohandler/__init__.py | 15 ++ k8srepohandler/apps.py | 22 ++ k8srepohandler/models.py | 20 ++ k8srepohandler/template/k8srepo_list.html | 198 ++++++++++++++++++ .../template/modal/k8srepo_details.html | 39 ++++ .../template/modal/k8srepo_register.html | 76 +++++++ .../template/modal/k8srepo_update.html | 15 ++ k8srepohandler/urls.py | 26 +++ k8srepohandler/views.py | 107 ++++++++++ lib/osm/osmclient/clientv2.py | 173 ++++++++++++++- .../project/osm/osm_project_left_sidebar.html | 24 +++ sf_t3d/settings.py | 6 +- sf_t3d/urls.py | 2 + .../src/k8sclusterhandler/k8sclusters_list.js | 169 +++++++++++++++ static/src/k8srepohandler/k8srepos_list.js | 146 +++++++++++++ vimhandler/views.py | 2 + 25 files changed, 1552 insertions(+), 3 deletions(-) create mode 100644 k8sclusterhandler/__init__.py create mode 100644 k8sclusterhandler/apps.py create mode 100644 k8sclusterhandler/template/k8scluster_list.html create mode 100644 k8sclusterhandler/template/modal/k8scluster_details.html create mode 100644 k8sclusterhandler/template/modal/k8scluster_register.html create mode 100644 k8sclusterhandler/template/modal/k8scluster_update.html create mode 100644 k8sclusterhandler/urls.py create mode 100644 k8sclusterhandler/views.py create mode 100644 k8srepohandler/__init__.py create mode 100644 k8srepohandler/apps.py create mode 100644 k8srepohandler/models.py create mode 100644 k8srepohandler/template/k8srepo_list.html create mode 100644 k8srepohandler/template/modal/k8srepo_details.html create mode 100644 k8srepohandler/template/modal/k8srepo_register.html create mode 100644 k8srepohandler/template/modal/k8srepo_update.html create mode 100644 k8srepohandler/urls.py create mode 100644 k8srepohandler/views.py create mode 100644 static/src/k8sclusterhandler/k8sclusters_list.js create mode 100644 static/src/k8srepohandler/k8srepos_list.js diff --git a/build-debpkg.sh b/build-debpkg.sh index 46f5aae..90553c3 100755 --- a/build-debpkg.sh +++ b/build-debpkg.sh @@ -15,7 +15,7 @@ # under the License. -PKG_DIRECTORIES="authosm descriptorhandler instancehandler lib projecthandler sdnctrlhandler sf_t3d static template userhandler vimhandler packagehandler netslicehandler wimhandler rolehandler" +PKG_DIRECTORIES="authosm descriptorhandler instancehandler lib projecthandler sdnctrlhandler sf_t3d static template userhandler vimhandler packagehandler netslicehandler wimhandler rolehandler k8sclusterhandler k8srepohandler" PKG_FILES="bower.json django.ini LICENSE manage.py nginx-app.conf README.md requirements.txt supervisor-app.conf .bowerrc entrypoint.sh package.json" MDG_NAME=lightui DEB_INSTALL=debian/osm-${MDG_NAME}.install diff --git a/k8sclusterhandler/__init__.py b/k8sclusterhandler/__init__.py new file mode 100644 index 0000000..340b024 --- /dev/null +++ b/k8sclusterhandler/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/k8sclusterhandler/apps.py b/k8sclusterhandler/apps.py new file mode 100644 index 0000000..07d288e --- /dev/null +++ b/k8sclusterhandler/apps.py @@ -0,0 +1,22 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class K8SclusterhandlerConfig(AppConfig): + name = 'k8sclusterhandler' diff --git a/k8sclusterhandler/template/k8scluster_list.html b/k8sclusterhandler/template/k8scluster_list.html new file mode 100644 index 0000000..48201ae --- /dev/null +++ b/k8sclusterhandler/template/k8scluster_list.html @@ -0,0 +1,198 @@ + + +{% extends "base.html" %} +{% load get %} +{% load staticfiles %} + + +{% block head_block %} + {{ block.super }} + + + + + + + + + +{% endblock %} +{% block title_header_big %} + {{ block.super }} +{% endblock %} +{% block left_sidebar %} + {% include 'osm/osm_project_left_sidebar.html' %} +{% endblock %} + + +{% block breadcrumb_body %} + {{ block.super }} +
  • K8s clusters
  • +{% endblock %} + +{% block content_body %} + {{ block.super }} + {% include 'modal/k8scluster_details.html' %} + {% include 'modal/k8scluster_register.html' %} + {% csrf_token %} +
    +
    + +
    +
    +

    Registered K8s clusters

    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + +
    NameIdentifierK8 VersionOperational StateCreatedModifiedActions
    +
    +
    +
    + +
    +{% endblock %} + +{% block resource_block %} + {{ block.super }} + + + + + + + + + + + + + + + + + + + + +{% endblock %} + +{% block footer %} + {% include "footer.html" %} +{% endblock %} \ No newline at end of file diff --git a/k8sclusterhandler/template/modal/k8scluster_details.html b/k8sclusterhandler/template/modal/k8scluster_details.html new file mode 100644 index 0000000..661e92e --- /dev/null +++ b/k8sclusterhandler/template/modal/k8scluster_details.html @@ -0,0 +1,39 @@ + + + \ No newline at end of file diff --git a/k8sclusterhandler/template/modal/k8scluster_register.html b/k8sclusterhandler/template/modal/k8scluster_register.html new file mode 100644 index 0000000..1be648f --- /dev/null +++ b/k8sclusterhandler/template/modal/k8scluster_register.html @@ -0,0 +1,85 @@ + + + + + + diff --git a/k8sclusterhandler/template/modal/k8scluster_update.html b/k8sclusterhandler/template/modal/k8scluster_update.html new file mode 100644 index 0000000..d8dbb44 --- /dev/null +++ b/k8sclusterhandler/template/modal/k8scluster_update.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/k8sclusterhandler/urls.py b/k8sclusterhandler/urls.py new file mode 100644 index 0000000..f07893a --- /dev/null +++ b/k8sclusterhandler/urls.py @@ -0,0 +1,26 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from django.conf.urls import url +from k8sclusterhandler import views + +urlpatterns = [ + url(r'^list$', views.list, name='list'), + url(r'^create/', views.create, name='create'), + url(r'^(?P[0-9a-z-]+)/delete$', views.delete, name='delete'), + url(r'^(?P[0-9a-z-]+)', views.show, name='show'), + url(r'^(?P[0-9a-z-]+)/update$', views.update, name='update'), +] \ No newline at end of file diff --git a/k8sclusterhandler/views.py b/k8sclusterhandler/views.py new file mode 100644 index 0000000..f3ee93d --- /dev/null +++ b/k8sclusterhandler/views.py @@ -0,0 +1,113 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from django.shortcuts import render, redirect +from sf_t3d.decorators import login_required +from django.http import HttpResponse +import yaml +import json +import logging +import authosm.utils as osmutils +from lib.osm.osmclient.clientv2 import Client + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger('k8sclusterhandler/view.py') + + +@login_required +def list(request): + user = osmutils.get_user(request) + project_id = user.project_id + result = {'project_id': project_id} + raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') + if 'application/json' not in raw_content_types: + return __response_handler(request, result, 'k8scluster_list.html') + client = Client() + result_client = client.k8sc_list(user.get_token()) + + result['k8sc'] = result_client['data'] if result_client and result_client['error'] is False else [] + + return __response_handler(request, result, 'k8scluster_list.html') + + +@login_required +def create(request): + user = osmutils.get_user(request) + project_id = user.project_id + result = {'project_id': project_id} + client = Client() + try: + + new_k8sc = { + "name": request.POST.get('name'), + "credentials": yaml.load(request.POST.get('credentials')), + "vim_account": request.POST.get('vim_account'), + "k8s_version": request.POST.get('k8s_version'), + "nets": yaml.load(request.POST.get('nets')), + } + + # new_k8sc['vim_account'] = get_vim_account_id(new_k8sc['vim_account']) + + except Exception as e: + return __response_handler(request, {'status': 400, 'code': 'BAD_REQUEST', 'detail': e.message}, url=None, status=400) + result = client.k8sc_create(user.get_token(), new_k8sc) + if result['error']: + return __response_handler(request, result['data'], url=None, status=result['data']['status'] if 'status' in result['data'] else 500) + else: + return __response_handler(request, result, 'k8sc:list', to_redirect=True) + + +@login_required +def update(request, k8sc_id=None): + user = osmutils.get_user(request) + try: + update_k8sc_dict = request.POST.dict() + client = Client() + res = client.k8sc_update(user.get_token(), k8sc_id, update_k8sc_dict) + except Exception as e: + log.exception(e) + return __response_handler(request, res, 'k8sc:list', to_redirect=True) + + +@login_required +def show(request, k8sc_id=None): + user = osmutils.get_user(request) + project_id = user.project_id + client = Client() + result_client = client.k8sc_get(user.get_token(), k8sc_id) + + return __response_handler(request, result_client) + + +@login_required +def delete(request, k8sc_id=None): + user = osmutils.get_user(request) + try: + client = Client() + del_res = client.k8sc_delete(user.get_token(), k8sc_id) + except Exception as e: + log.exception(e) + return __response_handler(request, del_res, 'k8sc:list', to_redirect=True) + + +def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs): + raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') + if 'application/json' in raw_content_types or url is None: + return HttpResponse(json.dumps(data_res), content_type="application/json", *args, **kwargs) + elif to_redirect: + return redirect(url, *args, **kwargs) + else: + return render(request, url, data_res) diff --git a/k8srepohandler/__init__.py b/k8srepohandler/__init__.py new file mode 100644 index 0000000..340b024 --- /dev/null +++ b/k8srepohandler/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# \ No newline at end of file diff --git a/k8srepohandler/apps.py b/k8srepohandler/apps.py new file mode 100644 index 0000000..6efc9bd --- /dev/null +++ b/k8srepohandler/apps.py @@ -0,0 +1,22 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class K8SrepohandlerConfig(AppConfig): + name = 'k8srepohandler' diff --git a/k8srepohandler/models.py b/k8srepohandler/models.py new file mode 100644 index 0000000..3199b61 --- /dev/null +++ b/k8srepohandler/models.py @@ -0,0 +1,20 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import unicode_literals + +from django.db import models + +# Create your models here. diff --git a/k8srepohandler/template/k8srepo_list.html b/k8srepohandler/template/k8srepo_list.html new file mode 100644 index 0000000..889fded --- /dev/null +++ b/k8srepohandler/template/k8srepo_list.html @@ -0,0 +1,198 @@ + + +{% extends "base.html" %} +{% load get %} +{% load staticfiles %} + + +{% block head_block %} + {{ block.super }} + + + + + + + + + +{% endblock %} +{% block title_header_big %} + {{ block.super }} +{% endblock %} +{% block left_sidebar %} + {% include 'osm/osm_project_left_sidebar.html' %} +{% endblock %} + + +{% block breadcrumb_body %} + {{ block.super }} +
  • K8s repository
  • +{% endblock %} + +{% block content_body %} + {{ block.super }} + {% include 'modal/k8srepo_details.html' %} + {% include 'modal/k8srepo_register.html' %} + {% csrf_token %} +
    +
    + +
    +
    +

    Registered K8s repository

    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + +
    NameIdentifierUrlTypeCreatedModifiedActions
    +
    +
    +
    + +
    +{% endblock %} + +{% block resource_block %} + {{ block.super }} + + + + + + + + + + + + + + + + + + + + +{% endblock %} + +{% block footer %} + {% include "footer.html" %} +{% endblock %} \ No newline at end of file diff --git a/k8srepohandler/template/modal/k8srepo_details.html b/k8srepohandler/template/modal/k8srepo_details.html new file mode 100644 index 0000000..e38fbe0 --- /dev/null +++ b/k8srepohandler/template/modal/k8srepo_details.html @@ -0,0 +1,39 @@ + + + \ No newline at end of file diff --git a/k8srepohandler/template/modal/k8srepo_register.html b/k8srepohandler/template/modal/k8srepo_register.html new file mode 100644 index 0000000..b090bc8 --- /dev/null +++ b/k8srepohandler/template/modal/k8srepo_register.html @@ -0,0 +1,76 @@ + + + + + + diff --git a/k8srepohandler/template/modal/k8srepo_update.html b/k8srepohandler/template/modal/k8srepo_update.html new file mode 100644 index 0000000..d8dbb44 --- /dev/null +++ b/k8srepohandler/template/modal/k8srepo_update.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/k8srepohandler/urls.py b/k8srepohandler/urls.py new file mode 100644 index 0000000..ca3b5cd --- /dev/null +++ b/k8srepohandler/urls.py @@ -0,0 +1,26 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from django.conf.urls import url +from k8srepohandler import views + +urlpatterns = [ + url(r'^list$', views.list, name='list'), + url(r'^create/', views.create, name='create'), + url(r'^(?P[0-9a-z-]+)/delete$', views.delete, name='delete'), + url(r'^(?P[0-9a-z-]+)', views.show, name='show'), + url(r'^(?P[0-9a-z-]+)/update$', views.update, name='update'), +] \ No newline at end of file diff --git a/k8srepohandler/views.py b/k8srepohandler/views.py new file mode 100644 index 0000000..325e7e5 --- /dev/null +++ b/k8srepohandler/views.py @@ -0,0 +1,107 @@ +# +# Copyright 2019 EveryUP Srl +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from django.shortcuts import render, redirect +from sf_t3d.decorators import login_required +from django.http import HttpResponse +import json +import logging +import authosm.utils as osmutils +from lib.osm.osmclient.clientv2 import Client + +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger('k8srepohandler/view.py') + + +@login_required +def list(request): + user = osmutils.get_user(request) + project_id = user.project_id + result = {'project_id': project_id} + raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') + if 'application/json' not in raw_content_types: + return __response_handler(request, result, 'k8srepo_list.html') + client = Client() + result_client = client.k8sr_list(user.get_token()) + + result['k8sr'] = result_client['data'] if result_client and result_client['error'] is False else [] + + return __response_handler(request, result, 'k8srepo_list.html') + + +@login_required +def create(request): + user = osmutils.get_user(request) + project_id = user.project_id + result = {'project_id': project_id} + client = Client() + try: + new_k8sr = { + "name": request.POST.get('name'), + "type": request.POST.get('type'), + "url": request.POST.get('url'), + "description": request.POST.get('description'), + } + except Exception as e: + return __response_handler(request, {'status': 400, 'code': 'BAD_REQUEST', 'detail': e.message}, url=None, status=400) + result = client.k8sr_create(user.get_token(), new_k8sr) + if result['error']: + return __response_handler(request, result['data'], url=None, status=result['data']['status'] if 'status' in result['data'] else 500) + else: + return __response_handler(request, result, 'k8sr:list', to_redirect=True) + + +@login_required +def update(request, k8sr_id=None): + user = osmutils.get_user(request) + try: + update_k8sr_dict = request.POST.dict() + client = Client() + res = client.k8sr_update(user.get_token(), k8sr_id, update_k8sr_dict) + except Exception as e: + log.exception(e) + return __response_handler(request, res, 'k8sr:list', to_redirect=True) + + +@login_required +def show(request, k8sr_id=None): + user = osmutils.get_user(request) + project_id = user.project_id + client = Client() + result_client = client.k8sr_get(user.get_token(), k8sr_id) + + return __response_handler(request, result_client) + + +@login_required +def delete(request, k8sr_id=None): + user = osmutils.get_user(request) + try: + client = Client() + del_res = client.k8sr_delete(user.get_token(), k8sr_id) + except Exception as e: + log.exception(e) + return __response_handler(request, del_res, 'k8sr:list', to_redirect=True) + + +def __response_handler(request, data_res, url=None, to_redirect=None, *args, **kwargs): + raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',') + if 'application/json' in raw_content_types or url is None: + return HttpResponse(json.dumps(data_res), content_type="application/json", *args, **kwargs) + elif to_redirect: + return redirect(url, *args, **kwargs) + else: + return render(request, url, data_res) diff --git a/lib/osm/osmclient/clientv2.py b/lib/osm/osmclient/clientv2.py index cee0647..8056d36 100644 --- a/lib/osm/osmclient/clientv2.py +++ b/lib/osm/osmclient/clientv2.py @@ -114,7 +114,6 @@ class Client(object): headers = {"Content-Type": "application/json", "accept": "application/json", 'Authorization': 'Bearer {}'.format(token['id'])} _url = "{0}/admin/v1/roles/{1}".format(self._base_path, role_id) - try: r = requests.patch(_url, json=role_data, verify=False, headers=headers) except Exception as e: @@ -1531,6 +1530,178 @@ class Client(object): result['data'] = Util.json_loads_byteified(r.text) return result + def k8sc_get(self, token, id): + result = {'error': True, 'data': ''} + headers = {"accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + _url = "{0}/admin/v1/k8sclusters/{1}".format(self._base_path, id) + try: + r = requests.get(_url, params=None, verify=False, stream=True, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sc_list(self, token): + result = {'error': True, 'data': ''} + headers = {"accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + _url = "{0}/admin/v1/k8sclusters".format(self._base_path) + try: + r = requests.get(_url, params=None, verify=False, stream=True, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sc_create(self, token, cluster_data): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8sclusters".format(self._base_path) + + try: + r = requests.post(_url, json=cluster_data, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sc_update(self, token, id, cluster_data): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8sclusters/{1}".format(self._base_path, id) + try: + r = requests.patch(_url, json=cluster_data, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + else: + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sc_delete(self, token, id): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/yaml", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8sclusters/{1}".format(self._base_path, id) + try: + r = requests.delete(_url, params=None, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + else: + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sr_get(self, token, id): + result = {'error': True, 'data': ''} + headers = {"accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + _url = "{0}/admin/v1/k8srepos/{1}".format(self._base_path, id) + try: + r = requests.get(_url, params=None, verify=False, stream=True, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sr_list(self, token): + result = {'error': True, 'data': ''} + headers = {"accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + _url = "{0}/admin/v1/k8srepos".format(self._base_path) + try: + r = requests.get(_url, params=None, verify=False, stream=True, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sr_create(self, token, cluster_data): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8srepos".format(self._base_path) + + try: + r = requests.post(_url, json=cluster_data, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sr_update(self, token, id, cluster_data): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/json", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8srepos/{1}".format(self._base_path, id) + try: + r = requests.patch(_url, json=cluster_data, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + else: + result['data'] = Util.json_loads_byteified(r.text) + return result + + def k8sr_delete(self, token, id): + result = {'error': True, 'data': ''} + headers = {"Content-Type": "application/yaml", "accept": "application/json", + 'Authorization': 'Bearer {}'.format(token['id'])} + + _url = "{0}/admin/v1/k8srepos/{1}".format(self._base_path, id) + try: + r = requests.delete(_url, params=None, verify=False, headers=headers) + except Exception as e: + log.exception(e) + result['data'] = str(e) + return result + if r.status_code in (200, 201, 202, 204): + result['error'] = False + else: + result['data'] = Util.json_loads_byteified(r.text) + return result + @staticmethod def md5(f): hash_md5 = hashlib.md5() diff --git a/projecthandler/template/project/osm/osm_project_left_sidebar.html b/projecthandler/template/project/osm/osm_project_left_sidebar.html index a16d86e..5fdaf57 100644 --- a/projecthandler/template/project/osm/osm_project_left_sidebar.html +++ b/projecthandler/template/project/osm/osm_project_left_sidebar.html @@ -114,6 +114,30 @@ limitations under the License. + {% url "k8sc:list" as k8sc_list_url %} + + {% url "wims:list" as wim_list_url %}
  • diff --git a/sf_t3d/settings.py b/sf_t3d/settings.py index 0beb212..528929d 100644 --- a/sf_t3d/settings.py +++ b/sf_t3d/settings.py @@ -64,7 +64,9 @@ INSTALLED_APPS = [ 'sdnctrlhandler', 'userhandler', 'rolehandler', - 'netslicehandler' + 'netslicehandler', + 'k8sclusterhandler', + 'k8srepohandler' ] @@ -105,6 +107,8 @@ TEMPLATES = [ os.path.join(BASE_DIR, 'sdnctrlhandler', 'template'), os.path.join(BASE_DIR, 'userhandler', 'templates'), os.path.join(BASE_DIR, 'netslicehandler', 'template'), + os.path.join(BASE_DIR, 'k8sclusterhandler', 'template'), + os.path.join(BASE_DIR, 'k8srepohandler', 'template'), ], 'APP_DIRS': True, 'OPTIONS': { diff --git a/sf_t3d/urls.py b/sf_t3d/urls.py index 9c821b1..a908c13 100644 --- a/sf_t3d/urls.py +++ b/sf_t3d/urls.py @@ -26,6 +26,8 @@ urlpatterns = [ url(r'^projects/', include('projecthandler.urls.project', namespace='projects'), name='projects_base'), url(r'^sdn/', include('sdnctrlhandler.urls', namespace='sdns'), name='sdns_base'), url(r'^vims/', include('vimhandler.urls', namespace='vims'), name='vims_base'), + url(r'^k8scluster/', include('k8sclusterhandler.urls', namespace='k8sc'), name='k8sc_base'), + url(r'^k8srepo/', include('k8srepohandler.urls', namespace='k8sr'), name='k8sr_base'), url(r'^wims/', include('wimhandler.urls', namespace='wims'), name='wims_base'), url(r'^packages/', include('packagehandler.urls', namespace='packages'), name='packages_base'), url(r'^instances/', include('instancehandler.urls', namespace='instances'), name='instances_base'), diff --git a/static/src/k8sclusterhandler/k8sclusters_list.js b/static/src/k8sclusterhandler/k8sclusters_list.js new file mode 100644 index 0000000..5b1167f --- /dev/null +++ b/static/src/k8sclusterhandler/k8sclusters_list.js @@ -0,0 +1,169 @@ +/* + Copyright 2019 EveryUP srl + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +function openModalRegisterK8s(args) { + // load vim account list + select2_groups = $('#k8sc_vim_account').select2({ + placeholder: 'Select VIM', + width: '100%', + ajax: { + url: args.vim_list_url, + dataType: 'json', + processResults: function (data) { + vims = []; + if (data['datacenters']) { + for (d in data['datacenters']) { + var datacenter = data['datacenters'][d]; + vims.push({ id: datacenter['_id'], text: datacenter['name'] }) + } + } + + return { + results: vims + }; + } + } + }); + + + $('#modal_new_k8sc').modal('show'); +} + +function showK8sc(k8sc_id, k8sc_name) { + var url_info = '/k8scluster/' + k8sc_id; + var dialog = bootbox.dialog({ + message: '
    Loading...
    ', + closeButton: true + }); + $.ajax({ + url: url_info, + type: 'GET', + dataType: "json", + contentType: "application/json;charset=utf-8", + success: function (result) { + + if (result['data'] !== undefined) { + editorJSON.setValue(JSON.stringify(result['data'], null, "\t")); + editorJSON.setOption("autoRefresh", true); + dialog.modal('hide'); + $('#modal_show_k8sc').modal('show'); + } + else { + dialog.modal('hide'); + bootbox.alert("An error occurred while retrieving the information."); + } + }, + error: function (result) { + dialog.modal('hide'); + bootbox.alert("An error occurred while retrieving the information."); + } + }); +} + +function deleteK8sc(k8sc_id, k8sc_name) { + var url = "/k8scluster/"+k8sc_id+"/delete"; + bootbox.confirm("Are you sure want to delete " + k8sc_name + "?", function (result) { + if (result) { + var dialog = bootbox.dialog({ + message: '
    Loading...
    ', + closeButton: true + }); + $.ajax({ + url: url, + type: 'GET', + dataType: "json", + contentType: "application/json;charset=utf-8", + success: function (result) { + if (result['error'] == true) { + dialog.modal('hide'); + bootbox.alert("An error occurred."); + } + else { + table.ajax.reload(); + dialog.modal('hide'); + } + }, + error: function (error) { + dialog.modal('hide'); + bootbox.alert("An error occurred."); + } + }); + } + }) +} + +var editorJSON; + +$(document).ready(function () { + + var json_editor_settings = { + mode: "javascript", + showCursorWhenSelecting: true, + autofocus: true, + lineNumbers: true, + lineWrapping: true, + foldGutter: true, + gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], + autoCloseBrackets: true, + matchBrackets: true, + extraKeys: { + "F11": function (cm) { + cm.setOption("fullScreen", !cm.getOption("fullScreen")); + }, + "Esc": function (cm) { + if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false); + }, + "Ctrl-Q": function (cm) { + cm.foldCode(cm.getCursor()); + } + }, + theme: "neat", + keyMap: "sublime" + }; + var myJsonTextArea = document.getElementById("k8sc_view_json"); + editorJSON = CodeMirror(function (elt) { + myJsonTextArea.parentNode.replaceChild(elt, myJsonTextArea); + }, json_editor_settings); + + $("#formCreatek8sc").submit(function (event) { + event.preventDefault(); //prevent default action + var post_url = $(this).attr("action"); //get form action url + var request_method = $(this).attr("method"); //get form GET/POST method + var form_data = new FormData(this); //Encode form elements for submission + $.ajax({ + url: post_url, + type: request_method, + data: form_data, + headers: { + "Accept": 'application/json' + }, + contentType: false, + processData: false + }).done(function (response, textStatus, jqXHR) { + table.ajax.reload(); + $('#modal_new_k8sc').modal('hide'); + }).fail(function (result) { + var data = result.responseJSON; + var title = "Error " + (data.code ? data.code : 'unknown'); + var message = data.detail ? data.detail : 'No detail available.'; + bootbox.alert({ + title: title, + message: message + }); + }); + }); + +}); \ No newline at end of file diff --git a/static/src/k8srepohandler/k8srepos_list.js b/static/src/k8srepohandler/k8srepos_list.js new file mode 100644 index 0000000..5c3fa09 --- /dev/null +++ b/static/src/k8srepohandler/k8srepos_list.js @@ -0,0 +1,146 @@ +/* + Copyright 2019 EveryUP srl + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +function openModalRegisterK8sr(args) { + $('#modal_new_k8sr').modal('show'); +} + +function showK8sr(k8sr_id, k8sr_name) { + var url_info = '/k8srepo/' + k8sr_id; + var dialog = bootbox.dialog({ + message: '
    Loading...
    ', + closeButton: true + }); + $.ajax({ + url: url_info, + type: 'GET', + dataType: "json", + contentType: "application/json;charset=utf-8", + success: function (result) { + + if (result['data'] !== undefined) { + editorJSON.setValue(JSON.stringify(result['data'], null, "\t")); + editorJSON.setOption("autoRefresh", true); + dialog.modal('hide'); + $('#modal_show_k8sr').modal('show'); + } + else { + dialog.modal('hide'); + bootbox.alert("An error occurred while retrieving the information."); + } + }, + error: function (result) { + dialog.modal('hide'); + bootbox.alert("An error occurred while retrieving the information."); + } + }); +} + +function deleteK8sc(k8sr_id, k8sr_name) { + var url = "/k8srepo/"+k8sr_id+"/delete"; + bootbox.confirm("Are you sure want to delete " + k8sr_name + "?", function (result) { + if (result) { + var dialog = bootbox.dialog({ + message: '
    Loading...
    ', + closeButton: true + }); + $.ajax({ + url: url, + type: 'GET', + dataType: "json", + contentType: "application/json;charset=utf-8", + success: function (result) { + if (result['error'] == true) { + dialog.modal('hide'); + bootbox.alert("An error occurred."); + } + else { + table.ajax.reload(); + dialog.modal('hide'); + } + }, + error: function (error) { + dialog.modal('hide'); + bootbox.alert("An error occurred."); + } + }); + } + }) +} + + +var editorJSON; + +$(document).ready(function () { + + var json_editor_settings = { + mode: "javascript", + showCursorWhenSelecting: true, + autofocus: true, + lineNumbers: true, + lineWrapping: true, + foldGutter: true, + gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], + autoCloseBrackets: true, + matchBrackets: true, + extraKeys: { + "F11": function (cm) { + cm.setOption("fullScreen", !cm.getOption("fullScreen")); + }, + "Esc": function (cm) { + if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false); + }, + "Ctrl-Q": function (cm) { + cm.foldCode(cm.getCursor()); + } + }, + theme: "neat", + keyMap: "sublime" + }; + var myJsonTextArea = document.getElementById("k8sr_view_json"); + editorJSON = CodeMirror(function (elt) { + myJsonTextArea.parentNode.replaceChild(elt, myJsonTextArea); + }, json_editor_settings); + + $("#formCreatek8sr").submit(function (event) { + event.preventDefault(); //prevent default action + var post_url = $(this).attr("action"); //get form action url + var request_method = $(this).attr("method"); //get form GET/POST method + var form_data = new FormData(this); //Encode form elements for submission + $.ajax({ + url: post_url, + type: request_method, + data: form_data, + headers: { + "Accept": 'application/json' + }, + contentType: false, + processData: false + }).done(function (response, textStatus, jqXHR) { + table.ajax.reload(); + $('#modal_new_k8sr').modal('hide'); + }).fail(function (result) { + var data = result.responseJSON; + var title = "Error " + (data.code ? data.code : 'unknown'); + var message = data.detail ? data.detail : 'No detail available.'; + bootbox.alert({ + title: title, + message: message + }); + }); + }); + +}); \ No newline at end of file diff --git a/vimhandler/views.py b/vimhandler/views.py index 2a0d07e..ff1f2ae 100644 --- a/vimhandler/views.py +++ b/vimhandler/views.py @@ -78,6 +78,7 @@ def create(request): # TODO 'vim:show', to_redirect=True, vim_id=vim_id return __response_handler(request, result, 'vims:list', to_redirect=True, ) + @login_required def delete(request, vim_id=None): user = osmutils.get_user(request) @@ -88,6 +89,7 @@ def delete(request, vim_id=None): log.exception(e) return __response_handler(request, del_res, 'vims:list', to_redirect=True, ) + @login_required def show(request, vim_id=None): user = osmutils.get_user(request) -- 2.17.1