ironfan 3.1.7 → 3.2.2
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/CHANGELOG.md +11 -0
- data/Gemfile +15 -12
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/config/ubuntu10.04-ironfan.erb +10 -0
- data/config/ubuntu11.10-ironfan.erb +10 -0
- data/ironfan.gemspec +29 -54
- data/lib/chef/knife/bootstrap/centos6.2-ironfan.erb +10 -0
- data/lib/chef/knife/bootstrap/ubuntu10.04-ironfan.erb +10 -0
- data/lib/chef/knife/bootstrap/ubuntu11.10-ironfan.erb +10 -0
- data/lib/chef/knife/cluster_kick.rb +7 -2
- data/lib/chef/knife/cluster_launch.rb +3 -0
- data/lib/chef/knife/cluster_ssh.rb +3 -3
- data/lib/chef/knife/ironfan_knife_common.rb +21 -0
- data/lib/chef/knife/ironfan_script.rb +2 -0
- data/lib/ironfan/chef_layer.rb +9 -9
- data/lib/ironfan/cloud.rb +232 -360
- data/lib/ironfan/cluster.rb +3 -3
- data/lib/ironfan/compute.rb +26 -40
- data/lib/ironfan/deprecated.rb +45 -10
- data/lib/ironfan/discovery.rb +1 -1
- data/lib/ironfan/dsl_builder.rb +99 -0
- data/lib/ironfan/facet.rb +2 -3
- data/lib/ironfan/fog_layer.rb +14 -10
- data/lib/ironfan/private_key.rb +1 -1
- data/lib/ironfan/security_group.rb +46 -44
- data/lib/ironfan/server.rb +26 -52
- data/lib/ironfan/server_slice.rb +13 -19
- data/lib/ironfan/volume.rb +47 -59
- data/lib/ironfan.rb +5 -4
- metadata +116 -122
- data/lib/ironfan/dsl_object.rb +0 -124
- data/notes/Backup of ec2-pricing_and_capacity.numbers +0 -0
- data/notes/Home.md +0 -45
- data/notes/INSTALL-cloud_setup.md +0 -103
- data/notes/INSTALL.md +0 -134
- data/notes/Ironfan-Roadmap.md +0 -70
- data/notes/advanced-superpowers.md +0 -16
- data/notes/aws_servers.jpg +0 -0
- data/notes/aws_user_key.png +0 -0
- data/notes/cookbook-versioning.md +0 -11
- data/notes/core_concepts.md +0 -200
- data/notes/declaring_volumes.md +0 -3
- data/notes/design_notes-aspect_oriented_devops.md +0 -36
- data/notes/design_notes-ci_testing.md +0 -169
- data/notes/design_notes-cookbook_event_ordering.md +0 -249
- data/notes/design_notes-meta_discovery.md +0 -59
- data/notes/ec2-pricing_and_capacity.md +0 -69
- data/notes/ec2-pricing_and_capacity.numbers +0 -0
- data/notes/homebase-layout.txt +0 -102
- data/notes/knife-cluster-commands.md +0 -18
- data/notes/named-cloud-objects.md +0 -11
- data/notes/opscode_org_key.png +0 -0
- data/notes/opscode_user_key.png +0 -0
- data/notes/philosophy.md +0 -13
- data/notes/rake_tasks.md +0 -24
- data/notes/renamed-recipes.txt +0 -142
- data/notes/silverware.md +0 -85
- data/notes/style_guide.md +0 -300
- data/notes/tips_and_troubleshooting.md +0 -92
- data/notes/version-3_2.md +0 -273
- data/notes/walkthrough-hadoop.md +0 -168
- data/notes/walkthrough-web.md +0 -166
data/lib/ironfan/cluster.rb
CHANGED
@@ -51,7 +51,7 @@ module Ironfan
|
|
51
51
|
def facet(facet_name, attrs={}, &block)
|
52
52
|
facet_name = facet_name.to_sym
|
53
53
|
@facets[facet_name] ||= Ironfan::Facet.new(self, facet_name)
|
54
|
-
@facets[facet_name].
|
54
|
+
@facets[facet_name].receive!(attrs, &block)
|
55
55
|
@facets[facet_name]
|
56
56
|
end
|
57
57
|
|
@@ -83,7 +83,7 @@ module Ironfan
|
|
83
83
|
#
|
84
84
|
# @return [Ironfan::ServerSlice] the requested slice
|
85
85
|
def slice facet_name=nil, slice_indexes=nil
|
86
|
-
return
|
86
|
+
return servers if facet_name.nil?
|
87
87
|
find_facet(facet_name).slice(slice_indexes)
|
88
88
|
end
|
89
89
|
|
@@ -103,7 +103,7 @@ module Ironfan
|
|
103
103
|
# Create a security group named for the cluster
|
104
104
|
# that is friends with everything in the cluster
|
105
105
|
def create_cluster_security_group
|
106
|
-
clname = self.name # put it in scope
|
106
|
+
clname = self.name.to_s # put it in scope
|
107
107
|
cloud.security_group(clname){ authorize_group(clname) }
|
108
108
|
end
|
109
109
|
|
data/lib/ironfan/compute.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
|
+
require 'ironfan/volume' # configure external and internal volumes
|
1
2
|
module Ironfan
|
2
3
|
#
|
3
4
|
# Base class allowing us to layer settings for facet over cluster
|
4
5
|
#
|
5
|
-
class ComputeBuilder < Ironfan::
|
6
|
-
|
7
|
-
|
6
|
+
class ComputeBuilder < Ironfan::DslBuilder
|
7
|
+
magic :name, String
|
8
|
+
magic :bogosity, String, :default => false
|
9
|
+
magic :environment, String
|
10
|
+
collection :volumes, Ironfan::Volume, :resolution => ->(f) { merge_resolve(f) }
|
11
|
+
|
12
|
+
attr_reader :cloud, :chef_roles
|
8
13
|
@@role_implications ||= Mash.new
|
9
14
|
@@run_list_rank ||= 0
|
10
15
|
|
11
16
|
def initialize(builder_name, attrs={})
|
12
17
|
super(attrs)
|
13
|
-
|
18
|
+
name builder_name
|
14
19
|
@run_list_info = attrs[:run_list] || Mash.new
|
15
|
-
@
|
20
|
+
@clouds = Mash.new
|
16
21
|
end
|
17
22
|
|
18
23
|
# set the bogosity to a descriptive reason. Anything truthy implies bogusness
|
@@ -36,11 +41,18 @@ module Ironfan
|
|
36
41
|
# region 'us-east-1d'
|
37
42
|
# end
|
38
43
|
#
|
39
|
-
def cloud(cloud_provider
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
def cloud(cloud_provider=:ec2, attrs={}, &block)
|
45
|
+
case cloud_provider
|
46
|
+
when :ec2
|
47
|
+
klass = Ironfan::CloudDsl::Ec2
|
48
|
+
when :virtualbox
|
49
|
+
klass = Ironfan::CloudDsl::VirtualBox
|
50
|
+
else
|
51
|
+
raise "Only have EC2 and VirtualBox so far"
|
52
|
+
end
|
53
|
+
@clouds[cloud_provider] ||= klass.new(self)
|
54
|
+
@clouds[cloud_provider].receive!(attrs, &block)
|
55
|
+
@clouds[cloud_provider]
|
44
56
|
end
|
45
57
|
|
46
58
|
# sugar for cloud(:ec2)
|
@@ -48,39 +60,13 @@ module Ironfan
|
|
48
60
|
cloud(:ec2, attrs, &block)
|
49
61
|
end
|
50
62
|
|
51
|
-
# Magic method to describe a volume
|
52
|
-
# * returns the named volume, creating it if necessary.
|
53
|
-
# * executes the block (if any) in the volume's context
|
54
|
-
#
|
55
|
-
# @example
|
56
|
-
# # a 1 GB volume at '/data' from the given snapshot
|
57
|
-
# volume(:data) do
|
58
|
-
# size 1
|
59
|
-
# mount_point '/data'
|
60
|
-
# snapshot_id 'snap-12345'
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# @param volume_name [String] an arbitrary handle -- you can use the device
|
64
|
-
# name, or a descriptive symbol.
|
65
|
-
# @param attrs [Hash] a hash of attributes to pass down.
|
66
|
-
#
|
67
|
-
def volume(volume_name, attrs={}, &block)
|
68
|
-
volumes[volume_name] ||= Ironfan::Volume.new(:parent => self, :name => volume_name)
|
69
|
-
volumes[volume_name].configure(attrs, &block)
|
70
|
-
volumes[volume_name]
|
71
|
-
end
|
72
|
-
|
73
63
|
def raid_group(rg_name, attrs={}, &block)
|
74
|
-
volumes[rg_name]
|
75
|
-
|
76
|
-
|
64
|
+
raid = volumes[rg_name] || Ironfan::RaidGroup.new(:parent => self, :name => rg_name)
|
65
|
+
raid.receive!(attrs, &block)
|
66
|
+
raid.sub_volumes.each do |sv_name|
|
77
67
|
volume(sv_name){ in_raid(rg_name) ; mountable(false) ; tags({}) }
|
78
68
|
end
|
79
|
-
volumes[rg_name]
|
80
|
-
end
|
81
|
-
|
82
|
-
def root_volume(attrs={}, &block)
|
83
|
-
volume(:root, attrs, &block)
|
69
|
+
volumes[rg_name] = raid
|
84
70
|
end
|
85
71
|
|
86
72
|
#
|
data/lib/ironfan/deprecated.rb
CHANGED
@@ -1,33 +1,68 @@
|
|
1
1
|
module Ironfan
|
2
|
+
def self.deprecated call, replacement=nil
|
3
|
+
correction = ", use #{replacement} instead" if replacement
|
4
|
+
ui.warn "The '#{call}' statement is deprecated #{caller(2).first.inspect}#{correction}"
|
5
|
+
end
|
6
|
+
|
7
|
+
class DslBuilder
|
8
|
+
def to_hash
|
9
|
+
Ironfan.deprecated 'to_hash', 'attributes'
|
10
|
+
attributes
|
11
|
+
end
|
12
|
+
def to_mash
|
13
|
+
Ironfan.deprecated 'to_mash', 'attributes'
|
14
|
+
attributes
|
15
|
+
end
|
16
|
+
def reverse_merge!(attrs={})
|
17
|
+
Ironfan.deprecated 'reverse_merge!', 'receive!'
|
18
|
+
receive!(attrs)
|
19
|
+
end
|
20
|
+
def configure(attrs={},&block)
|
21
|
+
Ironfan.deprecated 'configure', 'receive!'
|
22
|
+
receive!(attrs, &block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ComputeBuilder
|
27
|
+
def root_volume(attrs={}, &block)
|
28
|
+
Ironfan.deprecated 'root_volume', 'volume(:root)'
|
29
|
+
volume(:root, attrs, &block)
|
30
|
+
end
|
31
|
+
end
|
2
32
|
|
3
33
|
class Cluster
|
4
|
-
#
|
5
|
-
# **DEPRECATED**: This doesn't really work -- use +reverse_merge!+ instead
|
6
|
-
#
|
7
34
|
def use(*clusters)
|
8
|
-
|
35
|
+
Ironfan.deprecated 'use', 'underlay'
|
9
36
|
clusters.each do |c|
|
10
37
|
other_cluster = Ironfan.load_cluster(c)
|
11
|
-
|
38
|
+
cluster.underlay other_cluster
|
12
39
|
end
|
13
40
|
self
|
14
41
|
end
|
15
|
-
|
16
42
|
end
|
17
43
|
|
18
44
|
class Server
|
19
|
-
# **DEPRECATED**: Please use +fullname+ instead.
|
20
45
|
def chef_node_name name
|
21
|
-
|
46
|
+
Ironfan.deprecated 'chef_node_name', 'fullname'
|
22
47
|
fullname name
|
23
48
|
end
|
49
|
+
|
50
|
+
def composite_volumes
|
51
|
+
Ironfan.deprecated 'composite_volumes', 'volumes'
|
52
|
+
volumes
|
53
|
+
end
|
24
54
|
end
|
25
55
|
|
26
|
-
class
|
27
|
-
# **DEPRECATED**: Please use +public_ip+ instead.
|
56
|
+
class CloudDsl::Ec2
|
28
57
|
def elastic_ip(*args, &block)
|
58
|
+
Ironfan.deprecated 'elastic_ip', 'public_ip'
|
29
59
|
public_ip(*args, &block)
|
30
60
|
end
|
31
61
|
end
|
32
62
|
|
63
|
+
class Volume
|
64
|
+
def defaults
|
65
|
+
Ironfan.deprecated 'defaults'
|
66
|
+
end
|
67
|
+
end
|
33
68
|
end
|
data/lib/ironfan/discovery.rb
CHANGED
@@ -76,7 +76,7 @@ module Ironfan
|
|
76
76
|
next
|
77
77
|
end
|
78
78
|
svr = Ironfan::Server.get(cluster_name, facet_name, facet_index)
|
79
|
-
svr.chef_node
|
79
|
+
svr.chef_node chef_node
|
80
80
|
@aws_instance_hash[ chef_node.ec2.instance_id ] = svr if chef_node[:ec2] && chef_node.ec2.instance_id
|
81
81
|
end
|
82
82
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Gorillib
|
2
|
+
module Model
|
3
|
+
Field.class_eval do
|
4
|
+
field :resolution, Whatever
|
5
|
+
end
|
6
|
+
end
|
7
|
+
module Underlies
|
8
|
+
include Gorillib::FancyBuilder
|
9
|
+
attr_accessor :underlay
|
10
|
+
|
11
|
+
def read_attribute(field_name)
|
12
|
+
field = self.class.fields[field_name] or return
|
13
|
+
return override_resolve(field_name) unless field.resolution.is_a? Proc
|
14
|
+
return self.instance_exec(field_name, &field.resolution)
|
15
|
+
end
|
16
|
+
|
17
|
+
def override_resolve(field_name)
|
18
|
+
result = read_set_or_underlay(field_name)
|
19
|
+
return result unless result.nil?
|
20
|
+
read_unset_attribute(field_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def merge_resolve(field_name)
|
24
|
+
attr = {}
|
25
|
+
if self.class.fields[field_name].respond_to? :item_type
|
26
|
+
attr[:item_type] = self.class.fields[field_name].item_type
|
27
|
+
end
|
28
|
+
result = self.class.fields[field_name].type.new(attr)
|
29
|
+
result.receive! read_underlay_attribute(field_name) || {}
|
30
|
+
result.receive! read_set_attribute(field_name) || {}
|
31
|
+
return result unless result.empty?
|
32
|
+
read_unset_attribute(field_name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def read_set_attribute(field_name)
|
36
|
+
attr_name = "@#{field_name}"
|
37
|
+
instance_variable_get(attr_name) if instance_variable_defined?(attr_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def read_underlay_attribute(field_name)
|
41
|
+
return if @underlay.nil?
|
42
|
+
underlay.read_set_or_underlay(field_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def read_set_or_underlay(field_name)
|
46
|
+
result = read_set_attribute(field_name)
|
47
|
+
return result unless result.nil?
|
48
|
+
read_underlay_attribute(field_name)
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module Ironfan
|
55
|
+
#
|
56
|
+
# This class is intended as a drop-in replacement for DslObject, using
|
57
|
+
# Gorillib::Builder setup, instead its half-baked predecessor.
|
58
|
+
#
|
59
|
+
# The magic attribute :underlay provides an object (preferably another
|
60
|
+
# Gorillib::Model or the like) that will respond with defaults. If
|
61
|
+
# fields are declared with a resolution lambda, it will apply that
|
62
|
+
# lambda in preference to the normal resolution rules (self.field
|
63
|
+
# -> underlay.magic -> self.field.default )
|
64
|
+
#
|
65
|
+
module DslHooks
|
66
|
+
def self.ui() Ironfan.ui ; end
|
67
|
+
def ui() Ironfan.ui ; end
|
68
|
+
|
69
|
+
# helper method for turning exceptions into warnings
|
70
|
+
def safely(*args, &block) Ironfan.safely(*args, &block) ; end
|
71
|
+
|
72
|
+
def step(desc, *style)
|
73
|
+
ui.info(" #{"%-15s" % (name.to_s+":")}\t#{ui.color(desc.to_s, *style)}")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class DslBuilder
|
78
|
+
include Gorillib::FancyBuilder
|
79
|
+
include Gorillib::Underlies
|
80
|
+
include Ironfan::DslHooks
|
81
|
+
end
|
82
|
+
|
83
|
+
class DslBuilderCollection < Gorillib::ModelCollection
|
84
|
+
include Ironfan::DslHooks
|
85
|
+
include Enumerable
|
86
|
+
# #
|
87
|
+
# # Enumerable
|
88
|
+
# #
|
89
|
+
# def each(&block)
|
90
|
+
# @servers.each(&block)
|
91
|
+
# end
|
92
|
+
# def length
|
93
|
+
# @servers.length
|
94
|
+
# end
|
95
|
+
# def empty?
|
96
|
+
# length == 0
|
97
|
+
# end
|
98
|
+
end
|
99
|
+
end
|
data/lib/ironfan/facet.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Ironfan
|
2
2
|
class Facet < Ironfan::ComputeBuilder
|
3
3
|
attr_reader :cluster
|
4
|
-
|
4
|
+
magic :instances, Integer, :default => 1
|
5
5
|
|
6
6
|
def initialize cluster, facet_name, attrs={}
|
7
7
|
super(facet_name.to_sym, attrs)
|
8
8
|
@cluster = cluster
|
9
9
|
@servers = Mash.new
|
10
10
|
@chef_roles = []
|
11
|
-
@settings[:instances] ||= 1
|
12
11
|
create_facet_role
|
13
12
|
create_facet_security_group unless attrs[:no_security_group]
|
14
13
|
end
|
@@ -55,7 +54,7 @@ module Ironfan
|
|
55
54
|
def server(idx, attrs={}, &block)
|
56
55
|
idx = idx.to_i
|
57
56
|
@servers[idx] ||= Ironfan::Server.new(self, idx)
|
58
|
-
@servers[idx].
|
57
|
+
@servers[idx].receive!(attrs, &block)
|
59
58
|
@servers[idx]
|
60
59
|
end
|
61
60
|
|
data/lib/ironfan/fog_layer.rb
CHANGED
@@ -33,6 +33,7 @@ module Ironfan
|
|
33
33
|
:key_name => cloud.keypair.to_s,
|
34
34
|
# Fog does not actually create tags when it creates a server.
|
35
35
|
:tags => {
|
36
|
+
:name => self.fullname,
|
36
37
|
:cluster => cluster_name,
|
37
38
|
:facet => facet_name,
|
38
39
|
:index => facet_index, },
|
@@ -72,11 +73,12 @@ module Ironfan
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def discover_volumes!
|
75
|
-
|
76
|
-
|
77
|
-
next if
|
76
|
+
result = self.class.fields[:volumes].type.new
|
77
|
+
volumes.each_pair do |vol_name, definition|
|
78
|
+
next if definition.fog_volume
|
78
79
|
next if Ironfan.chef_config[:cloud] == false
|
79
|
-
|
80
|
+
vol = definition.dup
|
81
|
+
vol.fog_volume = Ironfan.fog_volumes.find do |fv|
|
80
82
|
( # matches the explicit volume id
|
81
83
|
(vol.volume_id && (fv.id == vol.volume_id) ) ||
|
82
84
|
# OR this server's machine exists, and this volume is attached to
|
@@ -90,19 +92,21 @@ module Ironfan
|
|
90
92
|
(fv.tags['device'] == vol.device.to_s) )
|
91
93
|
)
|
92
94
|
end
|
93
|
-
next unless
|
94
|
-
|
95
|
-
|
96
|
-
check_server_id_pairing(
|
95
|
+
next unless vol.fog_volume
|
96
|
+
vol.volume_id(vol.fog_volume.id) unless vol.volume_id.present?
|
97
|
+
vol.availability_zone(vol.fog_volume.availability_zone) unless vol.availability_zone.present?
|
98
|
+
check_server_id_pairing(vol.fog_volume, vol.desc)
|
99
|
+
result[vol.name] = vol
|
97
100
|
end
|
101
|
+
write_attribute(:volumes,result)
|
98
102
|
end
|
99
103
|
|
100
104
|
def attach_volumes
|
101
105
|
return unless in_cloud?
|
102
106
|
discover_volumes!
|
103
|
-
return if
|
107
|
+
return if volumes.empty?
|
104
108
|
step(" attaching volumes")
|
105
|
-
|
109
|
+
volumes.each_pair do |vol_name, vol|
|
106
110
|
next if vol.volume_id.blank? || (vol.attachable != :ebs)
|
107
111
|
if (not vol.in_cloud?) then Chef::Log.debug("Volume not found: #{vol.desc}") ; next ; end
|
108
112
|
if (vol.has_server?) then check_server_id_pairing(vol.fog_volume, vol.desc) ; next ; end
|
data/lib/ironfan/private_key.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
module Ironfan
|
2
|
-
module
|
2
|
+
module CloudDsl
|
3
|
+
class SecurityGroup < Ironfan::DslBuilder
|
4
|
+
magic :name, String
|
5
|
+
magic :description, String
|
6
|
+
magic :group_authorizations, Array
|
7
|
+
magic :group_authorized_by, Array
|
8
|
+
magic :range_authorizations, Array
|
3
9
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
10
|
+
def initialize params
|
11
|
+
name params[:name].to_s
|
12
|
+
description "ironfan generated group #{name}"
|
13
|
+
group_authorizations []
|
14
|
+
group_authorized_by []
|
15
|
+
range_authorizations []
|
16
|
+
end
|
8
17
|
|
9
|
-
def
|
10
|
-
|
11
|
-
set :name, group_name.to_s
|
12
|
-
description group_description || "ironfan generated group #{group_name}"
|
13
|
-
@cloud = cloud
|
14
|
-
@group_authorizations = []
|
15
|
-
@group_authorized_by = []
|
16
|
-
@range_authorizations = []
|
17
|
-
owner_id(group_owner_id || Chef::Config[:knife][:aws_account_id])
|
18
|
+
def to_key
|
19
|
+
name
|
18
20
|
end
|
19
21
|
|
20
22
|
@@all = nil
|
@@ -52,34 +54,34 @@ module Ironfan
|
|
52
54
|
end
|
53
55
|
|
54
56
|
def authorize_group(group_name, owner_id=nil)
|
55
|
-
|
57
|
+
group_authorizations << [group_name.to_s, owner_id]
|
56
58
|
end
|
57
59
|
|
58
60
|
def authorized_by_group(other_name)
|
59
|
-
|
61
|
+
group_authorized_by << other_name.to_s
|
60
62
|
end
|
61
63
|
|
62
64
|
def authorize_port_range(range, cidr_ip = '0.0.0.0/0', ip_protocol = 'tcp')
|
63
65
|
range = (range .. range) if range.is_a?(Integer)
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
def group_permission_already_set?(fog_group, other_name, authed_owner)
|
68
|
-
return false if fog_group.ip_permissions.nil?
|
69
|
-
fog_group.ip_permissions.any? do |existing_permission|
|
70
|
-
existing_permission["groups"].include?({"userId" => authed_owner, "groupName" => other_name}) &&
|
71
|
-
existing_permission["fromPort"] == 1 &&
|
72
|
-
existing_permission["toPort"] == 65535
|
73
|
-
end
|
66
|
+
range_authorizations << [range, cidr_ip, ip_protocol]
|
74
67
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
68
|
+
#
|
69
|
+
# def group_permission_already_set?(fog_group, other_name, authed_owner)
|
70
|
+
# return false if fog_group.ip_permissions.nil?
|
71
|
+
# fog_group.ip_permissions.any? do |existing_permission|
|
72
|
+
# existing_permission["groups"].include?({"userId" => authed_owner, "groupName" => other_name}) &&
|
73
|
+
# existing_permission["fromPort"] == 1 &&
|
74
|
+
# existing_permission["toPort"] == 65535
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# def range_permission_already_set?(fog_group, range, cidr_ip, ip_protocol)
|
79
|
+
# return false if fog_group.ip_permissions.nil?
|
80
|
+
# fog_group.ip_permissions.include?(
|
81
|
+
# { "groups"=>[], "ipRanges"=>[{"cidrIp"=>cidr_ip}],
|
82
|
+
# "ipProtocol"=>ip_protocol, "fromPort"=>range.first, "toPort"=>range.last})
|
83
|
+
# end
|
84
|
+
#
|
83
85
|
# FIXME: so if you're saying to yourself, "self, this is some soupy gooey
|
84
86
|
# code right here" then you and your self are correct. Much of this is to
|
85
87
|
# work around old limitations in the EC2 api. You can now treat range and
|
@@ -110,22 +112,22 @@ module Ironfan
|
|
110
112
|
rescue StandardError => err ; handle_security_group_error(err) ; end
|
111
113
|
end
|
112
114
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
115
|
+
#
|
116
|
+
# def handle_security_group_error(err)
|
117
|
+
# if (/has already been authorized/ =~ err.to_s)
|
118
|
+
# Chef::Log.debug err
|
119
|
+
# else
|
120
|
+
# ui.warn(err)
|
121
|
+
# end
|
122
|
+
# end
|
123
|
+
#
|
122
124
|
def self.step(group_name, desc, *style)
|
123
125
|
ui.info(" group #{"%-15s" % (group_name+":")}\t#{ui.color(desc.to_s, *style)}")
|
124
126
|
end
|
125
127
|
def step(desc, *style)
|
126
128
|
self.class.step(self.name, desc, *style)
|
127
129
|
end
|
128
|
-
|
129
130
|
end
|
131
|
+
|
130
132
|
end
|
131
133
|
end
|
data/lib/ironfan/server.rb
CHANGED
@@ -7,15 +7,20 @@ module Ironfan
|
|
7
7
|
# or if it exists in the real world (as revealed by Fog)
|
8
8
|
#
|
9
9
|
class Server < Ironfan::ComputeBuilder
|
10
|
-
|
11
|
-
|
10
|
+
magic :cluster, Cluster
|
11
|
+
magic :facet, Facet
|
12
|
+
magic :facet_index, Integer
|
13
|
+
attr_reader :tags
|
14
|
+
|
15
|
+
magic :chef_node, Whatever, :default => -> owner,name { owner.cluster.find_node(name) || false }
|
16
|
+
attr_accessor :fog_server
|
12
17
|
|
13
18
|
@@all ||= Mash.new
|
14
19
|
|
15
20
|
def initialize facet, idx
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
cluster facet.cluster
|
22
|
+
facet facet
|
23
|
+
facet_index idx
|
19
24
|
@fullname = [cluster_name, facet_name, facet_index].join('-')
|
20
25
|
super(@fullname)
|
21
26
|
@tags = { "name" => name, "cluster" => cluster_name, "facet" => facet_name, "index" => facet_index, }
|
@@ -40,13 +45,13 @@ module Ironfan
|
|
40
45
|
Ironfan::ServerSlice.new(cluster, [self])
|
41
46
|
end
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
# def bogosity val=nil
|
49
|
+
# @settings[:bogosity] = val if not val.nil?
|
50
|
+
# return @settings[:bogosity] if not @settings[:bogosity].nil?
|
51
|
+
# return :bogus_facet if facet.bogus?
|
52
|
+
# # return :out_of_range if (self.facet_index.to_i >= facet.instances)
|
53
|
+
# false
|
54
|
+
# end
|
50
55
|
|
51
56
|
def in_cloud?
|
52
57
|
!! fog_server
|
@@ -85,7 +90,7 @@ module Ironfan
|
|
85
90
|
end
|
86
91
|
|
87
92
|
def permanent?
|
88
|
-
|
93
|
+
[true, :true, 'true'].include?(self.cloud.permanent)
|
89
94
|
end
|
90
95
|
|
91
96
|
def killable?
|
@@ -118,13 +123,12 @@ module Ironfan
|
|
118
123
|
# Resolve:
|
119
124
|
#
|
120
125
|
def resolve!
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
cloud.
|
126
|
-
|
127
|
-
#
|
126
|
+
facet.underlay = cluster
|
127
|
+
self.underlay = facet
|
128
|
+
|
129
|
+
facet.cloud.underlay = cluster.cloud
|
130
|
+
cloud.underlay = facet.cloud
|
131
|
+
|
128
132
|
cloud.user_data({
|
129
133
|
:chef_server => chef_server_url,
|
130
134
|
:validation_client_name => validation_client_name,
|
@@ -185,36 +189,6 @@ module Ironfan
|
|
185
189
|
cg[:last], fg[:last], sg[:last], ].flatten.compact.uniq
|
186
190
|
end
|
187
191
|
|
188
|
-
#
|
189
|
-
# This prepares a composited view of the volumes -- it shows the cluster
|
190
|
-
# definition overlaid by the facet definition overlaid by the server
|
191
|
-
# definition.
|
192
|
-
#
|
193
|
-
# This method *does* auto-vivify an empty volume declaration on the server,
|
194
|
-
# but doesn't modify it.
|
195
|
-
#
|
196
|
-
# This code is pretty smelly, but so is the resolve! behavior. advice welcome.
|
197
|
-
#
|
198
|
-
def composite_volumes
|
199
|
-
vols = {}
|
200
|
-
self.volumes.each do |vol_name, vol|
|
201
|
-
vols[vol_name] ||= self.volumes[vol_name].dup
|
202
|
-
vols[vol_name].reverse_merge!(vol)
|
203
|
-
end
|
204
|
-
facet.volumes.each do |vol_name, vol|
|
205
|
-
self.volumes[vol_name] ||= Ironfan::Volume.new(:parent => self, :name => vol_name)
|
206
|
-
vols[vol_name] ||= self.volumes[vol_name].dup
|
207
|
-
vols[vol_name].reverse_merge!(vol)
|
208
|
-
end
|
209
|
-
cluster.volumes.each do |vol_name, vol|
|
210
|
-
self.volumes[vol_name] ||= Ironfan::Volume.new(:parent => self, :name => vol_name)
|
211
|
-
vols[vol_name] ||= self.volumes[vol_name].dup
|
212
|
-
vols[vol_name].reverse_merge!(vol)
|
213
|
-
end
|
214
|
-
vols.each{|vol_name, vol| vol.availability_zone self.default_availability_zone }
|
215
|
-
vols
|
216
|
-
end
|
217
|
-
|
218
192
|
# FIXME -- this will break on some edge case wehre a bogus node is
|
219
193
|
# discovered after everything is resolve!d
|
220
194
|
def default_availability_zone
|
@@ -269,7 +243,7 @@ module Ironfan
|
|
269
243
|
return unless created?
|
270
244
|
step(" labeling servers and volumes")
|
271
245
|
fog_create_tags(fog_server, self.fullname, tags)
|
272
|
-
|
246
|
+
volumes.each_pair do |vol_name, vol|
|
273
247
|
if vol.fog_volume
|
274
248
|
fog_create_tags(vol.fog_volume, vol.desc,
|
275
249
|
{ "server" => self.fullname, "name" => "#{name}-#{vol.name}", "device" => vol.device, "mount_point" => vol.mount_point, "cluster" => cluster_name, "facet" => facet_name, "index" => facet_index, })
|
@@ -278,7 +252,7 @@ module Ironfan
|
|
278
252
|
end
|
279
253
|
|
280
254
|
def block_device_mapping
|
281
|
-
|
255
|
+
volumes.values.map(&:block_device_mapping).compact
|
282
256
|
end
|
283
257
|
|
284
258
|
# ugh. non-dry below.
|