A Treequel::Control module that implements the "Content Sync" control (RFC 4533)
NOTICE: This control currently doesn't do anything, as it depends on Intermediate Responses, which the underlying Ruby-LDAP library doesn't support (yet).
As with all Controls, you must first register the control with the Treequel::Directory object you're intending to search:
dir = Treequel.directory( 'ldap://ldap.acme.com/dc=acme,dc=com' ) dir.register_controls( Treequel::ContentSyncControl )
Once that's done, any Treequel::Branchset you create will have the #on_sync method:
# Build DHCP records out of all the hosts in the directory, then rebuild # everything when a host record changes. hosts = dir.filter( :ou => Hosts ).collection hosts.filter( :objectClass => :ipHost ).on_sync do || # end
See deveiate.org/projects/Treequel/ticket/6 Ticket: Add support for the RFC4533 Content Sync operation.
The control's OID
Sync mode constants (from RFC4533, section 2.2)
The callback to call when results change
Add the requisite instance variables to including Branchsets.
# File lib/treequel/controls/contentsync.rb, line 50 def initialize self.log.notice "The ContentSync control doesn't work yet -- it requires support for " + "IntermediateResponses, which Ruby-LDAP doesn't do yet. " + "See http://deveiate.org/projects/Treequel/ticket/6 for updates on the " + "status of this." @content_sync_callback = nil end
Override the Enumerable method to update the cookie value each time a page is fetched.
# File lib/treequel/controls/contentsync.rb, line 78 def each( &block ) super do |branch| self.log.debug "Looking for the sync control in controls: %p" % [ branch.controls ] branch.controls.each do |control| self.log.debug " got a %s control: %p" % [ CONTROL_NAMES[control.oid], control.decode, ] case control.oid when CONTROL_OIDS[:sync_state] self.log.debug " got a 'state' control" block.call( branch ) when CONTROL_OIDS[:sync_done] self.log.debug " got a 'done' control" break else self.log.info " got an unexpected control (%p)" % [ control ] end end end end
Clone the Branchset with a persistent change callback.
# File lib/treequel/controls/contentsync.rb, line 68 def on_sync( &callback ) newset = self.clone newset.content_sync_callback = callback return newset end
Treequel::Control API -- Get a configured LDAP::Control object for this Branchset.
# File lib/treequel/controls/contentsync.rb, line 129 def get_server_controls controls = super value = self.make_sync_control_value( 1, '', false ) return controls << LDAP::Control.new( OID, value, true ) end
Make the ASN.1 string for the control value out of the given
mode
, cookie
, reload_hint
.
# File lib/treequel/controls/contentsync.rb, line 108 def make_sync_control_value( mode, cookie, reload_hint ) # (http://tools.ietf.org/html/rfc4533#section-2.2): # syncRequestValue ::= SEQUENCE { # mode ENUMERATED { # -- 0 unused # refreshOnly (1), # -- 2 reserved # refreshAndPersist (3) # }, # cookie syncCookie OPTIONAL, # reloadHint BOOLEAN DEFAULT FALSE # } encoded_vals = [ OpenSSL::ASN1::Enumerated.new( SYNC_MODE_REFRESH_AND_PERSIST ) ] return OpenSSL::ASN1::Sequence.new( encoded_vals ).to_der end