[pep8][doc] Fixes in pep8 issues and comment in readme

This commit is contained in:
Peter Lomakin 2013-10-22 19:42:37 +04:00
parent 079a2e1883
commit 0386a2766f
18 changed files with 71 additions and 242 deletions

@ -35,6 +35,7 @@ Deployment
3. After that you can access application on http://<host_machine_ip>:8000/validation 3. After that you can access application on http://<host_machine_ip>:8000/validation
### Heroku deployment ### Heroku deployment
This steps is already depricated, because of mongo-db usage.
1. $ git clone git@github.com:MirantisLabs/rubick.git 1. $ git clone git@github.com:MirantisLabs/rubick.git
2. $ cd rubick 2. $ cd rubick
3. $ heroku git:remote -a <name_of_the_heroku_app> 3. $ heroku git:remote -a <name_of_the_heroku_app>

@ -1,53 +0,0 @@
#from nodes import NodesDict
import sys
# yaml.load(sys.stdin.read());
VAGRANT_DEFAULT_KEY = "-----BEGIN RSA PRIVATE KEY----\
MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI\
w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP\
kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2\
hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO\
Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW\
yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd\
ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1\
Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf\
TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK\
iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A\
sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf\
4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP\
cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk\
EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN\
CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX\
3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG\
YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj\
3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+\
dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz\
6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC\
P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF\
llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ\
kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH\
+vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ\
NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=\
-----END RSA PRIVATE KEY-----"
class Joker():
def __init__(self, key = VAGRANT_DEFAULT_KEY, *args, **kwargs):
self.default_key = key
def addNode(self, name, host, port, user):
return
def genStub(self, hostname, ip, port, user, key):
return {"name": hostname, "ip": ip, "user": user,
"key": key, "port": 22}
def discover(self):
return [self.genStub(
"controller", "192.168.28.100", 22, "vagrant", self.default_key),
self.genStub(
"compute1", "192.168.28.101", 22, "vagrant", self.default_key),
self.genStub(
"compute2", "192.168.30.101", 22, "vagrant", self.default_key)
]

@ -1,136 +0,0 @@
import collections
import paramiko
class TransformedDict(collections.MutableMapping):
def __init__(self, *args, **kwargs):
self.store = dict()
self.update(dict(*args, **kwargs)) # use the free update to set keys
def __getitem__(self, key):
return self.store[self.__keytransform__(key)]
def __setitem__(self, key, value):
self.store[self.__keytransform__(key)] = value
def __delitem__(self, key):
del self.store[self.__keytransform__(key)]
def __iter__(self):
return iter(self.store)
def __len__(self):
return len(self.store)
def __keytransform__(self, key):
return key
class NodesDict(TransformedDict):
def add(self, element):
return self.__setitem__(element, element)
def __keytransform__(self, key):
try:
# now uniq for hash is only hwaddr key
# print 'hwaddr = ' + key['hwaddr']
return key['hwaddr']
except KeyError:
raise
class Node():
def __init__(self, name, ip):
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.setHostName(ip)
self.setName(name)
self.connected = False
self.neighbours = NodesDict()
def prepare(self):
self.runCommand(
"[ ! -x arp-scan ] && sudo apt-get --force-yes install arp-scan")
# install arp-scan on node
return True
def infect(self):
# infect node
return True
def setName(self, name):
self.name = name
def setHostName(self, hostname):
self.hostName = hostname
def setAccessPort(self, port):
self.accessPort = port
def assignCredential(self, user, password, key):
self.user = user
self.password = password
self.key = key
def setProxyCommand(self, proxyCommand):
self.proxyCommand = proxyCommand
def connect(self):
if self.connected is True:
raise assertionError(self.connected is True)
try:
self.ssh.connect(self.hostName, self.accessPort, self.user,
key_filename=self.key)
self.connected = True
return True
except paramiko.BadHostKeyException, e:
print "Host key could not be verified: ", e
return False
except paramiko.AuthenticationException, e:
print "Error unable to authenticate: ", e
return False
except paramiko.SSHException, e:
print e
return False
def runCommand(self, command):
if (command == ""):
assertionError(command == "")
if (self.connected is False):
self.connect()
stdin, stdout, stderr = self.ssh.exec_command(command)
return (stdout.readlines(), stderr.readlines())
def discovery(self):
self.prepare()
(self.discovery_data, _) = self.runCommand(
"ip link | awk -F: '/^[0-9]+?: / {print $2}' |\
sudo xargs -I% arp-scan -l -I % 2>&1 | grep -E '^[0-9]+?\.'")
for node in self.discovery_data:
( node['ip'], node['hwAddr'] ) = node.split("\t")
return True
# ssh -p2301 -i /home/ryabin/.vagrant.d/insecure_private_key
# vagrant@127.0.0.1 " link | grep -B1 link/ether | awk -F: '/^[0-9]+?:
# / {print \$2}' | sudo xargs -I% arp-scan -l -I % 2>&1 | grep -E
# '^[0-9]+?\.'
n = Node("controller", "127.0.0.1")
n.assignCredential(
"vagrant", None, "/home/ryabin/.vagrant.d/insecure_private_key")
n.setAccessPort(2301)
n.discovery()
print n.discovery_data

