bbrowning-deltacloud-core 0.0.4-java
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/COPYING +176 -0
- data/Rakefile +99 -0
- data/bin/deltacloudd +120 -0
- data/config.ru +5 -0
- data/deltacloud.rb +18 -0
- data/lib/deltacloud/base_driver/base_driver.rb +229 -0
- data/lib/deltacloud/base_driver/features.rb +166 -0
- data/lib/deltacloud/base_driver/mock_driver.rb +40 -0
- data/lib/deltacloud/base_driver.rb +20 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +410 -0
- data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +50 -0
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +332 -0
- data/lib/deltacloud/drivers/gogrid/test.rb +13 -0
- data/lib/deltacloud/drivers/mock/data/images/img1.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/images/img2.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/images/img3.yml +3 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +16 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +9 -0
- data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +9 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml +4 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +6 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +6 -0
- data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +6 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +277 -0
- data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
- data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
- data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +130 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +182 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +255 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +85 -0
- data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +166 -0
- data/lib/deltacloud/drivers/terremark/terremark_driver.rb +286 -0
- data/lib/deltacloud/hardware_profile.rb +153 -0
- data/lib/deltacloud/helpers/application_helper.rb +115 -0
- data/lib/deltacloud/helpers/conversion_helper.rb +39 -0
- data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
- data/lib/deltacloud/helpers.rb +5 -0
- data/lib/deltacloud/method_serializer.rb +85 -0
- data/lib/deltacloud/models/base_model.rb +59 -0
- data/lib/deltacloud/models/image.rb +27 -0
- data/lib/deltacloud/models/instance.rb +38 -0
- data/lib/deltacloud/models/instance_profile.rb +48 -0
- data/lib/deltacloud/models/key.rb +35 -0
- data/lib/deltacloud/models/realm.rb +26 -0
- data/lib/deltacloud/models/storage_snapshot.rb +27 -0
- data/lib/deltacloud/models/storage_volume.rb +28 -0
- data/lib/deltacloud/state_machine.rb +84 -0
- data/lib/deltacloud/validation.rb +70 -0
- data/lib/drivers.rb +50 -0
- data/lib/sinatra/accept_media_types.rb +128 -0
- data/lib/sinatra/lazy_auth.rb +56 -0
- data/lib/sinatra/rabbit.rb +273 -0
- data/lib/sinatra/respond_to.rb +272 -0
- data/lib/sinatra/static_assets.rb +83 -0
- data/lib/sinatra/url_for.rb +53 -0
- data/public/favicon.ico +0 -0
- data/public/images/grid.png +0 -0
- data/public/images/logo-wide.png +0 -0
- data/public/images/rails.png +0 -0
- data/public/images/topbar-bg.png +0 -0
- data/public/javascripts/application.js +32 -0
- data/public/javascripts/jquery-1.4.2.min.js +154 -0
- data/public/stylesheets/compiled/application.css +613 -0
- data/public/stylesheets/compiled/ie.css +31 -0
- data/public/stylesheets/compiled/print.css +27 -0
- data/public/stylesheets/compiled/screen.css +456 -0
- data/server.rb +354 -0
- data/support/fedora/deltacloudd +68 -0
- data/support/fedora/rubygem-deltacloud-core.spec +91 -0
- data/tests/api_test.rb +37 -0
- data/tests/hardware_profiles_test.rb +120 -0
- data/tests/images_test.rb +111 -0
- data/tests/instance_states_test.rb +52 -0
- data/tests/instances_test.rb +219 -0
- data/tests/realms_test.rb +78 -0
- data/tests/url_for_test.rb +50 -0
- data/views/accounts/index.html.haml +11 -0
- data/views/accounts/show.html.haml +30 -0
- data/views/api/show.html.haml +15 -0
- data/views/api/show.xml.haml +5 -0
- data/views/docs/collection.html.haml +37 -0
- data/views/docs/collection.xml.haml +14 -0
- data/views/docs/index.html.haml +15 -0
- data/views/docs/index.xml.haml +5 -0
- data/views/docs/operation.html.haml +31 -0
- data/views/docs/operation.xml.haml +10 -0
- data/views/errors/auth_exception.html.haml +8 -0
- data/views/errors/auth_exception.xml.haml +2 -0
- data/views/errors/backend_error.html.haml +19 -0
- data/views/errors/backend_error.xml.haml +8 -0
- data/views/errors/not_found.html.haml +6 -0
- data/views/errors/not_found.xml.haml +2 -0
- data/views/errors/validation_failure.html.haml +11 -0
- data/views/errors/validation_failure.xml.haml +7 -0
- data/views/hardware_profiles/index.html.haml +25 -0
- data/views/hardware_profiles/index.xml.haml +4 -0
- data/views/hardware_profiles/show.html.haml +19 -0
- data/views/hardware_profiles/show.xml.haml +18 -0
- data/views/images/index.html.haml +30 -0
- data/views/images/index.xml.haml +8 -0
- data/views/images/show.html.haml +21 -0
- data/views/images/show.xml.haml +5 -0
- data/views/instance_states/show.gv.erb +45 -0
- data/views/instance_states/show.html.haml +31 -0
- data/views/instance_states/show.xml.haml +8 -0
- data/views/instances/index.html.haml +30 -0
- data/views/instances/index.xml.haml +21 -0
- data/views/instances/new.html.haml +55 -0
- data/views/instances/show.html.haml +43 -0
- data/views/instances/show.xml.haml +49 -0
- data/views/keys/index.html.haml +26 -0
- data/views/keys/index.xml.haml +4 -0
- data/views/keys/new.html.haml +8 -0
- data/views/keys/show.html.haml +22 -0
- data/views/keys/show.xml.haml +20 -0
- data/views/layout.html.haml +26 -0
- data/views/realms/index.html.haml +29 -0
- data/views/realms/index.xml.haml +10 -0
- data/views/realms/show.html.haml +15 -0
- data/views/realms/show.xml.haml +9 -0
- data/views/root/index.html.haml +4 -0
- data/views/storage_snapshots/index.html.haml +20 -0
- data/views/storage_snapshots/index.xml.haml +9 -0
- data/views/storage_snapshots/show.html.haml +14 -0
- data/views/storage_snapshots/show.xml.haml +7 -0
- data/views/storage_volumes/index.html.haml +21 -0
- data/views/storage_volumes/index.xml.haml +13 -0
- data/views/storage_volumes/show.html.haml +20 -0
- data/views/storage_volumes/show.xml.haml +11 -0
- metadata +334 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
module RightAws
|
|
2
|
+
class MockEc2
|
|
3
|
+
|
|
4
|
+
def initialize(opts={})
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def describe_images(id)
|
|
8
|
+
load_fixtures_for(:images).select { |i| i[:aws_id].eql?(id) }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def describe_images_by_owner(id)
|
|
12
|
+
load_fixtures_for(:images).select { |i| i[:aws_owner].eql?(id) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def describe_images(opts={})
|
|
16
|
+
load_fixtures_for(:images)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def describe_availability_zones(opts={})
|
|
20
|
+
load_fixtures_for(:realms)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def describe_instances(opts={})
|
|
24
|
+
instances = load_fixtures_for(:instances)
|
|
25
|
+
instances.each_with_index do |instance, i|
|
|
26
|
+
instances[i] = update_delayed_state(instance)
|
|
27
|
+
return [instance] if opts and opts[:id] and instance[:aws_instance_id].eql?(opts[:id])
|
|
28
|
+
end
|
|
29
|
+
update_fixtures_for(:instances, instances)
|
|
30
|
+
instances
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def run_instances(image_id, min_count, max_count, group_ids, key_name, user_data='', addressing_type = nil, instance_type = nil, kernel_id = nil, ramdisk_id = nil, availability_zone = nil, block_device_mappings = nil)
|
|
34
|
+
|
|
35
|
+
instances = load_fixtures_for(:instances)
|
|
36
|
+
image = load_fixtures_for(:images).select { |img| img[:aws_id].eql?(image_id) }.first
|
|
37
|
+
|
|
38
|
+
if availability_zone
|
|
39
|
+
realm = load_fixtures_for(:realms).select { |realm| realm[:zone_name].eql?(availability_zone) }.first
|
|
40
|
+
else
|
|
41
|
+
realm = load_fixtures_for(:realms).first
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
raise Exception unless image
|
|
45
|
+
raise Exception unless realm
|
|
46
|
+
|
|
47
|
+
instance = { }
|
|
48
|
+
instance[:aws_image_id] = image[:aws_id]
|
|
49
|
+
instance[:aws_availability_zone] = realm[:zone_name]
|
|
50
|
+
instance[:aws_instance_type] = instance_type
|
|
51
|
+
instance[:aws_owner] = user_data
|
|
52
|
+
instance[:aws_state] = 'pending'
|
|
53
|
+
instance[:aws_reason] = ''
|
|
54
|
+
instance[:dns_name] = "#{random_dns}-01-C9.usma2.compute.amazonaws.com"
|
|
55
|
+
instance[:private_dns_name] = "#{random_dns}-02-P9.usma2.compute.amazonaws.com"
|
|
56
|
+
instance[:aws_state_code] = "0"
|
|
57
|
+
instance[:aws_key_name] = "staging"
|
|
58
|
+
instance[:aws_kernel_id] = "aki-be3adfd7"
|
|
59
|
+
instance[:aws_ramdisk_id] = "ari-ce34gad7"
|
|
60
|
+
instance[:aws_groups] = ["default"]
|
|
61
|
+
instance[:aws_instance_id] = random_instance_id
|
|
62
|
+
instance[:aws_reservation_id] = "r-aabbccdd"
|
|
63
|
+
instance[:aws_launch_time] = instance_time_format
|
|
64
|
+
|
|
65
|
+
instances << instance
|
|
66
|
+
|
|
67
|
+
update_fixtures_for(:instances, instances)
|
|
68
|
+
|
|
69
|
+
return [instance]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def terminate_instances(id)
|
|
74
|
+
update_instance_state(id, 'stopping', '80')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def reboot_instances(id)
|
|
78
|
+
update_instance_state(id, 'pending', '0')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
alias :destroy_instance :terminate_instances
|
|
82
|
+
|
|
83
|
+
def describe_snapshots(opts={})
|
|
84
|
+
load_fixtures_for(:storage_snapshot)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def describe_volumes(opts={})
|
|
88
|
+
load_fixtures_for(:storage_volume)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def driver_dir
|
|
94
|
+
File::expand_path(File::join(File::dirname(__FILE__), '../../../../features/support/ec2'))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def fixtures_path
|
|
98
|
+
File::expand_path(File::join(driver_dir, 'fixtures'))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def load_fixtures_for(collection)
|
|
102
|
+
YAML.load_file(File::join(fixtures_path, "#{collection}.yaml"))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def update_fixtures_for(collection, new_data)
|
|
106
|
+
File.open(File::join(fixtures_path, "#{collection}.yaml"), 'w' ) do |out|
|
|
107
|
+
YAML.dump(new_data, out)
|
|
108
|
+
end
|
|
109
|
+
return new_data
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def instance_time_format
|
|
113
|
+
DateTime.now.to_s.gsub(/\+(.+)$/, '.000Z')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def random_instance_id
|
|
117
|
+
id_1 = ("%.4s" % Time.now.to_i.to_s.reverse).reverse
|
|
118
|
+
id_2 = ("%.3s" % Time.now.to_i.to_s.reverse)
|
|
119
|
+
"i-#{id_1}f#{id_2}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def random_dns
|
|
123
|
+
"domU-#{rand(90)+10}-#{rand(90)+10}-#{rand(90)+10}-#{rand(90)+10}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def update_delayed_state(instance)
|
|
127
|
+
time = DateTime.now - DateTime.parse(instance[:aws_launch_time])
|
|
128
|
+
hours, minutes, seconds, frac = Date.day_fraction_to_time(time)
|
|
129
|
+
|
|
130
|
+
if (minutes>(rand(2)+1) or hours>0) and instance[:aws_state].eql?('pending')
|
|
131
|
+
instance[:aws_state], instance[:aws_state_code] = 'running', '16'
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if (minutes>(rand(1)+1) or hours>0) and instance[:aws_state].eql?('stopping')
|
|
135
|
+
instance[:aws_state], instance[:aws_state_code] = 'stopped', '80'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return instance
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def update_instance_state(id, state, state_code)
|
|
142
|
+
instance = describe_instances(:id => id).first
|
|
143
|
+
if instance
|
|
144
|
+
instance[:aws_state], instance[:aws_state_code] = state, state_code
|
|
145
|
+
instance[:aws_launch_time] = instance_time_format
|
|
146
|
+
instances = load_fixtures_for(:instances)
|
|
147
|
+
instances.each_with_index do |inst, i|
|
|
148
|
+
instances[i] = instance if inst[:aws_instance_id].eql?(id)
|
|
149
|
+
end
|
|
150
|
+
update_fixtures_for(:instances, instances)
|
|
151
|
+
return instance
|
|
152
|
+
else
|
|
153
|
+
raise Exception
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
Deltacloud::Drivers::EC2::EC2Driver.class_eval do
|
|
161
|
+
alias_method :original_new_client, :new_client
|
|
162
|
+
|
|
163
|
+
def new_client(credentials, opts={})
|
|
164
|
+
if credentials.user != 'mockuser' and credentials.password != 'mockpassword'
|
|
165
|
+
raise Deltacloud::AuthException.new
|
|
166
|
+
end
|
|
167
|
+
RightAws::MockEc2.new
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'digest/md5'
|
|
2
|
+
require 'cgi'
|
|
3
|
+
require 'open-uri'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
class GoGridClient
|
|
7
|
+
|
|
8
|
+
def initialize(server='https://api.gogrid.com/api',
|
|
9
|
+
apikey='YOUR API KEY',
|
|
10
|
+
secret='YOUR SHARED SECRET',
|
|
11
|
+
format='json',
|
|
12
|
+
version='1.5')
|
|
13
|
+
@server = server
|
|
14
|
+
@secret = secret
|
|
15
|
+
@default_params = {'format'=>format, 'v'=>version,'api_key' => apikey}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def getRequestURL(method,params)
|
|
19
|
+
requestURL = @server+'/'+method+'?'
|
|
20
|
+
call_params = @default_params.merge(params)
|
|
21
|
+
call_params['sig']=getSignature(@default_params['api_key'],@secret)
|
|
22
|
+
requestURL = requestURL+encode_params(call_params)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def getSignature(key,secret)
|
|
26
|
+
Digest::MD5.hexdigest(key+secret+"%.0f"%Time.new.to_f)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def sendAPIRequest(method,params={})
|
|
30
|
+
open(getRequestURL(method,params)).read
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def request(method, params={}, version=nil)
|
|
34
|
+
if version
|
|
35
|
+
@default_params['v'] = version
|
|
36
|
+
else
|
|
37
|
+
@default_params['v'] = '1.5'
|
|
38
|
+
end
|
|
39
|
+
begin
|
|
40
|
+
JSON::parse(sendAPIRequest(method, params))
|
|
41
|
+
rescue Exception => e
|
|
42
|
+
STDERR.puts("ERROR: #{e.message}")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def encode_params(params)
|
|
47
|
+
params.map {|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join("&")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2009 Red Hat, Inc.
|
|
3
|
+
#
|
|
4
|
+
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
5
|
+
# contributor license agreements. See the NOTICE file distributed with
|
|
6
|
+
# this work for additional information regarding copyright ownership. The
|
|
7
|
+
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
8
|
+
# "License"); you may not use this file except in compliance with the
|
|
9
|
+
# License. You may obtain a copy of the License at
|
|
10
|
+
#
|
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
#
|
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
15
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
16
|
+
# License for the specific language governing permissions and limitations
|
|
17
|
+
# under the License.
|
|
18
|
+
|
|
19
|
+
require 'deltacloud/base_driver'
|
|
20
|
+
require 'deltacloud/drivers/gogrid/gogrid_client'
|
|
21
|
+
|
|
22
|
+
class Instance
|
|
23
|
+
attr_accessor :username
|
|
24
|
+
attr_accessor :password
|
|
25
|
+
attr_accessor :authn_error
|
|
26
|
+
|
|
27
|
+
def authn_feature_failed?
|
|
28
|
+
return true unless authn_error.nil?
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Deltacloud
|
|
33
|
+
module Drivers
|
|
34
|
+
module Gogrid
|
|
35
|
+
|
|
36
|
+
class GogridDriver < Deltacloud::BaseDriver
|
|
37
|
+
|
|
38
|
+
feature :instances, :authentication_password
|
|
39
|
+
|
|
40
|
+
define_hardware_profile 'server' do
|
|
41
|
+
cpu 2
|
|
42
|
+
memory [512, 1024, 2048, 4096, 8192]
|
|
43
|
+
storage 10
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def supported_collections
|
|
47
|
+
DEFAULT_COLLECTIONS.reject! { |c| [ :storage_volumes, :storage_snapshots ].include?(c) }
|
|
48
|
+
DEFAULT_COLLECTIONS + [ :keys ]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def images(credentials, opts=nil)
|
|
52
|
+
imgs = []
|
|
53
|
+
if opts and opts[:id]
|
|
54
|
+
safely do
|
|
55
|
+
imgs = [convert_image(new_client(credentials).request('grid/image/get', { 'id' => opts[:id] })['list'].first)]
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
safely do
|
|
59
|
+
imgs = new_client(credentials).request('grid/image/list', { 'state' => 'Available'})['list'].collect do |image|
|
|
60
|
+
convert_image(image, credentials.user)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
imgs = filter_on( imgs, :architecture, opts )
|
|
65
|
+
imgs.sort_by{|e| [e.owner_id, e.description]}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def realms(credentials, opts=nil)
|
|
69
|
+
safely do
|
|
70
|
+
new_client(credentials).request('common/lookup/list', { 'lookup' => 'ip.datacenter' })['list'].collect do |realm|
|
|
71
|
+
convert_realm(realm)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def create_instance(credentials, image_id, opts=nil)
|
|
77
|
+
server_ram = nil
|
|
78
|
+
if opts[:hwp_memory]
|
|
79
|
+
mem = opts[:hwp_memory].to_i
|
|
80
|
+
server_ram = (mem == 512) ? "512MB" : "#{mem / 1024}GB"
|
|
81
|
+
else
|
|
82
|
+
server_ram = "512MB"
|
|
83
|
+
end
|
|
84
|
+
client = new_client(credentials)
|
|
85
|
+
name = (opts[:name] && opts[:name]!='') ? opts[:name] : get_random_instance_name
|
|
86
|
+
safely do
|
|
87
|
+
instance = client.request('grid/server/add', {
|
|
88
|
+
'name' => name,
|
|
89
|
+
'image' => image_id,
|
|
90
|
+
'server.ram' => server_ram,
|
|
91
|
+
'ip' => get_free_ip_from_realm(credentials, opts[:realm_id] || '1')
|
|
92
|
+
})['list'].first
|
|
93
|
+
if instance
|
|
94
|
+
login_data = get_login_data(client, instance[:id])
|
|
95
|
+
if login_data['username'] and login_data['password']
|
|
96
|
+
instance['username'] = login_data['username']
|
|
97
|
+
instance['password'] = login_data['password']
|
|
98
|
+
inst = convert_instance(instance, credentials.user)
|
|
99
|
+
else
|
|
100
|
+
inst = convert_instance(instance, credentials.user)
|
|
101
|
+
inst.authn_error = "Unable to fetch password"
|
|
102
|
+
end
|
|
103
|
+
return inst
|
|
104
|
+
else
|
|
105
|
+
return nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def list_instances(credentials, id)
|
|
111
|
+
instances = []
|
|
112
|
+
safely do
|
|
113
|
+
new_client(credentials).request('grid/server/list')['list'].collect do |instance|
|
|
114
|
+
if id.nil? or instance['name'] == id
|
|
115
|
+
instances << convert_instance(instance, credentials.user)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
instances
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def instances(credentials, opts=nil)
|
|
123
|
+
require 'ap'
|
|
124
|
+
instances = []
|
|
125
|
+
if opts and opts[:id]
|
|
126
|
+
begin
|
|
127
|
+
client = new_client(credentials)
|
|
128
|
+
instance = client.request('grid/server/get', { 'name' => opts[:id] })['list'].first
|
|
129
|
+
login_data = get_login_data(client, instance['id'])
|
|
130
|
+
if login_data['username'] and login_data['password']
|
|
131
|
+
instance['username'] = login_data['username']
|
|
132
|
+
instance['password'] = login_data['password']
|
|
133
|
+
inst = convert_instance(instance, credentials.user)
|
|
134
|
+
else
|
|
135
|
+
inst = convert_instance(instance, credentials.user)
|
|
136
|
+
inst.authn_error = "Unable to fetch password"
|
|
137
|
+
end
|
|
138
|
+
instances = [inst]
|
|
139
|
+
rescue Exception => e
|
|
140
|
+
if e.message == "400 Bad Request"
|
|
141
|
+
# in the case of a VM that we just made, the grid/server/get method
|
|
142
|
+
# throws a "400 Bad Request error". In this case we try again by
|
|
143
|
+
# getting a full listing a filtering on the id. This could
|
|
144
|
+
# potentially take a long time, but I don't see another way to get
|
|
145
|
+
# information about a newly created instance
|
|
146
|
+
instances = list_instances(credentials, opts[:id])
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
else
|
|
150
|
+
instances = list_instances(credentials, nil)
|
|
151
|
+
end
|
|
152
|
+
instances = filter_on( instances, :state, opts )
|
|
153
|
+
instances
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def reboot_instance(credentials, id)
|
|
157
|
+
safely do
|
|
158
|
+
new_client(credentials).request('grid/server/power', { 'name' => id, 'power' => 'reboot'})
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def destroy_instance(credentials, id)
|
|
163
|
+
safely do
|
|
164
|
+
new_client(credentials).request('grid/server/delete', { 'name' => id})
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def stop_instance(credentials, id)
|
|
169
|
+
safely do
|
|
170
|
+
new_client(credentials).request('grid/server/power', { 'name' => id, 'power' => 'off'})
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def start_instance(credentials, id)
|
|
175
|
+
safely do
|
|
176
|
+
new_client(credentials).request('grid/server/power', { 'name' => id, 'power' => 'on'})
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def key(credentials, opts=nil)
|
|
181
|
+
keys(credentials, opts).first
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def keys(credentials, opts=nil)
|
|
185
|
+
gogrid = new_client( credentials )
|
|
186
|
+
creds = []
|
|
187
|
+
safely do
|
|
188
|
+
gogrid.request('support/password/list')['list'].each do |password|
|
|
189
|
+
creds << convert_key(password)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
return creds
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
define_instance_states do
|
|
196
|
+
start.to( :pending ) .automatically
|
|
197
|
+
pending.to( :running ) .automatically
|
|
198
|
+
running.to( :stopped ) .on( :stop )
|
|
199
|
+
stopped.to( :running ) .on( :start )
|
|
200
|
+
running.to( :finish ) .on( :destroy )
|
|
201
|
+
stopped.to( :finish ) .on( :destroy )
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
private
|
|
205
|
+
|
|
206
|
+
def new_client(credentials)
|
|
207
|
+
GoGridClient.new('https://api.gogrid.com/api', credentials.user, credentials.password)
|
|
208
|
+
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def get_login_data(client, instance_id)
|
|
212
|
+
login_data = {}
|
|
213
|
+
begin
|
|
214
|
+
client.request('support/password/list')['list'].each do |passwd|
|
|
215
|
+
next unless passwd['server']
|
|
216
|
+
if passwd['server']['id'] == instance_id
|
|
217
|
+
login_data['username'], login_data['password'] = passwd['username'], passwd['password']
|
|
218
|
+
break
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
rescue Exception => e
|
|
222
|
+
login_data[:error] = e.message
|
|
223
|
+
end
|
|
224
|
+
return login_data
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def convert_key(password)
|
|
228
|
+
Key.new({
|
|
229
|
+
:id => password['id'],
|
|
230
|
+
:username => password['username'],
|
|
231
|
+
:password => password['password'],
|
|
232
|
+
:credential_type => :password
|
|
233
|
+
})
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def convert_image(gg_image, owner_id=nil)
|
|
237
|
+
Image.new( {
|
|
238
|
+
:id=>gg_image['id'],
|
|
239
|
+
:name => gg_image['friendlyName'],
|
|
240
|
+
:description=> convert_description(gg_image),
|
|
241
|
+
:owner_id=>gg_image['owner']['name'],
|
|
242
|
+
:architecture=>convert_arch(gg_image['description']),
|
|
243
|
+
} )
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def convert_description(image)
|
|
247
|
+
if image['price'].eql?(0)
|
|
248
|
+
image['description']
|
|
249
|
+
else
|
|
250
|
+
"#{image['description']} (#{image['price']}$)"
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def convert_realm(realm)
|
|
255
|
+
Realm.new(
|
|
256
|
+
:id => realm['id'],
|
|
257
|
+
:name => realm['name'],
|
|
258
|
+
:state => :unlimited,
|
|
259
|
+
:storage => :unlimited
|
|
260
|
+
)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def convert_arch(description)
|
|
264
|
+
description.include?('64-bit') ? 'x86_64' : 'i386'
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def convert_instance(instance, owner_id)
|
|
268
|
+
opts = {}
|
|
269
|
+
unless instance['ram']['id'] == "1"
|
|
270
|
+
mem = instance['ram']['name']
|
|
271
|
+
if mem == "512MB"
|
|
272
|
+
opts[:hwp_memory] = "512"
|
|
273
|
+
else
|
|
274
|
+
opts[:hwp_memory] = (mem.to_i * 1024).to_s
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
prof = InstanceProfile.new("server", opts)
|
|
278
|
+
|
|
279
|
+
Instance.new(
|
|
280
|
+
# note that we use 'name' as the id here, because newly created instances
|
|
281
|
+
# don't get a real ID until later on. The name is good enough; from
|
|
282
|
+
# what I can tell, 'name' per user is unique, so it should be sufficient
|
|
283
|
+
# to uniquely identify this instance.
|
|
284
|
+
:id => instance['name'],
|
|
285
|
+
:owner_id => owner_id,
|
|
286
|
+
:image_id => instance['image']['id'],
|
|
287
|
+
:instance_profile => prof,
|
|
288
|
+
:name => instance['name'],
|
|
289
|
+
:realm_id => instance['ip']['datacenter']['id'],
|
|
290
|
+
:state => convert_server_state(instance['state']['name'], instance['id']),
|
|
291
|
+
:actions => instance_actions_for(convert_server_state(instance['state']['name'], instance['id'])),
|
|
292
|
+
:public_addresses => [ instance['ip']['ip'] ],
|
|
293
|
+
:private_addresses => [],
|
|
294
|
+
:username => instance['username'],
|
|
295
|
+
:password => instance['password']
|
|
296
|
+
)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def get_random_instance_name
|
|
300
|
+
"Server #{Time.now.to_i.to_s.reverse[0..3]}#{rand(9)}"
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def convert_server_state(state, id)
|
|
304
|
+
return 'PENDING' unless id
|
|
305
|
+
state.eql?('Off') ? 'STOPPED' : 'RUNNING'
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def get_free_ip_from_realm(credentials, realm_id)
|
|
309
|
+
ip = ""
|
|
310
|
+
safely do
|
|
311
|
+
ip = new_client(credentials).request('grid/ip/list', {
|
|
312
|
+
'ip.type' => '1',
|
|
313
|
+
'ip.state' => '1',
|
|
314
|
+
'datacenter' => realm_id
|
|
315
|
+
})['list'].first['ip']
|
|
316
|
+
end
|
|
317
|
+
return ip
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def safely(&block)
|
|
321
|
+
begin
|
|
322
|
+
block.call
|
|
323
|
+
rescue Exception => e
|
|
324
|
+
raise Deltacloud::BackendError.new(500, e.class.to_s, e.message, e.backtrace)
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'gogrid_client'
|
|
2
|
+
require 'ap'
|
|
3
|
+
|
|
4
|
+
user='fbb1de3897597ccf'
|
|
5
|
+
password='ngieth10'
|
|
6
|
+
|
|
7
|
+
client=GoGridClient.new('https://api.gogrid.com/api', user, password)
|
|
8
|
+
|
|
9
|
+
ap client.request('grid/ip/list', {
|
|
10
|
+
'ip.type' => '1',
|
|
11
|
+
'ip.state' => '1',
|
|
12
|
+
'datacenter' => '1'
|
|
13
|
+
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
:realm_id: us
|
|
3
|
+
:public_addresses:
|
|
4
|
+
- img1.inst0.public.com
|
|
5
|
+
:state: RUNNING
|
|
6
|
+
:name: "Mock Instance With Profile Change"
|
|
7
|
+
:private_addresses:
|
|
8
|
+
- img1.inst0.private.com
|
|
9
|
+
:image_id: img1
|
|
10
|
+
:instance_profile: !ruby/object:InstanceProfile
|
|
11
|
+
id: m1-large
|
|
12
|
+
memory: "12288"
|
|
13
|
+
:owner_id: mockuser
|
|
14
|
+
:actions:
|
|
15
|
+
- :reboot
|
|
16
|
+
- :stop
|