diff options
-rw-r--r-- | docker/README.MD | 24 | ||||
-rw-r--r-- | docker/pom.xml | 154 | ||||
-rw-r--r-- | docker/src/main/docker/Dockerfile | 29 | ||||
-rw-r--r-- | docker/src/main/docker/prod_settings.cfg | 8 | ||||
-rw-r--r-- | docker/src/main/docker/run.sh | 7 | ||||
-rw-r--r-- | ice-server/heat_test/app.py | 53 | ||||
-rw-r--r-- | ice-server/heat_test/default_settings.cfg | 13 | ||||
-rw-r--r-- | ice-server/heat_test/default_settings.py | 9 | ||||
-rw-r--r-- | ice-server/heat_test/heat_validator.py | 7 | ||||
-rw-r--r-- | ice-server/heat_test/test/fixture/heat_template_empty.zip (renamed from ice-server/heat_test/test/fixture/test.zip) | bin | 166 -> 166 bytes | |||
-rw-r--r-- | ice-server/heat_test/test/fixture/heat_template_ok.zip | bin | 0 -> 1120 bytes | |||
-rw-r--r-- | pom.xml | 1 |
12 files changed, 285 insertions, 20 deletions
diff --git a/docker/README.MD b/docker/README.MD new file mode 100644 index 0000000..26a793b --- /dev/null +++ b/docker/README.MD @@ -0,0 +1,24 @@ +Introduction: +============= +This document provides the required steps for : +- generating the docker image of the heat validation rest service +- running the rest server. + +Installation steps: +==================== +Install following software: +- maven +- docker + +Configuration steps: +==================== +you can override the defaults settings (declared in default_settings.cfg and prod_settings.cfg) +by setting the env variable with the appropriate values (see Dockerfile for available ENV vars) + +How to run? +=========== +- make sure that the MSB is running +- build the image : +- ``$ mvn -P docker clean package`` +- run the server in DEBUG mode: +- ``$ docker run --rm --name vnfsdk-ice -d -p 5000:5000 -e DEBUG=True -e MSB_ADDR=<MSB ADDR> -e MSB_PORT=80 onap/vnfsdk/ice`` diff --git a/docker/pom.xml b/docker/pom.xml new file mode 100644 index 0000000..ad876b4 --- /dev/null +++ b/docker/pom.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Copyright (c) 2018 Orange. All rights reserved. + +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. +--><project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.oparent</groupId> + <artifactId>oparent</artifactId> + <version>0.1.1</version> + <relativePath>../../oparent</relativePath> + </parent> + + <groupId>org.onap.vnfsdk.ice</groupId> + <artifactId>vnf-sdk-ice-docker</artifactId> + <version>1.0.0-SNAPSHOT</version> + + <name>ice docker image builder</name> + <description>heat validation docker image builder</description> + <packaging>pom</packaging> + + <properties> + <maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format> + <docker.push.registry></docker.push.registry> + <skip.docker.build>true</skip.docker.build> + <skip.docker.tag>true</skip.docker.tag> + <skip.docker.push>true</skip.docker.push> + <docker.skip>false</docker.skip> + <docker.skip.build>false</docker.skip.build> + </properties> + <profiles> + <profile> + <id>docker</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <build> + <plugins> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + <version>0.16.7</version> + <configuration> + <verbose>true</verbose> + <apiVersion>1.23</apiVersion> + <skipDocker>${docker.skip}</skipDocker> + <images> + <image> + <name>onap/vnfsdk/ice</name> + <alias>ice</alias> + <build> + <cleanup>try</cleanup> + <dockerFileDir>${project.basedir}/src/main/docker</dockerFileDir> + <assembly> + <mode>dir</mode> + <inline xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>middleware-rest</id> + <fileSet> + <directory>${project.basedir}/../ice-server</directory> + <includes> + <include>requirements.txt</include> + <include>README.MD</include> + </includes> + <outputDirectory>ice-server</outputDirectory> + </fileSet> + <fileSet> + <directory>${project.basedir}/../ice-server/heat_test</directory> + <excludes> + <exclude>**/*.pyc</exclude> + <exclude>**/__pycache__</exclude> + </excludes> + <outputDirectory>ice-server/heat_test</outputDirectory> + </fileSet> + <fileSet> + <directory>${project.basedir}/../validation-scripts</directory> + <includes> + <include>requirements.txt</include> + <include>README.MD</include> + </includes> + <outputDirectory>validation-scripts</outputDirectory> + </fileSet> + <fileSet> + <directory>${project.basedir}/../validation-scripts/ice_validator</directory> + <excludes> + <exclude>**/*.pyc</exclude> + <exclude>**/__pycache__</exclude> + </excludes> + <outputDirectory>validation-scripts/ice_validator</outputDirectory> + </fileSet> + </inline> + </assembly> + </build> + </image> + </images> + </configuration> + <executions> + <execution> + <id>clean-images</id> + <phase>pre-clean</phase> + <goals> + <goal>remove</goal> + </goals> + <configuration> + <removeAll>true</removeAll> + <image>onap/vnfsdk/ice</image> + </configuration> + </execution> + + <execution> + <id>generate-images</id> + <phase>generate-sources</phase> + <goals> + <goal>build</goal> + </goals> + <configuration> + <skipDockerBuild>${docker.skip.build}</skipDockerBuild> + </configuration> + </execution> + <execution> + <id>push-images</id> + <phase>deploy</phase> + <goals> + <goal>build</goal> + <goal>push</goal> + </goals> + <configuration> + <image>onap/vnfsdk/ice</image> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/docker/src/main/docker/Dockerfile b/docker/src/main/docker/Dockerfile new file mode 100644 index 0000000..7b3f033 --- /dev/null +++ b/docker/src/main/docker/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.6.1 + +ENV ICE_SETTINGS /opt/ice/ice-server/heat_test/prod_settings.cfg +ENV DEBUG False +ENV MSB_ADDR "127.0.0.1" +ENV MSB_PORT 80 + +# add application +COPY maven/ /opt/ice +COPY prod_settings.cfg /opt/ice/ice-server/heat_test/ +COPY run.sh /opt/ice/ice-server/heat_test/ + +EXPOSE 5000 + +# install requirements +# Create the group and user to be used in this container +RUN pip install -r /opt/ice/ice-server/requirements.txt &&\ + pip install -r /opt/ice/validation-scripts/requirements.txt &&\ + pip install dumb-init &&\ + groupadd flaskgroup && useradd -m -g flaskgroup -s /bin/bash flask &&\ + chown -R flask:flaskgroup /opt/ice &&\ + chmod +x /opt/ice/ice-server/heat_test/*.sh + +USER flask +WORKDIR /opt/ice/ice-server/heat_test +# use dumb-init to translate SIGTERM to SIGINT +# this is needed to gracefully stop flask (and unregister service properly) +ENTRYPOINT ["dumb-init", "--rewrite", "15:2", "--"] +CMD ["./run.sh"] diff --git a/docker/src/main/docker/prod_settings.cfg b/docker/src/main/docker/prod_settings.cfg new file mode 100644 index 0000000..f623d76 --- /dev/null +++ b/docker/src/main/docker/prod_settings.cfg @@ -0,0 +1,8 @@ +# ICE production settings +DEBUG = False + +# MSB production settings +MSB_ADDR = "127.0.0.1" +MSB_PORT = "80" +MSB_URL = "http://%s:%s/api/microservices/v1/services" % (MSB_ADDR, MSB_PORT) + diff --git a/docker/src/main/docker/run.sh b/docker/src/main/docker/run.sh new file mode 100644 index 0000000..662c8cf --- /dev/null +++ b/docker/src/main/docker/run.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +sed -i "s/DEBUG =.*/DEBUG = ${DEBUG}/g" ${ICE_SETTINGS} +sed -i "s/MSB_ADDR =.*/MSB_ADDR = \"${MSB_ADDR}\"/g" ${ICE_SETTINGS} +sed -i "s/MSB_PORT =.*/MSB_PORT = \"${MSB_PORT}\"/g" ${ICE_SETTINGS} + +/usr/local/bin/python app.py
\ No newline at end of file diff --git a/ice-server/heat_test/app.py b/ice-server/heat_test/app.py index c61150a..97c32a9 100644 --- a/ice-server/heat_test/app.py +++ b/ice-server/heat_test/app.py @@ -1,18 +1,19 @@ #!flask/bin/python -import argparse +import atexit import logging -import requests import connexion +import requests from connexion.resolver import RestyResolver +config = '' def create_app(): logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') app = connexion.App(__name__, specification_dir='swagger/') # load default config - app.app.config.from_object("default_settings") + app.app.config.from_pyfile("default_settings.cfg") app.app.config.from_envvar('ICE_SETTINGS', silent=True) app.add_api('ice_api.yaml', swagger_ui=app.app.config['DEBUG'], resolver=RestyResolver('ice_validator')) @@ -32,15 +33,51 @@ def start_app(app): logging.info("######################################") logging.info("starting server") logging.info("######################################") + global config + config = app.app.config + msb_register() + atexit.register(msb_unregister) app.run(port=app.app.config['ICE_PORT'], debug=app.app.config['DEBUG']) - # register service in MSB + +def msb_register(): + try: + msb_url = config['MSB_URL'] + ice_json = { + "serviceName": config['ICE_SERVICE_NAME'], + "version": config['ICE_VERSION'], + "url": "/onapapi/ice/v1", + "protocol": "REST", + "visualRange": "1", + "nodes": [ + { + "ip": config['ICE_ADDR'], + "port": config['ICE_PORT'], + "ttl": 0 + } + ] + } + resp = requests.post(msb_url, json=ice_json) + if resp.status_code == 201: + global registered + registered = True + logging.info("registration to '%s' done", msb_url) + else: + logging.info("registration to '%s' failed; status_code = '%s'", msb_url, resp.status_code) + except: + logging.info("registration to '%s' failed", msb_url) + + +def msb_unregister(): try: - msb_url = app.app.config['MSB_URL'] - requests.get(msb_url) - logging.info("registration to %s done", msb_url) + msb_url = "%s/%s/version/%s" % (config['MSB_URL'], config['ICE_SERVICE_NAME'], config['ICE_VERSION']) + resp = requests.delete(msb_url) + if resp.status_code == 200: + logging.info("unregistration from '%s' done", msb_url) + else: + logging.info("unregistration from '%s' failed; status_code = '%s'", msb_url, resp.status_code) except: - logging.info("registration to %s failed", msb_url) + logging.info("unregistration from '%s' failed", msb_url) if __name__ == '__main__': diff --git a/ice-server/heat_test/default_settings.cfg b/ice-server/heat_test/default_settings.cfg new file mode 100644 index 0000000..3721bbf --- /dev/null +++ b/ice-server/heat_test/default_settings.cfg @@ -0,0 +1,13 @@ +# ICE settings +DEBUG = True +ICE_ADDR = "127.0.0.1" +ICE_PORT = 5000 +ICE_SCRIPT_PATH = '../../validation-scripts/ice_validator' +ICE_VERSION = "v1" +ICE_SERVICE_NAME = "vnfsdk-ice" + +# MSB settings +MSB_ADDR = "127.0.0.1" +MSB_PORT = "80" +MSB_URL = "http://%s:%s/api/microservices/v1/services" % (MSB_ADDR, MSB_PORT) + diff --git a/ice-server/heat_test/default_settings.py b/ice-server/heat_test/default_settings.py deleted file mode 100644 index d32d039..0000000 --- a/ice-server/heat_test/default_settings.py +++ /dev/null @@ -1,9 +0,0 @@ -# ICE settings -DEBUG = True -ICE_PORT = 5000 - -# MSB settings -MSB_IP = "127.0.0.1" -MSB_PORT = "80" -MSB_URL = "http://"+MSB_IP+':'+MSB_PORT+"/api/microservices/v1/services" - diff --git a/ice-server/heat_test/heat_validator.py b/ice-server/heat_test/heat_validator.py index 0cc32a1..d76d275 100644 --- a/ice-server/heat_test/heat_validator.py +++ b/ice-server/heat_test/heat_validator.py @@ -7,7 +7,7 @@ import zipfile from io import StringIO import pytest -from flask import (request, jsonify, abort) +from flask import (request, jsonify, abort, current_app) class HeatValidator(object): @@ -49,7 +49,8 @@ class HeatValidator(object): original_output = sys.stdout # Assign StringIO so the output is not sent anymore to the console sys.stdout = StringIO() - exit_code = pytest.main(['../../validation-scripts/ice_validator', + script_path = current_app.config['ICE_SCRIPT_PATH'] + exit_code = pytest.main([script_path, '--resultlog=' + tmp_dir + '/result.txt', '--template-dir', tmp_dir]) with open(tmp_dir + '/result.txt', 'r') as result_file: @@ -62,7 +63,7 @@ class HeatValidator(object): except zipfile.BadZipFile: logging.exception("invalid file") abort(422, {'status': 4, 'message': 'invalid file'}) - except: + except Exception as e: logging.exception("server error on file") abort(500, {'status': 3, 'message': 'server error'}) finally: diff --git a/ice-server/heat_test/test/fixture/test.zip b/ice-server/heat_test/test/fixture/heat_template_empty.zip Binary files differindex d1e6d99..d1e6d99 100644 --- a/ice-server/heat_test/test/fixture/test.zip +++ b/ice-server/heat_test/test/fixture/heat_template_empty.zip diff --git a/ice-server/heat_test/test/fixture/heat_template_ok.zip b/ice-server/heat_test/test/fixture/heat_template_ok.zip Binary files differnew file mode 100644 index 0000000..4e89aba --- /dev/null +++ b/ice-server/heat_test/test/fixture/heat_template_ok.zip @@ -33,5 +33,6 @@ under the License. <modules> <module>validation-scripts</module> <module>ice-server</module> + <module>docker</module> </modules> </project> |