dop_common 0.13.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 (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +176 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE.txt +177 -0
  8. data/README.md +48 -0
  9. data/Rakefile +49 -0
  10. data/Vagrantfile +25 -0
  11. data/bin/dop-puppet-autosign +56 -0
  12. data/doc/examples/example_deploment_plan_v0.0.1.yaml +302 -0
  13. data/doc/plan_format_v0.0.1.md +919 -0
  14. data/doc/plan_format_v0.0.2_snippets.md +56 -0
  15. data/dop_common.gemspec +44 -0
  16. data/lib/dop_common/affinity_group.rb +57 -0
  17. data/lib/dop_common/cli/global_options.rb +37 -0
  18. data/lib/dop_common/cli/log.rb +51 -0
  19. data/lib/dop_common/cli/node_selection.rb +62 -0
  20. data/lib/dop_common/command.rb +125 -0
  21. data/lib/dop_common/config/helper.rb +39 -0
  22. data/lib/dop_common/config.rb +66 -0
  23. data/lib/dop_common/configuration.rb +37 -0
  24. data/lib/dop_common/credential.rb +152 -0
  25. data/lib/dop_common/data_disk.rb +62 -0
  26. data/lib/dop_common/dns.rb +55 -0
  27. data/lib/dop_common/hash_parser.rb +241 -0
  28. data/lib/dop_common/hooks.rb +81 -0
  29. data/lib/dop_common/infrastructure.rb +160 -0
  30. data/lib/dop_common/infrastructure_properties.rb +185 -0
  31. data/lib/dop_common/interface.rb +113 -0
  32. data/lib/dop_common/log.rb +78 -0
  33. data/lib/dop_common/network.rb +85 -0
  34. data/lib/dop_common/node/config.rb +159 -0
  35. data/lib/dop_common/node.rb +442 -0
  36. data/lib/dop_common/node_filter.rb +74 -0
  37. data/lib/dop_common/plan.rb +188 -0
  38. data/lib/dop_common/plan_cache.rb +83 -0
  39. data/lib/dop_common/plan_store.rb +263 -0
  40. data/lib/dop_common/pre_processor.rb +73 -0
  41. data/lib/dop_common/run_options.rb +56 -0
  42. data/lib/dop_common/signal_handler.rb +58 -0
  43. data/lib/dop_common/state_store.rb +95 -0
  44. data/lib/dop_common/step.rb +200 -0
  45. data/lib/dop_common/step_set.rb +41 -0
  46. data/lib/dop_common/thread_context_logger.rb +77 -0
  47. data/lib/dop_common/utils.rb +106 -0
  48. data/lib/dop_common/validator.rb +53 -0
  49. data/lib/dop_common/version.rb +3 -0
  50. data/lib/dop_common.rb +32 -0
  51. data/lib/hiera/backend/dop_backend.rb +94 -0
  52. data/lib/hiera/dop_logger.rb +20 -0
  53. data/spec/data/fake_hook_file_invalid +1 -0
  54. data/spec/data/fake_hook_file_valid +5 -0
  55. data/spec/data/fake_keyfile +1 -0
  56. data/spec/dop-puppet-autosign_spec_disable.rb +33 -0
  57. data/spec/dop_common/affinity_group_spec.rb +41 -0
  58. data/spec/dop_common/command_spec.rb +83 -0
  59. data/spec/dop_common/credential_spec.rb +73 -0
  60. data/spec/dop_common/data_disk_spec.rb +165 -0
  61. data/spec/dop_common/dns_spec.rb +33 -0
  62. data/spec/dop_common/hash_parser_spec.rb +181 -0
  63. data/spec/dop_common/hooks_spec.rb +33 -0
  64. data/spec/dop_common/infrastructure_properties_spec.rb +224 -0
  65. data/spec/dop_common/infrastructure_spec.rb +77 -0
  66. data/spec/dop_common/interface_spec.rb +192 -0
  67. data/spec/dop_common/network_spec.rb +92 -0
  68. data/spec/dop_common/node_filter_spec.rb +70 -0
  69. data/spec/dop_common/node_spec.rb +623 -0
  70. data/spec/dop_common/plan_cache_spec.rb +46 -0
  71. data/spec/dop_common/plan_spec.rb +136 -0
  72. data/spec/dop_common/plan_store_spec.rb +194 -0
  73. data/spec/dop_common/pre_processor_spec.rb +27 -0
  74. data/spec/dop_common/run_options_spec.rb +65 -0
  75. data/spec/dop_common/signal_handler_spec.rb +31 -0
  76. data/spec/dop_common/step_set_spec.rb +21 -0
  77. data/spec/dop_common/step_spec.rb +175 -0
  78. data/spec/dop_common/utils_spec.rb +27 -0
  79. data/spec/dop_common/validator_spec.rb +47 -0
  80. data/spec/example_plans_spec.rb +16 -0
  81. data/spec/fixtures/example_ssh_key +27 -0
  82. data/spec/fixtures/example_ssh_key.pub +1 -0
  83. data/spec/fixtures/incl/root_part.yaml +1 -0
  84. data/spec/fixtures/incl/some_list.yaml +2 -0
  85. data/spec/fixtures/other_plan_same_nodes.yaml +19 -0
  86. data/spec/fixtures/simple_include.yaml +6 -0
  87. data/spec/fixtures/simple_include_with_errors.yaml +4 -0
  88. data/spec/fixtures/simple_plan.yaml +19 -0
  89. data/spec/fixtures/simple_plan_invalid.yaml +18 -0
  90. data/spec/fixtures/simple_plan_modified.yaml +21 -0
  91. data/spec/spec_helper.rb +106 -0
  92. metadata +381 -0
@@ -0,0 +1,192 @@
1
+ require 'spec_helper'
2
+
3
+ describe DopCommon::Interface do
4
+ before(:each) do
5
+ @networks = {
6
+ :valid_defgw => [DopCommon::Network.new(
7
+ 'valid_defgw', {
8
+ 'ip_pool' => {'from' => '192.168.1.100', 'to' => '192.168.1.200'},
9
+ 'ip_netmask' => '255.255.255.0',
10
+ 'ip_defgw' => '192.168.1.254'
11
+ }
12
+ )],
13
+ :valid_nodefgw => [DopCommon::Network.new(
14
+ 'valid_nodefgw', {
15
+ 'ip_pool' => {'from' => '192.168.1.100', 'to' => '192.168.1.200'},
16
+ 'ip_netmask' => '255.255.255.0',
17
+ 'ip_defgw' => false
18
+ }
19
+ )]
20
+ }
21
+ end
22
+
23
+ describe '#network' do
24
+ it 'will return a network name in case it is defined in networks hash' do
25
+ interface = DopCommon::Interface.new(
26
+ 'eth0',
27
+ {'network' => 'valid_defgw'},
28
+ {:parsed_networks => @networks[:valid_defgw]}
29
+ )
30
+ expect(interface.network).to eq @networks[:valid_defgw].first.name
31
+ end
32
+ it "will raise an error if network name is invalid" do
33
+ [nil, [], {}, "", 1].each do |n|
34
+ interface = DopCommon::Interface.new(
35
+ 'eth0',
36
+ {'network' => n},
37
+ {:parsed_networks => @networks[:valid_defgw]}
38
+ )
39
+ expect{interface.network}.to raise_error DopCommon::PlanParsingError
40
+ end
41
+ end
42
+ it "will raise an error if the network points to invalid network definition" do
43
+ interface = DopCommon::Interface.new(
44
+ 'eth0',
45
+ {'network' => 'invalid definition', 'ip' => '192.168.1.101'},
46
+ {:parsed_networks => @networks[:valid_defgw]}
47
+ )
48
+ expect{interface.network}.to raise_error DopCommon::PlanParsingError
49
+ end
50
+ end
51
+
52
+ describe '#ip' do
53
+ it "will return :dhcp if 'dhcp' is specified" do
54
+ interface = DopCommon::Interface.new('eth0', {:ip => 'dhcp'})
55
+ expect(interface.ip).to eq(:dhcp)
56
+ end
57
+ it "will return 'none' if none is specified" do
58
+ interface = DopCommon::Interface.new('eth0', {:ip => 'none'})
59
+ expect(interface.ip).to eq(:none)
60
+ end
61
+ it 'will return an IP if specified correctly' do
62
+ interface = DopCommon::Interface.new(
63
+ 'eth0',
64
+ {'network' => 'valid_defgw', 'ip' => '192.168.1.101'},
65
+ {:parsed_networks => @networks[:valid_defgw]}
66
+ )
67
+ expect(interface.ip).to eq('192.168.1.101')
68
+ end
69
+ it 'will raise an error if the ip is not valid' do
70
+ interface = DopCommon::Interface.new('eth0', {'ip' => 'not valid ip'})
71
+ expect{interface.ip}.to raise_error DopCommon::PlanParsingError
72
+ interface = DopCommon::Interface.new('eth0', {'ip' => 2})
73
+ expect{interface.ip}.to raise_error DopCommon::PlanParsingError
74
+ interface = DopCommon::Interface.new('eth0', {'ip' => '300.0.0.0'})
75
+ expect{interface.ip}.to raise_error DopCommon::PlanParsingError
76
+ %w(192.168.1.202 192.168.1.254).each do |ip|
77
+ interface = DopCommon::Interface.new(
78
+ 'eth0',
79
+ {'network' => 'valid_defgw', 'ip' => ip},
80
+ {:parsed_networks => @networks[:valid_defgw]}
81
+ )
82
+ expect{interface.ip}.to raise_error DopCommon::PlanParsingError
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#netmask' do
88
+ it 'will return a netmask if specified correctly' do
89
+ interface = DopCommon::Interface.new(
90
+ 'eth0',
91
+ {'network' => 'valid_defgw', 'ip' => '192.168.1.101'},
92
+ {:parsed_networks => @networks[:valid_defgw]}
93
+ )
94
+ netmask = @networks[:valid_defgw].first.ip_netmask.to_s
95
+ expect(interface.netmask).to eq(netmask)
96
+ end
97
+ end
98
+
99
+ describe '#gateway' do
100
+ it 'will return a gateway if specified correctly' do
101
+ %w(valid_defgw valid_nodefgw).each do |n|
102
+ interface = DopCommon::Interface.new(
103
+ 'eth0',
104
+ {'network' => n, 'ip' => '192.168.1.101'},
105
+ {:parsed_networks => @networks[n.to_sym]}
106
+ )
107
+ gateway = @networks[n.to_sym].first.ip_defgw.to_s
108
+ expect(interface.gateway.to_s).to eq(gateway)
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '#set_gateway?' do
114
+ it 'will return true if not specified and network definition contains a default gateway' do
115
+ interface = DopCommon::Interface.new(
116
+ 'eth0',
117
+ {'network' => 'valid_defgw', 'ip' => '192.168.1.101'},
118
+ {:parsed_networks => @networks[:valid_defgw]}
119
+ )
120
+ expect(interface.set_gateway?).to eq(true)
121
+ end
122
+ [true, false].each do |v|
123
+ it "will return #{v} if specified and network definition contains a default gateway" do
124
+ interface = DopCommon::Interface.new(
125
+ 'eth0',
126
+ {'network' => 'valid_defgw', 'ip' => '192.168.1.101', 'set_gateway' => v},
127
+ {:parsed_networks => @networks[:valid_defgw]}
128
+ )
129
+ expect(interface.set_gateway?).to eq(v)
130
+ end
131
+ end
132
+ it 'will return false if not specified and network definition does not contain a default gateway' do
133
+ interface = DopCommon::Interface.new(
134
+ 'eth0',
135
+ {'network' => 'valid_nodefgw', 'ip' => '192.168.1.101'},
136
+ {:parsed_networks => @networks[:valid_nodefgw]}
137
+ )
138
+ expect(interface.set_gateway?).to eq(false)
139
+ end
140
+ it 'will raise an error if not specified correctly' do
141
+ [[], {}, 0, 1, 'foo'].each do |v|
142
+ interface = DopCommon::Interface.new(
143
+ 'eth0',
144
+ {'network' => 'valid_defgw', 'ip' => '192.168.1.101', 'set_gateway' => v},
145
+ {:parsed_networks => @networks[:valid_defgw]}
146
+ )
147
+ expect{interface.set_gateway?}.to raise_error DopCommon::PlanParsingError
148
+ end
149
+ end
150
+ it "will raise an error if set to 'true' and network definition does not contain a default gateway" do
151
+ interface = DopCommon::Interface.new(
152
+ 'eth0',
153
+ {'network' => 'valid_nodefgw', 'ip' => '192.168.1.101', 'set_gateway' => true},
154
+ {:parsed_networks => @networks[:valid_nodefgw]}
155
+ )
156
+ expect{interface.set_gateway?}.to raise_error DopCommon::PlanParsingError
157
+ end
158
+ end
159
+ describe '#virtual_switch' do
160
+ it 'will return a virtual switch name if specified correctly' do
161
+ ['foo', 'foo123', '123', 'foo bar', 'foo-bar', nil].each do |s|
162
+ interface = DopCommon::Interface.new('eth0', {'virtual_switch' => s})
163
+ expect(interface.virtual_switch).to be_a_kind_of(s.class)
164
+ expect(interface.virtual_switch).to eq s
165
+ end
166
+ end
167
+ it "will raise an error if the virtual switch definition isn't valid" do
168
+ [123, {}, [], ""].each do |s|
169
+ interface = DopCommon::Interface.new('eth0', {'virtual_switch' => s})
170
+ expect{interface.virtual_switch}.to raise_error DopCommon::PlanParsingError
171
+ end
172
+ end
173
+ end
174
+
175
+ describe '#floating_network' do
176
+ it 'will return nil if not specified' do
177
+ interface = DopCommon::Interface.new('eth0', {})
178
+ expect(interface.floating_network).to eq(nil)
179
+ end
180
+ it 'will return an IP network if specified properly' do
181
+ interface = DopCommon::Interface.new('eth0', {'floating_network' => 'floating-network'})
182
+ expect(interface.floating_network).to eq('floating-network')
183
+ end
184
+ it 'will raise an error if not specified correctly' do
185
+ [{}, [], '', 1].each do |n|
186
+ interface = DopCommon::Interface.new('eth0', {'floating_network' => n})
187
+ expect{interface.floating_network}.to raise_error DopCommon::PlanParsingError
188
+ end
189
+ end
190
+ end
191
+ end
192
+
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe DopCommon::Network do
4
+
5
+ good_ip_defgw = '192.168.1.1'
6
+ good_ip_netmask = '255.255.255.0'
7
+ good_net = {
8
+ 'ip_defgw' => good_ip_defgw,
9
+ 'ip_netmask' => good_ip_netmask
10
+ }
11
+
12
+ describe '#ip_defgw' do
13
+ it 'will return a netmask object if the default gateway is correct' do
14
+ network = DopCommon::Network.new('dummy', {})
15
+ expect(network.ip_defgw).to be_nil
16
+ network = DopCommon::Network.new('dummy', good_net)
17
+ expect(network.ip_defgw.to_s).to eq(good_net['ip_defgw'])
18
+ end
19
+ it 'will return a netmask object if the default gateway is nil' do
20
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_defgw' => false))
21
+ expect(network.ip_defgw).to be_falsey
22
+ end
23
+ it 'will raise an error in case of invalid default gateway IP' do
24
+ network = DopCommon::Network.new('dummy', {'ip_defgw' => :invalid})
25
+ expect { network.ip_defgw }.to raise_error DopCommon::PlanParsingError
26
+ end
27
+ end
28
+
29
+
30
+ describe '#ip_netmask' do
31
+ it 'will return a netmask object if the netmask is correct' do
32
+ network = DopCommon::Network.new('dummy', {})
33
+ expect(network.ip_netmask).to eq(nil)
34
+ network = DopCommon::Network.new('dummy', {'ip_netmask' => good_ip_netmask})
35
+ expect(network.ip_netmask.to_s).to eq(good_ip_netmask)
36
+ end
37
+ it 'will raise an error in case of invalid netmask' do
38
+ network = DopCommon::Network.new('dummy', {'ip_netmask' => :invalid})
39
+ expect { network.ip_netmask }.to raise_error DopCommon::PlanParsingError
40
+ end
41
+ end
42
+
43
+ describe '#ip_pool' do
44
+ good_ip_from = '192.168.1.11'
45
+ good_ip_to = '192.168.1.249'
46
+
47
+ it 'will return an empty hash if "ip_pool" is unspecified' do
48
+ network = DopCommon::Network.new('dummy', {})
49
+ expect(network.ip_pool).to eq({})
50
+ end
51
+
52
+ it 'will return a hash with "from" and "to" if network is specified properly' do
53
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'from' => good_ip_from, 'to' => good_ip_to}))
54
+ expect(network.ip_pool[:from].to_s).to eq(good_ip_from)
55
+ expect(network.ip_pool[:to].to_s).to eq(good_ip_to)
56
+ end
57
+
58
+ it 'will raise an error if ip_pool is not a hash and any of "from" or "to" is not defined' do
59
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => :invalid))
60
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
61
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'to' => good_ip_to}))
62
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
63
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'from' => good_ip_from}))
64
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
65
+ end
66
+
67
+ it 'will raise an error in case "from" is an invalid IP' do
68
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'from' => :invalid, 'to' => good_ip_to}))
69
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
70
+ end
71
+
72
+ it 'will raise an error in case "to" is an invalid IP' do
73
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'from' => good_ip_from, 'to' => :invalid}))
74
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
75
+ end
76
+
77
+ it 'will raise an error in case of invalid ip_pool specification (from > to)' do
78
+ network = DopCommon::Network.new('dummy', good_net.merge('ip_pool' => {'from' => good_ip_to, 'to' => good_ip_from}))
79
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
80
+ end
81
+
82
+ it 'will raise an error if the IP of default gateway is within IP pool range' do
83
+ bad_net = {
84
+ 'ip_defgw' => good_ip_from,
85
+ 'ip_netmask' => good_net['ip_netmask']
86
+ }
87
+ network = DopCommon::Network.new('dummy', bad_net.merge('ip_pool' => {'from' => good_ip_to, 'to' => good_ip_from}))
88
+ expect { network.ip_pool }.to raise_error DopCommon::PlanParsingError
89
+ end
90
+ end
91
+ end
92
+
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ class NodeFilterTest
4
+ include DopCommon::NodeFilter
5
+ end
6
+
7
+ describe DopCommon::NodeFilter do
8
+ describe '#filter_nodes' do
9
+ subject { NodeFilterTest.new.filter_nodes(nodes, filters) }
10
+
11
+ context 'include only specified nodes' do
12
+ let(:nodes) {[
13
+ instance_double(DopCommon::Node, :has_name? => true),
14
+ instance_double(DopCommon::Node, :has_name? => false)
15
+ ]}
16
+ let(:filters){OpenStruct.new({:nodes => '/foo/'})}
17
+
18
+ it { is_expected.to include(nodes[0]) }
19
+ it { is_expected.to_not include(nodes[1]) }
20
+ end
21
+
22
+ context 'exclude specified nodes' do
23
+ let(:nodes) {[
24
+ instance_double(DopCommon::Node, :has_name? => true),
25
+ instance_double(DopCommon::Node, :has_name? => false)
26
+ ]}
27
+ let(:filters){OpenStruct.new({:nodes => :all, :exclude_nodes => '/foo/'})}
28
+
29
+ it { is_expected.to include(nodes[1]) }
30
+ it { is_expected.to_not include(nodes[0]) }
31
+ end
32
+
33
+ context 'include only specified roles' do
34
+ let(:nodes) {[
35
+ instance_double(DopCommon::Node, :has_role? => true),
36
+ instance_double(DopCommon::Node, :has_role? => false)
37
+ ]}
38
+ let(:filters){OpenStruct.new({:roles => :all, :exclude_roles => '/foo/'})}
39
+
40
+ it { is_expected.to include(nodes[1]) }
41
+ it { is_expected.to_not include(nodes[0]) }
42
+ end
43
+
44
+ context 'exclude specified roles' do
45
+ let(:nodes) {[
46
+ instance_double(DopCommon::Node, :has_role? => true),
47
+ instance_double(DopCommon::Node, :has_role? => false)
48
+ ]}
49
+ let(:filters){OpenStruct.new({:roles => '/foo/'})}
50
+
51
+ it { is_expected.to include(nodes[0]) }
52
+ it { is_expected.to_not include(nodes[1]) }
53
+ end
54
+
55
+ context 'include only specified nodes by config' do
56
+ let(:nodes) {[
57
+ instance_double(DopCommon::Node, :config_includes? => true),
58
+ instance_double(DopCommon::Node, :config_includes? => false)
59
+ ]}
60
+ let(:filters){OpenStruct.new({:nodes_by_config => {'foo' => '/foo/'}})}
61
+
62
+ it { is_expected.to include(nodes[0]) }
63
+ it { is_expected.to_not include(nodes[1]) }
64
+ end
65
+
66
+
67
+ end
68
+ end
69
+
70
+