aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorFeng Pan <fpan@redhat.com>2017-02-19 15:14:40 -0500
committerFeng Pan <fpan@redhat.com>2017-02-20 10:53:29 -0500
commitac2d7693e02a11d80879ccd80dc33a4f213295e6 (patch)
treeba4d6cb546b1db34af796b065be9b625c676cc31 /lib
parent32ce2b41b1ca0b6224b45d8bf79039db5e15e997 (diff)
Add support for inline config changes
This patch changes VPP configuration from file template to inline change directly. This prevents issue with overwriting existing VPP config. Change-Id: I4133be8ebe689d9288e3a8e64cca43afd7e42e64 Signed-off-by: Feng Pan <fpan@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/provider/vpp_config/vpp.rb118
-rw-r--r--lib/puppet/provider/vpp_service/vpp.rb113
-rw-r--r--lib/puppet/type/vpp_config.rb14
-rw-r--r--lib/puppet/type/vpp_service.rb46
4 files changed, 132 insertions, 159 deletions
diff --git a/lib/puppet/provider/vpp_config/vpp.rb b/lib/puppet/provider/vpp_config/vpp.rb
new file mode 100644
index 0000000..2574d4c
--- /dev/null
+++ b/lib/puppet/provider/vpp_config/vpp.rb
@@ -0,0 +1,118 @@
+Puppet::Type.type(:vpp_config).provide(:vpp) do
+
+ def file_path
+ '/etc/vpp/startup.conf'
+ end
+
+ def initialize(value={})
+ super(value)
+ settings_arr = @resource[:setting].split('/')
+ @section = settings_arr[0]
+ @real_setting = settings_arr[1]
+ @dev = settings_arr[2]
+
+ if @section.nil? || @real_setting.nil?
+ fail("#{@resource[:setting]} is not a valid setting string")
+ end
+
+ if @dev
+ @search_regex = /^\s*dev\s+#{@dev}\s*({[^}]*})?/
+ else
+ @search_regex = /^\s*#{@real_setting}\s+(\S+)?/
+ end
+
+ end
+
+ def write_config(config)
+ if File.read(file_path) != config
+ File.open(file_path, 'w') do |fh|
+ fh.puts(config)
+ end
+ end
+ end
+
+ def get_sections
+ vpp_config = File.read(file_path)
+ scanner = StringScanner.new vpp_config
+
+ #first skip to section beginning
+ string = scanner.scan_until(/#{@section}\s*{\s*/)
+
+ #if we can't find the section, add it to the end
+ return vpp_config+"\n#{@section} {", "", "}\n" unless string
+
+ level = 1
+ before = string
+ after = ''
+ section_config = ''
+
+ while current_char = scanner.getch
+ case current_char
+ when '{'
+ level += 1
+ section_config << current_char
+ when '}'
+ level -= 1
+ if level == 0
+ after = current_char + scanner.post_match
+ break
+ else
+ section_config << current_char
+ end
+ else
+ section_config << current_char
+ end
+ end
+
+ fail("Failed to parse VPP config: #{vpp_config}") unless level == 0
+ return before, section_config, after
+ end
+
+ def add_setting(value)
+ before, section_config, after = get_sections
+
+ if @dev
+ if value.to_s.empty?
+ setting_string = "#{@real_setting} #{@dev}"
+ else
+ setting_string = "#{@real_setting} #{@dev} {#{value}}"
+ end
+ else
+ setting_string = "#{@real_setting} #{value}"
+ end
+
+ if section_config =~ @search_regex
+ section_config.sub!(@search_regex, " #{setting_string}")
+ else
+ section_config.rstrip!
+ section_config << "\n #{setting_string}\n"
+ end
+
+ write_config(before+section_config+after)
+ end
+
+ def create
+ add_setting(@resource[:value])
+ end
+
+ def destroy
+ before, section_config, after = get_sections
+ section_config.sub!(@search_regex, "")
+ write_config(before+section_config+after)
+ end
+
+ def exists?
+ before, section_config, after = get_sections
+ @search_regex.match(section_config)
+ end
+
+ def value
+ before, section_config, after = get_sections
+ @search_regex.match(section_config) { |m| m[1] }
+ end
+
+ def value=(value)
+ add_setting(value)
+ end
+
+end
diff --git a/lib/puppet/provider/vpp_service/vpp.rb b/lib/puppet/provider/vpp_service/vpp.rb
deleted file mode 100644
index a887404..0000000
--- a/lib/puppet/provider/vpp_service/vpp.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-Puppet::Type.type(:vpp_service).provide :vpp do
-
- commands :vppctlcmd => "vppctl"
- commands :systemctlcmd => "systemctl"
-
- def get_int_prefix(name)
- if %r{([[:alpha:]]*#{name})\s+} =~ `vppctl show int`
- return $1
- else
- raise Puppet::Error.new("Cannot find vpp interface matching: #{name}")
- end
- end
-
- def convert_pci_addr(pci_dev)
- if pci_dev =~ /\p{XDigit}+:(\p{XDigit}+):(\p{XDigit}+)\.(\p{XDigit}+)/
- return "%x/%x/%x" % ["0x#{$1}".hex, "0x#{$2}".hex, "0x#{$3}".hex]
- else
- raise Puppet::Error.new("Incorrect pci dev format: #{pci_dev}")
- end
- end
-
- def vpp_pre_config
- @resource[:pci_devs].each do |pci_dev|
- Facter.value(:interfaces).split(',').each do |kernel_nic|
- if pci_dev == `ethtool -i #{kernel_nic} | grep bus-info | awk '{print $2}'`.strip
- unless system("ip link set dev #{kernel_nic} down")
- raise Puppet::Error.new("Failed to shut down kernel nic #{kernel_nic}")
- end
-
- #Disable NIC on boot
- file_data = ""
- onboot_exists = false
- if File.exist?("/etc/sysconfig/network-scripts/ifcfg-#{kernel_nic}")
- IO.foreach("/etc/sysconfig/network-scripts/ifcfg-#{kernel_nic}") do |line|
- if /ONBOOT/.match(line)
- onboot_exists = true
- file_data += "ONBOOT=no\n"
- else
- file_data += line
- end
- end
- unless onboot_exists
- file_data += "ONBOOT=no"
- end
- File.open("/etc/sysconfig/network-scripts/ifcfg-#{kernel_nic}", "w") {|file| file.puts file_data}
- end
-
- if Facter.value("ipaddress_#{kernel_nic}")
- @int_ip_mapping[pci_dev] = Facter.value("ipaddress_#{kernel_nic}") + "/" + Facter.value("netmask_#{kernel_nic}")
- end
- end
- end
- end
- end
-
- def configure_vpp_interfaces
- @resource[:pci_devs].each do |pci_dev|
- vpp_int_name= get_int_prefix(convert_pci_addr(pci_dev))
- vppctlcmd "set int state", vpp_int_name, @resource[:state]
- if @resource[:copy_kernel_nic_ip] && @int_ip_mapping.has_key?(pci_dev)
- vppctlcmd "set int ip address", vpp_int_name, @int_ip_mapping[pci_dev]
- end
- end
- end
-
- def create
- @int_ip_mapping = {}
- vpp_pre_config
-
- #Bring up VPP service
- systemctlcmd "restart", "vpp"
- systemctlcmd "enable", "vpp"
- sleep 10
-
- #Configure VPP interfaces
- configure_vpp_interfaces
- end
-
- def destroy
- systemctlcmd "stop", "vpp"
- systemctlcmd "disable", "vpp"
- end
-
- def exists?
- if system("systemctl is-active vpp --quiet")
- @resource[:pci_devs].each do |pci_dev|
- int_name_str = convert_pci_addr(pci_dev)
- if %r{([[:alpha:]]*#{int_name_str})\s+} !~ `vppctl show int`
- return false
- end
- end
- else
- return false
- end
- return true
- end
-
- def state
- @resource[:pci_devs].each do |pci_dev|
- vpp_int_output = `vppctl show int #{get_int_prefix(convert_pci_addr(pci_dev))}`
- if ! /\s+up\s+/.match(vpp_int_output)
- return "down"
- end
- end
- return "up"
- end
-
- def state=(value)
- @resource[:pci_devs].each do |pci_dev|
- vppctlcmd "set int state", get_int_prefix(convert_pci_addr(pci_dev)), value
- end
- end
-end \ No newline at end of file
diff --git a/lib/puppet/type/vpp_config.rb b/lib/puppet/type/vpp_config.rb
new file mode 100644
index 0000000..17c910f
--- /dev/null
+++ b/lib/puppet/type/vpp_config.rb
@@ -0,0 +1,14 @@
+Puppet::Type.newtype(:vpp_config) do
+
+ ensurable
+
+ newparam(:setting, :namevar => true) do
+ end
+
+ newproperty(:value) do
+ munge do |value|
+ value.strip if value.is_a? String
+ end
+ end
+
+end
diff --git a/lib/puppet/type/vpp_service.rb b/lib/puppet/type/vpp_service.rb
deleted file mode 100644
index c1c818f..0000000
--- a/lib/puppet/type/vpp_service.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-Puppet::Type.newtype(:vpp_service) do
-
- ensurable
-
- newparam(:name) do
- end
-
- newparam(:pci_devs, :array_matching => :all) do
- desc "PCI dev addresses to be bound to VPP"
- def insync?(is)
- is.sort == should.sort
- end
-
- validate do |values|
- values = [values] unless values.is_a?(Array)
- values.map! do |value|
- if value =~ /\p{XDigit}+:(\p{XDigit}+):(\p{XDigit}+)\.(\p{XDigit}+)/
- value
- else
- raise(Puppet::Error, "Incorrect PCI dev address #{value}")
- end
- end
- end
-
- munge do |values|
- if values.is_a?(Array)
- values
- else
- [values]
- end
- end
- end
-
- newproperty(:state) do
- desc "VPP interface state"
- defaultto :up
- newvalues(:up, :down)
- end
-
- newparam(:copy_kernel_nic_ip) do
- desc "Whether to configure VPP interface with kernel NIC's IP settings"
- defaultto :true
- newvalues(:true, :false)
- end
-
-end