WGmeta::Wrapper::ConfigT - Class for interfacing the wireguard configuration supporting concurrent access
Specialized child class of Wireguard::WGmeta::Wrapper::Config which is capable of handling concurrent access.
The interface is almost identical with the exception of "commit([$is_hot_config = FALSE, $plain = FALSE, $ref_hash_integrity_keys = undef])"
use Wireguard::WGmeta::Wrapper::ConfigT; my $wg_metaT = Wireguard::WGmeta::Wrapper::ConfigT->new('<path to wireguard configuration>');
To ensure that no inconsistent config files are generated, calls to a get_*() may result in a reload from disk - namely when the config file on disk is newer than the current (parsed) one. So keep in mind to commit() as soon as possible (this is obviously only true for environments where such situations are possible to occur)
get_*()
commit()
# thread/process A $wg_metaT->set('wg0', 'WG_0_PEER_A_PUBLIC_KEY', 'alias', 'A'); # thread/process B $wg_metaT->set('wg0', 'WG_0_PEER_A_PUBLIC_KEY', 'alias', 'B'); $wg_metaT->commit(1); # thread/process A (alias 'A' is overwritten by 'B') wg_metaT->disable_by_alias('wg0', 'A'); # throws exception `invalid alias`!
For more details about the reloading behaviour please refer to "_may_reload_from_disk([$interface = undef])".
Commit behaviour
FUNCTION commit($integrity_hashes) FOR $interface IN $known_interfaces IF has_changed($interface) THEN lock_exclusive($interface) UNLESS my_config_is_latest THEN $on_disk <- read_from_disk($interface) $contents <- create_wg_config($interface, $on_disk,$integrity_hashes) write($contents) FUNCTION create_wg_config($interface, $on_disk, $integrity_hashes); $may_conflicting <- search_for_common_data($interface, $on_disk) FOR $section IN $may_conflicting $sha_internal <- calculate_sha_from_internal() $sha_disk <- calculate_sha_from_disk() IF $sha_internal NE $sha_disk IF $sha_disk EQ $integrity_hashes[$section] $section_data <- take_from_internal() ELSE $section_data <- take_from_disk() ELSE $section_data <- take_from_disk() $config_content .= create_section($section_data) $config_content .= create_non_conflicting() return $config_content
use Wireguard::WGmeta::Wrapper::ConfigT; # thread A my $wg_metaT = Wireguard::WGmeta::Wrapper::ConfigT->new('<path to wireguard configuration>'); $wg_metaT->set('wg0', 'WG_0_PEER_A_PUBLIC_KEY', 'name', 'set_in_thread_A'); # Assumption: Our internal version is equal with the on-disk version at this point my $integrity_hash = $wg_metaT->calculate_sha_from_internal(); # thread B my $wg_metaT = Wireguard::WGmeta::Wrapper::ConfigT->new('<path to wireguard configuration>'); $wg_metaT->set('wg0', 'AN_OTHER_PUBLIC_KEY', 'name', 'set_in_thread_B'); $wg_metaT->commit(1); # works fine (internal & on_disk have same version) # thread A (non conflicting changes -> same file, different section) $wg_metaT->commit(1); # "Your changes for `WG_0_PEER_A_PUBLIC_KEY` were not applied" $wg_metaT->commit(1, 0, {'WG_0_PEER_A_PUBLIC_KEY' => $integrity_hash}); # works fine -> non conflicting changes # Reload callbacks sub my_reload_callback($interface, $ref_list_args){ my @args = @{$ref_list_args}; print "$interface, reloaded and $args[0]!"; } # register our callback handler $wg_metaT->register_on_reload_listener(\&my_reload_callback, 'handler_id', [ 'hello from listener' ]); # Everytime an interface is reloaded, our handler is called until we uninstall our handler $wg_metaT->remove_on_reload_listener('handler_id');
"is_valid_interface($interface)" in Wireguard::WGmeta::Wrapper::Config
"is_valid_identifier($interface, $identifier)" in Wireguard::WGmeta::Wrapper::Config
"translate_alias($interface, $alias)" in Wireguard::WGmeta::Wrapper::Config
"try_translate_alias($interface, $may_alias)" in Wireguard::WGmeta::Wrapper::Config
"get_interface_section($interface, $identifier)" in Wireguard::WGmeta::Wrapper::Config
"get_section_list($interface)" in Wireguard::WGmeta::Wrapper::Config
"get_peer_count([$interface = undef])" in Wireguard::WGmeta::Wrapper::Config
"get_interface_fqdn($interface)" in Wireguard::WGmeta::Wrapper::Config
"get_interface_list()" in Wireguard::WGmeta::Wrapper::Config
Writes down the parsed config to the wireguard configuration folder.
Parameters
[$is_hot_config = FALSE]) If set to TRUE, the existing configuration is overwritten. Otherwise, the suffix '_not_applied' is appended to the filename
[$is_hot_config = FALSE])
[$plain = FALSE]) If set to TRUE, no header is generated
[$plain = FALSE])
[$ref_hash_integrity_keys = undef]) Reference to a hash of integrity keys. Expected structure:
[$ref_hash_integrity_keys = undef])
{ <identifier1> => 'integrity_hash_of_corresponding_section', <identifier2> => 'integrity_hash_of_corresponding_section' }
For a more detailed explanation when this information is needed please refer to "CONCURRENCY".
Raises
Exception if: Folder or file is not writeable
Returns
None
This method is called before any data is returned from one of the get_*() methods. It behaves as follows:
If the interface is not defined, it loops through the known interfaces and reloads them individually (if needed).
If the interface is defined (and known), the modify timestamps are compared an if the on-disk version is newer, a reload is triggered.
If the interface is defined (but not known -> this could be the case if a new interface has been added), first we check if there is actually a matching config file on disk and if yes, its loaded and parsed from disk.
Remark: This method is not meant for public access, there is just this extensive documentation block since its behaviour is crucial to the function of this class.
$interface A (possibly) invalid (or new) interface name
$interface
Calculates the sha1 from a section (already parsed).
Caveat
It is possible that this method does not return the most recent, on-disk version of this section! It returns your current parsed state! This method does NOT trigger a _may_reload_from_disk()!
_may_reload_from_disk()
$interface A valid interface name
$identifier A valid identifier for this interface
$identifier
The sha1 (in HEX) the requested section
To install Wireguard::WGmeta, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Wireguard::WGmeta
CPAN shell
perl -MCPAN -e shell install Wireguard::WGmeta
For more information on module installation, please visit the detailed CPAN module installation guide.