Merge "Add ironic component to the tempest"
diff --git a/Makefile b/Makefile
index 4a83bf8..fb69046 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,12 @@
 SALTENVDIR=/usr/share/salt-formulas/env
 RECLASSDIR=/usr/share/salt-formulas/reclass
 FORMULANAME=$(shell grep name: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\-\_]*')
+VERSION=$(shell grep version: metadata.yml|head -1|cut -d : -f 2|grep -Eo '[a-z0-9\.\-\_]*')
+VERSION_MAJOR := $(shell echo $(VERSION)|cut -d . -f 1-2)
+VERSION_MINOR := $(shell echo $(VERSION)|cut -d . -f 3)
+
+NEW_MAJOR_VERSION ?= $(shell date +%Y.%m|sed 's,\.0,\.,g')
+NEW_MINOR_VERSION ?= $(shell /bin/bash -c 'echo $$[ $(VERSION_MINOR) + 1 ]')
 
 MAKE_PID := $(shell echo $$PPID)
 JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
@@ -12,10 +18,26 @@
 JOBS := 1
 endif
 
+ifeq (,$(wildcard ./.kitchen.openstack.yml))
+KITCHEN_LOCAL_YAML?=.kitchen.openstack.yml
+else
+KITCHEN_LOCAL_YAML?=.kitchen.yml
+endif
+KITCHEN_OPTS?="--concurrency=$(JOBS)"
+KITCHEN_OPTS_CREATE?=""
+KITCHEN_OPTS_CONVERGE?=""
+KITCHEN_OPTS_VERIFY?=""
+KITCHEN_OPTS_TEST?=""
+
 all:
 	@echo "make install - Install into DESTDIR"
+	@echo "make lint    - Run lint tests"
 	@echo "make test    - Run tests"
+	@echo "make kitchen - Run Kitchen CI tests (create, converge, verify)"
 	@echo "make clean   - Cleanup after tests run"
+	@echo "make release-major  - Generate new major release"
+	@echo "make release-minor  - Generate new minor release"
+	@echo "make changelog      - Show changes since last release"
 
 install:
 	# Formula
@@ -23,13 +45,82 @@
 	cp -a $(FORMULANAME) $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _modules ] || cp -a _modules $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _states ] || cp -a _states $(DESTDIR)/$(SALTENVDIR)/ || true
