summaryrefslogtreecommitdiffstats
path: root/ci
diff options
context:
space:
mode:
Diffstat (limited to 'ci')
-rw-r--r--ci/bundle_tpl/bundle.yaml47
-rw-r--r--ci/bundle_tpl/ceilometer.yaml17
-rw-r--r--ci/bundle_tpl/ceph.yaml40
-rw-r--r--ci/bundle_tpl/cinder.yaml14
-rw-r--r--ci/bundle_tpl/glance.yaml12
-rw-r--r--ci/bundle_tpl/haclusters.yaml52
-rw-r--r--ci/bundle_tpl/heat.yaml11
-rw-r--r--ci/bundle_tpl/keystone.yaml14
-rw-r--r--ci/bundle_tpl/mysql.yaml16
-rw-r--r--ci/bundle_tpl/neutron-api.yaml16
-rw-r--r--ci/bundle_tpl/neutron-gateway.yaml14
-rw-r--r--ci/bundle_tpl/neutron-ovs.yaml12
-rw-r--r--ci/bundle_tpl/nova-cloud-controller.yaml17
-rw-r--r--ci/bundle_tpl/nova-compute.yaml18
-rw-r--r--ci/bundle_tpl/odl.yaml16
-rw-r--r--ci/bundle_tpl/openstack-dashboard.yaml15
-rw-r--r--ci/bundle_tpl/opnfv-promise.yaml5
-rw-r--r--ci/bundle_tpl/phase2-overrides.yaml23
-rw-r--r--ci/bundle_tpl/rabbitmq.yaml7
-rw-r--r--ci/bundle_tpl/relations.yaml135
-rw-r--r--ci/default_deployment_config.yaml26
-rw-r--r--ci/genBundle.py165
22 files changed, 692 insertions, 0 deletions
diff --git a/ci/bundle_tpl/bundle.yaml b/ci/bundle_tpl/bundle.yaml
new file mode 100644
index 00000000..8f1c5546
--- /dev/null
+++ b/ci/bundle_tpl/bundle.yaml
@@ -0,0 +1,47 @@
+# vim: set ts=2 et:
+{{ ubuntu.release }}-{{ os.release }}-nodes:
+ inherits: openstack-phase1
+
+
+{{ ubuntu.release }}-{{ os.release }}:
+ inherits: openstack-phase2
+ overrides:
+{% include 'phase2-overrides.yaml' %}
+
+
+openstack-phase1:
+ services:
+ nodes:
+ charm: "cs:{{ ubuntu.release }}/ubuntu"
+ num_units: 2
+ ntp:
+ charm: "local:{{ ubuntu.release }}/ntp"
+ relations:
+ - - "ntp:juju-info"
+ - "nodes:juju-info"
+
+
+openstack-phase2:
+ inherits: openstack-phase1
+ relations:
+{% include 'relations.yaml' %}
+ services:
+{% if os.ha.mode == 'ha' %}
+ {% include 'haclusters.yaml' %}
+{% endif %}
+{% include 'mysql.yaml' %}
+{% include 'ceilometer.yaml' %}
+{% include 'ceph.yaml' %}
+{% include 'cinder.yaml' %}
+{% include 'glance.yaml' %}
+{% include 'opnfv-promise.yaml' %}
+{% include 'keystone.yaml' %}
+{% include 'nova-cloud-controller.yaml' %}
+{% include 'nova-compute.yaml' %}
+{% include 'openstack-dashboard.yaml' %}
+{% include 'rabbitmq.yaml' %}
+{% include 'heat.yaml' %}
+{% include 'neutron-api.yaml' %}
+{% include 'neutron-gateway.yaml' %}
+{% if os.network.controller == 'nosdn' %}{% include 'neutron-ovs.yaml' %}
+{% elif os.network.controller == 'odl' %}{% include 'odl.yaml' %}{% endif %}
diff --git a/ci/bundle_tpl/ceilometer.yaml b/ci/bundle_tpl/ceilometer.yaml
new file mode 100644
index 00000000..f76a7c7d
--- /dev/null
+++ b/ci/bundle_tpl/ceilometer.yaml
@@ -0,0 +1,17 @@
+ ceilometer-agent:
+ charm: "local:{{ ubuntu.release }}/ceilometer-agent"
+ mongodb:
+ charm: local:{{ ubuntu.release }}/mongodb
+ to:
+ - "lxc:nodes=0"
+ ceilometer:
+ charm: "local:{{ ubuntu.release }}/ceilometer"
+ num_units: {{ unit_qty() }}
+ options:
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.ceilometer }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/ceph.yaml b/ci/bundle_tpl/ceph.yaml
new file mode 100644
index 00000000..725ac705
--- /dev/null
+++ b/ci/bundle_tpl/ceph.yaml
@@ -0,0 +1,40 @@
+{% if opnfv.storage_dict.ceph is defined %}
+ ceph:
+ charm: "local:{{ ubuntu.release }}/ceph"
+ num_units: {{ unit_qty() }}
+ options:
+ monitor-count: {{ unit_qty() }}
+ fsid: 5a791d94-980b-11e4-b6f6-3c970e8b1cf7
+ monitor-secret: AQAi5a9UeJXUExAA+By9u+GPhl8/XiUQ4nwI3A==
+ osd-reformat: {{ opnfv.storage_dict.ceph.reformat }}
+{% if opnfv.spaces_dict.storage is defined %}
+ ceph-cluster-network: {{ opnfv.spaces_dict.storage.cidr }}
+{% endif %}
+# ceph-public-network: 192.168.0.0/24
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
+ ceph-osd:
+ charm: "local:{{ ubuntu.release }}/ceph-osd"
+ num_units: {{ unit_qty() }}
+ options:
+ osd-devices: {{ opnfv.storage_dict.ceph.disk }}
+ osd-reformat: 'yes'
+ to:
+{% for unit_id in to_select() %}
+ - "nodes={{ unit_id }}"
+{% endfor %}
+ ceph-radosgw:
+ charm: "local:{{ ubuntu.release }}/ceph-radosgw"
+ num_units: {{ unit_qty() if os.beta.hacluster_ceph_radosgw else 1 }}
+ options:
+ use-embedded-webserver: true
+ operator-roles: "Member,admin"
+ to:
+{% for unit_id in to_select(unit_qty() if os.beta.hacluster_ceph_radosgw else 1) %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
+ cinder-ceph:
+ charm: "local:{{ ubuntu.release }}/cinder-ceph"
+{% endif %}
diff --git a/ci/bundle_tpl/cinder.yaml b/ci/bundle_tpl/cinder.yaml
new file mode 100644
index 00000000..6113200a
--- /dev/null
+++ b/ci/bundle_tpl/cinder.yaml
@@ -0,0 +1,14 @@
+ cinder:
+ charm: "local:{{ ubuntu.release }}/cinder"
+ num_units: {{ unit_qty() }}
+ options:
+ block-device: None
+ glance-api-version: 2
+ ha-mcastport: 5401
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.cinder }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/glance.yaml b/ci/bundle_tpl/glance.yaml
new file mode 100644
index 00000000..c571760b
--- /dev/null
+++ b/ci/bundle_tpl/glance.yaml
@@ -0,0 +1,12 @@
+ glance:
+ charm: "local:{{ ubuntu.release }}/glance"
+ num_units: {{ unit_qty() }}
+ options:
+ ha-mcastport: 5402
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.glance }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/haclusters.yaml b/ci/bundle_tpl/haclusters.yaml
new file mode 100644
index 00000000..c21ec545
--- /dev/null
+++ b/ci/bundle_tpl/haclusters.yaml
@@ -0,0 +1,52 @@
+ hacluster-keystone:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'QisjNpoKHLkvyc3PEdDHP5VZjgD0kOk9t0ABPWmCELlu5AgWgnW6bJd34BVXO7VhW+3ZwNQM3W+bZ3pl28ftY4ki4N/S0KLFNia5egFgiA3AH2QXLnokS7OYXuu6GMJJ1S5mDe6P5zU+tfJe/Mebq24u7CgR0gAvohSPRdDTwdY='
+ hacluster-cinder:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'cc6n5Zv6M2mQ2mUhTx/aKoImQ7q77pKDdkSwBUG5VqoSb23SxnGUsAxH5E8lOeCZ84EURzS71FEb8F9P5YY+2deh0+tdXukoKTugdVmJfarahPpWpEEZRRCigUngdFw/479FOcFCkN1SJtQNqWi1ACYSn1/GRoQ2vP+2byrkV6E='
+ hacluster-heat:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'tNeFXmOqzytRq7loxLMDaaMqZZXjC7BNfMbcKxSNeIPyBj4lkJwHZyuV7mo0ogzcfVJqLBHBULai+ed9uyWCZJxLXoi+WwTj5AqcXfxfSo9vLCthukJJ4zuKvzeGibZRszwINf32RW9jtXSCPosv8a+9MSg49KD1c9fS20aEuIM='
+ hacluster-horizon:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'aCVPHw6XYne+Hxv0WPiM3+yEfeIxs0Ly0EMKB494Rdzjf5rE52GcXqqxuvIa/nXJ4GCR+UdKk9FEwcASfYkeu3HDWUld9uTE6pOc+ibWYnybNH7VBfEHW8h9YmQKs3HD2T3wlTcS2irU4CUW7/IKNok4etYdM3iFn1K2ReSGXEI='
+ hacluster-nova:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'gel86qmEze8dYKYbfqIgRpqapJpKtdYL2hxC1y5nWYBPq7EMf6V8mF01IjeUkSRs14CUDrsPpT4PWeom7EOY2fleuLx/aIuqQUfEDkhf/gvaz7BaU4hrmTCoDBK7/HvEwY+/wu4qkEeckzSRPsm9MYzqnLRshh8yjZJ70xU/mmk='
+ hacluster-neutron:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'KNhb4++3jlllbnscS5D3qdzOJDsQPEeZ7zOLZJHbkKrRjX9gRCijVVOiv2JCvq03HqQ7LIufQzWGl9Za8qh0f6QmQ3XhFh/Cb/3WaYFj+tEf0zArWv+8miswmM1z4eyTSrTWBq0dTgx1z96wjBxP5HV0+1LWW+3Ei4oZWyRGeR0='
+ hacluster-glance:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'el1dd8107J5mwQDPS7tEJPZrr0XFfL95+Tku/QG90W5Q5f5SP4W8TRfKvddGmZWZl2lVd1neG5WqaHa1mq/aScJpoflzVAJCvshN7Gd2AjHhLNNugeI8S90j/7wrKUhqiCAlkKaeri2xs5bB5PZ7Z9AHuNZL7SW1al8lxrKhUFI='
+ hacluster-ceilometer:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'cHkgKGJpdHMgPSA5NjApLgpQcmVzcyBrZXlzIG9uIHlvdXIga2V5Ym9hcmQgdG8gZ2VuZXJhdGUgZW50cm9weSAoYml0cyA9IDEwMDgpLgpXcml0aW5nIGNvcm9zeW5jIGtleSB0byAvZXRjL2Nvcm9zeW5jL2F1dGhrZXkuCg=='
+ hacluster-mysql:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'Q29yb3N5bmMgQ2x1c3RlciBFbmdpbmUgQXV0aGVudGljYXRpb24ga2V5IGdlbmVyYXRvci4KR2F0aGVyaW5nIDEwMjQgYml0cyBmb3Iga2V5IGZyb20gL2Rldi9yYW5kb20uClByZXNzIGtleXMgb24geW91ciBrZXlib2FyZCB0byBnZW5lcmF0ZSBlbnRyb3B5LgpQcmVzcyBrZXlzIG9uIHlvdXIga2V5Ym9hcmQgdG8gZ2VuZXJhdGUgZW50cm9weSAoYml0cyA9IDkyMCkuClByZXNzIGtleXMgb24geW91ciBrZXlib2FyZCB0byBnZW5lcmF0ZSBlbnRyb3B5IChiaXRzID0gMTAwMCkuCldyaXRpbmcgY29yb3N5bmMga2V5IHRvIC9ldGMvY29yb3N5bmMvYXV0aGtleS4K'
+{% if os.beta.hacluster_ceph_radosgw %}
+ hacluster-ceph-radosgw:
+ charm: "local:{{ ubuntu.release }}/hacluster"
+ options:
+ corosync_key: |
+ 'tk8U/FkH1+dNsvj6IU0C8AST7i/9ylIoCD8kWpPjB+UE2AYR7tkgkjnc4m5dzIYPYTceY7Hnb9xLJ0nlcQLYYFBRAJOg3drNTcVrfh63y9g9La1J1r51YSbOqXq1Q6RUhxP4OQBtDGE6/4NtZwuRPvPGLcI2ENiVm78l8JFkXRw='
+{% endif %}
diff --git a/ci/bundle_tpl/heat.yaml b/ci/bundle_tpl/heat.yaml
new file mode 100644
index 00000000..ba97fb61
--- /dev/null
+++ b/ci/bundle_tpl/heat.yaml
@@ -0,0 +1,11 @@
+ heat:
+ charm: "local:{{ ubuntu.release }}/heat"
+ num_units: {{ unit_qty() }}
+ options:
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.heat }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/keystone.yaml b/ci/bundle_tpl/keystone.yaml
new file mode 100644
index 00000000..18f5cc63
--- /dev/null
+++ b/ci/bundle_tpl/keystone.yaml
@@ -0,0 +1,14 @@
+ keystone:
+ charm: "local:{{ ubuntu.release }}/keystone"
+ num_units: {{ unit_qty() }}
+ options:
+ admin-password: {{ opnfv.admin_password | default(os.admin.password) }}
+ admin-token: {{ os.admin.name }}
+ ha-mcastport: 5403
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.keystone }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/mysql.yaml b/ci/bundle_tpl/mysql.yaml
new file mode 100644
index 00000000..4835dfe6
--- /dev/null
+++ b/ci/bundle_tpl/mysql.yaml
@@ -0,0 +1,16 @@
+ mysql:
+ charm: "local:{{ ubuntu.release }}/percona-cluster"
+ num_units: {{ unit_qty() }}
+ options:
+ dataset-size: 2G
+ lp1366997-workaround: true
+ max-connections: 10000
+ root-password: {{ get_password('mysql_root') }}
+ sst-password: {{ get_password('mysql_sst') }}
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.mysql }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/neutron-api.yaml b/ci/bundle_tpl/neutron-api.yaml
new file mode 100644
index 00000000..403babcf
--- /dev/null
+++ b/ci/bundle_tpl/neutron-api.yaml
@@ -0,0 +1,16 @@
+ neutron-api:
+ charm: "local:{{ ubuntu.release }}/neutron-api"
+ num_units: {{ unit_qty() }}
+ options:
+ neutron-security-groups: true
+ flat-network-providers: "*"
+{% if os.network.controller == 'odl' %}
+ manage-neutron-plugin-legacy-mode: False
+{% endif %}
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.neutron }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/neutron-gateway.yaml b/ci/bundle_tpl/neutron-gateway.yaml
new file mode 100644
index 00000000..65cfab80
--- /dev/null
+++ b/ci/bundle_tpl/neutron-gateway.yaml
@@ -0,0 +1,14 @@
+ neutron-gateway:
+ charm: "local:{{ ubuntu.release }}/neutron-gateway"
+ num_units: 1
+ options:
+{% if opnfv.ext_port is defined %}
+ ext-port: {{ opnfv.ext_port }}
+{% endif %}
+{% if os.network.controller == 'odl' %}
+ plugin: ovs-odl
+{% endif %}
+ instance-mtu: 1400
+ to:
+ - "nodes=0"
+{# Empty block to avoid bad block trim #}
diff --git a/ci/bundle_tpl/neutron-ovs.yaml b/ci/bundle_tpl/neutron-ovs.yaml
new file mode 100644
index 00000000..1670d43c
--- /dev/null
+++ b/ci/bundle_tpl/neutron-ovs.yaml
@@ -0,0 +1,12 @@
+ neutron-openvswitch:
+ charm: "local:{{ ubuntu.release }}/neutron-openvswitch"
+ num_units: 1
+ options:
+{% if os.network.dpdk %}
+ enable-dpdk: true
+ #dpdk-driver: uio_pci_generic
+{% endif %}
+ #data-port: ""
+ #default-socket-memory: 1024
+ #default-socket-cores: 1
+{# Empty block to avoid bad block trim #}
diff --git a/ci/bundle_tpl/nova-cloud-controller.yaml b/ci/bundle_tpl/nova-cloud-controller.yaml
new file mode 100644
index 00000000..8b0e3c16
--- /dev/null
+++ b/ci/bundle_tpl/nova-cloud-controller.yaml
@@ -0,0 +1,17 @@
+ nova-cloud-controller:
+ charm: "local:{{ ubuntu.release }}/nova-cloud-controller"
+ num_units: {{ unit_qty() }}
+ options:
+ console-access-protocol: novnc
+{% if opnfv.domain is defined %}
+ console-proxy-ip: {{ opnfv.domain }}
+{% endif %}
+ network-manager: Neutron
+ service-guard: true
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.nova }}
+{% endif %}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/nova-compute.yaml b/ci/bundle_tpl/nova-compute.yaml
new file mode 100644
index 00000000..e6305d4c
--- /dev/null
+++ b/ci/bundle_tpl/nova-compute.yaml
@@ -0,0 +1,18 @@
+ nova-compute:
+ charm: "local:{{ ubuntu.release }}/nova-compute"
+ num_units: {{ opnfv.units }}
+ options:
+ enable-live-migration: true
+ enable-resize: true
+ manage-neutron-plugin-legacy-mode: false
+ migration-auth-type: ssh
+{% if os.beta.huge_pages %}
+ hugepages: "50%"
+{% endif %}
+{% if os.lxd %}
+ virt-type: lxd
+{% endif %}
+ to:
+{% for unit_id in to_select(opnfv.units) %}
+ - "nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/odl.yaml b/ci/bundle_tpl/odl.yaml
new file mode 100644
index 00000000..96568d4f
--- /dev/null
+++ b/ci/bundle_tpl/odl.yaml
@@ -0,0 +1,16 @@
+ odl-controller:
+ charm: local:{{ ubuntu.release }}/odl-controller
+ options:
+ install-url: "https://nexus.opendaylight.org/content/repositories/opendaylight.release/org/opendaylight/integration/distribution-karaf/0.4.2-Beryllium-SR2/distribution-karaf-0.4.2-Beryllium-SR2.tar.gz"
+ profile: "openvswitch-odl-beryllium"
+ http-proxy: "http://squid.internal:3128"
+ https-proxy: "http://squid.internal:3128"
+ to:
+ - "lxc:nodes=0"
+ neutron-api-odl:
+ charm: local:{{ ubuntu.release }}/neutron-api-odl
+ options:
+ overlay-network-type: 'vxlan'
+ security-groups: True
+ openvswitch-odl:
+ charm: local:{{ ubuntu.release }}/openvswitch-odl
diff --git a/ci/bundle_tpl/openstack-dashboard.yaml b/ci/bundle_tpl/openstack-dashboard.yaml
new file mode 100644
index 00000000..ee006bb0
--- /dev/null
+++ b/ci/bundle_tpl/openstack-dashboard.yaml
@@ -0,0 +1,15 @@
+ openstack-dashboard:
+ charm: "local:{{ ubuntu.release }}/openstack-dashboard"
+ num_units: {{ unit_qty() }}
+ options:
+ secret: admin
+ webroot: /
+{% if os.ha.mode == 'ha' %}
+ vip: {{ opnfv.vip.dashboard }}
+{% endif %}
+{% if os.beta.public_api %}
+ endpoint-type: internalURL
+{% endif %}
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/opnfv-promise.yaml b/ci/bundle_tpl/opnfv-promise.yaml
new file mode 100644
index 00000000..4e96cf73
--- /dev/null
+++ b/ci/bundle_tpl/opnfv-promise.yaml
@@ -0,0 +1,5 @@
+ opnfv-promise:
+ charm: local:{{ ubuntu.release }}/promise
+ to:
+ - "lxc:nodes=0"
+{# Empty block to avoid bad block trim #}
diff --git a/ci/bundle_tpl/phase2-overrides.yaml b/ci/bundle_tpl/phase2-overrides.yaml
new file mode 100644
index 00000000..8ec13f70
--- /dev/null
+++ b/ci/bundle_tpl/phase2-overrides.yaml
@@ -0,0 +1,23 @@
+{% if opnfv.spaces_dict.data is defined %}
+ os-data-network: {{ opnfv.spaces_dict.data.cidr }}
+{% endif %}
+{% if opnfv.spaces_dict.storage is defined %}
+ ceph-cluster-network: {{ opnfv.spaces_dict.storage.cidr }}
+{% endif %}
+ prefer-ipv6: {{ os.network.ipv6 }}
+{% if os.network.dvr %}
+ enable-dvr: true
+{% endif %}
+{% if os.network.l2_population %}
+ l2-population: true
+{% endif %}
+ region: {{ os.region }}
+ #source: "cloud:{{ ubuntu.release }}-{{ os.release }}"
+ openstack-origin: "cloud:{{ ubuntu.release }}-{{ os.release }}"
+ ceph-osd-replication-count: {{ os.storage.ceph_replica }}
+ admin-role: {{ os.admin_role }}
+ keystone-admin-role: {{ os.admin_role }}
+{% if os.beta.public_api %}
+ use-internal-endpoints: true
+ os-public-hostname: api.{{ opnfv.domain }}
+{% endif %}
diff --git a/ci/bundle_tpl/rabbitmq.yaml b/ci/bundle_tpl/rabbitmq.yaml
new file mode 100644
index 00000000..35e07e90
--- /dev/null
+++ b/ci/bundle_tpl/rabbitmq.yaml
@@ -0,0 +1,7 @@
+ rabbitmq-server:
+ charm: "local:{{ ubuntu.release }}/rabbitmq-server"
+ num_units: {{ unit_qty() }}
+ to:
+{% for unit_id in to_select() %}
+ - "lxc:nodes={{ unit_id }}"
+{% endfor %}
diff --git a/ci/bundle_tpl/relations.yaml b/ci/bundle_tpl/relations.yaml
new file mode 100644
index 00000000..ddfa2fe4
--- /dev/null
+++ b/ci/bundle_tpl/relations.yaml
@@ -0,0 +1,135 @@
+{% if os.ha.mode == 'ha' %}
+ - - mysql:ha
+ - hacluster-mysql:ha
+ - - cinder:ha
+ - hacluster-cinder:ha
+ - - heat:ha
+ - hacluster-heat:ha
+ - - glance:ha
+ - hacluster-glance:ha
+ - - keystone:ha
+ - hacluster-keystone:ha
+ - - neutron-api:ha
+ - hacluster-neutron:ha
+ - - nova-cloud-controller:ha
+ - hacluster-nova:ha
+ - - openstack-dashboard:ha
+ - hacluster-horizon:ha
+ - - heat:ha
+ - hacluster-heat:ha
+{% if os.beta.hacluster_ceph_radosgw %}
+ - - ceph-radosgw:ha
+ - hacluster-ceph-radosgw:ha
+{% endif %}
+{% endif %}
+ - - nova-compute:amqp
+ - rabbitmq-server:amqp
+ - - neutron-gateway:amqp
+ - rabbitmq-server:amqp
+ - - keystone:shared-db
+ - mysql:shared-db
+ - - nova-cloud-controller:identity-service
+ - keystone:identity-service
+ - - glance:identity-service
+ - keystone:identity-service
+ - - neutron-api:identity-service
+ - keystone:identity-service
+ - - neutron-api:shared-db
+ - mysql:shared-db
+ - - neutron-api:amqp
+ - rabbitmq-server:amqp
+ - - neutron-gateway:neutron-plugin-api
+ - neutron-api:neutron-plugin-api
+ - - glance:shared-db
+ - mysql:shared-db
+ - - glance:amqp
+ - rabbitmq-server:amqp
+ - - nova-cloud-controller:image-service
+ - glance:image-service
+ - - nova-compute:image-service
+ - glance:image-service
+ - - nova-cloud-controller:cloud-compute
+ - nova-compute:cloud-compute
+ - - nova-cloud-controller:amqp
+ - rabbitmq-server:amqp
+ - - nova-cloud-controller:quantum-network-service
+ - neutron-gateway:quantum-network-service
+ - - openstack-dashboard:identity-service
+ - keystone:identity-service
+ - - nova-cloud-controller:shared-db
+ - mysql:shared-db
+ - - nova-cloud-controller:neutron-api
+ - neutron-api:neutron-api
+ - - cinder:image-service
+ - glance:image-service
+ - - cinder:amqp
+ - rabbitmq-server:amqp
+ - - cinder:identity-service
+ - keystone:identity-service
+ - - cinder:cinder-volume-service
+ - nova-cloud-controller:cinder-volume-service
+ - - cinder-ceph:storage-backend
+ - cinder:storage-backend
+ - - ceph:client
+ - nova-compute:ceph
+ - - cinder:shared-db
+ - mysql:shared-db
+ - - ceph:client
+ - cinder-ceph:ceph
+ - - ceph:client
+ - glance:ceph
+ - - ceph-osd:mon
+ - ceph:osd
+ - - ntp:juju-info
+ - nova-compute:juju-info
+ - - ntp:juju-info
+ - neutron-gateway:juju-info
+ - - ceph-radosgw:mon
+ - ceph:radosgw
+ - - ceph-radosgw:identity-service
+ - keystone:identity-service
+ - - ceilometer:amqp
+ - rabbitmq-server:amqp
+ - - ceilometer-agent:ceilometer-service
+ - ceilometer:ceilometer-service
+ - - ceilometer:identity-service
+ - keystone:identity-service
+ - - ceilometer:identity-notifications
+ - keystone:identity-notifications
+ - - ceilometer-agent:nova-ceilometer
+ - nova-compute:nova-ceilometer
+ - - ceilometer:shared-db
+ - mongodb:database
+ - - heat:shared-db
+ - mysql:shared-db
+ - - heat:identity-service
+ - keystone:identity-service
+ - - heat:amqp
+ - rabbitmq-server:amqp
+ - - congress:shared-db
+ - mysql:shared-db
+ - - congress:identity-service
+ - keystone:identity-service
+ - - congress:amqp
+ - rabbitmq-server:amqp
+{% if os.lxd %}
+ - - nova-compute:lxd
+ - lxd:lxd
+{% endif %}
+{% if os.network.controller == 'nosdn' %}
+ - - neutron-openvswitch:amqp
+ - rabbitmq-server:amqp
+ - - nova-compute:neutron-plugin
+ - neutron-openvswitch:neutron-plugin
+ - - neutron-openvswitch:neutron-plugin-api
+ - neutron-api:neutron-plugin-api
+{% elif os.network.controller == 'odl' %}
+ - - nova-compute:neutron-plugin
+ - openvswitch-odl:neutron-plugin
+ - - neutron-gateway
+ - openvswitch-odl
+ - - openvswitch-odl:ovsdb-manager
+ - odl-controller:ovsdb-manager
+ - - neutron-api-odl:odl-controller
+ - odl-controller:controller-api
+{% endif %}
diff --git a/ci/default_deployment_config.yaml b/ci/default_deployment_config.yaml
new file mode 100644
index 00000000..3e9467a1
--- /dev/null
+++ b/ci/default_deployment_config.yaml
@@ -0,0 +1,26 @@
+ubuntu:
+ release: xenial
+
+os:
+ release: mitaka
+ ha:
+ mode: ha
+ cluster_size: 3
+ lxd: False
+ region: Canonical
+ admin:
+ role: admin
+ name: admin
+ password: openstack
+ storage:
+ ceph_replica: '2'
+ network:
+ controller: odl
+ enhanced_ovs: False
+ dvr: False
+ ipv6: False
+ l2_population: False
+ beta:
+ hacluster_ceph_radosgw: False
+ public_api: False
+ huge_pages: False
diff --git a/ci/genBundle.py b/ci/genBundle.py
new file mode 100644
index 00000000..99cf53d6
--- /dev/null
+++ b/ci/genBundle.py
@@ -0,0 +1,165 @@
+#!/usr/bin/python3
+# -*- coding: utf-8 -*-
+
+from optparse import OptionParser
+from jinja2 import Environment, FileSystemLoader
+from pprint import pprint as pp
+import os
+import random
+import yaml
+import sys, traceback
+
+##
+## Parse parameters
+##
+
+parser = OptionParser()
+parser.add_option("-s", "--scenario", dest="scenario", help ="scenario name")
+parser.add_option("-l", "--lab", dest="lab", help ="lab config file")
+(options, args) = parser.parse_args()
+scenario = options.scenario
+labconfig_file = options.lab
+
+##
+## Set Path and configs path
+##
+
+scenarioconfig_file = 'default_deployment_config.yaml'
+# Capture our current directory
+TPL_DIR = os.path.dirname(os.path.abspath(__file__))+'/bundle_tpl'
+
+##
+## Prepare variables
+##
+
+# Prepare a storage for passwords
+passwords_store = dict()
+
+##
+## Local Functions
+##
+
+def load_yaml(filepath):
+ with open(filepath, 'r') as stream:
+ try:
+ return yaml.load(stream)
+ except yaml.YAMLError as exc:
+ print(exc)
+
+##
+## Templates functions
+##
+
+def unit_qty():
+ global config
+ if config['os']['ha']['mode'] == 'ha':
+ return config['os']['ha']['cluster_size']
+ else:
+ return 1
+
+def to_select( qty = False ):
+ global config
+ if not qty:
+ qty = config['os']['ha']['cluster_size'] if config['os']['ha']['mode'] == 'ha' else 1
+ return random.sample(range(0,config['opnfv']['units']), qty )
+
+def get_password(key, length=16, special=False):
+ global passwords_store
+ if key not in passwords_store.keys():
+ alphabet = "abcdefghijklmnopqrstuvwxyz"
+ upperalphabet = alphabet.upper()
+ char_list = alphabet + upperalphabet
+ pwlist = []
+ if special:
+ char_list += "+-,;./:?!*"
+ for i in range(length):
+ pwlist.append(char_list[random.randrange(len(char_list))])
+ random.shuffle(pwlist)
+ passwords_store[key] = "".join(pwlist)
+ return passwords_store[key]
+
+##
+## Config import
+##
+
+#Load scenario Config
+config = load_yaml(scenarioconfig_file)
+#Load lab Config
+config.update(load_yaml(labconfig_file))
+
+#We transform array to hash for an easier work
+config['opnfv']['spaces_dict'] = dict()
+for space in config['opnfv']['spaces']:
+ config['opnfv']['spaces_dict'][space['type']] = space
+config['opnfv']['storage_dict'] = dict()
+for storage in config['opnfv']['storage']:
+ config['opnfv']['storage_dict'][storage['type']] = storage
+
+##
+## Parse scenario name
+##
+
+# Set default scenario name
+if not scenario:
+ scenario = "os-nosdn-nofeature-nonha"
+
+# Parse scenario name
+try:
+ sc = scenario.split('-')
+ (sdn, features, hamode) = sc[1:4]
+ features = features.split('_')
+ if len(sc) > 4:
+ extra = sc[4].split('_')
+ else:
+ extra = []
+except ValueError as err:
+ print('Error: Bad scenario name syntax, use '
+ '"os-<controller>-<nfvfeature>-<mode>[-<extrastuff>]" format')
+ sys.exit(1)
+
+##
+## Update config with scenario name
+##
+
+# change ha mode
+config['os']['ha']['mode'] = hamode
+
+# change ha mode
+config['os']['network']['controller'] = sdn
+
+# Change features
+if 'lxd' in features:
+ config['os']['lxd'] = True
+if 'drv' in features:
+ config['os']['network']['dvr'] = True
+if 'ipv6' in features:
+ config['os']['network']['ipv6'] = True
+if 'ovs' in features:
+ config['os']['network']['enhanced_ovs'] = True
+
+# Set beta option from extra
+if 'publicapi' in extra:
+ config['os']['beta']['public_api'] = True
+if 'radosgwcluster' in extra:
+ config['os']['beta']['hacluster_ceph_radosgw'] = True
+if 'hugepages' in extra:
+ config['os']['beta']['huge_pages'] = True
+
+# pp(config)
+
+##
+## Transform template to bundle.yaml according to config
+##
+
+# Create the jinja2 environment.
+env = Environment(loader=FileSystemLoader(TPL_DIR),
+ trim_blocks=True)
+template = env.get_template('bundle.yaml')
+
+# Add functions
+env.globals.update(get_password=get_password)
+env.globals.update(unit_qty=unit_qty)
+env.globals.update(to_select=to_select)
+
+# Render the template
+print(template.render(**config))