chef-vpc-toolkit 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/COPYING +26 -0
- data/README.rdoc +75 -0
- data/Rakefile +34 -0
- data/VERSION +1 -0
- data/bin/chef-vpc-toolkit +80 -0
- data/config/chef_installer.yml +20 -0
- data/config/databags.json.example +24 -0
- data/config/nodes.json +10 -0
- data/config/server_group.json +16 -0
- data/contrib/doc/ChefVPCToolkit.odt +0 -0
- data/contrib/doc/ChefVPCToolkit.pdf +0 -0
- data/contrib/etc/chef_vpc_toolkit.conf +10 -0
- data/contrib/rake/Rakefile +23 -0
- data/cookbook-repos/local/README +5 -0
- data/cookbook-repos/local/Rakefile +66 -0
- data/cookbook-repos/local/certificates/README +1 -0
- data/cookbook-repos/local/config/client.rb.example +21 -0
- data/cookbook-repos/local/config/knife.rb.example +10 -0
- data/cookbook-repos/local/config/rake.rb +60 -0
- data/cookbook-repos/local/config/server.rb.example +42 -0
- data/cookbook-repos/local/config/solo.rb.example +13 -0
- data/cookbook-repos/local/cookbooks/README +4 -0
- data/cookbook-repos/local/cookbooks/motd/README.rdoc +15 -0
- data/cookbook-repos/local/cookbooks/motd/attributes/motd.rb +1 -0
- data/cookbook-repos/local/cookbooks/motd/metadata.rb +6 -0
- data/cookbook-repos/local/cookbooks/motd/recipes/default.rb +13 -0
- data/cookbook-repos/local/cookbooks/motd/templates/default/motd.erb +1 -0
- data/cookbook-repos/local/roles/README +4 -0
- data/lib/chef-vpc-toolkit.rb +6 -0
- data/lib/chef-vpc-toolkit/chef-0.9.bash +232 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/centos.bash +47 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/fedora.bash +41 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/rhel.bash +38 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/ubuntu.bash +32 -0
- data/lib/chef-vpc-toolkit/chef_installer.rb +276 -0
- data/lib/chef-vpc-toolkit/cloud_files.bash +67 -0
- data/lib/chef-vpc-toolkit/cloud_servers_vpc.rb +285 -0
- data/lib/chef-vpc-toolkit/http_util.rb +117 -0
- data/lib/chef-vpc-toolkit/ssh_util.rb +22 -0
- data/lib/chef-vpc-toolkit/util.rb +56 -0
- data/lib/chef-vpc-toolkit/version.rb +8 -0
- data/rake/chef_vpc_toolkit.rake +284 -0
- data/test/cloud_servers_vpc_test.rb +174 -0
- data/test/test_helper.rb +25 -0
- metadata +153 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
4
|
+
|
5
|
+
[[ "$INSTALL_TYPE" == "CLIENT" ]] || { echo "Chef server installations are not yet supported on Fedora."; exit 1; }
|
6
|
+
|
7
|
+
yum install -q -y ruby ruby-devel gcc gcc-c++ automake autoconf rubygems make &> /dev/null || { echo "Failed to install ruby, ruby-devel, etc."; exit 1; }
|
8
|
+
gem update --system
|
9
|
+
gem update
|
10
|
+
gem install json -v 1.1.4 --no-rdoc --no-ri &> /dev/null || \
|
11
|
+
{ echo "Failed to install JSON gem on $HOSTNAME."; exit 1; }
|
12
|
+
gem install ohai -v 0.5.6 --no-rdoc --no-ri &> /dev/null || \
|
13
|
+
{ echo "Failed to install ohai gem on $HOSTNAME."; exit 1; }
|
14
|
+
gem install chef -v 0.9.8 --no-rdoc --no-ri &> /dev/null || \
|
15
|
+
{ echo "Failed to install chef gem on $HOSTNAME."; exit 1; }
|
16
|
+
|
17
|
+
for DIR in /etc/chef /var/log/chef /var/cache/chef /var/lib/chef /var/run/chef; do
|
18
|
+
mkdir -p $DIR
|
19
|
+
done
|
20
|
+
|
21
|
+
cat > /etc/chef/client.rb <<-"EOF_CAT"
|
22
|
+
log_level :info
|
23
|
+
log_location STDOUT
|
24
|
+
ssl_verify_mode :verify_none
|
25
|
+
chef_server_url "http://localhost:4000"
|
26
|
+
file_cache_path "/var/cache/chef"
|
27
|
+
file_backup_path "/var/lib/chef/backup"
|
28
|
+
pid_file "/var/run/chef/client.pid"
|
29
|
+
cache_options({ :path => "/var/cache/chef/checksums", :skip_expires => true})
|
30
|
+
signing_ca_user "chef"
|
31
|
+
Mixlib::Log::Formatter.show_time = true
|
32
|
+
validation_client_name "chef-validator"
|
33
|
+
validation_key "/etc/chef/validation.pem"
|
34
|
+
client_key "/etc/chef/client.pem"
|
35
|
+
EOF_CAT
|
36
|
+
|
37
|
+
cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/init.d/chef-client /etc/init.d/
|
38
|
+
cp /usr/lib/ruby/gems/1.8/gems/chef-0.9.8/distro/redhat/etc/logrotate.d/chef-client /etc/logrotate.d/
|
39
|
+
chmod 755 /etc/init.d/chef-client
|
40
|
+
|
41
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
4
|
+
|
5
|
+
# cached RPMs from ELFF
|
6
|
+
local CDN_BASE="http://c2521002.cdn.cloudfiles.rackspacecloud.com"
|
7
|
+
|
8
|
+
local TARBALL="chef-client-0.9.8-rhel5-x86_64.tar.gz"
|
9
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
10
|
+
TARBALL="chef-server-0.9.8-rhel5-x86_64.tar.gz"
|
11
|
+
fi
|
12
|
+
|
13
|
+
rpm -q rsync &> /dev/null || yum install -y -q rsync
|
14
|
+
rpm -q wget &> /dev/null || yum install -y -q wget
|
15
|
+
|
16
|
+
if ! rpm -q rubygem-chef &> /dev/null; then
|
17
|
+
|
18
|
+
local CHEF_RPM_DIR=$(mktemp -d)
|
19
|
+
|
20
|
+
wget "$CDN_BASE/$TARBALL" -O "$CHEF_RPM_DIR/chef.tar.gz" &> /dev/null \
|
21
|
+
|| { echo "Failed to download Chef RPM tarball."; exit 1; }
|
22
|
+
cd $CHEF_RPM_DIR
|
23
|
+
|
24
|
+
tar xzf chef.tar.gz || { echo "Failed to extract Chef tarball."; exit 1; }
|
25
|
+
rm chef.tar.gz
|
26
|
+
cd chef*
|
27
|
+
yum install -q -y --nogpgcheck */*.rpm
|
28
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
29
|
+
rpm -q rubygem-chef-server &> /dev/null || { echo "Failed to install chef."; exit 1; }
|
30
|
+
else
|
31
|
+
rpm -q rubygem-chef &> /dev/null || { echo "Failed to install chef."; exit 1; }
|
32
|
+
fi
|
33
|
+
cd /tmp
|
34
|
+
rm -Rf "$CHEF_RPM_DIR"
|
35
|
+
|
36
|
+
fi
|
37
|
+
|
38
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
function install_chef {
|
2
|
+
|
3
|
+
CODENAME=$(cat /etc/*release | grep CODENAME | sed -e "s|^.*=\([^$]*\)$|\1|")
|
4
|
+
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
5
|
+
|
6
|
+
[ -f /etc/apt/sources.list.d/opscode.list ] || echo "deb http://apt.opscode.com $CODENAME main" > /etc/apt/sources.list.d/opscode.list
|
7
|
+
wget -q -O- http://apt.opscode.com/packages@opscode.com.gpg.key | apt-key add - &> /dev/null || { echo "Failed to configure Apt repo."; exit 1; }
|
8
|
+
|
9
|
+
dpkg -L rsync &> /dev/null || apt-get install -y rsync &> /dev/null
|
10
|
+
|
11
|
+
if ! dpkg -L chef &> /dev/null; then
|
12
|
+
|
13
|
+
if [[ "$INSTALL_TYPE" == "SERVER" ]]; then
|
14
|
+
|
15
|
+
[[ "$CODENAME" == "lucid" ]] || { echo "Ubuntu 10.0.4 lucid is required for Chef server installations."; exit 1; }
|
16
|
+
apt-get update &> /dev/null || { echo "Failed to apt-get update."; exit 1; }
|
17
|
+
echo "chef-solr chef-solr/amqp_password password YA1B2C301234Z" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef-solr."; exit 1; }
|
18
|
+
echo "chef chef/chef_server_url string http://localhost:4000" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef."; exit 1; }
|
19
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y chef-server chef &> /dev/null || { echo "Failed to install the Chef Server via apt-get on $HOSTNAME."; exit 1; }
|
20
|
+
else
|
21
|
+
apt-get update &> /dev/null || { echo "Failed to apt-get update."; exit 1; }
|
22
|
+
echo "chef chef/chef_server_url string http://localhost:4000" | debconf-set-selections &> /dev/null || { echo "Failed to set debconf selections for chef."; exit 1; }
|
23
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y chef &> /dev/null || { echo "Failed to install Chef via apt-get on $HOSTNAME."; exit 1; }
|
24
|
+
fi
|
25
|
+
|
26
|
+
/etc/init.d/chef-client stop &> /dev/null
|
27
|
+
sleep 2
|
28
|
+
rm /var/log/chef/client.log
|
29
|
+
|
30
|
+
fi
|
31
|
+
|
32
|
+
}
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module ChefVPCToolkit
|
6
|
+
|
7
|
+
module ChefInstaller
|
8
|
+
CHEF_INSTALL_FUNCTIONS=File.dirname(__FILE__) + "/chef-0.9.bash"
|
9
|
+
|
10
|
+
def self.load_configs
|
11
|
+
|
12
|
+
config_file=CHEF_VPC_PROJECT + File::SEPARATOR + "config" + File::SEPARATOR + "chef_installer.yml"
|
13
|
+
|
14
|
+
if File.exists?(config_file) then
|
15
|
+
return YAML.load_file(config_file)
|
16
|
+
else
|
17
|
+
raise "The config/chef_installer.conf file is missing."
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# validate the chef.json config file by parsing it
|
23
|
+
def self.validate_json(options)
|
24
|
+
|
25
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
26
|
+
begin
|
27
|
+
JSON.parse(IO.read(options["chef_json_file"]))
|
28
|
+
rescue Exception => e
|
29
|
+
puts "Failed to parse Chef JSON config file:"
|
30
|
+
puts ""
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
34
|
+
if not options["databags_json_file"].nil? and not options["databags_json_file"].empty?
|
35
|
+
begin
|
36
|
+
JSON.parse(IO.read(options["databags_json_file"]))
|
37
|
+
rescue Exception => e
|
38
|
+
puts "Failed to parse Databag JSON config file:"
|
39
|
+
puts ""
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.install_chef_server(options, machine_os_types)
|
47
|
+
|
48
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
49
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
50
|
+
Util.raise_if_nil_or_empty(options, "chef_server_name")
|
51
|
+
|
52
|
+
# should we install a Chef client on the server?
|
53
|
+
json=JSON.parse(IO.read(options["chef_json_file"]))
|
54
|
+
configure_client_script=""
|
55
|
+
start_client_script=""
|
56
|
+
if json.has_key?(options["chef_server_name"]) then
|
57
|
+
configure_client_script="configure_chef_client '#{options['chef_server_name']}' ''"
|
58
|
+
start_client_script="start_chef_client"
|
59
|
+
end
|
60
|
+
knife_add_nodes_script=""
|
61
|
+
json.each_pair do |node_name, node_json|
|
62
|
+
run_list=node_json['run_list'].inspect
|
63
|
+
node_json.delete("run_list")
|
64
|
+
attributes=node_json.to_json.to_s
|
65
|
+
knife_add_nodes_script+="knife_add_node '#{node_name}' '#{run_list}' '#{attributes}'\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
cookbook_urls=""
|
69
|
+
if options["chef_cookbook_repos"] then
|
70
|
+
cookbook_urls=options["chef_cookbook_repos"].inject { |sum, c| sum + " " + c }
|
71
|
+
end
|
72
|
+
os_type=machine_os_types[options['chef_server_name']]
|
73
|
+
|
74
|
+
data=%x{
|
75
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
76
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
77
|
+
echo "Installing Chef server on: $HOSTNAME"
|
78
|
+
EOF_BASH
|
79
|
+
EOF_GATEWAY
|
80
|
+
}
|
81
|
+
puts data
|
82
|
+
|
83
|
+
data=%x{
|
84
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
85
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
86
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
87
|
+
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
88
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
89
|
+
install_chef "SERVER"
|
90
|
+
|
91
|
+
mkdir -p /root/cookbook-repos
|
92
|
+
|
93
|
+
configure_chef_server
|
94
|
+
start_chef_server
|
95
|
+
|
96
|
+
#{configure_client_script}
|
97
|
+
|
98
|
+
configure_knife "#{options["knife_editor"]}"
|
99
|
+
|
100
|
+
knife_upload_cookbooks_and_roles
|
101
|
+
|
102
|
+
#{knife_add_nodes_script}
|
103
|
+
|
104
|
+
#{start_client_script}
|
105
|
+
|
106
|
+
EOF_BASH
|
107
|
+
EOF_GATEWAY
|
108
|
+
}
|
109
|
+
puts data
|
110
|
+
|
111
|
+
return client_validation_key(options)
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.client_validation_key(options)
|
116
|
+
|
117
|
+
client_validation_key=%x{
|
118
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
119
|
+
ssh #{options['chef_server_name']} bash <<-"EOF_BASH"
|
120
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
121
|
+
print_client_validation_key
|
122
|
+
EOF_BASH
|
123
|
+
EOF_GATEWAY
|
124
|
+
}
|
125
|
+
|
126
|
+
raise "Client validation key is blank." if client_validation_key.nil? or client_validation_key.empty?
|
127
|
+
|
128
|
+
return client_validation_key
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.install_chef_clients(options, client_validation_key, os_types)
|
133
|
+
|
134
|
+
# configure Chef clients on each node
|
135
|
+
json=JSON.parse(IO.read(options['chef_json_file']))
|
136
|
+
json.each_pair do |hostname, json_hash|
|
137
|
+
if hostname != options['chef_server_name']
|
138
|
+
install_chef_client(options, hostname, client_validation_key, os_types[hostname])
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.install_chef_client(options, client_name, client_validation_key, os_type)
|
145
|
+
|
146
|
+
puts "Installing Chef client on: #{client_name}"
|
147
|
+
|
148
|
+
data=%x{
|
149
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
150
|
+
ssh #{client_name} bash <<-"EOF_BASH"
|
151
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
152
|
+
#{IO.read(File.dirname(__FILE__) + "/chef_bootstrap/#{os_type}.bash")}
|
153
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
154
|
+
install_chef "CLIENT"
|
155
|
+
configure_chef_client '#{options['chef_server_name']}' '#{client_validation_key}'
|
156
|
+
start_chef_client
|
157
|
+
EOF_BASH
|
158
|
+
EOF_GATEWAY
|
159
|
+
}
|
160
|
+
puts data
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.create_databags(options)
|
165
|
+
|
166
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
167
|
+
|
168
|
+
if options["databags_json_file"].nil? or options["databags_json_file"].empty?
|
169
|
+
puts "No databag config file specified."
|
170
|
+
return
|
171
|
+
end
|
172
|
+
printf "Creating databags..."
|
173
|
+
STDOUT.flush
|
174
|
+
|
175
|
+
if not File.exists?(options["databags_json_file"]) then
|
176
|
+
raise "Databags json file is missing: #{options["databags_json_file"]}."
|
177
|
+
end
|
178
|
+
|
179
|
+
json=JSON.parse(IO.read(options["databags_json_file"]))
|
180
|
+
|
181
|
+
databag_cmds=""
|
182
|
+
|
183
|
+
json.each_pair do |bag_name, items_json|
|
184
|
+
databag_cmds+="knife data bag delete '#{bag_name}' -y &> /dev/null \n"
|
185
|
+
databag_cmds+="knife data bag create '#{bag_name}' -y \n"
|
186
|
+
|
187
|
+
items_json.each do |item_json|
|
188
|
+
|
189
|
+
item_id=item_json["id"]
|
190
|
+
raise "Databags json missing item ID." if item_id.nil? or item_id.empty?
|
191
|
+
databag_cmds+="knife_create_databag '#{bag_name}' '#{item_id}' '#{item_json.to_json.to_s}'\n"
|
192
|
+
end
|
193
|
+
|
194
|
+
data=%x{
|
195
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
196
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
197
|
+
#{databag_cmds}
|
198
|
+
EOF_GATEWAY
|
199
|
+
}
|
200
|
+
puts "OK."
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.knife_readd_node(options, client_name)
|
207
|
+
|
208
|
+
Util.raise_if_nil_or_empty(options, "ssh_gateway_ip")
|
209
|
+
Util.raise_if_nil_or_empty(options, "chef_json_file")
|
210
|
+
|
211
|
+
json=JSON.parse(IO.read(options["chef_json_file"]))
|
212
|
+
node_json=json[client_name]
|
213
|
+
run_list=node_json['run_list'].inspect
|
214
|
+
node_json.delete("run_list")
|
215
|
+
attributes=node_json.to_json.to_s
|
216
|
+
data=%x{
|
217
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_GATEWAY"
|
218
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
219
|
+
knife_delete_node '#{client_name}'
|
220
|
+
knife_add_node '#{client_name}' '#{run_list}' '#{attributes}'
|
221
|
+
EOF_GATEWAY
|
222
|
+
}
|
223
|
+
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.tail_log(gateway_ip, server_name, log_file="/var/log/chef/client.log", num_lines="100")
|
227
|
+
%x{ssh root@#{gateway_ip} ssh #{server_name} tail -n #{num_lines} #{log_file}}
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-repos/", remote_directory="/root/cookbook-repos")
|
231
|
+
|
232
|
+
if File.exists?(local_dir) then
|
233
|
+
$stdout.printf "Syncing local Chef cookbook repositories..."
|
234
|
+
configs=Util.load_configs
|
235
|
+
%x{ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
236
|
+
mkdir -p #{remote_directory}
|
237
|
+
if [ -f /usr/bin/yum ]; then
|
238
|
+
rpm -q rsync &> /dev/null || yum install -y -q rsync
|
239
|
+
else
|
240
|
+
dpkg -L rsync > /dev/null 2>&1 || apt-get install -y --quiet rsync > /dev/null 2>&1
|
241
|
+
fi
|
242
|
+
EOF_SSH
|
243
|
+
}
|
244
|
+
system("rsync -azL '#{local_dir}' root@#{options['ssh_gateway_ip']}:#{remote_directory}")
|
245
|
+
puts "OK"
|
246
|
+
end
|
247
|
+
|
248
|
+
cookbook_urls=""
|
249
|
+
if options["chef_cookbook_repos"] then
|
250
|
+
cookbook_urls=options["chef_cookbook_repos"].inject { |sum, c| sum + " " + c }
|
251
|
+
end
|
252
|
+
|
253
|
+
data=%x{
|
254
|
+
ssh root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
255
|
+
#{IO.read(File.dirname(__FILE__) + "/cloud_files.bash")}
|
256
|
+
#{IO.read(CHEF_INSTALL_FUNCTIONS)}
|
257
|
+
|
258
|
+
if [ -n "#{cookbook_urls}" ]; then
|
259
|
+
download_cookbook_repos "#{cookbook_urls}"
|
260
|
+
fi
|
261
|
+
|
262
|
+
if [ -f /root/.chef/knife.rb ]; then
|
263
|
+
echo -n "Uploading cookbooks and roles..."
|
264
|
+
knife_upload_cookbooks_and_roles
|
265
|
+
echo "OK"
|
266
|
+
fi
|
267
|
+
|
268
|
+
EOF_SSH
|
269
|
+
}
|
270
|
+
puts data
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Load the username and password into variables that are used by this
|
2
|
+
# bash API.
|
3
|
+
function install_curl {
|
4
|
+
|
5
|
+
if [ -f /usr/bin/yum ]; then
|
6
|
+
rpm -q curl &> /dev/null || yum install -y -q curl
|
7
|
+
elif [ -f /usr/bin/dpkg ]; then
|
8
|
+
dpkg -L curl > /dev/null 2>&1 || apt-get install -y --quiet curl > /dev/null 2>&1
|
9
|
+
else
|
10
|
+
echo "Failed to install curl. Unsupported platform."
|
11
|
+
exit 1
|
12
|
+
fi
|
13
|
+
|
14
|
+
}
|
15
|
+
|
16
|
+
function load_cloud_configs {
|
17
|
+
|
18
|
+
if [ -z "$RACKSPACE_CLOUD_API_USERNAME" ] || [ -z "$RACKSPACE_CLOUD_API_KEY" ]; then
|
19
|
+
|
20
|
+
if [ ! -f ~/.rackspace_cloud ]; then
|
21
|
+
echo "Missing .rackspace_cloud config file."
|
22
|
+
exit 1
|
23
|
+
fi
|
24
|
+
|
25
|
+
export RACKSPACE_CLOUD_API_USERNAME=$(cat ~/.rackspace_cloud | grep "userid" | sed -e "s|.*: \([^ \n\r]*\).*|\1|")
|
26
|
+
export RACKSPACE_CLOUD_API_KEY=$(cat ~/.rackspace_cloud | grep "api_key" | sed -e "s|.*: \([^ \n\r]*\).*|\1|")
|
27
|
+
|
28
|
+
if [ -z "$RACKSPACE_CLOUD_API_USERNAME" ] || [ -z "$RACKSPACE_CLOUD_API_KEY" ]; then
|
29
|
+
echo "Please define a 'userid' and 'api_key' in ~/.rackspace_cloud"
|
30
|
+
exit 1
|
31
|
+
fi
|
32
|
+
|
33
|
+
fi
|
34
|
+
|
35
|
+
}
|
36
|
+
|
37
|
+
# Download a private file from Rackspace Cloud Files using the secure
|
38
|
+
# X-Storage-Url.
|
39
|
+
function download_cloud_file {
|
40
|
+
|
41
|
+
if (( $# != 2 )); then
|
42
|
+
echo "Failed to download cloud file."
|
43
|
+
echo "usage: download_cloud_file <container_url> <output_file>"
|
44
|
+
exit 1
|
45
|
+
fi
|
46
|
+
|
47
|
+
load_cloud_configs
|
48
|
+
install_curl
|
49
|
+
|
50
|
+
local CONTAINER_URL=$1
|
51
|
+
local OUTPUT_FILE=$2
|
52
|
+
|
53
|
+
local AUTH_RESPONSE=$(curl -D - \
|
54
|
+
-H "X-Auth-Key: $RACKSPACE_CLOUD_API_KEY" \
|
55
|
+
-H "X-Auth-User: $RACKSPACE_CLOUD_API_USERNAME" \
|
56
|
+
"https://auth.api.rackspacecloud.com/v1.0" 2> /dev/null)
|
57
|
+
|
58
|
+
[[ $? == 0 ]] || { echo "Failed to authenticate."; exit 1; }
|
59
|
+
|
60
|
+
local AUTH_TOKEN=$(echo $AUTH_RESPONSE | \
|
61
|
+
sed -e "s|.* X-Auth-Token: \([^ \n\r]*\).*|\1|g")
|
62
|
+
local STORAGE_URL=$(echo $AUTH_RESPONSE | \
|
63
|
+
sed -e "s|.* X-Storage-Url: \([^ \n\r]*\).*|\1|g")
|
64
|
+
|
65
|
+
curl -s -X GET -H "X-Auth-Token: $AUTH_TOKEN" "$STORAGE_URL/$CONTAINER_URL" -o "$OUTPUT_FILE"
|
66
|
+
|
67
|
+
}
|