mirror of
https://github.com/xcat2/confluent.git
synced 2024-11-22 09:32:21 +00:00
Style cleanup on several files
This commit is contained in:
parent
5152759270
commit
2b086b9424
@ -21,9 +21,9 @@
|
||||
|
||||
import confluent.config.configmanager as configmanager
|
||||
import eventlet
|
||||
import Crypto.Protocol.KDF as kdf
|
||||
import Crypto.Hash as hash
|
||||
import os
|
||||
import Crypto.Protocol.KDF as KDF
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
|
||||
_passcache = {}
|
||||
@ -33,7 +33,7 @@ _passchecking = {}
|
||||
def _prune_passcache():
|
||||
# This function makes sure we don't remember a passphrase in memory more
|
||||
# than 10 seconds
|
||||
while (1):
|
||||
while True:
|
||||
curtime = time.time()
|
||||
for passent in _passcache.iterkeys():
|
||||
if passent[2] < curtime - 10:
|
||||
@ -88,7 +88,7 @@ def authorize(name, element, tenant=False, operation='create'):
|
||||
manager = configmanager.ConfigManager(tenant)
|
||||
userobj = manager.get_user(user)
|
||||
if userobj: # returning
|
||||
return (userobj, manager, user, tenant)
|
||||
return userobj, manager, user, tenant
|
||||
return None
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ def check_user_passphrase(name, passphrase, element=None, tenant=False):
|
||||
embedded in name)
|
||||
"""
|
||||
# The reason why tenant is 'False' instead of 'None':
|
||||
# None means explictly not a tenant. False means check
|
||||
# None means explicitly not a tenant. False means check
|
||||
# the username for signs of being a tenant
|
||||
# If there is any sign of guessing on a user, all valid and
|
||||
# invalid attempts are equally slowed to no more than 20 per second
|
||||
@ -135,7 +135,7 @@ def check_user_passphrase(name, passphrase, element=None, tenant=False):
|
||||
cfm = configmanager.ConfigManager(tenant)
|
||||
ucfg = cfm.get_user(user)
|
||||
if ucfg is None or 'cryptpass' not in ucfg:
|
||||
eventlet.sleep(0.05) # stall even on test for existance of a username
|
||||
eventlet.sleep(0.05) # stall even on test for existence of a username
|
||||
return None
|
||||
_passchecking[(user, tenant)] = True
|
||||
# TODO(jbjohnso): WORKERPOOL
|
||||
@ -143,8 +143,8 @@ def check_user_passphrase(name, passphrase, element=None, tenant=False):
|
||||
# throw it at the worker pool when implemented
|
||||
# maybe a distinct worker pool, wondering about starving out non-auth stuff
|
||||
salt, crypt = ucfg['cryptpass']
|
||||
crypted = kdf.PBKDF2(passphrase, salt, 32, 10000,
|
||||
lambda p, s: hash.HMAC.new(p, s, hash.SHA256).digest()
|
||||
crypted = KDF.PBKDF2(passphrase, salt, 32, 10000,
|
||||
lambda p, s: hmac.new(p, s, hashlib.sha256).digest()
|
||||
)
|
||||
del _passchecking[(user, tenant)]
|
||||
eventlet.sleep(0.05) # either way, we want to stall so that client can't
|
||||
|
@ -13,24 +13,30 @@
|
||||
# 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.
|
||||
|
||||
|
||||
class ConfluentException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotFoundException(ConfluentException):
|
||||
# Something that could be construed as a name was not found
|
||||
# basically, picture an http error code 404
|
||||
pass
|
||||
|
||||
|
||||
class InvalidArgumentException(ConfluentException):
|
||||
# Something from the remote client wasn't correct
|
||||
# like http code 400
|
||||
pass
|
||||
|
||||
|
||||
class TargetEndpointUnreachable(ConfluentException):
|
||||
# A target system was unavailable. For example, a BMC
|
||||
# was unreachable. http code 504
|
||||
pass
|
||||
|
||||
|
||||
class ForbiddenRequest(ConfluentException):
|
||||
# The client request is not allowed by authorization engine
|
||||
pass
|
||||
|
@ -52,7 +52,7 @@ def group_creation_resources():
|
||||
yield confluent.messages.Attributes(
|
||||
kv={'name': None}, desc="Name of the group").html() + '<br>'
|
||||
yield confluent.messages.ListAttributes(kv={'nodes': []},
|
||||
desc='Nodes to add to the group').html() + '<br>\n'
|
||||
desc='Nodes to add to the group').html() + '<br>\n'
|
||||
for attr in sorted(attribs.node.iterkeys()):
|
||||
if attr == 'groups':
|
||||
continue
|
||||
@ -60,7 +60,8 @@ def group_creation_resources():
|
||||
yield confluent.messages.CryptedAttributes(
|
||||
kv={attr: None},
|
||||
desc=attribs.node[attr]['description']).html() + '<br>\n'
|
||||
elif 'type' in attribs.node[attr] and list == attribs.node[attr]['type']:
|
||||
elif 'type' in attribs.node[attr] and list == attribs.node[attr][
|
||||
'type']:
|
||||
yield confluent.messages.ListAttributes(
|
||||
kv={attr: []},
|
||||
desc=attribs.node[attr]['description']).html() + '<br>\n'
|
||||
@ -78,7 +79,8 @@ def node_creation_resources():
|
||||
yield confluent.messages.CryptedAttributes(
|
||||
kv={attr: None},
|
||||
desc=attribs.node[attr]['description']).html() + '<br>\n'
|
||||
elif 'type' in attribs.node[attr] and list == attribs.node[attr]['type']:
|
||||
elif 'type' in attribs.node[attr] and list == attribs.node[attr][
|
||||
'type']:
|
||||
yield confluent.messages.ListAttributes(
|
||||
kv={attr: []},
|
||||
desc=attribs.node[attr]['description']).html() + '<br>\n'
|
||||
@ -87,6 +89,7 @@ def node_creation_resources():
|
||||
kv={attr: None},
|
||||
desc=attribs.node[attr]['description']).html() + '<br>\n'
|
||||
|
||||
|
||||
create_resource_functions = {
|
||||
'/nodes/': node_creation_resources,
|
||||
'/groups/': group_creation_resources,
|
||||
@ -127,7 +130,7 @@ def _get_query_dict(env, reqbody, reqtype):
|
||||
elif 'application/json' == reqtype:
|
||||
pbody = json.loads(reqbody)
|
||||
for key in pbody.iterkeys():
|
||||
qdict[key] = pbody[ky]
|
||||
qdict[key] = pbody[key]
|
||||
if 'restexplorerhonorkey' in qdict:
|
||||
nqdict = {}
|
||||
for key in qdict:
|
||||
@ -145,6 +148,7 @@ def _authorize_request(env, operation):
|
||||
|
||||
"""
|
||||
authdata = False
|
||||
name = ''
|
||||
cookie = Cookie.SimpleCookie()
|
||||
if 'HTTP_COOKIE' in env:
|
||||
#attempt to use the cookie. If it matches
|
||||
@ -178,10 +182,10 @@ def _authorize_request(env, operation):
|
||||
'target': env['PATH_INFO'],
|
||||
}
|
||||
authinfo = {'code': 200,
|
||||
'cookie': cookie,
|
||||
'cfgmgr': authdata[1],
|
||||
'username': authdata[2],
|
||||
'userdata': authdata[0]}
|
||||
'cookie': cookie,
|
||||
'cfgmgr': authdata[1],
|
||||
'username': authdata[2],
|
||||
'userdata': authdata[0]}
|
||||
if authdata[3] is not None:
|
||||
auditmsg['tenant'] = authdata[3]
|
||||
authinfo['tenant'] = authdata[3]
|
||||
@ -191,13 +195,13 @@ def _authorize_request(env, operation):
|
||||
return authinfo
|
||||
else:
|
||||
return {'code': 401}
|
||||
# TODO(jbjohnso): actually evaluate the request for authorization
|
||||
# In theory, the x509 or http auth stuff will get translated and then
|
||||
# passed on to the core authorization function in an appropriate form
|
||||
# expresses return in the form of http code
|
||||
# 401 if there is no known identity
|
||||
# 403 if valid identity, but no access
|
||||
# going to run 200 just to get going for now
|
||||
# TODO(jbjohnso): actually evaluate the request for authorization
|
||||
# In theory, the x509 or http auth stuff will get translated and then
|
||||
# passed on to the core authorization function in an appropriate form
|
||||
# expresses return in the form of http code
|
||||
# 401 if there is no known identity
|
||||
# 403 if valid identity, but no access
|
||||
# going to run 200 just to get going for now
|
||||
|
||||
|
||||
def _pick_mimetype(env):
|
||||
@ -239,6 +243,7 @@ def resourcehandler(env, start_response):
|
||||
yield '500 - Internal Server Error'
|
||||
return
|
||||
|
||||
|
||||
def resourcehandler_backend(env, start_response):
|
||||
"""Function to handle new wsgi requests
|
||||
"""
|
||||
@ -327,10 +332,11 @@ def resourcehandler_backend(env, start_response):
|
||||
try:
|
||||
rsp = json.dumps(rspdata)
|
||||
except UnicodeDecodeError:
|
||||
rsp = json.dumps(rspdata, encoding='cp437')
|
||||
except UnicodeDecodeError:
|
||||
rsp = json.dumps({'session': querydict['session'],
|
||||
'data': 'DECODEERROR'})
|
||||
try:
|
||||
rsp = json.dumps(rspdata, encoding='cp437')
|
||||
except UnicodeDecodeError:
|
||||
rsp = json.dumps({'session': querydict['session'],
|
||||
'data': 'DECODEERROR'})
|
||||
start_response('200 OK', headers)
|
||||
yield rsp
|
||||
return
|
||||
@ -367,7 +373,7 @@ def resourcehandler_backend(env, start_response):
|
||||
def _assemble_html(responses, resource, querydict, url):
|
||||
yield '<html><head><title>' \
|
||||
'Confluent REST Explorer: ' + url + '</title></head>' \
|
||||
'<body><form action="' + resource + '" method="post">'
|
||||
'<body><form action="' + resource + '" method="post">'
|
||||
if querydict:
|
||||
yield 'Response to input data:<br>' + \
|
||||
json.dumps(querydict, separators=(',', ': '),
|
||||
@ -399,7 +405,8 @@ def _assemble_html(responses, resource, querydict, url):
|
||||
firstpass = True
|
||||
for y in create_resource_functions[url]():
|
||||
if firstpass:
|
||||
yield "<hr>Define new resource in %s:<BR>" % url.split("/")[-2]
|
||||
yield "<hr>Define new resource in %s:<BR>" % \
|
||||
url.split("/")[-2]
|
||||
firstpass = False
|
||||
yield y
|
||||
yield ('<input value="create" name="restexplorerop" type="submit">'
|
||||
@ -464,7 +471,7 @@ def serve():
|
||||
#also, the potential for direct http can be handy
|
||||
#todo remains unix domain socket for even http
|
||||
eventlet.wsgi.server(eventlet.listen(("", 4005)), resourcehandler,
|
||||
log=False, log_output=False, debug=False)
|
||||
log=False, log_output=False, debug=False)
|
||||
|
||||
|
||||
class HttpApi(object):
|
||||
@ -475,4 +482,5 @@ class HttpApi(object):
|
||||
auditlog = log.Logger('audit')
|
||||
self.server = eventlet.spawn(serve)
|
||||
|
||||
|
||||
_cleaner = eventlet.spawn(_sessioncleaner)
|
||||
|
@ -80,6 +80,7 @@ import time
|
||||
|
||||
_loggers = {}
|
||||
|
||||
|
||||
class Events(object):
|
||||
(
|
||||
undefined, clearscreen, clientconnect, clientdisconnect,
|
||||
@ -186,7 +187,7 @@ class Logger(object):
|
||||
textfile = open(self.textpath, mode='r')
|
||||
binfile = open(self.binpath, mode='r')
|
||||
except IOError:
|
||||
return ('', 0)
|
||||
return '', 0
|
||||
fcntl.flock(binfile, fcntl.LOCK_SH)
|
||||
binfile.seek(0, 2)
|
||||
binidx = binfile.tell() - 16
|
||||
@ -210,14 +211,14 @@ class Logger(object):
|
||||
textdata = ''
|
||||
fcntl.flock(textfile, fcntl.LOCK_SH)
|
||||
while offsets:
|
||||
(offset, len) = offsets.pop()
|
||||
(offset, length) = offsets.pop()
|
||||
textfile.seek(offset, 0)
|
||||
textdata += textfile.read(len)
|
||||
textdata += textfile.read(length)
|
||||
fcntl.flock(textfile, fcntl.LOCK_UN)
|
||||
textfile.close()
|
||||
if termstate is None:
|
||||
termstate = 0
|
||||
return (textdata, termstate)
|
||||
return textdata, termstate
|
||||
|
||||
def log(self, logdata=None, ltype=None, event=0, eventdata=None):
|
||||
if type(logdata) not in (str, unicode, dict):
|
||||
|
@ -29,15 +29,14 @@ import confluent.pluginapi as pluginapi
|
||||
import confluent.httpapi as httpapi
|
||||
import confluent.sockapi as sockapi
|
||||
import eventlet
|
||||
import eventlet.backdoor as backdoor
|
||||
from eventlet.green import socket
|
||||
from eventlet import wsgi
|
||||
#import eventlet.backdoor as backdoor
|
||||
import fcntl
|
||||
import multiprocessing
|
||||
#import multiprocessing
|
||||
import sys
|
||||
import os
|
||||
import signal
|
||||
|
||||
|
||||
def _daemonize():
|
||||
thispid = os.fork()
|
||||
if thispid > 0:
|
||||
@ -48,7 +47,7 @@ def _daemonize():
|
||||
if thispid > 0:
|
||||
print 'confluent server starting as pid %d' % thispid
|
||||
os._exit(0)
|
||||
os.closerange(0,2)
|
||||
os.closerange(0, 2)
|
||||
os.umask(63)
|
||||
os.open(os.devnull, os.O_RDWR)
|
||||
os.dup2(0, 1)
|
||||
@ -69,7 +68,8 @@ def _checkpidfile():
|
||||
fcntl.flock(pidfile, fcntl.LOCK_EX)
|
||||
pid = pidfile.read()
|
||||
if pid != '':
|
||||
print '/var/run/confluent/pid exists and indicates %s is still running' % pid
|
||||
print ('/var/run/confluent/pid exists and indicates %s is still '
|
||||
'running' % pid)
|
||||
sys.exit(1)
|
||||
pidfile.write(str(os.getpid()))
|
||||
fcntl.flock(pidfile, fcntl.LOCK_UN)
|
||||
@ -84,21 +84,24 @@ def _checkpidfile():
|
||||
fcntl.flock(pidfile, fcntl.LOCK_SH)
|
||||
pid = pidfile.read()
|
||||
if pid != str(os.getpid()):
|
||||
print '/var/run/confluent/pid exists and indicates %s is still running' % pid
|
||||
print ('/var/run/confluent/pid exists and indicates %s is still '
|
||||
'running' % pid)
|
||||
sys.exit(1)
|
||||
fcntl.flock(pidfile, fcntl.LOCK_UN)
|
||||
pidfile.close()
|
||||
|
||||
|
||||
def terminate(signal, frame):
|
||||
def terminate(signalname, frame):
|
||||
sys.exit(0)
|
||||
|
||||
def exit():
|
||||
|
||||
def doexit():
|
||||
pidfile = open('/var/run/confluent/pid')
|
||||
pid = pidfile.read()
|
||||
if pid == str(os.getpid()):
|
||||
os.remove('/var/run/confluent/pid')
|
||||
|
||||
|
||||
def run():
|
||||
_checkpidfile()
|
||||
pluginapi.load_plugins()
|
||||
@ -106,7 +109,7 @@ def run():
|
||||
_updatepidfile()
|
||||
signal.signal(signal.SIGINT, terminate)
|
||||
signal.signal(signal.SIGTERM, terminate)
|
||||
#TODO(jbjohnso): eventlet has a bug about unix domain sockets, this code
|
||||
#TODO(jbjohnso): eventlet has a bug about unix domain sockets, this code
|
||||
#works with bugs fixed
|
||||
#dbgsock = eventlet.listen("/var/run/confluent/dbg.sock",
|
||||
# family=socket.AF_UNIX)
|
||||
@ -115,7 +118,6 @@ def run():
|
||||
webservice.start()
|
||||
sockservice = sockapi.SockApi()
|
||||
sockservice.start()
|
||||
atexit.register(exit)
|
||||
while (1):
|
||||
atexit.register(doexit)
|
||||
while 1:
|
||||
eventlet.sleep(100)
|
||||
|
||||
|
@ -39,7 +39,6 @@ def _htmlify_structure(indict):
|
||||
return ret + '</ul>'
|
||||
|
||||
|
||||
|
||||
class ConfluentMessage(object):
|
||||
readonly = False
|
||||
defaultvalue = ''
|
||||
@ -68,23 +67,26 @@ class ConfluentMessage(object):
|
||||
for key in self.kvpairs.iterkeys():
|
||||
val = self.kvpairs[key]
|
||||
value = self.defaultvalue
|
||||
type = self.defaulttype
|
||||
valtype = self.defaulttype
|
||||
notes = []
|
||||
if val is not None and 'value' in val:
|
||||
value = val['value']
|
||||
if 'inheritedfrom' in val:
|
||||
notes.append('Inherited from %s' % val['inheritedfrom'])
|
||||
if 'expression' in val:
|
||||
notes.append('Derived from expression "%s"' % val['expression'])
|
||||
notes.append(
|
||||
'Derived from expression "%s"' % val['expression'])
|
||||
elif val is not None and 'expression' in val and 'broken' in val:
|
||||
value = "*BROKEN*"
|
||||
notes.append('Derived from expression "%s"' % val['expression'])
|
||||
notes.append(
|
||||
'Derived from expression "%s"' % val['expression'])
|
||||
notes.append('Broken because of %s' % val['broken'])
|
||||
elif val is not None and 'expression' in val:
|
||||
value = val['expression']
|
||||
if value is None:
|
||||
value = ''
|
||||
if val is not None and value == '' and 'isset' in val and val['isset'] is True:
|
||||
if val is not None and value == '' and 'isset' in val and val[
|
||||
'isset'] is True:
|
||||
# an encrypted value, put some *** to show it is set
|
||||
# in the explorer
|
||||
if 'inheritedfrom' in val:
|
||||
@ -95,19 +97,19 @@ class ConfluentMessage(object):
|
||||
if len(val) == 0 and not self.readonly:
|
||||
snippet += ('<input type="{0}" name="{1}" value="" '
|
||||
' "title="{2}">'
|
||||
).format(type, key, self.desc)
|
||||
).format(valtype, key, self.desc)
|
||||
for v in val:
|
||||
if self.readonly:
|
||||
snippet += _htmlify_structure(v)
|
||||
else:
|
||||
snippet += ('<input type="{0}" name="{1}" value="{2}" '
|
||||
' "title="{3}">'
|
||||
).format(type, key, v, self.desc)
|
||||
).format(valtype, key, v, self.desc)
|
||||
if not self.readonly:
|
||||
snippet += (
|
||||
'<input type="{0}" name="{1}" value="" title="{2}">'
|
||||
'<input type="checkbox" name="restexplorerhonorkey" '
|
||||
'value="{1}">').format(type, key, self.desc)
|
||||
'value="{1}">').format(valtype, key, self.desc)
|
||||
return snippet
|
||||
if self.readonly:
|
||||
snippet += "{0}: {1}".format(key, value)
|
||||
@ -116,7 +118,7 @@ class ConfluentMessage(object):
|
||||
'<input type="{0}" name="{1}" value="{2}" '
|
||||
'title="{3}"><input type="checkbox" '
|
||||
'name="restexplorerhonorkey" value="{1}">'
|
||||
).format(type, key, value, self.desc)
|
||||
).format(valtype, key, value, self.desc)
|
||||
if len(notes) > 0:
|
||||
snippet += '(' + ','.join(notes) + ')'
|
||||
return snippet
|
||||
@ -128,7 +130,6 @@ class DeletedResource(ConfluentMessage):
|
||||
|
||||
|
||||
class ConfluentChoiceMessage(ConfluentMessage):
|
||||
|
||||
def html(self):
|
||||
snippet = ""
|
||||
for key in self.kvpairs.iterkeys():
|
||||
@ -143,7 +144,7 @@ class ConfluentChoiceMessage(ConfluentMessage):
|
||||
snippet += '<option value="%s">%s</option>' % (opt, opt)
|
||||
snippet += '</select>'
|
||||
snippet += '<input type="checkbox" name="restexplorerhonorkey" '
|
||||
snippet += 'value="%s">' % (key)
|
||||
snippet += 'value="{0}">'.format(key)
|
||||
return snippet
|
||||
|
||||
|
||||
@ -200,7 +201,6 @@ def get_input_message(path, operation, inputdata, nodes=None):
|
||||
|
||||
|
||||
class InputAttributes(ConfluentMessage):
|
||||
|
||||
def __init__(self, path, inputdata, nodes=None):
|
||||
self.nodeattribs = {}
|
||||
nestedmode = False
|
||||
@ -263,7 +263,7 @@ class InputPowerMessage(ConfluentMessage):
|
||||
'off',
|
||||
'reset',
|
||||
'boot',
|
||||
])
|
||||
])
|
||||
|
||||
def __init__(self, path, nodes, inputdata):
|
||||
self.powerbynode = {}
|
||||
@ -276,13 +276,13 @@ class InputPowerMessage(ConfluentMessage):
|
||||
raise exc.InvalidArgumentException()
|
||||
datum = inputdata[key]
|
||||
if ('state' not in datum or
|
||||
datum['state'] not in self.valid_values):
|
||||
datum['state'] not in self.valid_values):
|
||||
raise exc.InvalidArgumentException()
|
||||
self.powerbynode[key] = datum['state']
|
||||
else: # we have a state argument not by node
|
||||
datum = inputdata
|
||||
if ('state' not in datum or
|
||||
datum['state'] not in self.valid_values):
|
||||
datum['state'] not in self.valid_values):
|
||||
raise exc.InvalidArgumentException()
|
||||
for node in nodes:
|
||||
self.powerbynode[node] = datum['state']
|
||||
@ -298,7 +298,7 @@ class BootDevice(ConfluentChoiceMessage):
|
||||
'setup',
|
||||
'default',
|
||||
'cd',
|
||||
])
|
||||
])
|
||||
|
||||
def __init__(self, node, device):
|
||||
if device not in self.valid_values:
|
||||
@ -321,13 +321,13 @@ class InputBootDevice(BootDevice):
|
||||
raise exc.InvalidArgumentException()
|
||||
datum = inputdata[key]
|
||||
if ('state' not in datum or
|
||||
datum['state'] not in self.valid_values):
|
||||
datum['state'] not in self.valid_values):
|
||||
raise exc.InvalidArgumenTException()
|
||||
self.bootdevbynode[key] = datum['nextdevice']
|
||||
else:
|
||||
datum = inputdata
|
||||
if ('nextdevice' not in datum or
|
||||
datum['nextdevice'] not in self.valid_values):
|
||||
datum['nextdevice'] not in self.valid_values):
|
||||
raise exc.InvalidArgumentException()
|
||||
for node in nodes:
|
||||
self.bootdevbynode[node] = datum['nextdevice']
|
||||
@ -342,7 +342,7 @@ class PowerState(ConfluentChoiceMessage):
|
||||
'off',
|
||||
'reset',
|
||||
'boot',
|
||||
])
|
||||
])
|
||||
|
||||
def __init__(self, node, state):
|
||||
self.kvpairs = {
|
||||
@ -391,6 +391,7 @@ class HealthSummary(ConfluentMessage):
|
||||
else:
|
||||
self.kvpairs = {name: {'health': {'value': health}}}
|
||||
|
||||
|
||||
class Attributes(ConfluentMessage):
|
||||
def __init__(self, name=None, kv=None, desc=''):
|
||||
self.desc = desc
|
||||
|
Loading…
Reference in New Issue
Block a user