Merge "Adding persistent volume to POL"
authorlavado <glavado@whitestack.com>
Wed, 7 Nov 2018 19:50:48 +0000 (20:50 +0100)
committerGerrit Code Review <root@osm.etsi.org>
Wed, 7 Nov 2018 19:50:48 +0000 (20:50 +0100)
44 files changed:
descriptor-packages/nsd/hackfest_ansible_ns/Makefile [new file with mode: 0644]
descriptor-packages/nsd/hackfest_ansible_ns/src/ansiblecharm_nsd.yaml [new file with mode: 0644]
descriptor-packages/nsd/hackfest_ansible_ns/src/icons/osm.png [new file with mode: 0644]
descriptor-packages/vnfd/cirros_vnf/src/cirros_vnfd.yaml
descriptor-packages/vnfd/hackfest_ansible_vnf/Makefile [new file with mode: 0644]
descriptor-packages/vnfd/hackfest_ansible_vnf/src/ansiblecharm_vnfd.yaml [new file with mode: 0644]
descriptor-packages/vnfd/hackfest_ansible_vnf/src/cloud_init/cloud-config.txt [new file with mode: 0644]
descriptor-packages/vnfd/hackfest_ansible_vnf/src/icons/osm.png [new file with mode: 0644]
descriptor-packages/vnfd/hackfest_basic_vnf/src/hackfest_basic_vnfd.yaml
docker/Keystone/Dockerfile
docker/LCM/Dockerfile
docker/MON/Dockerfile
docker/MON/scripts/requirements.txt [deleted file]
docker/RO/Dockerfile
docker/light-ui/Dockerfile
docker/mk/Makefile.include
installers/docker/osm_elk/docker-compose.yml
installers/docker/osm_elk/elasticsearch.yml
installers/docker/osm_elk/filebeat.yml [new file with mode: 0644]
installers/docker/osm_elk/logstash.conf [deleted file]
installers/docker/osm_elk/logstash.yml [deleted file]
installers/docker/osm_elk/metricbeat.yml [new file with mode: 0644]
installers/docker/osm_metrics/docker-compose.yml
installers/docker/osm_metrics/osm-sample-dashboard.json
installers/full_install_osm.sh
installers/install_osm.sh
installers/osm_health.sh
jenkins/ci-pipelines/ci_stage_3.groovy
juju-charms/Makefile
juju-charms/layers/ansible-charm/LICENSE [new file with mode: 0644]
juju-charms/layers/ansible-charm/README.md [new file with mode: 0755]
juju-charms/layers/ansible-charm/actions.yaml [new file with mode: 0755]
juju-charms/layers/ansible-charm/actions/ansible-playbook [new file with mode: 0755]
juju-charms/layers/ansible-charm/icon.svg [new file with mode: 0755]
juju-charms/layers/ansible-charm/layer.yaml [new file with mode: 0755]
juju-charms/layers/ansible-charm/metadata.yaml [new file with mode: 0755]
juju-charms/layers/ansible-charm/playbook/playbook.yaml [new file with mode: 0755]
juju-charms/layers/ansible-charm/reactive/ansible_charm.py [new file with mode: 0755]
juju-charms/layers/ansible-charm/tests/00-setup [new file with mode: 0755]
juju-charms/layers/ansible-charm/tests/10-deploy [new file with mode: 0755]
juju-charms/layers/simple/metadata.yaml
juju-charms/layers/simple/reactive/simple.py
systest/Makefile
systest/testcases/vnfs/test_vnfs.py

