Merge branch 'feature_boolean_parameter' of https://github.com/asteven/cdist

This commit is contained in:
Nico Schottelius 2012-02-16 11:04:50 +01:00
commit 27fb4374d3
11 changed files with 135 additions and 11 deletions

View File

@ -101,12 +101,15 @@ conf/type/<name>/gencode-local::
conf/type/<name>/gencode-remote::
Used to generate code to be executed on the client.
conf/type/<name>/parameters/required::
conf/type/<name>/parameter/required::
Parameters required by type, \n seperated list.
conf/type/<name>/parameters/optional::
conf/type/<name>/parameter/optional::
Parameters optionally accepted by type, \n seperated list.
conf/type/<name>/parameter/boolean::
Boolean parameters accepted by type, \n seperated list.
conf/type/<name>/explorer::
Location of the type specific explorers.
This directory is referenced by the variable __type_explorer (see below).

View File

@ -40,7 +40,7 @@ A list of supported types can be found in the cdist-reference(7) manpage.
SINGLETON TYPES
---------------
If a type is flagged as a singleton, it may be used only
If a type is flagged as a singleton, it may be used only
once per host. This is useful for types which can be used only once on a
system. Singleton types do not take an object name as argument.
@ -72,15 +72,42 @@ To begin a new type, just create the directory **conf/type/__NAME**.
DEFINING PARAMETERS
-------------------
Every type consists of optional and required parameters, which must
be created in a newline seperated file in ***parameters/required*** and
***parameters/optional***. If either or both missing, the type will have
no required, no optional or no parameters at all.
Every type consists of required, optional and boolean parameters, which must
be created in a newline seperated file in ***parameter/required***,
***parameter/optional*** and ***parameter/boolean***. If either is missing,
the type will have no required, no optional, no boolean or no parameters at
all.
Example:
--------------------------------------------------------------------------------
echo servername >> conf/type/__nginx_vhost/parameter/required
echo logdirectory >> conf/type/__nginx_vhost/parameter/optional
echo use_ssl >> conf/type/__nginx_vhost/parameter/boolean
--------------------------------------------------------------------------------
USING PARAMETERS
----------------
The parameters given to a type can be accessed and used in all type scripts
(e.g manifest, gencode-*, explorer/*). Note that boolean parameters are
represented by file existence. File exists -> True,
file does not exist -> False
Example: (e.g. in conf/type/__nginx_vhost/manifest)
--------------------------------------------------------------------------------
# required parameter
servername="$(cat "$__object/parameter/servername")"
# optional parameter
if [ -f "$__object/parameter/logdirectory" ]; then
logdirectory="$(cat "$__object/parameter/logdirectory")"
fi
# boolean parameter
if [ -f "$__object/parameter/use_ssl" ]; then
# file exists -> True
# do some fancy ssl stuff
fi
--------------------------------------------------------------------------------
@ -116,7 +143,7 @@ SINGLETON - ONLY INSTANCE ONLY
------------------------------
If you want to ensure that a type can only be used once per target, you can
mark it as a singleton: Just create the (empty) file "singleton" in your type
directory:
directory:
--------------------------------------------------------------------------------
touch conf/type/__NAME/singleton
@ -128,7 +155,7 @@ This will also change the way your type must be called:
__YOURTYPE --parameter value
--------------------------------------------------------------------------------
As you can see, the object ID is omitted, because it does not make any sense,
As you can see, the object ID is omitted, because it does not make any sense,
if your type can be used only once.

View File

@ -82,6 +82,7 @@ class CdistType(object):
self.__explorers = None
self.__required_parameters = None
self.__optional_parameters = None
self.__boolean_parameters = None
def __repr__(self):
return '<CdistType %s>' % self.name
@ -144,3 +145,19 @@ class CdistType(object):
finally:
self.__optional_parameters = parameters
return self.__optional_parameters
@property
def boolean_parameters(self):
"""Return a list of boolean parameters"""
if not self.__boolean_parameters:
parameters = []
try:
with open(os.path.join(self.absolute_path, "parameter", "boolean")) as fd:
for line in fd:
parameters.append(line.strip())
except EnvironmentError:
# error ignored
pass
finally:
self.__boolean_parameters = parameters
return self.__boolean_parameters

View File

@ -87,7 +87,7 @@ class Emulator(object):
def commandline(self):
"""Parse command line"""
parser = argparse.ArgumentParser(add_help=False)
parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS)
for parameter in self.cdist_type.optional_parameters:
argument = "--" + parameter
@ -95,6 +95,9 @@ class Emulator(object):
for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter
parser.add_argument(argument, dest=parameter, action='store', required=True)
for parameter in self.cdist_type.boolean_parameters:
argument = "--" + parameter
parser.add_argument(argument, dest=parameter, action='store_const', const='')
# If not singleton support one positional parameter
if not self.cdist_type.is_singleton:

View File

@ -126,7 +126,7 @@ class AutoRequireEmulatorTestCase(test.CdistTestCase):
self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
class ArgumentsWithDashesTestCase(test.CdistTestCase):
class ArgumentsTestCase(test.CdistTestCase):
def setUp(self):
self.temp_dir = self.mkdtemp()
@ -159,3 +159,59 @@ class ArgumentsWithDashesTestCase(test.CdistTestCase):
cdist_type = core.CdistType(self.local.type_path, '__arguments_with_dashes')
cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'some-id')
self.assertTrue('with-dash' in cdist_object.parameters)
def test_boolean(self):
type_name = '__arguments_boolean'
object_id = 'some-id'
argv = [type_name, object_id, '--boolean1']
os.environ.update(self.env)
emu = emulator.Emulator(argv)
emu.run()
cdist_type = core.CdistType(self.local.type_path, type_name)
cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
self.assertTrue('boolean1' in cdist_object.parameters)
self.assertFalse('boolean2' in cdist_object.parameters)
# empty file -> True
self.assertTrue(cdist_object.parameters['boolean1'] == '')
def test_required(self):
type_name = '__arguments_required'
object_id = 'some-id'
value = 'some value'
argv = [type_name, object_id, '--required1', value, '--required2', value]
os.environ.update(self.env)
emu = emulator.Emulator(argv)
emu.run()
cdist_type = core.CdistType(self.local.type_path, type_name)
cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
self.assertTrue('required1' in cdist_object.parameters)
self.assertTrue('required2' in cdist_object.parameters)
self.assertEqual(cdist_object.parameters['required1'], value)
self.assertEqual(cdist_object.parameters['required2'], value)
# def test_required_missing(self):
# type_name = '__arguments_required'
# object_id = 'some-id'
# value = 'some value'
# argv = [type_name, object_id, '--required1', value]
# os.environ.update(self.env)
# emu = emulator.Emulator(argv)
#
# self.assertRaises(SystemExit, emu.run)
def test_optional(self):
type_name = '__arguments_optional'
object_id = 'some-id'
value = 'some value'
argv = [type_name, object_id, '--optional1', value]
os.environ.update(self.env)
emu = emulator.Emulator(argv)
emu.run()
cdist_type = core.CdistType(self.local.type_path, type_name)
cdist_object = core.CdistObject(cdist_type, self.local.object_path, object_id)
self.assertTrue('optional1' in cdist_object.parameters)
self.assertFalse('optional2' in cdist_object.parameters)
self.assertEqual(cdist_object.parameters['optional1'], value)

View File

@ -0,0 +1,2 @@
boolean1
boolean2

View File

@ -0,0 +1,2 @@
required1
required2

View File

@ -145,3 +145,14 @@ class TypeTestCase(test.CdistTestCase):
base_path = fixtures
cdist_type = core.CdistType(base_path, '__without_optional_parameters')
self.assertEqual(cdist_type.optional_parameters, [])
def test_with_boolean_parameters(self):
base_path = fixtures
cdist_type = core.CdistType(base_path, '__with_boolean_parameters')
self.assertEqual(cdist_type.boolean_parameters, ['boolean1', 'boolean2'])
def test_without_boolean_parameters(self):
base_path = fixtures
cdist_type = core.CdistType(base_path, '__without_boolean_parameters')
self.assertEqual(cdist_type.boolean_parameters, [])

View File

@ -0,0 +1,2 @@
boolean1
boolean2