diff options
author | Peter Bandzi <pbandzi@cisco.com> | 2015-07-21 16:31:40 +0200 |
---|---|---|
committer | Peter Bandzi <pbandzi@cisco.com> | 2015-07-22 10:00:04 +0200 |
commit | 2beb18fbd56e7474e6da103634ce1feb697a4965 (patch) | |
tree | c45cf7109ab6be7ff281676f565e4b506720e0d0 | |
parent | 85b729b515037043e21bbbcf3128045af1979c5e (diff) |
Script for reconfiguring UCS network
Script will reconfigure POD-2 network for foreman or fuel
Networ is specified in yaml file.
Template must be created on UCS.
JIRA: OCTO-109
Change-Id: I375a387c7607eb5dea126812569d8e19fda0c5c0
Signed-off-by: Peter Bandzi <pbandzi@cisco.com>
-rwxr-xr-x | utils/lab-reconfiguration/create_venv.sh | 35 | ||||
-rw-r--r-- | utils/lab-reconfiguration/foreman.yaml | 14 | ||||
-rw-r--r-- | utils/lab-reconfiguration/fuel.yaml | 8 | ||||
-rwxr-xr-x | utils/lab-reconfiguration/reconfigUcsNet.py | 180 | ||||
-rw-r--r-- | utils/lab-reconfiguration/requirements.pip | 2 |
5 files changed, 239 insertions, 0 deletions
diff --git a/utils/lab-reconfiguration/create_venv.sh b/utils/lab-reconfiguration/create_venv.sh new file mode 100755 index 000000000..19d9b49c4 --- /dev/null +++ b/utils/lab-reconfiguration/create_venv.sh @@ -0,0 +1,35 @@ +#!/bin/bash -e + +# Script checks that venv exists. If it doesn't it will be created +# It requires python2.7 and virtualenv packages installed + +BASEDIR=`dirname $0` + +function venv_install() { + if command -v virtualenv-2.7; then + virtualenv-2.7 $1 + elif command -v virtualenv2; then + virtualenv2 $1 + elif command -v virtualenv; then + virtualenv $1 + else + echo Cannot find virtualenv command. + return 1 + fi +} + +# exit when something goes wrong during venv install +set -e +if [ ! -d "$BASEDIR/venv" ]; then + venv_install $BASEDIR/venv + echo "Virtualenv created." +fi + +if [ ! -f "$BASEDIR/venv/updated" -o $BASEDIR/requirements.pip -nt $BASEDIR/venv/updated ]; then + source $BASEDIR/venv/bin/activate + pip install -r $BASEDIR/requirements.pip + touch $BASEDIR/venv/updated + echo "Requirements installed." + deactivate +fi +set +e diff --git a/utils/lab-reconfiguration/foreman.yaml b/utils/lab-reconfiguration/foreman.yaml new file mode 100644 index 000000000..ad91ba911 --- /dev/null +++ b/utils/lab-reconfiguration/foreman.yaml @@ -0,0 +1,14 @@ +# Vnic configuration for foreman deploy + +eth0: + order: 1 + template: foreman-control +eth1: + order: 2 + template: foreman-private +eth2: + order: 3 + template: foreman-public +eth3: + order: 4 + template: foreman-storage diff --git a/utils/lab-reconfiguration/fuel.yaml b/utils/lab-reconfiguration/fuel.yaml new file mode 100644 index 000000000..3f31939e9 --- /dev/null +++ b/utils/lab-reconfiguration/fuel.yaml @@ -0,0 +1,8 @@ +# Vnic configuration for fuel deploy + +eth0: + order: 1 + template: fuel-public +eth1: + order: 2 + template: fuel-tagged diff --git a/utils/lab-reconfiguration/reconfigUcsNet.py b/utils/lab-reconfiguration/reconfigUcsNet.py new file mode 100755 index 000000000..8adace00b --- /dev/null +++ b/utils/lab-reconfiguration/reconfigUcsNet.py @@ -0,0 +1,180 @@ +#!/usr/bin/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. + +# This script reconfigure UCSM vnics for varios OPNFV deployers +# Usage: reconfigUcsNet.py [options] +# +# Options: +# -h, --help show this help message and exit +# -i IP, --ip=IP [Mandatory] UCSM IP Address +# -u USERNAME, --username=USERNAME +# [Mandatory] Account Username for UCSM Login +# -p PASSWORD, --password=PASSWORD +# [Mandatory] Account Password for UCSM Login +# -f FILE, --file=FILE +# [Optional] Yaml file with network config you want to set for POD +# If not present only current network config will be printed +# + +import getpass +import optparse +import platform +import yaml +from UcsSdk import * +from collections import defaultdict + + +def getpassword(prompt): + if platform.system() == "Linux": + return getpass.unix_getpass(prompt=prompt) + elif platform.system() == "Windows" or platform.system() == "Microsoft": + return getpass.win_getpass(prompt=prompt) + else: + return getpass.getpass(prompt=prompt) + + +def get_servers(handle=None): + """ + Return list of servers + """ + orgObj = handle.GetManagedObject(None, OrgOrg.ClassId(), {OrgOrg.DN : "org-root"})[0] + servers = handle.GetManagedObject(orgObj, LsServer.ClassId()) + for server in servers: + if server.Type == 'instance' and "POD-2" in server.Dn: + yield server + +def get_vnics(handle=None, server=None): + """ + Return list of vnics for given server + """ + vnics = handle.ConfigResolveChildren(VnicEther.ClassId(), server.Dn, None, YesOrNo.TRUE) + return vnics.OutConfigs.GetChild() + + +def get_network_config(handle=None): + """ + Print current network config + """ + print "\nCURRENT NETWORK CONFIG:" + for server in get_servers(handle): + print ' {}'.format(server.Name) + for vnic in get_vnics(handle, server): + print ' {}'.format(vnic.Name) + print ' {}'.format(vnic.Addr) + vnicIfs = handle.ConfigResolveChildren(VnicEtherIf.ClassId(), vnic.Dn, None, YesOrNo.TRUE) + for vnicIf in vnicIfs.OutConfigs.GetChild(): + print ' Vlan: {}'.format(vnicIf.Vnet) + + +def add_interface(handle=None, lsServerDn=None, vnicEther=None, templName=None, order=None): + """ + Add interface to server specified by server.DN name + """ + print " Adding interface: {}, template: {}, server.Dn: {}".format(vnicEther, templName, lsServerDn) + obj = handle.GetManagedObject(None, LsServer.ClassId(), {LsServer.DN:lsServerDn}) + vnicEtherDn = lsServerDn + "/ether-" + vnicEther + params = { + VnicEther.STATS_POLICY_NAME: "default", + VnicEther.NAME: vnicEther, + VnicEther.DN: vnicEtherDn, + VnicEther.SWITCH_ID: "A-B", + VnicEther.ORDER: order, + "adminHostPort": "ANY", + VnicEther.ADMIN_VCON: "any", + VnicEther.NW_TEMPL_NAME: templName, + VnicEther.MTU: "1500"} + handle.AddManagedObject(obj, VnicEther.ClassId(), params, True) + + +def remove_interface(handle=None, vnicEtherDn=None): + """ + Remove interface specified by Distinguished Name (vnicEtherDn) + """ + print " Removing interface: {}".format(vnicEtherDn) + obj = handle.GetManagedObject(None, VnicEther.ClassId(), {VnicEther.DN:vnicEtherDn}) + handle.RemoveManagedObject(obj) + + +def read_yaml_file(yamlFile): + """ + Read vnic config from yaml file + """ + # TODO: add check if vnic templates specified in file exist on UCS + with open(yamlFile, 'r') as stream: + return yaml.load(stream) + + +def set_network(handle=None, yamlFile=None): + """ + Configure VLANs on POD according specified network + """ + # add interfaces and bind them with vNIC templates + # TODO: make sure MAC address for admin is still same + print "\nRECONFIGURING VNICs..." + network = read_yaml_file(yamlFile) + for server in get_servers(handle): + for iface, data in network.iteritems(): + add_interface(handle, server.Dn, iface, data['template'], data['order']) + # Remove other interfaces which have not assigned required vnic template + vnics = get_vnics(handle, server) + for vnic in vnics: + if not any(data['template'] in vnic.OperNwTemplName for iface, data in network.iteritems()): + remove_interface(handle, vnic.Dn) + print " {} removed, template: {}".format(vnic.Name, vnic.OperNwTemplName) + + +if __name__ == "__main__": + # Latest urllib2 validate certs by default + # The process wide "revert to the old behaviour" hook is to monkeypatch the ssl module + # https://bugs.python.org/issue22417 + import ssl + if hasattr(ssl, '_create_unverified_context'): + ssl._create_default_https_context = ssl._create_unverified_context + try: + handle = UcsHandle() + parser = optparse.OptionParser() + parser.add_option('-i', '--ip',dest="ip", + help="[Mandatory] UCSM IP Address") + parser.add_option('-u', '--username',dest="userName", + help="[Mandatory] Account Username for UCSM Login") + parser.add_option('-p', '--password',dest="password", + help="[Mandatory] Account Password for UCSM Login") + parser.add_option('-f', '--file',dest="yamlFile", + help="[Optional] Yaml file contains network config you want to set on UCS POD1") + (options, args) = parser.parse_args() + + if not options.ip: + parser.print_help() + parser.error("Provide UCSM IP Address") + if not options.userName: + parser.print_help() + parser.error("Provide UCSM UserName") + if not options.password: + options.password=getpassword("UCSM Password:") + + handle.Login(options.ip, options.userName, options.password) + + if (options.yamlFile != None): + print options.yamlFile + set_network(handle, options.yamlFile) + get_network_config(handle) + + handle.Logout() + + except Exception, err: + handle.Logout() + print "Exception:", str(err) + import traceback, sys + print '-'*60 + traceback.print_exc(file=sys.stdout) + print '-'*60 diff --git a/utils/lab-reconfiguration/requirements.pip b/utils/lab-reconfiguration/requirements.pip new file mode 100644 index 000000000..8cd1db0ba --- /dev/null +++ b/utils/lab-reconfiguration/requirements.pip @@ -0,0 +1,2 @@ +UcsSdk==0.8.2.2 +PyYAML |