chef-vpc-toolkit 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/COPYING +1 -1
- data/README.rdoc +29 -7
- data/VERSION +1 -1
- data/config/server_group.json +2 -2
- data/lib/chef-vpc-toolkit.rb +7 -2
- data/lib/chef-vpc-toolkit/chef-0.9.bash +1 -0
- data/lib/chef-vpc-toolkit/chef_bootstrap/fedora.bash +3 -3
- data/lib/chef-vpc-toolkit/chef_bootstrap/ubuntu.bash +1 -0
- data/lib/chef-vpc-toolkit/chef_installer.rb +8 -1
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/client.rb +186 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/connection.rb +146 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/server.rb +113 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/server_group.rb +387 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/ssh_public_key.rb +25 -0
- data/lib/chef-vpc-toolkit/cloud-servers-vpc/vpn_network_interface.rb +29 -0
- data/lib/chef-vpc-toolkit/util.rb +20 -16
- data/lib/chef-vpc-toolkit/vpn_network_manager.rb +16 -16
- data/lib/chef-vpc-toolkit/xml_util.rb +15 -0
- data/rake/chef_vpc_toolkit.rake +194 -155
- data/test/client_test.rb +108 -0
- data/test/server_group_test.rb +259 -0
- data/test/server_test.rb +66 -0
- data/test/test_helper.rb +21 -0
- data/test/util_test.rb +7 -0
- data/test/vpn_network_manager_test.rb +7 -5
- metadata +17 -8
- data/lib/chef-vpc-toolkit/cloud_servers_vpc.rb +0 -393
- data/lib/chef-vpc-toolkit/http_util.rb +0 -118
- data/test/cloud_servers_vpc_test.rb +0 -129
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
* Thu Feb 6 2011 Dan Prince <dan.prince@rackspace.com> - 2.2.0
|
2
|
+
- Support command execution with 'rake ssh'.
|
3
|
+
- The 'chef:tail_logs' task now supports the SERVER_NAME variable.
|
4
|
+
- Support for Ubuntu 10.10 maverick.
|
5
|
+
- Add support for connecting to servers which require SSL client auth.
|
6
|
+
- Implement 'group:add_server' task.
|
7
|
+
- Implement 'group:delete_server' task.
|
8
|
+
- Implement 'group:list REMOTE=true' task.
|
9
|
+
- Implement 'group:join' task.
|
10
|
+
- Implement 'group:join' task.
|
11
|
+
- Update the 'chef:install' task to support the SERVER_NAME variable.
|
12
|
+
- The 'chef:sync_repos' task is now 'chef:push_repos'.
|
13
|
+
- Implement a 'chef:pull_repos' task.
|
14
|
+
|
1
15
|
* Tue Jan 11 2011 Dan Prince <dan.prince@rackspace.com> - 2.1.0
|
2
16
|
- Implement 'rake vpn' tasks.
|
3
17
|
- Set permission to 0600 on tmp/server_group files.
|
data/COPYING
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Unless otherwise noted, all files are released under the MIT license,
|
2
2
|
exceptions contain licensing information in them.
|
3
3
|
|
4
|
-
Copyright (C) 2010 Rackspace US, Inc.
|
4
|
+
Copyright (C) 2010-2011 Rackspace US, Inc.
|
5
5
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.rdoc
CHANGED
@@ -39,32 +39,54 @@ To install the gem:
|
|
39
39
|
|
40
40
|
Example commands:
|
41
41
|
|
42
|
-
- Create a new
|
42
|
+
- Create a new server group, upload cookbooks, install chef
|
43
43
|
on all the nodes, sync share data and cookbooks.
|
44
44
|
|
45
45
|
$ rake create
|
46
46
|
|
47
|
-
- List your currently running
|
47
|
+
- List your currently running server groups.
|
48
48
|
|
49
49
|
$ rake group:list
|
50
50
|
|
51
|
-
- SSH into the current (most recently created)
|
51
|
+
- SSH into the current (most recently created) server group
|
52
52
|
|
53
53
|
$ rake ssh
|
54
54
|
|
55
|
-
- SSH into a
|
55
|
+
- SSH into a server group with an ID of 3
|
56
56
|
|
57
57
|
$ rake ssh GROUP_ID=3
|
58
58
|
|
59
|
-
- Delete the
|
59
|
+
- Delete the server group with an ID of 3
|
60
60
|
|
61
61
|
$ rake group:delete GROUP_ID=3
|
62
62
|
|
63
|
-
- Rebuild/Re-Chef the 'db1' server in the most recently created
|
64
|
-
server group
|
63
|
+
- Rebuild/Re-Chef the 'db1' server in the most recently created server group
|
65
64
|
|
66
65
|
$ rake rechef SERVER_NAME=db1
|
67
66
|
|
67
|
+
- Connect to a group as a VPN client. Currently supports and requires
|
68
|
+
Network Manager Openvpn, nmcli, and nm-applet (Linux only).
|
69
|
+
|
70
|
+
$ rake vpn
|
71
|
+
|
72
|
+
- Disconnect from group as a VPN client
|
73
|
+
|
74
|
+
$ rake vpn:disconnect
|
75
|
+
|
76
|
+
== Bash Automation Script
|
77
|
+
The following is an example bash script to spin up a group and run commands via SSH. Useful for CI automation in Hudson, etc.
|
78
|
+
|
79
|
+
#!/bin/bash
|
80
|
+
|
81
|
+
chef-vpc-toolkit -v
|
82
|
+
trap "rake group:delete" INT TERM EXIT # cleanup the group on exit
|
83
|
+
|
84
|
+
rake create
|
85
|
+
VPN_GW=$(rake group:show | grep "VPN gateway IP" | sed -e "s|VPN gateway IP: ||")
|
86
|
+
ssh root@$VPN_GW bash <<-EOF_BASH
|
87
|
+
# do stuff here
|
88
|
+
EOF_BASH
|
89
|
+
|
68
90
|
== Author
|
69
91
|
|
70
92
|
Dan Prince <dan.prince@rackspace.com>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0
|
data/config/server_group.json
CHANGED
data/lib/chef-vpc-toolkit.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'chef-vpc-toolkit/util'
|
2
2
|
require 'chef-vpc-toolkit/chef_installer'
|
3
|
-
require 'chef-vpc-toolkit/cloud_servers_vpc'
|
4
|
-
require 'chef-vpc-toolkit/http_util'
|
5
3
|
require 'chef-vpc-toolkit/ssh_util'
|
6
4
|
require 'chef-vpc-toolkit/version'
|
5
|
+
require 'chef-vpc-toolkit/xml_util'
|
7
6
|
require 'chef-vpc-toolkit/vpn_network_manager'
|
7
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/connection'
|
8
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/client'
|
9
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/server'
|
10
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/server_group'
|
11
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/ssh_public_key'
|
12
|
+
require 'chef-vpc-toolkit/cloud-servers-vpc/vpn_network_interface'
|
@@ -30,6 +30,7 @@ fi
|
|
30
30
|
|
31
31
|
sed -e "s|localhost|$SERVER_NAME|g" -i /etc/chef/client.rb
|
32
32
|
sed -e "s|^chef_server_url.*|chef_server_url \"http://$SERVER_NAME:4000\"|g" -i /etc/chef/client.rb
|
33
|
+
sed -e "s|^log_location.*|log_location \"\/var/log/chef/client.log\"|g" -i /etc/chef/client.rb
|
33
34
|
|
34
35
|
local CHEF_CLIENT_CONF=/etc/default/chef-client
|
35
36
|
[ -d /etc/sysconfig/ ] && CHEF_CLIENT_CONF=/etc/sysconfig/chef-client
|
@@ -5,8 +5,8 @@ local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
|
5
5
|
[[ "$INSTALL_TYPE" == "CLIENT" ]] || { echo "Chef server installations are not yet supported on Fedora."; exit 1; }
|
6
6
|
|
7
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
|
8
|
+
#gem update --system
|
9
|
+
#gem update
|
10
10
|
gem install json -v 1.1.4 --no-rdoc --no-ri &> /dev/null || \
|
11
11
|
{ echo "Failed to install JSON gem on $HOSTNAME."; exit 1; }
|
12
12
|
gem install ohai -v 0.5.6 --no-rdoc --no-ri &> /dev/null || \
|
@@ -34,7 +34,7 @@ validation_key "/etc/chef/validation.pem"
|
|
34
34
|
client_key "/etc/chef/client.pem"
|
35
35
|
EOF_CAT
|
36
36
|
|
37
|
-
CHEF_GEM_DIR=$(gem contents chef | sed -e "s|\(.*chef-0.9.8\).*|\1|" | head -n 1)
|
37
|
+
CHEF_GEM_DIR=$(gem contents chef 2>/dev/null | sed -e "s|\(.*chef-0.9.8\).*|\1|" | head -n 1)
|
38
38
|
cp $CHEF_GEM_DIR/distro/redhat/etc/init.d/chef-client /etc/init.d/
|
39
39
|
cp $CHEF_GEM_DIR/distro/redhat/etc/logrotate.d/chef-client /etc/logrotate.d/
|
40
40
|
chmod 755 /etc/init.d/chef-client
|
@@ -1,6 +1,7 @@
|
|
1
1
|
function install_chef {
|
2
2
|
|
3
3
|
CODENAME=$(cat /etc/*release | grep CODENAME | sed -e "s|^.*=\([^$]*\)$|\1|")
|
4
|
+
[[ "$CODENAME" == "maverick" ]] && CODENAME="lucid"
|
4
5
|
local INSTALL_TYPE=${1:-"CLIENT"} # CLIENT/SERVER
|
5
6
|
|
6
7
|
[ -f /etc/apt/sources.list.d/opscode.list ] || echo "deb http://apt.opscode.com $CODENAME main" > /etc/apt/sources.list.d/opscode.list
|
@@ -228,10 +228,17 @@ def self.tail_log(gateway_ip, server_name, log_file="/var/log/chef/client.log",
|
|
228
228
|
%x{ssh -o "StrictHostKeyChecking no" root@#{gateway_ip} ssh #{server_name} tail -n #{num_lines} #{log_file}}
|
229
229
|
end
|
230
230
|
|
231
|
+
|
232
|
+
def self.pull_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-repos/", remote_directory="/root/cookbook-repos")
|
233
|
+
$stdout.printf "Pulling remote Chef cookbook repositories..."
|
234
|
+
system("rsync -azL root@#{options['ssh_gateway_ip']}:#{remote_directory}/* '#{local_dir}'")
|
235
|
+
puts "OK"
|
236
|
+
end
|
237
|
+
|
231
238
|
def self.rsync_cookbook_repos(options, local_dir="#{CHEF_VPC_PROJECT}/cookbook-repos/", remote_directory="/root/cookbook-repos")
|
232
239
|
|
233
240
|
if File.exists?(local_dir) then
|
234
|
-
$stdout.printf "
|
241
|
+
$stdout.printf "Pushing local Chef cookbook repositories..."
|
235
242
|
configs=Util.load_configs
|
236
243
|
%x{ssh -o "StrictHostKeyChecking no" root@#{options['ssh_gateway_ip']} bash <<-"EOF_SSH"
|
237
244
|
mkdir -p #{remote_directory}
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module ChefVPCToolkit
|
2
|
+
|
3
|
+
module CloudServersVPC
|
4
|
+
|
5
|
+
class Client
|
6
|
+
|
7
|
+
@@data_dir=File.join(CHEF_VPC_PROJECT, "tmp", "clients")
|
8
|
+
|
9
|
+
def self.data_dir
|
10
|
+
@@data_dir
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.data_dir=(dir)
|
14
|
+
@@data_dir=dir
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :id
|
18
|
+
attr_accessor :name
|
19
|
+
attr_accessor :description
|
20
|
+
attr_accessor :status
|
21
|
+
attr_accessor :server_group_id
|
22
|
+
|
23
|
+
def initialize(options={})
|
24
|
+
@id=options[:id].to_i
|
25
|
+
@name=options[:name]
|
26
|
+
@description=options[:description]
|
27
|
+
@status=options[:status] or @status = "Pending"
|
28
|
+
@server_group_id=options[:server_group_id]
|
29
|
+
|
30
|
+
@vpn_network_interfaces=[]
|
31
|
+
end
|
32
|
+
|
33
|
+
def vpn_network_interfaces
|
34
|
+
@vpn_network_interfaces
|
35
|
+
end
|
36
|
+
|
37
|
+
def cache_to_disk
|
38
|
+
FileUtils.mkdir_p(@@data_dir)
|
39
|
+
File.open(File.join(@@data_dir, "#{@server_group_id}.xml"), 'w') do |f|
|
40
|
+
f.chmod(0600)
|
41
|
+
f.write(self.to_xml)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def delete
|
46
|
+
client_xml_file=File.join(@@data_dir, "#{@server_group_id}.xml")
|
47
|
+
if File.exists?(client_xml_file) then
|
48
|
+
File.delete(client_xml_file)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.from_xml(xml)
|
53
|
+
|
54
|
+
client=nil
|
55
|
+
dom = REXML::Document.new(xml)
|
56
|
+
REXML::XPath.each(dom, "/client") do |client|
|
57
|
+
|
58
|
+
client=Client.new(
|
59
|
+
:id => XMLUtil.element_text(client,"id").to_i,
|
60
|
+
:name => XMLUtil.element_text(client, "name"),
|
61
|
+
:description => XMLUtil.element_text(client,"description"),
|
62
|
+
:status => XMLUtil.element_text(client,"status"),
|
63
|
+
:server_group_id => XMLUtil.element_text(client, "server-group-id").to_i
|
64
|
+
)
|
65
|
+
REXML::XPath.each(dom, "//vpn-network-interface") do |vni|
|
66
|
+
vni = VpnNetworkInterface.new(
|
67
|
+
:id => XMLUtil.element_text(vni, "id"),
|
68
|
+
:vpn_ip_addr => XMLUtil.element_text(vni, "vpn-ip-addr"),
|
69
|
+
:ptp_ip_addr => XMLUtil.element_text(vni, "ptp-ip-addr"),
|
70
|
+
:client_key => XMLUtil.element_text(vni, "client-key"),
|
71
|
+
:client_cert => XMLUtil.element_text(vni, "client-cert"),
|
72
|
+
:ca_cert => XMLUtil.element_text(vni, "ca-cert")
|
73
|
+
)
|
74
|
+
client.vpn_network_interfaces << vni
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
client
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_xml
|
83
|
+
|
84
|
+
xml = Builder::XmlMarkup.new
|
85
|
+
xml.tag! "client" do |sg|
|
86
|
+
sg.id(@id)
|
87
|
+
sg.name(@name)
|
88
|
+
sg.description(@description)
|
89
|
+
sg.status(@status)
|
90
|
+
sg.tag! "server-group-id", @server_group_id
|
91
|
+
sg.tag! "vpn-network-interfaces", {"type" => "array"} do |interfaces|
|
92
|
+
@vpn_network_interfaces.each do |vni|
|
93
|
+
interfaces.tag! "vpn-network-interface" do |xml_vni|
|
94
|
+
xml_vni.id(vni.id)
|
95
|
+
xml_vni.tag! "vpn-ip-addr", vni.vpn_ip_addr
|
96
|
+
xml_vni.tag! "ptp-ip-addr", vni.ptp_ip_addr
|
97
|
+
xml_vni.tag! "client-key", vni.client_key
|
98
|
+
xml_vni.tag! "client-cert", vni.client_cert
|
99
|
+
xml_vni.tag! "ca-cert", vni.ca_cert
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
xml.target!
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# Poll the server group until it is online.
|
111
|
+
# :timeout - max number of seconds to wait before raising an exception.
|
112
|
+
# Defaults to 1500
|
113
|
+
def poll_until_online(options={})
|
114
|
+
|
115
|
+
timeout=options[:timeout] or timeout = ENV['VPN_CLIENT_TIMEOUT']
|
116
|
+
if timeout.nil? or timeout.empty? then
|
117
|
+
timeout=300 # defaults to 5 minutes
|
118
|
+
end
|
119
|
+
|
120
|
+
online = false
|
121
|
+
count=0
|
122
|
+
until online or (count*5) >= timeout.to_i do
|
123
|
+
count+=1
|
124
|
+
begin
|
125
|
+
client=Client.fetch(:id => @id, :source => "remote")
|
126
|
+
|
127
|
+
if client.status == "Online" then
|
128
|
+
online = true
|
129
|
+
else
|
130
|
+
yield client if block_given?
|
131
|
+
sleep 5
|
132
|
+
end
|
133
|
+
rescue EOFError
|
134
|
+
end
|
135
|
+
end
|
136
|
+
if (count*20) >= timeout.to_i then
|
137
|
+
raise "Timeout waiting for client to come online."
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.create(server_group, client_name)
|
143
|
+
|
144
|
+
xml = Builder::XmlMarkup.new
|
145
|
+
xml.client do |client|
|
146
|
+
client.name(client_name)
|
147
|
+
client.description("Toolkit Client: #{client_name}")
|
148
|
+
client.tag! "server-group-id", server_group.id
|
149
|
+
end
|
150
|
+
|
151
|
+
xml=Connection.post("/clients.xml", xml.target!)
|
152
|
+
client=Client.from_xml(xml)
|
153
|
+
client.cache_to_disk
|
154
|
+
client
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
# Fetch a server group. The following options are available:
|
159
|
+
#
|
160
|
+
# :id - The ID of the group containing the client to fetch.
|
161
|
+
# :source - valid options are 'remote' and 'cache'
|
162
|
+
#
|
163
|
+
def self.fetch(options = {})
|
164
|
+
|
165
|
+
source = options[:source] or source = "remote"
|
166
|
+
|
167
|
+
if source == "remote" then
|
168
|
+
id=options[:id] or raise "Please specify a Client ID."
|
169
|
+
xml=Connection.get("/clients/#{id}.xml")
|
170
|
+
Client.from_xml(xml)
|
171
|
+
elsif source == "cache" then
|
172
|
+
id=options[:id] or id = ENV['GROUP_ID']
|
173
|
+
client_xml_file=File.join(@@data_dir, "#{id}.xml")
|
174
|
+
raise "No client files exist." if not File.exists?(client_xml_file)
|
175
|
+
Client.from_xml(IO.read(client_xml_file))
|
176
|
+
else
|
177
|
+
raise "Invalid fetch :source specified."
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'openssl'
|
6
|
+
require 'openssl/x509'
|
7
|
+
|
8
|
+
module ChefVPCToolkit
|
9
|
+
|
10
|
+
module CloudServersVPC
|
11
|
+
|
12
|
+
class Connection
|
13
|
+
|
14
|
+
MULTI_PART_BOUNDARY="jtZ!pZ1973um"
|
15
|
+
|
16
|
+
@@http=nil
|
17
|
+
@@auth_user=nil
|
18
|
+
@@auth_password=nil
|
19
|
+
|
20
|
+
def self.init_connection
|
21
|
+
|
22
|
+
configs=Util.load_configs
|
23
|
+
|
24
|
+
base_url = configs["cloud_servers_vpc_url"]
|
25
|
+
@@auth_user = configs["cloud_servers_vpc_username"]
|
26
|
+
@@auth_password = configs["cloud_servers_vpc_password"]
|
27
|
+
|
28
|
+
ssl_key = configs["ssl_key"]
|
29
|
+
ssl_cert = configs["ssl_cert"]
|
30
|
+
ssl_ca_cert = configs["ssl_ca_cert"]
|
31
|
+
|
32
|
+
url=URI.parse(base_url)
|
33
|
+
@@http = Net::HTTP.new(url.host,url.port)
|
34
|
+
|
35
|
+
if base_url =~ /^https/
|
36
|
+
@@http.use_ssl = true
|
37
|
+
if ssl_ca_cert then
|
38
|
+
@@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
39
|
+
else
|
40
|
+
@@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
41
|
+
end
|
42
|
+
|
43
|
+
if ssl_key then
|
44
|
+
pkey_data=IO.read(ssl_key)
|
45
|
+
if pkey_data.start_with?("-----BEGIN RSA PRIVATE KEY-----")
|
46
|
+
@@http.key=OpenSSL::PKey::RSA.new(pkey_data)
|
47
|
+
else
|
48
|
+
@@http.key=OpenSSL::PKey::DSA.new(pkey_data)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
@@http.cert=OpenSSL::X509::Certificate.new(IO.read(ssl_cert)) if ssl_cert
|
52
|
+
@@http.ca_file=ssl_ca_cert if ssl_ca_cert
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.file_upload(url_path, file_data={}, post_data={})
|
58
|
+
init_connection if @@http.nil?
|
59
|
+
req = Net::HTTP::Post.new(url_path)
|
60
|
+
|
61
|
+
post_arr=[]
|
62
|
+
post_data.each_pair do |key, value|
|
63
|
+
post_arr << "--#{MULTI_PART_BOUNDARY}\r\n"
|
64
|
+
post_arr << "Content-Disposition: form-data; name=\"#{key}\"\r\n"
|
65
|
+
post_arr << "\r\n"
|
66
|
+
post_arr << value
|
67
|
+
post_arr << "\r\n"
|
68
|
+
end
|
69
|
+
|
70
|
+
file_data.each_pair do |name, file|
|
71
|
+
post_arr << "--#{MULTI_PART_BOUNDARY}\r\n"
|
72
|
+
post_arr << "Content-Disposition: form-data; name=\"#{name}\"; filename=\"#{File.basename(file)}\"\r\n"
|
73
|
+
post_arr << "Content-Type: text/plain\r\n"
|
74
|
+
post_arr << "\r\n"
|
75
|
+
post_arr << File.read(file)
|
76
|
+
post_arr << "\r\n--#{MULTI_PART_BOUNDARY}--\r\n"
|
77
|
+
end
|
78
|
+
post_arr << "--#{MULTI_PART_BOUNDARY}--\r\n\r\n"
|
79
|
+
|
80
|
+
req.body=post_arr.join
|
81
|
+
|
82
|
+
req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
|
83
|
+
req["Content-Type"] = "multipart/form-data, boundary=#{MULTI_PART_BOUNDARY}"
|
84
|
+
|
85
|
+
response = @@http.request(req)
|
86
|
+
case response
|
87
|
+
when Net::HTTPSuccess
|
88
|
+
return response.body
|
89
|
+
else
|
90
|
+
puts response.body
|
91
|
+
response.error!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.post(url_path, post_data)
|
96
|
+
init_connection if @@http.nil?
|
97
|
+
req = Net::HTTP::Post.new(url_path)
|
98
|
+
if post_data.kind_of?(String) then
|
99
|
+
req.body=post_data
|
100
|
+
elsif post_data.kind_of?(Hash) then
|
101
|
+
req.form_data=post_data
|
102
|
+
else
|
103
|
+
raise "Invalid post data type."
|
104
|
+
end
|
105
|
+
req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
|
106
|
+
response = @@http.request(req)
|
107
|
+
case response
|
108
|
+
when Net::HTTPSuccess
|
109
|
+
return response.body
|
110
|
+
else
|
111
|
+
puts response.body
|
112
|
+
response.error!
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.get(url_path)
|
117
|
+
init_connection if @@http.nil?
|
118
|
+
req = Net::HTTP::Get.new(url_path)
|
119
|
+
req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
|
120
|
+
response = @@http.request(req)
|
121
|
+
case response
|
122
|
+
when Net::HTTPSuccess
|
123
|
+
return response.body
|
124
|
+
else
|
125
|
+
response.error!
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.delete(url_path)
|
130
|
+
init_connection if @@http.nil?
|
131
|
+
req = Net::HTTP::Delete.new(url_path)
|
132
|
+
req.basic_auth @@auth_user, @@auth_password if @@auth_user and @@auth_password
|
133
|
+
response = @@http.request(req)
|
134
|
+
case response
|
135
|
+
when Net::HTTPSuccess
|
136
|
+
return response.body
|
137
|
+
else
|
138
|
+
response.error!
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|