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:: conf/type/<name>/gencode-remote::
Used to generate code to be executed on the client. 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. 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. 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:: conf/type/<name>/explorer::
Location of the type specific explorers. Location of the type specific explorers.
This directory is referenced by the variable __type_explorer (see below). 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 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 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. 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 DEFINING PARAMETERS
------------------- -------------------
Every type consists of optional and required parameters, which must Every type consists of required, optional and boolean parameters, which must
be created in a newline seperated file in ***parameters/required*** and be created in a newline seperated file in ***parameter/required***,
***parameters/optional***. If either or both missing, the type will have ***parameter/optional*** and ***parameter/boolean***. If either is missing,
no required, no optional or no parameters at all. the type will have no required, no optional, no boolean or no parameters at
all.
Example: Example:
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
echo servername >> conf/type/__nginx_vhost/parameter/required echo servername >> conf/type/__nginx_vhost/parameter/required
echo logdirectory >> conf/type/__nginx_vhost/parameter/optional 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 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 mark it as a singleton: Just create the (empty) file "singleton" in your type
directory: directory:
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
touch conf/type/__NAME/singleton touch conf/type/__NAME/singleton
@ -128,7 +155,7 @@ This will also change the way your type must be called:
__YOURTYPE --parameter value __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. if your type can be used only once.

View file

@ -82,6 +82,7 @@ class CdistType(object):
self.__explorers = None self.__explorers = None
self.__required_parameters = None self.__required_parameters = None
self.__optional_parameters = None self.__optional_parameters = None
self.__boolean_parameters = None
def __repr__(self): def __repr__(self):
return '<CdistType %s>' % self.name return '<CdistType %s>' % self.name
@ -144,3 +145,19 @@ class CdistType(object):
finally: finally:
self.__optional_parameters = parameters self.__optional_parameters = parameters
return self.__optional_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): def commandline(self):
"""Parse command line""" """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: for parameter in self.cdist_type.optional_parameters:
argument = "--" + parameter argument = "--" + parameter
@ -95,6 +95,9 @@ class Emulator(object):
for parameter in self.cdist_type.required_parameters: for parameter in self.cdist_type.required_parameters:
argument = "--" + parameter argument = "--" + parameter
parser.add_argument(argument, dest=parameter, action='store', required=True) 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 singleton support one positional parameter
if not self.cdist_type.is_singleton: 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)) self.assertEqual(sorted(cdist_object.requirements), sorted(expected))
class ArgumentsWithDashesTestCase(test.CdistTestCase): class ArgumentsTestCase(test.CdistTestCase):
def setUp(self): def setUp(self):
self.temp_dir = self.mkdtemp() 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_type = core.CdistType(self.local.type_path, '__arguments_with_dashes')
cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'some-id') cdist_object = core.CdistObject(cdist_type, self.local.object_path, 'some-id')
self.assertTrue('with-dash' in cdist_object.parameters) 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 base_path = fixtures
cdist_type = core.CdistType(base_path, '__without_optional_parameters') cdist_type = core.CdistType(base_path, '__without_optional_parameters')
self.assertEqual(cdist_type.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