+	[ ! -d _grains ] || cp -a _grains $(DESTDIR)/$(SALTENVDIR)/ || true
 	# Metadata
 	[ -d $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME) ] || mkdir -p $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
 	cp -a metadata/service/* $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
 
+lint:
+	[ ! -d tests ] || (cd tests; ./run_tests.sh lint)
+
 test:
 	[ ! -d tests ] || (cd tests; ./run_tests.sh)
 
+release-major: check-changes
+	@echo "Current version is $(VERSION), new version is $(NEW_MAJOR_VERSION)"
+	@[ $(VERSION_MAJOR) != $(NEW_MAJOR_VERSION) ] || (echo "Major version $(NEW_MAJOR_VERSION) already released, nothing to do. Do you want release-minor?" && exit 1)
+	echo "$(NEW_MAJOR_VERSION)" > VERSION
+	sed -i 's,version: .*,version: "$(NEW_MAJOR_VERSION)",g' metadata.yml
+	[ ! -f debian/changelog ] || dch -v $(NEW_MAJOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+	make genchangelog-$(NEW_MAJOR_VERSION)
+	(git add -u; git commit -m "Version $(NEW_MAJOR_VERSION)")
+	git tag -s -m $(NEW_MAJOR_VERSION) $(NEW_MAJOR_VERSION)
+
+release-minor: check-changes
+	@echo "Current version is $(VERSION), new version is $(VERSION_MAJOR).$(NEW_MINOR_VERSION)"
+	echo "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)" > VERSION
+	sed -i 's,version: .*,version: "$(VERSION_MAJOR).$(NEW_MINOR_VERSION)",g' metadata.yml
+	[ ! -f debian/changelog ] || dch -v $(VERSION_MAJOR).$(NEW_MINOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
+	make genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+	(git add -u; git commit -m "Version $(VERSION_MAJOR).$(NEW_MINOR_VERSION)")
+	git tag -s -m $(VERSION_MAJOR).$(NEW_MINOR_VERSION) $(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+check-changes:
+	@git log --pretty=oneline --decorate $(VERSION)..HEAD | grep -Eqc '.*' || (echo "No new changes since version $(VERSION)"; exit 1)
+
+changelog:
+	git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $(VERSION)..HEAD
+
+genchangelog: genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+
+genchangelog-%:
+	$(eval NEW_VERSION := $(patsubst genchangelog-%,%,$@))
+	(echo "=========\nChangelog\n=========\n"; \
+	(echo $(NEW_VERSION);git tag) | sort -r | grep -E '^[0-9\.]+' | while read i; do \
+	    cur=$$i; \
+	    test $$i = $(NEW_VERSION) && i=HEAD; \
+	    prev=`(echo $(NEW_VERSION);git tag)|sort|grep -E '^[0-9\.]+'|grep -B1 "$$cur\$$"|head -1`; \
+	    echo "Version $$cur\n=============================\n"; \
+	    git log --pretty=short --invert-grep --grep="Merge pull request" --decorate $$prev..$$i; \
+	    echo; \
+	done) > CHANGELOG.rst
+
+kitchen-check:
+	@[ -e $(KITCHEN_LOCAL_YAML) ] || (echo "Kitchen tests not available, there's no $(KITCHEN_LOCAL_YAML)." && exit 1)
+
+kitchen: kitchen-check kitchen-create kitchen-converge kitchen-verify kitchen-list
+
+kitchen-create: kitchen-check
+	kitchen create ${KITCHEN_OPTS} ${KITCHEN_OPTS_CREATE}
+	[ "$(shell echo $(KITCHEN_LOCAL_YAML)|grep -Eo docker)" = "docker" ] || sleep 120
+
+kitchen-converge: kitchen-check
+	kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE} &&\
+	kitchen converge ${KITCHEN_OPTS} ${KITCHEN_OPTS_CONVERGE}
+
+kitchen-verify: kitchen-check
+	[ ! -d tests/integration ] || kitchen verify -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+	[ -d tests/integration ]   || kitchen verify ${KITCHEN_OPTS} ${KITCHEN_OPTS_VERIFY}
+
+kitchen-test: kitchen-check
+	[ ! -d tests/integration ] || kitchen test -t tests/integration ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+	[ -d tests/integration ]   || kitchen test ${KITCHEN_OPTS} ${KITCHEN_OPTS_TEST}
+
+kitchen-list: kitchen-check
+	kitchen list
+
 clean:
+	[ ! -x "$(shell which kitchen)" ] || kitchen destroy
+	[ ! -d .kitchen ] || rm -rf .kitchen
 	[ ! -d tests/build ] || rm -rf tests/build
 	[ ! -d build ] || rm -rf build
diff --git a/_modules/runtest/tempest_sections/compute.py b/_modules/runtest/tempest_sections/compute.py
index 6ae4439..783f997 100644
--- a/_modules/runtest/tempest_sections/compute.py
+++ b/_modules/runtest/tempest_sections/compute.py
@@ -162,7 +162,10 @@
 
     @property
     def min_compute_nodes(self):
-        pass
+        c = conditions.BaseRule(field='nova.compute.enabled', op='eq',
+                                val=True)
+        nodes = self.get_nodes_where_condition_match(c)
+        return len(nodes)
 
     @property
     def min_microversion(self):
diff --git a/_modules/runtest/tempest_sections/network.py b/_modules/runtest/tempest_sections/network.py
index c1baa6a..b9d8cf9 100644
--- a/_modules/runtest/tempest_sections/network.py
+++ b/_modules/runtest/tempest_sections/network.py
@@ -69,7 +69,12 @@
 
     @property
     def project_network_cidr(self):
-        pass
+        contrail_enabled = conditions.BaseRule('*.opencontrail.control.enabled',
+                                               'eq', True, multiple='any')
+        if contrail_enabled.check(self.pillar):
+            return '10.100.0.0/24'
+        else:
+            pass
 
     @property
     def project_network_mask_bits(self):
@@ -77,7 +82,12 @@
 
     @property
     def project_network_v6_cidr(self):
-        pass
+        contrail_enabled = conditions.BaseRule('*.opencontrail.control.enabled',
+                                               'eq', True, multiple='any')
+        if contrail_enabled.check(self.pillar):
+            return '2003::/120'
+        else:
+            pass
 
     @property
     def project_network_v6_mask_bits(self):
diff --git a/runtest/artifact_collector.sls b/runtest/artifact_collector.sls
index a5a1057..9c7f46e 100644
--- a/runtest/artifact_collector.sls
+++ b/runtest/artifact_collector.sls
@@ -32,19 +32,20 @@
 
 {%- for artifact_name, artifact_params in artifact_collector.artifacts.iteritems() %}
 {%- if salt['file.file_exists'](artifact_params.path) or salt['file.directory_exists'](artifact_params.path) %}
-{%- set zip_file = "/tmp/"+artifact_name+".zip" %}
+{%- set tar_file = "/tmp/"+artifact_name+".tar.gz" %}
 
-zip_{{artifact_name}}:
+tar_{{artifact_name}}:
   module.run:
-    - name: archive.zip
-    - zip_file: {{ zip_file }}
+    - name: archive.tar
+    - options: czvf
+    - tarfile: {{ tar_file }}
     - sources: {{ artifact_params.path }}
 
 {%- if artifact_collector.get('artifactory', {}).get('enabled', False) %}
 deploy_{{artifact_name}}:
     module.run:
       - name: artifactory.deploy_artifact
-      - source_file: {{ zip_file }}
+      - source_file: {{ tar_file }}
       - endpoint: {{ artifact_collector.artifactory.endpoint }}
       - require:
         - pkg: required_artifact_pkgs
diff --git a/runtest/salttest/modules/openstack/designatev2.sls b/runtest/salttest/modules/openstack/designatev2.sls
new file mode 100644
index 0000000..6e261bf
--- /dev/null
+++ b/runtest/salttest/modules/openstack/designatev2.sls
@@ -0,0 +1,44 @@
+{% set Designate_Zone_Name = 'test.org.' %}
+designatev2_zone_create:
+  module.run:
+    - name: designatev2.zone_create
+    - kwargs:
+        cloud_name: admin_identity
+        name: {{ Designate_Zone_Name }}
+        email: 'example@doc.com'
+
+designatev2_zone_list:
+  module.run:
+    - name: designatev2.zone_list
+    - kwargs:
+        cloud_name: admin_identity
+
+designatev2_zone_get_details:
+  module.run:
+    - name: designatev2.zone_get_details
+    - kwargs:
+        cloud_name: admin_identity
+        zone_id: {{ Designate_Zone_Name }}
+
+designatev2_zone_update:
+  module.run:
+    - name: designatev2.zone_update
+    - kwargs:
+        cloud_name: admin_identity
+        zone_id: {{ Designate_Zone_Name }}
+        email: 'example@doc.com'
+
+designatev2_zone_get_name_servers:
+  module.run:
+    - name: designatev2.zone_get_name_servers
+    - kwargs:
+        cloud_name: admin_identity
+        zone_id: {{ Designate_Zone_Name }}
+
+designate_zone_delete:
+  module.run:
+    - name: designatev2.zone_delete
+    - kwargs:
+        cloud_name: admin_identity
+        zone_id: {{ Designate_Zone_Name }}
+
diff --git a/runtest/salttest/states/openstack/designatev2.sls b/runtest/salttest/states/openstack/designatev2.sls
new file mode 100644
index 0000000..d8b4dc3
--- /dev/null
+++ b/runtest/salttest/states/openstack/designatev2.sls
@@ -0,0 +1,12 @@
+{% set Designate_Test_Zone = 'designate.test.org.' %}
+designatev2_zone_present:
+  designatev2.zone_present:
+  - cloud_name: admin_identity
+  - name: {{ Designate_Test_Zone }}
+  - email: 'example@doc.com'
+
+designatev2_zone_absent:
+  designatev2.zone_absent:
+  - cloud_name: admin_identity
+  - name: {{ Designate_Test_Zone }}
+