Fetch all compute ips via installer Fuel. 71/18071/5
authorwu.zhihui <wu.zhihui1@zte.com.cn>
Fri, 5 Aug 2016 07:05:30 +0000 (15:05 +0800)
committerwu.zhihui <wu.zhihui1@zte.com.cn>
Thu, 18 Aug 2016 15:26:02 +0000 (23:26 +0800)
1. Fetch all compute ips via installer Fuel.
2. check the machines' ip. if unassigned, assign one of compute's
ip to it. if assigned by test case yaml, check the validation.

JIRA: QTIP-98

Change-Id: I5517916c594a14055087134d20c1fe4320b6d707
Signed-off-by: wu.zhihui <wu.zhihui1@zte.com.cn>
func/env_setup.py
func/fetch_compute_ips.sh [new file with mode: 0755]
tests/env_setup_test.py

index 9c0dadb..fdddf49 100644 (file)
@@ -1,5 +1,5 @@
 ##############################################################################
-# Copyright (c) 2015 Dell Inc  and others.
+# Copyright (c) 2016 Dell Inc, ZTE and others.
 #
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Apache License, Version 2.0
@@ -14,9 +14,16 @@ import yaml
 import time
 import paramiko
 import socket
+from os.path import expanduser
+import random
+import logging
+
+LOG = logging.getLogger(__name__)
+LOG.setLevel(logging.DEBUG)
 
 
 class Env_setup:
+
     roles_ip_list = []  # ROLE and its corresponding IP address list
     ip_pw_list = []  # IP and password, this will be used to ssh
     roles_dict = defaultdict(list)
@@ -110,10 +117,58 @@ class Env_setup:
                     time.sleep(10)
                 print ('\n\n %s is UP \n\n ' % ipvar)
 
-    def get_host_machine_info(self, host_tag):
+    @staticmethod
+    def fetch_compute_ips():
+        LOG.info("Fetch compute ips through installer")
+        ips = []
+
+        installer_type = os.environ['INSTALLER_TYPE']
+        installer_ip = os.environ['INSTALLER_IP']
+        if installer_type.down.lower() != "fuel" or "compass":
+            raise RuntimeError("%s is not supported" % installer_type)
+        if installer_ip:
+            raise RuntimeError("undefine environment variable INSTALLER_IP")
+
+        cmd = "bash ./fetch_compute_ip.sh -i %s -a %s" % \
+            (installer_type, installer_ip)
+        os.system(cmd)
+        home = expanduser("~")
+        os.chdir(home)
+        with open("ips.log", "r") as file:
+            data = file.read()
+        if data:
+            ips.extend(data.rstrip('\n').split('\n'))
+        LOG.info("All compute ips: %s" % ips)
+        return ips
+
+    def check_machine_ips(self, host_tag):
+        LOG.info("Check machine ips")
+        ips = self.fetch_compute_ips()
+        ips_num = len(ips)
+        num = len(host_tag)
+        if num > ips_num:
+            err = "host num %s > compute ips num %s" % (num, ips_num)
+            raise RuntimeError(err)
 
+        for x in range(num):
+            hostlabel = 'machine_' + str(x + 1)
+            if host_tag[hostlabel]['ip']:
+                if host_tag[hostlabel]['ip'] in ips:
+                    info = "%s's ip %s is defined by test case yaml file" % \
+                        (hostlabel, host_tag[hostlabel]['ip'])
+                    LOG.info(info)
+                else:
+                    err = "%s is not in %s" % (host_tag[hostlabel]['ip'], ips)
+                    raise RuntimeError(err)
+            else:
+                host_tag[hostlabel]['ip'] = random.choice(ips)
+                info = "assign ip %s to %s" % (host_tag[hostlabel]['ip'], hostlabel)
+            ips.remove(host_tag[hostlabel]['ip'])
+
+    def get_host_machine_info(self, host_tag):
         num = len(host_tag)
         offset = len(self.roles_ip_list)
