rewrite options to dict parser, fixes #5032

reviewable/pr18780/r1
Matthias Blaser 11 years ago
parent 4c35b7f380
commit 1e1def3fbd

@ -111,6 +111,7 @@ import os
import pwd import pwd
import os.path import os.path
import tempfile import tempfile
import re
import shlex import shlex
def keyfile(module, user, write=False, path=None, manage_dir=True): def keyfile(module, user, write=False, path=None, manage_dir=True):
@ -170,33 +171,44 @@ def keyfile(module, user, write=False, path=None, manage_dir=True):
return keysfile return keysfile
def parseoptions(options): def parseoptions(module, options):
''' '''
reads a string containing ssh-key options reads a string containing ssh-key options
and returns a dictionary of those options and returns a dictionary of those options
''' '''
options_dict = {} options_dict = {}
if options: if options:
lex = shlex.shlex(options) token_exp = [
lex.quotes = ["'", '"'] # matches separator
lex.whitespace_split = True (r',+', False),
opt_parts = list(lex) # matches option with value, e.g. from="x,y"
(r'([a-z0-9-]+)="((?:[^"\\]|\\.)*)"', True),
# matches single option, e.g. no-agent-forwarding
(r'[a-z0-9-]+', True)
]
#options_list = options.strip().split(",") pos = 0
options_list = opt_parts while pos < len(options):
for option in options_list: match = None
# happen when there is comma at the end for pattern, is_valid_option in token_exp:
if option == '': regex = re.compile(pattern, re.IGNORECASE)
continue match = regex.match(options, pos)
if option.find("=") != -1: if match:
(arg,val) = option.split("=", 1) text = match.group(0)
if is_valid_option:
if len(match.groups()) == 2:
options_dict[match.group(1)] = match.group(2)
else: else:
arg = option options_dict[text] = None
val = None break
options_dict[arg] = val.replace('"', '').replace("'", "") if not match:
module.fail_json(msg="invalid option string: %s" % options)
else:
pos = match.end(0)
return options_dict return options_dict
def parsekey(raw_key): def parsekey(module, raw_key):
''' '''
parses a key, which may or may not contain a list parses a key, which may or may not contain a list
of ssh-key options at the beginning of ssh-key options at the beginning
@ -239,7 +251,7 @@ def parsekey(raw_key):
options = key_parts[0] options = key_parts[0]
# parse the options (if any) # parse the options (if any)
options = parseoptions(options) options = parseoptions(module, options)
# get key after the type index # get key after the type index
key = key_parts[(type_index + 1)] key = key_parts[(type_index + 1)]
@ -250,7 +262,7 @@ def parsekey(raw_key):
return (key, key_type, options, comment) return (key, key_type, options, comment)
def readkeys(filename): def readkeys(module, filename):
if not os.path.isfile(filename): if not os.path.isfile(filename):
return {} return {}
@ -258,7 +270,7 @@ def readkeys(filename):
keys = {} keys = {}
f = open(filename) f = open(filename)
for line in f.readlines(): for line in f.readlines():
key_data = parsekey(line) key_data = parsekey(module, line)
if key_data: if key_data:
# use key as identifier # use key as identifier
keys[key_data[0]] = key_data keys[key_data[0]] = key_data
@ -314,14 +326,14 @@ def enforce_state(module, params):
# check current state -- just get the filename, don't create file # check current state -- just get the filename, don't create file
do_write = False do_write = False
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir) params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
existing_keys = readkeys(params["keyfile"]) existing_keys = readkeys(module, params["keyfile"])
# Check our new keys, if any of them exist we'll continue. # Check our new keys, if any of them exist we'll continue.
for new_key in key: for new_key in key:
if key_options is not None: if key_options is not None:
new_key = "%s %s" % (key_options, new_key) new_key = "%s %s" % (key_options, new_key)
parsed_new_key = parsekey(new_key) parsed_new_key = parsekey(module, new_key)
if not parsed_new_key: if not parsed_new_key:
module.fail_json(msg="invalid key specified: %s" % new_key) module.fail_json(msg="invalid key specified: %s" % new_key)

Loading…
Cancel
Save