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