+        self.check_machine_ips(host_tag)
         for x in range(num):
             hostlabel = 'machine_' + str(x + 1)
             self.roles_ip_list.insert(
diff --git a/func/fetch_compute_ips.sh b/func/fetch_compute_ips.sh
new file mode 100755 (executable)
index 0000000..c1cc4c6
--- /dev/null
@@ -0,0 +1,117 @@
+#!/bin/bash
+##############################################################################
+#Copyright (c) 2016 Ericsson AB, ZTE and others.
+#jose.lausuch@ericsson.com
+#wu.zhihui1@zte.com.cn
+#All rights reserved. This program and the accompanying materials
+#are made available under the terms of the Apache License, Version 2.0
+#which accompanies this distribution, and is available at
+#http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+usage(){
+   echo "usage: $0 [-v] -i <installer_type> -a <installer_ip>" >&2
+   echo "[-v] Virtualized deployment" >&2
+}
+
+info()  {
+   logger -s -t "fetch_compute_info.info" "$*"
+}
+
+
+error() {
+   logger -s -t "fetch_compute_info.error" "$*"
+   exit 1
+}
+
+verify_connectivity(){
+   local ip=$1
+   info "Verifying connectivity to $ip..."
+   for i in $(seq 0 10); do
+       if ping -c 1 -W 1 $ip > /dev/null; then
+           info "$ip is reachable!"
+           return 0
+       fi
+       sleep 1
+   done
+   error "Can not talk to $ip."
+}
+
+:${DEPLOY_TYPE:=''}
+
+#Getoptions
+whilegetopts ":d:i:a:h:v" optchar; do
+   case "${optchar}" in
+       i) installer_type=${OPTARG} ;;
+       a) installer_ip=${OPTARG} ;;
+       v) DEPLOY_TYPE="virt" ;;
+       *) echo "Non-option argument: '-${OPTARG}'" >&2
+          usage
+          exit 2
+          ;;
+   esac
+done
+
+#set vars from env if not provided by user as options
+installer_type=${installer_type:-$INSTALLER_TYPE}
+installer_ip=${installer_ip:-$INSTALLER_IP}
+
+if[ -z $installer_type ] || [ -z $installer_ip ]; then
+   usage
+   exit 2
+fi
+
+ssh_options="-oUserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
+
+#Start fetching compute ip
+if[ "$installer_type" == "fuel" ]; then
+   verify_connectivity $installer_ip
+
+   env=$(sshpass -p r00tme ssh 2>/dev/null $ssh_options root@${installer_ip} \
+       'fuel env'|grep operational|head -1|awk '{print $1}') &> /dev/null
+   if [ -z $env ]; then
+       error "No operational environment detected in Fuel"
+   fi
+   env_id="${FUEL_ENV:-$env}"
+
+   # Check if compute is alive (online='True')
+   IPS=$(sshpass -p r00tme ssh 2>/dev/null $ssh_options root@${installer_ip} \
+       "fuel node --env ${env_id} | grep compute | grep 'True\|  1' | awk -F\| '{print \$5}' " | \
+       sed 's/ //g') &> /dev/null
+
+
+elif[ "$installer_type" == "apex" ]; then
+   echo "not implement now"
+   exit 1
+
+elif[ "$installer_type" == "compass" ]; then
+   # need test
+   verify_connectivity $installer_ip
+   IPS=$(sshpass -p'root' ssh 2>/dev/null $ssh_options root@${installer_ip} \
+       'mysql -ucompass -pcompass -Dcompass -e"select *  from cluster;"' \
+       | awk -F"," '{for(i=1;i<NF;i++)if($i~/\"host[4-5]\"/) {print $(i+1);}}'  \
+       | grep -oP "\d+.\d+.\d+.\d+")
+
+elif[ "$installer_type" == "joid" ]; then
+   echo "not implement now"
+   exit 1
+
+elif[ "$installer_type" == "foreman" ]; then
+   echo "not implement now"
+   exit 1
+
+else
+   error "Installer $installer is not supported by this script"
+fi
+
+if[ -z $IPS ]; then
+   error "The compute node $IPS are not up. Please check that the POD is correctly deployed."
+else
+   echo "-------- all compute node ips: --------"
+   touch $HOME/ips.log
+   echo "$IPS" > $HOME/ips.log
+   echo $IPS
+fi
+
+exit0
index 9112ff9..cc3c6b6 100644 (file)
@@ -1,6 +1,16 @@
+##############################################################################
+# Copyright (c) 2016 ZTE and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
 import pytest
 import filecmp
 from func.env_setup import Env_setup
+import mock
 
 
 class TestClass:
@@ -31,6 +41,8 @@ class TestClass:
         print (test_input)
         print (expected)
         test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
         benchmark, vm_para, details, proxy = \
             test_class.parse(test_input)
         assert benchmark == expected[0]
@@ -40,12 +52,16 @@ class TestClass:
 
     def test_parse_vm_error(self):
         test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
         with pytest.raises(KeyError) as excinfo:
             test_class.parse("tests/test_case/vm_error.yaml")
         assert "benchmark" in str(excinfo.value)
 
     def test_update_ansible(self):
         test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
         test_class.parse("tests/test_case/bm_without_proxy.yaml")
         test_class.update_ansible()
         result = filecmp.cmp('tests/output/hosts', 'data/hosts')
@@ -53,7 +69,40 @@ class TestClass:
 
     def test_ping(self, capfd):
         test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["127.0.0.1", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
         test_class.parse("tests/test_case/bm_ping.yaml")
         test_class.call_ping_test()
         resout, reserr = capfd.readouterr()
         assert '127.0.0.1 is UP' in resout
+
+    def test_check_machine_ips_without_ip(self):
+        test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
+        inputs = {"machine_1": {"ip": "", "pw": "", "role": "host"},
+                  "machine_2": {"ip": "", "pw": "", "role": "host"}}
+        test_class.check_machine_ips(inputs)
+        assert inputs["machine_1"]['ip'] in ["10.20.0.28", "10.20.0.29"]
+        assert inputs["machine_2"]['ip'] in ["10.20.0.28", "10.20.0.29"]
+        assert inputs["machine_1"]['ip'] != inputs["machine_2"]['ip']
+
+    def test_check_machine_ips_with_ip(self):
+        test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
+        inputs = {"machine_1": {"ip": "10.20.0.28", "pw": "", "role": "host"},
+                  "machine_2": {"ip": "10.20.0.29", "pw": "", "role": "host"}}
+        test_class.check_machine_ips(inputs)
+        assert inputs["machine_1"]['ip'] in ["10.20.0.28", "10.20.0.29"]
+        assert inputs["machine_2"]['ip'] in ["10.20.0.28", "10.20.0.29"]
+        assert inputs["machine_1"]['ip'] != inputs["machine_2"]['ip']
+
+    def test_check_machine_ips_with_invalid_ip(self):
+        test_class = Env_setup()
+        mock_ips = mock.Mock(return_value=["10.20.0.28", "10.20.0.29"])
+        test_class.fetch_compute_ips = mock_ips
+        inputs = {"machine_1": {"ip": "10.20.0.3", "pw": "", "role": "host"},
+                  "machine_2": {"ip": "10.20.0.4", "pw": "", "role": "host"}}
+        with pytest.raises(RuntimeError):
+            test_class.check_machine_ips(inputs)