ironfan 4.10.3 → 4.10.4
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 +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +10 -0
- data/README.md +1 -1
- data/VERSION +1 -1
- data/ironfan.gemspec +9 -3
- data/lib/chef/knife/bootstrap/rhel6.3-ironfan.erb +179 -0
- data/lib/chef/knife/cluster_launch.rb +1 -1
- data/lib/ironfan/dsl/cloud.rb +1 -0
- data/lib/ironfan/dsl/rds.rb +84 -0
- data/lib/ironfan/headers.rb +7 -1
- data/lib/ironfan/provider/ec2/machine.rb +4 -0
- data/lib/ironfan/provider/rds/machine.rb +225 -0
- data/lib/ironfan/provider/rds/security_group.rb +128 -0
- data/lib/ironfan/provider/rds.rb +53 -0
- data/lib/ironfan/provider/vsphere/machine.rb +4 -0
- data/lib/ironfan/provider.rb +1 -0
- data/lib/ironfan/requirements.rb +4 -0
- data/spec/fixtures/knife/knife.rb +5 -0
- data/spec/spec_helper.rb +9 -3
- metadata +10 -3
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# v4.10.4
|
|
2
|
+
* Cleaning up specs to use local credentials, chef-zero (requires libssl): fixes #242
|
|
3
|
+
* Added RDS support, see https://github.com/infochimps-labs/ironfan/pull/290 for details
|
|
4
|
+
|
|
1
5
|
# v4.10.3
|
|
2
6
|
* Tightening version constraints on excon, to avoid bad interaction between it & fog
|
|
3
7
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -22,6 +22,11 @@ GEM
|
|
|
22
22
|
treetop (~> 1.4.9)
|
|
23
23
|
uuidtools
|
|
24
24
|
yajl-ruby (~> 1.1)
|
|
25
|
+
chef-zero (1.1.3)
|
|
26
|
+
hashie (~> 2.0)
|
|
27
|
+
mixlib-log (~> 1.3)
|
|
28
|
+
moneta (< 0.7.0)
|
|
29
|
+
puma (~> 2.0)
|
|
25
30
|
coderay (1.0.9)
|
|
26
31
|
columnize (0.3.6)
|
|
27
32
|
configliere (0.4.18)
|
|
@@ -59,6 +64,7 @@ GEM
|
|
|
59
64
|
guard-yard (2.1.0)
|
|
60
65
|
guard (>= 1.1.0)
|
|
61
66
|
yard (>= 0.7.0)
|
|
67
|
+
hashie (2.0.5)
|
|
62
68
|
highline (1.6.19)
|
|
63
69
|
ipaddress (0.8.0)
|
|
64
70
|
jeweler (1.8.4)
|
|
@@ -107,6 +113,9 @@ GEM
|
|
|
107
113
|
coderay (~> 1.0.5)
|
|
108
114
|
method_source (~> 0.8)
|
|
109
115
|
slop (~> 3.4)
|
|
116
|
+
puma (2.0.1)
|
|
117
|
+
rack (>= 1.1, < 2.0)
|
|
118
|
+
rack (1.5.2)
|
|
110
119
|
rake (10.0.4)
|
|
111
120
|
rb-fsevent (0.9.3)
|
|
112
121
|
rb-inotify (0.9.0)
|
|
@@ -163,6 +172,7 @@ PLATFORMS
|
|
|
163
172
|
DEPENDENCIES
|
|
164
173
|
bundler (~> 1.0)
|
|
165
174
|
chef (~> 10.16)
|
|
175
|
+
chef-zero
|
|
166
176
|
excon (~> 0.21.0)
|
|
167
177
|
fog (~> 1.2)
|
|
168
178
|
formatador (~> 0.2)
|
data/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Ironfan consists of the following Toolset:
|
|
|
23
23
|
- knife plugins to orchestrate clusters of machines using simple commands like `knife cluster launch`
|
|
24
24
|
- logic to coordinate truth among chef server and cloud providers.
|
|
25
25
|
* [ironfan-pantry](https://github.com/infochimps-labs/ironfan-pantry): Our collection of industrial-strength, cloud-ready recipes for Hadoop, HBase, Cassandra, Elasticsearch, Zabbix and more.
|
|
26
|
-
* [silverware cookbook](https://github.com/infochimps-labs/ironfan-
|
|
26
|
+
* [silverware cookbook](https://github.com/infochimps-labs/ironfan-pantry/tree/master/cookbooks/silverware): coordinate discovery of services ("list all the machines for `awesome_webapp`, that I might load balance them") and aspects ("list all components that write logs, that I might logrotate them, or that I might monitor the free space on their volumes".
|
|
27
27
|
|
|
28
28
|
### Documentation
|
|
29
29
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.10.
|
|
1
|
+
4.10.4
|
data/ironfan.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "ironfan"
|
|
8
|
-
s.version = "4.10.
|
|
8
|
+
s.version = "4.10.4"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Infochimps"]
|
|
12
|
-
s.date = "2013-
|
|
12
|
+
s.date = "2013-06-03"
|
|
13
13
|
s.description = "Ironfan allows you to orchestrate not just systems but clusters of machines. It includes a powerful layer on top of knife and a collection of cloud cookbooks."
|
|
14
14
|
s.email = "coders@infochimps.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
|
|
|
40
40
|
"ironfan.gemspec",
|
|
41
41
|
"lib/chef/knife/bootstrap/centos6.2-ironfan.erb",
|
|
42
42
|
"lib/chef/knife/bootstrap/chef-full-ironfan.erb",
|
|
43
|
+
"lib/chef/knife/bootstrap/rhel6.3-ironfan.erb",
|
|
43
44
|
"lib/chef/knife/bootstrap/ubuntu10.04-ironfan.erb",
|
|
44
45
|
"lib/chef/knife/bootstrap/ubuntu12.04-ironfan.erb",
|
|
45
46
|
"lib/chef/knife/cluster_bootstrap.rb",
|
|
@@ -69,6 +70,7 @@ Gem::Specification.new do |s|
|
|
|
69
70
|
"lib/ironfan/dsl/compute.rb",
|
|
70
71
|
"lib/ironfan/dsl/ec2.rb",
|
|
71
72
|
"lib/ironfan/dsl/facet.rb",
|
|
73
|
+
"lib/ironfan/dsl/rds.rb",
|
|
72
74
|
"lib/ironfan/dsl/role.rb",
|
|
73
75
|
"lib/ironfan/dsl/server.rb",
|
|
74
76
|
"lib/ironfan/dsl/virtualbox.rb",
|
|
@@ -89,6 +91,9 @@ Gem::Specification.new do |s|
|
|
|
89
91
|
"lib/ironfan/provider/ec2/machine.rb",
|
|
90
92
|
"lib/ironfan/provider/ec2/placement_group.rb",
|
|
91
93
|
"lib/ironfan/provider/ec2/security_group.rb",
|
|
94
|
+
"lib/ironfan/provider/rds.rb",
|
|
95
|
+
"lib/ironfan/provider/rds/machine.rb",
|
|
96
|
+
"lib/ironfan/provider/rds/security_group.rb",
|
|
92
97
|
"lib/ironfan/provider/virtualbox.rb",
|
|
93
98
|
"lib/ironfan/provider/virtualbox/machine.rb",
|
|
94
99
|
"lib/ironfan/provider/vsphere.rb",
|
|
@@ -132,6 +137,7 @@ Gem::Specification.new do |s|
|
|
|
132
137
|
"spec/fixtures/ec2/elb/snakeoil.key",
|
|
133
138
|
"spec/fixtures/gunbai.rb",
|
|
134
139
|
"spec/fixtures/gunbai_slice.json",
|
|
140
|
+
"spec/fixtures/knife/knife.rb",
|
|
135
141
|
"spec/integration/minimal-chef-repo/chefignore",
|
|
136
142
|
"spec/integration/minimal-chef-repo/environments/_default.json",
|
|
137
143
|
"spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb",
|
|
@@ -155,7 +161,7 @@ Gem::Specification.new do |s|
|
|
|
155
161
|
s.require_paths = ["lib"]
|
|
156
162
|
s.rubygems_version = "1.8.23"
|
|
157
163
|
s.summary = "Infochimps' lightweight cloud orchestration toolkit, built on top of Chef."
|
|
158
|
-
s.test_files = ["spec/spec_helper/dummy_chef.rb", "spec/integration/spec_helper/launch_cluster.rb", "spec/integration/minimal-chef-repo/roles/systemwide.rb", "spec/integration/minimal-chef-repo/chefignore", "spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb", "spec/integration/minimal-chef-repo/knife/knife.rb", "spec/integration/minimal-chef-repo/environments/_default.json", "spec/integration/spec/simple_cluster_spec.rb", "spec/integration/spec/elb_build_spec.rb", "spec/integration/spec_helper.rb", "spec/test_config.rb", "spec/chef/cluster_bootstrap_spec.rb", "spec/chef/cluster_launch_spec.rb", "spec/fixtures/gunbai_slice.json", "spec/fixtures/ec2/elb/snakeoil.crt", "spec/fixtures/ec2/elb/snakeoil.key", "spec/fixtures/gunbai.rb", "spec/spec_helper.rb", "spec/ironfan/cluster_spec.rb", "spec/ironfan/ec2/cloud_provider_spec.rb", "spec/ironfan/ec2/elb_spec.rb", "spec/ironfan/ec2/security_group_spec.rb"]
|
|
164
|
+
s.test_files = ["spec/spec_helper/dummy_chef.rb", "spec/integration/spec_helper/launch_cluster.rb", "spec/integration/minimal-chef-repo/roles/systemwide.rb", "spec/integration/minimal-chef-repo/chefignore", "spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb", "spec/integration/minimal-chef-repo/knife/knife.rb", "spec/integration/minimal-chef-repo/environments/_default.json", "spec/integration/spec/simple_cluster_spec.rb", "spec/integration/spec/elb_build_spec.rb", "spec/integration/spec_helper.rb", "spec/test_config.rb", "spec/chef/cluster_bootstrap_spec.rb", "spec/chef/cluster_launch_spec.rb", "spec/fixtures/gunbai_slice.json", "spec/fixtures/knife/knife.rb", "spec/fixtures/ec2/elb/snakeoil.crt", "spec/fixtures/ec2/elb/snakeoil.key", "spec/fixtures/gunbai.rb", "spec/spec_helper.rb", "spec/ironfan/cluster_spec.rb", "spec/ironfan/ec2/cloud_provider_spec.rb", "spec/ironfan/ec2/elb_spec.rb", "spec/ironfan/ec2/security_group_spec.rb"]
|
|
159
165
|
|
|
160
166
|
if s.respond_to? :specification_version then
|
|
161
167
|
s.specification_version = 3
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
bash <<'EOF' || echo "Chef bootstrap failed!"
|
|
2
|
+
|
|
3
|
+
# This is the RHEL 6 bootstrap script from infochimps' ironfan. It is
|
|
4
|
+
# based on opscode's bootstrap script, with the following important differences:
|
|
5
|
+
#
|
|
6
|
+
# * installs ruby 1.9.2 (not 1.8.7) from source
|
|
7
|
+
# * upgrades rubygems rather than installing from source
|
|
8
|
+
# * pushes the computer identity into the first-boot.json
|
|
9
|
+
# * installs the chef-client service and kicks off the first run of chef
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
<%= (@config[:verbosity].to_i > 1 ? 'set -v' : '') %>
|
|
14
|
+
|
|
15
|
+
RUBY_VERSION=1.9.2-p290
|
|
16
|
+
CHEF_VERSION=<%= bootstrap_version_string.gsub(/.*[\s=]/,"") %>
|
|
17
|
+
|
|
18
|
+
mkdir -p /tmp/knife-bootstrap
|
|
19
|
+
chmod 700 /tmp/knife-bootstrap
|
|
20
|
+
cd /tmp/knife-bootstrap
|
|
21
|
+
|
|
22
|
+
<%= "export http_proxy=\"#{knife_config[:bootstrap_proxy]}\"" if knife_config[:bootstrap_proxy] -%>
|
|
23
|
+
cat /etc/redhat-release
|
|
24
|
+
|
|
25
|
+
date > /etc/box_build_time
|
|
26
|
+
|
|
27
|
+
echo -e "`date` \n\n**** \n**** yum upgrade:\n****\n"
|
|
28
|
+
yum upgrade --assumeyes
|
|
29
|
+
|
|
30
|
+
echo -e "`date` \n\n**** \n**** Installing base packages:\n****\n"
|
|
31
|
+
yum install --assumeyes make wget
|
|
32
|
+
yum install --assumeyes git rpm-build rpmdevtools gcc glibc-static zlib-devel libxml2-devel libxslt-devel openssl-devel telnet nc uuid-devel
|
|
33
|
+
if [ ! -d runit-rpm ]; then git clone https://github.com/imeyer/runit-rpm.git; fi
|
|
34
|
+
cd runit-rpm
|
|
35
|
+
./build.sh
|
|
36
|
+
yum install --assumeyes /root/rpmbuild/RPMS/x86_64/runit-*.rpm || true # TODO: Remove this shim
|
|
37
|
+
cd -
|
|
38
|
+
yum remove --assumeyes prelink
|
|
39
|
+
yum clean all
|
|
40
|
+
|
|
41
|
+
if [ ! -f /usr/bin/chef-client ]; then
|
|
42
|
+
echo -e "`date` \n\n**** \n**** Installing ruby version ${RUBY_VERSION}:\n****\n"
|
|
43
|
+
|
|
44
|
+
wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-${RUBY_VERSION}.tar.gz
|
|
45
|
+
tar xzf ruby-${RUBY_VERSION}.tar.gz
|
|
46
|
+
cd ruby-${RUBY_VERSION}
|
|
47
|
+
./configure --with-ruby-version=${RUBY_VERSION} --prefix=/usr --program-suffix=${RUBY_VERSION}
|
|
48
|
+
make -j2
|
|
49
|
+
make install
|
|
50
|
+
|
|
51
|
+
alternatives \
|
|
52
|
+
--install /usr/bin/ruby ruby /usr/bin/ruby${RUBY_VERSION} 400 \
|
|
53
|
+
--slave /usr/bin/ri ri /usr/bin/ri${RUBY_VERSION} \
|
|
54
|
+
--slave /usr/bin/irb irb /usr/bin/irb${RUBY_VERSION} \
|
|
55
|
+
--slave /usr/bin/erb erb /usr/bin/erb${RUBY_VERSION} \
|
|
56
|
+
--slave /usr/bin/gem gem /usr/bin/gem${RUBY_VERSION} \
|
|
57
|
+
--slave /usr/share/man/man1/ruby.1.gz ruby.1.gz \
|
|
58
|
+
/usr/share/man/man1/ruby${RUBY_VERSION}.1
|
|
59
|
+
|
|
60
|
+
echo -e "`date` \n\n**** \n**** Updating rubygems:\n****\n"
|
|
61
|
+
gem install rubygems-update -v 1.8.5
|
|
62
|
+
|
|
63
|
+
echo -e "`date` \n\n**** \n**** Installing chef:\n****\n"
|
|
64
|
+
gem install net-ssh --no-rdoc --no-ri --version 2.2.2
|
|
65
|
+
gem install net-ssh-gateway --no-rdoc --no-ri --version 1.1.0
|
|
66
|
+
gem install net-ssh-multi --no-rdoc --no-ri --version 1.1
|
|
67
|
+
gem install ohai --no-rdoc --no-ri --version 6.14.0
|
|
68
|
+
gem install chef --no-rdoc --no-ri --version 10.16.4
|
|
69
|
+
# gems needed for the client.rb or so generically useful you want them at hand
|
|
70
|
+
gem install --no-rdoc --no-ri extlib bundler json right_aws pry fog
|
|
71
|
+
|
|
72
|
+
else # no chef-client
|
|
73
|
+
echo -e "`date` \n\n**** \n**** Chef is present -- skipping apt/ruby/chef installation\n****\n"
|
|
74
|
+
fi # end ruby+chef install
|
|
75
|
+
|
|
76
|
+
echo -e "`date` \n\n**** \n**** Knifing in the chef client config files:\n****\n"
|
|
77
|
+
mkdir -p /etc/chef
|
|
78
|
+
|
|
79
|
+
<%- if @config[:client_key] %>
|
|
80
|
+
(
|
|
81
|
+
cat <<'EOP'
|
|
82
|
+
<%= @config[:client_key] %>
|
|
83
|
+
EOP
|
|
84
|
+
) > /tmp/knife-bootstrap/client.pem
|
|
85
|
+
awk NF /tmp/knife-bootstrap/client.pem > /etc/chef/client.pem
|
|
86
|
+
<%- else %>
|
|
87
|
+
(
|
|
88
|
+
cat <<'EOP'
|
|
89
|
+
<%= validation_key %>
|
|
90
|
+
EOP
|
|
91
|
+
) > /tmp/knife-bootstrap/validation.pem
|
|
92
|
+
awk NF /tmp/knife-bootstrap/validation.pem > /etc/chef/validation.pem
|
|
93
|
+
<%- end %>
|
|
94
|
+
|
|
95
|
+
<% if @chef_config[:encrypted_data_bag_secret] -%>
|
|
96
|
+
(
|
|
97
|
+
cat <<'EOP'
|
|
98
|
+
<%= encrypted_data_bag_secret %>
|
|
99
|
+
EOP
|
|
100
|
+
) > /tmp/encrypted_data_bag_secret
|
|
101
|
+
awk NF /tmp/encrypted_data_bag_secret > /etc/chef/encrypted_data_bag_secret
|
|
102
|
+
rm /tmp/encrypted_data_bag_secret
|
|
103
|
+
<% end -%>
|
|
104
|
+
|
|
105
|
+
echo -e "`date` \n\n**** \n**** Nuking our temp files:\n****\n"
|
|
106
|
+
|
|
107
|
+
cd /tmp
|
|
108
|
+
rm -rf /tmp/knife-bootstrap
|
|
109
|
+
|
|
110
|
+
echo -e "`date` \n\n**** \n**** Creating chef client script:\n****\n"
|
|
111
|
+
|
|
112
|
+
(
|
|
113
|
+
cat <<'EOP'
|
|
114
|
+
<%= config_content %>
|
|
115
|
+
<%= @config[:computer].chef_client_script_content %>
|
|
116
|
+
EOP
|
|
117
|
+
) > /etc/chef/client.rb
|
|
118
|
+
|
|
119
|
+
(
|
|
120
|
+
cat <<'EOP'
|
|
121
|
+
<%= { "run_list" => @run_list, "cluster_name" => @config[:server].cluster_name, "facet_name" => @config[:server].facet_name, "facet_index" => @config[:server].index }.to_json %>
|
|
122
|
+
EOP
|
|
123
|
+
) > /etc/chef/first-boot.json
|
|
124
|
+
|
|
125
|
+
# Ensure that EC2 images are recognized even inside VPC
|
|
126
|
+
mkdir -p /etc/chef/ohai/hints/
|
|
127
|
+
touch /etc/chef/ohai/hints/ec2.json
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
echo -e "`date` \n\n**** \n**** Adding chef client nonce script:\n****\n"
|
|
131
|
+
|
|
132
|
+
cat > /etc/init.d/chef-client-nonce <<'EOP'
|
|
133
|
+
#! /bin/sh
|
|
134
|
+
### BEGIN INIT INFO
|
|
135
|
+
# Provides: chef-client-nonce
|
|
136
|
+
# Required-Start: $remote_fs $network
|
|
137
|
+
# Required-Stop:
|
|
138
|
+
# Default-Start: 2 3 4 5
|
|
139
|
+
# Default-Stop: 0 1 6
|
|
140
|
+
# Short-Description: Start a single chef-client run.
|
|
141
|
+
### END INIT INFO
|
|
142
|
+
#
|
|
143
|
+
# Copyright (c) 2009-2010 Opscode, Inc, <legal@opscode.com>
|
|
144
|
+
#
|
|
145
|
+
# chef-client Startup script for chef-client.
|
|
146
|
+
# chkconfig: - 99 02
|
|
147
|
+
# description: starts up chef-client once, at boot
|
|
148
|
+
|
|
149
|
+
case "$1" in
|
|
150
|
+
start)
|
|
151
|
+
/usr/bin/chef-client -L /var/log/chef/client.log
|
|
152
|
+
exit $?
|
|
153
|
+
;;
|
|
154
|
+
*)
|
|
155
|
+
echo "Usage: /etc/init.d/chef-client-nonce start" >&2
|
|
156
|
+
exit 1
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
EOP
|
|
160
|
+
|
|
161
|
+
mkdir -p /var/log/chef
|
|
162
|
+
mkdir -p /etc/sv
|
|
163
|
+
chmod +x /etc/init.d/chef-client-nonce
|
|
164
|
+
chkconfig --add chef-client-nonce
|
|
165
|
+
chkconfig --del iptables
|
|
166
|
+
chkconfig --del rh-cloud-firstboot
|
|
167
|
+
chkconfig --add rh-cloud-firstboot
|
|
168
|
+
|
|
169
|
+
rm /etc/sysconfig/rh-cloud-firstboot
|
|
170
|
+
|
|
171
|
+
<%- if (@config[:bootstrap_runs_chef_client].to_s == 'true') || (@chef_config.knife[:bootstrap_runs_chef_client].to_s == 'true') %>
|
|
172
|
+
sudo /etc/init.d/chef-client-nonce start
|
|
173
|
+
<%- end %>
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
echo -e "`date` \n\n**** \n**** Cleanup:\n****\n"
|
|
178
|
+
cd /
|
|
179
|
+
rm -r /tmp/knife-bootstrap
|
|
@@ -95,7 +95,7 @@ class Chef
|
|
|
95
95
|
# As each server finishes, configure it
|
|
96
96
|
Ironfan.parallel(launched) do |computer|
|
|
97
97
|
if (computer.is_a?(Exception)) then ui.warn "Error launching #{computer.inspect}; skipping after-launch tasks."; next; end
|
|
98
|
-
perform_after_launch_tasks(computer)
|
|
98
|
+
perform_after_launch_tasks(computer) if computer.machine.perform_after_launch_tasks?
|
|
99
99
|
end
|
|
100
100
|
|
|
101
101
|
if healthy?
|
data/lib/ironfan/dsl/cloud.rb
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
|
|
3
|
+
module Ironfan
|
|
4
|
+
class Dsl
|
|
5
|
+
|
|
6
|
+
class Compute < Ironfan::Dsl
|
|
7
|
+
def rds(*attrs,&block) cloud(:rds,*attrs,&block); end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Rds < Cloud
|
|
11
|
+
magic :autoupgrade, :boolean, :default => true
|
|
12
|
+
magic :availability_zones, Array, :default => ['us-east-1d']
|
|
13
|
+
magic :backup_retention, Integer, :default => 1
|
|
14
|
+
magic :charset, String, :default => nil
|
|
15
|
+
magic :dbname, String, :default => nil
|
|
16
|
+
magic :default_availability_zone, String, :default => ->{ availability_zones.first }
|
|
17
|
+
magic :engine, String, :default => ->{ engines.first }
|
|
18
|
+
magic :engines, Array, :default => ["MySQL", "oracle-se1", "oracle-se", "oracle-ee", "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web"]
|
|
19
|
+
magic :flavor, String, :default => "db.t1.micro"
|
|
20
|
+
magic :iops, Integer, :default => 1000
|
|
21
|
+
magic :license_model, String, :default => nil
|
|
22
|
+
magic :multi_az, :boolean, :default => false
|
|
23
|
+
magic :password, String, :default => nil
|
|
24
|
+
magic :port, Integer, :default => -> { default_port }
|
|
25
|
+
magic :preferred_backup_window, String, :default => nil # Format hh24:mi-hh24:mi. Needs to be at least 30 minutes, UTC,
|
|
26
|
+
magic :preferred_maintenance_window, String, :default => nil # Format ddd:hh24:mi-ddd:hh24:mi. Minimum 30 minutes, UTC
|
|
27
|
+
magic :provider, Whatever, :default => Ironfan::Provider::Rds
|
|
28
|
+
magic :size, Integer, :default => 50 # Size in GB
|
|
29
|
+
collection :security_groups, Ironfan::Dsl::Rds::SecurityGroup, :key_method => :name
|
|
30
|
+
magic :username, String, :default => nil
|
|
31
|
+
magic :version, String, :default => nil
|
|
32
|
+
|
|
33
|
+
def receive_provider(obj)
|
|
34
|
+
if obj.is_a?(String)
|
|
35
|
+
write_attribute :provider, Gorillib::Inflector.constantize(Gorillib::Inflector.camelize(obj.gsub(/\./, '/')))
|
|
36
|
+
else
|
|
37
|
+
super(obj)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# This is a dummy function to fill Ironfan's requirements.
|
|
42
|
+
def implied_volumes
|
|
43
|
+
[]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def default_port
|
|
47
|
+
return 3306 if engine == "MySQL"
|
|
48
|
+
return 1521 if ["oracle-se1", "oracle-se", "oracle-ee"].include?(engine)
|
|
49
|
+
return 1433 if ["sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web"].include?(engine)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def to_display(style,values={})
|
|
53
|
+
return values if style == :minimal
|
|
54
|
+
|
|
55
|
+
values["Engine"] = engine
|
|
56
|
+
values["AZ"] = default_availability_zone
|
|
57
|
+
return values if style == :default
|
|
58
|
+
|
|
59
|
+
# values["Public IP"] = elastic_ip if elastic_ip
|
|
60
|
+
values
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class SecurityGroup < Ironfan::Dsl
|
|
64
|
+
field :name, String
|
|
65
|
+
field :ec2_authorizations, Array, :default => []
|
|
66
|
+
field :ip_authorizations, Array, :default => []
|
|
67
|
+
|
|
68
|
+
def authorize_ip_range(cidr_ip = '0.0.0.0/0')
|
|
69
|
+
ip_authorizations << cidr_ip
|
|
70
|
+
ip_authorizations.compact!
|
|
71
|
+
ip_authorizations.uniq!
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def authorize_ec2_group(ec2_security_group)
|
|
75
|
+
ec2_authorizations << ec2_security_group
|
|
76
|
+
ec2_authorizations.compact!
|
|
77
|
+
ec2_authorizations.uniq!
|
|
78
|
+
end
|
|
79
|
+
end # SecurityGroup
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
data/lib/ironfan/headers.rb
CHANGED
|
@@ -31,6 +31,9 @@ module Ironfan
|
|
|
31
31
|
end
|
|
32
32
|
class VirtualBox < Cloud; end
|
|
33
33
|
class Vsphere < Cloud; end
|
|
34
|
+
class Rds < Cloud
|
|
35
|
+
class SecurityGroup < Ironfan::Dsl; end
|
|
36
|
+
end
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
class Provider < Builder
|
|
@@ -62,7 +65,10 @@ module Ironfan
|
|
|
62
65
|
class Machine < Ironfan::IaasProvider::Machine; end
|
|
63
66
|
class Keypair < Ironfan::Provider::Resource; end
|
|
64
67
|
end
|
|
65
|
-
|
|
68
|
+
class Rds < Ironfan::IaasProvider
|
|
69
|
+
class Machine < Ironfan::IaasProvider::Machine; end
|
|
70
|
+
class SecurityGroup < Ironfan::Provider::Resource; end
|
|
71
|
+
end
|
|
66
72
|
end
|
|
67
73
|
|
|
68
74
|
end
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
module Ironfan
|
|
2
|
+
class Provider
|
|
3
|
+
class Rds
|
|
4
|
+
|
|
5
|
+
class Machine < Ironfan::IaasProvider::Machine
|
|
6
|
+
delegate :availability_zone, :created_at, :desstroy, :endpoint, :engine,
|
|
7
|
+
:engine_version, :destroy, :flavor_id, :id, :id=, :name, :state, :add_tags,
|
|
8
|
+
:tags,
|
|
9
|
+
:to => :adaptee
|
|
10
|
+
|
|
11
|
+
def self.shared?() false; end
|
|
12
|
+
def self.multiple?() false; end
|
|
13
|
+
def self.resource_type() :machine; end
|
|
14
|
+
def self.expected_ids(computer) [computer.server.full_name]; end
|
|
15
|
+
|
|
16
|
+
def name
|
|
17
|
+
return id if tags.empty?
|
|
18
|
+
tags["Name"] || tags["name"] || id
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def public_hostname ; dns_name ; end
|
|
22
|
+
|
|
23
|
+
def created?
|
|
24
|
+
not ['terminated', 'shutting-down'].include? state
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def deleting?
|
|
28
|
+
state == "deleting"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def pending?
|
|
32
|
+
state == "pending"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def creating?
|
|
36
|
+
state == "creating"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def rebooting?
|
|
40
|
+
state == "rebooting"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def available?
|
|
44
|
+
state == "available"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def stopped?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def perform_after_launch_tasks?
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def to_display(style,values={})
|
|
55
|
+
# style == :minimal
|
|
56
|
+
values["State"] = state.to_sym
|
|
57
|
+
values["Endpoint"] = adaptee.endpoint["Address"]
|
|
58
|
+
values["Created On"] = created_at.to_date
|
|
59
|
+
return values if style == :minimal
|
|
60
|
+
|
|
61
|
+
# style == :default
|
|
62
|
+
values["Flavor"] = flavor_id
|
|
63
|
+
values["AZ"] = availability_zone
|
|
64
|
+
return values if style == :default
|
|
65
|
+
|
|
66
|
+
# style == :expanded
|
|
67
|
+
values["Port"] = adaptee.endpoint["Port"]
|
|
68
|
+
values["Engine"] = engine
|
|
69
|
+
values["EngineVersion"] = engine_version
|
|
70
|
+
values
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def to_s
|
|
74
|
+
"<%-15s %-12s %-25s %-25s %-15s %-15s>" % [
|
|
75
|
+
self.class.handle, id, created_at, tags['name'], flavor_id, availability_zone]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
# Discovery
|
|
80
|
+
#
|
|
81
|
+
def self.load!(cluster=nil)
|
|
82
|
+
Rds.connection.servers.each do |fs|
|
|
83
|
+
machine = new(:adaptee => fs)
|
|
84
|
+
if (not machine.created?)
|
|
85
|
+
next unless Ironfan.chef_config[:include_terminated]
|
|
86
|
+
remember machine, :append_id => "terminated:#{machine.id}"
|
|
87
|
+
elsif recall? machine.name
|
|
88
|
+
machine.bogus << :duplicate_machines
|
|
89
|
+
recall(machine.name).bogus << :duplicate_machines
|
|
90
|
+
remember machine, :append_id => "duplicate:#{machine.id}"
|
|
91
|
+
else # never seen it
|
|
92
|
+
remember machine
|
|
93
|
+
end
|
|
94
|
+
Chef::Log.debug("Loaded #{machine}")
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def receive_adaptee(obj)
|
|
99
|
+
obj = Rds.connection.servers.new(obj) if obj.is_a?(Hash)
|
|
100
|
+
super
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Find active machines that haven't matched, but should have,
|
|
104
|
+
# make sure all bogus machines have a computer to attach to
|
|
105
|
+
# for display purposes
|
|
106
|
+
def self.validate_resources!(computers)
|
|
107
|
+
recall.each_value do |machine|
|
|
108
|
+
next unless machine.users.empty? and machine.name
|
|
109
|
+
if machine.name.match("^#{computers.cluster.name}-")
|
|
110
|
+
machine.bogus << :unexpected_machine
|
|
111
|
+
end
|
|
112
|
+
next unless machine.bogus?
|
|
113
|
+
fake = Ironfan::Broker::Computer.new
|
|
114
|
+
fake[:machine] = machine
|
|
115
|
+
fake.name = machine.name
|
|
116
|
+
machine.users << fake
|
|
117
|
+
computers << fake
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
#
|
|
122
|
+
# Manipulation
|
|
123
|
+
#
|
|
124
|
+
def self.create!(computer)
|
|
125
|
+
return if computer.machine? and computer.machine.created?
|
|
126
|
+
Ironfan.step(computer.name,"creating RDS machine... go grab some a beer or two.", :green)
|
|
127
|
+
#
|
|
128
|
+
errors = lint(computer)
|
|
129
|
+
if errors.present? then raise ArgumentError, "Failed validation: #{errors.inspect}" ; end
|
|
130
|
+
#
|
|
131
|
+
launch_desc = launch_description(computer)
|
|
132
|
+
launch_desc[:id] = computer.name
|
|
133
|
+
Chef::Log.debug(JSON.pretty_generate(launch_desc))
|
|
134
|
+
|
|
135
|
+
Ironfan.safely do
|
|
136
|
+
fog_server = Rds.connection.servers.create(launch_desc)
|
|
137
|
+
machine = Machine.new(:adaptee => fog_server)
|
|
138
|
+
computer.machine = machine
|
|
139
|
+
remember machine, :id => computer.name
|
|
140
|
+
|
|
141
|
+
Ironfan.step(fog_server.id,"waiting for machine to be ready", :gray)
|
|
142
|
+
Ironfan.tell_you_thrice :name => fog_server.id,
|
|
143
|
+
:problem => "server unavailable",
|
|
144
|
+
:error_class => Fog::Errors::Error do
|
|
145
|
+
fog_server.wait_for { ready? }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# tag the computer correctly
|
|
150
|
+
tags = {
|
|
151
|
+
'cluster' => computer.server.cluster_name,
|
|
152
|
+
'facet' => computer.server.facet_name,
|
|
153
|
+
'index' => computer.server.index,
|
|
154
|
+
'name' => computer.name,
|
|
155
|
+
'Name' => computer.name,
|
|
156
|
+
}
|
|
157
|
+
Rds.ensure_tags(tags, computer.machine)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# @returns [Hash{String, Array}] of 'what you did wrong' => [relevant, info]
|
|
161
|
+
def self.lint(computer)
|
|
162
|
+
cloud = computer.server.cloud(:rds)
|
|
163
|
+
info = [computer.name, cloud.inspect]
|
|
164
|
+
errors = {}
|
|
165
|
+
errors["No Password"] = info if cloud.password.empty?
|
|
166
|
+
errors["No Username"] = info if cloud.username.empty?
|
|
167
|
+
errors["Size"] = info if cloud.size < 5
|
|
168
|
+
errors
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def self.launch_description(computer)
|
|
172
|
+
cloud = computer.server.cloud(:rds)
|
|
173
|
+
user_data_hsh = {
|
|
174
|
+
:chef_server => Chef::Config[:chef_server_url],
|
|
175
|
+
:node_name => computer.name,
|
|
176
|
+
:organization => Chef::Config[:organization],
|
|
177
|
+
:cluster_name => computer.server.cluster_name,
|
|
178
|
+
:facet_name => computer.server.facet_name,
|
|
179
|
+
:facet_index => computer.server.index,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# main machine info
|
|
184
|
+
# note that Fog does not actually create tags when it creates a
|
|
185
|
+
# server; they and permanence are applied during sync
|
|
186
|
+
description = {
|
|
187
|
+
:allocated_storage => cloud.size,
|
|
188
|
+
:auto_minor_version_upgrade => cloud.autoupgrade,
|
|
189
|
+
:availability_zone => cloud.multi_az ? nil : cloud.default_availability_zone,
|
|
190
|
+
:backup_retention_period => cloud.backup_retention,
|
|
191
|
+
:db_name => cloud.dbname,
|
|
192
|
+
:engine => cloud.engine,
|
|
193
|
+
:engine_version => cloud.version,
|
|
194
|
+
:flavor_id => cloud.flavor,
|
|
195
|
+
:license_model => cloud.license_model,
|
|
196
|
+
:master_username => cloud.username,
|
|
197
|
+
:multi_az => cloud.multi_az,
|
|
198
|
+
:password => cloud.password,
|
|
199
|
+
:port => cloud.port,
|
|
200
|
+
:preferred_backup_window => cloud.preferred_backup_window,
|
|
201
|
+
:preferred_maintenance_window => cloud.preferred_maintenance_window,
|
|
202
|
+
:security_group_names => cloud.security_groups.keys,
|
|
203
|
+
:user_data => JSON.pretty_generate(user_data_hsh),
|
|
204
|
+
# :charset => cloud.charset, # Not supported in FOG?
|
|
205
|
+
# :iops => cloud.iops, # Not supported in FOG?
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
description
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def self.destroy!(computer)
|
|
212
|
+
return unless computer.machine?
|
|
213
|
+
forget computer.machine.name
|
|
214
|
+
computer.machine.destroy
|
|
215
|
+
computer.machine.reload # show the node as shutting down
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def self.save!(computer)
|
|
219
|
+
return unless computer.machine?
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module Ironfan
|
|
2
|
+
class Provider
|
|
3
|
+
class Rds
|
|
4
|
+
|
|
5
|
+
class SecurityGroup < Ironfan::Provider::Resource
|
|
6
|
+
|
|
7
|
+
delegate :id, :authorize_port_range,
|
|
8
|
+
:to => :adaptee
|
|
9
|
+
|
|
10
|
+
def self.shared?() true; end
|
|
11
|
+
def self.multiple?() true; end
|
|
12
|
+
def self.resource_type() :security_group; end
|
|
13
|
+
def self.expected_ids(computer)
|
|
14
|
+
return unless computer.server
|
|
15
|
+
rds = computer.server.cloud(:rds)
|
|
16
|
+
rds.security_groups.keys.uniq
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name()
|
|
20
|
+
adaptee.id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Discovery
|
|
25
|
+
#
|
|
26
|
+
def self.load!(cluster=nil)
|
|
27
|
+
Rds.connection.security_groups.reject { |raw| raw.blank? }.each do |raw|
|
|
28
|
+
sg = SecurityGroup.new(:adaptee => raw)
|
|
29
|
+
remember(sg)
|
|
30
|
+
Chef::Log.debug("Loaded #{sg}: #{sg.inspect}")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def receive_adaptee(obj)
|
|
35
|
+
obj = Rds.connection.security_groups.new(obj) if obj.is_a?(Hash)
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_s
|
|
40
|
+
return "<%-15s %s>" % [ self.class.handle, id ]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# Manipulation
|
|
45
|
+
#
|
|
46
|
+
|
|
47
|
+
def self.prepare!(computers)
|
|
48
|
+
|
|
49
|
+
# Create any groups that don't yet exist, and ensure any authorizations
|
|
50
|
+
# that are required for those groups
|
|
51
|
+
cluster_name = nil
|
|
52
|
+
groups_to_create = [ ]
|
|
53
|
+
ec2_authorizations = [ ]
|
|
54
|
+
ip_authorizations = [ ]
|
|
55
|
+
|
|
56
|
+
# First, deduce the list of all groups to which at least one instance belongs
|
|
57
|
+
# We'll use this later to decide whether to create groups, or authorize access,
|
|
58
|
+
# using a VPC security group or an EC2 security group.
|
|
59
|
+
|
|
60
|
+
computers.select { |computer| Rds.applicable computer }.each do |computer|
|
|
61
|
+
cloud = computer.server.cloud(:rds)
|
|
62
|
+
cluster_name = computer.server.cluster_name
|
|
63
|
+
|
|
64
|
+
# Iterate over all of the security group information, keeping track of
|
|
65
|
+
# any groups that must exist and any authorizations that must be ensured
|
|
66
|
+
cloud.security_groups.values.each do |dsl_group|
|
|
67
|
+
groups_to_create << dsl_group.name
|
|
68
|
+
ip_authorizations << dsl_group.ip_authorizations.map do |ip|
|
|
69
|
+
{
|
|
70
|
+
:grantor => dsl_group.name,
|
|
71
|
+
:grantee => ip,
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
ec2_authorizations << dsl_group.ec2_authorizations.map do |ec2|
|
|
76
|
+
{
|
|
77
|
+
:grantor => dsl_group.name,
|
|
78
|
+
:grantee => ec2,
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
groups_to_create = groups_to_create.flatten.uniq.reject { |group| recall? group.to_s }.sort
|
|
85
|
+
ip_authorizations = ip_authorizations.flatten.uniq.sort { |a,b| a[:grantor] <=> b[:grantor] }
|
|
86
|
+
ec2_authorizations = ec2_authorizations.flatten.uniq.sort { |a,b| a[:grantor] <=> b[:grantor] }
|
|
87
|
+
|
|
88
|
+
Ironfan.step(cluster_name, "creating security groups", :blue) unless groups_to_create.empty?
|
|
89
|
+
groups_to_create.each do |group|
|
|
90
|
+
Ironfan.step(group, "creating #{group} security group", :blue)
|
|
91
|
+
begin
|
|
92
|
+
Rds.connection.create_db_security_group(group,"Ironfan created group #{group}")
|
|
93
|
+
rescue Fog::Compute::AWS::Error => e # InvalidPermission.Duplicate
|
|
94
|
+
Chef::Log.info("ignoring security group error: #{e}")
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Re-load everything so that we have a @@known list of security groups to manipulate
|
|
99
|
+
load! unless groups_to_create.empty?
|
|
100
|
+
|
|
101
|
+
# Now make sure that all required authorizations are present
|
|
102
|
+
Ironfan.step(cluster_name, "ensuring security group permissions", :blue) unless (ec2_authorizations.empty? or ip_authorizations.empty?)
|
|
103
|
+
ip_authorizations.each do |auth|
|
|
104
|
+
message = " ensuring access from #{auth[:grantor]} to #{auth[:grantee]} "
|
|
105
|
+
Ironfan.step(auth[:grantor], message, :blue)
|
|
106
|
+
begin
|
|
107
|
+
Rds.connection.authorize_db_security_group_ingress(auth[:grantor], { "CIDRIP" => auth[:grantee] })
|
|
108
|
+
rescue Fog::AWS::RDS::AuthorizationAlreadyExists => e
|
|
109
|
+
Chef::Log.info("ignoring security group error: #{e}")
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
ec2_authorizations.each do |auth|
|
|
114
|
+
message = " ensuring access from #{auth[:grantor]} to #{auth[:grantee]} "
|
|
115
|
+
Ironfan.step(auth[:grantor], message, :blue)
|
|
116
|
+
aws_account, security_group = auth[:grantee].split('/')
|
|
117
|
+
begin
|
|
118
|
+
Rds.connection.authorize_db_security_group_ingress(auth[:grantor], { "EC2SecurityGroupName" => security_group, "EC2SecurityGroupOwnerId" => aws_account })
|
|
119
|
+
rescue Fog::AWS::RDS::AuthorizationAlreadyExists => e
|
|
120
|
+
Chef::Log.info("ignoring security group error: #{e}")
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Ironfan
|
|
2
|
+
class Provider
|
|
3
|
+
|
|
4
|
+
class Rds < Ironfan::IaasProvider
|
|
5
|
+
self.handle = :rds
|
|
6
|
+
|
|
7
|
+
def self.resources
|
|
8
|
+
[ Machine, SecurityGroup ]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Utility functions
|
|
13
|
+
#
|
|
14
|
+
def self.connection
|
|
15
|
+
@@connection ||= Fog::AWS::RDS.new(self.aws_credentials)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.iam
|
|
19
|
+
credentials = self.aws_credentials
|
|
20
|
+
credentials.delete(:region)
|
|
21
|
+
@@iam ||= Fog::AWS::IAM.new(credentials)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.aws_account_id()
|
|
25
|
+
Chef::Config[:knife][:aws_account_id]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Ensure that a fog object (machine, volume, etc.) has the proper tags on it
|
|
29
|
+
def self.ensure_tags(tags, fog)
|
|
30
|
+
tags.delete_if {|k, v| fog.tags[k] == v.to_s rescue false }
|
|
31
|
+
return if tags.empty?
|
|
32
|
+
|
|
33
|
+
Ironfan.step(fog.id, "tagging with #{tags.inspect}", :green)
|
|
34
|
+
fog.add_tags(tags)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.applicable(computer)
|
|
38
|
+
computer.server and computer.server.clouds.include?(:rds)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def self.aws_credentials
|
|
44
|
+
return {
|
|
45
|
+
:aws_access_key_id => Chef::Config[:knife][:aws_access_key_id],
|
|
46
|
+
:aws_secret_access_key => Chef::Config[:knife][:aws_secret_access_key],
|
|
47
|
+
:region => Chef::Config[:knife][:region]
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -78,6 +78,10 @@ module Ironfan
|
|
|
78
78
|
adaptee.PowerOffVM_Task.wait_for_completion
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
def perform_after_launch_tasks?
|
|
82
|
+
true
|
|
83
|
+
end
|
|
84
|
+
|
|
81
85
|
def self.ip_settings(settings, hostname)
|
|
82
86
|
# FIXME: A lot of this is required if using a static IP
|
|
83
87
|
# Heavily referenced Serengeti's FOG here
|
data/lib/ironfan/provider.rb
CHANGED
data/lib/ironfan/requirements.rb
CHANGED
|
@@ -20,6 +20,7 @@ require 'ironfan/dsl/volume'
|
|
|
20
20
|
require 'ironfan/dsl/cloud'
|
|
21
21
|
require 'ironfan/dsl/ec2'
|
|
22
22
|
require 'ironfan/dsl/vsphere'
|
|
23
|
+
require 'ironfan/dsl/rds'
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
# Providers for specific resources
|
|
@@ -47,6 +48,9 @@ require 'ironfan/provider/vsphere'
|
|
|
47
48
|
require 'ironfan/provider/vsphere/machine'
|
|
48
49
|
require 'ironfan/provider/vsphere/keypair'
|
|
49
50
|
|
|
51
|
+
require 'ironfan/provider/rds'
|
|
52
|
+
require 'ironfan/provider/rds/machine'
|
|
53
|
+
require 'ironfan/provider/rds/security_group'
|
|
50
54
|
|
|
51
55
|
# Broker classes to coordinate DSL expectations and provider resources
|
|
52
56
|
require 'ironfan/broker'
|
data/spec/spec_helper.rb
CHANGED
|
@@ -12,9 +12,11 @@ Pathname.register_paths(
|
|
|
12
12
|
fixtures: [:code, 'spec', 'fixtures'],
|
|
13
13
|
)
|
|
14
14
|
|
|
15
|
-
RSpec.configure do |
|
|
15
|
+
RSpec.configure do |cfg|
|
|
16
16
|
def ironfan_go!
|
|
17
|
-
Chef::Knife.new
|
|
17
|
+
k = Chef::Knife.new
|
|
18
|
+
k.config[:config_file] = Pathname.path_to(:fixtures, 'knife/knife.rb')
|
|
19
|
+
k.configure_chef
|
|
18
20
|
Chef::Config.instance_eval do
|
|
19
21
|
knife.merge!({
|
|
20
22
|
:aws_access_key_id => 'access_key',
|
|
@@ -26,7 +28,11 @@ RSpec.configure do |config|
|
|
|
26
28
|
require 'ironfan'
|
|
27
29
|
|
|
28
30
|
Ironfan.ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
|
|
29
|
-
Ironfan.chef_config =
|
|
31
|
+
Ironfan.chef_config = k.config
|
|
30
32
|
Ironfan.cluster_path
|
|
31
33
|
end
|
|
32
34
|
end
|
|
35
|
+
|
|
36
|
+
require 'chef_zero/server'
|
|
37
|
+
server = ChefZero::Server.new(port: 4000)
|
|
38
|
+
server.start_background
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ironfan
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.10.
|
|
4
|
+
version: 4.10.4
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-06-03 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: chef
|
|
@@ -251,6 +251,7 @@ files:
|
|
|
251
251
|
- ironfan.gemspec
|
|
252
252
|
- lib/chef/knife/bootstrap/centos6.2-ironfan.erb
|
|
253
253
|
- lib/chef/knife/bootstrap/chef-full-ironfan.erb
|
|
254
|
+
- lib/chef/knife/bootstrap/rhel6.3-ironfan.erb
|
|
254
255
|
- lib/chef/knife/bootstrap/ubuntu10.04-ironfan.erb
|
|
255
256
|
- lib/chef/knife/bootstrap/ubuntu12.04-ironfan.erb
|
|
256
257
|
- lib/chef/knife/cluster_bootstrap.rb
|
|
@@ -280,6 +281,7 @@ files:
|
|
|
280
281
|
- lib/ironfan/dsl/compute.rb
|
|
281
282
|
- lib/ironfan/dsl/ec2.rb
|
|
282
283
|
- lib/ironfan/dsl/facet.rb
|
|
284
|
+
- lib/ironfan/dsl/rds.rb
|
|
283
285
|
- lib/ironfan/dsl/role.rb
|
|
284
286
|
- lib/ironfan/dsl/server.rb
|
|
285
287
|
- lib/ironfan/dsl/virtualbox.rb
|
|
@@ -300,6 +302,9 @@ files:
|
|
|
300
302
|
- lib/ironfan/provider/ec2/machine.rb
|
|
301
303
|
- lib/ironfan/provider/ec2/placement_group.rb
|
|
302
304
|
- lib/ironfan/provider/ec2/security_group.rb
|
|
305
|
+
- lib/ironfan/provider/rds.rb
|
|
306
|
+
- lib/ironfan/provider/rds/machine.rb
|
|
307
|
+
- lib/ironfan/provider/rds/security_group.rb
|
|
303
308
|
- lib/ironfan/provider/virtualbox.rb
|
|
304
309
|
- lib/ironfan/provider/virtualbox/machine.rb
|
|
305
310
|
- lib/ironfan/provider/vsphere.rb
|
|
@@ -343,6 +348,7 @@ files:
|
|
|
343
348
|
- spec/fixtures/ec2/elb/snakeoil.key
|
|
344
349
|
- spec/fixtures/gunbai.rb
|
|
345
350
|
- spec/fixtures/gunbai_slice.json
|
|
351
|
+
- spec/fixtures/knife/knife.rb
|
|
346
352
|
- spec/integration/minimal-chef-repo/chefignore
|
|
347
353
|
- spec/integration/minimal-chef-repo/environments/_default.json
|
|
348
354
|
- spec/integration/minimal-chef-repo/knife/credentials/knife-org.rb
|
|
@@ -375,7 +381,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
375
381
|
version: '0'
|
|
376
382
|
segments:
|
|
377
383
|
- 0
|
|
378
|
-
hash: -
|
|
384
|
+
hash: -3042039387970317693
|
|
379
385
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
380
386
|
none: false
|
|
381
387
|
requirements:
|
|
@@ -403,6 +409,7 @@ test_files:
|
|
|
403
409
|
- spec/chef/cluster_bootstrap_spec.rb
|
|
404
410
|
- spec/chef/cluster_launch_spec.rb
|
|
405
411
|
- spec/fixtures/gunbai_slice.json
|
|
412
|
+
- spec/fixtures/knife/knife.rb
|
|
406
413
|
- spec/fixtures/ec2/elb/snakeoil.crt
|
|
407
414
|
- spec/fixtures/ec2/elb/snakeoil.key
|
|
408
415
|
- spec/fixtures/gunbai.rb
|