summaryrefslogtreecommitdiff
path: root/scripts/VyattaConfig.pm
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-11-21 17:09:30 -0800
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-11-21 17:09:30 -0800
commit32cefc2d846f9946bf6e5b84cd914b5e2959dbfa (patch)
tree0bbb5d52e5621b84a897bd023ae51e15c9e72be9 /scripts/VyattaConfig.pm
parent6d87be16190a658ac324488024a82961774f0ece (diff)
downloadvyatta-cfg-32cefc2d846f9946bf6e5b84cd914b5e2959dbfa.tar.gz
vyatta-cfg-32cefc2d846f9946bf6e5b84cd914b5e2959dbfa.zip
Convert VyattaConfig (et al) to Vyatta::Config
Use hierarchal directory structure
Diffstat (limited to 'scripts/VyattaConfig.pm')
-rwxr-xr-xscripts/VyattaConfig.pm603
1 files changed, 0 insertions, 603 deletions
diff --git a/scripts/VyattaConfig.pm b/scripts/VyattaConfig.pm
deleted file mode 100755
index 9ddc8ef..0000000
--- a/scripts/VyattaConfig.pm
+++ /dev/null
@@ -1,603 +0,0 @@
-#!/usr/bin/perl
-
-# Author: An-Cheng Huang <ancheng@vyatta.com>
-# Date: 2007
-# Description: vyatta configuration parser
-
-# **** License ****
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# This code was originally developed by Vyatta, Inc.
-# Portions created by Vyatta are Copyright (C) 2006, 2007, 2008 Vyatta, Inc.
-# All Rights Reserved.
-# **** End License ****
-
-package VyattaConfig;
-
-use strict;
-
-use VyattaConfigDOMTree;
-
-my %fields = (
- _changes_only_dir_base => $ENV{VYATTA_CHANGES_ONLY_DIR},
- _new_config_dir_base => $ENV{VYATTA_TEMP_CONFIG_DIR},
- _active_dir_base => $ENV{VYATTA_ACTIVE_CONFIGURATION_DIR},
- _vyatta_template_dir => $ENV{VYATTA_CONFIG_TEMPLATE},
- _current_dir_level => "/",
- _level => undef,
-);
-
-sub new {
- my $that = shift;
- my $class = ref ($that) || $that;
- my $self = {
- %fields,
- };
-
- bless $self, $class;
- return $self;
-}
-
-sub _set_current_dir_level {
- my ($self) = @_;
- my $level = $self->{_level};
-
- $level =~ s/\//%2F/g;
- $level =~ s/\s+/\//g;
-
- $self->{_current_dir_level} = "/$level";
- return $self->{_current_dir_level};
-}
-
-## setLevel("level")
-# if "level" is supplied, set the current level of the hierarchy we are working on
-# return the current level
-sub setLevel {
- my ($self, $level) = @_;
-
- $self->{_level} = $level if defined($level);
- $self->_set_current_dir_level();
-
- return $self->{_level};
-}
-
-## listNodes("level")
-# return array of all nodes at "level"
-# level is relative
-sub listNodes {
- my ($self, $path) = @_;
- my @nodes = ();
-
- if (defined $path) {
- $path =~ s/\//%2F/g;
- $path =~ s/\s+/\//g;
- $path = $self->{_new_config_dir_base} . $self->{_current_dir_level} . "/" . $path;
- }
- else {
- $path = $self->{_new_config_dir_base} . $self->{_current_dir_level};
- }
-
- #print "DEBUG VyattaConfig->listNodes(): path = $path\n";
- opendir DIR, "$path" or return ();
- @nodes = grep !/^\./, readdir DIR;
- closedir DIR;
-
- my @nodes_modified = ();
- while (@nodes) {
- my $tmp = pop (@nodes);
- $tmp =~ s/\n//g;
- $tmp =~ s/%2F/\//g;
- #print "DEBUG VyattaConfig->listNodes(): node = $tmp\n";
- push @nodes_modified, $tmp;
- }
-
- return @nodes_modified;
-}
-
-## listOrigNodes("level")
-# return array of all original nodes (i.e., before any current change; i.e.,
-# in "working") at "level"
-# level is relative
-sub listOrigNodes {
- my ($self, $path) = @_;
- my @nodes = ();
-
- if (defined $path) {
- $path =~ s/\//%2F/g;
- $path =~ s/\s+/\//g;
- $path = $self->{_active_dir_base} . $self->{_current_dir_level} . "/"
- . $path;
- }
- else {
- $path = $self->{_active_dir_base} . $self->{_current_dir_level};
- }
-
- #print "DEBUG VyattaConfig->listNodes(): path = $path\n";
- opendir DIR, "$path" or return ();
- @nodes = grep !/^\./, readdir DIR;
- closedir DIR;
-
- my @nodes_modified = ();
- while (@nodes) {
- my $tmp = pop (@nodes);
- $tmp =~ s/\n//g;
- $tmp =~ s/%2F/\//g;
- #print "DEBUG VyattaConfig->listNodes(): node = $tmp\n";
- push @nodes_modified, $tmp;
- }
-
- return @nodes_modified;
-}
-
-## listOrigNodes("level")
-# return array of all original nodes (i.e., before any current change; i.e.,
-# in "working") at "level"
-# level is relative
-sub listOrigNodesNoDef {
- my ($self, $path) = @_;
- my @nodes = ();
-
- if (defined $path) {
- $path =~ s/\//%2F/g;
- $path =~ s/\s+/\//g;
- $path = $self->{_active_dir_base} . $self->{_current_dir_level} . "/"
- . $path;
- }
- else {
- $path = $self->{_active_dir_base} . $self->{_current_dir_level};
- }
-
- #print "DEBUG VyattaConfig->listNodes(): path = $path\n";
- opendir DIR, "$path" or return ();
- @nodes = grep !/^\./, readdir DIR;
- closedir DIR;
-
- my @nodes_modified = ();
- while (@nodes) {
- my $tmp = pop (@nodes);
- $tmp =~ s/\n//g;
- $tmp =~ s/%2F/\//g;
- #print "DEBUG VyattaConfig->listNodes(): node = $tmp\n";
- if ($tmp ne 'def') {
- push @nodes_modified, $tmp;
- }
- }
-
- return @nodes_modified;
-}
-
-## returnParent("level")
-# return the name of parent node relative to the current hierarchy
-# in this case "level" is set to the parent dir ".. .."
-# for example
-sub returnParent {
- my ($self, $node) = @_;
- my @x, my $tmp;
-
- # split our hierarchy into vars on a stack
- my @level = split /\s+/, $self->{_level};
-
- # count the number of parents we need to lose
- # and then pop 1 less
- @x = split /\s+/, $node;
- for ($tmp = 1; $tmp < @x; $tmp++) {
- pop @level;
- }
-
- # return the parent
- $tmp = pop @level;
- return $tmp;
-}
-
-## returnValue("node")
-# returns the value of "node" or undef if the node doesn't exist .
-# node is relative
-sub returnValue {
- my ( $self, $node ) = @_;
- my $tmp;
-
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
-
- if ( -f "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node/node.val" ) {
- open FILE, "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node/node.val" || return undef;
- read FILE, $tmp, 16384;
- close FILE;
-
- $tmp =~ s/\n$//;
- return $tmp;
- }
- else {
- return undef;
- }
-}
-
-
-## returnOrigValue("node")
-# returns the original value of "node" (i.e., before the current change; i.e.,
-# in "working") or undef if the node doesn't exist.
-# node is relative
-sub returnOrigValue {
- my ( $self, $node ) = @_;
- my $tmp;
-
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
- my $filepath = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
- if ( -f "$filepath/node.val") {
- open FILE, "$filepath/node.val" || return undef;
- read FILE, $tmp, 16384;
- close FILE;
-
- $tmp =~ s/\n$//;
- return $tmp;
- } else {
- return undef;
- }
-}
-
-## returnValues("node")
-# returns an array of all the values of "node", or an empty array if the values do not exist.
-# node is relative
-sub returnValues {
- my $val = returnValue(@_);
- my @values = ();
- if (defined($val)) {
- @values = split("\n", $val);
- }
- return @values;
-}
-
-## returnOrigValues("node")
-# returns an array of all the original values of "node" (i.e., before the
-# current change; i.e., in "working"), or an empty array if the values do not
-# exist.
-# node is relative
-sub returnOrigValues {
- my $val = returnOrigValue(@_);
- my @values = ();
- if (defined($val)) {
- @values = split("\n", $val);
- }
- return @values;
-}
-
-## exists("node")
-# Returns true if the "node" exists.
-sub exists {
- my ( $self, $node ) = @_;
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
-
- if ( -d "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node" ) {
- #print "DEBUG: the dir is there\n";
- return !0;
- } else {
- return undef;
- }
-}
-
-## existsOrig("node")
-# Returns true if the "original node" exists.
-sub existsOrig {
- my ( $self, $node ) = @_;
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
-
- if ( -d "$self->{_active_dir_base}$self->{_current_dir_level}/$node" ) {
- return 1;
- } else {
- return undef;
- }
-}
-
-## isDeleted("node")
-# is the "node" deleted. node is relative. returns true or false
-sub isDeleted {
- my ($self, $node) = @_;
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
-
- my $filepathAct
- = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
- my $filepathNew
- = "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node";
-
- if ((-e $filepathAct) && !(-e $filepathNew)) {
- return 1;
- }
- return 0;
-}
-
-## listDeleted("level")
-# return array of deleted nodes in the "level"
-# "level" defaults to current
-sub listDeleted {
- my ($self, $path) = @_;
- my @new_nodes = $self->listNodes("$path");
- my @orig_nodes = $self->listOrigNodes("$path");
- my %new_hash = map { $_ => 1 } @new_nodes;
- my @deleted = grep { !defined($new_hash{$_}) } @orig_nodes;
- return @deleted;
-}
-
-## isChanged("node")
-# will check the change_dir to see if the "node" has been changed from a previous
-# value. returns true or false.
-sub isChanged {
- my ($self, $node) = @_;
-
- # let's setup the filepath for the change_dir
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
- my $filepath = "$self->{_changes_only_dir_base}$self->{_current_dir_level}/$node";
-
- # if the node exists in the change dir, it's modified.
- if (-e "$filepath") { return 1; }
- else { return 0; }
-}
-
-## isChangedOrDeleted("node")
-# is the "node" changed or deleted. node is relative. returns true or false
-sub isChangedOrDeleted {
- my ($self, $node) = @_;
-
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
-
- my $filepathChg
- = "$self->{_changes_only_dir_base}$self->{_current_dir_level}/$node";
- if (-e $filepathChg) {
- return 1;
- }
-
- my $filepathAct
- = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
- my $filepathNew
- = "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node";
-
- if ((-e $filepathAct) && !(-e $filepathNew)) {
- return 1;
- }
-
- return 0;
-}
-
-## isAdded("node")
-# will compare the new_config_dir to the active_dir to see if the "node" has
-# been added. returns true or false.
-sub isAdded {
- my ($self, $node) = @_;
-
- #print "DEBUG VyattaConfig->isAdded(): node $node\n";
- # let's setup the filepath for the modify dir
- $node =~ s/\//%2F/g;
- $node =~ s/\s+/\//g;
- my $filepathNewConfig = "$self->{_new_config_dir_base}$self->{_current_dir_level}/$node";
-
- #print "DEBUG VyattaConfig->isAdded(): filepath $filepathNewConfig\n";
-
- # if the node doesn't exist in the modify dir, it's not
- # been added. so short circuit and return false.
- if (! -e $filepathNewConfig) { return 0; }
-
- # now let's setup the path for the working dir
- my $filepathActive = "$self->{_active_dir_base}$self->{_current_dir_level}/$node";
-
- # if the node is in the active_dir it's not new
- if (-e $filepathActive) { return 0; }
- else { return 1; }
-}
-
-## listNodeStatus("level")
-# return a hash of the status of nodes at the current config level
-# node name is the hash key. node status is the hash value.
-# node status can be one of deleted, added, changed, or static
-sub listNodeStatus {
- my ($self, $path) = @_;
- my @nodes = ();
- my %nodehash = ();
-
- # find deleted nodes first
- @nodes = $self->listDeleted("$path");
- foreach my $node (@nodes) {
- if ($node =~ /.+/) { $nodehash{$node} = "deleted" };
- }
-
- @nodes = ();
- @nodes = $self->listNodes("$path");
- foreach my $node (@nodes) {
- if ($node =~ /.+/) {
- #print "DEBUG VyattaConfig->listNodeStatus(): node $node\n";
- # No deleted nodes -- added, changed, ot static only.
- if ($self->isAdded("$path $node")) { $nodehash{$node} = "added"; }
- elsif ($self->isChanged("$path $node")) { $nodehash{$node} = "changed"; }
- else { $nodehash{$node} = "static"; }
- }
- }
-
- return %nodehash;
-}
-
-############ DOM Tree ################
-
-#Create active DOM Tree
-sub createActiveDOMTree {
-
- my $self = shift;
-
- my $tree = new VyattaConfigDOMTree($self->{_active_dir_base} . $self->{_current_dir_level},"active");
-
- return $tree;
-}
-
-#Create changes only DOM Tree
-sub createChangesOnlyDOMTree {
-
- my $self = shift;
-
- my $tree = new VyattaConfigDOMTree($self->{_changes_only_dir_base} . $self->{_current_dir_level},
- "changes_only");
-
- return $tree;
-}
-
-#Create new config DOM Tree
-sub createNewConfigDOMTree {
-
- my $self = shift;
-
- my $tree = new VyattaConfigDOMTree($self->{_new_config_dir_base} . $self->{_current_dir_level},
- "new_config");
-
- return $tree;
-}
-
-
-###### functions for templates ######
-
-# $1: array representing the config node path.
-# returns the filesystem path to the template of the specified node,
-# or undef if the specified node path is not valid.
-sub getTmplPath {
- my $self = shift;
- my @cfg_path = @{$_[0]};
- my $tpath = $self->{_vyatta_template_dir};
- for my $p (@cfg_path) {
- if (-d "$tpath/$p") {
- $tpath .= "/$p";
- next;
- }
- if (-d "$tpath/node.tag") {
- $tpath .= "/node.tag";
- next;
- }
- # the path is not valid!
- return undef;
- }
- return $tpath
-}
-
-sub isTagNode {
- my $self = shift;
- my $cfg_path_ref = shift;
- my $tpath = $self->getTmplPath($cfg_path_ref);
- return undef if (!defined($tpath));
- if (-d "$tpath/node.tag") {
- return 1;
- }
- return 0;
-}
-
-sub hasTmplChildren {
- my $self = shift;
- my $cfg_path_ref = shift;
- my $tpath = $self->getTmplPath($cfg_path_ref);
- return undef if (!defined($tpath));
- opendir(TDIR, $tpath) or return 0;
- my @tchildren = grep !/^node\.def$/, (grep !/^\./, (readdir TDIR));
- closedir TDIR;
- if (scalar(@tchildren) > 0) {
- return 1;
- }
- return 0;
-}
-
-# $cfg_path_ref: ref to array containing the node path.
-# returns ($is_multi, $is_text, $default),
-# or undef if specified node is not valid.
-sub parseTmpl {
- my $self = shift;
- my $cfg_path_ref = shift;
- my ($is_multi, $is_text, $default) = (0, 0, undef);
- my $tpath = $self->getTmplPath($cfg_path_ref);
- return undef if (!defined($tpath));
- if (! -r "$tpath/node.def") {
- return ($is_multi, $is_text);
- }
- open(TMPL, "<$tpath/node.def") or return ($is_multi, $is_text);
- foreach (<TMPL>) {
- if (/^multi:/) {
- $is_multi = 1;
- }
- if (/^type:\s+txt\s*$/) {
- $is_text = 1;
- }
- if (/^default:\s+(\S+)\s*$/) {
- $default = $1;
- }
- }
- close TMPL;
- return ($is_multi, $is_text, $default);
-}
-
-###### misc functions ######
-
-# compare two value lists and return "deleted" and "added" lists.
-# since this is for multi-value nodes, there is no "changed" (if a value's
-# ordering changed, it is deleted then added).
-# $0: \@orig_values
-# $1: \@new_values
-sub compareValueLists {
- my $self = shift;
- my @ovals = @{$_[0]};
- my @nvals = @{$_[1]};
- my %comp_hash = (
- 'deleted' => [],
- 'added' => [],
- );
- my $idx = 0;
- my %ohash = map { $_ => ($idx++) } @ovals;
- $idx = 0;
- my %nhash = map { $_ => ($idx++) } @nvals;
- my $min_changed_idx = 2**31;
- my %dhash = ();
- foreach (@ovals) {
- if (!defined($nhash{$_})) {
- push @{$comp_hash{'deleted'}}, $_;
- $dhash{$_} = 1;
- if ($ohash{$_} < $min_changed_idx) {
- $min_changed_idx = $ohash{$_};
- }
- }
- }
- foreach (@nvals) {
- if (defined($ohash{$_})) {
- if ($ohash{$_} != $nhash{$_}) {
- if ($ohash{$_} < $min_changed_idx) {
- $min_changed_idx = $ohash{$_};
- }
- }
- }
- }
- foreach (@nvals) {
- if (defined($ohash{$_})) {
- if ($ohash{$_} != $nhash{$_}) {
- if (!defined($dhash{$_})) {
- push @{$comp_hash{'deleted'}}, $_;
- $dhash{$_} = 1;
- }
- push @{$comp_hash{'added'}}, $_;
- } elsif ($ohash{$_} >= $min_changed_idx) {
- # ordering unchanged, but something before it is changed.
- if (!defined($dhash{$_})) {
- push @{$comp_hash{'deleted'}}, $_;
- $dhash{$_} = 1;
- }
- push @{$comp_hash{'added'}}, $_;
- } else {
- # this is before any changed value. do nothing.
- }
- } else {
- push @{$comp_hash{'added'}}, $_;
- }
- }
- return %comp_hash;
-}