Class: RightSupport::Net::S3Helper

Inherits:
Object
  • Object
show all
Defined in:
lib/right_support/net/s3_helper.rb

Overview

Class provides S3 functionality. As part of RightSupport S3Helper does not include Rightscale::S3 and Encryptor modules. This modules must be included in application.

Example:

require ‘right_support’ require ‘right_aws’ require ‘encryptor’

s3_config = YAML.load_file(File.expand_path(“../../config/s3.yml”,__FILE__))[ENV] RightSupport::Net::S3Helper.init(s3_config, Rightscale::S3, Encryptor) s3_health = RightSupport::Net::S3Helper.health_check

Defined Under Namespace

Classes: BucketNotFound

Class Method Summary collapse

Class Method Details

.bucketObject

Create Bucket object using S3 object

Raises:

  • BucketNotFound if bucket name specified in config does not exist



78
79
80
81
82
# File 'lib/right_support/net/s3_helper.rb', line 78

def self.bucket
  @bucket ||= s3.bucket(config["bucket_name"])
  raise BucketNotFound, "Bucket #{config["bucket_name"]} does not exist" if @bucket.nil?
  @bucket
end

.configObject

Returns @config parameter



69
70
71
# File 'lib/right_support/net/s3_helper.rb', line 69

def self.config
  @config
end

.get(key, &blck) ⇒ String

Downloads data from S3 Bucket

Parameters:

  • key (String)

    Name of the bucket key

  • blck (Block)

    Ruby code wich will be done by Bucket object

Returns:

  • (String)

    S3 bucket’s key content in plain/text format



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/right_support/net/s3_helper.rb', line 93

def self.get(key, &blck)
  return nil unless s3_enabled?

  object = bucket.key(key, true, &blck)
  return nil if object.nil?

  # don't decrypt/verify unencrypted values
  return object.data if object.meta_headers["digest"].nil?

  ciphertext = object.data
  passphrase = "#{key}:#{master_secret}"
  plaintext = @encryptor.decrypt(:key=>passphrase, :value=>ciphertext)
  digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, passphrase, plaintext)

  if digest == object.meta_headers["digest"]
    return plaintext
  else
    raise "digest for key:#{key} in s3 does not match calculated digest."
  end
end

.health_checkString or True

Checks if it is possible to connect to the S3 Bucket.

Returns:

  • (String or True)

    If test was successful then return true Else return error message



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/right_support/net/s3_helper.rb', line 130

def self.health_check
  config
  s3
  # test config file
  return 'S3 Config file: Credentials: Syntax error.' unless s3_enabled?
  ["bucket_name", "master_secret"].each do |conf|
    return "S3 Config file: #{conf.upcase}: Syntax error." if config[conf].nil? || config[conf] == '' || config[conf] == "@@#{conf.upcase}@@"
  end
  # test connection
  original_text = 'heath check'
  test_key  = 'ping'
  begin
    post(test_key, original_text)
  rescue Exception => e
    return e.message
  end
  begin
    result_text = get(test_key)
  rescue Exception => e
    return e.message
  end
  return 'Sended text and returned one are not equal. Possible master_secret problem' if result_text != original_text
  # retrurn true if there were not errors
  true
end

.init(config, s3, encryptor, options = {}) ⇒ true

Init() is the first method which must be called. This is configuration and integration with S3 and Encryptor

Parameters:

  • config (Hash)

    config for current environment (from YAML config file) creds:

    aws_access_key_id: String
    aws_secret_access_key: String
    

    bucket_name: String master_secret: String

  • s3 (Class)

    Rightscale::S3 class is used to connect to S3

  • encryptor (Class)

    Class which will be used to encrypt data encrypt() and decrypt() methods must be implemented

Returns:

  • (true)

    always returns true

Raises:

  • BucketNotFound if bucket name specified in config does not exist



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/right_support/net/s3_helper.rb', line 44

def self.init(config, s3, encryptor, options = {})
  @config = config
  @s3class = s3
  @encryptor = encryptor
  @options = options

  # Reset any S3 objects we'd been caching, since config may have changed
  @s3 = @bucket = nil
  # Make sure our bucket exists -- better to do it now than on first access!
  self.bucket

  true
end

.master_secretObject

Returns Master secret from config



84
85
86
# File 'lib/right_support/net/s3_helper.rb', line 84

def self.master_secret
  config["master_secret"]
end

.post(key, plaintext, &blck) ⇒ Object

Upload data to S3 Bucket

Parameters:

  • key (String)

    Name of the bucket key

  • plaintext (String)

    Data which should be saved in the Bucket

  • blck (Block)

    Ruby code wich will be done by Bucket object



119
120
121
122
123
124
125
# File 'lib/right_support/net/s3_helper.rb', line 119

def self.post(key, plaintext, &blck)
  passphrase = "#{key}:#{master_secret}"
  plaintext = "-- no detail --" unless plaintext && plaintext.size > 0
  ciphertext = @encryptor.encrypt(:key=>passphrase, :value=>plaintext)
  digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, passphrase, plaintext)
  bucket.put(key, ciphertext, {"digest" => digest}, &blck)
end

.s3Object

Create (if does not exist) and return S3 object



73
74
75
# File 'lib/right_support/net/s3_helper.rb', line 73

def self.s3
  @s3 ||= @s3class.new config["creds"]["aws_access_key_id"], config["creds"]["aws_secret_access_key"], @options
end

.s3_enabled?Boolean

Checks S3 credentials syntax in config parameter

Returns:

  • (Boolean)

    true if s3 creadentials are ok or false if not



61
62
63
64
65
66
67
# File 'lib/right_support/net/s3_helper.rb', line 61

def self.s3_enabled?
  return @s3_enabled if @s3_enabled
  @s3_enabled ||= !config.empty? &&
    !config["creds"].empty?    &&
    !config["creds"]["aws_access_key_id"].nil? &&
    config["creds"]["aws_access_key_id"] != "@@AWS_ACCESS_KEY_ID@@"
end