rest_connection 0.0.23 → 0.1.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/README.rdoc +3 -3
- data/Rakefile +5 -4
- data/VERSION +1 -1
- data/git_hooks/post-commit.disabled +4 -0
- data/git_hooks/post-merge.disabled +4 -0
- data/git_hooks/pre-commit +53 -0
- data/lib/rest_connection.rb +75 -12
- data/lib/rest_connection/patches.rb +106 -0
- data/lib/rest_connection/rightscale/account.rb +27 -0
- data/lib/rest_connection/rightscale/alert_spec.rb +2 -2
- data/lib/rest_connection/rightscale/audit_entry.rb +5 -5
- data/lib/rest_connection/rightscale/child_account.rb +27 -0
- data/lib/rest_connection/rightscale/cloud.rb +26 -0
- data/lib/rest_connection/rightscale/credential.rb +1 -1
- data/lib/rest_connection/rightscale/deployment.rb +33 -7
- data/lib/rest_connection/rightscale/ec2_ebs_snapshot.rb +3 -1
- data/lib/rest_connection/rightscale/ec2_ebs_volume.rb +3 -1
- data/lib/rest_connection/rightscale/ec2_elastic_ip.rb +1 -1
- data/lib/rest_connection/rightscale/ec2_security_group.rb +2 -2
- data/lib/rest_connection/rightscale/ec2_server_array.rb +7 -5
- data/lib/rest_connection/rightscale/ec2_ssh_key.rb +11 -2
- data/lib/rest_connection/rightscale/ec2_ssh_key_internal.rb +2 -2
- data/lib/rest_connection/rightscale/executable.rb +4 -4
- data/lib/rest_connection/rightscale/instance.rb +5 -3
- data/lib/rest_connection/rightscale/instance_type.rb +31 -0
- data/lib/rest_connection/rightscale/macro.rb +19 -0
- data/lib/rest_connection/rightscale/mc_datacenter.rb +53 -0
- data/lib/rest_connection/rightscale/mc_deployment.rb +60 -0
- data/lib/rest_connection/rightscale/mc_image.rb +42 -0
- data/lib/rest_connection/rightscale/mc_instance.rb +170 -0
- data/lib/rest_connection/rightscale/mc_instance_type.rb +47 -0
- data/lib/rest_connection/rightscale/mc_multi_cloud_image.rb +58 -0
- data/lib/rest_connection/rightscale/mc_multi_cloud_image_setting.rb +46 -0
- data/lib/rest_connection/rightscale/mc_security_group.rb +42 -0
- data/lib/rest_connection/rightscale/mc_server.rb +250 -6
- data/lib/rest_connection/rightscale/mc_server_array.rb +44 -0
- data/lib/rest_connection/rightscale/mc_server_template.rb +53 -0
- data/lib/rest_connection/rightscale/mc_ssh_key.rb +50 -0
- data/lib/rest_connection/rightscale/mc_tag.rb +69 -0
- data/lib/rest_connection/rightscale/mc_volume.rb +53 -0
- data/lib/rest_connection/rightscale/mc_volume_attachment.rb +48 -0
- data/lib/rest_connection/rightscale/mc_volume_snapshot.rb +55 -0
- data/lib/rest_connection/rightscale/mc_volume_type.rb +47 -0
- data/lib/rest_connection/rightscale/monitoring_metric.rb +35 -0
- data/lib/rest_connection/rightscale/multi_cloud_image.rb +16 -2
- data/lib/rest_connection/rightscale/multi_cloud_image_cloud_setting_internal.rb +2 -2
- data/lib/rest_connection/rightscale/multi_cloud_image_internal.rb +25 -1
- data/lib/rest_connection/rightscale/permission.rb +27 -0
- data/lib/rest_connection/rightscale/right_script.rb +4 -4
- data/lib/rest_connection/rightscale/right_script_internal.rb +4 -4
- data/lib/rest_connection/rightscale/rightscale_api_base.rb +69 -20
- data/lib/rest_connection/rightscale/rightscale_api_gateway.rb +198 -13
- data/lib/rest_connection/rightscale/rightscale_api_internal.rb +3 -3
- data/lib/rest_connection/rightscale/rightscale_api_mc_input.rb +32 -0
- data/lib/rest_connection/rightscale/rightscale_api_mc_taggable.rb +57 -0
- data/lib/rest_connection/rightscale/rightscale_api_resources.rb +32 -2
- data/lib/rest_connection/rightscale/rightscale_api_taggable.rb +116 -0
- data/lib/rest_connection/rightscale/rs_internal.rb +6 -6
- data/lib/rest_connection/rightscale/s3_bucket.rb +36 -0
- data/lib/rest_connection/rightscale/server.rb +186 -37
- data/lib/rest_connection/rightscale/server_interface.rb +264 -0
- data/lib/rest_connection/rightscale/server_internal.rb +3 -3
- data/lib/rest_connection/rightscale/server_template.rb +15 -4
- data/lib/rest_connection/rightscale/server_template_internal.rb +4 -4
- data/lib/rest_connection/rightscale/status.rb +2 -2
- data/lib/rest_connection/rightscale/tag.rb +2 -2
- data/lib/rest_connection/rightscale/task.rb +47 -0
- data/lib/rest_connection/rightscale/user.rb +27 -0
- data/lib/rest_connection/ssh_hax.rb +42 -40
- data/rest_connection.gemspec +5 -5
- data/spec/mcserver_spec.rb +17 -0
- data/spec/multi.rb +16 -0
- metadata +65 -12
@@ -0,0 +1,42 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McImage
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
|
23
|
+
def resource_plural_name
|
24
|
+
"images"
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_singular_name
|
28
|
+
"image"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.resource_plural_name
|
32
|
+
"images"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_singular_name
|
36
|
+
"image"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_args(cloud_id)
|
40
|
+
"clouds/#{cloud_id}/"
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McInstance
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
include RightScale::Api::McTaggable
|
23
|
+
extend RightScale::Api::McTaggableExtend
|
24
|
+
include RightScale::Api::McInput
|
25
|
+
attr_accessor :monitoring_metrics
|
26
|
+
|
27
|
+
def resource_plural_name
|
28
|
+
"instances"
|
29
|
+
end
|
30
|
+
|
31
|
+
def resource_singular_name
|
32
|
+
"instance"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_plural_name
|
36
|
+
"instances"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.resource_singular_name
|
40
|
+
"instance"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.parse_args(cloud_id)
|
44
|
+
"clouds/#{cloud_id}/"
|
45
|
+
end
|
46
|
+
|
47
|
+
def show
|
48
|
+
inst_href = URI.parse(self.href)
|
49
|
+
@params.merge! connection.get(inst_href.path, 'view' => "full")
|
50
|
+
end
|
51
|
+
|
52
|
+
def save
|
53
|
+
update
|
54
|
+
end
|
55
|
+
|
56
|
+
def map_security_groups(to, sg_ary)
|
57
|
+
sg_ary.map { |hsh| hsh["href"] }
|
58
|
+
end
|
59
|
+
|
60
|
+
def map_user_data(to, user_data)
|
61
|
+
user_data
|
62
|
+
end
|
63
|
+
|
64
|
+
def update
|
65
|
+
fields = [{"attr" => :datacenter, "api" => :datacenter_href},
|
66
|
+
{"attr" => :image, "api" => :image_href},
|
67
|
+
{"attr" => :instance_type, "api" => :instance_type_href},
|
68
|
+
{ "api" => :kernel_image_href},
|
69
|
+
{"attr" => :multi_cloud_image, "api" => :multi_cloud_image_href},
|
70
|
+
{ "api" => :ramdisk_image_href},
|
71
|
+
{"attr" => :security_groups, "fn" => :map_security_groups, "api" => :security_group_hrefs},
|
72
|
+
{"attr" => :server_template, "api" => :server_template_href},
|
73
|
+
{"attr" => :ssh_key, "api" => :ssh_key_href},
|
74
|
+
{"attr" => :user_data, "fn" => :map_user_data, "api" => :user_data}]
|
75
|
+
|
76
|
+
opts = {"instance" => {}}
|
77
|
+
instance = opts["instance"]
|
78
|
+
to = "api"
|
79
|
+
from = "attr"
|
80
|
+
fields.each { |hsh|
|
81
|
+
next unless hsh[from]
|
82
|
+
val = self[hsh[from]]
|
83
|
+
if hsh["fn"]
|
84
|
+
instance[hsh[to].to_s] = __send__(hsh["fn"], to, val) unless val.nil? || val.empty?
|
85
|
+
else
|
86
|
+
instance[hsh[to].to_s] = val unless val.nil? || val.empty?
|
87
|
+
end
|
88
|
+
}
|
89
|
+
inst_href = URI.parse(self.href)
|
90
|
+
connection.put(inst_href.path, opts)
|
91
|
+
end
|
92
|
+
|
93
|
+
def launch
|
94
|
+
inst_href = URI.parse(self.href)
|
95
|
+
connection.post(inst_href.path + '/launch')
|
96
|
+
end
|
97
|
+
|
98
|
+
def terminate
|
99
|
+
inst_href = URI.parse(self.href)
|
100
|
+
connection.post(inst_href.path + '/terminate')
|
101
|
+
end
|
102
|
+
|
103
|
+
def multi_update(input_ary)
|
104
|
+
inst_href = URI.parse(self.href)
|
105
|
+
connection.put(inst_href.path + '/inputs/multi_update', {'inputs' => input_ary})
|
106
|
+
end
|
107
|
+
|
108
|
+
def transform_inputs(sym, parameters)
|
109
|
+
ret = nil
|
110
|
+
if parameters.is_a?(Array) and sym == :to_h
|
111
|
+
ret = {}
|
112
|
+
parameters.each { |hash| ret[hash['name']] = hash['value'] }
|
113
|
+
elsif parameters.is_a?(Hash) and sym == :to_a
|
114
|
+
ret = []
|
115
|
+
parameters.each { |key,val| ret << {'name' => key, 'value' => val} }
|
116
|
+
end
|
117
|
+
ret
|
118
|
+
end
|
119
|
+
|
120
|
+
def translate_href(old_href)
|
121
|
+
href = old_href.dup
|
122
|
+
href.gsub!(/ec2_/,'')
|
123
|
+
href.gsub!(/\/acct\/[0-9]*/,'')
|
124
|
+
return href
|
125
|
+
end
|
126
|
+
|
127
|
+
def run_executable(executable, opts=nil)
|
128
|
+
run_options = Hash.new
|
129
|
+
if executable.is_a?(Executable)
|
130
|
+
if executable.recipe?
|
131
|
+
run_options[:recipe_name] = executable.recipe
|
132
|
+
else
|
133
|
+
run_options[:right_script_href] = translate_href(executable.right_script.href)
|
134
|
+
end
|
135
|
+
elsif executable.is_a?(RightScript)
|
136
|
+
run_options[:right_script_href] = translate_href(executable.href)
|
137
|
+
else
|
138
|
+
raise "Invalid class passed to run_executable, needs Executable or RightScript, was:#{executable.class}"
|
139
|
+
end
|
140
|
+
|
141
|
+
inst_href = URI.parse(self.href)
|
142
|
+
run_options[:inputs] = transform_inputs(:to_a, opts) unless opts.nil?
|
143
|
+
location = connection.post(inst_href.path + '/run_executable', run_options)
|
144
|
+
Task.new('href' => location)
|
145
|
+
end
|
146
|
+
|
147
|
+
def fetch_monitoring_metrics
|
148
|
+
@monitoring_metrics = []
|
149
|
+
return @monitoring_metrics if self.state != "operational"
|
150
|
+
connection.get(URI.parse(self.href).path + '/monitoring_metrics').each { |mm|
|
151
|
+
@monitoring_metrics << MonitoringMetric.new(mm)
|
152
|
+
}
|
153
|
+
@monitoring_metrics
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_sketchy_data(params)
|
157
|
+
metric = fetch_monitoring_metrics.detect { |mm| mm.plugin == params['plugin_name'] and mm.view == params['plugin_type'] }
|
158
|
+
raise "Metric not found!" unless metric
|
159
|
+
metric.data(params['start'], params['end'])
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_data(params)
|
163
|
+
get_sketchy_data(params)
|
164
|
+
end
|
165
|
+
|
166
|
+
def reboot
|
167
|
+
self.show
|
168
|
+
connection.post(URI.parse(self.href).path + '/reboot')
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McInstanceType
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
|
23
|
+
def resource_plural_name
|
24
|
+
"instance_types"
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_singular_name
|
28
|
+
"instance_type"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.resource_plural_name
|
32
|
+
"instance_types"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_singular_name
|
36
|
+
"instance_type"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_args(cloud_id)
|
40
|
+
"clouds/#{cloud_id}/"
|
41
|
+
end
|
42
|
+
|
43
|
+
def show
|
44
|
+
inst_href = URI.parse(self.href)
|
45
|
+
@params.merge! connection.get(inst_href.path, 'view' => "default")
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McMultiCloudImage
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
include RightScale::Api::McTaggable
|
23
|
+
extend RightScale::Api::McTaggableExtend
|
24
|
+
attr_reader :settings
|
25
|
+
|
26
|
+
def resource_plural_name
|
27
|
+
"multi_cloud_images"
|
28
|
+
end
|
29
|
+
|
30
|
+
def resource_singular_name
|
31
|
+
"multi_cloud_image"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.resource_plural_name
|
35
|
+
"multi_cloud_images"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.resource_singular_name
|
39
|
+
"multi_cloud_image"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.parse_args(server_template_id=nil)
|
43
|
+
server_template_id ? "server_templates/#{server_template_id}/" : ""
|
44
|
+
end
|
45
|
+
|
46
|
+
def supported_cloud_ids
|
47
|
+
@settings.map { |mcics| mcics.cloud_id }
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_settings
|
51
|
+
@settings = []
|
52
|
+
url = URI.parse(self.href)
|
53
|
+
connection.get(url.path + '/settings').each { |s|
|
54
|
+
@settings << McMultiCloudImageSetting.new(s)
|
55
|
+
}
|
56
|
+
@settings
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McMultiCloudImageSetting
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
|
23
|
+
def resource_plural_name
|
24
|
+
"settings"
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_singular_name
|
28
|
+
"setting"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.resource_plural_name
|
32
|
+
"settings"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_singular_name
|
36
|
+
"setting"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_args(multi_cloud_image_id)
|
40
|
+
"multi_cloud_images/#{multi_cloud_image_id}/"
|
41
|
+
end
|
42
|
+
|
43
|
+
def cloud_id
|
44
|
+
self.cloud.split(/\//).last.to_i
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
#
|
17
|
+
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
+
#
|
19
|
+
class McSecurityGroup
|
20
|
+
include RightScale::Api::Gateway
|
21
|
+
extend RightScale::Api::GatewayExtend
|
22
|
+
|
23
|
+
def resource_plural_name
|
24
|
+
"security_groups"
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_singular_name
|
28
|
+
"security_group"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.resource_plural_name
|
32
|
+
"security_groups"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.resource_singular_name
|
36
|
+
"security_group"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse_args(cloud_id)
|
40
|
+
"clouds/#{cloud_id}/"
|
41
|
+
end
|
42
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# This file is part of RestConnection
|
1
|
+
# This file is part of RestConnection
|
2
2
|
#
|
3
3
|
# RestConnection is free software: you can redistribute it and/or modify
|
4
4
|
# it under the terms of the GNU General Public License as published by
|
@@ -13,13 +13,16 @@
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
14
14
|
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# You must have Beta v1.5 API access to use these internal API calls.
|
18
|
-
#
|
19
|
-
class McServer
|
18
|
+
#
|
19
|
+
class McServer < Server
|
20
20
|
include RightScale::Api::Gateway
|
21
21
|
extend RightScale::Api::GatewayExtend
|
22
|
-
|
22
|
+
include RightScale::Api::McTaggable
|
23
|
+
extend RightScale::Api::McTaggableExtend
|
24
|
+
attr_accessor :current_instance, :next_instance, :inputs
|
25
|
+
|
23
26
|
def resource_plural_name
|
24
27
|
"servers"
|
25
28
|
end
|
@@ -35,5 +38,246 @@ class McServer
|
|
35
38
|
def self.resource_singular_name
|
36
39
|
"server"
|
37
40
|
end
|
38
|
-
|
41
|
+
|
42
|
+
def self.parse_args(deployment_id=nil)
|
43
|
+
deployment_id ? "deployments/#{deployment_id}/" : ""
|
44
|
+
end
|
45
|
+
|
46
|
+
def launch
|
47
|
+
if actions.include?("launch")
|
48
|
+
t = URI.parse(self.href)
|
49
|
+
connection.post(t.path + '/launch')
|
50
|
+
elsif self.state == "inactive"
|
51
|
+
raise "FATAL: Server is in an unlaunchable state!"
|
52
|
+
else
|
53
|
+
connection.logger("WARNING: was in #{self.state} so skipping launch call")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def terminate
|
58
|
+
if actions.include?("terminate")
|
59
|
+
t = URI.parse(self.href)
|
60
|
+
connection.post(t.path + '/terminate')
|
61
|
+
@current_instance = nil
|
62
|
+
# elsif self.state != "inactive"
|
63
|
+
# raise "FATAL: Server is in an interminable state!"
|
64
|
+
else
|
65
|
+
connection.logger("WARNING: was in #{self.state} so skipping terminate call")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def force_terminate
|
70
|
+
t = URI.parse(self.href)
|
71
|
+
connection.post(t.path + '/terminate')
|
72
|
+
connection.post(t.path + '/terminate')
|
73
|
+
@current_instance = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def start #start_ebs
|
77
|
+
raise "You shouldn't be here."
|
78
|
+
end
|
79
|
+
|
80
|
+
def stop #stop_ebs
|
81
|
+
raise "You shouldn't be here."
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_executable(executable, opts=nil)
|
85
|
+
raise "Instance isn't running; Can't run executable" unless @current_instance
|
86
|
+
@current_instance.run_executable(executable, opts)
|
87
|
+
end
|
88
|
+
|
89
|
+
def transform_inputs(sym, parameters)
|
90
|
+
ret = nil
|
91
|
+
if parameters.is_a?(Array) and sym == :to_h
|
92
|
+
ret = {}
|
93
|
+
parameters.each { |hash| ret[hash['name']] = hash['value'] }
|
94
|
+
elsif parameters.is_a?(Hash) and sym == :to_a
|
95
|
+
ret = []
|
96
|
+
parameters.each { |key,val| ret << {'name' => key, 'value' => val} }
|
97
|
+
end
|
98
|
+
ret
|
99
|
+
end
|
100
|
+
|
101
|
+
def inputs
|
102
|
+
if @current_instance
|
103
|
+
@current_instance.show
|
104
|
+
return transform_inputs(:to_h, @current_instance.inputs)
|
105
|
+
else
|
106
|
+
@next_instance.show
|
107
|
+
return transform_inputs(:to_h, @next_instance.inputs)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def set_input(name, value)
|
112
|
+
settings unless @next_instance
|
113
|
+
@current_instance.multi_update([{'name' => name, 'value' => value}]) if @current_instance
|
114
|
+
@next_instance.multi_update([{'name' => name, 'value' => value}])
|
115
|
+
end
|
116
|
+
|
117
|
+
def set_current_inputs(hash = {})
|
118
|
+
settings unless @next_instance
|
119
|
+
@current_instance.multi_update(transform_inputs(:to_a, hash)) if @current_instance
|
120
|
+
end
|
121
|
+
|
122
|
+
def set_next_inputs(hash = {})
|
123
|
+
settings unless @next_instance
|
124
|
+
@next_instance.multi_update(transform_inputs(:to_a, hash))
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
def settings #show
|
129
|
+
serv_href = URI.parse(self.href)
|
130
|
+
@params = connection.get(serv_href.path, 'view' => 'instance_detail')
|
131
|
+
if self['current_instance']
|
132
|
+
@current_instance = McInstance.new(self['current_instance'])
|
133
|
+
@current_instance.show
|
134
|
+
end
|
135
|
+
@next_instance = McInstance.new(self['next_instance'])
|
136
|
+
@next_instance.show
|
137
|
+
@params
|
138
|
+
end
|
139
|
+
|
140
|
+
def monitoring
|
141
|
+
ret = @current_instance.fetch_monitoring_metrics
|
142
|
+
raise "FATAL: Monitoring not available!" if ret.empty?
|
143
|
+
ret
|
144
|
+
end
|
145
|
+
|
146
|
+
def relaunch
|
147
|
+
self.terminate
|
148
|
+
self.wait_for_state("inactive")
|
149
|
+
self.launch
|
150
|
+
end
|
151
|
+
|
152
|
+
# Attributes taken for granted in API 1.0
|
153
|
+
def server_type
|
154
|
+
"gateway"
|
155
|
+
end
|
156
|
+
|
157
|
+
def server_template_href
|
158
|
+
if @current_instance
|
159
|
+
return @current_instance.server_template
|
160
|
+
end
|
161
|
+
self.settings unless @next_instance
|
162
|
+
return @next_instance.server_template
|
163
|
+
end
|
164
|
+
|
165
|
+
def deployment_href
|
166
|
+
hash_of_links["deployment"]
|
167
|
+
end
|
168
|
+
|
169
|
+
def current_instance_href
|
170
|
+
hash_of_links["current_instance"]
|
171
|
+
end
|
172
|
+
|
173
|
+
def cloud_id
|
174
|
+
settings unless @next_instance
|
175
|
+
cloud_href = @current_instance.hash_of_links["cloud"] if @current_instance
|
176
|
+
cloud_href = @next_instance.hash_of_links["cloud"] unless cloud_href
|
177
|
+
return cloud_href.split("/").last.to_i
|
178
|
+
end
|
179
|
+
|
180
|
+
=begin
|
181
|
+
def wait_for_operational_with_dns(state_wait_timeout=1200)
|
182
|
+
timeout = 600
|
183
|
+
wait_for_state("operational", state_wait_timeout)
|
184
|
+
step = 15
|
185
|
+
while(timeout > 0)
|
186
|
+
self.settings
|
187
|
+
break if self.reachable_ip
|
188
|
+
connection.logger "waiting for any IP for #{self.nickname}"
|
189
|
+
sleep step
|
190
|
+
timeout -= step
|
191
|
+
end
|
192
|
+
connection.logger "got IP: #{self.reachable_ip}"
|
193
|
+
raise "FATAL, this server #{self.audit_link} timed out waiting for an IP" if timeout <= 0
|
194
|
+
end
|
195
|
+
=end
|
196
|
+
|
197
|
+
def dns_name
|
198
|
+
self.settings
|
199
|
+
if @current_instance
|
200
|
+
return @current_instance.public_ip_addresses.first || @current_instance.public_dns_names.first
|
201
|
+
end
|
202
|
+
nil
|
203
|
+
end
|
204
|
+
|
205
|
+
def private_ip
|
206
|
+
self.settings
|
207
|
+
if @current_instance
|
208
|
+
return @current_instance.private_ip_addresses.first || @current_instance.private_dns_names.first
|
209
|
+
end
|
210
|
+
nil
|
211
|
+
end
|
212
|
+
|
213
|
+
def save
|
214
|
+
update
|
215
|
+
end
|
216
|
+
|
217
|
+
def update
|
218
|
+
@next_instance.update
|
219
|
+
@current_instance.update if @current_instance
|
220
|
+
end
|
221
|
+
|
222
|
+
def reload_as_current
|
223
|
+
settings # Gets all instance (including current) information
|
224
|
+
end
|
225
|
+
|
226
|
+
def reload_as_next
|
227
|
+
settings # Gets all instance (including current) information
|
228
|
+
end
|
229
|
+
|
230
|
+
def get_sketchy_data(params)
|
231
|
+
settings
|
232
|
+
raise "No current instance found!" unless @current_instance
|
233
|
+
@current_instance.get_sketchy_data(params)
|
234
|
+
end
|
235
|
+
|
236
|
+
# Override Taggable mixin so that it sets tags on both next and current instances
|
237
|
+
def current_tags(reload=true)
|
238
|
+
ret = []
|
239
|
+
if @current_instance
|
240
|
+
ret = McTag.search_by_href(self.current_instance_href).first["tags"].map { |h| h["name"] }
|
241
|
+
end
|
242
|
+
ret
|
243
|
+
end
|
244
|
+
|
245
|
+
def add_tags(*args)
|
246
|
+
return false if args.empty?
|
247
|
+
args.uniq!
|
248
|
+
McTag.set(self.href, args)
|
249
|
+
McTag.set(self.current_instance_href, args) if @current_instance
|
250
|
+
self.tags(true)
|
251
|
+
end
|
252
|
+
|
253
|
+
def remove_tags(*args)
|
254
|
+
return false if args.empty?
|
255
|
+
args.uniq!
|
256
|
+
McTag.unset(self.href, args)
|
257
|
+
McTag.unset(self.current_instance_href, args) if @current_instance
|
258
|
+
self.tags(true)
|
259
|
+
end
|
260
|
+
|
261
|
+
def get_tags_by_namespace(namespace)
|
262
|
+
ret = {}
|
263
|
+
tags = {"self" => self.tags(true)}
|
264
|
+
tags["current_instance"] = self.current_tags if @current_instance
|
265
|
+
tags.each { |res,ary|
|
266
|
+
ret[res] ||= {}
|
267
|
+
ary.each { |tag|
|
268
|
+
next unless tag.start_with?("#{namespace}:")
|
269
|
+
key = tag.split("=").first.split(":")[1..-1].join(":")
|
270
|
+
value = tag.split(":")[1..-1].join(":").split("=")[1..-1].join("=")
|
271
|
+
ret[res][key] = value
|
272
|
+
}
|
273
|
+
}
|
274
|
+
return ret
|
275
|
+
end
|
276
|
+
|
277
|
+
def clear_tags(namespace = nil)
|
278
|
+
tags = self.tags(true)
|
279
|
+
tags.deep_merge! self.current_tags if @current_instance
|
280
|
+
tags = tags.select { |tag| tag.start_with?("#{namespace}:") } if namespace
|
281
|
+
self.remove_tags(*tags)
|
282
|
+
end
|
39
283
|
end
|