Class: Cifrado::SwiftClient

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/cifrado/swift_client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#calculate_chunks, #clean_object_name, #decrypt_filename, #encrypt_filename, #humanize_bytes, #mime_type, #prettify_backtrace, #unix_time

Constructor Details

#initialize(auth_data = {}) ⇒ SwiftClient

Returns a new instance of SwiftClient.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/cifrado/swift_client.rb', line 13

def initialize(auth_data = {})
  @username = auth_data[:username]
  @api_key  = auth_data[:api_key]
  @auth_url = auth_data[:auth_url]
  @tenant   = auth_data[:tenant]
  @region   = auth_data[:region]
  @connection_options = auth_data[:connection_options] || {}
  @service_type = auth_data[:service_type] || 'object-store'
  @endpoint_type = auth_data[:endpoint_type] || 'publicURL'
  @password_salt = auth_data[:password_salt]

  @connection_options.each do |k, v|
    Excon.defaults[k] = v
  end
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



9
10
11
# File 'lib/cifrado/swift_client.rb', line 9

def api_key
  @api_key
end

#auth_urlObject (readonly)

Returns the value of attribute auth_url.



11
12
13
# File 'lib/cifrado/swift_client.rb', line 11

def auth_url
  @auth_url
end

#usernameObject (readonly)

Returns the value of attribute username.



10
11
12
# File 'lib/cifrado/swift_client.rb', line 10

def username
  @username
end

Instance Method Details

#create_directory(container, wait_for_it = false) ⇒ Object



66
67
68
# File 'lib/cifrado/swift_client.rb', line 66

def create_directory(container, wait_for_it = false)
  create_container container, wait_for_it
end

#download(container, object = nil, options = {}) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/cifrado/swift_client.rb', line 155

def download(container, object = nil, options = {})
  if object
    download_object container, object, options
  else
    dir = service.directories.get container
    unless dir
      Log.debug "Container #{container} not found"
      raise "Container #{container} not found"
    end
    dest_dir = options[:output] || Dir.pwd
    unless File.directory?(dest_dir)
      raise ArgumentError.new "Directory #{dest_dir} does not exist"
    end
    dir.files.each do |f|
      # Skip segments from segmented uploads
      if f.key =~ /segments\/\d+\.\d{2}\/\d+/
        Log.debug "Skipping segment #{f.key}"
        next
      end
      unless options[:decrypt] == true
        options[:output] = File.join(dest_dir, f.key)
      end
      download_object container, f.key, options
    end
    Excon::Response.new :status => 200
  end
end

#encrypted_upload(container, object, options = {}) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/cifrado/swift_client.rb', line 70

def encrypted_upload(container, object, options = {})
  cipher = CryptoEngineAES.new @api_key
  encrypted_name = cipher.encrypt object
  options[:headers] ||= {}
  options[:headers]['X-Object-Meta-Encrypted-Name'] = encrypted_name
  upload container, object, options
end

#file_available?(container, object) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/cifrado/swift_client.rb', line 47

def file_available?(container, object)
  !head(container, object).nil?
end

#head(container = nil, object = nil) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/cifrado/swift_client.rb', line 33

def head(container = nil, object = nil)
  begin 
    if container and object
      service.head_object(container, clean_object_name(object)).headers
    elsif container
      service.head_container(container).headers
    else
      (service.request :method => 'HEAD').headers
    end
  rescue Fog::Storage::OpenStack::NotFound
    nil
  end
end

#match(source_file, container, object_path = nil) ⇒ Object



188
189
190
191
192
193
194
195
196
197
# File 'lib/cifrado/swift_client.rb', line 188

def match(source_file, container, object_path = nil)
  obj = object_path || source_file
  headers = head container, clean_object_name(obj)
  if headers
    md5 = Digest::MD5.file(source_file).to_s
    (md5 == headers['Etag']) ? 1 : 2
  else
    0
  end
end

#serviceObject



51
52
53
# File 'lib/cifrado/swift_client.rb', line 51

def service
  @service ||= authenticate_v2
end

#set_acl(acl, container, object = nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/cifrado/swift_client.rb', line 55

def set_acl(acl, container, object = nil)
  if object
    raise NotImplementedError.new
  else
    service.request :path => Fog::OpenStack.escape(container), 
                    :headers => { 'X-Container-Read' => acl },
                    :expects => [201, 202],
                    :method  => 'PUT'
  end
end

#stream(container, object, options = {}) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/cifrado/swift_client.rb', line 134

def stream(container, object, options = {})
  raise ArgumentError.new "Invalid object" unless object

  storage_url = service.credentials[:server_management_url]
  storage_url << "/" unless storage_url =~ /\/$/

  path = File.join(container, clean_object_name(object))

  headers = {
    "User-Agent" => "#{user_agent}",
    "X-Auth-Token" => @auth_token
  }
  res = StreamingDownloader.get storage_url + Fog::OpenStack.escape(path),
                                nil,
                                :progress_callback => options[:progress_callback],
                                :connection_options => @connection_options,
                                :headers => headers,
                                :bwlimit => options[:bwlimit],
                                :stream => true
end

#test_connectionObject



29
30
31
# File 'lib/cifrado/swift_client.rb', line 29

def test_connection
  authenticate_v2
end

#upload(container, object, options = {}) ⇒ Object

Raises:

  • (ArgumentError)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/cifrado/swift_client.rb', line 78

def upload(container, object, options = {})

  raise ArgumentError.new("Invalid container") if container.nil?
  raise ArgumentError.new("Invalid object") if object.nil?

  # if :source_file present, object may be the destination
  # path of the object and may not be the path to the
  # real file
  object_path = clean_object_name(options[:object_path] || object)
  object_size = File.size(object)

  Log.debug "Object size: #{humanize_bytes(object_size)}"

  path = File.join('/', container, object_path)

  Log.debug "X-Storage-Url: #{@storage_url}"

  create_container container, true

  Log.debug "Destination URI: " + @storage_url + path

  pcallback = options[:progress_callback]
  nchunk = 0
  headers = { 'X-Auth-Token' => @auth_token }
  if mime = mime_type(object)
    headers['Content-Type'] = mime
  end
  if options[:headers]
    headers = headers.merge options[:headers] 
  end
  if pcallback
    res = Cifrado::StreamingUploader.put(
        @storage_url + Fog::OpenStack.escape(path),
        :headers => headers, 
        :file => File.open(object),
        :ssl_verify_peer => @connection_options[:ssl_verify_peer],
        :bwlimit => options[:bwlimit]
    ) { |bytes| pcallback.call(object_size, bytes) }
  else
    res = Cifrado::StreamingUploader.put(
        @storage_url + Fog::OpenStack.escape(path),
        :headers => headers, 
        :file => File.open(object),
        :ssl_verify_peer => @connection_options[:ssl_verify_peer],
        :bwlimit => options[:bwlimit]
    ) 
  end

  Log.debug "Upload response #{res.class}"
  res
end

#user_agentObject



130
131
132
# File 'lib/cifrado/swift_client.rb', line 130

def user_agent
  "Cifrado #{Cifrado::VERSION}"
end