diff --git a/descriptor-packages/nsd/hackfest_ansible_ns/Makefile b/descriptor-packages/nsd/hackfest_ansible_ns/Makefile
new file mode 100644 (file)
index 0000000..9c18082
--- /dev/null
@@ -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 (file)
index 0000000..031ed4e
--- /dev/null
@@ -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 (file)
index 0000000..62012d2
Binary files /dev/null and b/descriptor-packages/nsd/hackfest_ansible_ns/src/icons/osm.png differ
index 94fa5f1..6d5da86 100644 (file)
@@ -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 (file)
index 0000000..e989331
--- /dev/null
@@ -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 (file)
index 0000000..873d041
--- /dev/null
@@ -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: <rw_mgmt_ip>
+                 -   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 (file)
index 0000000..36c8d1b
--- /dev/null
@@ -0,0 +1,12 @@
+#cloud-config\r
+password: osm4u\r
+chpasswd: { expire: False }\r
+ssh_pwauth: True\r
+\r
+write_files:\r
+-   content: |\r
+        # My new helloworld file\r
+\r
+    owner: root:root\r
+    permissions: '0644'\r
+    path: /root/helloworld.txt\r
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 (file)
index 0000000..62012d2
Binary files /dev/null and b/descriptor-packages/vnfd/hackfest_ansible_vnf/src/icons/osm.png differ
index fa7f1ff..b407a84 100644 (file)
@@ -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
 
index 263716a..2030aa5 100644 (file)
@@ -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
index 46be58e..1a750d3 100644 (file)
@@ -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"]
index 0da9c91..5b9da33 100644 (file)
@@ -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=<IP_ACCESIBLE_FROM_OPENSTACK>: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 (file)
index 28bb719..0000000
+++ /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.*
index 0607d91..8ba46c4 100644 (file)
@@ -3,7 +3,8 @@ from ubuntu:xenial
 MAINTAINER Gennadiy Dubina <gennadiy.dubina@dataat.com>; Alfonso Tierno <alfonso.tiernosepulveda@telefoncia.com>
 
 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
index 5cf9aa7..4440b9a 100644 (file)
@@ -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
index 04d2fac..2be4d29 100644 (file)
@@ -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) .
 
index 9f03c4f..f7dc2aa 100644 (file)
@@ -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}
index ba67874..f6a7dd4 100644 (file)
@@ -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 (file)
index 0000000..6769a9f
--- /dev/null
@@ -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 (file)
index a83a572..0000000
+++ /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 (file)
index 91bcbb1..0000000
+++ /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 (file)
index 0000000..61feaef
--- /dev/null
@@ -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
index fb0e835..98fd565 100644 (file)
@@ -2,7 +2,7 @@ version: '3'
 networks:
   netOSM:
     external:
-       name: ${OSM_NETWORK:-netOSM}
+       name: ${OSM_NETWORK:-netosm}
 services:
   grafana:
     image: grafana/grafana
index a640c50..cb9ca06 100644 (file)
@@ -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
       },
           "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,
           "min": null,
           "show": true
         }
-      ]
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
     },
     {
       "aliasColors": {},
       "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": {
       "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,
           "min": null,
           "show": true
         }
-      ]
+      ],
+      "yaxis": {
+        "align": false,
+        "alignLevel": null
+      }
     }
   ],
+  "refresh": "5s",
   "schemaVersion": 16,
   "style": "dark",
   "tags": [],
     "list": []
   },
   "time": {
-    "from": "now-6h",
+    "from": "now-1m",
     "to": "now"
   },
   "timepicker": {
   "title": "OSM Sample Dashboard",
   "uid": "x5vtPXmik",
   "version": 1
-}
+}
\ No newline at end of file
index 5c6e253..ddff44a 100755 (executable)
@@ -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
index 2ab11d6..899adb1 100755 (executable)
@@ -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
index 4625dc8..2684af7 100755 (executable)
@@ -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
 
index 1e9eb5a..6d0d00e 100644 (file)
@@ -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
                     }
                 }
             }
