bosh_cpi_networking 2.5
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.
- checksums.yaml +7 -0
- data/lib/bosh/cpi.rb +8 -0
- data/lib/bosh/cpi/cli.rb +147 -0
- data/lib/bosh/cpi/compatibility_helpers.rb +5 -0
- data/lib/bosh/cpi/compatibility_helpers/delete_vm.rb +15 -0
- data/lib/bosh/cpi/logger.rb +15 -0
- data/lib/bosh/cpi/redactor.rb +32 -0
- data/lib/bosh/cpi/registry_client.rb +107 -0
- data/lib/bosh/cpi/tasks.rb +1 -0
- data/lib/bosh/cpi/tasks/spec.rake +10 -0
- data/lib/cloud.rb +259 -0
- data/lib/cloud/config.rb +17 -0
- data/lib/cloud/errors.rb +21 -0
- data/lib/cloud/version.rb +5 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 80456c92fa86f1e403aa2c5c9db8da44b91cb51b
|
4
|
+
data.tar.gz: 31d96dfaae8ba996c5878e405d0c0445cbc19dfb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3905e313c73b7ed04f3b1974562b5e0b1200433da41315b2759c8ab1ae8cf6c0cb3d003c3612659da560b28b5563542041e978ac4cb1d95e00aa2fb117c95a2a
|
7
|
+
data.tar.gz: a4fa23dece8e65f1f062cd82f92cc5f56dc7932ffd40e3f7638a7ba3289ca9b0ce0c756c56bd5983d375292ff1e6a52865c0f7d0f818e86653fd9b036b2d55db
|
data/lib/bosh/cpi.rb
ADDED
data/lib/bosh/cpi/cli.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Bosh::Cpi::Cli
|
4
|
+
KNOWN_RPC_METHODS = %w(
|
5
|
+
info
|
6
|
+
current_vm_id
|
7
|
+
create_stemcell
|
8
|
+
delete_stemcell
|
9
|
+
create_vm
|
10
|
+
delete_vm
|
11
|
+
has_vm
|
12
|
+
reboot_vm
|
13
|
+
set_vm_metadata
|
14
|
+
set_disk_metadata
|
15
|
+
create_disk
|
16
|
+
has_disk
|
17
|
+
delete_disk
|
18
|
+
attach_disk
|
19
|
+
detach_disk
|
20
|
+
snapshot_disk
|
21
|
+
delete_snapshot
|
22
|
+
get_disks
|
23
|
+
resize_disk
|
24
|
+
ping
|
25
|
+
calculate_vm_cloud_properties
|
26
|
+
create_subnet
|
27
|
+
delete_subnet
|
28
|
+
has_subnet
|
29
|
+
set_subnet_metadata
|
30
|
+
).freeze
|
31
|
+
|
32
|
+
RPC_METHOD_TO_RUBY_METHOD = {
|
33
|
+
'has_vm' => 'has_vm?',
|
34
|
+
'has_disk' => 'has_disk?',
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
INVALID_CALL_ERROR_TYPE = 'InvalidCall'.freeze
|
38
|
+
UNKNOWN_ERROR_TYPE = 'Unknown'.freeze
|
39
|
+
|
40
|
+
def initialize(cpi, logs_string_io, result_io)
|
41
|
+
@cpi = cpi
|
42
|
+
@logs_string_io = logs_string_io
|
43
|
+
@result_io = result_io
|
44
|
+
@logger = Bosh::Cpi::Logger.new(STDERR)
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(json)
|
48
|
+
begin
|
49
|
+
request = JSON.load(json)
|
50
|
+
rescue JSON::ParserError => e
|
51
|
+
return error_response(INVALID_CALL_ERROR_TYPE, "Request cannot be deserialized, details: #{e.message}", false, e.backtrace)
|
52
|
+
end
|
53
|
+
|
54
|
+
method = request['method']
|
55
|
+
unless method.is_a?(String)
|
56
|
+
return error_response(INVALID_CALL_ERROR_TYPE, "Method must be a String, got: '#{method.inspect}'", false)
|
57
|
+
end
|
58
|
+
|
59
|
+
unless KNOWN_RPC_METHODS.include?(method)
|
60
|
+
return error_response(Bosh::Clouds::NotImplemented.name, "Method is not known, got: '#{method}'", false)
|
61
|
+
end
|
62
|
+
|
63
|
+
arguments = request['arguments']
|
64
|
+
unless arguments.is_a?(Array)
|
65
|
+
return error_response(INVALID_CALL_ERROR_TYPE, "Arguments must be an Array", false)
|
66
|
+
end
|
67
|
+
|
68
|
+
context = request['context']
|
69
|
+
unless context.is_a?(Hash) && context['director_uuid'].is_a?(String)
|
70
|
+
return error_response(INVALID_CALL_ERROR_TYPE, "Request should include context with director uuid", false)
|
71
|
+
end
|
72
|
+
|
73
|
+
req_id = context['request_id']
|
74
|
+
@logger.set_request_id(req_id)
|
75
|
+
|
76
|
+
configure_director(context['director_uuid'])
|
77
|
+
|
78
|
+
ruby_method = RPC_METHOD_TO_RUBY_METHOD[method] || method
|
79
|
+
|
80
|
+
begin
|
81
|
+
start_time = Time.now.utc
|
82
|
+
@logger.info("Starting #{method}...")
|
83
|
+
|
84
|
+
cpi = @cpi.call(context)
|
85
|
+
|
86
|
+
result = cpi.public_send(ruby_method, *arguments)
|
87
|
+
rescue Bosh::Clouds::RetriableCloudError => e
|
88
|
+
return error_response(error_name(e), e.message, e.ok_to_retry, e.backtrace)
|
89
|
+
rescue Bosh::Clouds::CloudError, Bosh::Clouds::CpiError => e
|
90
|
+
return error_response(error_name(e), e.message, false, e.backtrace)
|
91
|
+
rescue ArgumentError => e
|
92
|
+
return error_response(INVALID_CALL_ERROR_TYPE, "Arguments are not correct, details: '#{e.message}'", false, e.backtrace)
|
93
|
+
rescue Exception => e
|
94
|
+
return error_response(UNKNOWN_ERROR_TYPE, e.message, false, e.backtrace)
|
95
|
+
ensure
|
96
|
+
end_time = Time.now.utc
|
97
|
+
@logger.info("Finished #{method} in #{(end_time - start_time).round(2)} seconds")
|
98
|
+
end
|
99
|
+
|
100
|
+
result_response(result)
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def configure_director(director_uuid)
|
106
|
+
Bosh::Clouds::Config.uuid = director_uuid
|
107
|
+
end
|
108
|
+
|
109
|
+
def error_response(type, message, ok_to_retry, bt=[])
|
110
|
+
if !bt.empty?
|
111
|
+
@logs_string_io.print("Rescued #{type}: #{message}. backtrace: #{bt.join("\n")}")
|
112
|
+
end
|
113
|
+
|
114
|
+
hash = {
|
115
|
+
result: nil,
|
116
|
+
error: {
|
117
|
+
type: type,
|
118
|
+
message: message,
|
119
|
+
ok_to_retry: ok_to_retry,
|
120
|
+
},
|
121
|
+
log: encode_string_as_utf8(@logs_string_io.string)
|
122
|
+
}
|
123
|
+
@result_io.print(JSON.dump(hash)); nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def result_response(result)
|
127
|
+
hash = {
|
128
|
+
result: result,
|
129
|
+
error: nil,
|
130
|
+
log: encode_string_as_utf8(@logs_string_io.string)
|
131
|
+
}
|
132
|
+
@result_io.print(JSON.dump(hash)); nil
|
133
|
+
end
|
134
|
+
|
135
|
+
def error_name(error)
|
136
|
+
error.class.name
|
137
|
+
end
|
138
|
+
|
139
|
+
def encode_string_as_utf8(src)
|
140
|
+
log = @logs_string_io.string.force_encoding(Encoding::UTF_8)
|
141
|
+
unless log.valid_encoding?
|
142
|
+
# the src encoding hint of Encoding::BINARY is only required for ruby 1.9.3
|
143
|
+
log = @logs_string_io.string.encode(Encoding::UTF_8, Encoding::BINARY, undef: :replace, invalid: :replace)
|
144
|
+
end
|
145
|
+
log
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'bosh/cpi/compatibility_helpers'
|
2
|
+
|
3
|
+
module Bosh::Cpi::CompatibilityHelpers
|
4
|
+
def it_can_delete_non_existent_vm(vm_cid='vm-cid')
|
5
|
+
describe "delete_vm (deleting non existent vm)" do
|
6
|
+
context "when VM is not present" do
|
7
|
+
it "raises VMNotFound error" do
|
8
|
+
expect {
|
9
|
+
cpi.delete_vm(vm_cid)
|
10
|
+
}.to raise_error(Bosh::Clouds::VMNotFound, "VM '#{vm_cid}' not found")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
class Bosh::Cpi::Logger < Logger
|
4
|
+
|
5
|
+
def initialize(log_device)
|
6
|
+
super(log_device)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_request_id(req_id)
|
10
|
+
original_formatter = Logger::Formatter.new
|
11
|
+
self.formatter = proc { |severity, datetime, progname, msg|
|
12
|
+
original_formatter.call(severity, datetime, "[req_id #{req_id}]#{progname}", msg)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Bosh::Cpi
|
2
|
+
class Redactor
|
3
|
+
|
4
|
+
REDACTED = '<redacted>'
|
5
|
+
|
6
|
+
def self.clone_and_redact(hash, *paths)
|
7
|
+
begin
|
8
|
+
hash = JSON.parse(hash.to_json)
|
9
|
+
rescue
|
10
|
+
return nil
|
11
|
+
end
|
12
|
+
|
13
|
+
redact!(hash, *paths)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.redact!(hash, *json_paths)
|
17
|
+
json_paths.each do |json_path|
|
18
|
+
properties = json_path.split('.')
|
19
|
+
property_to_redact = properties.pop
|
20
|
+
|
21
|
+
target_hash = properties.reduce(hash, &fetch_property)
|
22
|
+
target_hash[property_to_redact] = REDACTED if target_hash.has_key? property_to_redact
|
23
|
+
end
|
24
|
+
|
25
|
+
hash
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.fetch_property
|
29
|
+
-> (hash, property) { hash.fetch(property, {})}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'cloud/errors'
|
2
|
+
require 'httpclient'
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Bosh::Cpi
|
7
|
+
class RegistryClient
|
8
|
+
attr_reader :endpoint
|
9
|
+
attr_reader :user
|
10
|
+
attr_reader :password
|
11
|
+
|
12
|
+
def initialize(endpoint, user, password)
|
13
|
+
@endpoint = endpoint
|
14
|
+
|
15
|
+
unless @endpoint =~ /^http:\/\//
|
16
|
+
@endpoint = "http://#{@endpoint}"
|
17
|
+
end
|
18
|
+
|
19
|
+
@user = user
|
20
|
+
@password = password
|
21
|
+
|
22
|
+
auth = Base64.encode64("#{@user}:#{@password}").gsub("\n", '')
|
23
|
+
|
24
|
+
@headers = {
|
25
|
+
"Accept" => 'application/json',
|
26
|
+
"Authorization" => "Basic #{auth}"
|
27
|
+
}
|
28
|
+
|
29
|
+
@client = HTTPClient.new
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Update instance settings in the registry
|
34
|
+
# @param [String] instance_id EC2 instance id
|
35
|
+
# @param [Hash] settings New agent settings
|
36
|
+
# @return [Boolean]
|
37
|
+
def update_settings(instance_id, settings)
|
38
|
+
unless settings.is_a?(Hash)
|
39
|
+
raise ArgumentError, "Invalid settings format, Hash expected, #{settings.class} given"
|
40
|
+
end
|
41
|
+
|
42
|
+
payload = JSON.dump(settings)
|
43
|
+
url = "#{@endpoint}/instances/#{instance_id}/settings"
|
44
|
+
put_headers = @headers.merge('Content-Type' => 'application/json')
|
45
|
+
|
46
|
+
response = @client.put(url, {:body => payload, :header => put_headers})
|
47
|
+
|
48
|
+
unless HTTP::Status.successful?(response.status)
|
49
|
+
cloud_error("Cannot update settings for '#{instance_id}', got HTTP #{response.status}")
|
50
|
+
end
|
51
|
+
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Read instance settings from the registry
|
57
|
+
# @param [String] instance_id EC2 instance id
|
58
|
+
# @return [Hash] Agent settings
|
59
|
+
def read_settings(instance_id)
|
60
|
+
url = "#{@endpoint}/instances/#{instance_id}/settings"
|
61
|
+
|
62
|
+
response = @client.get(url, {:header => @headers})
|
63
|
+
|
64
|
+
if response.status != 200
|
65
|
+
cloud_error("Cannot read settings for '#{instance_id}', got HTTP #{response.status}")
|
66
|
+
end
|
67
|
+
|
68
|
+
body = JSON.load(response.body)
|
69
|
+
|
70
|
+
unless body.is_a?(Hash)
|
71
|
+
cloud_error("Invalid registry response, Hash expected, got #{body.class}: #{body}")
|
72
|
+
end
|
73
|
+
|
74
|
+
settings = JSON.load(body["settings"])
|
75
|
+
|
76
|
+
unless settings.is_a?(Hash)
|
77
|
+
cloud_error("Invalid settings format, Hash expected, got #{settings.class}: #{settings}")
|
78
|
+
end
|
79
|
+
|
80
|
+
settings
|
81
|
+
rescue JSON::ParserError => e
|
82
|
+
cloud_error("Cannot parse settings for '#{instance_id}': #{e.message}")
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Delete instance settings from the registry
|
87
|
+
# @param [String] instance_id EC2 instance id
|
88
|
+
# @return [Boolean]
|
89
|
+
def delete_settings(instance_id)
|
90
|
+
url = "#{@endpoint}/instances/#{instance_id}/settings"
|
91
|
+
|
92
|
+
response = @client.delete(url, {:header => @headers})
|
93
|
+
|
94
|
+
unless [200, 404].include? response.status
|
95
|
+
cloud_error("Cannot delete settings for '#{instance_id}', got HTTP #{response.status}")
|
96
|
+
end
|
97
|
+
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def cloud_error(message)
|
104
|
+
raise Bosh::Clouds::CloudError, message
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Dir.glob(File.expand_path('tasks/**/*.rake', File.dirname(__FILE__))).each { |r| import r }
|
data/lib/cloud.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh; module Clouds; end; end
|
4
|
+
|
5
|
+
require "forwardable"
|
6
|
+
|
7
|
+
require "cloud/config"
|
8
|
+
require "cloud/errors"
|
9
|
+
|
10
|
+
module Bosh
|
11
|
+
|
12
|
+
##
|
13
|
+
# CPI - Cloud Provider Interface, used for interfacing with various IaaS APIs.
|
14
|
+
#
|
15
|
+
# Key terms:
|
16
|
+
# Stemcell: template used for creating VMs (shouldn't be powered on)
|
17
|
+
# VM: VM created from a stemcell with custom settings (networking and resources)
|
18
|
+
# Disk: volume that can be attached and detached from the VMs,
|
19
|
+
# never attached to more than a single VM at one time
|
20
|
+
class Cloud
|
21
|
+
|
22
|
+
##
|
23
|
+
# Cloud initialization
|
24
|
+
#
|
25
|
+
# @param [Hash] options cloud options
|
26
|
+
def initialize(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
## Information about cpi
|
30
|
+
#
|
31
|
+
# Sample info response:
|
32
|
+
# {"stemcell_formats" =>
|
33
|
+
# ["aws-raw", "aws-light"]
|
34
|
+
# }
|
35
|
+
# @return [Hash] information about cpi, currently stemcell formats, which are supported
|
36
|
+
def info
|
37
|
+
not_implemented(:info)
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Get the vm_id of this host
|
42
|
+
#
|
43
|
+
# @return [String] opaque id later used by other methods of the CPI
|
44
|
+
def current_vm_id
|
45
|
+
not_implemented(:current_vm_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Creates a stemcell
|
50
|
+
#
|
51
|
+
# @param [String] image_path path to an opaque blob containing the stemcell image
|
52
|
+
# @param [Hash] cloud_properties properties required for creating this template
|
53
|
+
# specific to a CPI
|
54
|
+
# @return [String] opaque id later used by {#create_vm} and {#delete_stemcell}
|
55
|
+
def create_stemcell(image_path, cloud_properties)
|
56
|
+
not_implemented(:create_stemcell)
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Deletes a stemcell
|
61
|
+
#
|
62
|
+
# @param [String] stemcell stemcell id that was once returned by {#create_stemcell}
|
63
|
+
# @return [void]
|
64
|
+
def delete_stemcell(stemcell_id)
|
65
|
+
not_implemented(:delete_stemcell)
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Creates a VM - creates (and powers on) a VM from a stemcell with the proper resources
|
70
|
+
# and on the specified network. When disk locality is present the VM will be placed near
|
71
|
+
# the provided disk so it won't have to move when the disk is attached later.
|
72
|
+
#
|
73
|
+
# Sample networking config:
|
74
|
+
# {"network_a" =>
|
75
|
+
# {
|
76
|
+
# "netmask" => "255.255.248.0",
|
77
|
+
# "ip" => "172.30.41.40",
|
78
|
+
# "gateway" => "172.30.40.1",
|
79
|
+
# "dns" => ["172.30.22.153", "172.30.22.154"],
|
80
|
+
# "cloud_properties" => {"name" => "VLAN444"}
|
81
|
+
# }
|
82
|
+
# }
|
83
|
+
#
|
84
|
+
# Sample resource pool config (CPI specific):
|
85
|
+
# {
|
86
|
+
# "ram" => 512,
|
87
|
+
# "disk" => 512,
|
88
|
+
# "cpu" => 1
|
89
|
+
# }
|
90
|
+
# or similar for EC2:
|
91
|
+
# {"name" => "m1.small"}
|
92
|
+
#
|
93
|
+
# @param [String] agent_id UUID for the agent that will be used later on by the director
|
94
|
+
# to locate and talk to the agent
|
95
|
+
# @param [String] stemcell stemcell id that was once returned by {#create_stemcell}
|
96
|
+
# @param [Hash] resource_pool cloud specific properties describing the resources needed
|
97
|
+
# for this VM
|
98
|
+
# @param [Hash] networks list of networks and their settings needed for this VM
|
99
|
+
# @param [String, Array] disk_locality disk id(s) if known of the disk(s) that will be
|
100
|
+
# attached to this vm
|
101
|
+
# @param [Hash] env environment that will be passed to this vm
|
102
|
+
# @return [String] opaque id later used by {#attach_disk}, {#detach_disk} and {#delete_vm}
|
103
|
+
def create_vm(agent_id, stemcell_id, resource_pool,
|
104
|
+
networks, disk_locality, env)
|
105
|
+
not_implemented(:create_vm)
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Deletes a VM. If the VM has already been deleted, this call returns normally and has no effect.
|
110
|
+
#
|
111
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
112
|
+
# @return [void]
|
113
|
+
def delete_vm(vm_id)
|
114
|
+
not_implemented(:delete_vm)
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Checks if a VM exists
|
119
|
+
#
|
120
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
121
|
+
# @return [Boolean] True if the vm exists
|
122
|
+
def has_vm?(vm_id)
|
123
|
+
not_implemented(:has_vm?)
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
# Checks if a disk exists
|
128
|
+
#
|
129
|
+
# @param [String] disk disk_id that was once returned by {#create_disk}
|
130
|
+
# @return [Boolean] True if the disk exists
|
131
|
+
def has_disk?(disk_id)
|
132
|
+
not_implemented(:has_disk?)
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Reboots a VM
|
137
|
+
#
|
138
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
139
|
+
# @param [Optional, Hash] CPI specific options (e.g hard/soft reboot)
|
140
|
+
# @return [void]
|
141
|
+
def reboot_vm(vm_id)
|
142
|
+
not_implemented(:reboot_vm)
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Set metadata for a VM
|
147
|
+
#
|
148
|
+
# Optional. Implement to provide more information for the IaaS.
|
149
|
+
#
|
150
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
151
|
+
# @param [Hash] metadata metadata key/value pairs
|
152
|
+
# @return [void]
|
153
|
+
def set_vm_metadata(vm, metadata)
|
154
|
+
not_implemented(:set_vm_metadata)
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# Set metadata for a disk
|
159
|
+
#
|
160
|
+
# Optional. Implement to provide more information for the IaaS.
|
161
|
+
#
|
162
|
+
# @param [String] disk_id disk id that was once returned by {#create_disk}
|
163
|
+
# @param [Hash] metadata metadata key/value pairs
|
164
|
+
# @return [void]
|
165
|
+
def set_disk_metadata(disk_id, metadata)
|
166
|
+
not_implemented(:set_disk_metadata)
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
170
|
+
# Creates a disk (possibly lazily) that will be attached later to a VM. When
|
171
|
+
# VM locality is specified the disk will be placed near the VM so it won't have to move
|
172
|
+
# when it's attached later.
|
173
|
+
#
|
174
|
+
# @param [Integer] size disk size in MB
|
175
|
+
# @param [Hash] cloud_properties properties required for creating this disk
|
176
|
+
# specific to a CPI
|
177
|
+
# @param [String] vm_locality vm id if known of the VM that this disk will
|
178
|
+
# be attached to
|
179
|
+
# @return [String] opaque id later used by {#attach_disk}, {#detach_disk}, and {#delete_disk}
|
180
|
+
def create_disk(size, cloud_properties, vm_locality)
|
181
|
+
not_implemented(:create_disk)
|
182
|
+
end
|
183
|
+
|
184
|
+
##
|
185
|
+
# Deletes a disk
|
186
|
+
# Will raise an exception if the disk is attached to a VM
|
187
|
+
#
|
188
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
189
|
+
# @return [void]
|
190
|
+
def delete_disk(disk_id)
|
191
|
+
not_implemented(:delete_disk)
|
192
|
+
end
|
193
|
+
|
194
|
+
# Attaches a disk
|
195
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
196
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
197
|
+
# @return [void]
|
198
|
+
def attach_disk(vm_id, disk_id)
|
199
|
+
not_implemented(:attach_disk)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Take snapshot of disk
|
203
|
+
# @param [String] disk_id disk id of the disk to take the snapshot of
|
204
|
+
# @param [Hash] metadata metadata key/value pairs
|
205
|
+
# @return [String] snapshot id
|
206
|
+
def snapshot_disk(disk_id, metadata)
|
207
|
+
not_implemented(:snapshot_disk)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Delete a disk snapshot
|
211
|
+
# @param [String] snapshot_id snapshot id to delete
|
212
|
+
# @return [void]
|
213
|
+
def delete_snapshot(snapshot_id)
|
214
|
+
not_implemented(:delete_snapshot)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Detaches a disk
|
218
|
+
# @param [String] vm vm id that was once returned by {#create_vm}
|
219
|
+
# @param [String] disk disk id that was once returned by {#create_disk}
|
220
|
+
# @return [void]
|
221
|
+
def detach_disk(vm_id, disk_id)
|
222
|
+
not_implemented(:detach_disk)
|
223
|
+
end
|
224
|
+
|
225
|
+
# List the attached disks of the VM.
|
226
|
+
# @param [String] vm_id is the CPI-standard vm_id (eg, returned from current_vm_id)
|
227
|
+
# @return [array[String]] list of opaque disk_ids that can be used with the
|
228
|
+
# other disk-related methods on the CPI
|
229
|
+
def get_disks(vm_id)
|
230
|
+
not_implemented(:get_disks)
|
231
|
+
end
|
232
|
+
|
233
|
+
##
|
234
|
+
# Resizes an existing disk
|
235
|
+
#
|
236
|
+
# @param [String] disk_id disk id
|
237
|
+
# @param [Integer] new_size disk size in MiB
|
238
|
+
# @return [void]
|
239
|
+
def resize_disk(disk_id, new_size)
|
240
|
+
not_implemented(:resize_disk)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Specify VM's hardware resources
|
244
|
+
# @param [Hash] vm_properties (typically cpu, ram, ephemeral_disk_size)
|
245
|
+
# @return [Hash] opaque description of the VM's configuration that
|
246
|
+
# can be used with {#create_vm}
|
247
|
+
def calculate_vm_cloud_properties(vm_properties)
|
248
|
+
not_implemented(:calculate_vm_cloud_properties)
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
def not_implemented(method)
|
254
|
+
raise Bosh::Clouds::NotImplemented,
|
255
|
+
"'#{method}' is not implemented by #{self.class}"
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
end
|
data/lib/cloud/config.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Bosh::Clouds
|
4
|
+
class Config
|
5
|
+
|
6
|
+
class << self
|
7
|
+
extend Forwardable
|
8
|
+
def_delegators :@delegate, :db, :logger, :uuid, :uuid=, :task_checkpoint, :cpi_task_log
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param [Bosh::Director::Config] config director config file
|
12
|
+
def self.configure(config)
|
13
|
+
@delegate = config
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/cloud/errors.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bosh::Clouds
|
2
|
+
class CpiError < StandardError; end
|
3
|
+
class NotImplemented < CpiError; end
|
4
|
+
class NotSupported < CpiError; end
|
5
|
+
|
6
|
+
class CloudError < StandardError; end
|
7
|
+
class VMNotFound < CloudError; end
|
8
|
+
|
9
|
+
class RetriableCloudError < CloudError
|
10
|
+
attr_accessor :ok_to_retry
|
11
|
+
|
12
|
+
def initialize(ok_to_retry)
|
13
|
+
@ok_to_retry = ok_to_retry
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class NoDiskSpace < RetriableCloudError; end
|
18
|
+
class DiskNotAttached < RetriableCloudError; end
|
19
|
+
class DiskNotFound < RetriableCloudError; end
|
20
|
+
class VMCreationFailed < RetriableCloudError; end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bosh_cpi_networking
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '2.5'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- VMware
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-04-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: membrane
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httpclient
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.8.3
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.8.3
|
41
|
+
description: BOSH CPI with network management support
|
42
|
+
email: support@cloudfoundry.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- lib/bosh/cpi.rb
|
48
|
+
- lib/bosh/cpi/cli.rb
|
49
|
+
- lib/bosh/cpi/compatibility_helpers.rb
|
50
|
+
- lib/bosh/cpi/compatibility_helpers/delete_vm.rb
|
51
|
+
- lib/bosh/cpi/logger.rb
|
52
|
+
- lib/bosh/cpi/redactor.rb
|
53
|
+
- lib/bosh/cpi/registry_client.rb
|
54
|
+
- lib/bosh/cpi/tasks.rb
|
55
|
+
- lib/bosh/cpi/tasks/spec.rake
|
56
|
+
- lib/cloud.rb
|
57
|
+
- lib/cloud/config.rb
|
58
|
+
- lib/cloud/errors.rb
|
59
|
+
- lib/cloud/version.rb
|
60
|
+
homepage: https://github.com/medvedzver/bosh-cpi-ruby
|
61
|
+
licenses:
|
62
|
+
- Apache 2.0
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.9.3
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.5.1
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: BOSH CPI with network management support
|
84
|
+
test_files: []
|