mirror of
https://github.com/fog/fog-aws.git
synced 2022-11-09 13:50:52 -05:00
create, describe, and destroy elastic file systems
This commit is contained in:
parent
df01e7bc24
commit
98f3af916e
10 changed files with 439 additions and 0 deletions
|
@ -36,6 +36,7 @@ module Fog
|
|||
autoload :DataPipeline, File.expand_path('../aws/data_pipeline', __FILE__)
|
||||
autoload :DynamoDB, File.expand_path('../aws/dynamodb', __FILE__)
|
||||
autoload :ECS, File.expand_path('../aws/ecs', __FILE__)
|
||||
autoload :EFS, File.expand_path('../aws/efs', __FILE__)
|
||||
autoload :ELB, File.expand_path('../aws/elb', __FILE__)
|
||||
autoload :EMR, File.expand_path('../aws/emr', __FILE__)
|
||||
autoload :ElasticBeanstalk, File.expand_path('../aws/beanstalk', __FILE__)
|
||||
|
@ -66,6 +67,7 @@ module Fog
|
|||
service(:dynamodb, 'DynamoDB')
|
||||
service(:elasticache, 'Elasticache')
|
||||
service(:ecs, 'ECS')
|
||||
service(:efs, 'EFS')
|
||||
service(:elb, 'ELB')
|
||||
service(:emr, 'EMR')
|
||||
service(:federation, 'Federation')
|
||||
|
|
147
lib/fog/aws/efs.rb
Normal file
147
lib/fog/aws/efs.rb
Normal file
|
@ -0,0 +1,147 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class EFS < Fog::Service
|
||||
extend Fog::AWS::CredentialFetcher::ServiceMethods
|
||||
|
||||
class FileSystemInUse < Fog::Errors::Error; end
|
||||
|
||||
requires :aws_access_key_id, :aws_secret_access_key
|
||||
|
||||
model_path 'fog/aws/models/efs'
|
||||
request_path 'fog/aws/requests/efs'
|
||||
|
||||
model :file_system
|
||||
collection :file_systems
|
||||
|
||||
request :create_file_system
|
||||
request :delete_file_system
|
||||
request :describe_file_systems
|
||||
|
||||
class Mock
|
||||
def self.data
|
||||
@data ||= Hash.new do |hash, region|
|
||||
hash[region] = Hash.new do |region_hash, key|
|
||||
region_hash[key] = {
|
||||
:file_systems => {}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@data = nil
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@region][@aws_access_key_id]
|
||||
end
|
||||
|
||||
def reset
|
||||
self.class.reset
|
||||
end
|
||||
|
||||
attr_accessor :region
|
||||
|
||||
def initialize(options={})
|
||||
@region = options[:region] || "us-east-1"
|
||||
end
|
||||
end
|
||||
|
||||
class Real
|
||||
include Fog::AWS::CredentialFetcher::ConnectionMethods
|
||||
|
||||
def initialize(options={})
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@instrumentor = options[:instrumentor]
|
||||
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.efs'
|
||||
|
||||
@region = 'us-east-1'
|
||||
@host = options[:host] || "elasticfilesystem.#{@region}.amazonaws.com"
|
||||
@port = options[:port] || 443
|
||||
@scheme = options[:scheme] || "https"
|
||||
@persistent = options[:persistent] || false
|
||||
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
|
||||
@version = options[:version] || '2015-02-01'
|
||||
@path = options[:path] || "/#{@version}/"
|
||||
|
||||
setup_credentials(options)
|
||||
end
|
||||
|
||||
def reload
|
||||
@connection.reset
|
||||
end
|
||||
|
||||
def setup_credentials(options)
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
@aws_secret_access_key = options[:aws_secret_access_key]
|
||||
@aws_session_token = options[:aws_session_token]
|
||||
@aws_credentials_expire_at = options[:aws_credentials_expire_at]
|
||||
|
||||
#global services that have no region are signed with the us-east-1 region
|
||||
#the only exception is GovCloud, which requires the region to be explicitly specified as us-gov-west-1
|
||||
@signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 'elasticfilesystem')
|
||||
end
|
||||
|
||||
def request(params)
|
||||
refresh_credentials_if_expired
|
||||
idempotent = params.delete(:idempotent)
|
||||
parser = params.delete(:parser)
|
||||
expects = params.delete(:expects) || 200
|
||||
path = @path + params.delete(:path)
|
||||
method = params.delete(:method) || 'GET'
|
||||
request_body = Fog::JSON.encode(params)
|
||||
|
||||
body, headers = Fog::AWS.signed_params_v4(
|
||||
params,
|
||||
{
|
||||
'Content-Type' => "application/x-amz-json-1.0",
|
||||
},
|
||||
{
|
||||
:host => @host,
|
||||
:path => path,
|
||||
:port => @port,
|
||||
:version => @version,
|
||||
:signer => @signer,
|
||||
:aws_session_token => @aws_session_token,
|
||||
:method => method,
|
||||
:body => request_body
|
||||
}
|
||||
)
|
||||
|
||||
if @instrumentor
|
||||
@instrumentor.instrument("#{@instrumentor_name}.request", params) do
|
||||
_request(body, headers, idempotent, parser, method, path, expects)
|
||||
end
|
||||
else
|
||||
_request(body, headers, idempotent, parser, method, path, expects)
|
||||
end
|
||||
end
|
||||
|
||||
def _request(body, headers, idempotent, parser, method, path, expects)
|
||||
response = @connection.request({
|
||||
:body => body,
|
||||
:expects => expects,
|
||||
:idempotent => idempotent,
|
||||
:headers => headers,
|
||||
:method => method,
|
||||
:parser => parser,
|
||||
:path => path
|
||||
})
|
||||
unless response.body.empty?
|
||||
response.body = Fog::JSON.decode(response.body)
|
||||
end
|
||||
response
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
match = Fog::AWS::Errors.match_error(error)
|
||||
raise if match.empty?
|
||||
raise case match[:message]
|
||||
when /invalid file system id/i
|
||||
Fog::AWS::EFS::NotFound.slurp(error, match[:message])
|
||||
else
|
||||
Fog::AWS::EFS::Error.slurp(error, "#{match[:code]} => #{match[:message]}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
lib/fog/aws/models/efs/file_system.rb
Normal file
36
lib/fog/aws/models/efs/file_system.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class EFS
|
||||
class FileSystem < Fog::Model
|
||||
identity :id, :aliases => 'FileSystemId'
|
||||
|
||||
attribute :owner_id, :aliases => 'OwnerId'
|
||||
attribute :creation_token, :aliases => 'CreationToken'
|
||||
attribute :performance_mode, :aliases => 'PerformanceMode'
|
||||
attribute :creation_time, :aliases => 'CreationTime'
|
||||
attribute :state, :aliases => 'LifeCycleState'
|
||||
attribute :name, :aliases => 'Name'
|
||||
attribute :number_of_mount_targets, :aliases => 'NumberOfMountTargets'
|
||||
attribute :size_in_bytes, :aliases => 'SizeInBytes'
|
||||
|
||||
def destroy
|
||||
requires :identity
|
||||
|
||||
service.delete_file_system(:id => self.identity)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def save
|
||||
params = {
|
||||
:creation_token => self.creation_token || Fog::Mock.random_hex(32)
|
||||
}
|
||||
|
||||
params.merge!(:performance_mode => self.performance_mode) if self.performance_mode
|
||||
|
||||
merge_attributes(service.create_file_system(:creation_token => self.creation_token).body)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
lib/fog/aws/models/efs/file_systems.rb
Normal file
23
lib/fog/aws/models/efs/file_systems.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require 'fog/aws/models/efs/file_system'
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class EFS
|
||||
class FileSystems < Fog::Collection
|
||||
model Fog::AWS::EFS::FileSystem
|
||||
|
||||
def all
|
||||
data = service.describe_file_systems.body["FileSystems"]
|
||||
load(data)
|
||||
end
|
||||
|
||||
def get(identity)
|
||||
data = service.describe_file_systems(:id => identity).body
|
||||
new(data)
|
||||
rescue Fog::AWS::EFS::NotFound
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
51
lib/fog/aws/requests/efs/create_file_system.rb
Normal file
51
lib/fog/aws/requests/efs/create_file_system.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class EFS
|
||||
class Real
|
||||
# Create a new, empty file system
|
||||
# http://docs.aws.amazon.com/efs/latest/ug/API_CreateFileSystem.html
|
||||
# ==== Parameters
|
||||
# * CreationToken <~String> - String of up to 64 ASCII characters. Amazon EFS uses this to ensure idempotent creation.
|
||||
# * PerformanceMode <~String> - (Optional) The PerformanceMode of the file system. We recommend generalPurpose performance mode for most file systems. File systems using the maxIO performance mode can scale to higher levels of aggregate throughput and operations per second with a tradeoff of slightly higher latencies for most file operations. This can't be changed after the file system has been created.
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>
|
||||
# * body<~Hash>
|
||||
def create_file_system(options={})
|
||||
request({
|
||||
:path => "file-systems",
|
||||
:method => 'POST',
|
||||
:expects => 201,
|
||||
'CreationToken' => options[:creation_token],
|
||||
'PerformanceMode' => options[:performance_mode] || 'generalPurpose'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def create_file_system(options={})
|
||||
response = Excon::Response.new
|
||||
|
||||
id = "fs-#{Fog::Mock.random_letters(8)}"
|
||||
file_system = {
|
||||
"OwnerId" => Fog::AWS::Mock.owner_id,
|
||||
"CreationToken" => options[:creation_token],
|
||||
"PerformanceMode" => options[:performance_mode] || "generalPurpose",
|
||||
"FileSystemId" => id,
|
||||
"CreationTime" => Time.now.to_i.to_f,
|
||||
"LifeCycleState" => "creating",
|
||||
"NumberOfMountTargets" => 0,
|
||||
"SizeInBytes" => {
|
||||
"Value" => 1024,
|
||||
"Timestamp" => Time.now.to_i.to_f
|
||||
}
|
||||
}
|
||||
|
||||
self.data[:file_systems][id] = file_system
|
||||
response.body = file_system
|
||||
response.status = 201
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
46
lib/fog/aws/requests/efs/delete_file_system.rb
Normal file
46
lib/fog/aws/requests/efs/delete_file_system.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class EFS
|
||||
class Real
|
||||
# Delete a file system
|
||||
# http://docs.aws.amazon.com/efs/latest/ug/API_DeleteFileSystem.html
|
||||
# ==== Parameters
|
||||
# * FileSystemId <~String> - ID of the file system you want to delete.
|
||||
# ==== Response
|
||||
# * response<~Excon::Response>
|
||||
# * body - Empty
|
||||
# * status - 204
|
||||
def delete_file_system(options={})
|
||||
id = options.delete(:id)
|
||||
request({
|
||||
:path => "file-systems/#{id}",
|
||||
:method => 'DELETE',
|
||||
:expects => 204,
|
||||
'CreationToken' => options[:creation_token],
|
||||
'PerformanceMode' => options[:performance_mode] || 'generalPurpose'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def delete_file_system(options={})
|
||||
id = options.delete(:id)
|
||||
|
||||
unless file_system = self.data[:file_systems][id]
|
||||
raise Fog::AWS::EFS::NotFound.new("invalid file system ID: #{id}")
|
||||
end
|
||||
|
||||
if file_system["NumberOfMountTargets"] > 0
|
||||
raise Fog::AWS::EFS::FileSystemInUse.new("file system still has active mount targets")
|
||||
end
|
||||
|
||||
self.data[:file_systems].delete(id)
|
||||
|
||||
response = Excon::Response.new
|
||||
response.status = 204
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
62
lib/fog/aws/requests/efs/describe_file_systems.rb
Normal file
62
lib/fog/aws/requests/efs/describe_file_systems.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class EFS
|
||||
class Real
|
||||
# Describe all or specified elastic file systems
|
||||
# http://docs.aws.amazon.com/efs/latest/ug/API_DescribeFileSystems.html
|
||||
# ==== Parameters
|
||||
# * CreationToken <~String> - (Optional) Restricts the list to the file system with this creation token (String). You specify a creation token when you create an Amazon EFS file system.
|
||||
# * FileSystemId <~String> - (Optional) ID of the file system whose description you want to retrieve (String).
|
||||
# ==== Returns
|
||||
# * response<~Excon::Response>:
|
||||
# * body<~Hash>
|
||||
def describe_file_systems(options={})
|
||||
params = {}
|
||||
if options[:marker]
|
||||
params['Marker'] = options[:marker]
|
||||
end
|
||||
if options[:max_records]
|
||||
params['MaxRecords'] = options[:max_records]
|
||||
end
|
||||
if options[:id]
|
||||
params['FileSystemId'] = options[:id]
|
||||
end
|
||||
if options[:creation_token]
|
||||
params['CreationToken'] = options[:creation_token]
|
||||
end
|
||||
|
||||
request({
|
||||
:path => "file-systems"
|
||||
}.merge(params))
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def describe_file_systems(options={})
|
||||
response = Excon::Response.new
|
||||
|
||||
file_systems = if id = options[:id]
|
||||
if fs = self.data[:file_systems][id]
|
||||
[fs]
|
||||
else
|
||||
raise Fog::AWS::EFS::NotFound.new("invalid file system ID: #{id}")
|
||||
end
|
||||
elsif creation_token = options[:creation_token]
|
||||
fs = self.data[:file_systems].values.detect { |file_system| file_system["CreationToken"] == creation_token }
|
||||
[fs]
|
||||
else
|
||||
self.data[:file_systems].values
|
||||
end
|
||||
|
||||
file_systems.each do |file_system|
|
||||
file_system['LifeCycleState'] = 'available'
|
||||
self.data[:file_systems][file_system['FileSystemId']] = file_system
|
||||
end
|
||||
|
||||
response.body = {"FileSystems" => file_systems}
|
||||
response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
12
tests/models/efs/file_system_tests.rb
Normal file
12
tests/models/efs/file_system_tests.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
Shindo.tests("AWS::EFS | file system", ["aws", "efs"]) do
|
||||
file_system_params = {
|
||||
:creation_token => "fogtoken#{rand(999).to_s}"
|
||||
}
|
||||
|
||||
model_tests(Fog::AWS[:efs].file_systems, file_system_params, true)
|
||||
|
||||
file_system_params = {
|
||||
:creation_token => "fogtoken#{rand(999).to_s}"
|
||||
}
|
||||
collection_tests(Fog::AWS[:efs].file_systems, file_system_params, true)
|
||||
end
|
36
tests/requests/efs/file_system_tests.rb
Normal file
36
tests/requests/efs/file_system_tests.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
Shindo.tests('AWS::EFS | file systems', ['aws', 'efs']) do
|
||||
suffix = rand(65535).to_s(16)
|
||||
|
||||
@creation_token = "fogtest#{suffix}"
|
||||
|
||||
tests('success') do
|
||||
tests("#create_file_system").formats(AWS::EFS::Formats::FILE_SYSTEM_FORMAT) do
|
||||
result = Fog::AWS[:efs].create_file_system(:creation_token => @creation_token).body
|
||||
returns('creating') { result['LifeCycleState'] }
|
||||
result
|
||||
end
|
||||
|
||||
tests("#describe_file_systems").formats(AWS::EFS::Formats::DESCRIBE_FILE_SYSTEMS_RESULT) do
|
||||
Fog::AWS[:efs].describe_file_systems.body
|
||||
end
|
||||
|
||||
tests("#describe_file_systems(creation_token: #{@creation_token})").formats(AWS::EFS::Formats::DESCRIBE_FILE_SYSTEMS_RESULT) do
|
||||
result = Fog::AWS[:efs].describe_file_systems(:creation_token => @creation_token).body
|
||||
returns(@creation_token) { result["FileSystems"].first["CreationToken"] }
|
||||
result
|
||||
end
|
||||
|
||||
file_system = Fog::AWS[:efs].describe_file_systems(:creation_token => @creation_token).body["FileSystems"].first
|
||||
|
||||
tests("#describe_file_systems(id: #{file_system["FileSystemId"]})").formats(AWS::EFS::Formats::DESCRIBE_FILE_SYSTEMS_RESULT) do
|
||||
Fog::AWS[:efs].describe_file_systems(:id => file_system["FileSystemId"]).body
|
||||
end
|
||||
|
||||
tests("#delete_file_system") do
|
||||
returns(true) do
|
||||
result = Fog::AWS[:efs].delete_file_system(:id => file_system["FileSystemId"])
|
||||
result.body.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
tests/requests/efs/helper.rb
Normal file
24
tests/requests/efs/helper.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
class AWS
|
||||
module EFS
|
||||
module Formats
|
||||
FILE_SYSTEM_FORMAT = {
|
||||
"CreationTime" => Float,
|
||||
"CreationToken" => String,
|
||||
"FileSystemId" => String,
|
||||
"LifeCycleState" => String,
|
||||
"Name" => Fog::Nullable::String,
|
||||
"NumberOfMountTargets" => Integer,
|
||||
"OwnerId" => String,
|
||||
"PerformanceMode" => String,
|
||||
"SizeInBytes" => {
|
||||
"Timestamp" => Fog::Nullable::Float,
|
||||
"Value" => Integer
|
||||
}
|
||||
}
|
||||
|
||||
DESCRIBE_FILE_SYSTEMS_RESULT = {
|
||||
"FileSystems" => [FILE_SYSTEM_FORMAT]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue