From 25bbfb14f191992f407d957d524ffb1cd0378655 Mon Sep 17 00:00:00 2001 From: fujinhua Date: Fri, 18 Aug 2017 15:03:18 +0800 Subject: Add seed codes of nfvo catalog Change-Id: Id0646870cbb297cbeddfe223feb2235f11a4a511 Issue-Id: VFC-108 Signed-off-by: fujinhua --- .gitignore | 3 + README.md | 15 ++ assembly.xml | 68 ++++++++++ catalog/__init__.py | 13 ++ catalog/pub/__init__.py | 13 ++ catalog/pub/config/__init__.py | 13 ++ catalog/pub/config/config.py | 60 ++++++++ catalog/pub/database/__init__.py | 13 ++ catalog/pub/database/models.py | 23 ++++ catalog/pub/exceptions.py | 17 +++ catalog/pub/msapi/__init__.py | 13 ++ catalog/pub/msapi/sdc.py | 69 ++++++++++ catalog/pub/utils/__init__.py | 13 ++ catalog/pub/utils/fileutil.py | 52 +++++++ catalog/pub/utils/restcall.py | 95 +++++++++++++ catalog/pub/utils/syscomm.py | 19 +++ catalog/pub/utils/timeutil.py | 19 +++ catalog/pub/utils/values.py | 25 ++++ catalog/samples/__init__.py | 13 ++ catalog/samples/tests.py | 32 +++++ catalog/samples/urls.py | 20 +++ catalog/samples/views.py | 65 +++++++++ catalog/settings.py | 151 +++++++++++++++++++++ catalog/urls.py | 26 ++++ catalog/wsgi.py | 22 +++ initialize.sh | 16 +++ logs/empty.txt | 0 manage.py | 22 +++ pom.xml | 52 +++++++ requirements.txt | 21 +++ resources/bin/initDB.sh | 50 +++++++ .../dbscripts/mysql/vfc-nfvo-catalog-createdb.sql | 31 +++++ .../dbscripts/mysql/vfc-nfvo-catalog-createobj.sql | 23 ++++ run.sh | 16 +++ static/catalog/empty.txt | 0 stop.sh | 16 +++ tox.ini | 10 ++ 37 files changed, 1129 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 assembly.xml create mode 100644 catalog/__init__.py create mode 100644 catalog/pub/__init__.py create mode 100644 catalog/pub/config/__init__.py create mode 100644 catalog/pub/config/config.py create mode 100644 catalog/pub/database/__init__.py create mode 100644 catalog/pub/database/models.py create mode 100644 catalog/pub/exceptions.py create mode 100644 catalog/pub/msapi/__init__.py create mode 100644 catalog/pub/msapi/sdc.py create mode 100644 catalog/pub/utils/__init__.py create mode 100644 catalog/pub/utils/fileutil.py create mode 100644 catalog/pub/utils/restcall.py create mode 100644 catalog/pub/utils/syscomm.py create mode 100644 catalog/pub/utils/timeutil.py create mode 100644 catalog/pub/utils/values.py create mode 100644 catalog/samples/__init__.py create mode 100644 catalog/samples/tests.py create mode 100644 catalog/samples/urls.py create mode 100644 catalog/samples/views.py create mode 100644 catalog/settings.py create mode 100644 catalog/urls.py create mode 100644 catalog/wsgi.py create mode 100644 initialize.sh create mode 100644 logs/empty.txt create mode 100644 manage.py create mode 100644 pom.xml create mode 100644 requirements.txt create mode 100644 resources/bin/initDB.sh create mode 100644 resources/dbscripts/mysql/vfc-nfvo-catalog-createdb.sql create mode 100644 resources/dbscripts/mysql/vfc-nfvo-catalog-createobj.sql create mode 100644 run.sh create mode 100644 static/catalog/empty.txt create mode 100644 stop.sh create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..67c551bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +logs/*.log +*.pyc +.idea \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..15867162 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +# Micro service of nfvo catalog. diff --git a/assembly.xml b/assembly.xml new file mode 100644 index 00000000..9143ac9f --- /dev/null +++ b/assembly.xml @@ -0,0 +1,68 @@ + + + catalog + + zip + + + + catalog + /catalog + + **/*.py + **/*.json + **/*.xml + + + + logs + /logs + + *.txt + + + + static + /static + + **/*.txt + + + + resources + /resources + + **/*.sh + **/*.sql + + + + . + / + + *.py + *.txt + *.sh + *.ini + *.md + + + + vfc/nfvo/catalog + diff --git a/catalog/__init__.py b/catalog/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/__init__.py b/catalog/pub/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/pub/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/config/__init__.py b/catalog/pub/config/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/pub/config/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/config/config.py b/catalog/pub/config/config.py new file mode 100644 index 00000000..0a64cb58 --- /dev/null +++ b/catalog/pub/config/config.py @@ -0,0 +1,60 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. +import os + +# [MSB] +MSB_SERVICE_IP = '127.0.0.1' +MSB_SERVICE_PORT = '80' + +# [REDIS] +REDIS_HOST = '127.0.0.1' +REDIS_PORT = '6379' +REDIS_PASSWD = '' + +# [mysql] +DB_IP = "127.0.0.1" +DB_PORT = 3306 +DB_NAME = "nfvocatalog" +DB_USER = "nfvocatalog" +DB_PASSWD = "nfvocatalog" + +# [register] +REG_TO_MSB_WHEN_START = True +REG_TO_MSB_REG_URL = "/api/microservices/v1/services" +REG_TO_MSB_REG_PARAM = { + "serviceName": "nfvocatalog", + "version": "v1", + "url": "/api/nfvocatalog/v1", + "protocol": "REST", + "visualRange": "1", + "nodes": [{ + "ip": "127.0.0.1", + "port": "8806", + "ttl": 0 + }] +} + +# catalog path(values is defined in settings.py) +CATALOG_ROOT_PATH = None +CATALOG_URL_PATH = None + +# [sdc config] +SDC_BASE_URL = "https://127.0.0.1:1234/api" +SDC_USER = "admin" +SDC_PASSWD = "admin" + + + + + diff --git a/catalog/pub/database/__init__.py b/catalog/pub/database/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/pub/database/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/database/models.py b/catalog/pub/database/models.py new file mode 100644 index 00000000..2d2ee330 --- /dev/null +++ b/catalog/pub/database/models.py @@ -0,0 +1,23 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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.db import models + + +class SampleModel(models.Model): + class Meta: + db_table = 'NFVO_SAMPLE' + + id = models.CharField(db_column='SAMPLEID', primary_key=True, max_length=255) + name = models.CharField(db_column='SAMPLENAME', max_length=255) + diff --git a/catalog/pub/exceptions.py b/catalog/pub/exceptions.py new file mode 100644 index 00000000..c994b46e --- /dev/null +++ b/catalog/pub/exceptions.py @@ -0,0 +1,17 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + + +class CatalogException(Exception): + pass diff --git a/catalog/pub/msapi/__init__.py b/catalog/pub/msapi/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/pub/msapi/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/msapi/sdc.py b/catalog/pub/msapi/sdc.py new file mode 100644 index 00000000..a4b157c3 --- /dev/null +++ b/catalog/pub/msapi/sdc.py @@ -0,0 +1,69 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import json +import logging + +from catalog.pub.exceptions import CatalogException +from catalog.pub.utils import restcall +from catalog.pub.config.config import SDC_BASE_URL, SDC_USER, SDC_PASSWD + +logger = logging.getLogger(__name__) + +ASSETTYPE_RESOURCES = "resources" +ASSETTYPE_SERVICES = "services" + +def call_sdc(resource, method, content=''): + return restcall.call_req(base_url=SDC_BASE_URL, + user=SDC_USER, + passwd=SDC_PASSWD, + auth_type=restcall.rest_no_auth, + resource=resource, + method=method, + content=content) + +def get_artifacts(asset_type): + resource = "/sdc/v1/catalog/{assetType}" + resource = resource.format(assetType=asset_type) + ret = call_sdc(resource, "GET") + if ret[0] != 0: + logger.error("Status code is %s, detail is %s.", ret[2], ret[1]) + raise CatalogException("Failed to query artifacts(%s) from sdc." % asset_type) + return json.JSONDecoder().decode(ret[1]) + +def get_artifact(asset_type, csar_id): + artifacts = get_artifacts(asset_type) + for artifact in artifacts: + if artifact["uuid"] == csar_id: + return artifact + raise CatalogException("Failed to query artifact(%s,%s) from sdc." % (asset_type, csar_id)) + +def delete_artifact(asset_type, asset_id, artifact_id): + resource = "/sdc/v1/catalog/{assetType}/{uuid}/artifacts/{artifactUUID}" + resource = resource.format(assetType=asset_type, uuid=asset_id, artifactUUID=artifact_id) + ret = call_sdc(resource, "DELETE") + if ret[0] != 0: + logger.error("Status code is %s, detail is %s.", ret[2], ret[1]) + raise CatalogException("Failed to delete artifacts(%s) from sdc." % artifact_id) + return json.JSONDecoder().decode(ret[1]) + +def download_artifacts(download_url, local_path): + ret = restcall.call_req(base_url=download_url, + user=SDC_USER, + passwd=SDC_PASSWD, + auth_type=rest_no_auth, + resource="", + method="GET") + # TODO: + diff --git a/catalog/pub/utils/__init__.py b/catalog/pub/utils/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/pub/utils/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/pub/utils/fileutil.py b/catalog/pub/utils/fileutil.py new file mode 100644 index 00000000..bd1a4aff --- /dev/null +++ b/catalog/pub/utils/fileutil.py @@ -0,0 +1,52 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. +import os +import shutil +import logging +import traceback +import urllib2 + +logger = logging.getLogger(__name__) + + +def make_dirs(path): + if not os.path.exists(path): + os.makedirs(path, 0777) + + +def delete_dirs(path): + try: + if os.path.exists(path): + shutil.rmtree(path) + except Exception as e: + logger.error(traceback.format_exc()) + logger.error("Failed to delete %s:%s", path, e.message) + + +def download_file_from_http(url, local_dir, file_name): + local_file_name = os.path.join(local_dir, file_name) + is_download_ok = False + try: + make_dirs(local_dir) + r = urllib2.Request(url) + req = urllib2.urlopen(r) + save_file = open(local_file_name, 'wb') + save_file.write(req.read()) + save_file.close() + req.close() + is_download_ok = True + except: + logger.error(traceback.format_exc()) + logger.error("Failed to download %s to %s.", url, local_file_name) + return is_download_ok, local_file_name diff --git a/catalog/pub/utils/restcall.py b/catalog/pub/utils/restcall.py new file mode 100644 index 00000000..a027fae4 --- /dev/null +++ b/catalog/pub/utils/restcall.py @@ -0,0 +1,95 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import sys +import traceback +import logging +import urllib2 +import uuid +import httplib2 + +from catalog.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT + +rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2 +HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '200', '201', '204', '202' +status_ok_list = [HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED] +HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN, HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '404', '403', '401', '400' + +logger = logging.getLogger(__name__) + + +def call_req(base_url, user, passwd, auth_type, resource, method, content=''): + callid = str(uuid.uuid1()) + logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % ( + callid, base_url, user, passwd, auth_type, resource, method, content)) + ret = None + resp_status = '' + try: + full_url = combine_url(base_url, resource) + headers = {'content-type': 'application/json', 'accept': 'application/json'} + if user: + headers['Authorization'] = 'Basic ' + ('%s:%s' % (user, passwd)).encode("base64") + ca_certs = None + for retry_times in range(3): + http = httplib2.Http(ca_certs=ca_certs, disable_ssl_certificate_validation=(auth_type == rest_no_auth)) + http.follow_all_redirects = True + try: + resp, resp_content = http.request(full_url, method=method.upper(), body=content, headers=headers) + resp_status, resp_body = resp['status'], resp_content.decode('UTF-8') + logger.debug("[%s][%d]status=%s,resp_body=%s)" % (callid, retry_times, resp_status, resp_body)) + if resp_status in status_ok_list: + ret = [0, resp_body, resp_status] + else: + ret = [1, resp_body, resp_status] + break + except Exception as ex: + if 'httplib.ResponseNotReady' in str(sys.exc_info()): + logger.debug("retry_times=%d", retry_times) + logger.error(traceback.format_exc()) + ret = [1, "Unable to connect to %s" % full_url, resp_status] + continue + raise ex + except urllib2.URLError as err: + ret = [2, str(err), resp_status] + except Exception as ex: + logger.error(traceback.format_exc()) + logger.error("[%s]ret=%s" % (callid, str(sys.exc_info()))) + res_info = str(sys.exc_info()) + if 'httplib.ResponseNotReady' in res_info: + res_info = "The URL[%s] request failed or is not responding." % full_url + ret = [3, res_info, resp_status] + except: + logger.error(traceback.format_exc()) + ret = [4, str(sys.exc_info()), resp_status] + + logger.debug("[%s]ret=%s" % (callid, str(ret))) + return ret + + +def req_by_msb(resource, method, content=''): + base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT) + return call_req(base_url, "", "", rest_no_auth, resource, method, content) + + +def combine_url(base_url, resource): + full_url = None + if base_url.endswith('/') and resource.startswith('/'): + full_url = base_url[:-1] + resource + elif base_url.endswith('/') and not resource.startswith('/'): + full_url = base_url + resource + elif not base_url.endswith('/') and resource.startswith('/'): + full_url = base_url + resource + else: + full_url = base_url + '/' + resource + return full_url diff --git a/catalog/pub/utils/syscomm.py b/catalog/pub/utils/syscomm.py new file mode 100644 index 00000000..89219ec9 --- /dev/null +++ b/catalog/pub/utils/syscomm.py @@ -0,0 +1,19 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import inspect + + +def fun_name(): + return inspect.stack()[1][3] diff --git a/catalog/pub/utils/timeutil.py b/catalog/pub/utils/timeutil.py new file mode 100644 index 00000000..1d97e9d7 --- /dev/null +++ b/catalog/pub/utils/timeutil.py @@ -0,0 +1,19 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import datetime + + +def now_time(fmt="%Y-%m-%d %H:%M:%S"): + return datetime.datetime.now().strftime(fmt) diff --git a/catalog/pub/utils/values.py b/catalog/pub/utils/values.py new file mode 100644 index 00000000..e3ac599e --- /dev/null +++ b/catalog/pub/utils/values.py @@ -0,0 +1,25 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + + +def ignore_case_get(args, key, def_val=""): + if not key: + return def_val + if key in args: + return args[key] + for old_key in args: + if old_key.upper() == key.upper(): + return args[old_key] + return def_val + diff --git a/catalog/samples/__init__.py b/catalog/samples/__init__.py new file mode 100644 index 00000000..c7b6818e --- /dev/null +++ b/catalog/samples/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. diff --git a/catalog/samples/tests.py b/catalog/samples/tests.py new file mode 100644 index 00000000..d2673d4b --- /dev/null +++ b/catalog/samples/tests.py @@ -0,0 +1,32 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import unittest +import json +from django.test import Client +from rest_framework import status + + +class SampleViewTest(unittest.TestCase): + def setUp(self): + self.client = Client() + + def tearDown(self): + pass + + def test_sample(self): + response = self.client.get("/samples/") + self.assertEqual(status.HTTP_200_OK, response.status_code, response.content) + resp_data = json.loads(response.content) + self.assertEqual({"status": "active"}, resp_data) diff --git a/catalog/samples/urls.py b/catalog/samples/urls.py new file mode 100644 index 00000000..7d65b36c --- /dev/null +++ b/catalog/samples/urls.py @@ -0,0 +1,20 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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 catalog.samples import views + +urlpatterns = [ + url(r'^api/nfvocatalog/v1/mandb/(?P[a-zA-Z\-]+)$', views.TablesList.as_view()), + url(r'^samples/$', views.SampleList.as_view()), ] diff --git a/catalog/samples/views.py b/catalog/samples/views.py new file mode 100644 index 00000000..bc1ebea2 --- /dev/null +++ b/catalog/samples/views.py @@ -0,0 +1,65 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import logging +import traceback + +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from catalog.pub.database import models + + +logger = logging.getLogger(__name__) + + +class SampleList(APIView): + """ + List all samples. + """ + def get(self, request, format=None): + logger.debug("get") + return Response({"status": "active"}) + +class TablesList(APIView): + def delete(self, request, modelName): + logger.debug("Start delete model %s", modelName) + try: + modelNames = modelName.split("-") + for name in modelNames: + model_obj = eval("models.%s.objects" % name) + model_obj.filter().delete() + logger.debug("End delete model %s", name) + except: + logger.error(traceback.format_exc()) + return Response(data={"error": "failed"}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response(data={}, status=status.HTTP_204_NO_CONTENT) + + + def get(self, request, modelName): + logger.debug("Get model %s", modelName) + count = 0 + try: + model_obj = eval("models.%s.objects" % modelName) + count = len(model_obj.filter()) + except: + logger.error(traceback.format_exc()) + return Response(data={"error": "failed"}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response(data={"count": count}, status=status.HTTP_200_OK) + + + + diff --git a/catalog/settings.py b/catalog/settings.py new file mode 100644 index 00000000..629f68a1 --- /dev/null +++ b/catalog/settings.py @@ -0,0 +1,151 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import os +import sys + +import redisco + +from catalog.pub.config.config import REDIS_HOST, REDIS_PORT, REDIS_PASSWD +from catalog.pub.config.config import DB_NAME, DB_IP, DB_USER, DB_PASSWD, DB_PORT +from catalog.pub.config import config + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '3o-wney!99y)^h3v)0$j16l9=fdjxcb+a8g+q3tfbahcnu2b0o' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rest_framework', + 'catalog.pub.database', + 'catalog.samples' +] + +MIDDLEWARE_CLASSES = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'catalog.urls' + +WSGI_APPLICATION = 'catalog.wsgi.application' + +REST_FRAMEWORK = { + 'DEFAULT_RENDERER_CLASSES': ( + 'rest_framework.renderers.JSONRenderer', + ), + + 'DEFAULT_PARSER_CLASSES': ( + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.MultiPartParser', + # 'rest_framework.parsers.FormParser', + # 'rest_framework.parsers.FileUploadParser', + ) +} + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': DB_NAME, + 'HOST': DB_IP, + 'PORT': DB_PORT, + 'USER': DB_USER, + 'PASSWORD': DB_PASSWD, + }, +} + +redisco.connection_setup(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWD, db=0) +# CACHE_BACKEND = 'redis_cache.cache://%s@%s:%s' % (REDIS_PASSWD, REDIS_HOST, REDIS_PORT) + +TIME_ZONE = 'UTC' + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.6/howto/static-files/ + +STATIC_URL = '/static/' + +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, "static") +] + +config.CATALOG_ROOT_PATH = os.path.join(STATICFILES_DIRS[0], "catalog") +config.CATALOG_URL_PATH = "static/catalog" + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': True, + 'formatters': { + 'standard': { + 'format': '%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s', + }, + }, + 'filters': { + }, + 'handlers': { + 'catalog_handler': { + 'level': 'DEBUG', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': os.path.join(BASE_DIR, 'logs/runtime_catalog.log'), + 'formatter': 'standard', + 'maxBytes': 1024 * 1024 * 50, + 'backupCount': 5, + }, + }, + + 'loggers': { + 'catalog': { + 'handlers': ['catalog_handler'], + 'level': 'DEBUG', + 'propagate': False + }, + } +} + +if 'test' in sys.argv: + config.REG_TO_MSB_WHEN_START = False + DATABASES = {} + DATABASES['default'] = { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:', + } + REST_FRAMEWORK = {} + import platform + + if platform.system() == 'Linux': + TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner' + TEST_OUTPUT_VERBOSE = True + TEST_OUTPUT_DESCRIPTIONS = True + TEST_OUTPUT_DIR = 'test-reports' diff --git a/catalog/urls.py b/catalog/urls.py new file mode 100644 index 00000000..46ae345c --- /dev/null +++ b/catalog/urls.py @@ -0,0 +1,26 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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 include, url +from catalog.pub.config.config import REG_TO_MSB_WHEN_START, REG_TO_MSB_REG_URL, REG_TO_MSB_REG_PARAM + +urlpatterns = [ + url(r'^', include('catalog.samples.urls')), +] + +# regist to MSB when startup +if REG_TO_MSB_WHEN_START: + import json + from catalog.pub.utils.restcall import req_by_msb + req_by_msb(REG_TO_MSB_REG_URL, "POST", json.JSONEncoder().encode(REG_TO_MSB_REG_PARAM)) diff --git a/catalog/wsgi.py b/catalog/wsgi.py new file mode 100644 index 00000000..35f6db05 --- /dev/null +++ b/catalog/wsgi.py @@ -0,0 +1,22 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "catalog.settings") + +application = get_wsgi_application() diff --git a/initialize.sh b/initialize.sh new file mode 100644 index 00000000..3425019b --- /dev/null +++ b/initialize.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +pip install -r requirements.txt diff --git a/logs/empty.txt b/logs/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/manage.py b/manage.py new file mode 100644 index 00000000..74b03610 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. + +import os +import sys + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "catalog.settings") + +if __name__ == "__main__": + from django.core.management import execute_from_command_line + execute_from_command_line(sys.argv) diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..0ca4b5ec --- /dev/null +++ b/pom.xml @@ -0,0 +1,52 @@ + + + + + org.onap.oparent + oparent + 1.0.0-SNAPSHOT + + 4.0.0 + org.onap.vfc.nfvo.catalog + vfc-nfvo-catalog + 1.0.0-SNAPSHOT + pom + vfc/nfvo/catalog + vfc nfvo catalog + + + + maven-assembly-plugin + + false + + assembly.xml + + + + + make-assembly + package + + single + + + + + + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..c98aff71 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,21 @@ +# rest framework +Django==1.9.6 +djangorestframework==3.3.3 + +# for access MySQL +MySQL-python==1.2.5 + +# redis cache +redis==2.10.5 + +# for access redis cache +redisco==0.1.4 +django-redis-cache==0.13.1 + +# for call rest api +httplib2==0.9.2 + +# for unit test +coverage==4.2 +mock==2.0.0 +unittest_xml_reporting==1.12.0 diff --git a/resources/bin/initDB.sh b/resources/bin/initDB.sh new file mode 100644 index 00000000..0971e00a --- /dev/null +++ b/resources/bin/initDB.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. +# + +DIRNAME=`dirname $0` +HOME=`cd $DIRNAME/; pwd` +user=$1 +password=$2 +port=$3 +host=$4 +echo "start create nfvocatalog db" +sql_path=$HOME/../ +mysql -u$user -p$password -P$port -h$host <$sql_path/dbscripts/mysql/vfc-nfvo-catalog-createdb.sql +sql_result=$? +if [ $sql_result != 0 ] ; then + echo "failed to create nfvocatalog database" + exit 1 +fi +fileFlag=*createobj.sql +location=$sql_path/dbscripts/mysql +fileName="" +for i in `ls $location` +do + if [[ $i == ${fileFlag} ]];then + fileName=${i}; + echo "start create table:${fileName}" + mysql -u$user -p$password -P$port -h$host <$sql_path/dbscripts/mysql/$fileName + sql_result=$? + if [ $sql_result != 0 ] ; then + echo "failed to init nfvocatalog table:${fileName}" + exit 1 + fi + fi +done +echo "init nfvocatalog database success!" +exit 0 + diff --git a/resources/dbscripts/mysql/vfc-nfvo-catalog-createdb.sql b/resources/dbscripts/mysql/vfc-nfvo-catalog-createdb.sql new file mode 100644 index 00000000..5e72e608 --- /dev/null +++ b/resources/dbscripts/mysql/vfc-nfvo-catalog-createdb.sql @@ -0,0 +1,31 @@ +-- +-- Copyright 2017 ZTE Corporation. +-- +-- 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 "AS IS" 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. +-- + +/******************drop old database and user***************************/ +use mysql; +drop database IF EXISTS nfvocatalog; +delete from user where User='nfvocatalog'; +FLUSH PRIVILEGES; + +/******************create new database and user***************************/ +create database nfvocatalog CHARACTER SET utf8; + +GRANT ALL PRIVILEGES ON nfvocatalog.* TO 'nfvocatalog'@'%' IDENTIFIED BY 'nfvocatalog' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON mysql.* TO 'nfvocatalog'@'%' IDENTIFIED BY 'nfvocatalog' WITH GRANT OPTION; + +GRANT ALL PRIVILEGES ON nfvocatalog.* TO 'nfvocatalog'@'localhost' IDENTIFIED BY 'nfvocatalog' WITH GRANT OPTION; +GRANT ALL PRIVILEGES ON mysql.* TO 'nfvocatalog'@'localhost' IDENTIFIED BY 'nfvocatalog' WITH GRANT OPTION; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/resources/dbscripts/mysql/vfc-nfvo-catalog-createobj.sql b/resources/dbscripts/mysql/vfc-nfvo-catalog-createobj.sql new file mode 100644 index 00000000..53b5b4f0 --- /dev/null +++ b/resources/dbscripts/mysql/vfc-nfvo-catalog-createobj.sql @@ -0,0 +1,23 @@ +-- +-- Copyright 2017 ZTE Corporation. +-- +-- 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 "AS IS" 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. +-- + +use nfvocatalog; + +DROP TABLE IF EXISTS NFVO_SAMPLE; +CREATE TABLE NFVO_SAMPLE ( + `SAMPLEID` varchar(255) NOT NULL PRIMARY KEY, + `SAMPLENAME` varchar(255) NOT NULL +); diff --git a/run.sh b/run.sh new file mode 100644 index 00000000..40136547 --- /dev/null +++ b/run.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. +sip=127.0.0.1 +nohup python manage.py runserver $sip:8806 > /dev/null & diff --git a/static/catalog/empty.txt b/static/catalog/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/stop.sh b/stop.sh new file mode 100644 index 00000000..67aceb90 --- /dev/null +++ b/stop.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2017 ZTE Corporation. +# +# 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 "AS IS" 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. +sip=127.0.0.1 +ps auxww | grep "manage.py runserver $sip:8806" | awk '{print $2}' | xargs kill -9 diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..baf2214a --- /dev/null +++ b/tox.ini @@ -0,0 +1,10 @@ +[tox] +envlist = py27 +skipsdist = true + +[tox:jenkins] +downloadcache = ~/cache/pip + +[testenv] +deps = -r{toxinidir}/requirements.txt +commands = coverage run --branch manage.py test lcm -- cgit 1.2.3-korg