hostlist_expression 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/hostlist_expression.rb +117 -0
  3. metadata +47 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4444bb6780f552999628387b893e98e8df483562
4
+ data.tar.gz: 97cf032750d191be707b748bce011ea29b7d57ba
5
+ SHA512:
6
+ metadata.gz: 86108d43e27579172276c5c17e0c9b4922a33b4fc1bb0554325304fd50f55a4f80bd0bcfdfc76a8f9bde511d82b6f5db37ab9d65d934cd5556e2ebedaec60bea
7
+ data.tar.gz: 784f9d4f7ddc2e14ae4c2d2f62b57a6d927e8fbb2f3df77182451dfc093cb8ca4d2fd1165bba3da5107537d66f05d6b07456832dde395941ff7d2b833291cac5
@@ -0,0 +1,117 @@
1
+ # Author: Daniel Schroeder
2
+ # License: MIT
3
+ # Home: https://github.com/udondan/hostlist_expression-ruby
4
+ #
5
+ # Public: Expand hostlist expression
6
+ #
7
+ # expression - Hostlist expression.
8
+ # separator - Character(s) for separating ranges (default: [":", "-"]).
9
+ #
10
+ # Examples
11
+ #
12
+ # hostlist_expression("your-host-[1-3].com")
13
+ # # => ["your-host-1.com", "your-host-2.com", "your-host-3.com"]
14
+ #
15
+ # Returns the expanded host list as array.
16
+ def hostlist_expression(expression, separator = [":", "-"])
17
+
18
+ # Validate range separator
19
+ if separator.class == Array
20
+ separator = separator.join("")
21
+ end
22
+ if not separator.class == String
23
+ puts "Error: Range separator must be either of type String or Array. given: #{separator.class}"
24
+ exit 1
25
+ elsif separator.length == 0
26
+ puts "Error: Range separator is empty"
27
+ exit 1
28
+ end
29
+
30
+ # Prepeare separator for use in regular expressions
31
+ separator = Regexp.escape(separator)
32
+
33
+ # Return input, if this is not a hostlist expression
34
+ return expression if not expression.match(/\[(?:[\da-z]+(?:[#{separator}][\da-z]+)?,?)+\]/i)
35
+
36
+ # hosts array will hold all expanded results, it as well is the working array where partially resolved results are stored
37
+ hosts = Array.new
38
+ hosts.push(expression)
39
+
40
+ # Iterate over all range definitions, e.g. [0:10] or [A:Z]
41
+ expression.scan(/\[([\da-z#{separator},]+)\]/i).each do|match|
42
+
43
+ # Will hold replacements for each match
44
+ replacements = Array.new
45
+
46
+ # The pattern may be a sequence with multiple ranges. Split...
47
+ match[0].split(",").each do |range|
48
+
49
+ # Split ranges by range separator
50
+ range_items = range.split(/[#{separator}]/)
51
+
52
+ # If it's not really a range, duplicate the single item
53
+ if range_items.length == 1
54
+ range_items.push(range_items[0])
55
+ end
56
+
57
+ # Numeric range
58
+ if range_items[0].match(/^[0-9]+$/) and range_items[1].match(/^[0-9]+$/)
59
+ isnum = true
60
+ from = range_items[0].to_i
61
+ to = range_items[1].to_i
62
+
63
+ # Uppercase alphabetic range
64
+ elsif range_items[0].length == 1 and range_items[1].length == 1 and /^[[:upper:]]+$/.match(range_items[0]) and /^[[:upper:]]+$/.match(range_items[1])
65
+ alphabet = ('A'..'Z').to_a
66
+ from = alphabet.index(range_items[0])
67
+ to = alphabet.index(range_items[1])
68
+
69
+ # Lowercase alphabetic range
70
+ elsif range_items[0].length == 1 and range_items[1].length == 1 and /^[[:lower:]]+$/.match(range_items[0]) and /^[[:lower:]]+$/.match(range_items[1])
71
+ alphabet = ('a'..'z').to_a
72
+ from = alphabet.index(range_items[0])
73
+ to = alphabet.index(range_items[1])
74
+
75
+ else
76
+ puts "Error: Invalid host range definition #{expression}"
77
+ exit 1
78
+ end
79
+
80
+ # Fail if "to" is higher than "from"
81
+ if from>to
82
+ puts "Error: Invalid host range definition. 'to' part must be higher than 'from' part: #{expression}"
83
+ exit 1
84
+ end
85
+
86
+ # Iterate over all hosts and store the resolved patterns in "replacements"
87
+ hosts.each do |exitem|
88
+
89
+ # Iterate over the range
90
+ (from..to).each do |i|
91
+ if isnum
92
+ # Formatting number with leading zeros
93
+ replacements.push("#{i}".rjust(range_items[0].length, "0"))
94
+ else
95
+ # Select correct letter from alphabet
96
+ replacements.push(alphabet[i])
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ # We clone the hosts array, because we can't modify it while iterating over its elements. So we iterate over the clone instead
103
+ hosts.clone.each do |exitem|
104
+
105
+ # Remove the original element
106
+ hosts.delete(exitem)
107
+
108
+ # Iterate over previously stored replacements
109
+ replacements.each do|replacement|
110
+ # Adding replacement to hosts array
111
+ hosts.push(exitem.sub(/\[#{match[0]}\]/, replacement))
112
+ end
113
+ end
114
+ end
115
+
116
+ return hosts.uniq
117
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hostlist_expression
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Schroeder
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "Expand hostlist expression like those defined in pdsh or Ansible inventory
14
+ files.\n \nAn expression like \"your-host-[1-3].com\" will expand into an array
15
+ containing the elements:\n - your-host-1.com\n - your-host-2.com\n - your-host-3.com\n\nSee
16
+ https://github.com/udondan/hostlist_expression-ruby for documentation\n"
17
+ email: daniel@phatthanan.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/hostlist_expression.rb
23
+ homepage: https://github.com/udondan/hostlist_expression-ruby
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.0.14
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Expand hostlist expression
47
+ test_files: []