aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--all-nodes-validation.yaml27
-rw-r--r--overcloud-resource-registry-puppet.yaml3
-rw-r--r--overcloud-resource-registry.yaml3
-rw-r--r--overcloud-without-mergepy.yaml48
-rw-r--r--puppet/hieradata/controller.yaml2
-rw-r--r--puppet/manifests/overcloud_controller_pacemaker.pp2
-rwxr-xr-xtools/yaml-validate.py46
-rw-r--r--tox.ini3
-rw-r--r--validation-scripts/all-nodes.sh29
9 files changed, 163 insertions, 0 deletions
diff --git a/all-nodes-validation.yaml b/all-nodes-validation.yaml
new file mode 100644
index 00000000..a7383375
--- /dev/null
+++ b/all-nodes-validation.yaml
@@ -0,0 +1,27 @@
+heat_template_version: 2015-04-30
+
+description: >
+ Software Config to drive validations that occur on all nodes.
+ Note, you need the heat-config-script element built into your
+ images, due to the script group below.
+
+parameters:
+ PingTestIps:
+ default: ''
+ description: A string containing a space separated list of IP addresses used to ping test each available network interface.
+ type: string
+
+resources:
+ AllNodesValidationsImpl:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ group: script
+ inputs:
+ - name: ping_test_ips
+ default: {get_param: PingTestIps}
+ config: {get_file: ./validation-scripts/all-nodes.sh}
+
+outputs:
+ OS::stack_id:
+ description: The ID of the AllNodesValidationsImpl resource.
+ value: {get_resource: AllNodesValidationsImpl}
diff --git a/overcloud-resource-registry-puppet.yaml b/overcloud-resource-registry-puppet.yaml
index ecb1162e..7680192f 100644
--- a/overcloud-resource-registry-puppet.yaml
+++ b/overcloud-resource-registry-puppet.yaml
@@ -80,5 +80,8 @@ resource_registry:
# Port assignments for service virtual IPs for the controller role
OS::TripleO::Controller::Ports::RedisVipPort: network/ports/ctlplane_vip.yaml
+ # validation resources
+ OS::TripleO::AllNodes::Validation: all-nodes-validation.yaml
+
parameter_defaults:
EnablePackageInstall: false
diff --git a/overcloud-resource-registry.yaml b/overcloud-resource-registry.yaml
index 094b3311..eaedf790 100644
--- a/overcloud-resource-registry.yaml
+++ b/overcloud-resource-registry.yaml
@@ -65,3 +65,6 @@ resource_registry:
# Port assignments for service virtual IPs for the controller role
OS::TripleO::Controller::Ports::RedisVipPort: network/ports/noop.yaml
+
+ # validation resources
+ OS::TripleO::AllNodes::Validation: all-nodes-validation.yaml
diff --git a/overcloud-without-mergepy.yaml b/overcloud-without-mergepy.yaml
index 63cce2a3..260952b3 100644
--- a/overcloud-without-mergepy.yaml
+++ b/overcloud-without-mergepy.yaml
@@ -1253,6 +1253,54 @@ resources:
config: {get_attr: [allNodesConfig, config_id]}
servers: {get_attr: [CephStorage, attributes, nova_server_resource]}
+ # All Nodes Validations
+ AllNodesValidationConfig:
+ type: OS::TripleO::AllNodes::Validation
+ properties:
+ PingTestIps:
+ list_join:
+ - ' '
+ - - {get_attr: [Controller, resource.0.external_ip_address]}
+ - {get_attr: [Controller, resource.0.internal_api_ip_address]}
+ - {get_attr: [Controller, resource.0.storage_ip_address]}
+ - {get_attr: [Controller, resource.0.storage_mgmt_ip_address]}
+ - {get_attr: [Controller, resource.0.tenant_ip_address]}
+
+ ControllerAllNodesValidationDeployment:
+ type: OS::Heat::StructuredDeployments
+ depends_on: ControllerAllNodesDeployment
+ properties:
+ config: {get_resource: AllNodesValidationConfig}
+ servers: {get_attr: [Controller, attributes, nova_server_resource]}
+
+ ComputeAllNodesValidationDeployment:
+ type: OS::Heat::StructuredDeployments
+ depends_on: ComputeAllNodesDeployment
+ properties:
+ config: {get_resource: AllNodesValidationConfig}
+ servers: {get_attr: [Compute, attributes, nova_server_resource]}
+
+ BlockStorageAllNodesValidationDeployment:
+ type: OS::Heat::StructuredDeployments
+ depends_on: BlockStorageAllNodesDeployment
+ properties:
+ config: {get_resource: AllNodesValidationConfig}
+ servers: {get_attr: [BlockStorage, attributes, nova_server_resource]}
+
+ ObjectStorageAllNodesValidationDeployment:
+ type: OS::Heat::StructuredDeployments
+ depends_on: ObjectStorageAllNodesDeployment
+ properties:
+ config: {get_resource: AllNodesValidationConfig}
+ servers: {get_attr: [ObjectStorage, attributes, nova_server_resource]}
+
+ CephStorageAllNodesValidationDeployment:
+ type: OS::Heat::StructuredDeployments
+ depends_on: CephStorageAllNodesDeployment
+ properties:
+ config: {get_resource: AllNodesValidationConfig}
+ servers: {get_attr: [CephStorage, attributes, nova_server_resource]}
+
# Nested stack deployment runs after all other controller deployments
ControllerNodesPostDeployment:
type: OS::TripleO::ControllerPostDeployment
diff --git a/puppet/hieradata/controller.yaml b/puppet/hieradata/controller.yaml
index 48def44d..9929cfa6 100644
--- a/puppet/hieradata/controller.yaml
+++ b/puppet/hieradata/controller.yaml
@@ -92,6 +92,8 @@ heat::instance_user: ''
# pacemaker
pacemaker::corosync::cluster_name: 'tripleo_cluster'
pacemaker::corosync::manage_fw: false
+pacemaker::resource_defaults::defaults:
+ resource-stickiness: { value: INFINITY }
# horizon
horizon::allowed_hosts: '*'
diff --git a/puppet/manifests/overcloud_controller_pacemaker.pp b/puppet/manifests/overcloud_controller_pacemaker.pp
index 4e70c86b..e4a179d6 100644
--- a/puppet/manifests/overcloud_controller_pacemaker.pp
+++ b/puppet/manifests/overcloud_controller_pacemaker.pp
@@ -177,6 +177,8 @@ if hiera('step') >= 2 {
if $pacemaker_master {
+ include pacemaker::resource_defaults
+
# FIXME: we should not have to access tripleo::loadbalancer class
# parameters here to configure pacemaker VIPs. The configuration
# of pacemaker VIPs could move into puppet-tripleo or we should
diff --git a/tools/yaml-validate.py b/tools/yaml-validate.py
new file mode 100755
index 00000000..cb5669a7
--- /dev/null
+++ b/tools/yaml-validate.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# 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 os
+import sys
+import traceback
+import yaml
+
+base_path = sys.argv[1]
+exit_val = 0
+failed_files = []
+
+def validate(filename):
+ try:
+ yaml.load(open(filename).read())
+ except Exception:
+ print(traceback.format_exc())
+ return 1
+ return 0
+
+for subdir, dirs, files in os.walk(base_path):
+ for f in files:
+ if f.endswith('.yaml'):
+ file_path = os.path.join(subdir, f)
+ failed = validate(file_path)
+ if failed:
+ failed_files.append(file_path)
+ exit_val |= failed
+
+if failed_files:
+ print('Validation failed on:')
+ for f in failed_files:
+ print(f)
+else:
+ print('Validation successful!')
+sys.exit(exit_val)
diff --git a/tox.ini b/tox.ini
index a7823b10..bc14bda1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,3 +9,6 @@ deps = -r{toxinidir}/requirements.txt
[testenv:venv]
commands = {posargs}
+
+[testenv:validate]
+commands = python ./tools/yaml-validate.py . \ No newline at end of file
diff --git a/validation-scripts/all-nodes.sh b/validation-scripts/all-nodes.sh
new file mode 100644
index 00000000..38a5a55e
--- /dev/null
+++ b/validation-scripts/all-nodes.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# For each unique remote IP (specified via Heat) we check to
+# see if one of the locally configured networks matches and if so we
+# attempt a ping test on that networks remote IP.
+function ping_controller_ips() {
+ local REMOTE_IPS=$1
+
+ for REMOTE_IP in $(echo $REMOTE_IPS | sed -e "s| |\n|g" | sort -u); do
+
+ for LOCAL_NETWORK in $(ip r | grep -v default | cut -d " " -f 1); do
+ local LOCAL_CIDR=$(echo $LOCAL_NETWORK | cut -d "/" -f 2)
+ local LOCAL_NETMASK=$(ipcalc -m $LOCAL_NETWORK | grep NETMASK | cut -d "=" -f 2)
+ local REMOTE_NETWORK=$(ipcalc -np $REMOTE_IP $LOCAL_NETMASK | grep NETWORK | cut -d "=" -f 2)
+
+ if [ $REMOTE_NETWORK/$LOCAL_CIDR == $LOCAL_NETWORK ]; then
+ echo -n "Trying to ping $REMOTE_IP for local network $LOCAL_NETWORK..."
+ if ! ping -c 1 $REMOTE_IP &> /dev/null; then
+ echo "FAILURE"
+ echo "$REMOTE_IP is not pingable. Local Network: $LOCAL_NETWORK" >&2
+ exit 1
+ fi
+ echo "SUCCESS"
+ fi
+ done
+ done
+}
+
+ping_controller_ips "$ping_test_ips"