diff options
-rw-r--r-- | doc/client/tools/actions.txt | 24 | ||||
-rw-r--r-- | doc/server/plugins/generators/cfg.txt | 3 | ||||
-rw-r--r-- | schemas/authorizedkeys.xsd | 64 | ||||
-rw-r--r-- | schemas/types.xsd | 9 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/__init__.py | 6 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Bundler.py | 5 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py | 13 | ||||
-rwxr-xr-x | tools/bcfg2_local.py | 5 |
8 files changed, 100 insertions, 29 deletions
diff --git a/doc/client/tools/actions.txt b/doc/client/tools/actions.txt index 61bb8854b..52d07eb4f 100644 --- a/doc/client/tools/actions.txt +++ b/doc/client/tools/actions.txt @@ -30,10 +30,11 @@ return status, causing failures to still not be centrally reported. If central reporting of action failure is desired, set this attribute to 'check'. -Actions are not completely defined inside of a bundle; they are an -abstract entry. The Rules plugin can bind these entries. For example -to include the above action in a bundle, first the Action entry must -be included in the bundle: +Actions may be completely defined inside of a bundle with the use of +:ref:`server-configurationentries`, much like Packages, Services or Paths. +The Rules plugin can also bind these entries. For example to include the +above action in a bundle, first the Action entry must be included in the +bundle: .. code-block:: xml @@ -79,3 +80,18 @@ requires this key. <Action timing='post' name='apt-key-update' command='apt-key adv --recv-keys --keyserver hkp://pgp.mit.edu 0C5A2783' when='modified' status='check'/> </Group> </Rules> + +Example BoundAction (add RPM GPG keys) +====================================== + +This example will add the RPM-GPG-KEY-redhat-release key to the RPM +GPG keyring **before** Package entries are handled on the client run. + +.. code-block:: xml + + <Bundle name="rpm-gpg-keys"> + <Group name='rhel'> + <Path name="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"/> + <BoundAction timing="pre" name="install rpm key" command="rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release" when="modified" status="check"/> + </Group> + </Bundle> diff --git a/doc/server/plugins/generators/cfg.txt b/doc/server/plugins/generators/cfg.txt index 8220fb21b..7a404c824 100644 --- a/doc/server/plugins/generators/cfg.txt +++ b/doc/server/plugins/generators/cfg.txt @@ -539,7 +539,8 @@ Example </Group> <Allow from="/root/.ssh/id_rsa.pub" host="foo.example.com"/> <Allow from="/home/foo_user/.ssh/id_rsa.pub"> - <Params command="/home/foo_user/.ssh/ssh_command_filter"/> + <Option name="command" value="/home/foo_user/.ssh/ssh_command_filter"/> + <Option name="no-X11-forwarding"/> </Allow> <Allow> ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDw/rgKQeARRAHK5bQQhAAe1b+gzdtqBXWrZIQ6cIaLgxqj76TwZ3DY4A6aW9RgC4zzd0p4a9MfsScUIB4+UeZsx9GopUj4U6H8Vz7S3pXxrr4E9logVLuSfOLFbI/wMWNRuOANqquLYQ+JYWKeP4kagkVp0aAWp7mH5IOI0rp0A6qE2you4ep9N/nKvHDrtypwhYBWprsgTUXXMHnAWGmyuHGYWxNYBV9AARPdAvZfb8ggtuwibcOULlyK4DdVNbDTAN1/BDBE1ve6WZDcrc386KhqUGj/yoRyPjNZ46uZiOjRr3cdY6yUZoCwzzxvm5vle6mEbLjHgjGEMQMArzM9 vendor@example.com diff --git a/schemas/authorizedkeys.xsd b/schemas/authorizedkeys.xsd index 20e568a07..c3cd50181 100644 --- a/schemas/authorizedkeys.xsd +++ b/schemas/authorizedkeys.xsd @@ -49,6 +49,42 @@ <xsd:attributeGroup ref="py:genshiAttrs"/> </xsd:complexType> + <xsd:complexType name="OptionContainerType"> + <xsd:annotation> + <xsd:documentation> + An **OptionContainerType** is a tag used to provide logic. + Child entries of an OptionContainerType tag only apply to + machines that match the condition specified -- either + membership in a group, or a matching client name. + :xml:attribute:`OptionContainerType:negate` can be set to + negate the sense of the match. + </xsd:documentation> + </xsd:annotation> + <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:element name="Group" type="OptionContainerType"/> + <xsd:element name="Client" type="OptionContainerType"/> + <xsd:element name="Option" type="AuthorizedKeysOptionType"/> + </xsd:choice> + <xsd:attribute name='name' type='xsd:string'> + <xsd:annotation> + <xsd:documentation> + The name of the client or group to match on. Child entries + will only apply to this client or group (unless + :xml:attribute:`OptionContainerType:negate` is set). + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name='negate' type='xsd:boolean'> + <xsd:annotation> + <xsd:documentation> + Negate the sense of the match, so that child entries only + apply to a client if it is not a member of the given group + or does not have the given name. + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> + </xsd:complexType> + <xsd:complexType name="AllowType" mixed="true"> <xsd:annotation> <xsd:documentation> @@ -58,7 +94,9 @@ </xsd:annotation> <xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:group ref="py:genshiElements"/> - <xsd:element name="Params" type="AuthorizedKeysParamsType"/> + <xsd:element name="Group" type="OptionContainerType"/> + <xsd:element name="Client" type="OptionContainerType"/> + <xsd:element name="Option" type="AuthorizedKeysOptionType"/> </xsd:choice> <xsd:attribute name="from" type="xsd:string"> <xsd:annotation> @@ -86,16 +124,28 @@ <xsd:attributeGroup ref="py:genshiAttrs"/> </xsd:complexType> - <xsd:complexType name="AuthorizedKeysParamsType"> + <xsd:complexType name="AuthorizedKeysOptionType"> <xsd:annotation> <xsd:documentation> - Specify parameters for public key authentication and - connection. See :manpage:`sshd(8)` for details on allowable - parameters. + Specify options for public key authentication and connection. + See :manpage:`sshd(8)` for details on allowable options. </xsd:documentation> </xsd:annotation> - <xsd:attributeGroup ref="py:genshiAttrs"/> - <xsd:anyAttribute processContents="lax"/> + <xsd:attribute name="name" type="xsd:string" use="required"> + <xsd:annotation> + <xsd:documentation> + The name of the sshd option. + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> + <xsd:attribute name="value" type="xsd:string"> + <xsd:annotation> + <xsd:documentation> + The value of the sshd option. This can be omitted for + options that take no value. + </xsd:documentation> + </xsd:annotation> + </xsd:attribute> </xsd:complexType> <xsd:complexType name="AuthorizedKeysType"> diff --git a/schemas/types.xsd b/schemas/types.xsd index 5dec03cdb..5abc35144 100644 --- a/schemas/types.xsd +++ b/schemas/types.xsd @@ -115,7 +115,10 @@ <xsd:attribute type='ActionTimingEnum' name='timing'> <xsd:annotation> <xsd:documentation> - When the action is run. + When the action is run. Actions with "pre" timing are run + after important entries have been installed and before + bundle entries are installed. Actions with "post" timing + are run after bundle entries are installed. </xsd:documentation> </xsd:annotation> </xsd:attribute> @@ -123,9 +126,7 @@ <xsd:annotation> <xsd:documentation> If the action is always run, or is only run when a bundle - has been modified. Actions that run before bundle - installation ("pre" and "both") ignore the setting of - ``when`` and are always run regardless. + has been modified. </xsd:documentation> </xsd:annotation> </xsd:attribute> diff --git a/src/lib/Bcfg2/Client/__init__.py b/src/lib/Bcfg2/Client/__init__.py index 6243213cd..433fb570a 100644 --- a/src/lib/Bcfg2/Client/__init__.py +++ b/src/lib/Bcfg2/Client/__init__.py @@ -669,13 +669,15 @@ class Client(object): # first process prereq actions for bundle in bundles[:]: if bundle.tag == 'Bundle': - bmodified = any(item in self.whitelist for item in bundle) + bmodified = any((item in self.whitelist or + item in self.modified) for item in bundle) else: bmodified = False actions = [a for a in bundle.findall('./Action') if (a.get('timing') in ['pre', 'both'] and (bmodified or a.get('when') == 'always'))] - # now we process all "always actions" + # now we process all "pre" and "both" actions that are either + # always or the bundle has been modified if Bcfg2.Options.setup.interactive: self.promptFilter(iprompt, actions) self.DispatchInstallCalls(actions) diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py index f91bac634..b3824fb57 100644 --- a/src/lib/Bcfg2/Server/Plugins/Bundler.py +++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py @@ -52,15 +52,12 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data) #: Bundles by bundle name, rather than filename self.bundles = dict() - __init__.__doc__ = Bcfg2.Server.Plugin.Plugin.__init__.__doc__ def HandleEvent(self, event): Bcfg2.Server.Plugin.XMLDirectoryBacked.HandleEvent(self, event) self.bundles = dict([(b.bundle_name, b) for b in self.entries.values()]) - HandleEvent.__doc__ = \ - Bcfg2.Server.Plugin.XMLDirectoryBacked.HandleEvent.__doc__ def BuildStructures(self, metadata): bundleset = [] @@ -121,5 +118,3 @@ class Bundler(Bcfg2.Server.Plugin.Plugin, data.remove(child) bundleset.append(data) return bundleset - BuildStructures.__doc__ = \ - Bcfg2.Server.Plugin.Structure.BuildStructures.__doc__ diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py index 384d1bf12..895752c9c 100644 --- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py +++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py @@ -38,10 +38,13 @@ class CfgAuthorizedKeysGenerator(CfgGenerator, StructFile): spec = self.XMLMatch(metadata) rv = [] for allow in spec.findall("Allow"): - params = '' - if allow.find("Params") is not None: - params = ",".join("=".join(p) - for p in allow.find("Params").attrib.items()) + options = [] + for opt in allow.findall("Option"): + if opt.get("value"): + options.append("%s=%s" % (opt.get("name"), + opt.get("value"))) + else: + options.append(opt.get("name")) pubkey_name = allow.get("from") if pubkey_name: @@ -85,6 +88,6 @@ class CfgAuthorizedKeysGenerator(CfgGenerator, StructFile): (metadata.hostname, lxml.etree.tostring(allow))) continue - rv.append(" ".join([params, pubkey]).strip()) + rv.append(" ".join([",".join(options), pubkey]).strip()) return "\n".join(rv) get_data.__doc__ = CfgGenerator.get_data.__doc__ diff --git a/tools/bcfg2_local.py b/tools/bcfg2_local.py index 21b5ad8d4..5e5bca777 100755 --- a/tools/bcfg2_local.py +++ b/tools/bcfg2_local.py @@ -47,7 +47,10 @@ class LocalProxy(object): func = getattr(self.core, attr) if func.exposed: def inner(*args, **kwargs): - args = ((self.ipaddr, self.hostname), ) + args + # the port portion of the addresspair tuple isn't + # actually used, so it's safe to hardcode 6789 + # here. + args = ((self.ipaddr, 6789), ) + args return func(*args, **kwargs) return inner raise AttributeError(attr) |