chef-vpc-toolkit 2.1.0 → 2.2.0
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 +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
|