1
0
Fork 0
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:
Eugene Howe 2016-10-05 14:29:19 -04:00
parent df01e7bc24
commit 98f3af916e
10 changed files with 439 additions and 0 deletions

View file

@ -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
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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