index 690904e..ad8af98 100644 (file)
@@ -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 (file)
index 0000000..830e559
--- /dev/null
@@ -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 <bdorado@pa.uc3m.es>, Iván Vidal <ividal@it.uc3m.es>
+
+   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 (executable)
index 0000000..0529137
--- /dev/null
@@ -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 (executable)
index 0000000..37ef945
--- /dev/null
@@ -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 (executable)
index 0000000..6133ca5
--- /dev/null
@@ -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 (executable)
index 0000000..e092eef
--- /dev/null
@@ -0,0 +1,279 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r
+\r
+<svg\r
+   xmlns:dc="http://purl.org/dc/elements/1.1/"\r
+   xmlns:cc="http://creativecommons.org/ns#"\r
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+   xmlns:svg="http://www.w3.org/2000/svg"\r
+   xmlns="http://www.w3.org/2000/svg"\r
+   xmlns:xlink="http://www.w3.org/1999/xlink"\r
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"\r
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"\r
+   width="96"\r
+   height="96"\r
+   id="svg6517"\r
+   version="1.1"\r
+   inkscape:version="0.48+devel r12274"\r
+   sodipodi:docname="Juju_charm_icon_template.svg">\r
+  <defs\r
+     id="defs6519">\r
+    <linearGradient\r
+       inkscape:collect="always"\r
+       xlink:href="#Background"\r
+       id="linearGradient6461"\r
+       gradientUnits="userSpaceOnUse"\r
+       x1="0"\r
+       y1="970.29498"\r
+       x2="144"\r
+       y2="970.29498"\r
+       gradientTransform="matrix(0,-0.66666669,0.6660448,0,-866.25992,731.29077)" />\r
+    <linearGradient\r
+       id="Background">\r
+      <stop\r
+         id="stop4178"\r
+         offset="0"\r
+         style="stop-color:#b8b8b8;stop-opacity:1" />\r
+      <stop\r
+         id="stop4180"\r
+         offset="1"\r
+         style="stop-color:#c9c9c9;stop-opacity:1" />\r
+    </linearGradient>\r
+    <filter\r
+       style="color-interpolation-filters:sRGB;"\r
+       inkscape:label="Inner Shadow"\r
+       id="filter1121">\r
+      <feFlood\r
+         flood-opacity="0.59999999999999998"\r
+         flood-color="rgb(0,0,0)"\r
+         result="flood"\r
+         id="feFlood1123" />\r
+      <feComposite\r
+         in="flood"\r
+         in2="SourceGraphic"\r
+         operator="out"\r
+         result="composite1"\r
+         id="feComposite1125" />\r
+      <feGaussianBlur\r
+         in="composite1"\r
+         stdDeviation="1"\r
+         result="blur"\r
+         id="feGaussianBlur1127" />\r
+      <feOffset\r
+         dx="0"\r
+         dy="2"\r
+         result="offset"\r
+         id="feOffset1129" />\r
+      <feComposite\r
+         in="offset"\r
+         in2="SourceGraphic"\r
+         operator="atop"\r
+         result="composite2"\r
+         id="feComposite1131" />\r
+    </filter>\r
+    <filter\r
+       style="color-interpolation-filters:sRGB;"\r
+       inkscape:label="Drop Shadow"\r
+       id="filter950">\r
+      <feFlood\r
+         flood-opacity="0.25"\r
+         flood-color="rgb(0,0,0)"\r
+         result="flood"\r
+         id="feFlood952" />\r
+      <feComposite\r
+         in="flood"\r
+         in2="SourceGraphic"\r
+         operator="in"\r
+         result="composite1"\r
+         id="feComposite954" />\r
+      <feGaussianBlur\r
+         in="composite1"\r
+         stdDeviation="1"\r
+         result="blur"\r
+         id="feGaussianBlur956" />\r
+      <feOffset\r
+         dx="0"\r
+         dy="1"\r
+         result="offset"\r
+         id="feOffset958" />\r
+      <feComposite\r
+         in="SourceGraphic"\r
+         in2="offset"\r
+         operator="over"\r
+         result="composite2"\r
+         id="feComposite960" />\r
+    </filter>\r
+    <clipPath\r
+       clipPathUnits="userSpaceOnUse"\r
+       id="clipPath873">\r
+      <g\r
+         transform="matrix(0,-0.66666667,0.66604479,0,-258.25992,677.00001)"\r
+         id="g875"\r
+         inkscape:label="Layer 1"\r
+         style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline">\r
+        <path\r
+           style="fill:#ff00ff;fill-opacity:1;stroke:none;display:inline"\r
+           d="m 46.702703,898.22775 50.594594,0 C 138.16216,898.22775 144,904.06497 144,944.92583 l 0,50.73846 c 0,40.86071 -5.83784,46.69791 -46.702703,46.69791 l -50.594594,0 C 5.8378378,1042.3622 0,1036.525 0,995.66429 L 0,944.92583 C 0,904.06497 5.8378378,898.22775 46.702703,898.22775 Z"\r
+           id="path877"\r
+           inkscape:connector-curvature="0"\r
+           sodipodi:nodetypes="sssssssss" />\r
+      </g>\r
+    </clipPath>\r
+    <filter\r
+       inkscape:collect="always"\r
+       id="filter891"\r
+       inkscape:label="Badge Shadow">\r
+      <feGaussianBlur\r
+         inkscape:collect="always"\r
+         stdDeviation="0.71999962"\r
+         id="feGaussianBlur893" />\r
+    </filter>\r
+  </defs>\r
+  <sodipodi:namedview\r
+     id="base"\r
+     pagecolor="#ffffff"\r
+     bordercolor="#666666"\r
+     borderopacity="1.0"\r
+     inkscape:pageopacity="0.0"\r
+     inkscape:pageshadow="2"\r
+     inkscape:zoom="4.0745362"\r
+     inkscape:cx="18.514671"\r
+     inkscape:cy="49.018169"\r
+     inkscape:document-units="px"\r
+     inkscape:current-layer="layer1"\r
+     showgrid="true"\r
+     fit-margin-top="0"\r
+     fit-margin-left="0"\r
+     fit-margin-right="0"\r
+     fit-margin-bottom="0"\r
+     inkscape:window-width="1920"\r
+     inkscape:window-height="1029"\r
+     inkscape:window-x="0"\r
+     inkscape:window-y="24"\r
+     inkscape:window-maximized="1"\r
+     showborder="true"\r
+     showguides="true"\r
+     inkscape:guide-bbox="true"\r
+     inkscape:showpageshadow="false">\r
+    <inkscape:grid\r
+       type="xygrid"\r
+       id="grid821" />\r
+    <sodipodi:guide\r
+       orientation="1,0"\r
+       position="16,48"\r
+       id="guide823" />\r
+    <sodipodi:guide\r
+       orientation="0,1"\r
+       position="64,80"\r
+       id="guide825" />\r
+    <sodipodi:guide\r
+       orientation="1,0"\r
+       position="80,40"\r
+       id="guide827" />\r
+    <sodipodi:guide\r
+       orientation="0,1"\r
+       position="64,16"\r
+       id="guide829" />\r
+  </sodipodi:namedview>\r
+  <metadata\r
+     id="metadata6522">\r
+    <rdf:RDF>\r
+      <cc:Work\r
+         rdf:about="">\r
+        <dc:format>image/svg+xml</dc:format>\r
+        <dc:type\r
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />\r
+        <dc:title></dc:title>\r
+      </cc:Work>\r
+    </rdf:RDF>\r
+  </metadata>\r
+  <g\r
+     inkscape:label="BACKGROUND"\r
+     inkscape:groupmode="layer"\r
+     id="layer1"\r
+     transform="translate(268,-635.29076)"\r
+     style="display:inline">\r
+    <path\r
+       style="fill:url(#linearGradient6461);fill-opacity:1;stroke:none;display:inline;filter:url(#filter1121)"\r
+       d="m -268,700.15563 0,-33.72973 c 0,-27.24324 3.88785,-31.13513 31.10302,-31.13513 l 33.79408,0 c 27.21507,0 31.1029,3.89189 31.1029,31.13513 l 0,33.72973 c 0,27.24325 -3.88783,31.13514 -31.1029,31.13514 l -33.79408,0 C -264.11215,731.29077 -268,727.39888 -268,700.15563 Z"\r
+       id="path6455"\r
+       inkscape:connector-curvature="0"\r
+       sodipodi:nodetypes="sssssssss" />\r
+  </g>\r
+  <g\r
+     inkscape:groupmode="layer"\r
+     id="layer3"\r
+     inkscape:label="PLACE YOUR PICTOGRAM HERE"\r
+     style="display:inline" />\r
+  <g\r
+     inkscape:groupmode="layer"\r
+     id="layer2"\r
+     inkscape:label="BADGE"\r
+     style="display:none"\r
+     sodipodi:insensitive="true">\r
+    <g\r
+       style="display:inline"\r
+       transform="translate(-340.00001,-581)"\r
+       id="g4394"\r
+       clip-path="none">\r
+      <g\r
+         id="g855">\r
+        <g\r
+           inkscape:groupmode="maskhelper"\r
+           id="g870"\r
+           clip-path="url(#clipPath873)"\r
+           style="opacity:0.6;filter:url(#filter891)">\r
+          <path\r
+             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-237.54282)"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             sodipodi:ry="12"\r
+             sodipodi:rx="12"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:cx="252"\r
+             id="path844"\r
+             style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             sodipodi:type="arc" />\r
+        </g>\r
+        <g\r
+           id="g862">\r
+          <path\r
+             sodipodi:type="arc"\r
+             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             id="path4398"\r
+             sodipodi:cx="252"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:rx="12"\r
+             sodipodi:ry="12"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             transform="matrix(1.4999992,0,0,1.4999992,-29.999795,-238.54282)" />\r
+          <path\r
+             transform="matrix(1.25,0,0,1.25,33,-100.45273)"\r
+             d="m 264,552.36218 a 12,12 0 1 1 -24,0 A 12,12 0 1 1 264,552.36218 Z"\r
+             sodipodi:ry="12"\r
+             sodipodi:rx="12"\r
+             sodipodi:cy="552.36218"\r
+             sodipodi:cx="252"\r
+             id="path4400"\r
+             style="color:#000000;fill:#dd4814;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             sodipodi:type="arc" />\r
+          <path\r
+             sodipodi:type="star"\r
+             style="color:#000000;fill:#f5f5f5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"\r
+             id="path4459"\r
+             sodipodi:sides="5"\r
+             sodipodi:cx="666.19574"\r
+             sodipodi:cy="589.50385"\r
+             sodipodi:r1="7.2431178"\r
+             sodipodi:r2="4.3458705"\r
+             sodipodi:arg1="1.0471976"\r
+             sodipodi:arg2="1.6755161"\r
+             inkscape:flatsided="false"\r
+             inkscape:rounded="0.1"\r
+             inkscape:randomized="0"\r
+             d="m 669.8173,595.77657 c -0.39132,0.22593 -3.62645,-1.90343 -4.07583,-1.95066 -0.44938,-0.0472 -4.05653,1.36297 -4.39232,1.06062 -0.3358,-0.30235 0.68963,-4.03715 0.59569,-4.47913 -0.0939,-0.44198 -2.5498,-3.43681 -2.36602,-3.8496 0.18379,-0.41279 4.05267,-0.59166 4.44398,-0.81759 0.39132,-0.22593 2.48067,-3.48704 2.93005,-3.4398 0.44938,0.0472 1.81505,3.67147 2.15084,3.97382 0.3358,0.30236 4.08294,1.2817 4.17689,1.72369 0.0939,0.44198 -2.9309,2.86076 -3.11469,3.27355 C 669.9821,591.68426 670.20862,595.55064 669.8173,595.77657 Z"\r
+             transform="matrix(1.511423,-0.16366377,0.16366377,1.511423,-755.37346,-191.93651)" />\r
+        </g>\r
+      </g>\r
+    </g>\r
+  </g>\r
+</svg>\r
diff --git a/juju-charms/layers/ansible-charm/layer.yaml b/juju-charms/layers/ansible-charm/layer.yaml
new file mode 100755 (executable)
index 0000000..6a0704c
--- /dev/null
@@ -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 (executable)
index 0000000..acce785
--- /dev/null
@@ -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 <bdorado@pa.uc3m.es>
+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 (executable)
index 0000000..2c7b54b
--- /dev/null
@@ -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 (executable)
index 0000000..a129df3
--- /dev/null
@@ -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 (executable)
index 0000000..5088c72
--- /dev/null
@@ -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 (executable)
index 0000000..8f3fb36
--- /dev/null
@@ -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()
index 1105105..fd80d1a 100644 (file)
@@ -1,5 +1,5 @@
 name: simple
-summary: A simple VNF proxy charm 
+summary: A simple VNF proxy charm
 maintainer: Adam Israel <adam.israel@canonical.com>
 subordinate: false
 series: ['xenial']
index 8355bf3..228be3c 100644 (file)
@@ -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')
index b2a66ec..75ab556 100644 (file)
@@ -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
index 79d9ae2..b84da44 100644 (file)
@@ -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: