ironfan 4.12.3 → 5.0.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.
- data/Gemfile +1 -0
- data/Gemfile.lock +9 -8
- data/VERSION +1 -1
- data/ironfan.gemspec +19 -4
- data/lib/chef/knife/cluster_diff.rb +95 -0
- data/lib/chef/knife/cluster_launch.rb +1 -1
- data/lib/chef/knife/cluster_list.rb +4 -2
- data/lib/chef/knife/cluster_pry.rb +1 -1
- data/lib/chef/knife/cluster_show.rb +8 -5
- data/lib/chef/knife/cluster_ssh.rb +1 -1
- data/lib/chef/knife/environment_from_realm.rb +60 -0
- data/lib/chef/knife/ironfan_knife_common.rb +22 -0
- data/lib/chef/knife/ironfan_script.rb +1 -1
- data/lib/gorillib/diff.rb +266 -0
- data/lib/gorillib/nil_check_delegate.rb +30 -0
- data/lib/ironfan/broker/computer.rb +3 -0
- data/lib/ironfan/dsl/cluster.rb +10 -0
- data/lib/ironfan/dsl/component.rb +157 -0
- data/lib/ironfan/dsl/compute.rb +21 -0
- data/lib/ironfan/dsl/facet.rb +11 -0
- data/lib/ironfan/dsl/realm.rb +17 -14
- data/lib/ironfan/dsl/server.rb +287 -0
- data/lib/ironfan/dsl/volume.rb +1 -0
- data/lib/ironfan/dsl.rb +133 -1
- data/lib/ironfan/headers.rb +7 -0
- data/lib/ironfan/plugin/base.rb +89 -0
- data/lib/ironfan/provider/ec2/security_group.rb +2 -1
- data/lib/ironfan/requirements.rb +6 -0
- data/lib/ironfan.rb +21 -4
- data/spec/ironfan/diff_spec.rb +78 -0
- data/spec/ironfan/dsl_spec.rb +115 -0
- data/spec/ironfan/manifest_spec.rb +29 -0
- data/spec/ironfan/plugin_spec.rb +138 -0
- data/spec/ironfan/realm_spec.rb +137 -0
- data/spec/spec_helper/dummy_diff_drawer.rb +94 -0
- data/spec/spec_helper.rb +15 -0
- metadata +53 -19
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gorillib/diff'
|
3
|
+
require_relative '../spec_helper/dummy_diff_drawer.rb'
|
4
|
+
|
5
|
+
describe Gorillib::DiffFormatter do
|
6
|
+
it 'writes the indices of displayed elements for both sides' do
|
7
|
+
TestDrawer.diffing_objs([1], [1,2]) do |drawer|
|
8
|
+
drawer.should_receive(:display_indices).with(1,1)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
it 'adds objects correctly on the right' do
|
12
|
+
TestDrawer.diffing_objs([1], [1,2]) do |drawer|
|
13
|
+
drawer.should_receive(:display_add).with(nil, 2)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
it 'labels objects correctly on the right' do
|
17
|
+
TestDrawer.diffing_objs([1], [1,2]) do |drawer|
|
18
|
+
# meaning it displayed the name of the right object
|
19
|
+
drawer.should_receive(:b_right)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
it 'adds objects correctly on the left' do
|
23
|
+
TestDrawer.diffing_objs([1,2], [1]) do |drawer|
|
24
|
+
drawer.should_receive(:display_add).with(2, nil)
|
25
|
+
end
|
26
|
+
TestDrawer.diffing_objs([1,2], [1]) do |drawer|
|
27
|
+
# meaning it displayed the name of the left object
|
28
|
+
drawer.should_receive(:b_left)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
it 'lists keys only on the left correctly' do
|
32
|
+
TestDrawer.diffing_objs({a: 1, b: 2}, {a: 1}) do |drawer|
|
33
|
+
drawer.should_receive(:only_left_key).with(:b)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
it 'lists keys only on the right correctly' do
|
37
|
+
TestDrawer.diffing_objs({a: 1}, {a: 1, b: 2}) do |drawer|
|
38
|
+
drawer.should_receive(:only_right_key).with(:b)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
it 'explains when elements differ' do
|
42
|
+
TestDrawer.diffing_objs(1, 2) do |drawer|
|
43
|
+
drawer.should_receive(:display_noteql_atoms).with(1,2)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
it 'explains when elements are of different classes' do
|
47
|
+
TestDrawer.diffing_objs([], {}) do |drawer|
|
48
|
+
drawer.should_receive(:display_hetero).with([],{})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
it 'initializes itself every time it diffs a new pair of objects object' do
|
52
|
+
diff_formatter = TestDrawer.diff_formatter
|
53
|
+
|
54
|
+
diff_formatter.should_receive :setup
|
55
|
+
diff_formatter.display_diff(nil, nil)
|
56
|
+
diff_formatter.should_receive :setup
|
57
|
+
diff_formatter.display_diff(nil, nil)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'correctly diffs complex objects' do
|
61
|
+
|
62
|
+
# These aren't incredibly descriptive, but they are nice for
|
63
|
+
# bug-hunting.
|
64
|
+
|
65
|
+
TestDrawer.transform_ltor(1,2)
|
66
|
+
TestDrawer.transform_ltor([1], [1,2])
|
67
|
+
TestDrawer.transform_ltor({a: 1}, {a: 1, b: 2})
|
68
|
+
TestDrawer.transform_ltor([1,2], [1])
|
69
|
+
TestDrawer.transform_ltor({a: 1, b: 2}, {a: 1})
|
70
|
+
TestDrawer.transform_ltor({a: 1, b: 2}, {a: 1, c: 3})
|
71
|
+
TestDrawer.transform_ltor({a: [1]}, {a: [1,2]})
|
72
|
+
TestDrawer.transform_ltor({a: [1,2]}, {a: [1]})
|
73
|
+
TestDrawer.transform_ltor({a: [1]}, {a: [1,2]})
|
74
|
+
TestDrawer.transform_ltor({a: [1]}, {a: [1,2]})
|
75
|
+
TestDrawer.transform_ltor({a: [1], b: 3, c: {a: 1}, d: []}, {a: [1,2], c: [7,8], d: {a: 2}})
|
76
|
+
TestDrawer.transform_ltor([], [[1,2]])
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ironfan'
|
3
|
+
|
4
|
+
describe Ironfan::Dsl do
|
5
|
+
context 'when joining requirement pairs' do
|
6
|
+
subject{ Ironfan::Dsl.new }
|
7
|
+
|
8
|
+
def test_join(cn1, cn2)
|
9
|
+
name = 'foo'
|
10
|
+
subject.join_req(Ironfan::Plugin::CookbookRequirement.new(name: name, constraint: cn1),
|
11
|
+
Ironfan::Plugin::CookbookRequirement.new(name: name, constraint: cn2)).constraint
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'joins =,= requirements when valid' do
|
15
|
+
test_join('= 1.0.0', '= 1.0.0').should == '= 1.0.0'
|
16
|
+
end
|
17
|
+
it 'raises when =,= requirements not valid' do
|
18
|
+
expect{ test_join('= 1.0.0', '= 2.0.0') }.to raise_error
|
19
|
+
end
|
20
|
+
it 'chooses the more restrictive constraint for >= , >= requirements' do
|
21
|
+
test_join('>= 1.0.0', '>= 2.0.0').should == '>= 2.0.0'
|
22
|
+
test_join('>= 2.0.0', '>= 1.0.0').should == '>= 2.0.0'
|
23
|
+
end
|
24
|
+
it 'chooses the more restrictive constraint for ~> , ~> requirements' do
|
25
|
+
test_join('~> 1.0', '~> 1.2').should == '~> 1.2'
|
26
|
+
test_join('~> 1.2', '~> 1.0').should == '~> 1.2'
|
27
|
+
end
|
28
|
+
it 'raises when ~> , ~> requirements not valid' do
|
29
|
+
expect{ test_join('~> 1.0', '~> 1.0.0') }.to raise_error
|
30
|
+
expect{ test_join('~> 1.0', '~> 2.0') }.to raise_error
|
31
|
+
expect{ test_join('~> 2.0', '~> 1.0') }.to raise_error
|
32
|
+
end
|
33
|
+
it 'joins =, >= requirements when valid' do
|
34
|
+
test_join('= 1.1.0', '>= 1.1.0').should == '= 1.1.0'
|
35
|
+
test_join('>= 1.1.0', '= 1.1.0').should == '= 1.1.0'
|
36
|
+
end
|
37
|
+
it 'raises when =, >= requirements not valid' do
|
38
|
+
expect{ test_join('= 1.0.0', '>= 1.1.0') }.to raise_error
|
39
|
+
expect{ test_join('>= 1.1.0', '= 1.0.0') }.to raise_error
|
40
|
+
end
|
41
|
+
it 'joins =, ~> requirements when valid' do
|
42
|
+
test_join('= 1.1.0', '~> 1.0').should == '= 1.1.0'
|
43
|
+
test_join('~> 1.0', '= 1.1.0').should == '= 1.1.0'
|
44
|
+
end
|
45
|
+
it 'raises when =, ~> requirements not valid' do
|
46
|
+
expect{ test_join('= 2.0.0', '~> 1.0') }.to raise_error
|
47
|
+
expect{ test_join('~> 1.0', '= 2.0.0') }.to raise_error
|
48
|
+
end
|
49
|
+
it 'joins >=, ~> requirements when valid' do
|
50
|
+
test_join('>= 1.1.0', '~> 1.1.2').should == '~> 1.1.2'
|
51
|
+
test_join('~> 1.1.2', '>= 1.1.0').should == '~> 1.1.2'
|
52
|
+
end
|
53
|
+
it 'raises when >=, ~> requirements not valid' do
|
54
|
+
expect{ test_join('>= 1.1.3', '~> 1.1.2') }.to raise_error
|
55
|
+
expect{ test_join('~> 1.1.2', '>= 1.1.3') }.to raise_error
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when aggregating requirements' do
|
60
|
+
before(:each) do
|
61
|
+
Ironfan::Dsl.class_eval{ @@testing = true }
|
62
|
+
|
63
|
+
Ironfan::Dsl::Component.template(%w[foo]) do
|
64
|
+
cookbook_req 'a', '>= 1.2.3'
|
65
|
+
def project(*_) end
|
66
|
+
end
|
67
|
+
Ironfan::Dsl::Component.template(%w[bar]) do
|
68
|
+
cookbook_req 'a', '>= 1.2.5'
|
69
|
+
def project(*_) end
|
70
|
+
end
|
71
|
+
Ironfan::Dsl::Component.template(%w[baz]) do
|
72
|
+
cookbook_req 'a', '>= 1.2.7'
|
73
|
+
def project(*_) end
|
74
|
+
end
|
75
|
+
Ironfan.realm(:test) do
|
76
|
+
cluster(:just_foo) do
|
77
|
+
foo
|
78
|
+
end
|
79
|
+
cluster(:foo_bar) do
|
80
|
+
foo; bar
|
81
|
+
end
|
82
|
+
cluster(:nest_foo_bar) do
|
83
|
+
foo
|
84
|
+
facet(:bar) do
|
85
|
+
bar
|
86
|
+
end
|
87
|
+
end
|
88
|
+
cluster(:baz) do
|
89
|
+
baz
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
after(:each) do
|
95
|
+
[:Foo, :Bar, :Baz].each{|x| Ironfan::Dsl::Component.send(:remove_const, x)}
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'correctly merges version requirements in simple cases' do
|
99
|
+
Ironfan.realm(:test).tap do |realm|
|
100
|
+
realm.cluster(:just_foo).cookbook_reqs['a'].should == '>= 1.2.3'
|
101
|
+
realm.cluster( :foo_bar).cookbook_reqs['a'].should == '>= 1.2.5'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'correctly handles nested versions requirements' do
|
106
|
+
Ironfan.realm(:test).tap do |realm|
|
107
|
+
realm.cluster(:nest_foo_bar).tap do |cluster|
|
108
|
+
cluster .cookbook_reqs['a'].should == '>= 1.2.5'
|
109
|
+
cluster.facet(:bar).cookbook_reqs['a'].should == '>= 1.2.5'
|
110
|
+
end
|
111
|
+
realm.cookbook_reqs['a'].should == '>= 1.2.7'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ironfan'
|
3
|
+
|
4
|
+
describe Ironfan::Dsl::MachineManifest do
|
5
|
+
context 'it disregards whether values are strings or symbols' do
|
6
|
+
before(:each) do
|
7
|
+
Ironfan::Dsl::Component.template(%w[baz bif]) do
|
8
|
+
collection :bams, Symbol
|
9
|
+
magic :pow, Whatever
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def comparable_manifest(hsh)
|
14
|
+
Ironfan::Dsl::MachineManifest.receive(components: [Ironfan::Dsl::Component::BazBif.new(hsh)]).to_comparable
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'when those values are contained in an array of within its serialization' do
|
18
|
+
comparable_manifest(bam: [:a, :b, :c]).should == comparable_manifest(bam: %w[a b c])
|
19
|
+
comparable_manifest(pow: [:a, :b, :c]).should == comparable_manifest(pow: %w[a b c])
|
20
|
+
end
|
21
|
+
it 'when those values are contained in hash within its serialization' do
|
22
|
+
comparable_manifest(pow: {a: 'a'}).should == comparable_manifest(pow: {'a' => :a})
|
23
|
+
end
|
24
|
+
it 'correctly stores the chef environment' do
|
25
|
+
node = Chef::Node.json_create('chef_environment' => 'buzi', 'recipes' => [])
|
26
|
+
Ironfan::Dsl::MachineManifest.from_remote(nil, nil, nil, node, nil, nil, nil, nil, nil).environment.to_s.should == 'buzi'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe MyPlugin do
|
4
|
+
subject { MyPlugin }
|
5
|
+
|
6
|
+
it 'should respond to template' do
|
7
|
+
subject.should(respond_to(:template))
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when templatizing plugins' do
|
11
|
+
after(:each) do
|
12
|
+
uncreate_plugin(subject, Foo)
|
13
|
+
end
|
14
|
+
before(:each) do
|
15
|
+
subject.template(%w[baz bif])
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should create them as classes within itself' do
|
19
|
+
subject.constants.should(include(:BazBif))
|
20
|
+
end
|
21
|
+
it 'should create them as subclasses of itself' do
|
22
|
+
subject.const_get(:BazBif).should(be < subject)
|
23
|
+
end
|
24
|
+
it 'should allow customizing the classes' do
|
25
|
+
uncreate_plugin(subject, Foo)
|
26
|
+
subject.template(%w[baz bif]){ def bam() end }
|
27
|
+
subject.const_get(:BazBif).new.should(respond_to(:bam))
|
28
|
+
end
|
29
|
+
it 'should register methods on the specified class' do
|
30
|
+
Foo.new.should(respond_to(:baz_bif))
|
31
|
+
end
|
32
|
+
it 'should wire those methods to the plugin_hook method of itself' do
|
33
|
+
foo = Foo.new
|
34
|
+
subject.should_receive(:plugin_hook).with(foo, {}, :baz, :baz_bif)
|
35
|
+
foo.baz_bif
|
36
|
+
end
|
37
|
+
it 'should allow the user to create a custom class that will also be registered' do
|
38
|
+
Foo.registry[:baz_bif].should(be(subject.const_get(:BazBif)))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe Ironfan::Dsl::Component do
|
44
|
+
before(:each) do
|
45
|
+
Ironfan::Dsl::Component.template(%w[baz bif]) do
|
46
|
+
include Ironfan::Dsl::Component::Announcement
|
47
|
+
|
48
|
+
magic :bam, Symbol, node_attr: 'a.b.c', default: nil
|
49
|
+
|
50
|
+
def project(compute)
|
51
|
+
compute.role(:called_from_project, compute) unless bam
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
after(:each) do
|
57
|
+
uncreate_plugin(Ironfan::Dsl::Component, Ironfan::Dsl::Compute)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have its project method called by the plugin_hook' do
|
61
|
+
Ironfan.cluster(:foo) do
|
62
|
+
should_receive(:role).with(:called_from_project, self)
|
63
|
+
baz_bif
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should merge its node attribute to create a node' do
|
68
|
+
node = Chef::Node.new
|
69
|
+
node.set['a'] = {'b' => {'c' => :baz}}
|
70
|
+
Ironfan.cluster(:foo) do
|
71
|
+
baz_bif{ bam(:baz) }.to_node.to_hash.should == node.to_hash
|
72
|
+
end
|
73
|
+
end
|
74
|
+
it 'should be instantiable from a node object' do
|
75
|
+
node = Chef::Node.new
|
76
|
+
node.set['a'] = {'b' => {'c' => :baz}}
|
77
|
+
Ironfan::Dsl::Compute.registry[:baz_bif].from_node(node).bam.should == :baz
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should remember all of its node attributes' do
|
81
|
+
Ironfan.cluster(:foo) do
|
82
|
+
component = baz_bif{ bam(:baz) }
|
83
|
+
component.to_node.to_hash.should ==
|
84
|
+
Ironfan::Dsl::Compute.registry[:baz_bif].from_node(component.to_node).to_node.to_hash
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when announcing' do
|
89
|
+
before (:each) do
|
90
|
+
def make_plugin(name, server_b)
|
91
|
+
Ironfan::Dsl::Component.template([name, server_b ? 'server' : 'client']) do
|
92
|
+
include Ironfan::Dsl::Component::Announcement if server_b
|
93
|
+
include Ironfan::Dsl::Component::Discovery if not server_b
|
94
|
+
|
95
|
+
if server_b
|
96
|
+
def project(compute)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
def project(compute)
|
100
|
+
set_discovery compute, [announce_name]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_plugin_pair(name) make_plugin(name, true); make_plugin(name, false); end
|
107
|
+
|
108
|
+
make_plugin_pair(:bam); make_plugin_pair(:pow)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'automatically discovers announcements within realms' do
|
112
|
+
Ironfan.realm(:wap) do
|
113
|
+
cluster(:foo){ bam_client; pow_server }
|
114
|
+
cluster(:bar){ bam_server; pow_client }
|
115
|
+
|
116
|
+
cluster(:foo).cluster_role.override_attributes[:discovers].should == {bam: :wap_bar}
|
117
|
+
cluster(:bar).cluster_role.override_attributes[:discovers].should == {pow: :wap_foo}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'automatically configures security groups during discovery' do
|
122
|
+
Ironfan.realm(:wap) do
|
123
|
+
cloud(:ec2)
|
124
|
+
|
125
|
+
cluster(:foo){ bam_client; pow_server }
|
126
|
+
cluster(:bar){ bam_server; pow_client }
|
127
|
+
end.resolve!
|
128
|
+
|
129
|
+
rspec = self
|
130
|
+
|
131
|
+
foo_group = Ironfan.realm(:wap).cluster(:foo).cloud(:ec2).security_group('wap_foo')
|
132
|
+
bar_group = Ironfan.realm(:wap).cluster(:bar).cloud(:ec2).security_group('wap_bar')
|
133
|
+
|
134
|
+
foo_group.group_authorized.should include('wap_bar')
|
135
|
+
bar_group.group_authorized.should include('wap_foo')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'ironfan'
|
4
|
+
|
5
|
+
describe Ironfan::Dsl::Realm do
|
6
|
+
before(:each) do
|
7
|
+
(Chef::Config[:ec2_image_info] ||= {}).merge!({
|
8
|
+
%w[us-east-1 64-bit ebs ironfan-precise ] =>
|
9
|
+
{ :image_id => 'ami-29fe7640', :ssh_user => 'bam', :bootstrap_distro => "ubuntu12.04-ironfan", },
|
10
|
+
})
|
11
|
+
|
12
|
+
Ironfan.realm(:foo) do
|
13
|
+
environment :bif
|
14
|
+
|
15
|
+
cloud(:ec2) do
|
16
|
+
flavor 'm1.xlarge'
|
17
|
+
image_name 'ironfan-precise'
|
18
|
+
end
|
19
|
+
|
20
|
+
cluster(:bar) do
|
21
|
+
cluster_role.override_attributes(a: 1)
|
22
|
+
facet(:baz) do
|
23
|
+
instances 1
|
24
|
+
role :blah
|
25
|
+
facet_role.override_attributes(b: 1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def manifest
|
32
|
+
Ironfan.cluster(:foo_bar).facets[:baz].server(0).to_machine_manifest
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should choose its own name as its default environment' do
|
36
|
+
Ironfan.realm(:bar).environment.to_s.should == 'bar'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should choose the widest possible cookbook contraints to satisfy all plugins' do
|
40
|
+
Ironfan::Dsl::Component.template(%w[bam pow]) do
|
41
|
+
cookbook_req 'bif', '>= 1.0.0'
|
42
|
+
def project(_) end
|
43
|
+
end
|
44
|
+
|
45
|
+
Ironfan::Dsl::Component.template(%w[jam wam]) do
|
46
|
+
cookbook_req 'bif', '>= 2.0.0'
|
47
|
+
def project(_) end
|
48
|
+
end
|
49
|
+
|
50
|
+
Ironfan.realm(:qux) do
|
51
|
+
cluster(:cuz) do
|
52
|
+
facet(:lix) do
|
53
|
+
bam_pow
|
54
|
+
jam_wam
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end.cookbook_reqs['bif'].should == '>= 2.0.0'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should complain when no cookbook constraints can satisfy all plugins' do
|
61
|
+
Ironfan::Dsl::Component.template(%w[bam pow]) do
|
62
|
+
cookbook_req 'bif', '~> 1.0.0'
|
63
|
+
def project(_) end
|
64
|
+
end
|
65
|
+
|
66
|
+
Ironfan::Dsl::Component.template(%w[jam wam]) do
|
67
|
+
cookbook_req 'bif', '>= 2.0.0'
|
68
|
+
def project(_) end
|
69
|
+
end
|
70
|
+
|
71
|
+
Ironfan.realm(:qux) do
|
72
|
+
cluster(:cuz) do
|
73
|
+
facet(:lix) do
|
74
|
+
bam_pow
|
75
|
+
jam_wam
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
expect{ Ironfan.realm(:qux).cookbook_reqs }.to raise_error
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should create clusters that can be referenced later' do
|
84
|
+
x = self
|
85
|
+
Ironfan.realm :xx do
|
86
|
+
cluster(:bar).should(x.be(cluster(:bar)))
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should create clusters that can be edited later' do
|
91
|
+
Ironfan.realm :xy do
|
92
|
+
cluster(:baz)
|
93
|
+
cluster(:baz){ facet :bif }
|
94
|
+
end
|
95
|
+
|
96
|
+
Ironfan.cluster(:xy_baz).facets.to_a.should_not(be_empty)
|
97
|
+
Ironfan.cluster(:xy_baz).servers.to_a.first.should_not(be_nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should create clusters with names prefixed by its own' do
|
101
|
+
Ironfan.cluster(:foo_bar).should_not(be_nil)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should create clusters with machines' do
|
105
|
+
Ironfan.cluster(:foo_bar).facets[:baz].server(0).should_not(be_nil)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should create clusters with attributes correctly applied' do
|
109
|
+
manifest.cluster_override_attributes.should == {a: 1}
|
110
|
+
manifest.facet_override_attributes.should == {b: 1}
|
111
|
+
manifest.run_list.should == %w[role[blah] role[foo_bar-cluster] role[foo_bar-baz-facet]]
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should create clusters with the correct ssh user' do
|
115
|
+
manifest.flavor.should == 'm1.xlarge'
|
116
|
+
manifest.ssh_user.should == 'bam'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should save cloud properties to be shared among all clusters within the realm' do
|
120
|
+
# We need to resolve before the cloud settings come through
|
121
|
+
Ironfan.realm(:foo).clusters[:foo_bar].resolve.facets[:baz].servers.to_a.first.to_machine_manifest.flavor.should == 'm1.xlarge'
|
122
|
+
|
123
|
+
# Ironfan.cluster will do the resolution for us.
|
124
|
+
manifest.flavor.should == 'm1.xlarge'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should save an environment to be shared among all clusters within the realm' do
|
128
|
+
# We need to resolve before the cloud settings come through
|
129
|
+
Ironfan.realm(:foo).clusters[:foo_bar].resolve.facets[:baz].environment.should == :bif
|
130
|
+
|
131
|
+
# The server manifest should contain the environment.
|
132
|
+
manifest.environment.should == :bif
|
133
|
+
|
134
|
+
# Ironfan.cluster will do the resolution for us.
|
135
|
+
Ironfan.cluster(:foo_bar).facets[:baz].environment.should == :bif
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'gorillib/diff'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module TransformLeftToRight
|
5
|
+
attr_reader :left
|
6
|
+
|
7
|
+
DELETE_ME = Object.new
|
8
|
+
|
9
|
+
def display_key_header(key)
|
10
|
+
@left_lineage << [@left, key]
|
11
|
+
@left = @left[key]
|
12
|
+
|
13
|
+
@right_lineage << @right
|
14
|
+
@right = @right[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def only_left_key(_)
|
18
|
+
@left = DELETE_ME
|
19
|
+
end
|
20
|
+
|
21
|
+
def only_right_key(key)
|
22
|
+
@left = @right
|
23
|
+
end
|
24
|
+
|
25
|
+
def display_add(this, other)
|
26
|
+
if this.nil?
|
27
|
+
@left.insert(@ix, other)
|
28
|
+
@ix += 1
|
29
|
+
else
|
30
|
+
@left.delete_at(@ix)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def display_hetero(this, other)
|
35
|
+
@ix += 1
|
36
|
+
@left = @right
|
37
|
+
end
|
38
|
+
|
39
|
+
def display_noteql_items(*args)
|
40
|
+
@in_array = true
|
41
|
+
super(*args)
|
42
|
+
@in_array = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def display_noteql_atoms(this, other)
|
46
|
+
@ix += 1
|
47
|
+
@left = @right
|
48
|
+
end
|
49
|
+
|
50
|
+
def decrease_indentation
|
51
|
+
tmp = @left
|
52
|
+
@left,key = @left_lineage.pop
|
53
|
+
|
54
|
+
if tmp.equal?(DELETE_ME)
|
55
|
+
@left.delete(key)
|
56
|
+
else
|
57
|
+
@left[key] = tmp
|
58
|
+
end
|
59
|
+
|
60
|
+
@right = @right_lineage.pop
|
61
|
+
end
|
62
|
+
|
63
|
+
def increase_indentation() end
|
64
|
+
def indent() end
|
65
|
+
|
66
|
+
def display_indices(ixl, ixr)
|
67
|
+
@ix = ixr
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class TestDrawer
|
72
|
+
include Gorillib::DiffDrawerMethods
|
73
|
+
include TransformLeftToRight
|
74
|
+
|
75
|
+
def initialize this = nil, other = nil
|
76
|
+
@left_lineage = [@left = this]
|
77
|
+
@right_lineage = [@right = other]
|
78
|
+
@ix = 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.diffing_objs this, other
|
82
|
+
diff_formatter.display_diff(this, other)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.diff_formatter(drawer = nil)
|
86
|
+
Gorillib::DiffFormatter.new(stream: StringIO.new, drawer: drawer)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.transform_ltor this, other
|
90
|
+
drawer = new(this, other)
|
91
|
+
Gorillib::DiffFormatter.new(drawer: drawer).display_diff(this, other)
|
92
|
+
drawer.left.should == other
|
93
|
+
end
|
94
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
2
|
require 'chef'
|
3
3
|
require 'chef/knife'
|
4
|
+
require 'ironfan'
|
4
5
|
require 'fog'
|
5
6
|
Fog.mock!
|
6
7
|
Fog::Mock.delay = 0
|
@@ -36,3 +37,17 @@ end
|
|
36
37
|
require 'chef_zero/server'
|
37
38
|
server = ChefZero::Server.new(port: 4000)
|
38
39
|
server.start_background
|
40
|
+
|
41
|
+
def uncreate_plugin(plugin_class, target_class)
|
42
|
+
target_class.registry.clear
|
43
|
+
plugin_class.instance_eval{ remove_const :BazBif }
|
44
|
+
end
|
45
|
+
|
46
|
+
class Foo
|
47
|
+
end
|
48
|
+
|
49
|
+
class MyPlugin
|
50
|
+
include Ironfan::Plugin::Base; register_with Foo
|
51
|
+
|
52
|
+
def self.plugin_hook(*_) end
|
53
|
+
end
|