Fail when Nova API, Nova network and Swift hosts are not set as IP addresses
- Refactor value validator system - cleanup, pep8, documentation, tests and allow multiple validators for each parameter Fixes: rhbz#886603 Change-Id: I1bb3486ed7168bda2855ee877e32423033620ecc
This commit is contained in:
parent
f6a0b0781b
commit
a3d2a6d616
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
*.pyc
|
*.py[co]
|
||||||
*.swp
|
*.swp
|
||||||
*.log
|
*.log
|
||||||
|
.tox
|
||||||
|
packstack.egg-info
|
||||||
|
@ -1,411 +1,207 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
contains all available validation functions
|
Contains all core validation functions.
|
||||||
"""
|
"""
|
||||||
import common_utils as utils
|
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
import output_messages
|
|
||||||
import basedefs
|
|
||||||
import socket
|
|
||||||
import types
|
|
||||||
import traceback
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import re
|
||||||
|
import socket
|
||||||
|
import logging
|
||||||
import tempfile
|
import tempfile
|
||||||
from setup_controller import Controller
|
import traceback
|
||||||
|
|
||||||
|
import basedefs
|
||||||
|
import common_utils as utils
|
||||||
|
|
||||||
|
from .setup_controller import Controller
|
||||||
|
from .exceptions import ParamValidationError
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ('ParamValidationError', 'validate_integer',
|
||||||
|
'validate_regexp', 'validate_port', 'validate_not_empty',
|
||||||
|
'validate_options', 'validate_ip', 'validate_multi_ip',
|
||||||
|
'validate_file', 'validate_ping', 'validate_ssh',
|
||||||
|
'validate_multi_ssh')
|
||||||
|
|
||||||
# XXX: Validators should probably only validate (pass on success,
|
|
||||||
# raise appropriate exception on failure). We should move logging
|
|
||||||
# and printing probably to run_setup (preferably to single place)
|
|
||||||
|
|
||||||
def validateDirSize(path, size):
|
def validate_integer(param, options=None):
|
||||||
availableSpace = utils.getAvailableSpace(_getBasePath(path))
|
"""
|
||||||
if availableSpace < size:
|
Raises ParamValidationError if given param is not integer.
|
||||||
print output_messages.INFO_VAL_PATH_SPACE % (path,
|
"""
|
||||||
utils.transformUnits(availableSpace),
|
options = options or []
|
||||||
utils.transformUnits(size))
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validateInteger(param, options=[]):
|
|
||||||
try:
|
try:
|
||||||
int(param)
|
int(param)
|
||||||
return True
|
except ValueError:
|
||||||
except:
|
logging.debug('validate_integer(%s, options=%s) failed.' %
|
||||||
logging.warn("validateInteger('%s') - failed" %(param))
|
(param, options))
|
||||||
print output_messages.INFO_VAL_NOT_INTEGER
|
msg = 'Given value is not an integer: %s'
|
||||||
return False
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
def validateRe(param, options=[]):
|
|
||||||
|
def validate_regexp(param, options=None):
|
||||||
|
"""
|
||||||
|
Raises ParamValidationError if given param doesn't match at least
|
||||||
|
one of regular expressions given in options.
|
||||||
|
"""
|
||||||
|
options = options or []
|
||||||
for regex in options:
|
for regex in options:
|
||||||
if re.search(regex, param):
|
if re.search(regex, param):
|
||||||
return True
|
break
|
||||||
logging.warn("validateRe('%s') - failed" %(param))
|
else:
|
||||||
return False
|
logging.debug('validate_regexp(%s, options=%s) failed.' %
|
||||||
|
(param, options))
|
||||||
|
msg = 'Given value does not match required regular expresion: %s'
|
||||||
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
def validatePort(param, options = []):
|
|
||||||
#TODO: add actual port check with socket open
|
def validate_port(param, options=None):
|
||||||
logging.debug("Validating %s as a valid TCP Port" % (param))
|
"""
|
||||||
minVal = 0
|
Raises ParamValidationError if given param is not a decimal number
|
||||||
controller = Controller()
|
in range (0, 65535).
|
||||||
isProxyEnabled = utils.compareStrIgnoreCase(controller.CONF["OVERRIDE_HTTPD_CONFIG"], "yes")
|
"""
|
||||||
if not isProxyEnabled:
|
options = options or []
|
||||||
minVal = 1024
|
validate_integer(param, options)
|
||||||
if not validateInteger(param, options):
|
|
||||||
return False
|
|
||||||
port = int(param)
|
port = int(param)
|
||||||
if not (port > minVal and port < 65535) :
|
if not (port >= 0 and port < 65535):
|
||||||
logging.warn(output_messages.INFO_VAL_PORT_NOT_RANGE %(minVal))
|
logging.debug('validate_port(%s, options=%s) failed.' %
|
||||||
print output_messages.INFO_VAL_PORT_NOT_RANGE %(minVal)
|
(param, options))
|
||||||
return False
|
msg = 'Given value is outside the range of (0, 65535): %s'
|
||||||
(portOpen, process, pid) = utils.isTcpPortOpen(param)
|
raise ParamValidationError(msg % param)
|
||||||
if portOpen:
|
|
||||||
logging.warn(output_messages.INFO_VAL_PORT_OCCUPIED % (param, process, pid))
|
|
||||||
print output_messages.INFO_VAL_PORT_OCCUPIED % (param, process, pid)
|
|
||||||
return False
|
|
||||||
if isProxyEnabled and not checkAndSetHttpdPortPolicy(param):
|
|
||||||
logging.warn(output_messages.INFO_VAL_FAILED_ADD_PORT_TO_HTTP_POLICY, port)
|
|
||||||
print output_messages.INFO_VAL_FAILED_ADD_PORT_TO_HTTP_POLICY % port
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def checkAndSetHttpdPortPolicy(port):
|
|
||||||
def parsePorts(portsStr):
|
|
||||||
ports = []
|
|
||||||
for part in portsStr.split(","):
|
|
||||||
part = part.strip().split("-")
|
|
||||||
if len(part) > 1:
|
|
||||||
for port in range(int(part[0]),int(part[1])):
|
|
||||||
ports.append(port)
|
|
||||||
else:
|
|
||||||
ports.append(int(part[0]))
|
|
||||||
return ports
|
|
||||||
|
|
||||||
newPort = int(port)
|
|
||||||
cmd = [
|
|
||||||
basedefs.EXEC_SEMANAGE, "port", "-l",
|
|
||||||
]
|
|
||||||
out, rc = utils.execCmd(cmdList=cmd) #, "-t", "http_port_t"])
|
|
||||||
if rc:
|
|
||||||
return False
|
|
||||||
httpPortsList = []
|
|
||||||
pattern = re.compile("^http_port_t\s*tcp\s*([0-9, \-]*)$")
|
|
||||||
for line in out.splitlines():
|
|
||||||
httpPortPolicy = re.match(pattern, line)
|
|
||||||
if httpPortPolicy:
|
|
||||||
httpPortsList = parsePorts(httpPortPolicy.groups()[0])
|
|
||||||
logging.debug("http_port_t = %s"%(httpPortsList))
|
|
||||||
if newPort in httpPortsList:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
cmd = [
|
|
||||||
basedefs.EXEC_SEMANAGE,
|
|
||||||
"port",
|
|
||||||
"-a",
|
|
||||||
"-t", "http_port_t",
|
|
||||||
"-p", "tcp",
|
|
||||||
"%d"%(newPort),
|
|
||||||
]
|
|
||||||
out, rc = utils.execCmd(cmdList=cmd, failOnError=False, usePipeFiles=True)
|
|
||||||
if rc:
|
|
||||||
logging.error(out)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
def validate_not_empty(param, options=None):
|
||||||
def validateRemotePort(param, options = []):
|
|
||||||
#Validate that the port is an integer betweeen 1024 and 65535
|
|
||||||
logging.debug("Validating %s as a valid TCP Port" % (param))
|
|
||||||
if validateInteger(param, options):
|
|
||||||
port = int(param)
|
|
||||||
if (port > 0 and port < 65535):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logging.warn("validatePort('%s') - failed" %(param))
|
|
||||||
print output_messages.INFO_VAL_PORT_NOT_RANGE
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validateStringNotEmpty(param, options=[]):
|
|
||||||
if type(param) != types.StringType or len(param) == 0:
|
|
||||||
logging.warn("validateStringNotEmpty('%s') - failed" %(param))
|
|
||||||
print output_messages.INFO_VAL_STRING_EMPTY %(param)
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validateOptions(param, options=[]):
|
|
||||||
logging.info("Validating %s as part of %s"%(param, options))
|
|
||||||
if not validateStringNotEmpty(param, options):
|
|
||||||
return False
|
|
||||||
if "yes" in options and param.lower() == "y":
|
|
||||||
return True
|
|
||||||
if "no" in options and param.lower() == "n":
|
|
||||||
return True
|
|
||||||
if param.lower() in [option.lower() for option in options]:
|
|
||||||
return True
|
|
||||||
print output_messages.INFO_VAL_NOT_IN_OPTIONS % (", ".join(options))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validateDomain(param, options=[]):
|
|
||||||
"""
|
"""
|
||||||
Validate domain name
|
Raises ParamValidationError if given param is empty.
|
||||||
"""
|
"""
|
||||||
logging.info("validating %s as a valid domain string" % (param))
|
options = options or []
|
||||||
(errMsg, rc) = _validateString(param, 1, 1024, "^[\w\-\_]+\.[\w\.\-\_]+\w+$")
|
if not param and param is not False:
|
||||||
|
logging.debug('validate_not_empty(%s, options=%s) failed.' %
|
||||||
|
(param, options))
|
||||||
|
msg = 'Given value is not allowed: %s'
|
||||||
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
# Right now we print a generic error, might want to change it in the future
|
|
||||||
if rc != 0:
|
|
||||||
print output_messages.INFO_VAL_NOT_DOMAIN
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validateUser(param, options=[]):
|
def validate_options(param, options=None):
|
||||||
"""
|
"""
|
||||||
Validate Auth Username
|
Raises ParamValidationError if given param is not member of options.
|
||||||
Setting a logical max value of 256
|
|
||||||
"""
|
"""
|
||||||
logging.info("validating %s as a valid user name" % (param))
|
options = options or []
|
||||||
(errMsg, rc) = _validateString(param, 1, 256, "^\w[\w\.\-\_\%\@]{2,}$")
|
|
||||||
|
|
||||||
# Right now we print a generic error, might want to change it in the future
|
validate_not_empty(param, options)
|
||||||
if rc != 0:
|
if param not in options:
|
||||||
print output_messages.INFO_VAL_NOT_USER
|
logging.debug('validate_options(%s, options=%s) failed.' %
|
||||||
return False
|
(param, options))
|
||||||
else:
|
msg = 'Given value is not is allowed values %s: %s'
|
||||||
return True
|
raise ParamValidationError(msg % (options, param))
|
||||||
|
|
||||||
def validateRemoteHost(param, options=[]):
|
|
||||||
""" Validate that the we are working with remote DB host
|
def validate_ip(param, options=None):
|
||||||
"""
|
"""
|
||||||
# If we received localhost, use default flow.
|
Raises ParamValidationError if given parameter value is not in IPv4
|
||||||
# If not local, REMOTE_DB group is run.
|
or IPv6 address.
|
||||||
# It means returning True if remote, and False if local
|
"""
|
||||||
|
for family in (socket.AF_INET, socket.AF_INET6):
|
||||||
if "DB_REMOTE_INSTALL" in param.keys() and param["DB_REMOTE_INSTALL"] == "remote":
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validateFQDN(param, options=[]):
|
|
||||||
logging.info("Validating %s as a FQDN"%(param))
|
|
||||||
if not validateDomain(param,options):
|
|
||||||
return False
|
|
||||||
try:
|
try:
|
||||||
#get set of IPs
|
socket.inet_pton(family, param)
|
||||||
ipAddresses = utils.getConfiguredIps()
|
break
|
||||||
if len(ipAddresses) < 1:
|
except socket.error:
|
||||||
logging.error("Could not find any configured IP address on the host")
|
continue
|
||||||
raise Exception(output_messages.ERR_EXP_CANT_FIND_IP)
|
|
||||||
|
|
||||||
#resolve fqdn
|
|
||||||
pattern = 'Address: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
|
|
||||||
resolvedAddresses = _getPatternFromNslookup(param, pattern)
|
|
||||||
if len(resolvedAddresses) < 1:
|
|
||||||
logging.error("Failed to resolve %s"%(param))
|
|
||||||
print output_messages.ERR_DIDNT_RESOLVED_IP%(param)
|
|
||||||
return False
|
|
||||||
|
|
||||||
#string is generated here since we use it in all latter error messages
|
|
||||||
prettyString = " ".join(["%s"%string for string in resolvedAddresses])
|
|
||||||
|
|
||||||
#compare found IP with list of local IPs and match.
|
|
||||||
if not resolvedAddresses.issubset(ipAddresses):
|
|
||||||
logging.error("the following address(es): %s are not configured on this host"%(prettyString))
|
|
||||||
#different grammar for plural and single
|
|
||||||
if len(resolvedAddresses) > 1:
|
|
||||||
print output_messages.ERR_IPS_NOT_CONFIGED%(prettyString, param)
|
|
||||||
else:
|
else:
|
||||||
print output_messages.ERR_IPS_NOT_CONFIGED_ON_INT%(prettyString, param)
|
logging.debug('validate_ip(%s, options=%s) failed.' %
|
||||||
return False
|
(param, options))
|
||||||
|
msg = 'Given host is not in IP address format: %s'
|
||||||
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
#reverse resolved IP and compare with given fqdn
|
|
||||||
counter = 0
|
|
||||||
pattern = '[\w\.-]+\s+name\s\=\s([\w\.\-]+)\.'
|
|
||||||
for address in resolvedAddresses:
|
|
||||||
addressSet = _getPatternFromNslookup(address, pattern)
|
|
||||||
reResolvedAddress = None
|
|
||||||
if len(addressSet) > 0:
|
|
||||||
reResolvedAddress = addressSet.pop()
|
|
||||||
if reResolvedAddress == param:
|
|
||||||
counter += 1
|
|
||||||
else:
|
|
||||||
logging.warn("%s did not reverse-resolve into %s"%(address,param))
|
|
||||||
if counter < 1:
|
|
||||||
logging.error("The following addresses: %s did not reverse resolve into %s"%(prettyString, param))
|
|
||||||
#different grammar for plural and single
|
|
||||||
if len(resolvedAddresses) > 1:
|
|
||||||
print output_messages.ERR_IPS_HAS_NO_PTR%(prettyString, param)
|
|
||||||
else:
|
|
||||||
print output_messages.ERR_IP_HAS_NO_PTR%(prettyString, param)
|
|
||||||
return False
|
|
||||||
|
|
||||||
#conditions passed
|
def validate_multi_ip(param, options=None):
|
||||||
return True
|
|
||||||
except:
|
|
||||||
logging.error(traceback.format_exc())
|
|
||||||
raise
|
|
||||||
|
|
||||||
def validateFile(param, options=[]):
|
|
||||||
"""
|
"""
|
||||||
Check that provided param is a file
|
Raises ParamValidationError if comma separated IP addresses given
|
||||||
|
parameter value are in IPv4 or IPv6 aformat.
|
||||||
"""
|
"""
|
||||||
if not validateStringNotEmpty(param):
|
for host in param.split(','):
|
||||||
return False
|
host, device = host.split('/', 1)
|
||||||
|
validate_ip(host.strip(), options)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_file(param, options=None):
|
||||||
|
"""
|
||||||
|
Raises ParamValidationError if provided file in param does not exist.
|
||||||
|
"""
|
||||||
|
options = options or []
|
||||||
|
validate_not_empty(param)
|
||||||
|
|
||||||
if not os.path.isfile(param):
|
if not os.path.isfile(param):
|
||||||
print "\n" + output_messages.ERR_FILE + ".\n"
|
logging.debug('validate_file(%s, options=%s) failed.' %
|
||||||
return False
|
(param, options))
|
||||||
|
msg = 'Given file does not exist: %s'
|
||||||
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validatePing(param, options=[]):
|
def validate_ping(param, options=None):
|
||||||
"""
|
"""
|
||||||
Check that provided host answers to ping
|
Raises ParamValidationError if provided host does not answer to ICMP
|
||||||
|
echo request.
|
||||||
"""
|
"""
|
||||||
if validateStringNotEmpty(param):
|
options = options or []
|
||||||
cmd = [
|
validate_not_empty(param)
|
||||||
"/bin/ping",
|
|
||||||
"-c", "1",
|
cmd = ["/bin/ping", "-c", "1", str(param)]
|
||||||
"%s" % param,
|
|
||||||
]
|
|
||||||
out, rc = utils.execCmd(cmdList=cmd)
|
out, rc = utils.execCmd(cmdList=cmd)
|
||||||
if rc == 0:
|
if rc != 0:
|
||||||
return True
|
logging.debug('validate_ping(%s, options=%s) failed.' %
|
||||||
|
(param, options))
|
||||||
|
msg = 'Given host is unreachable: %s'
|
||||||
|
raise ParamValidationError(msg % param)
|
||||||
|
|
||||||
print "\n" + output_messages.ERR_PING + " %s .\n"%param
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validateMultiPing(param, options=[]):
|
def validate_multi_ping(param, options=None):
|
||||||
if validateStringNotEmpty(param):
|
|
||||||
hosts = param.split(",")
|
|
||||||
for host in hosts:
|
|
||||||
if validatePing(host.strip()) == False:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
print "\n" + output_messages.ERR_PING + ".\n"
|
|
||||||
return False
|
|
||||||
|
|
||||||
_testedPorts = []
|
|
||||||
def validatePort(host, port):
|
|
||||||
"""
|
"""
|
||||||
Check that provided host is listening on provided port
|
Raises ParamValidationError if comma separated host given in param
|
||||||
|
do not answer to ICMP echo request.
|
||||||
"""
|
"""
|
||||||
key = "%s:%d"%(host, port)
|
options = options or []
|
||||||
# No need to keep checking the same port multiple times
|
validate_not_empty(param)
|
||||||
if key in _testedPorts:
|
for host in param.split(","):
|
||||||
return True
|
validate_ping(host.strip())
|
||||||
|
|
||||||
|
|
||||||
|
_tested_ports = []
|
||||||
|
def touch_port(host, port):
|
||||||
|
"""
|
||||||
|
Check that provided host is listening on provided port.
|
||||||
|
"""
|
||||||
|
key = "%s:%d" % (host, port)
|
||||||
|
if key in _tested_ports:
|
||||||
|
return
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
try:
|
|
||||||
s.connect((host, port))
|
s.connect((host, port))
|
||||||
s.shutdown(socket.SHUT_RDWR)
|
s.shutdown(socket.SHUT_RDWR)
|
||||||
s.close()
|
s.close()
|
||||||
except socket.error as msg:
|
_tested_ports.append(key)
|
||||||
return False
|
|
||||||
_testedPorts.append(key)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validateSSH(param, options=[]):
|
|
||||||
|
def validate_ssh(param, options=None):
|
||||||
"""
|
"""
|
||||||
Check that provided host is listening on port 22
|
Raises ParamValidationError if provided host does not listen
|
||||||
|
on port 22.
|
||||||
"""
|
"""
|
||||||
if validatePort(param.strip(), 22):
|
options = options or []
|
||||||
return True
|
|
||||||
print "\n" + output_messages.ERR_SSH%param
|
|
||||||
return False
|
|
||||||
|
|
||||||
def validateMultiSSH(param, options=[]):
|
|
||||||
if validateStringNotEmpty(param):
|
|
||||||
hosts = param.split(",")
|
|
||||||
for host in hosts:
|
|
||||||
if validateSSH(host) == False:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
print "\n" + output_messages.ERR_SSH%param + ".\n"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _validateString(string, minLen, maxLen, regex=".*"):
|
|
||||||
"""
|
|
||||||
Generic func to verify a string
|
|
||||||
match its min/max length
|
|
||||||
and doesn't contain illegal chars
|
|
||||||
|
|
||||||
The func returns various return codes according to the error
|
|
||||||
plus a default error message
|
|
||||||
the calling func can decide if to use to default error msg
|
|
||||||
or to use a more specific one according the RC.
|
|
||||||
Return codes:
|
|
||||||
1 - string length is less than min
|
|
||||||
2 - string length is more tham max
|
|
||||||
3 - string contain illegal chars
|
|
||||||
0 - success
|
|
||||||
"""
|
|
||||||
# String length is less than minimum allowed
|
|
||||||
if len(string) < minLen:
|
|
||||||
msg = output_messages.INFO_STRING_LEN_LESS_THAN_MIN % (minLen)
|
|
||||||
return(msg, 1)
|
|
||||||
# String length is more than max allowed
|
|
||||||
elif len(string) > maxLen:
|
|
||||||
msg = output_messages.INFO_STRING_EXCEEDS_MAX_LENGTH % (maxLen)
|
|
||||||
return(msg, 2)
|
|
||||||
# String contains illegal chars
|
|
||||||
elif not utils.verifyStringFormat(string, regex):
|
|
||||||
return(output_messages.INFO_STRING_CONTAINS_ILLEGAL_CHARS, 3)
|
|
||||||
else:
|
|
||||||
# Success
|
|
||||||
return (None, 0)
|
|
||||||
|
|
||||||
def _getPatternFromNslookup(address, pattern):
|
|
||||||
rePattern = re.compile(pattern)
|
|
||||||
addresses = set()
|
|
||||||
output = utils.nslookup(address)
|
|
||||||
list = output.splitlines()
|
|
||||||
#do not go over the first 2 lines in nslookup output
|
|
||||||
for line in list[2:]:
|
|
||||||
found = rePattern.search(line)
|
|
||||||
if found:
|
|
||||||
foundAddress = found.group(1)
|
|
||||||
logging.debug("%s resolved into %s"%(address, foundAddress))
|
|
||||||
addresses.add(foundAddress)
|
|
||||||
return addresses
|
|
||||||
|
|
||||||
def _getBasePath(path):
|
|
||||||
if os.path.exists(path):
|
|
||||||
return path
|
|
||||||
|
|
||||||
# Iterate up in the tree structure until we get an
|
|
||||||
# existing path
|
|
||||||
return _getBasePath(os.path.dirname(path.rstrip("/")))
|
|
||||||
|
|
||||||
def _isPathWriteable(path):
|
|
||||||
try:
|
try:
|
||||||
logging.debug("attempting to write temp file to %s" % (path))
|
touch_port(param.strip(), 22)
|
||||||
tempfile.TemporaryFile(dir=path)
|
except socket.error:
|
||||||
return True
|
logging.debug('validate_ssh(%s, options=%s) failed.' %
|
||||||
except:
|
(param, options))
|
||||||
logging.warning(traceback.format_exc())
|
msg = 'Given host does not listen on port 22: %s'
|
||||||
logging.warning("%s is not writeable" % path)
|
raise ParamValidationError(msg % param)
|
||||||
return False
|
|
||||||
|
|
||||||
def r_validateIF(server, device):
|
|
||||||
""" Validate that a network interface exists on a remote host """
|
|
||||||
server.append("ifconfig %s || ( echo Device %s does not exist && exit 1 )"%(device, device))
|
|
||||||
|
|
||||||
def r_validateDevice(server, device=None):
|
def validate_multi_ssh(param, options=None):
|
||||||
if device:
|
"""
|
||||||
# the device MUST exist
|
Raises ParamValidationError if comma separated host provided
|
||||||
server.append('ls -l /dev/%s'%device)
|
in param do not listen on port 22.
|
||||||
|
"""
|
||||||
# if it is not mounted then we can use it
|
options = options or []
|
||||||
server.append('grep "/dev/%s " /proc/self/mounts || exit 0'%device)
|
validate_not_empty(param)
|
||||||
|
for host in param.split(","):
|
||||||
# if it is mounted then the mount point has to be in /srv/node
|
validate_ssh(host)
|
||||||
server.append('grep "/dev/%s /srv/node" /proc/self/mounts && exit 0'%device)
|
|
||||||
|
|
||||||
# if we got here without exiting then we can't use this device
|
|
||||||
server.append('exit 1')
|
|
||||||
return False
|
|
||||||
|
@ -20,22 +20,25 @@ class PackStackError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class MissingRequirements(PackStackError):
|
class MissingRequirements(PackStackError):
|
||||||
"""Raised when minimum install requirements are not met"""
|
"""Raised when minimum install requirements are not met."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InstallError(PackStackError):
|
class InstallError(PackStackError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class FlagValidationError(InstallError):
|
class FlagValidationError(InstallError):
|
||||||
|
"""Raised when single flag validation fails."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ParamValidationError(InstallError):
|
||||||
|
"""Raised when parameter value validation fails."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PluginError(PackStackError):
|
class PluginError(PackStackError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ParamProcessingError(PluginError):
|
class ParamProcessingError(PluginError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ INFO_VAL_PORT_OCCUPIED="Error: TCP Port %s is already open by %s (pid: %s)"
|
|||||||
INFO_VAL_PORT_OCCUPIED_BY_JBOSS="Error: TCP Port %s is used by JBoss"
|
INFO_VAL_PORT_OCCUPIED_BY_JBOSS="Error: TCP Port %s is used by JBoss"
|
||||||
INFO_VAL_PASSWORD_DONT_MATCH="Error: passwords don't match"
|
INFO_VAL_PASSWORD_DONT_MATCH="Error: passwords don't match"
|
||||||
|
|
||||||
INFO_VAL_IS_HOSTNAME = ("Packstack changed given hostname %s to IP "
|
INFO_CHANGED_VALUE = ("Packstack changed given value %s to required "
|
||||||
"address %s.")
|
"value %s")
|
||||||
WARN_VAL_IS_HOSTNAME = ("Warning: Packstack failed to change given "
|
WARN_VAL_IS_HOSTNAME = ("Warning: Packstack failed to change given "
|
||||||
"hostname %s to IP address. Note that some "
|
"hostname %s to IP address. Note that some "
|
||||||
"services might not run correctly when hostname"
|
"services might not run correctly when hostname"
|
||||||
|
@ -17,7 +17,7 @@ import common_utils as utils
|
|||||||
import engine_processors as process
|
import engine_processors as process
|
||||||
import engine_validators as validate
|
import engine_validators as validate
|
||||||
import output_messages
|
import output_messages
|
||||||
from .exceptions import FlagValidationError
|
from .exceptions import FlagValidationError, ParamValidationError
|
||||||
|
|
||||||
from setup_controller import Controller
|
from setup_controller import Controller
|
||||||
|
|
||||||
@ -77,7 +77,8 @@ def _getInputFromUser(param):
|
|||||||
message = StringIO()
|
message = StringIO()
|
||||||
message.write(param.getKey("PROMPT"))
|
message.write(param.getKey("PROMPT"))
|
||||||
|
|
||||||
if not param.getKey("VALIDATION_FUNC") == validate.validateRe \
|
validators = param.getKey("VALIDATORS") or []
|
||||||
|
if validate.validate_regexp not in validators \
|
||||||
and param.getKey("OPTION_LIST"):
|
and param.getKey("OPTION_LIST"):
|
||||||
message.write(" [%s]" % "|".join(param.getKey("OPTION_LIST")))
|
message.write(" [%s]" % "|".join(param.getKey("OPTION_LIST")))
|
||||||
|
|
||||||
@ -99,62 +100,33 @@ def _getInputFromUser(param):
|
|||||||
userInput = param.getKey("DEFAULT_VALUE")
|
userInput = param.getKey("DEFAULT_VALUE")
|
||||||
|
|
||||||
# Param processing
|
# Param processing
|
||||||
try:
|
userInput = process_param_value(param, userInput)
|
||||||
logging.debug("Processing value of parameter "
|
|
||||||
"%s." % param.getKey("CONF_NAME"))
|
|
||||||
processFunc = param.getKey("PROCESSOR_FUNC")
|
|
||||||
try:
|
|
||||||
processArgs = param.getKey("PROCESSOR_ARGS")
|
|
||||||
except KeyError:
|
|
||||||
processArgs = None
|
|
||||||
try:
|
|
||||||
_userInput = processFunc(userInput, processArgs)
|
|
||||||
if userInput != _userInput:
|
|
||||||
msg = output_messages.INFO_VAL_IS_HOSTNAME
|
|
||||||
print msg % (userInput, _userInput)
|
|
||||||
userInput = _userInput
|
|
||||||
else:
|
|
||||||
logging.debug("Processor returned the original "
|
|
||||||
"value: %s" % _userInput)
|
|
||||||
except process.ParamProcessingError, ex:
|
|
||||||
try:
|
|
||||||
cn = param.getKey("CONF_NAME")
|
|
||||||
msg = param.getKey("PROCESSOR_MSG")
|
|
||||||
print getattr(output_messages, msg) % cn
|
|
||||||
except KeyError:
|
|
||||||
logging.debug("Value processing of parameter "
|
|
||||||
"%s failed." % param.getKey("CONF_NAME"))
|
|
||||||
except KeyError:
|
|
||||||
logging.debug("Parameter %s doesn't have value "
|
|
||||||
"processor." % param.getKey("CONF_NAME"))
|
|
||||||
|
|
||||||
# If param requires validation
|
# If param requires validation
|
||||||
if param.getKey("VALIDATION_FUNC")(userInput, param.getKey("OPTION_LIST")):
|
try:
|
||||||
if "yes" in param.getKey("OPTION_LIST") and userInput.lower() == "y":
|
validate_param_value(param, userInput)
|
||||||
userInput = "yes"
|
|
||||||
if "no" in param.getKey("OPTION_LIST") and userInput.lower() == "n":
|
|
||||||
userInput = "no"
|
|
||||||
controller.CONF[param.getKey("CONF_NAME")] = userInput
|
controller.CONF[param.getKey("CONF_NAME")] = userInput
|
||||||
loop = False
|
loop = False
|
||||||
|
except ParamValidationError:
|
||||||
|
if param.getKey("LOOSE_VALIDATION"):
|
||||||
# If validation failed but LOOSE_VALIDATION is true, ask user
|
# If validation failed but LOOSE_VALIDATION is true, ask user
|
||||||
elif param.getKey("LOOSE_VALIDATION"):
|
answer = _askYesNo("User input failed validation, "
|
||||||
answer = _askYesNo("User input failed validation, do you still wish to use it")
|
"do you still wish to use it")
|
||||||
|
loop = not answer
|
||||||
if answer:
|
if answer:
|
||||||
loop = False
|
|
||||||
controller.CONF[param.getKey("CONF_NAME")] = userInput
|
controller.CONF[param.getKey("CONF_NAME")] = userInput
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
if commandLineValues.has_key(param.getKey("CONF_NAME")):
|
if commandLineValues.has_key(param.getKey("CONF_NAME")):
|
||||||
del commandLineValues[param.getKey("CONF_NAME")]
|
del commandLineValues[param.getKey("CONF_NAME")]
|
||||||
loop = True
|
|
||||||
else:
|
else:
|
||||||
# Delete value from commandLineValues so that we will prompt the user for input
|
# Delete value from commandLineValues so that we will prompt the user for input
|
||||||
if commandLineValues.has_key(param.getKey("CONF_NAME")):
|
if commandLineValues.has_key(param.getKey("CONF_NAME")):
|
||||||
del commandLineValues[param.getKey("CONF_NAME")]
|
del commandLineValues[param.getKey("CONF_NAME")]
|
||||||
loop = True
|
loop = True
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print "" # add the new line so messages wont be displayed in the same line as the question
|
print "" # add the new line so messages wont be displayed in the same line as the question
|
||||||
raise KeyboardInterrupt
|
raise
|
||||||
except:
|
except:
|
||||||
logging.error(traceback.format_exc())
|
logging.error(traceback.format_exc())
|
||||||
raise Exception(output_messages.ERR_EXP_READ_INPUT_PARAM % (param.getKey("CONF_NAME")))
|
raise Exception(output_messages.ERR_EXP_READ_INPUT_PARAM % (param.getKey("CONF_NAME")))
|
||||||
@ -172,7 +144,7 @@ def input_param(param):
|
|||||||
confirmedParamName = param.getKey("CONF_NAME") + "_CONFIRMED"
|
confirmedParamName = param.getKey("CONF_NAME") + "_CONFIRMED"
|
||||||
confirmedParam.setKey("CONF_NAME", confirmedParamName)
|
confirmedParam.setKey("CONF_NAME", confirmedParamName)
|
||||||
confirmedParam.setKey("PROMPT", output_messages.INFO_CONF_PARAMS_PASSWD_CONFIRM_PROMPT)
|
confirmedParam.setKey("PROMPT", output_messages.INFO_CONF_PARAMS_PASSWD_CONFIRM_PROMPT)
|
||||||
confirmedParam.setKey("VALIDATION_FUNC", validate.validateStringNotEmpty)
|
confirmedParam.setKey("VALIDATORS", [validate.validate_not_empty])
|
||||||
# Now get both values from user (with existing validations
|
# Now get both values from user (with existing validations
|
||||||
while True:
|
while True:
|
||||||
_getInputFromUser(param)
|
_getInputFromUser(param)
|
||||||
@ -285,35 +257,39 @@ def maskString(str):
|
|||||||
str = str.replace(password, '*'*8)
|
str = str.replace(password, '*'*8)
|
||||||
return str
|
return str
|
||||||
|
|
||||||
def _validateParamValue(param, paramValue):
|
def validate_param_value(param, value):
|
||||||
validateFunc = param.getKey("VALIDATION_FUNC")
|
cname = param.getKey("CONF_NAME")
|
||||||
optionsList = param.getKey("OPTION_LIST")
|
logging.debug("Validating parameter %s." % cname)
|
||||||
logging.debug("validating param %s in answer file." % param.getKey("CONF_NAME"))
|
|
||||||
if not validateFunc(paramValue, optionsList):
|
|
||||||
raise Exception(output_messages.ERR_EXP_VALIDATE_PARAM % param.getKey("CONF_NAME"))
|
|
||||||
|
|
||||||
def _processParamValue(param, paramValue):
|
validators = param.getKey("VALIDATORS") or []
|
||||||
|
opt_list = param.getKey("OPTION_LIST")
|
||||||
|
for val_func in validators:
|
||||||
try:
|
try:
|
||||||
processFunc = param.getKey("PROCESSOR_FUNC")
|
val_func(value, opt_list)
|
||||||
except KeyError:
|
except ParamValidationError as ex:
|
||||||
return paramValue
|
print 'Parameter %s failed validation: %s' % (cname, ex)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def process_param_value(param, value):
|
||||||
|
_value = value
|
||||||
|
processors = param.getKey("PROCESSORS") or []
|
||||||
|
for proc_func in processors:
|
||||||
|
logging.debug("Processing value of parameter "
|
||||||
|
"%s." % param.getKey("CONF_NAME"))
|
||||||
try:
|
try:
|
||||||
processArgs = param.getKey("PROCESSOR_ARGS")
|
new_value = proc_func(_value, controller.CONF)
|
||||||
except KeyError:
|
if new_value != _value:
|
||||||
processArgs = None
|
msg = output_messages.INFO_CHANGED_VALUE
|
||||||
logging.debug("processing param %s in answer file." % param.getKey("CONF_NAME"))
|
print msg % (_value, new_value)
|
||||||
try:
|
_value = new_value
|
||||||
return processFunc(paramValue, processArgs)
|
else:
|
||||||
|
logging.debug("Processor returned the original "
|
||||||
|
"value: %s" % _value)
|
||||||
except process.ParamProcessingError, ex:
|
except process.ParamProcessingError, ex:
|
||||||
cn = param.getKey("CONF_NAME")
|
print ("Value processing of parameter %s "
|
||||||
logging.debug("processing param %s failed, falling back to "
|
"failed.\n%s" % (param.getKey("CONF_NAME"), ex))
|
||||||
"original, reason: %s" % (cn, ex))
|
raise
|
||||||
try:
|
return _value
|
||||||
msg = param.getKey("PROCESSOR_MSG")
|
|
||||||
print getattr(output_messages, msg) % cn
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
return paramValue
|
|
||||||
|
|
||||||
def _handleGroupCondition(config, conditionName, conditionValue):
|
def _handleGroupCondition(config, conditionName, conditionValue):
|
||||||
"""
|
"""
|
||||||
@ -349,8 +325,8 @@ def _loadParamFromFile(config, section, paramName):
|
|||||||
|
|
||||||
# Validate param value using its validation func
|
# Validate param value using its validation func
|
||||||
param = controller.getParamByName(paramName)
|
param = controller.getParamByName(paramName)
|
||||||
value = _processParamValue(param, value)
|
value = process_param_value(param, value)
|
||||||
_validateParamValue(param, value)
|
validate_param_value(param, value)
|
||||||
|
|
||||||
# Keep param value in our never ending global conf
|
# Keep param value in our never ending global conf
|
||||||
controller.CONF[param.getKey("CONF_NAME")] = value
|
controller.CONF[param.getKey("CONF_NAME")] = value
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
"""
|
|
||||||
Creates a Sample File
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
|
|
||||||
import engine_validators as validate
|
|
||||||
import basedefs
|
|
||||||
import common_utils as utils
|
|
||||||
|
|
||||||
# Controller object will be initialized from main flow
|
|
||||||
controller = None
|
|
||||||
|
|
||||||
logging.debug("plugin %s loaded", __name__)
|
|
||||||
|
|
||||||
def initConfig(controllerObject):
|
|
||||||
global controller
|
|
||||||
controller = controllerObject
|
|
||||||
logging.debug("Initialising Plugine")
|
|
||||||
conf_params = {"SAMPLE": [
|
|
||||||
{"CMD_OPTION" : "filename",
|
|
||||||
"USAGE" : "File to create",
|
|
||||||
"PROMPT" : "File to create",
|
|
||||||
"OPTION_LIST" : [],
|
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
|
||||||
"DEFAULT_VALUE" : "/tmp/samplefile.txt",
|
|
||||||
"MASK_INPUT" : False,
|
|
||||||
"LOOSE_VALIDATION": True,
|
|
||||||
"CONF_NAME" : "CONFIG_FILENAME",
|
|
||||||
"USE_DEFAULT" : False,
|
|
||||||
"NEED_CONFIRM" : False,
|
|
||||||
"CONDITION" : False },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
conf_groups = [
|
|
||||||
{ "GROUP_NAME" : "SAMPLE",
|
|
||||||
"DESCRIPTION" : "Sample config group",
|
|
||||||
"PRE_CONDITION" : utils.returnYes,
|
|
||||||
"PRE_CONDITION_MATCH" : "yes",
|
|
||||||
"POST_CONDITION" : False,
|
|
||||||
"POST_CONDITION_MATCH" : True},
|
|
||||||
]
|
|
||||||
|
|
||||||
for group in conf_groups:
|
|
||||||
paramList = conf_params[group["GROUP_NAME"]]
|
|
||||||
controller.addGroup(group, paramList)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def initSequences(controller):
|
|
||||||
preparesteps = [
|
|
||||||
{'title': 'Create File', 'functions':[createfile]}
|
|
||||||
]
|
|
||||||
controller.addSequence("Creating File", [], [], preparesteps)
|
|
||||||
|
|
||||||
|
|
||||||
def createfile():
|
|
||||||
with open(controller.CONF["CONFIG_FILENAME"], "a") as fp:
|
|
||||||
fp.write("HELLO WORLD")
|
|
||||||
|
|
@ -3,9 +3,9 @@ Container set for groups and parameters
|
|||||||
"""
|
"""
|
||||||
class Param(object):
|
class Param(object):
|
||||||
allowed_keys = ('CMD_OPTION','USAGE','PROMPT','OPTION_LIST',
|
allowed_keys = ('CMD_OPTION','USAGE','PROMPT','OPTION_LIST',
|
||||||
'PROCESSOR_ARGS', 'PROCESSOR_FUNC', 'PROCESSOR_MSG',
|
'PROCESSORS', 'VALIDATORS','DEFAULT_VALUE',
|
||||||
'VALIDATION_FUNC','DEFAULT_VALUE','MASK_INPUT','LOOSE_VALIDATION',
|
'MASK_INPUT', 'LOOSE_VALIDATION', 'CONF_NAME',
|
||||||
'CONF_NAME','USE_DEFAULT','NEED_CONFIRM','CONDITION')
|
'USE_DEFAULT','NEED_CONFIRM','CONDITION')
|
||||||
|
|
||||||
def __init__(self, attributes=None):
|
def __init__(self, attributes=None):
|
||||||
if not attributes:
|
if not attributes:
|
||||||
@ -25,10 +25,10 @@ class Param(object):
|
|||||||
|
|
||||||
def getKey(self, key):
|
def getKey(self, key):
|
||||||
self.validateKey(key)
|
self.validateKey(key)
|
||||||
return self.__ATTRIBUTES[key]
|
return self.__ATTRIBUTES.get(key)
|
||||||
|
|
||||||
def validateKey(self, key):
|
def validateKey(self, key):
|
||||||
if not self.__ATTRIBUTES.has_key(key):
|
if key not in self.allowed_keys:
|
||||||
raise KeyError("%s is not a valid key" % key)
|
raise KeyError("%s is not a valid key" % key)
|
||||||
|
|
||||||
class Group(Param):
|
class Group(Param):
|
||||||
|
@ -5,6 +5,7 @@ import re
|
|||||||
|
|
||||||
from packstack.installer import basedefs
|
from packstack.installer import basedefs
|
||||||
from packstack.installer.setup_controller import Controller
|
from packstack.installer.setup_controller import Controller
|
||||||
|
from packstack.installer.exceptions import PackStackError
|
||||||
|
|
||||||
controller = Controller()
|
controller = Controller()
|
||||||
|
|
||||||
@ -12,10 +13,6 @@ PUPPET_DIR = os.path.join(basedefs.DIR_PROJECT_DIR, "puppet")
|
|||||||
PUPPET_TEMPLATE_DIR = os.path.join(PUPPET_DIR, "templates")
|
PUPPET_TEMPLATE_DIR = os.path.join(PUPPET_DIR, "templates")
|
||||||
|
|
||||||
|
|
||||||
class PackStackError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NovaConfig(object):
|
class NovaConfig(object):
|
||||||
"""
|
"""
|
||||||
Helper class to create puppet manifest entries for nova_config
|
Helper class to create puppet manifest entries for nova_config
|
||||||
|
@ -34,11 +34,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install Cinder",
|
"USAGE" : "The IP address of the server on which to install Cinder",
|
||||||
"PROMPT" : "Enter the IP address of the Cinder server",
|
"PROMPT" : "Enter the IP address of the Cinder server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_CINDER_HOST",
|
"CONF_NAME" : "CONFIG_CINDER_HOST",
|
||||||
@ -49,7 +46,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Cinder to access DB",
|
"USAGE" : "The password to use for the Cinder to access DB",
|
||||||
"PROMPT" : "Enter the password for the Cinder DB access",
|
"PROMPT" : "Enter the password for the Cinder DB access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -61,7 +58,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Cinder to authenticate with Keystone",
|
"USAGE" : "The password to use for the Cinder to authenticate with Keystone",
|
||||||
"PROMPT" : "Enter the password for the Cinder Keystone access",
|
"PROMPT" : "Enter the password for the Cinder Keystone access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -73,7 +70,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Cinder's volumes group size",
|
"USAGE" : "Cinder's volumes group size",
|
||||||
"PROMPT" : "Enter Cinder's volumes group size",
|
"PROMPT" : "Enter Cinder's volumes group size",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "2G",
|
"DEFAULT_VALUE" : "2G",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -85,7 +82,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Cinder's volumes group path",
|
"USAGE" : "Cinder's volumes group path",
|
||||||
"PROMPT" : "Enter Cinder's volumes group path",
|
"PROMPT" : "Enter Cinder's volumes group path",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "/var/lib/cinder",
|
"DEFAULT_VALUE" : "/var/lib/cinder",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -97,7 +94,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Cinder's volumes group name",
|
"USAGE" : "Cinder's volumes group name",
|
||||||
"PROMPT" : "Enter Cinder's volumes group name",
|
"PROMPT" : "Enter Cinder's volumes group name",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "cinder-volumes",
|
"DEFAULT_VALUE" : "cinder-volumes",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -109,7 +106,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Create Cinder's volumes group",
|
"USAGE" : "Create Cinder's volumes group",
|
||||||
"PROMPT" : "Should Cinder's volumes group be created?",
|
"PROMPT" : "Should Cinder's volumes group be created?",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : createVolume,
|
"VALIDATORS" : [validate.validate_options, createVolume],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -141,18 +138,19 @@ def initSequences(controller):
|
|||||||
controller.addSequence("Installing OpenStack Cinder", [], [], cindersteps)
|
controller.addSequence("Installing OpenStack Cinder", [], [], cindersteps)
|
||||||
|
|
||||||
|
|
||||||
def createVolume(param, options=[]):
|
def createVolume(param, options=None):
|
||||||
"""
|
"""
|
||||||
Check that provided host is listening on port 22
|
Check that provided host is listening on port 22
|
||||||
"""
|
"""
|
||||||
|
options = options or []
|
||||||
if param == "n":
|
if param == "n":
|
||||||
return True
|
return
|
||||||
|
|
||||||
|
# XXX: For this case it probably is better (cleaner) to use processor instead of validator
|
||||||
for option in ['CONFIG_CINDER_VOLUMES_SIZE', 'CONFIG_CINDER_VOLUMES_PATH']:
|
for option in ['CONFIG_CINDER_VOLUMES_SIZE', 'CONFIG_CINDER_VOLUMES_PATH']:
|
||||||
param = controller.getParamByName(option)
|
param = controller.getParamByName(option)
|
||||||
param.setKey('USE_DEFAULT', False)
|
param.setKey('USE_DEFAULT', False)
|
||||||
setup.input_param(param)
|
setup.input_param(param)
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def checkcindervg():
|
def checkcindervg():
|
||||||
|
@ -30,11 +30,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install Horizon",
|
"USAGE" : "The IP address of the server on which to install Horizon",
|
||||||
"PROMPT" : "Enter the IP address of the Horizon server",
|
"PROMPT" : "Enter the IP address of the Horizon server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_HORIZON_HOST",
|
"CONF_NAME" : "CONFIG_HORIZON_HOST",
|
||||||
|
@ -30,11 +30,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install Glance",
|
"USAGE" : "The IP address of the server on which to install Glance",
|
||||||
"PROMPT" : "Enter the IP address of the Glance server",
|
"PROMPT" : "Enter the IP address of the Glance server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_GLANCE_HOST",
|
"CONF_NAME" : "CONFIG_GLANCE_HOST",
|
||||||
@ -45,7 +42,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Glance to access DB",
|
"USAGE" : "The password to use for the Glance to access DB",
|
||||||
"PROMPT" : "Enter the password for the Glance DB access",
|
"PROMPT" : "Enter the password for the Glance DB access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -57,7 +54,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Glance to authenticate with Keystone",
|
"USAGE" : "The password to use for the Glance to authenticate with Keystone",
|
||||||
"PROMPT" : "Enter the password for the Glance Keystone access",
|
"PROMPT" : "Enter the password for the Glance Keystone access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
|
@ -31,11 +31,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install Keystone",
|
"USAGE" : "The IP address of the server on which to install Keystone",
|
||||||
"PROMPT" : "Enter the IP address of the Keystone server",
|
"PROMPT" : "Enter the IP address of the Keystone server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_KEYSTONE_HOST",
|
"CONF_NAME" : "CONFIG_KEYSTONE_HOST",
|
||||||
@ -46,7 +43,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Keystone to access DB",
|
"USAGE" : "The password to use for the Keystone to access DB",
|
||||||
"PROMPT" : "Enter the password for the Keystone DB access",
|
"PROMPT" : "Enter the password for the Keystone DB access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -58,7 +55,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The token to use for the Keystone service api",
|
"USAGE" : "The token to use for the Keystone service api",
|
||||||
"PROMPT" : "The token to use for the Keystone service api",
|
"PROMPT" : "The token to use for the Keystone service api",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex,
|
"DEFAULT_VALUE" : uuid.uuid4().hex,
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -70,7 +67,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Keystone admin user",
|
"USAGE" : "The password to use for the Keystone admin user",
|
||||||
"PROMPT" : "Enter the password for the Keystone admin user",
|
"PROMPT" : "Enter the password for the Keystone admin user",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
|
@ -30,11 +30,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install MySQL",
|
"USAGE" : "The IP address of the server on which to install MySQL",
|
||||||
"PROMPT" : "Enter the IP address of the MySQL server",
|
"PROMPT" : "Enter the IP address of the MySQL server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_MYSQL_HOST",
|
"CONF_NAME" : "CONFIG_MYSQL_HOST",
|
||||||
@ -45,7 +42,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Username for the MySQL admin user",
|
"USAGE" : "Username for the MySQL admin user",
|
||||||
"PROMPT" : "Enter the username for the MySQL admin user",
|
"PROMPT" : "Enter the username for the MySQL admin user",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "root",
|
"DEFAULT_VALUE" : "root",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -57,7 +54,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Password for the MySQL admin user",
|
"USAGE" : "Password for the MySQL admin user",
|
||||||
"PROMPT" : "Enter the password for the MySQL admin user",
|
"PROMPT" : "Enter the password for the MySQL admin user",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
|
@ -28,11 +28,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the Nova API service",
|
"USAGE" : "The IP address of the server on which to install the Nova API service",
|
||||||
"PROMPT" : "Enter the IP address of the Nova API service",
|
"PROMPT" : "Enter the IP address of the Nova API service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ip, validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_API_HOST",
|
"CONF_NAME" : "CONFIG_NOVA_API_HOST",
|
||||||
@ -43,11 +40,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the Nova Cert service",
|
"USAGE" : "The IP address of the server on which to install the Nova Cert service",
|
||||||
"PROMPT" : "Enter the IP address of the Nova Cert service",
|
"PROMPT" : "Enter the IP address of the Nova Cert service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_CERT_HOST",
|
"CONF_NAME" : "CONFIG_NOVA_CERT_HOST",
|
||||||
@ -58,11 +52,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the Nova VNC proxy",
|
"USAGE" : "The IP address of the server on which to install the Nova VNC proxy",
|
||||||
"PROMPT" : "Enter the IP address of the Nova VNC proxy",
|
"PROMPT" : "Enter the IP address of the Nova VNC proxy",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_VNCPROXY_HOST",
|
"CONF_NAME" : "CONFIG_NOVA_VNCPROXY_HOST",
|
||||||
@ -73,11 +64,11 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "A comma separated list of IP addresses on which to install the Nova Compute services",
|
"USAGE" : "A comma separated list of IP addresses on which to install the Nova Compute services",
|
||||||
"PROMPT" : "Enter a comma separated list of IP addresses on which to install the Nova Compute services",
|
"PROMPT" : "Enter a comma separated list of IP addresses on which to install the Nova Compute services",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateMultiSSH,
|
"VALIDATORS" : [validate.validate_multi_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_COMPUTE_HOSTS", # TO-DO: Create processor for CSV
|
"CONF_NAME" : "CONFIG_NOVA_COMPUTE_HOSTS",
|
||||||
"USE_DEFAULT" : False,
|
"USE_DEFAULT" : False,
|
||||||
"NEED_CONFIRM" : False,
|
"NEED_CONFIRM" : False,
|
||||||
"CONDITION" : False },
|
"CONDITION" : False },
|
||||||
@ -85,7 +76,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Private interface for Flat DHCP on the Nova compute servers",
|
"USAGE" : "Private interface for Flat DHCP on the Nova compute servers",
|
||||||
"PROMPT" : "Enter the Private interface for Flat DHCP on the Nova compute servers",
|
"PROMPT" : "Enter the Private interface for Flat DHCP on the Nova compute servers",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "eth1",
|
"DEFAULT_VALUE" : "eth1",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -97,11 +88,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the Nova Network service",
|
"USAGE" : "The IP address of the server on which to install the Nova Network service",
|
||||||
"PROMPT" : "Enter the IP address of the Nova Network service",
|
"PROMPT" : "Enter the IP address of the Nova Network service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ip, validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_NETWORK_HOST",
|
"CONF_NAME" : "CONFIG_NOVA_NETWORK_HOST",
|
||||||
@ -112,7 +100,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Nova to access DB",
|
"USAGE" : "The password to use for the Nova to access DB",
|
||||||
"PROMPT" : "Enter the password for the Nova DB access",
|
"PROMPT" : "Enter the password for the Nova DB access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -124,7 +112,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Nova to authenticate with Keystone",
|
"USAGE" : "The password to use for the Nova to authenticate with Keystone",
|
||||||
"PROMPT" : "Enter the password for the Nova Keystone access",
|
"PROMPT" : "Enter the password for the Nova Keystone access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -136,7 +124,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Public interface on the Nova network server",
|
"USAGE" : "Public interface on the Nova network server",
|
||||||
"PROMPT" : "Enter the Public interface on the Nova network server",
|
"PROMPT" : "Enter the Public interface on the Nova network server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "eth0",
|
"DEFAULT_VALUE" : "eth0",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -148,7 +136,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Private interface for Flat DHCP on the Nova network server",
|
"USAGE" : "Private interface for Flat DHCP on the Nova network server",
|
||||||
"PROMPT" : "Enter the Private interface for Flat DHCP on the Nova network server",
|
"PROMPT" : "Enter the Private interface for Flat DHCP on the Nova network server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : "eth1",
|
"DEFAULT_VALUE" : "eth1",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -160,7 +148,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "IP Range for Flat DHCP",
|
"USAGE" : "IP Range for Flat DHCP",
|
||||||
"PROMPT" : "Enter the IP Range for Flat DHCP",
|
"PROMPT" : "Enter the IP Range for Flat DHCP",
|
||||||
"OPTION_LIST" : ["^([\d]{1,3}\.){3}[\d]{1,3}/\d\d?$"],
|
"OPTION_LIST" : ["^([\d]{1,3}\.){3}[\d]{1,3}/\d\d?$"],
|
||||||
"VALIDATION_FUNC" : validate.validateRe,
|
"VALIDATORS" : [validate.validate_regexp],
|
||||||
"DEFAULT_VALUE" : "192.168.32.0/22",
|
"DEFAULT_VALUE" : "192.168.32.0/22",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -172,7 +160,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "IP Range for Floating IP's",
|
"USAGE" : "IP Range for Floating IP's",
|
||||||
"PROMPT" : "Enter the IP Range for Floating IP's",
|
"PROMPT" : "Enter the IP Range for Floating IP's",
|
||||||
"OPTION_LIST" : ["^([\d]{1,3}\.){3}[\d]{1,3}/\d\d?$"],
|
"OPTION_LIST" : ["^([\d]{1,3}\.){3}[\d]{1,3}/\d\d?$"],
|
||||||
"VALIDATION_FUNC" : validate.validateRe,
|
"VALIDATORS" : [validate.validate_regexp],
|
||||||
"DEFAULT_VALUE" : "10.3.4.0/22",
|
"DEFAULT_VALUE" : "10.3.4.0/22",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -184,11 +172,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the Nova Scheduler service",
|
"USAGE" : "The IP address of the server on which to install the Nova Scheduler service",
|
||||||
"PROMPT" : "Enter the IP address of the Nova Scheduler service",
|
"PROMPT" : "Enter the IP address of the Nova Scheduler service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_NOVA_SCHED_HOST",
|
"CONF_NAME" : "CONFIG_NOVA_SCHED_HOST",
|
||||||
@ -204,6 +189,7 @@ def initConfig(controllerObject):
|
|||||||
"POST_CONDITION_MATCH" : True}
|
"POST_CONDITION_MATCH" : True}
|
||||||
controller.addGroup(groupDict, paramsList)
|
controller.addGroup(groupDict, paramsList)
|
||||||
|
|
||||||
|
|
||||||
def initSequences(controller):
|
def initSequences(controller):
|
||||||
if controller.CONF['CONFIG_NOVA_INSTALL'] != 'y':
|
if controller.CONF['CONFIG_NOVA_INSTALL'] != 'y':
|
||||||
return
|
return
|
||||||
@ -220,59 +206,71 @@ def initSequences(controller):
|
|||||||
]
|
]
|
||||||
controller.addSequence("Installing OpenStack Nova API", [], [], novaapisteps)
|
controller.addSequence("Installing OpenStack Nova API", [], [], novaapisteps)
|
||||||
|
|
||||||
|
|
||||||
def createapimanifest():
|
def createapimanifest():
|
||||||
manifestfile = "%s_api_nova.pp"%controller.CONF['CONFIG_NOVA_API_HOST']
|
manifestfile = "%s_api_nova.pp"%controller.CONF['CONFIG_NOVA_API_HOST']
|
||||||
manifestdata = getManifestTemplate("nova_api.pp")
|
manifestdata = getManifestTemplate("nova_api.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata, 'novaapi')
|
appendManifestFile(manifestfile, manifestdata, 'novaapi')
|
||||||
|
|
||||||
|
|
||||||
def createkeystonemanifest():
|
def createkeystonemanifest():
|
||||||
manifestfile = "%s_keystone.pp"%controller.CONF['CONFIG_KEYSTONE_HOST']
|
manifestfile = "%s_keystone.pp"%controller.CONF['CONFIG_KEYSTONE_HOST']
|
||||||
manifestdata = getManifestTemplate("keystone_nova.pp")
|
manifestdata = getManifestTemplate("keystone_nova.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
def createcertmanifest():
|
def createcertmanifest():
|
||||||
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_CERT_HOST']
|
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_CERT_HOST']
|
||||||
manifestdata = getManifestTemplate("nova_cert.pp")
|
manifestdata = getManifestTemplate("nova_cert.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
|
def check_ifcfg(host, device):
|
||||||
|
"""
|
||||||
|
Raises ScriptRuntimeError if given host does not have give device.
|
||||||
|
"""
|
||||||
|
server = utils.ScriptRunner(host)
|
||||||
|
cmd = "ifconfig %s || ( echo Device %s does not exist && exit 1 )"
|
||||||
|
server.append(cmd % (device, device))
|
||||||
|
server.execute()
|
||||||
|
|
||||||
|
|
||||||
def createcomputemanifest():
|
def createcomputemanifest():
|
||||||
for host in controller.CONF["CONFIG_NOVA_COMPUTE_HOSTS"].split(","):
|
for host in controller.CONF["CONFIG_NOVA_COMPUTE_HOSTS"].split(","):
|
||||||
controller.CONF["CONFIG_NOVA_COMPUTE_HOST"] = host
|
controller.CONF["CONFIG_NOVA_COMPUTE_HOST"] = host
|
||||||
manifestdata = getManifestTemplate("nova_compute.pp")
|
manifestdata = getManifestTemplate("nova_compute.pp")
|
||||||
manifestfile = "%s_nova.pp"%host
|
manifestfile = "%s_nova.pp"%host
|
||||||
|
|
||||||
server = utils.ScriptRunner(host)
|
|
||||||
nova_config_options = NovaConfig()
|
nova_config_options = NovaConfig()
|
||||||
|
|
||||||
if host != controller.CONF["CONFIG_NOVA_NETWORK_HOST"]:
|
if host != controller.CONF["CONFIG_NOVA_NETWORK_HOST"]:
|
||||||
nova_config_options.addOption("flat_interface", controller.CONF['CONFIG_NOVA_COMPUTE_PRIVIF'])
|
nova_config_options.addOption("flat_interface", controller.CONF['CONFIG_NOVA_COMPUTE_PRIVIF'])
|
||||||
validate.r_validateIF(server, controller.CONF['CONFIG_NOVA_COMPUTE_PRIVIF'])
|
check_ifcfg(host, controller.CONF['CONFIG_NOVA_COMPUTE_PRIVIF'])
|
||||||
|
|
||||||
server.execute()
|
|
||||||
appendManifestFile(manifestfile, manifestdata + "\n" + nova_config_options.getManifestEntry())
|
appendManifestFile(manifestfile, manifestdata + "\n" + nova_config_options.getManifestEntry())
|
||||||
|
|
||||||
|
|
||||||
def createnetworkmanifest():
|
def createnetworkmanifest():
|
||||||
hostname = controller.CONF['CONFIG_NOVA_NETWORK_HOST']
|
host = controller.CONF['CONFIG_NOVA_NETWORK_HOST']
|
||||||
|
check_ifcfg(host, controller.CONF['CONFIG_NOVA_NETWORK_PRIVIF'])
|
||||||
|
check_ifcfg(host, controller.CONF['CONFIG_NOVA_NETWORK_PUBIF'])
|
||||||
|
|
||||||
server = utils.ScriptRunner(hostname)
|
manifestfile = "%s_nova.pp" % host
|
||||||
validate.r_validateIF(server, controller.CONF['CONFIG_NOVA_NETWORK_PRIVIF'])
|
|
||||||
validate.r_validateIF(server, controller.CONF['CONFIG_NOVA_NETWORK_PUBIF'])
|
|
||||||
server.execute()
|
|
||||||
|
|
||||||
manifestfile = "%s_nova.pp"%hostname
|
|
||||||
manifestdata = getManifestTemplate("nova_network.pp")
|
manifestdata = getManifestTemplate("nova_network.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
def createschedmanifest():
|
def createschedmanifest():
|
||||||
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_SCHED_HOST']
|
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_SCHED_HOST']
|
||||||
manifestdata = getManifestTemplate("nova_sched.pp")
|
manifestdata = getManifestTemplate("nova_sched.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
def createvncproxymanifest():
|
def createvncproxymanifest():
|
||||||
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_VNCPROXY_HOST']
|
manifestfile = "%s_nova.pp"%controller.CONF['CONFIG_NOVA_VNCPROXY_HOST']
|
||||||
manifestdata = getManifestTemplate("nova_vncproxy.pp")
|
manifestdata = getManifestTemplate("nova_vncproxy.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
def createcommonmanifest():
|
def createcommonmanifest():
|
||||||
for manifestfile, marker in manifestfiles.getFiles():
|
for manifestfile, marker in manifestfiles.getFiles():
|
||||||
if manifestfile.endswith("_nova.pp"):
|
if manifestfile.endswith("_nova.pp"):
|
||||||
|
@ -29,11 +29,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the OpenStack client packages. An admin \"rc\" file will also be installed",
|
"USAGE" : "The IP address of the server on which to install the OpenStack client packages. An admin \"rc\" file will also be installed",
|
||||||
"PROMPT" : "Enter the IP address of the client server",
|
"PROMPT" : "Enter the IP address of the client server",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_OSCLIENT_HOST",
|
"CONF_NAME" : "CONFIG_OSCLIENT_HOST",
|
||||||
|
@ -29,7 +29,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install Glance",
|
"USAGE" : "Set to 'y' if you would like Packstack to install Glance",
|
||||||
"PROMPT" : "Should Packstack install Glance image service",
|
"PROMPT" : "Should Packstack install Glance image service",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -41,7 +41,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install Cinder",
|
"USAGE" : "Set to 'y' if you would like Packstack to install Cinder",
|
||||||
"PROMPT" : "Should Packstack install Cinder volume service",
|
"PROMPT" : "Should Packstack install Cinder volume service",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -53,7 +53,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install Nova",
|
"USAGE" : "Set to 'y' if you would like Packstack to install Nova",
|
||||||
"PROMPT" : "Should Packstack install Nova compute service",
|
"PROMPT" : "Should Packstack install Nova compute service",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -65,7 +65,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install Horizon",
|
"USAGE" : "Set to 'y' if you would like Packstack to install Horizon",
|
||||||
"PROMPT" : "Should Packstack install Horizon dashboard",
|
"PROMPT" : "Should Packstack install Horizon dashboard",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -77,7 +77,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install Swift",
|
"USAGE" : "Set to 'y' if you would like Packstack to install Swift",
|
||||||
"PROMPT" : "Should Packstack install Swift object storage",
|
"PROMPT" : "Should Packstack install Swift object storage",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "n",
|
"DEFAULT_VALUE" : "n",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -89,7 +89,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Set to 'y' if you would like Packstack to install the OpenStack Client packages. An admin \"rc\" file will also be installed",
|
"USAGE" : "Set to 'y' if you would like Packstack to install the OpenStack Client packages. An admin \"rc\" file will also be installed",
|
||||||
"PROMPT" : "Should Packstack install OpenStack client tools",
|
"PROMPT" : "Should Packstack install OpenStack client tools",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "y",
|
"DEFAULT_VALUE" : "y",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -101,7 +101,6 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Comma separated list of NTP servers. Leave plain if Packstack should not install ntpd on instances.",
|
"USAGE" : "Comma separated list of NTP servers. Leave plain if Packstack should not install ntpd on instances.",
|
||||||
"PROMPT" : "Enter list of NTP server(s). Leave plain if Packstack should not install ntpd on instances.",
|
"PROMPT" : "Enter list of NTP server(s). Leave plain if Packstack should not install ntpd on instances.",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : lambda param, options: True,
|
|
||||||
"DEFAULT_VALUE" : '',
|
"DEFAULT_VALUE" : '',
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
|
@ -29,11 +29,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address of the server on which to install the QPID service",
|
"USAGE" : "The IP address of the server on which to install the QPID service",
|
||||||
"PROMPT" : "Enter the IP address of the QPID service",
|
"PROMPT" : "Enter the IP address of the QPID service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"PROCESSOR_ARGS" : {"allow_localhost": True},
|
|
||||||
"PROCESSOR_FUNC" : process.processHost,
|
|
||||||
"PROCESSOR_MSG" : "WARN_VAL_IS_HOSTNAME",
|
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_QPID_HOST",
|
"CONF_NAME" : "CONFIG_QPID_HOST",
|
||||||
|
@ -28,7 +28,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Install OpenStack from EPEL. If set to \"y\" EPEL will be installed on each server",
|
"USAGE" : "Install OpenStack from EPEL. If set to \"y\" EPEL will be installed on each server",
|
||||||
"PROMPT" : "Should Packstack install EPEL on each server",
|
"PROMPT" : "Should Packstack install EPEL on each server",
|
||||||
"OPTION_LIST" : ["y", "n"],
|
"OPTION_LIST" : ["y", "n"],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "n",
|
"DEFAULT_VALUE" : "n",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -40,7 +40,6 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "A comma separated list of URLs to any additional yum repositories to install",
|
"USAGE" : "A comma separated list of URLs to any additional yum repositories to install",
|
||||||
"PROMPT" : "Enter a comma separated list of URLs to any additional yum repositories to install",
|
"PROMPT" : "Enter a comma separated list of URLs to any additional yum repositories to install",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : lambda a,b: True,
|
|
||||||
"DEFAULT_VALUE" : "",
|
"DEFAULT_VALUE" : "",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -52,7 +51,6 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "To subscribe each server with Red Hat subscription manager, include this with CONFIG_RH_PASSWORD",
|
"USAGE" : "To subscribe each server with Red Hat subscription manager, include this with CONFIG_RH_PASSWORD",
|
||||||
"PROMPT" : "To subscribe each server to Red Hat enter a username here",
|
"PROMPT" : "To subscribe each server to Red Hat enter a username here",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : lambda a,b: True,
|
|
||||||
"DEFAULT_VALUE" : "",
|
"DEFAULT_VALUE" : "",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -64,7 +62,6 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "To subscribe each server with Red Hat subscription manager, include this with CONFIG_RH_USERNAME",
|
"USAGE" : "To subscribe each server with Red Hat subscription manager, include this with CONFIG_RH_USERNAME",
|
||||||
"PROMPT" : "To subscribe each server to Red Hat enter your password here",
|
"PROMPT" : "To subscribe each server to Red Hat enter your password here",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : lambda a,b: True,
|
|
||||||
"DEFAULT_VALUE" : "",
|
"DEFAULT_VALUE" : "",
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
|
@ -32,8 +32,8 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Path to a Public key to install on servers. If a usable key has not been installed on the remote servers the user will be prompted for a password and this key will be installed so the password will not be required again",
|
"USAGE" : "Path to a Public key to install on servers. If a usable key has not been installed on the remote servers the user will be prompted for a password and this key will be installed so the password will not be required again",
|
||||||
"PROMPT" : "Enter the path to your ssh Public key to install on servers",
|
"PROMPT" : "Enter the path to your ssh Public key to install on servers",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateFile,
|
"VALIDATORS" : [validate.validate_file],
|
||||||
"PROCESSOR_FUNC" : process.processSSHKey,
|
"PROCESSORS" : [process.processSSHKey],
|
||||||
"DEFAULT_VALUE" : (glob.glob(os.path.join(os.environ["HOME"], ".ssh/*.pub"))+[""])[0],
|
"DEFAULT_VALUE" : (glob.glob(os.path.join(os.environ["HOME"], ".ssh/*.pub"))+[""])[0],
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
|
@ -31,11 +31,11 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The IP address on which to install the Swift proxy service",
|
"USAGE" : "The IP address on which to install the Swift proxy service",
|
||||||
"PROMPT" : "Enter the IP address of the Swift proxy service",
|
"PROMPT" : "Enter the IP address of the Swift proxy service",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateSSH,
|
"VALIDATORS" : [validate.validate_ip, validate.validate_ssh],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_SWIFT_PROXY_HOSTS", # TO-DO: Create processor for CSV
|
"CONF_NAME" : "CONFIG_SWIFT_PROXY_HOSTS", #XXX: Shouldn't be here CONFIG_SWIFT_PROXY_HOST?
|
||||||
"USE_DEFAULT" : False,
|
"USE_DEFAULT" : False,
|
||||||
"NEED_CONFIRM" : False,
|
"NEED_CONFIRM" : False,
|
||||||
"CONDITION" : False },
|
"CONDITION" : False },
|
||||||
@ -43,7 +43,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "The password to use for the Swift to authenticate with Keystone",
|
"USAGE" : "The password to use for the Swift to authenticate with Keystone",
|
||||||
"PROMPT" : "Enter the password for the Swift Keystone access",
|
"PROMPT" : "Enter the password for the Swift Keystone access",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty],
|
||||||
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
"DEFAULT_VALUE" : uuid.uuid4().hex[:16],
|
||||||
"MASK_INPUT" : True,
|
"MASK_INPUT" : True,
|
||||||
"LOOSE_VALIDATION": False,
|
"LOOSE_VALIDATION": False,
|
||||||
@ -55,11 +55,11 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "A comma separated list of IP addresses on which to install the Swift Storage services, each entry should take the format <ipaddress>[/dev], for example 127.0.0.1/vdb will install /dev/vdb on 127.0.0.1 as a swift storage device, if /dev is omitted Packstack will create a loopback device for a test setup",
|
"USAGE" : "A comma separated list of IP addresses on which to install the Swift Storage services, each entry should take the format <ipaddress>[/dev], for example 127.0.0.1/vdb will install /dev/vdb on 127.0.0.1 as a swift storage device, if /dev is omitted Packstack will create a loopback device for a test setup",
|
||||||
"PROMPT" : "Enter the Swift Storage servers e.g. host/dev,host/dev",
|
"PROMPT" : "Enter the Swift Storage servers e.g. host/dev,host/dev",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateStringNotEmpty,
|
"VALIDATORS" : [validate.validate_not_empty, validate_storage],
|
||||||
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
"DEFAULT_VALUE" : utils.getLocalhostIP(),
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
"CONF_NAME" : "CONFIG_SWIFT_STORAGE_HOSTS", # TO-DO: Create processor for CSV
|
"CONF_NAME" : "CONFIG_SWIFT_STORAGE_HOSTS",
|
||||||
"USE_DEFAULT" : False,
|
"USE_DEFAULT" : False,
|
||||||
"NEED_CONFIRM" : False,
|
"NEED_CONFIRM" : False,
|
||||||
"CONDITION" : False },
|
"CONDITION" : False },
|
||||||
@ -67,7 +67,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Number of swift storage zones, this number MUST be no bigger than the number of storage devices configured",
|
"USAGE" : "Number of swift storage zones, this number MUST be no bigger than the number of storage devices configured",
|
||||||
"PROMPT" : "Enter the number of swift storage zones, MUST be no bigger than the number of storage devices configured",
|
"PROMPT" : "Enter the number of swift storage zones, MUST be no bigger than the number of storage devices configured",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateInteger,
|
"VALIDATORS" : [validate.validate_integer],
|
||||||
"DEFAULT_VALUE" : "1",
|
"DEFAULT_VALUE" : "1",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -79,7 +79,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "Number of swift storage replicas, this number MUST be no bigger than the number of storage zones configured",
|
"USAGE" : "Number of swift storage replicas, this number MUST be no bigger than the number of storage zones configured",
|
||||||
"PROMPT" : "Enter the number of swift storage replicas, MUST be no bigger than the number of storage zones configured",
|
"PROMPT" : "Enter the number of swift storage replicas, MUST be no bigger than the number of storage zones configured",
|
||||||
"OPTION_LIST" : [],
|
"OPTION_LIST" : [],
|
||||||
"VALIDATION_FUNC" : validate.validateInteger,
|
"VALIDATORS" : [validate.validate_integer],
|
||||||
"DEFAULT_VALUE" : "1",
|
"DEFAULT_VALUE" : "1",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -91,7 +91,7 @@ def initConfig(controllerObject):
|
|||||||
"USAGE" : "FileSystem type for storage nodes",
|
"USAGE" : "FileSystem type for storage nodes",
|
||||||
"PROMPT" : "Enter FileSystem type for storage nodes",
|
"PROMPT" : "Enter FileSystem type for storage nodes",
|
||||||
"OPTION_LIST" : ['xfs','ext4'],
|
"OPTION_LIST" : ['xfs','ext4'],
|
||||||
"VALIDATION_FUNC" : validate.validateOptions,
|
"VALIDATORS" : [validate.validate_options],
|
||||||
"DEFAULT_VALUE" : "ext4",
|
"DEFAULT_VALUE" : "ext4",
|
||||||
"MASK_INPUT" : False,
|
"MASK_INPUT" : False,
|
||||||
"LOOSE_VALIDATION": True,
|
"LOOSE_VALIDATION": True,
|
||||||
@ -111,6 +111,12 @@ def initConfig(controllerObject):
|
|||||||
controller.addGroup(groupDict, paramsList)
|
controller.addGroup(groupDict, paramsList)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_storage(param, options=None):
|
||||||
|
for host in param.split(','):
|
||||||
|
host = host.split('/', 1)[0]
|
||||||
|
validate.validate_ip(host.strip(), options)
|
||||||
|
|
||||||
|
|
||||||
def initSequences(controller):
|
def initSequences(controller):
|
||||||
if controller.CONF['CONFIG_SWIFT_INSTALL'] != 'y':
|
if controller.CONF['CONFIG_SWIFT_INSTALL'] != 'y':
|
||||||
return
|
return
|
||||||
@ -124,12 +130,14 @@ def initSequences(controller):
|
|||||||
]
|
]
|
||||||
controller.addSequence("Installing OpenStack Swift", [], [], steps)
|
controller.addSequence("Installing OpenStack Swift", [], [], steps)
|
||||||
|
|
||||||
|
|
||||||
def createkeystonemanifest():
|
def createkeystonemanifest():
|
||||||
manifestfile = "%s_keystone.pp"%controller.CONF['CONFIG_KEYSTONE_HOST']
|
manifestfile = "%s_keystone.pp"%controller.CONF['CONFIG_KEYSTONE_HOST']
|
||||||
controller.CONF['CONFIG_SWIFT_PROXY'] = controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'].split(',')[0]
|
controller.CONF['CONFIG_SWIFT_PROXY'] = controller.CONF['CONFIG_SWIFT_PROXY_HOSTS'].split(',')[0]
|
||||||
manifestdata = getManifestTemplate("keystone_swift.pp")
|
manifestdata = getManifestTemplate("keystone_swift.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
devices = []
|
devices = []
|
||||||
def parseDevices(config_swift_storage_hosts):
|
def parseDevices(config_swift_storage_hosts):
|
||||||
device_number = 0
|
device_number = 0
|
||||||
@ -142,6 +150,7 @@ def parseDevices(config_swift_storage_hosts):
|
|||||||
devices.append({'host':host, 'device':device, 'device_name':'device%s'%device_number, 'zone':str(zone)})
|
devices.append({'host':host, 'device':device, 'device_name':'device%s'%device_number, 'zone':str(zone)})
|
||||||
return devices
|
return devices
|
||||||
|
|
||||||
|
|
||||||
# The ring file should be built and distributed befor the storage services
|
# The ring file should be built and distributed befor the storage services
|
||||||
# come up. Specifically the replicator crashes if the ring isn't present
|
# come up. Specifically the replicator crashes if the ring isn't present
|
||||||
def createbuildermanifest():
|
def createbuildermanifest():
|
||||||
@ -163,6 +172,7 @@ def createbuildermanifest():
|
|||||||
|
|
||||||
appendManifestFile(manifestfile, manifestdata, 'swiftbuilder')
|
appendManifestFile(manifestfile, manifestdata, 'swiftbuilder')
|
||||||
|
|
||||||
|
|
||||||
def createproxymanifest():
|
def createproxymanifest():
|
||||||
manifestfile = "%s_swift.pp"%controller.CONF['CONFIG_SWIFT_PROXY_HOSTS']
|
manifestfile = "%s_swift.pp"%controller.CONF['CONFIG_SWIFT_PROXY_HOSTS']
|
||||||
manifestdata = getManifestTemplate("swift_proxy.pp")
|
manifestdata = getManifestTemplate("swift_proxy.pp")
|
||||||
@ -171,6 +181,32 @@ def createproxymanifest():
|
|||||||
manifestdata += 'swift::ringsync{["account","container","object"]:\n ring_server => "%s"\n}'%controller.CONF['CONFIG_SWIFT_BUILDER_HOST']
|
manifestdata += 'swift::ringsync{["account","container","object"]:\n ring_server => "%s"\n}'%controller.CONF['CONFIG_SWIFT_BUILDER_HOST']
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
|
def check_device(host, device):
|
||||||
|
"""
|
||||||
|
Raises ScriptRuntimeError if given device is not mounted on given
|
||||||
|
host.
|
||||||
|
"""
|
||||||
|
server = utils.ScriptRunner()
|
||||||
|
|
||||||
|
# the device MUST exist
|
||||||
|
cmd = 'ls -l /dev/%s'
|
||||||
|
server.append(cmd % device)
|
||||||
|
|
||||||
|
# if it is not mounted then we can use it
|
||||||
|
cmd = 'grep "/dev/%s " /proc/self/mounts || exit 0'
|
||||||
|
server.append(cmd % device)
|
||||||
|
|
||||||
|
# if it is mounted then the mount point has to be in /srv/node
|
||||||
|
cmd = 'grep "/dev/%s /srv/node" /proc/self/mounts && exit 0'
|
||||||
|
server.append(cmd % device)
|
||||||
|
|
||||||
|
# if we got here without exiting then we can't use this device
|
||||||
|
server.append('exit 1')
|
||||||
|
server.execute()
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def createstoragemanifest():
|
def createstoragemanifest():
|
||||||
|
|
||||||
# this need to happen once per storage host
|
# this need to happen once per storage host
|
||||||
@ -185,10 +221,8 @@ def createstoragemanifest():
|
|||||||
host = device['host']
|
host = device['host']
|
||||||
devicename = device['device_name']
|
devicename = device['device_name']
|
||||||
device = device['device']
|
device = device['device']
|
||||||
|
if device:
|
||||||
server = utils.ScriptRunner(host)
|
check_device(host, device)
|
||||||
validate.r_validateDevice(server, device)
|
|
||||||
server.execute()
|
|
||||||
|
|
||||||
manifestfile = "%s_swift.pp"%host
|
manifestfile = "%s_swift.pp"%host
|
||||||
if device:
|
if device:
|
||||||
@ -198,6 +232,7 @@ def createstoragemanifest():
|
|||||||
manifestdata = "\n" + getManifestTemplate("swift_loopback.pp")
|
manifestdata = "\n" + getManifestTemplate("swift_loopback.pp")
|
||||||
appendManifestFile(manifestfile, manifestdata)
|
appendManifestFile(manifestfile, manifestdata)
|
||||||
|
|
||||||
|
|
||||||
def createcommonmanifest():
|
def createcommonmanifest():
|
||||||
for manifestfile, marker in manifestfiles.getFiles():
|
for manifestfile, marker in manifestfiles.getFiles():
|
||||||
if manifestfile.endswith("_swift.pp"):
|
if manifestfile.endswith("_swift.pp"):
|
||||||
|
2
run_tests.sh
Executable file
2
run_tests.sh
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
tox -epy26,py27,pep8
|
@ -1,52 +0,0 @@
|
|||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
||||||
|
|
||||||
# Copyright 2013, Red Hat, Inc.
|
|
||||||
#
|
|
||||||
# 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 shutil
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class fakePopen(object):
|
|
||||||
def __init__(self, returncode=0):
|
|
||||||
self.returncode = returncode
|
|
||||||
self.stdout = self.stderr = self.data = ""
|
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
self.args = args
|
|
||||||
self.kwargs = kwargs
|
|
||||||
return self
|
|
||||||
|
|
||||||
def communicate(self, data):
|
|
||||||
self.data += data
|
|
||||||
return self.stdout, self.stderr
|
|
||||||
|
|
||||||
|
|
||||||
class TestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
# Creating a temp directory that can be used by tests
|
|
||||||
self.tempdir = tempfile.mkdtemp()
|
|
||||||
|
|
||||||
# some plugins call popen, we're replacing it for tests
|
|
||||||
self._Popen = subprocess.Popen
|
|
||||||
self.fakePopen = subprocess.Popen = fakePopen()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
# remove the temp directory
|
|
||||||
shutil.rmtree(self.tempdir)
|
|
||||||
|
|
||||||
subprocess.Popen = self._Popen
|
|
76
tests/test_base.py
Normal file
76
tests/test_base.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013, Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 shutil
|
||||||
|
import tempfile
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
class FakePopen(object):
|
||||||
|
def __init__(self, returncode=0):
|
||||||
|
self.returncode = returncode
|
||||||
|
self.stdout = self.stderr = self.data = ""
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
return self
|
||||||
|
|
||||||
|
def communicate(self, data=None):
|
||||||
|
self.data += data or ''
|
||||||
|
return self.stdout, self.stderr
|
||||||
|
|
||||||
|
|
||||||
|
class PackstackTestCaseMixin(object):
|
||||||
|
"""
|
||||||
|
Implementation of some assertion methods available by default
|
||||||
|
in Python2.7+ only
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
# Creating a temp directory that can be used by tests
|
||||||
|
self.tempdir = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
# some plugins call popen, we're replacing it for tests
|
||||||
|
self._Popen = subprocess.Popen
|
||||||
|
self.fake_popen = subprocess.Popen = FakePopen()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# remove the temp directory
|
||||||
|
shutil.rmtree(self.tempdir)
|
||||||
|
subprocess.Popen = self._Popen
|
||||||
|
|
||||||
|
def assertItemsEqual(self, list1, list2, msg=None):
|
||||||
|
f, s = len(list1), len(list2)
|
||||||
|
self.assertEqual(f, s, msg=('Element counts were not equal. '
|
||||||
|
'First has %s, Second has %s' % (f, s)))
|
||||||
|
for i in list1:
|
||||||
|
if i not in list2:
|
||||||
|
raise AssertionError('Given lists differ:'
|
||||||
|
'\n%(list1)s\n%(list2)s' % locals())
|
||||||
|
|
||||||
|
def assertListEqual(self, list1, list2, msg=None):
|
||||||
|
f, s = len(list1), len(list2)
|
||||||
|
self.assertEqual(f, s, msg=('Element counts were not equal. '
|
||||||
|
'First has %s, Second has %s' % (f, s)))
|
||||||
|
for index, item in enumerate(list1):
|
||||||
|
if item != list2[index]:
|
||||||
|
raise AssertionError('Given lists differ:'
|
||||||
|
'\n%(list1)s\n%(list2)s' % locals())
|
||||||
|
|
||||||
|
def assertIsInstance(self, obj, cls, msg=None):
|
||||||
|
if not isinstance(obj, cls):
|
||||||
|
raise AssertionError('%s is not an instance of %s' % (obj, cls))
|
@ -1,3 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# Copyright 2013, Red Hat, Inc.
|
# Copyright 2013, Red Hat, Inc.
|
||||||
@ -15,14 +16,15 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from test import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from test_base import PackstackTestCaseMixin
|
||||||
from packstack.modules.ospluginutils import gethostlist, \
|
from packstack.modules.ospluginutils import gethostlist, \
|
||||||
validate_puppet_logfile, \
|
validate_puppet_logfile, \
|
||||||
PackStackError
|
PackStackError
|
||||||
|
|
||||||
|
|
||||||
class OSPluginUtilsTestCase(TestCase):
|
class OSPluginUtilsTestCase(PackstackTestCaseMixin, TestCase):
|
||||||
def test_gethostlist(self):
|
def test_gethostlist(self):
|
||||||
conf = {"A_HOST": "1.1.1.1", "B_HOSTS": "2.2.2.2,1.1.1.1",
|
conf = {"A_HOST": "1.1.1.1", "B_HOSTS": "2.2.2.2,1.1.1.1",
|
||||||
"C_HOSTS": "3.3.3.3/vdc"}
|
"C_HOSTS": "3.3.3.3/vdc"}
|
||||||
|
@ -15,15 +15,16 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from test import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from test_base import PackstackTestCaseMixin
|
||||||
from packstack.plugins import serverprep_901
|
from packstack.plugins import serverprep_901
|
||||||
from packstack.installer.setup_controller import Controller
|
from packstack.installer.setup_controller import Controller
|
||||||
|
|
||||||
serverprep_901.controller = Controller()
|
serverprep_901.controller = Controller()
|
||||||
|
|
||||||
|
|
||||||
class OSPluginUtilsTestCase(TestCase):
|
class OSPluginUtilsTestCase(PackstackTestCaseMixin, TestCase):
|
||||||
def test_rhn_creds_quoted(self):
|
def test_rhn_creds_quoted(self):
|
||||||
"""Make sure RHN password is quoted"""
|
"""Make sure RHN password is quoted"""
|
||||||
|
|
||||||
@ -37,5 +38,5 @@ class OSPluginUtilsTestCase(TestCase):
|
|||||||
serverprep_901.serverprep()
|
serverprep_901.serverprep()
|
||||||
|
|
||||||
self.assertNotEqual(
|
self.assertNotEqual(
|
||||||
self.fakePopen.data.find('--password="%s"' % password), -1
|
self.fake_popen.data.find('--password="%s"' % password), -1
|
||||||
)
|
)
|
||||||
|
82
tests/test_validators.py
Normal file
82
tests/test_validators.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright 2013, Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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 shutil
|
||||||
|
import tempfile
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from test_base import PackstackTestCaseMixin
|
||||||
|
from packstack.installer.engine_validators import *
|
||||||
|
|
||||||
|
|
||||||
|
class ValidatorsTestCase(PackstackTestCaseMixin, TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Creating a temp directory that can be used by tests
|
||||||
|
self.tempdir = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# remove the temp directory
|
||||||
|
shutil.rmtree(self.tempdir)
|
||||||
|
|
||||||
|
def test_validate_integer(self):
|
||||||
|
validate_integer('1')
|
||||||
|
self.assertRaises(ParamValidationError, validate_integer, 'test')
|
||||||
|
|
||||||
|
def test_validate_regexp(self):
|
||||||
|
validate_regexp('Test_123', options=['\w'])
|
||||||
|
self.assertRaises(ParamValidationError, validate_regexp,
|
||||||
|
'!#$%', options=['\w'])
|
||||||
|
|
||||||
|
def test_validate_port(self):
|
||||||
|
validate_port('666')
|
||||||
|
self.assertRaises(ParamValidationError, validate_port, 'test')
|
||||||
|
self.assertRaises(ParamValidationError, validate_port, '-3')
|
||||||
|
|
||||||
|
def test_validate_not_empty(self):
|
||||||
|
validate_not_empty('test')
|
||||||
|
validate_not_empty(False)
|
||||||
|
self.assertRaises(ParamValidationError, validate_not_empty, '')
|
||||||
|
self.assertRaises(ParamValidationError, validate_not_empty, [])
|
||||||
|
self.assertRaises(ParamValidationError, validate_not_empty, {})
|
||||||
|
|
||||||
|
def test_validate_options(self):
|
||||||
|
validate_options('a', options=['a', 'b'])
|
||||||
|
validate_options('b', options=['a', 'b'])
|
||||||
|
self.assertRaises(ParamValidationError, validate_options,
|
||||||
|
'c', options=['a', 'b'])
|
||||||
|
|
||||||
|
def test_validate_ip(self):
|
||||||
|
validate_ip('127.0.0.1')
|
||||||
|
validate_ip('::1')
|
||||||
|
self.assertRaises(ParamValidationError, validate_ip, 'test')
|
||||||
|
|
||||||
|
def test_validate_file(self):
|
||||||
|
fname = os.path.join(self.tempdir, '.test_validate_file')
|
||||||
|
bad_name = os.path.join(self.tempdir, '.me_no_exists')
|
||||||
|
with open(fname, 'w') as f:
|
||||||
|
f.write('test')
|
||||||
|
validate_file(fname)
|
||||||
|
self.assertRaises(ParamValidationError, validate_file, bad_name)
|
||||||
|
|
||||||
|
def test_validate_ping(self):
|
||||||
|
# ping to broadcast fails
|
||||||
|
self.assertRaises(ParamValidationError, validate_ping, '192.168.122.0')
|
||||||
|
|
||||||
|
def test_validate_ssh(self):
|
||||||
|
# ssh to broadcast fails
|
||||||
|
self.assertRaises(ParamValidationError, validate_ssh, '192.168.122.0')
|
Loading…
Reference in New Issue
Block a user