Binary file not shown.

@ -1,10 +0,0 @@
Metadata-Version: 1.0
Name: joker
Version: 0.1
Summary: why so serious?
Home-page: https://github.com/MirantisLabs/joker
Author: Mirantis
Author-email: emailme@mirantis.com
License: Apache
Description: UNKNOWN
Platform: UNKNOWN

@ -1,8 +0,0 @@
setup.py
joker/__init__.py
joker/nodes.py
joker.egg-info/PKG-INFO
joker.egg-info/SOURCES.txt
joker.egg-info/dependency_links.txt
joker.egg-info/not-zip-safe
joker.egg-info/top_level.txt

@ -1 +0,0 @@
joker

@ -29,7 +29,9 @@ class IniConfigParser:
line_number += 1 line_number += 1
if current_param_name and (current_param_value.quotechar or (line == '' or not line[0].isspace())): if current_param_name \
and (current_param_value.quotechar
or (line == '' or not line[0].isspace())):
param = ConfigParameter( param = ConfigParameter(
current_param_name.start_mark, current_param_name.start_mark,
current_param_value.end_mark, current_param_value.end_mark,
@ -55,28 +57,32 @@ class IniConfigParser:
continue continue
else: else:
errors.append( errors.append(
ParseError('Unexpected multiline value continuation', mark(line_number))) ParseError('Unexpected multiline value continuation',
mark(line_number)))
continue continue
if line[0] == '[': if line[0] == '[':
end_index = line.find(']') end_index = line.find(']')
if end_index == -1: if end_index == -1:
errors.append( errors.append(
ParseError('Unclosed section', mark(line_number, len(line)))) ParseError('Unclosed section', mark(line_number,
len(line))))
end_index = len(line) end_index = len(line)
while line[end_index - 1].isspace(): while line[end_index - 1].isspace():
end_index -= 1 end_index -= 1
if end_index <= 1: if end_index <= 1:
errors.append( errors.append(
ParseError('Missing section name', mark(line_number))) ParseError('Missing section name',
mark(line_number)))
continue continue
else: else:
i = end_index + 1 i = end_index + 1
while i < len(line): while i < len(line):
if not line[i].isspace(): if not line[i].isspace():
errors.append( errors.append(
ParseError('Extra chars after section name', mark(line_number, i))) ParseError('Extra chars after section name',
mark(line_number, i)))
break break
i += 1 i += 1
@ -111,7 +117,8 @@ class IniConfigParser:
# Unquote value # Unquote value
value = m.group(3) value = m.group(3)
quotechar = None quotechar = None
if len(value) > 0 and (value[0] == value[-1] and value[0] in "\"'"): if len(value) > 0 and (value[0] == value[-1]
and value[0] in "\"'"):
quotechar = value[0] quotechar = value[0]
value = value[1:-1] value = value[1:-1]

@ -14,7 +14,8 @@ class IniConfigParserTests(unittest.TestCase):
lines = lines[1:-1] lines = lines[1:-1]
first_line = lines[0] first_line = lines[0]
margin_size = 0 margin_size = 0
while margin_size < len(first_line) and first_line[margin_size].isspace(): while margin_size < len(first_line) \
and first_line[margin_size].isspace():
margin_size += 1 margin_size += 1
stripped_lines = [line[margin_size:] for line in lines] stripped_lines = [line[margin_size:] for line in lines]
@ -219,7 +220,8 @@ class IniConfigParserTests(unittest.TestCase):
for attr, expected in attribute_values.items(): for attr, expected in attribute_values.items():
actual = self._getattr(subject, attr) actual = self._getattr(subject, attr)
self.assertEqual( self.assertEqual(
expected, actual, "%s expected to have %s = %s, but the value was %s" % expected, actual,
"%s expected to have %s = %s, but the value was %s" %
(subject, attr, expected, actual)) (subject, attr, expected, actual))
def assertParameter(self, name, value, o): def assertParameter(self, name, value, o):

@ -188,7 +188,8 @@ class OpenstackDiscovery(object):
client.run(['echo', 'test']) client.run(['echo', 'test'])
except: except:
self.logger.exception("Can't connect to host %s" % node_info['host']) self.logger.exception("Can't connect to host %s"
% node_info['host'])
openstack.report_issue( openstack.report_issue(
Issue( Issue(
Issue.WARNING, Issue.WARNING,
@ -253,7 +254,9 @@ class OpenstackDiscovery(object):
def _find_python_package_version(self, client, package): def _find_python_package_version(self, client, package):
result = client.run( result = client.run(
['python', '-c', ['python', '-c',
'import pkg_resources; version = pkg_resources.get_provider(pkg_resources.Requirement.parse("%s")).version; print(version)' % 'import pkg_resources; version = pkg_resources'
'.get_provider(pkg_resources.Requirement.parse("%s"))'
'.version; print(version)' %
package]) package])
s = result.output.strip() s = result.output.strip()
@ -271,7 +274,8 @@ class OpenstackDiscovery(object):
def _get_processes(self, client): def _get_processes(self, client):
return ( return (
[line.split() [line.split()
for line in client.run(['ps', '-Ao', 'cmd', '--no-headers']).output.split("\n")] for line in client.run(['ps', '-Ao', 'cmd',
'--no-headers']).output.split("\n")]
) )
def _collect_host_id(self, client): def _collect_host_id(self, client):
@ -571,7 +575,9 @@ class OpenstackDiscovery(object):
mysql.config_files = [] mysql.config_files = []
config_locations_result = client.run( config_locations_result = client.run(
['bash', '-c', ['bash', '-c',
'mysqld --help --verbose | grep "Default options are read from the following files in the given order" -A 1']) 'mysqld --help --verbose '
'| grep "Default options are read from the following files in '
'the given order" -A 1'])
config_locations = config_locations_result.output.strip().split( config_locations = config_locations_result.output.strip().split(
"\n")[-1].split() "\n")[-1].split()
for path in config_locations: for path in config_locations:

@ -1,3 +1,4 @@
from rubick.inspections.keystone_authtoken import KeystoneAuthtokenSettingsInspection from rubick.inspections.keystone_authtoken \
import KeystoneAuthtokenSettingsInspection
from rubick.inspections.keystone_endpoints import KeystoneEndpointsInspection from rubick.inspections.keystone_endpoints import KeystoneEndpointsInspection
from rubick.inspections.lettuce_runner import LettuceRunnerInspection from rubick.inspections.lettuce_runner import LettuceRunnerInspection

@ -1,5 +1,5 @@
import logging
from itertools import groupby from itertools import groupby
import logging
from rubick.common import Mark, Issue, MarkedIssue from rubick.common import Mark, Issue, MarkedIssue
from rubick.schema import ConfigSchemaRegistry, TypeValidatorRegistry from rubick.schema import ConfigSchemaRegistry, TypeValidatorRegistry
@ -243,7 +243,8 @@ class OpenstackComponent(Service):
type_validation_result = type_validator.validate( type_validation_result = type_validator.validate(
parameter.value.text) parameter.value.text)
if isinstance(type_validation_result, Issue): if isinstance(type_validation_result, Issue):
type_validation_result.mark = parameter.value.start_mark.merge( type_validation_result.mark = parameter\
.value.start_mark.merge(
type_validation_result.mark) type_validation_result.mark)
type_validation_result.message = \ type_validation_result.message = \
'Property "%s" in section "%s": %s' % ( 'Property "%s" in section "%s": %s' % (
@ -260,7 +261,10 @@ class OpenstackComponent(Service):
config.set(parameter_fullname, value) config.set(parameter_fullname, value)
# if value == parameter_schema.default: # if value == parameter_schema.default:
# report_issue(MarkedIssue(Issue.INFO, 'Explicit value equals default: section "%s" parameter "%s"' % (section_name, parameter.name.text), parameter.start_mark)) # report_issue(MarkedIssue(Issue.INFO,
# 'Explicit value equals default: section "%s"
# parameter "%s"' % (section_name,
# parameter.name.text), parameter.start_mark))
if parameter_schema.deprecation_message: if parameter_schema.deprecation_message:
report_issue( report_issue(
MarkedIssue( MarkedIssue(

@ -113,7 +113,8 @@ class FilesystemSnapshot(object):
group=group, group=group,
permissions=permissions) permissions=permissions)
elif resource_type == 'file': elif resource_type == 'file':
source_path, local_path, owner, group, permissions = line.split('|')[1:] source_path, local_path, owner, group, \
permissions = line.split('|')[1:]
self._resources[source_path] = FileResource( self._resources[source_path] = FileResource(
os.path.basename(source_path), os.path.basename(source_path),
path=os.path.join(self.basedir, path=os.path.join(self.basedir,
@ -147,7 +148,8 @@ class ConfigSnapshotResourceLocator(object):
else: else:
return ( return (
[HostResource(os.path.basename(host_path), self) [HostResource(os.path.basename(host_path), self)
for host_path in glob.glob(os.path.join(self.basedir, '*')) if os.path.isdir(host_path)] for host_path in glob.glob(os.path.join(
self.basedir, '*')) if os.path.isdir(host_path)]
) )
if resource_type == Resource.FILE: if resource_type == Resource.FILE:
if not host: if not host:

@ -91,7 +91,8 @@ class SchemaBuilder(object):
def _ensure_version(self): def _ensure_version(self):
if not self.current_version: if not self.current_version:
raise Error( raise Error(
'Schema version is not specified. Please call version() method first') 'Schema version is not specified. Please call version() '
'method first')
class ConfigSchemaRegistry: class ConfigSchemaRegistry:
@ -118,7 +119,8 @@ class ConfigSchemaRegistry:
records = self.__schemas[fullname] records = self.__schemas[fullname]
i = len(records) - 1 i = len(records) - 1
# Find latest checkpoint prior given version # Find latest checkpoint prior given version
while i >= 0 and not (records[i].operation == 'checkpoint' and records[i].version <= version): while i >= 0 and not (records[i].operation == 'checkpoint'
and records[i].version <= version):
i -= 1 i -= 1
if i < 0: if i < 0:
@ -203,8 +205,14 @@ class ConfigParameterSchema:
def __repr__(self): def __repr__(self):
return ( return (
'<ConfigParameterSchema %s>' % ' '.join(['%s=%s' % (attr, getattr(self, attr)) '<ConfigParameterSchema %s>' % ' '.join(
for attr in ['section', 'name', 'type', 'description', 'default', 'required']]) ['%s=%s' % (attr, getattr(self, attr))
for attr in ['section',
'name',
'type',
'description',
'default',
'required']])
) )
@ -304,7 +312,8 @@ def validate_ipv4_network(s):
if len(parts) != 2: if len(parts) != 2:
return ( return (
InvalidValueError( InvalidValueError(
'Should have "/" character separating address and prefix length') 'Should have "/" character separating address and prefix '
'length')
) )
address, prefix = parts address, prefix = parts
@ -339,8 +348,8 @@ def validate_host_label(s):
if not s[0].isalpha(): if not s[0].isalpha():
return ( return (
InvalidValueError( InvalidValueError(
'Host label should start with a letter, but it starts with "%s"' % 'Host label should start with a letter, but it starts with '
s[0]) '"%s"' % s[0])
) )
if len(s) == 1: if len(s) == 1:
@ -349,7 +358,8 @@ def validate_host_label(s):
if not (s[-1].isdigit() or s[-1].isalpha()): if not (s[-1].isdigit() or s[-1].isalpha()):
return ( return (
InvalidValueError( InvalidValueError(
'Host label should end with letter or digit, but it ends with "%s"' % 'Host label should end with letter or digit, but it ends '
'with "%s"' %
s[-1], Mark('', 0, len(s) - 1)) s[-1], Mark('', 0, len(s) - 1))
) )
@ -360,7 +370,8 @@ def validate_host_label(s):
if not (c.isalpha() or c.isdigit() or c == '-'): if not (c.isalpha() or c.isdigit() or c == '-'):
return ( return (
InvalidValueError( InvalidValueError(
'Host label should contain only letters, digits or hypens, but it contains "%s"' % 'Host label should contain only letters, digits or hypens,'
' but it contains "%s"' %
c, Mark('', 0, i + 1)) c, Mark('', 0, i + 1))
) )
@ -426,7 +437,8 @@ def validate_string(s):
@type_validator('integer') @type_validator('integer')
def validate_integer(s, min=None, max=None): def validate_integer(s, min=None, max=None):
leading_whitespace_len = 0 leading_whitespace_len = 0
while leading_whitespace_len < len(s) and s[leading_whitespace_len].isspace(): while leading_whitespace_len < len(s) \
and s[leading_whitespace_len].isspace():
leading_whitespace_len += 1 leading_whitespace_len += 1
s = s.strip() s = s.strip()

@ -124,7 +124,8 @@ class ConfigurationTests(unittest.TestCase):
c.set_default('%s.param2' % self.section, 'value2') c.set_default('%s.param2' % self.section, 'value2')
self.assertEqual( self.assertEqual(
[('param1', 'value1'), ('param2', 'value2')], sorted(c.section(self.section).items())) [('param1', 'value1'), ('param2', 'value2')],
sorted(c.section(self.section).items()))
def test_subsection_get(self): def test_subsection_get(self):
c = Configuration() c = Configuration()

@ -83,7 +83,8 @@ class IntegerTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
self.assertEqual(123, v) self.assertEqual(123, v)
class HostAddressTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase): class HostAddressTypeValidatorTests(TypeValidatorTestHelper,
unittest.TestCase):
type_name = 'host_address' type_name = 'host_address'
def test_ipv4_address(self): def test_ipv4_address(self):
@ -135,7 +136,8 @@ class HostAddressTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
self.assertEqual(8, e.mark.column) self.assertEqual(8, e.mark.column)
class NetworkAddressTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase): class NetworkAddressTypeValidatorTests(TypeValidatorTestHelper,
unittest.TestCase):
type_name = 'network_address' type_name = 'network_address'
def test_ipv4_network(self): def test_ipv4_network(self):
@ -200,7 +202,8 @@ class PortTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase):
self.assertEqual(123, v) self.assertEqual(123, v)
class HostAndPortTypeValidatorTests(TypeValidatorTestHelper, unittest.TestCase): class HostAndPortTypeValidatorTests(TypeValidatorTestHelper,
unittest.TestCase):
type_name = 'host_and_port' type_name = 'host_and_port'
def test_ipv4_address(self): def test_ipv4_address(self):