From: lavado Date: Wed, 7 Nov 2018 19:50:48 +0000 (+0100) Subject: Merge "Adding persistent volume to POL" X-Git-Tag: v5.0.0~35 X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=e3167903834bdcb8d65e178edff8aca0bc31ce20;hp=0ef7a6de428944fd87f788d1af6f70ed5d1632c1;p=osm%2Fdevops.git Merge "Adding persistent volume to POL" --- diff --git a/descriptor-packages/nsd/hackfest_ansible_ns/Makefile b/descriptor-packages/nsd/hackfest_ansible_ns/Makefile new file mode 100644 index 00000000..9c180829 --- /dev/null +++ b/descriptor-packages/nsd/hackfest_ansible_ns/Makefile @@ -0,0 +1,20 @@ +# +# Copyright 2018 Telefonica +# +# 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. +# + +DESCRIPTORS_TOPDIR ?= ../.. +include $(DESCRIPTORS_TOPDIR)/mk/pkg.mk + +all: $(BUILD_DIR)/$(PKG_NAME) diff --git a/descriptor-packages/nsd/hackfest_ansible_ns/src/ansiblecharm_nsd.yaml b/descriptor-packages/nsd/hackfest_ansible_ns/src/ansiblecharm_nsd.yaml new file mode 100644 index 00000000..031ed4ec --- /dev/null +++ b/descriptor-packages/nsd/hackfest_ansible_ns/src/ansiblecharm_nsd.yaml @@ -0,0 +1,26 @@ +nsd:nsd-catalog: + nsd: + - id: ansiblecharm_nsd + name: ansiblecharm_nsd + short-name: ansiblecharm_nsd + description: Generated by OSM package generator + vendor: OSM + logo: osm.png + version: '1.0' + constituent-vnfd: + # The member-vnf-index needs to be unique, starting from 1 + # vnfd-id-ref is the id of the VNFD + # Multiple constituent VNFDs can be specified + - member-vnf-index: 1 + vnfd-id-ref: ansiblecharm_vnfd + vld: + # Networks for the VNFs + - id: mgmtnet + name: mgmtnet + short-name: mgmtnet + type: ELAN + mgmt-network: 'true' + vnfd-connection-point-ref: + - member-vnf-index-ref: 1 + vnfd-id-ref: ansiblecharm_vnfd + vnfd-connection-point-ref: vnf-cp0 diff --git a/descriptor-packages/nsd/hackfest_ansible_ns/src/icons/osm.png b/descriptor-packages/nsd/hackfest_ansible_ns/src/icons/osm.png new file mode 100644 index 00000000..62012d2a Binary files /dev/null and b/descriptor-packages/nsd/hackfest_ansible_ns/src/icons/osm.png differ diff --git a/descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml b/descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml index 94fa5f1f..6d5da86f 100644 --- a/descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml +++ b/descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml @@ -29,8 +29,8 @@ vnfd-catalog: storage-gb: 2 # Image/checksum or image including the full path - image: 'cirros034' - #checksum: + image: 'cirros-0.3.5-x86_64-disk.img' + #checksum: interface: # Specify the external interfaces diff --git a/descriptor-packages/vnfd/hackfest_ansible_vnf/Makefile b/descriptor-packages/vnfd/hackfest_ansible_vnf/Makefile new file mode 100644 index 00000000..e9893314 --- /dev/null +++ b/descriptor-packages/vnfd/hackfest_ansible_vnf/Makefile @@ -0,0 +1,21 @@ +# +# Copyright 2018 Telefonica +# +# 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. +# +DESCRIPTORS_TOPDIR ?= ../.. + +VNFD_CHARM = ansible-charm +include $(DESCRIPTORS_TOPDIR)/mk/pkg.mk + +all: $(BUILD_DIR)/$(PKG_NAME) diff --git a/descriptor-packages/vnfd/hackfest_ansible_vnf/src/ansiblecharm_vnfd.yaml b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/ansiblecharm_vnfd.yaml new file mode 100644 index 00000000..873d0412 --- /dev/null +++ b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/ansiblecharm_vnfd.yaml @@ -0,0 +1,55 @@ +vnfd:vnfd-catalog: + vnfd: + - id: ansiblecharm_vnfd + name: ansiblecharm_vnfd + short-name: ansiblecharm_vnfd + description: Generated by OSM package generator + vendor: OSM + logo: osm.png + version: '1.0' + connection-point: + - name: vnf-cp0 + type: VPORT + mgmt-interface: + cp: vnf-cp0 + vdu: + - id: ansiblecharm_vnfd-VM + name: ansiblecharm_vnfd-VM + description: ansiblecharm_vnfd-VM + count: 1 + vm-flavor: + vcpu-count: 1 + memory-mb: 1024 + storage-gb: 10 + image: 'ubuntu1604' + interface: + - name: vdu-eth0 + type: EXTERNAL + virtual-interface: + type: VIRTIO + external-connection-point-ref: vnf-cp0 + cloud-init-file: cloud-config.txt + vnf-configuration: + juju: + charm: ansible-charm + initial-config-primitive: + - seq: 1 + name: config + parameter: + - name: ssh-hostname + value: + - name: ssh-username + value: ubuntu + - name: ssh-password + value: osm4u + - seq: 2 + name: ansible-playbook + parameter: + - name: filename + value: '/home/ubuntu/first-touch' + config-primitive: + - name: ansible-playbook + parameter: + - name: filename + data-type: STRING + value: '/home/ubuntu/first-touch' diff --git a/descriptor-packages/vnfd/hackfest_ansible_vnf/src/cloud_init/cloud-config.txt b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/cloud_init/cloud-config.txt new file mode 100644 index 00000000..36c8d1bf --- /dev/null +++ b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/cloud_init/cloud-config.txt @@ -0,0 +1,12 @@ +#cloud-config +password: osm4u +chpasswd: { expire: False } +ssh_pwauth: True + +write_files: +- content: | + # My new helloworld file + + owner: root:root + permissions: '0644' + path: /root/helloworld.txt diff --git a/descriptor-packages/vnfd/hackfest_ansible_vnf/src/icons/osm.png b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/icons/osm.png new file mode 100644 index 00000000..62012d2a Binary files /dev/null and b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/icons/osm.png differ diff --git a/descriptor-packages/vnfd/hackfest_basic_vnf/src/hackfest_basic_vnfd.yaml b/descriptor-packages/vnfd/hackfest_basic_vnf/src/hackfest_basic_vnfd.yaml index fa7f1ff8..b407a849 100644 --- a/descriptor-packages/vnfd/hackfest_basic_vnf/src/hackfest_basic_vnfd.yaml +++ b/descriptor-packages/vnfd/hackfest_basic_vnf/src/hackfest_basic_vnfd.yaml @@ -1,29 +1,29 @@ vnfd:vnfd-catalog: - vnfd:vnfd: - - vnfd:id: hackfest_basic-vnf - vnfd:name: hackfest_basic-vnf - vnfd:short-name: hackfest_basic-vnf - vnfd:version: '1.0' - vnfd:description: A basic VNF descriptor w/ one VDU - vnfd:logo: osm.png - vnfd:connection-point: - - vnfd:name: vnf-cp0 - vnfd:type: VPORT - vnfd:vdu: - - vnfd:id: hackfest_basic-VM - vnfd:name: hackfest_basic-VM - vnfd:image: ubuntu1604 - vnfd:count: '1' - vnfd:vm-flavor: - vnfd:vcpu-count: '1' - vnfd:memory-mb: '1024' - vnfd:storage-gb: '10' - vnfd:interface: - - vnfd:name: vdu-eth0 - vnfd:type: EXTERNAL - vnfd:virtual-interface: - vnfd:type: VIRTIO - vnfd:external-connection-point-ref: vnf-cp0 - vnfd:mgmt-interface: - vnfd:cp: vnf-cp0 + vnfd: + - id: hackfest_basic-vnf + name: hackfest_basic-vnf + short-name: hackfest_basic-vnf + version: '1.0' + description: A basic VNF descriptor w/ one VDU + logo: osm.png + connection-point: + - name: vnf-cp0 + type: VPORT + vdu: + - id: hackfest_basic-VM + name: hackfest_basic-VM + image: ubuntu1604 + count: '1' + vm-flavor: + vcpu-count: '1' + memory-mb: '1024' + storage-gb: '10' + interface: + - name: vdu-eth0 + type: EXTERNAL + virtual-interface: + type: VIRTIO + external-connection-point-ref: vnf-cp0 + mgmt-interface: + cp: vnf-cp0 diff --git a/docker/Keystone/Dockerfile b/docker/Keystone/Dockerfile index 263716a0..2030aa51 100644 --- a/docker/Keystone/Dockerfile +++ b/docker/Keystone/Dockerfile @@ -21,12 +21,14 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* && \ chmod +x start.sh -ENV DB_HOST keystone-db # DB Hostname -ENV DB_PORT 3306 # DB Port -ENV ROOT_DB_USER root # DB Root User -ENV ROOT_DB_PASSWORD admin # DB Root Password -ENV KEYSTONE_DB_PASSWORD admin # Keystone user password -ENV ADMIN_PASSWORD admin # Admin password -ENV NBI_PASSWORD nbi # NBI password +# database +ENV DB_HOST keystone-db +ENV DB_PORT 3306 +ENV ROOT_DB_USER root +ENV ROOT_DB_PASSWORD admin +# keystone +ENV KEYSTONE_DB_PASSWORD admin +ENV ADMIN_PASSWORD admin +ENV NBI_PASSWORD nbi ENTRYPOINT ./start.sh diff --git a/docker/LCM/Dockerfile b/docker/LCM/Dockerfile index 46be58e7..1a750d3b 100644 --- a/docker/LCM/Dockerfile +++ b/docker/LCM/Dockerfile @@ -23,21 +23,24 @@ RUN apt-get update && apt-get -y install curl software-properties-common RUN apt-get update && apt-get install -y git make python3 \ python3-pip python3-pymongo python3-yaml python3-aiohttp \ - python3-all python3-setuptools \ + python3-all python3-setuptools openssh-client libffi-dev libssl-dev \ python3-bitarray python3-regex python3-lxml dh-python wget tox \ python3-cffi \ && pip3 install pip==9.0.3 \ && pip3 install -U aiokafka pyang lxml six enum34 \ && pip3 install websockets==4.0.1 \ - && pip3 install requests - -RUN pip3 install PyNaCl - -RUN git clone https://osm.etsi.org/gerrit/osm/N2VC.git \ - && cd N2VC \ - && git checkout BUILD_v4.0.1_1 \ - && cd modules/libjuju && python3 setup.py develop && cd ../.. \ - && pip3 install -U -r requirements.txt + && pip3 install requests \ + && rm -rf /var/lib/apt/lists/* + +# packages needed for N2VC because deb dependencies are not fine +RUN pip3 install 'macaroonbakery>=1.1,<2.0' 'pyRFC3339>=1.0,<2.0' \ + 'pyyaml>=3.0,<4.0' 'theblues>=0.3.8,<1.0' 'websockets>=4.0,<5.0' \ + 'paramiko' # PyNaCl +# +# RUN git clone https://osm.etsi.org/gerrit/osm/N2VC.git \ +# && cd N2VC \ +# && cd modules/libjuju && python3 setup.py develop && cd ../.. \ +# && pip3 install -U -r requirements.txt ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian ARG RELEASE=ReleaseFOUR-daily @@ -91,5 +94,9 @@ ENV OSMLCM_MESSAGE_DRIVER kafka ENV OSMLCM_MESSAGE_HOST kafka ENV OSMLCM_MESSAGE_PORT 9092 +HEALTHCHECK --interval=30s --timeout=140s --retries=1 \ + CMD python3 /usr/lib/python3/dist-packages/osm_lcm/lcm.py --health-check || exit 1 + + # Run app.py when the container launches CMD ["python3", "/usr/lib/python3/dist-packages/osm_lcm/lcm.py"] diff --git a/docker/MON/Dockerfile b/docker/MON/Dockerfile index 0da9c914..5b9da33e 100644 --- a/docker/MON/Dockerfile +++ b/docker/MON/Dockerfile @@ -45,11 +45,12 @@ RUN apt-get --yes update && apt-get -y install python3-osm-common${COMMON_VERSI COPY scripts/ scripts/ -RUN pip3 install -r scripts/requirements.txt - -# These ENV must be provided -# ENV BROKER_URI=kafka:9092 -# ENV OS_NOTIFIER_URI=:8662 +ENV BROKER_URI kafka:9092 +ENV MONGO_URI mongo:27017 +ENV DATABASE sqlite:///mon_sqlite.db +ENV OS_NOTIFIER_URI localhost:8662 +ENV OS_DEFAULT_GRANULARITY 300 +ENV REQUEST_TIMEOUT 10 EXPOSE 8662 diff --git a/docker/MON/scripts/requirements.txt b/docker/MON/scripts/requirements.txt deleted file mode 100644 index 28bb7197..00000000 --- a/docker/MON/scripts/requirements.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2017 Intel Research and Development Ireland Limited -# ************************************************************* - -# This file is part of OSM Monitoring module -# All Rights Reserved to Intel 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. - -# For those usages not covered by the Apache License, Version 2.0 please -# contact: prithiv.mohan@intel.com or adrian.hoban@intel.com -kafka==1.3.* -lxml==4.2.* -requests==2.18.* -logutils==0.3.* -cherrypy==14.0.* -jsmin==2.2.* -jsonschema==2.6.* -python-openstackclient==3.15.* -python-novaclient==10.1.* -python-keystoneclient==3.15.* -boto==2.48 -python-cloudwatchlogs-logging==0.0.3 -py-cloudwatch==0.0.1 -pyvcloud==19.1.1 -pyopenssl==17.5.* -six==1.11.* -bottle==0.12.* -peewee==3.1.* -pyyaml==3.* diff --git a/docker/RO/Dockerfile b/docker/RO/Dockerfile index 0607d91e..8ba46c48 100644 --- a/docker/RO/Dockerfile +++ b/docker/RO/Dockerfile @@ -3,7 +3,8 @@ from ubuntu:xenial MAINTAINER Gennadiy Dubina ; Alfonso Tierno RUN apt-get update && apt-get -y install curl software-properties-common git -RUN apt-get update && apt-get install -y python-setuptools python-wheel mysql-client python-bitarray +RUN apt-get update && apt-get install -y python-setuptools python-wheel mysql-client python-bitarray python-pip +RUN DEBIAN_FRONTEND=noninteractive pip2 install pip==9.0.3 pyangbind ARG REPOSITORY_BASE=http://osm-download.etsi.org/repository/osm/debian ARG RELEASE=ReleaseFOUR-daily diff --git a/docker/light-ui/Dockerfile b/docker/light-ui/Dockerfile index 5cf9aa70..4440b9a0 100644 --- a/docker/light-ui/Dockerfile +++ b/docker/light-ui/Dockerfile @@ -1,12 +1,12 @@ -FROM ubuntu:16.04 +FROM ubuntu:16.04 -WORKDIR /usr/src/app +WORKDIR /usr/share/osm-lightui RUN apt-get update && apt-get install -y npm git python-pip nginx supervisor RUN npm install -g bower ARG LWUI_VERSION= -RUN git clone https://osm.etsi.org/gerrit/osm/LW-UI /usr/src/app && echo LWUI_VERSION +RUN git clone https://osm.etsi.org/gerrit/osm/LW-UI /usr/share/osm-lightui && echo LWUI_VERSION RUN ln -s /usr/bin/nodejs /usr/bin/node RUN bower install --allow-root @@ -15,8 +15,8 @@ RUN pip install -r requirements.txt RUN pip install uwsgi # RUN echo "daemon off;" >> /etc/nginx/nginx.conf -RUN cp /usr/src/app/nginx-app.conf /etc/nginx/sites-available/default -RUN cp /usr/src/app/supervisor-app.conf /etc/supervisor/conf.d/ +RUN cp /usr/share/osm-lightui/nginx-app.conf /etc/nginx/sites-available/default +RUN cp /usr/share/osm-lightui/supervisor-app.conf /etc/supervisor/conf.d/ # delete the copy of the database inside the container (if exists) RUN rm -f db.sqlite3 diff --git a/docker/mk/Makefile.include b/docker/mk/Makefile.include index 04d2fac6..2be4d295 100644 --- a/docker/mk/Makefile.include +++ b/docker/mk/Makefile.include @@ -19,7 +19,7 @@ CONTAINER_NAME ?= $(LOWER_MDG) CMD_DOCKER_ARGS ?= -q DOCKER_ARGS = $(CMD_DOCKER_ARGS) -DEPS := MON IM LCM RO common osmclient devops NBI policy-module Keystone +DEPS := MON IM LCM RO common osmclient devops NBI policy-module Keystone N2VC DEPS_TARGETS = $(addprefix $(MKBUILD)/.dep_, $(DEPS)) @@ -49,6 +49,7 @@ build: $(MKBUILD) $(DEPS_TARGETS) --build-arg NBI_VERSION==$(shell cat $(MKBUILD)/.dep_NBI) \ --build-arg POL_VERSION==$(shell cat $(MKBUILD)/.dep_policy-module) \ --build-arg DEVOPS_VERSION==$(shell cat $(MKBUILD)/.dep_devops) \ + --build-arg N2VC_VERSION==$(shell cat $(MKBUILD)/.dep_N2VC) \ --build-arg LWUI_VERSION==$(shell date +%s) \ $(DOCKER_ARGS) . diff --git a/installers/docker/osm_elk/docker-compose.yml b/installers/docker/osm_elk/docker-compose.yml index 9f03c4fc..f7dc2aae 100644 --- a/installers/docker/osm_elk/docker-compose.yml +++ b/installers/docker/osm_elk/docker-compose.yml @@ -2,33 +2,51 @@ version: '3' services: - elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.3 - volumes: - - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro - environment: - ES_JAVA_OPTS: "-Xmx256m -Xms256m" + filebeat: + image: docker.elastic.co/beats/filebeat:${ELASTIC_VERSION:-6.4.2} + hostname: "{{.Node.Hostname}}-filebeat" + user: root networks: - elk + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/containers/:/var/lib/docker/containers/:ro + - ./filebeat.yml:/usr/share/filebeat/filebeat.yml + command: ["--strict.perms=false"] - logstash: - image: docker.elastic.co/logstash/logstash-oss:6.2.3 + metricbeat: + image: docker.elastic.co/beats/metricbeat:${ELASTIC_VERSION:-6.4.2} + user: root + deploy: + mode: global volumes: - - ./logstash.yml:/usr/share/logstash/config/logstash.yml:ro - - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro + - /proc:/hostfs/proc:ro + - /sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro + - /:/hostfs:ro + - ./metricbeat.yml:/usr/share/metricbeat/metricbeat.yml + - /var/run/docker.sock:/var/run/docker.sock:ro + command: --strict.perms=false -e -c /usr/share/metricbeat/metricbeat.yml -system.hostfs=/hostfs # -e flag to log to stderr and disable syslog/file output + networks: + - elk + depends_on: ['elasticsearch', 'kibana'] + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch-oss:${ELASTIC_VERSION:-6.4.2} + volumes: + - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro + ports: + - "9200:9200" environment: - LS_JAVA_OPTS: "-Xmx256m -Xms256m" + ES_JAVA_OPTS: "-Xmx256m -Xms256m" networks: - elk - depends_on: - - elasticsearch kibana: - image: docker.elastic.co/kibana/kibana-oss:6.2.3 + image: docker.elastic.co/kibana/kibana-oss:${ELASTIC_VERSION:-6.4.2} volumes: - ./kibana.yml:/usr/share/kibana/config/kibana.yml:ro ports: - - "${OSM_ELK_PORTS:-5601:5601}" + - "5601:5601" networks: - elk depends_on: @@ -37,4 +55,4 @@ services: networks: elk: external: - name: ${OSM_NETWORK:-netOSM} + name: ${OSM_NETWORK:-netosm} diff --git a/installers/docker/osm_elk/elasticsearch.yml b/installers/docker/osm_elk/elasticsearch.yml index ba678747..f6a7dd4a 100644 --- a/installers/docker/osm_elk/elasticsearch.yml +++ b/installers/docker/osm_elk/elasticsearch.yml @@ -3,3 +3,4 @@ network.host: 0.0.0.0 cluster.name: "docker-cluster" discovery.type: single-node discovery.zen.minimum_master_nodes: 1 +bootstrap.memory_lock: true diff --git a/installers/docker/osm_elk/filebeat.yml b/installers/docker/osm_elk/filebeat.yml new file mode 100644 index 00000000..6769a9f8 --- /dev/null +++ b/installers/docker/osm_elk/filebeat.yml @@ -0,0 +1,51 @@ +# 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. + +######################## Filebeat Configuration ############################ + +filebeat.inputs: +#------------------------------ Docker input -------------------------------- +# Experimental: Docker input reads and parses `json-file` logs from Docker +- type: docker + enabled: true + # Combine partial lines flagged by `json-file` format + #combine_partials: true + + # Use this to read from all containers, replace * with a container id to read from one: + containers: + # stream: all # can be all, stdout or stderr + ids: + - '*' + +processors: +- add_docker_metadata: ~ +# +# The following example enriches each event with host metadata. +# +#processors: +#- add_host_metadata: +# netinfo.enabled: false +# + +#-------------------------- Elasticsearch output ------------------------------- +output.elasticsearch: + # Boolean flag to enable or disable the output module. + #enabled: true + + # Array of hosts to connect to. + # Scheme and port can be left out and will be set to the default (http and 9200) + # In case you specify and additional path, the scheme is required: http://localhost:9200/path + # IPv6 addresses should always be defined as: https://[2001:db8::1]:9200 + hosts: ["elasticsearch:9200"] + + +logging.to_files: true diff --git a/installers/docker/osm_elk/logstash.conf b/installers/docker/osm_elk/logstash.conf deleted file mode 100644 index a83a572b..00000000 --- a/installers/docker/osm_elk/logstash.conf +++ /dev/null @@ -1,17 +0,0 @@ -input { - tcp { - port => 5000 - } - kafka { - bootstrap_servers => 'kafka:9092' - topics => ["alarm_response", "lcm_pm"] - } -} - -## Add your filters / logstash plugins configuration here - -output { - elasticsearch { - hosts => "elasticsearch:9200" - } -} diff --git a/installers/docker/osm_elk/logstash.yml b/installers/docker/osm_elk/logstash.yml deleted file mode 100644 index 91bcbb1c..00000000 --- a/installers/docker/osm_elk/logstash.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -path.config: /usr/share/logstash/pipeline -http.host: "0.0.0.0" diff --git a/installers/docker/osm_elk/metricbeat.yml b/installers/docker/osm_elk/metricbeat.yml new file mode 100644 index 00000000..61feaef7 --- /dev/null +++ b/installers/docker/osm_elk/metricbeat.yml @@ -0,0 +1,63 @@ +metricbeat.modules: +- module: docker + metricsets: ["container", "cpu", "diskio", "healthcheck", "info", "memory", "network"] + hosts: ["unix:///var/run/docker.sock"] + period: 30s + enabled: true +- module: mongodb + hosts: ["mongo"] + period: 30s + enabled: true +- module: mysql + metricsets: ["status"] + hosts: ["tcp(ro-db:3306)/"] + username: root + password: "YjkzMDkxMzJhNGJiNzA0YjFiZTI5MzYw" + period: 30s + enabled: true +- module: kafka + metricsets: ["consumergroup", "partition"] + period: 30s + hosts: ["kafka:9092"] + enabled: true +- module: system + enabled: true + period: 30s + metricsets: + - cpu # CPU usage + - load # CPU load averages + - memory # Memory usage + - network # Network IO + - process # Per process metrics + - process_summary # Process summary + - uptime # System Uptime + #- core # Per CPU core usage + - diskio # Disk IO + - filesystem # File system usage for each mountpoint + - fsstat # File system summary metrics + #- raid # Raid + #- socket # Sockets and connection info (linux only) + processes: ['.*'] + cpu.metrics: ["percentages"] # The other available options are normalized_percentages and ticks. + core.metrics: ["percentages"] # The other available option is ticks. + +setup.dashboards.enabled: false + +setup.kibana.host: "kibana" +setup.kibana.protocol: "http" +setup.kibana.username: "" +setup.kibana.password: "" + +fields: + env: dev + +output.elasticsearch: + hosts: ["elasticsearch:9200"] + +logging.level: debug +logging.to_files: true +logging.files: + path: /var/log/metricbeat + name: metricbeat + keepfiles: 7 + permissions: 0644 diff --git a/installers/docker/osm_metrics/docker-compose.yml b/installers/docker/osm_metrics/docker-compose.yml index fb0e8354..98fd5650 100644 --- a/installers/docker/osm_metrics/docker-compose.yml +++ b/installers/docker/osm_metrics/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' networks: netOSM: external: - name: ${OSM_NETWORK:-netOSM} + name: ${OSM_NETWORK:-netosm} services: grafana: image: grafana/grafana diff --git a/installers/docker/osm_metrics/osm-sample-dashboard.json b/installers/docker/osm_metrics/osm-sample-dashboard.json index a640c504..cb9ca068 100644 --- a/installers/docker/osm_metrics/osm-sample-dashboard.json +++ b/installers/docker/osm_metrics/osm-sample-dashboard.json @@ -1,34 +1,4 @@ { - "__inputs": [ - { - "name": "osm_prometheus", - "label": "osm_prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "5.0.4" - }, - { - "type": "panel", - "id": "graph", - "name": "Graph", - "version": "5.0.0" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "5.0.0" - } - ], "annotations": { "list": [ { @@ -45,7 +15,6 @@ "editable": true, "gnetId": null, "graphTooltip": 0, - "id": null, "links": [], "panels": [ { @@ -56,8 +25,8 @@ "datasource": "osm_prometheus", "fill": 1, "gridPos": { - "h": 9, - "w": 24, + "h": 8, + "w": 12, "x": 0, "y": 0 }, @@ -89,14 +58,14 @@ "format": "time_series", "interval": "", "intervalFactor": 1, - "legendFormat": "{{vdu_name}}", + "legendFormat": "NS {{ns_id}} - VNF {{vnf_member_index}} - VDU {{vdu_name}}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, - "title": "VDU CPU Metrics", + "title": "VDU CPU Metric (VIM)", "tooltip": { "shared": true, "sort": 0, @@ -127,7 +96,11 @@ "min": null, "show": true } - ] + ], + "yaxis": { + "align": false, + "alignLevel": null + } }, { "aliasColors": {}, @@ -137,10 +110,95 @@ "datasource": "osm_prometheus", "fill": 1, "gridPos": { - "h": 10, - "w": 24, + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "average_memory_utilization", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "NS {{ns_id}} - VNF {{vnf_member_index}} - VDU {{vdu_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "VDU Memory Metric (VIM)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "osm_prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, "x": 0, - "y": 9 + "y": 8 }, "id": 3, "legend": { @@ -166,18 +224,103 @@ "steppedLine": false, "targets": [ { - "expr": "average_memory_utilization", + "expr": "load", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "NS {{ns_id}} - VNF {{vnf_member_index}} - VDU {{vdu_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "VDU Load Metric (VCA)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "osm_prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "users", "format": "time_series", "interval": "", "intervalFactor": 1, - "legendFormat": "{{vdu_name}}", + "legendFormat": "NS {{ns_id}} - VNF {{vnf_member_index}} - VDU {{vdu_name}}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, - "title": "VDU Memory Metrics", + "title": "VNF Users Metric (VCA)", "tooltip": { "shared": true, "sort": 0, @@ -208,9 +351,14 @@ "min": null, "show": true } - ] + ], + "yaxis": { + "align": false, + "alignLevel": null + } } ], + "refresh": "5s", "schemaVersion": 16, "style": "dark", "tags": [], @@ -218,7 +366,7 @@ "list": [] }, "time": { - "from": "now-6h", + "from": "now-1m", "to": "now" }, "timepicker": { @@ -250,4 +398,4 @@ "title": "OSM Sample Dashboard", "uid": "x5vtPXmik", "version": 1 -} +} \ No newline at end of file diff --git a/installers/full_install_osm.sh b/installers/full_install_osm.sh index 5c6e2531..ddff44af 100755 --- a/installers/full_install_osm.sh +++ b/installers/full_install_osm.sh @@ -660,22 +660,34 @@ function generate_docker_images() { sg docker -c "docker pull prom/prometheus:${PROMETHEUS_TAG}" || FATAL "cannot get prometheus docker image" fi + if [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q KEYSTONE-DB ; then + sg docker -c "docker pull mariadb:${KEYSTONEDB_TAG}" || FATAL "cannot get keystone-db docker image" + fi + if [ -n "$PULL_IMAGES" ]; then sg docker -c "docker pull ${DOCKER_USER}/mon:${OSM_DOCKER_TAG}" || FATAL "cannot pull MON docker image" - sg docker -c "docker pull ${DOCKER_USER}/pol:${OSM_DOCKER_TAG}" || FATAL "cannot pull POL docker image" elif [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q MON ; then git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/MON git -C ${LWTEMPDIR}/MON checkout ${COMMIT_ID} sg docker -c "docker build ${LWTEMPDIR}/MON -f ${LWTEMPDIR}/MON/docker/Dockerfile -t osm/mon --no-cache" || FATAL "cannot build MON docker image" - sg docker -c "docker build ${LWTEMPDIR}/MON/policy_module -f ${LWTEMPDIR}/MON/policy_module/Dockerfile -t osm/pm --no-cache" || FATAL "cannot build PM docker image" + fi + + if [ -n "$PULL_IMAGES" ]; then + sg docker -c "docker pull ${DOCKER_USER}/pol:${OSM_DOCKER_TAG}" || FATAL "cannot pull POL docker image" + elif [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q MON ; then + git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/POL + git -C ${LWTEMPDIR}/POL checkout ${COMMIT_ID} + sg docker -c "docker build ${LWTEMPDIR}/POL -f ${LWTEMPDIR}/POL/docker/Dockerfile -t osm/pol --no-cache" || FATAL "cannot build PM docker image" fi if [ -n "$PULL_IMAGES" ]; then sg docker -c "docker pull ${DOCKER_USER}/nbi:${OSM_DOCKER_TAG}" || FATAL "cannot pull NBI docker image" + sg docker -c "docker pull ${DOCKER_USER}/keystone:${OSM_DOCKER_TAG}" || FATAL "cannot pull KEYSTONE docker image" elif [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q NBI ; then git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/NBI git -C ${LWTEMPDIR}/NBI checkout ${COMMIT_ID} sg docker -c "docker build ${LWTEMPDIR}/NBI -f ${LWTEMPDIR}/NBI/Dockerfile.local -t osm/nbi --no-cache" || FATAL "cannot build NBI docker image" + sg docker -c "docker build ${LWTEMPDIR}/NBI/keystone -f ${LWTEMPDIR}/NBI/keystone/Dockerfile -t osm/keystone --no-cache" || FATAL "cannot build KEYSTONE docker image" fi if [ -n "$PULL_IMAGES" ]; then @@ -700,7 +712,7 @@ function generate_docker_images() { elif [ -z "$TO_REBUILD" ] || echo $TO_REBUILD | grep -q LW-UI ; then git -C ${LWTEMPDIR} clone https://osm.etsi.org/gerrit/osm/LW-UI git -C ${LWTEMPDIR}/LW-UI checkout ${COMMIT_ID} - sg docker -c "docker build ${LWTEMPDIR}/LW-UI -t osm/light-ui -f ${LWTEMPDIR}/LW-UI/Dockerfile --no-cache" || FATAL "cannot build LW-UI docker image" + sg docker -c "docker build ${LWTEMPDIR}/LW-UI -t osm/light-ui -f ${LWTEMPDIR}/LW-UI/docker/Dockerfile --no-cache" || FATAL "cannot build LW-UI docker image" fi if [ -n "$PULL_IMAGES" ]; then @@ -732,8 +744,8 @@ function generate_config_log_folders() { function generate_docker_env_files() { echo "Generating docker env files" - echo "OSMLCM_VCA_HOST=${OSMLCM_VCA_HOST}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/lcm.env - echo "OSMLCM_VCA_SECRET=${OSMLCM_VCA_SECRET}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env + echo "OSMLCM_VCA_HOST=${OSM_VCA_HOST}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/lcm.env + echo "OSMLCM_VCA_SECRET=${OSM_VCA_SECRET}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/lcm.env MYSQL_ROOT_PASSWORD=`date +%s | sha256sum | base64 | head -c 32` if [ ! -f $OSM_DOCKER_WORK_DIR/ro-db.env ]; then @@ -762,12 +774,14 @@ function generate_docker_env_files() { fi echo "OS_NOTIFIER_URI=http://${DEFAULT_IP}:8662" |$WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/mon.env + echo "OSMMON_VCA_HOST=${OSM_VCA_HOST}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/mon.env + echo "OSMMON_VCA_SECRET=${OSM_VCA_SECRET}" | $WORKDIR_SUDO tee -a $OSM_DOCKER_WORK_DIR/mon.env echo "Finished generation of docker env files" } function generate_osmclient_script () { - echo "docker run -ti --network net${OSM_STACK_NAME} osm/osmclient:${OSM_DOCKER_TAG}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/osm + echo "docker run -ti --network net${OSM_STACK_NAME} ${DOCKER_USER}/osmclient:${OSM_DOCKER_TAG}" | $WORKDIR_SUDO tee $OSM_DOCKER_WORK_DIR/osm $WORKDIR_SUDO chmod +x "$OSM_DOCKER_WORK_DIR/osm" echo "osmclient sidecar container can be found at: $OSM_DOCKER_WORK_DIR/osm" } @@ -826,6 +840,7 @@ function deploy_lightweight() { echo "export DOCKER_USER=${DOCKER_USER}" | $WORKDIR_SUDO tee --append $OSM_DOCKER_WORK_DIR/osm_ports.sh echo "export KAFKA_TAG=${KAFKA_TAG}" | $WORKDIR_SUDO tee --append $OSM_DOCKER_WORK_DIR/osm_ports.sh echo "export PROMETHEUS_TAG=${PROMETHEUS_TAG}" | $WORKDIR_SUDO tee --append $OSM_DOCKER_WORK_DIR/osm_ports.sh + echo "export KEYSTONEDB_TAG=${KEYSTONEDB_TAG}" | $WORKDIR_SUDO tee --append $OSM_DOCKER_WORK_DIR/osm_ports.sh @@ -885,18 +900,14 @@ function deploy_elk() { } function deploy_perfmon() { - echo "Pulling docker images for PM (Grafana and Prometheus)" - sg docker -c "docker pull prom/prometheus" || FATAL "cannot get prometheus docker image" + echo "Pulling docker images for PM (Grafana)" sg docker -c "docker pull grafana/grafana" || FATAL "cannot get grafana docker image" echo "Finished pulling PM docker images" - echo "Generating osm/kafka-exporter docker image" - sg docker -c "docker build ${OSM_DEVOPS}/installers/docker/osm_metrics/kafka-exporter -f ${OSM_DEVOPS}/installers/docker/osm_metrics/kafka-exporter/Dockerfile -t osm/kafka-exporter --no-cache" || FATAL "cannot build kafka-exporter docker image" - echo "Finished generation of osm/kafka-exporter docker image" $WORKDIR_SUDO mkdir -p $OSM_DOCKER_WORK_DIR/osm_metrics $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.yml $OSM_DOCKER_WORK_DIR/osm_metrics $WORKDIR_SUDO cp -b ${OSM_DEVOPS}/installers/docker/osm_metrics/*.json $OSM_DOCKER_WORK_DIR/osm_metrics remove_stack osm_metrics - echo "Deploying PM stack (Kafka exporter + Prometheus + Grafana)" + echo "Deploying PM stack (Grafana)" sg docker -c "OSM_NETWORK=net${OSM_STACK_NAME} docker stack deploy -c $OSM_DOCKER_WORK_DIR/osm_metrics/docker-compose.yml osm_metrics" echo "Finished deployment of PM stack" return 0 @@ -919,7 +930,7 @@ function install_lightweight() { DEFAULT_MTU=$(ip addr show ${DEFAULT_IF} | perl -ne 'if (/mtu\s(\d+)/) {print $1;}') # if no host is passed in, we need to install lxd/juju, unless explicilty asked not to - if [ -z "$OSMLCM_VCA_HOST" ] && [ -z "$INSTALL_NOLXD" ]; then + if [ -z "$OSM_VCA_HOST" ] && [ -z "$INSTALL_NOLXD" ]; then need_packages_lw="lxd snapd" echo -e "Checking required packages: $need_packages_lw" dpkg -l $need_packages_lw &>/dev/null \ @@ -934,14 +945,14 @@ function install_lightweight() { track prereqok [ -z "$INSTALL_NOJUJU" ] && install_juju - if [ -z "$OSMLCM_VCA_HOST" ]; then + if [ -z "$OSM_VCA_HOST" ]; then juju_createcontroller - OSMLCM_VCA_HOST=`sg lxd -c "juju show-controller $OSM_STACK_NAME"|grep api-endpoints|awk -F\' '{print $2}'|awk -F\: '{print $1}'` - [ -z "$OSMLCM_VCA_HOST" ] && FATAL "Cannot obtain juju controller IP address" + OSM_VCA_HOST=`sg lxd -c "juju show-controller $OSM_STACK_NAME"|grep api-endpoints|awk -F\' '{print $2}'|awk -F\: '{print $1}'` + [ -z "$OSM_VCA_HOST" ] && FATAL "Cannot obtain juju controller IP address" fi - if [ -z "$OSMLCM_VCA_SECRET" ]; then - OSMLCM_VCA_SECRET=$(parse_juju_password $OSM_STACK_NAME) - [ -z "$OSMLCM_VCA_SECRET" ] && FATAL "Cannot obtain juju secret" + if [ -z "$OSM_VCA_SECRET" ]; then + OSM_VCA_SECRET=$(parse_juju_password $OSM_STACK_NAME) + [ -z "$OSM_VCA_SECRET" ] && FATAL "Cannot obtain juju secret" fi track juju @@ -1073,8 +1084,8 @@ NOCONFIGURE="" RELEASE_DAILY="" SESSION_ID=`date +%s` OSM_DEVOPS= -OSMLCM_VCA_HOST= -OSMLCM_VCA_SECRET= +OSM_VCA_HOST= +OSM_VCA_SECRET= OSM_STACK_NAME=osm NO_HOST_PORTS="" DOCKER_NOBUILD="" @@ -1086,6 +1097,7 @@ OSM_DOCKER_TAG=latest DOCKER_USER=osm KAFKA_TAG=2.11-1.0.2 PROMETHEUS_TAG=v2.4.3 +KEYSTONEDB_TAG=10 while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:H:S:s:w:t:" o; do case "${o}" in @@ -1124,10 +1136,10 @@ while getopts ":hy-:b:r:k:u:R:l:p:D:o:m:H:S:s:w:t:" o; do OSM_STACK_NAME="${OPTARG}" ;; H) - OSMLCM_VCA_HOST="${OPTARG}" + OSM_VCA_HOST="${OPTARG}" ;; S) - OSMLCM_VCA_SECRET="${OPTARG}" + OSM_VCA_SECRET="${OPTARG}" ;; w) # when specifying workdir, do not use sudo for access diff --git a/installers/install_osm.sh b/installers/install_osm.sh index 2ab11d6d..899adb17 100755 --- a/installers/install_osm.sh +++ b/installers/install_osm.sh @@ -13,12 +13,12 @@ add_repo() { dpkg -l $need_packages_lw &>/dev/null \ || ! echo -e "One or several required packages are not installed. Updating apt cache requires root privileges." \ || sudo apt-get -q update \ - || ! echo "failed to run apt-get update" + || ! echo "failed to run apt-get update" \ || exit 1 dpkg -l $need_packages_lw &>/dev/null \ || ! echo -e "Installing $need_packages_lw requires root privileges." \ || sudo apt-get install -y $need_packages_lw \ - || ! echo "failed to install $need_packages_lw" + || ! echo "failed to install $need_packages_lw" \ || exit 1 wget -qO - $REPOSITORY_BASE/$RELEASE/OSM%20ETSI%20Release%20Key.gpg | sudo apt-key add - sudo DEBIAN_FRONTEND=noninteractive add-apt-repository -y "$1" && sudo DEBIAN_FRONTEND=noninteractive apt-get update diff --git a/installers/osm_health.sh b/installers/osm_health.sh index 4625dc80..2684af73 100755 --- a/installers/osm_health.sh +++ b/installers/osm_health.sh @@ -1,8 +1,9 @@ #!/bin/sh -WAIT_TIME=60 -NUM_SERVICES_WITH_HEALTH=3 -SERVICES_WITH_HEALTH="nbi ro kafka" +WAIT_TIME=180 # LCM healthcheck needs 140 senconds +SERVICES_WITH_HEALTH="nbi ro zookeeper lcm" +NUM_SERVICES_WITH_HEALTH=$(echo $SERVICES_WITH_HEALTH | wc -w) +WAIT_FINAL=30 while getopts "w:s:n:c:" o; do case "${o}" in @@ -23,9 +24,12 @@ done time=0 -step=1 +step=2 while [ $time -le "$WAIT_TIME" ]; do if [ "$(docker ps | grep " ${STACK_NAME}_" | grep -i healthy | wc -l)" -ge "$NUM_SERVICES_WITH_HEALTH" ]; then + # all dockers are healthy now. + # final sleep is needed until more health checks are added to validate system is ready to handle requests + sleep $WAIT_FINAL exit 0 fi diff --git a/jenkins/ci-pipelines/ci_stage_3.groovy b/jenkins/ci-pipelines/ci_stage_3.groovy index 1e9eb5a4..6d0d00e0 100644 --- a/jenkins/ci-pipelines/ci_stage_3.groovy +++ b/jenkins/ci-pipelines/ci_stage_3.groovy @@ -35,12 +35,13 @@ properties([ booleanParam(defaultValue: false, description: '', name: 'SAVE_CONTAINER_ON_FAIL'), booleanParam(defaultValue: false, description: '', name: 'SAVE_CONTAINER_ON_PASS'), booleanParam(defaultValue: true, description: '', name: 'SAVE_ARTIFACTS_ON_SMOKE_SUCCESS'), - booleanParam(defaultValue: false, description: '', name: 'DO_STAGE_4'), + booleanParam(defaultValue: true, description: '', name: 'DO_STAGE_4'), booleanParam(defaultValue: true, description: '', name: 'DO_BUILD'), booleanParam(defaultValue: true, description: '', name: 'DO_INSTALL'), booleanParam(defaultValue: true, description: '', name: 'DO_SMOKE'), booleanParam(defaultValue: true, description: '', name: 'DO_DOCKERPUSH'), booleanParam(defaultValue: false, description: '', name: 'SAVE_ARTIFACTS_OVERRIDE'), + string(defaultValue: '/home/jenkins/hive/openstack-whitestack.rc', description: '', name: 'HIVE_VIM_1'), ]) ]) @@ -52,9 +53,14 @@ def uninstall_osm(stackName) { """ } -def run_systest(stackName,tagName,testName) { +def run_systest(stackName,tagName,testName,envfile=null) { tempdir = sh(returnStdout: true, script: "mktemp -d").trim() - sh "docker run --network net${stackName} -v ${tempdir}:/usr/share/osm-devops/systest/reports osm/osmclient:${tagName} make -C /usr/share/osm-devops/systest ${testName}" + if ( !envfile ) + { + sh(script: "touch ${tempdir}/env") + envfile="${tempdir}/env" + } + sh "docker run --network net${stackName} --env-file ${envfile} -v ${tempdir}:/usr/share/osm-devops/systest/reports osm/osmclient:${tagName} make -C /usr/share/osm-devops/systest ${testName}" sh "cp ${tempdir}/* ." junit '*.xml' } @@ -250,16 +256,13 @@ node("${params.NODE}") { } if ( params.DO_STAGE_4 ) { + // override stage_archive to only archive on stable + stage_archive = false stage("stage_4") { - def downstream_params = [ - string(name: 'CONTAINER_NAME', value: container_name), - string(name: 'NODE', value: NODE_NAME.split()[0]), - ] - stage_4_result = build job: "${params.DOWNSTREAM_STAGE_NAME}/${GERRIT_BRANCH}", parameters: downstream_params, propagate: false - currentBuild.result = stage_4_result.result - - if ( stage_4_result.getResult().equals('SUCCESS') ) { - stage_archive = true; + run_systest(container_name,container_name,"openstack_stage_4",params.HIVE_VIM_1) + + if ( ! currentBuild.result.equals('UNSTABLE') ) { + stage_archive = keep_artifacts } } } diff --git a/juju-charms/Makefile b/juju-charms/Makefile index 690904ef..ad8af987 100644 --- a/juju-charms/Makefile +++ b/juju-charms/Makefile @@ -17,7 +17,7 @@ BUILD_DIR = . -CHARMS:= pingpong vyos-proxy netutils simple +CHARMS:= pingpong vyos-proxy netutils simple ansible-charm CHARM_SRC_DIR := layers CHARM_BUILD_DIR := $(BUILD_DIR)/builds diff --git a/juju-charms/layers/ansible-charm/LICENSE b/juju-charms/layers/ansible-charm/LICENSE new file mode 100644 index 00000000..830e5599 --- /dev/null +++ b/juju-charms/layers/ansible-charm/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Borja Nogales , Iván Vidal + + 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/juju-charms/layers/ansible-charm/README.md b/juju-charms/layers/ansible-charm/README.md new file mode 100755 index 00000000..05291377 --- /dev/null +++ b/juju-charms/layers/ansible-charm/README.md @@ -0,0 +1,23 @@ +# Overview +This base charm layer provides a template to create a *proxy charm*, which enables to configure a Virtual Network Function (VNF) instantiated trough Open Source MANO (OSM) using an Ansible playbook. The files included in this charm layer are free to use under the terms provided by the license information specified below. + + +# Usage +The base charm layer includes the following base layers: [vnfproxy](https://github.com/AdamIsrael/vnfproxy) and [ansible-base](https://github.com/chuckbutler/ansible-base). It provides a template ready for customization, which enables to create a *proxy charm* that supports the execution of an Ansible playbook to configure a VNF. For more information on *proxy charms*, the reader is referred to the [OSM wiki](https://osm.etsi.org/wikipub/index.php/Creating_your_own_VNF_charm_(Release_TWO)). + +Step by step instructions to use the base charm layer: + +1. Include the playbook under the *playbook* folder of the base charm layer; name it as *playbook.yaml*. Alternatively, you can open the file *playbook.yaml* alreay existing in this directory and paste the playbook in this file. + +2. The base charm layer already implements a Juju action, _**ansible-playbook**_, which runs the playbook *playbook/playbook.yaml*. You can optionally define additional actions, if needed by your VNF. + +3. Build the charm, via the *charm build* command. + +4. Update the VNF descriptor (VNFD) to use the charm: a) specify the name of the Juju charm in in the VNF configuration; b) Include the action “ansible-playbook” with no arguments as a service primitive and as an initial configuration primitive. + +5. Include the compiled charm in the VNF package. + +More comprehensive and complementary information on building *Proxy charms* can be found in the [OSM wiki](https://osm.etsi.org/wikipub/index.php/Creating_your_own_VNF_charm_(Release_TWO)) and in the documentation of the [vnfproxy layer](https://github.com/AdamIsrael/vnfproxy). + +# Upstream Project Name +This work has been supported by the European H2020 5GinFIRE project (grant agreement 732497). diff --git a/juju-charms/layers/ansible-charm/actions.yaml b/juju-charms/layers/ansible-charm/actions.yaml new file mode 100755 index 00000000..37ef9453 --- /dev/null +++ b/juju-charms/layers/ansible-charm/actions.yaml @@ -0,0 +1,20 @@ +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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. +# + +ansible-playbook: + description: "Configure needed ansible files and run the playbook" diff --git a/juju-charms/layers/ansible-charm/actions/ansible-playbook b/juju-charms/layers/ansible-charm/actions/ansible-playbook new file mode 100755 index 00000000..6133ca59 --- /dev/null +++ b/juju-charms/layers/ansible-charm/actions/ansible-playbook @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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 +sys.path.append('lib') + +from charms.reactive import main +from charms.reactive import set_state +from charmhelpers.core.hookenv import action_fail, action_name + +""" +`set_state` only works here because it's flushed to disk inside the `main()` +loop. remove_state will need to be called inside the action method. +""" +set_state('actions.{}'.format(action_name())) + +try: + main() +except Exception as e: + action_fail(repr(e)) diff --git a/juju-charms/layers/ansible-charm/icon.svg b/juju-charms/layers/ansible-charm/icon.svg new file mode 100755 index 00000000..e092eef7 --- /dev/null +++ b/juju-charms/layers/ansible-charm/icon.svg @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/juju-charms/layers/ansible-charm/layer.yaml b/juju-charms/layers/ansible-charm/layer.yaml new file mode 100755 index 00000000..6a0704c6 --- /dev/null +++ b/juju-charms/layers/ansible-charm/layer.yaml @@ -0,0 +1,19 @@ +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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. +# + +includes: ['layer:ansible-base', 'layer:vnfproxy'] diff --git a/juju-charms/layers/ansible-charm/metadata.yaml b/juju-charms/layers/ansible-charm/metadata.yaml new file mode 100755 index 00000000..acce785f --- /dev/null +++ b/juju-charms/layers/ansible-charm/metadata.yaml @@ -0,0 +1,30 @@ +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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. +# + +name: ansible-charm +summary: Base charm layer to configure a VNF using ansible. +maintainer: borja +description: | + Base charm layer to configure a VNF using ansible, through the Juju framework of Open Source MANO (OSM). +series: + - trusty + - xenial +tags: + - osm + - vnf +subordinate: false diff --git a/juju-charms/layers/ansible-charm/playbook/playbook.yaml b/juju-charms/layers/ansible-charm/playbook/playbook.yaml new file mode 100755 index 00000000..2c7b54bf --- /dev/null +++ b/juju-charms/layers/ansible-charm/playbook/playbook.yaml @@ -0,0 +1,24 @@ +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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. +# +# Place here the ansible playbook to be run + +--- +- hosts: test + tasks: + - name: Create file + file: path=/tmp/playbook_created_file state=touch diff --git a/juju-charms/layers/ansible-charm/reactive/ansible_charm.py b/juju-charms/layers/ansible-charm/reactive/ansible_charm.py new file mode 100755 index 00000000..a129df35 --- /dev/null +++ b/juju-charms/layers/ansible-charm/reactive/ansible_charm.py @@ -0,0 +1,91 @@ +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# Copyright 2018 Altran +# +# 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 charmhelpers.core.hookenv import ( + action_get, + action_fail, + action_set, + config, + status_set, +) + +from charms.reactive import ( + remove_state as remove_flag, + set_state as set_flag, + when, +) +import charms.sshproxy + +from subprocess import ( + Popen, + CalledProcessError, + PIPE, +) + +#from charms.ansible import apply_playbook +import os, fnmatch +import subprocess + +cfg = config() + + +# Sets the status of the charm to show in OSM: configured +@when('config.changed') +def config_changed(): + set_flag('ansible-charm.configured') + status_set('active', 'ready!') + return + + +# Edits ansible config files and executes ansible-playbook +@when('ansible-charm.configured') +@when('actions.ansible-playbook') +def ansible_playbook(): + try: + # Retrieve the ssh parameter + cfg = config() + # edit ansible hosts file with the VNF parameters + h = open("/etc/ansible/hosts", "wt") + h.write("[test]\n") + h1 = "{} ansible_connection=ssh ansible_ssh_user={} ansible_ssh_pass={} ansible_python_interpreter=/usr/bin/python3\n".format(cfg['ssh-hostname'],cfg['ssh-username'],cfg['ssh-password']) + h.write(h1) + h.close() + # edit ansible config to enable ssh connection with th VNF + c = open("/etc/ansible/ansible.cfg", "wt") + c.write("[defaults]\n") + c.write("host_key_checking = False\n") + c.close() + # execute the ansible playbook + path = find('playbook.yaml','/var/lib/juju/agents/') + call = ['ansible-playbook', path] + subprocess.check_call(call) + except Exception as e: + action_fail('command failed: {}, errors: {}'.format(e, e.output)) + remove_flag('actions.ansible-playbook') + return + finally: + remove_flag('actions.ansible-playbook') + + +# Function to find the playbook path +def find(pattern, path): + result = '' + for root, dirs, files in os.walk(path): + for name in files: + if fnmatch.fnmatch(name, pattern): + result = os.path.join(root, name) + return result diff --git a/juju-charms/layers/ansible-charm/tests/00-setup b/juju-charms/layers/ansible-charm/tests/00-setup new file mode 100755 index 00000000..5088c722 --- /dev/null +++ b/juju-charms/layers/ansible-charm/tests/00-setup @@ -0,0 +1,22 @@ +#!/bin/bash +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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. +# + +sudo add-apt-repository ppa:juju/stable -y +sudo apt-get update +sudo apt-get install amulet python-requests -y diff --git a/juju-charms/layers/ansible-charm/tests/10-deploy b/juju-charms/layers/ansible-charm/tests/10-deploy new file mode 100755 index 00000000..8f3fb362 --- /dev/null +++ b/juju-charms/layers/ansible-charm/tests/10-deploy @@ -0,0 +1,52 @@ +#!/usr/bin/python3 +# +# OSM devops/juju-charms - Ansible charm inside OSM devops +# +# Copyright 2017-2018 Universidad Carlos III de Madrid +# +# 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 amulet +import requests +import unittest + + +class TestCharm(unittest.TestCase): + def setUp(self): + self.d = amulet.Deployment() + + self.d.add('ansible-charm') + self.d.expose('ansible-charm') + + self.d.setup(timeout=900) + self.d.sentry.wait() + + self.unit = self.d.sentry['ansible-charm'][0] + + def test_service(self): + # test we can access over http + page = requests.get('http://{}'.format(self.unit.info['public-address'])) + self.assertEqual(page.status_code, 200) + # Now you can use self.d.sentry[SERVICE][UNIT] to address each of the units and perform + # more in-depth steps. Each self.d.sentry[SERVICE][UNIT] has the following methods: + # - .info - An array of the information of that unit from Juju + # - .file(PATH) - Get the details of a file on that unit + # - .file_contents(PATH) - Get plain text output of PATH file from that unit + # - .directory(PATH) - Get details of directory + # - .directory_contents(PATH) - List files and folders in PATH on that unit + # - .relation(relation, service:rel) - Get relation data from return service + + +if __name__ == '__main__': + unittest.main() diff --git a/juju-charms/layers/simple/metadata.yaml b/juju-charms/layers/simple/metadata.yaml index 11051053..fd80d1a7 100644 --- a/juju-charms/layers/simple/metadata.yaml +++ b/juju-charms/layers/simple/metadata.yaml @@ -1,5 +1,5 @@ name: simple -summary: A simple VNF proxy charm +summary: A simple VNF proxy charm maintainer: Adam Israel subordinate: false series: ['xenial'] diff --git a/juju-charms/layers/simple/reactive/simple.py b/juju-charms/layers/simple/reactive/simple.py index 8355bf30..228be3c3 100644 --- a/juju-charms/layers/simple/reactive/simple.py +++ b/juju-charms/layers/simple/reactive/simple.py @@ -39,6 +39,6 @@ def touch(): except: action_fail('command failed:' + err) else: - action_set({'outout': result}) + action_set({'output': result}) finally: clear_flag('actions.touch') diff --git a/systest/Makefile b/systest/Makefile index b2a66ec9..75ab5563 100644 --- a/systest/Makefile +++ b/systest/Makefile @@ -38,6 +38,7 @@ VIM_EMU ?= TOPDIR=$(shell readlink -f .|sed -e 's/systest.*//') + ifdef OS_AUTH_URL OPTION_OS_AUTH_URL=--os-url $(OS_AUTH_URL) endif @@ -250,4 +251,8 @@ ping_pong: check_OSM_HOSTNAME check_openstack_env \ JUNITXML=pytest-$@.xml \ PYTEST_OPTIONS="$(PYTEST_OPTIONS) -m vnf" _run_test -.PHONY: report_dir cirros vim smoke ping_pong +stage_4_tests = cirros + +openstack_stage_4: $(stage_4_tests) + +.PHONY: report_dir cirros vim smoke ping_pong openstack_stage_4 stage_4_tests diff --git a/systest/testcases/vnfs/test_vnfs.py b/systest/testcases/vnfs/test_vnfs.py index 79d9ae2a..b84da44c 100644 --- a/systest/testcases/vnfs/test_vnfs.py +++ b/systest/testcases/vnfs/test_vnfs.py @@ -18,7 +18,7 @@ import pytest import pprint import time from osmclient.common import utils - +import pprint class TestClass(object): @@ -34,7 +34,7 @@ class TestClass(object): for file in nsd_file_list: try: desc = osm.get_api().package.get_key_val_from_pkg(file) - ns_name=osm.ns_name_prefix+nsd_desc['name'] + ns_name=osm.ns_name_prefix+desc['name'] osm.get_api().ns.delete(ns_name) except: pass @@ -79,17 +79,27 @@ class TestClass(object): time.sleep(5) def vnf_test(self,osm, openstack, vim, vmware, vnfd_file_list, nsd_file_list, ns_scale=False): + + # FIXME: need sleep after vim creation. Need a way to validate vim is ready to handle requests + time.sleep(20) + for file in nsd_file_list: nsd_desc = osm.get_api().package.get_key_val_from_pkg(file) ns_name=osm.ns_name_prefix+nsd_desc['name'] - assert not osm.get_api().ns.create(nsd_desc['name'],ns_name,vim.vim_name) + assert osm.get_api().ns.create(nsd_desc['name'],ns_name,vim.vim_name) - assert utils.wait_for_value(lambda: osm.get_api().ns.get_field(ns_name,'operational-status'),result='vnf-init-phase') + if not utils.wait_for_value(lambda: osm.get_api().ns.get_field(ns_name,'operational-status'),result='init', wait_time=10): + nsr=osm.get_api().ns.get(ns_name) + pprint.pprint(nsr) + assert Fail, "operational-status != init" # make sure ns is running - assert utils.wait_for_value(lambda: osm.get_api().ns.get_field(ns_name,'operational-status'),result='running',wait_time=300) + if not utils.wait_for_value(lambda: osm.get_api().ns.get_field(ns_name,'operational-status'),result='running',wait_time=240): + nsr=osm.get_api().ns.get(ns_name) + pprint.pprint(nsr) + assert Fail, "operational-status != running" if ns_scale: # for each descriptor, scale it @@ -107,6 +117,12 @@ class TestClass(object): assert not osm.get_api().ns.delete(ns_name) + #wait for the ns to delete + try: + utils.wait_for_value( lambda: osm.get_api().ns.get(nsd_desc['name']), result=False, wait_time=60) + except: + pass + assert not osm.get_api().nsd.delete(nsd_desc['name']) for file in vnfd_file_list: