dop_common 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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
+