From bee081b5b65e5dd7451eb328af6a01f564712da0 Mon Sep 17 00:00:00 2001
From: Dan Prince <dprince@redhat.com>
Date: Fri, 5 Apr 2013 07:50:04 -0400
Subject: [PATCH] Fix swift_ring_builder output parsing.

Updates the swift_ring_builder so that it parses ring builder output
from the most recent Swift releases correctly (1.7.6 or greated).

Backward compat for the previous parsing is still supported.

Change-Id: I4263b349310e16f6825960805eb27e4bfe3ff002
---
 lib/puppet/provider/swift_ring_builder.rb     | 18 ++++++++++++++-
 spec/fixtures/manifests/site.pp               |  0
 .../provider/swift_ring_builder_spec.rb       | 22 ++++++++++++++++++-
 3 files changed, 38 insertions(+), 2 deletions(-)
 delete mode 100644 spec/fixtures/manifests/site.pp

diff --git a/lib/puppet/provider/swift_ring_builder.rb b/lib/puppet/provider/swift_ring_builder.rb
index 235c94ec..a55c7fa5 100644
--- a/lib/puppet/provider/swift_ring_builder.rb
+++ b/lib/puppet/provider/swift_ring_builder.rb
@@ -14,7 +14,11 @@ class Puppet::Provider::SwiftRingBuilder < Puppet::Provider
     if File.exists?(builder_file_path)
       if rows = swift_ring_builder(builder_file_path).split("\n")[4..-1]
         rows.each do |row|
-          if row =~ /^\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s+(-?\d+\.\d+)\s+(\S*)$/
+           # Swift 1.7+ output example:
+           # Devices:    id  region  zone      ip address  port      name weight partitions balance meta
+           #              0     1     2       127.0.0.1  6022         2   1.00     262144   0.00
+          if row =~ /^\s*(\d+)\s+\d+\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s+(-?\d+\.\d+)\s*(\S*)/
+
             object_hash["#{$3}:#{$4}/#{$5}"] = {
               :id          => $1,
               :zone        => $2,
@@ -23,6 +27,18 @@ class Puppet::Provider::SwiftRingBuilder < Puppet::Provider
               :balance     => $8,
               :meta        => $9
             }
+           # This regex is for older swift versions
+          elsif row =~ /^\s+(\d+)\s+(\d+)\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+\.\d+)\s+(\d+)\s+(-?\d+\.\d+)\s+(\S*)$/
+
+            object_hash["#{$3}:#{$4}/#{$5}"] = {
+              :id          => $1,
+              :zone        => $2,
+              :weight      => $6,
+              :partitions  => $7,
+              :balance     => $8,
+              :meta        => $9
+            }
+
           else
             Puppet.warning("Unexpected line: #{row}")
           end
diff --git a/spec/fixtures/manifests/site.pp b/spec/fixtures/manifests/site.pp
deleted file mode 100644
index e69de29b..00000000
diff --git a/spec/unit/puppet/provider/swift_ring_builder_spec.rb b/spec/unit/puppet/provider/swift_ring_builder_spec.rb
index 5f66f3ad..e4b86a72 100644
--- a/spec/unit/puppet/provider/swift_ring_builder_spec.rb
+++ b/spec/unit/puppet/provider/swift_ring_builder_spec.rb
@@ -12,6 +12,26 @@ describe provider_class do
   end
 
   it 'should be able to lookup the local ring and build an object' do
+    File.expects(:exists?).with(builder_file_path).returns(true)
+    provider_class.expects(:builder_file_path).twice.returns(builder_file_path)
+    # Swift 1.7 output
+    provider_class.expects(:swift_ring_builder).returns(
+'/etc/swift/account.builder, build version 3
+262144 partitions, 3 replicas, 3 zones, 3 devices, 0.00 balance
+The minimum number of hours before a partition can be reassigned is 1
+Devices:    id  region  zone      ip address  port      name weight partitions balance meta
+             2     1     2  192.168.101.14  6002         1   1.00     262144    0.00 
+             0     1     3  192.168.101.15  6002         1   1.00     262144    0.00 
+             1     1     1  192.168.101.13  6002         1   1.00     262144    0.00 
+'
+    )
+    resources = provider_class.lookup_ring.inspect
+    resources['192.168.101.15:6002/1'].should_not be_nil
+    resources['192.168.101.13:6002/1'].should_not be_nil
+    resources['192.168.101.14:6002/1'].should_not be_nil
+  end
+
+  it 'should be able to lookup the local ring and build an object legacy' do
     File.expects(:exists?).with(builder_file_path).returns(true)
     provider_class.expects(:builder_file_path).twice.returns(builder_file_path)
     provider_class.expects(:swift_ring_builder).returns(
@@ -22,7 +42,6 @@ Devices:    id  zone      ip address  port      name weight partitions balance m
              2     2  192.168.101.14  6002         1   1.00     262144    0.00 
              0     3  192.168.101.15  6002         1   1.00     262144    0.00 
              1     1  192.168.101.13  6002         1   1.00     262144    0.00 
-
 '
     )
     resources = provider_class.lookup_ring.inspect
@@ -30,4 +49,5 @@ Devices:    id  zone      ip address  port      name weight partitions balance m
     resources['192.168.101.13:6002/1'].should_not be_nil
     resources['192.168.101.14:6002/1'].should_not be_nil
   end
+
 end