terraform-wrapper 0.0.2 → 0.1.0

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.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/terraform-wrapper.rb +34 -16
  3. data/lib/terraform-wrapper/common.rb +12 -23
  4. data/lib/terraform-wrapper/shared.rb +7 -1
  5. data/lib/terraform-wrapper/shared/auths.rb +9 -0
  6. data/lib/terraform-wrapper/shared/auths/azure.rb +179 -0
  7. data/lib/terraform-wrapper/shared/auths/common.rb +95 -0
  8. data/lib/terraform-wrapper/shared/backends/aws.rb +34 -29
  9. data/lib/terraform-wrapper/shared/backends/azure.rb +38 -39
  10. data/lib/terraform-wrapper/shared/backends/common.rb +18 -14
  11. data/lib/terraform-wrapper/shared/backends/local.rb +20 -18
  12. data/lib/terraform-wrapper/shared/binary.rb +16 -5
  13. data/lib/terraform-wrapper/shared/code.rb +15 -4
  14. data/lib/terraform-wrapper/shared/config.rb +61 -31
  15. data/lib/terraform-wrapper/shared/latest.rb +11 -7
  16. data/lib/terraform-wrapper/shared/logger.rb +80 -0
  17. data/lib/terraform-wrapper/shared/logging.rb +77 -0
  18. data/lib/terraform-wrapper/shared/runner.rb +59 -22
  19. data/lib/terraform-wrapper/shared/variables.rb +66 -0
  20. data/lib/terraform-wrapper/tasks/apply.rb +16 -14
  21. data/lib/terraform-wrapper/tasks/binary.rb +25 -21
  22. data/lib/terraform-wrapper/tasks/clean.rb +15 -11
  23. data/lib/terraform-wrapper/tasks/destroy.rb +16 -14
  24. data/lib/terraform-wrapper/tasks/init.rb +16 -14
  25. data/lib/terraform-wrapper/tasks/plan.rb +16 -14
  26. data/lib/terraform-wrapper/tasks/plandestroy.rb +16 -14
  27. data/lib/terraform-wrapper/tasks/validate.rb +7 -3
  28. data/lib/terraform-wrapper/version.rb +1 -1
  29. metadata +8 -3
  30. data/lib/terraform-wrapper/shared/identifiers.rb +0 -70
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ada2b6b6e65d6daedfc646d9f983894ada4061b649902252468bccaae76b4fee
4
- data.tar.gz: 4698b8bc21d9ab1ab2866a263645a2aa07955aeb03b2f10d15aed732da1d4553
3
+ metadata.gz: 8c1c8efca42bd473f3bbfa5c0e97f2782b8cc2652f96fa17b213c8fa87d4b0ae
4
+ data.tar.gz: df46cad597ad4101afc53b242a94e11452e9bd14b722a1e76eb91ad9a02909a3
5
5
  SHA512:
6
- metadata.gz: '095bd5f00cda0d8fa2e6e636bfaf4bf31e6dea0a03cbc49b3149c85b15c75e4928e5754dd56b9a71d9d0b33f5b8a7e033739e45e7746fe2fd97d28bb0139f62e'
7
- data.tar.gz: 36f56ccf800f33dba662e41f377688e753c409076417269a2b638a6a28b60980aea437736236ca1083602f2a1cf8d935c0cc7aaaa35b297ba11bde06e935efd2
6
+ metadata.gz: 97be709f764c69cd868834dfa6d6ffbe1917d40ede4ef0ceaf2a01fc26fdf84f9d5da0a45c8ac02f017f29eb42071cbf8ce50e3d8862123c2a96f4ce9adfcc04
7
+ data.tar.gz: e1f8420bc2165a6819bc08a85fbf5d3290d3e40154866d5d6e47ddabd51eb8124ad748668cae8dfb6fd4e7964b4d6cb68eec747d32aa92fc29991166713b7192
@@ -14,28 +14,46 @@ module TerraformWrapper
14
14
 
15
15
  ###############################################################################
16
16
 
17
- def self.define_tasks(backend: "local",
18
- binaries: File.join(Dir.pwd, "vendor", "terraform"),
19
- component:,
20
- configs: File.join(Dir.pwd, "config"),
21
- overrides: Hash.new,
22
- service:,
23
- terraform: File.join(Dir.pwd, "terraform"),
24
- version: TerraformWrapper::Shared::Latest.instance.version)
17
+ @logger = Shared::Logging.logger_for("TerraformWrapper")
25
18
 
26
- $logger.info("Building tasks for service: #{service}, component: #{component}...")
19
+ ###############################################################################
20
+
21
+ @logger.info("Terraform Wrapper for Ruby - version: #{TerraformWrapper::VERSION}")
22
+
23
+ ###############################################################################
24
+
25
+ def self.define_tasks(component:, options: Hash.new, service:)
26
+ @logger.info("Building tasks for service: #{service}, component: #{component}...")
27
+
28
+ @logger.fatal("Options must be specified as a hash!") unless options.kind_of?(Hash)
29
+
30
+ binary_options = Hash.new
31
+ binary_options["base"] = options.key?("binary-base") ? options["binary-base"] : File.join(Dir.pwd, "vendor", "terraform")
32
+ binary_options["version"] = options.key?("binary-version") ? options["binary-version"] : Shared::Latest.instance.version
33
+
34
+ code_options = Hash.new
35
+ code_options["base"] = options.key?("code-base") ? options["code-base"] : File.join(Dir.pwd, "terraform")
36
+ code_options["name"] = component
37
+
38
+ config_options = Hash.new
39
+ config_options["auth-azure"] = options.key?("config-auth-azure") ? options["config-auth-azure"] : false
40
+ config_options["auth-azure-options"] = options.key?("config-auth-azure-options") ? options["config-auth-azure-options"] : Hash.new
41
+ config_options["base"] = options.key?("config-base") ? options["config-base"] : File.join(Dir.pwd, "config")
42
+ config_options["backend"] = options.key?("config-backend") ? options["config-backend"] : "local"
43
+ config_options["backend-options"] = options.key?("config-backend-options") ? options["config-backend-options"] : Hash.new
44
+ config_options["service"] = service
27
45
 
28
- binary = TerraformWrapper::Shared::Binary.new(base: binaries, version: version)
29
- code = TerraformWrapper::Shared::Code.new(base: terraform, name: component)
46
+ binary = TerraformWrapper::Shared::Binary.new(options: binary_options)
47
+ code = TerraformWrapper::Shared::Code.new(options: code_options)
30
48
 
31
49
  tasks = Array.new
32
- tasks << TerraformWrapper::Tasks::Apply.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
50
+ tasks << TerraformWrapper::Tasks::Apply.new(binary: binary, code: code, options: config_options)
33
51
  tasks << TerraformWrapper::Tasks::Binary.new(binary: binary)
34
52
  tasks << TerraformWrapper::Tasks::Clean.new(code: code)
35
- tasks << TerraformWrapper::Tasks::Destroy.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
36
- tasks << TerraformWrapper::Tasks::Init.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
37
- tasks << TerraformWrapper::Tasks::Plan.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
38
- tasks << TerraformWrapper::Tasks::PlanDestroy.new(backend: backend, binary: binary, code: code, configs: configs, overrides: overrides, service: service)
53
+ tasks << TerraformWrapper::Tasks::Destroy.new(binary: binary, code: code, options: config_options)
54
+ tasks << TerraformWrapper::Tasks::Init.new(binary: binary, code: code, options: config_options)
55
+ tasks << TerraformWrapper::Tasks::Plan.new(binary: binary, code: code, options: config_options)
56
+ tasks << TerraformWrapper::Tasks::PlanDestroy.new(binary: binary, code: code, options: config_options)
39
57
  tasks << TerraformWrapper::Tasks::Validate.new(binary: binary, code: code)
40
58
  return tasks
41
59
  end
@@ -1,38 +1,27 @@
1
1
  ###############################################################################
2
2
 
3
- require 'logger'
3
+ module TerraformWrapper
4
4
 
5
5
  ###############################################################################
6
6
 
7
- $logger = Logger.new(STDOUT,
8
- level: "INFO",
9
- progname: "TerraformWrapper")
7
+ def self.create_directory(directory:, purpose: nil, exists: true)
8
+ return exists if File.directory?(directory)
10
9
 
11
- $logger.formatter = proc do |severity, datetime, progname, msg|
12
- sevId = severity.chars.first.upcase
13
- "#{progname} [#{sevId}] #{msg}\n"
14
- end
15
-
16
- ###############################################################################
10
+ result = false
17
11
 
18
- $logger.info("Terraform Wrapper for Ruby - version: #{TerraformWrapper::VERSION}")
12
+ if not purpose.nil? and purpose.kind_of?(String) and not purpose.strip.empty? then
13
+ @logger.info("Creating directory for: #{purpose}, path: #{directory}")
14
+ else
15
+ @logger.info("Creating directory: #{directory}")
16
+ end
19
17
 
20
- ###############################################################################
18
+ FileUtils.mkdir_p(directory)
21
19
 
22
- def create_directory(directory:, purpose: nil, exists: true)
23
- return exists if File.directory?(directory)
24
-
25
- result = false
26
-
27
- if not purpose.nil? and purpose.kind_of?(String) and not purpose.strip.empty? then
28
- $logger.info("Creating directory for: #{purpose}, path: #{directory}")
29
- else
30
- $logger.info("Creating directory: #{directory}")
20
+ result = File.directory?(directory)
31
21
  end
32
22
 
33
- FileUtils.mkdir_p(directory)
23
+ ###############################################################################
34
24
 
35
- result = File.directory?(directory)
36
25
  end
37
26
 
38
27
  ###############################################################################
@@ -1,11 +1,17 @@
1
1
  ###############################################################################
2
2
 
3
+ require_relative 'shared/logger'
4
+ require_relative 'shared/logging'
5
+
6
+ ###############################################################################
7
+
8
+ require_relative 'shared/auths'
3
9
  require_relative 'shared/backends'
4
10
  require_relative 'shared/binary'
5
11
  require_relative 'shared/code'
6
12
  require_relative 'shared/config'
7
- require_relative 'shared/identifiers'
8
13
  require_relative 'shared/latest'
9
14
  require_relative 'shared/runner'
15
+ require_relative 'shared/variables'
10
16
 
11
17
  ###############################################################################
@@ -0,0 +1,9 @@
1
+ ###############################################################################
2
+
3
+ require_relative 'auths/common'
4
+
5
+ ###############################################################################
6
+
7
+ require_relative 'auths/azure'
8
+
9
+ ###############################################################################
@@ -0,0 +1,179 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ module Auths
12
+
13
+ ###############################################################################
14
+
15
+ class Azure < Common
16
+
17
+ ###############################################################################
18
+
19
+ include TerraformWrapper::Shared::Logging
20
+
21
+ ###############################################################################
22
+
23
+ @@az = "az"
24
+ @@type = "azure"
25
+
26
+ ###############################################################################
27
+
28
+ @password = nil
29
+
30
+ ###############################################################################
31
+
32
+ attr_reader :subscription
33
+ attr_reader :tenant
34
+ attr_reader :username
35
+
36
+ ###############################################################################
37
+
38
+ def initialize(code:, config:, options:, service:, variables:)
39
+ construct(code: code, config: config, options: options, service: service, variables: variables)
40
+ end
41
+
42
+ ###############################################################################
43
+
44
+ def auth()
45
+ ENV["ARM_SUBSCRIPTION_ID"] = @subscription
46
+ ENV["ARM_TENANT_ID"] = @tenant
47
+ ENV["ARM_CLIENT_ID"] = @username unless @username.nil?
48
+ ENV["ARM_CLIENT_SECRET"] = @password unless @password.nil?
49
+ logger.success("Azure authenticator environment variables set!")
50
+ end
51
+
52
+ ###############################################################################
53
+
54
+ def clear()
55
+ ENV.delete("ARM_SUBSCRIPTION_ID")
56
+ ENV.delete("ARM_TENANT_ID")
57
+ logger.info("Azure authenticator environment variables cleared!")
58
+ end
59
+
60
+ ###############################################################################
61
+
62
+ private
63
+
64
+ ###############################################################################
65
+
66
+ def cli()
67
+ output = logger.colour ? "jsonc" : "json"
68
+ cmdline = "\"#{@@az}\" version --output \"#{output}\""
69
+ return(system(cmdline) || false)
70
+ end
71
+
72
+ ###############################################################################
73
+
74
+ def secret(vault:, name:)
75
+ logger.info("Getting secret: #{name}, from key vault: #{vault}...")
76
+
77
+ cmdline = "\"#{@@az}\" keyvault secret show --vault-name \"#{vault}\" --name \"#{name}\" --query \"value\" --output \"tsv\""
78
+ stdout = `#{cmdline}`
79
+ code = $?.exitstatus
80
+
81
+ logger.fatal("Failed to get secret: #{name} from key vault: #{vault}!") if (code != 0 and stdout.strip.empty?)
82
+
83
+ return(stdout.strip)
84
+ end
85
+
86
+ ###############################################################################
87
+
88
+ def subscription_details(subscription:)
89
+ logger.info("Looking up details for subscription: #{subscription}...")
90
+
91
+ cmdline = "\"#{@@az}\" account show --subscription \"#{subscription}\" --query \"{id:id,tenant:tenantId}\" --output \"yaml\""
92
+ stdout = `#{cmdline}`
93
+ code = $?.exitstatus
94
+
95
+ logger.fatal("Failed to get details for subscription: #{subscription}!") if code != 0
96
+
97
+ details = YAML.load(stdout.strip)
98
+
99
+ logger.fatal("Returned details did not include the subscription ID!") unless details.key?("id")
100
+ logger.fatal("Returned subscription ID is not a String!") unless details["id"].kind_of?(String)
101
+ logger.fatal("Returned subscription ID is empty!") if details["id"].strip.empty?
102
+
103
+ logger.fatal("Returned details did not include the tenant ID!") unless details.key?("tenant")
104
+ logger.fatal("Returned tenant ID is not a String!") unless details["tenant"].kind_of?(String)
105
+ logger.fatal("Returned tenant ID is empty!") if details["tenant"].strip.empty?
106
+
107
+ details.transform_values! { |value| value.strip }
108
+
109
+ logger.debug("Returned subscription ID: #{details["id"]}")
110
+ logger.debug("Returned tenant ID: #{details["tenant"]}")
111
+
112
+ return(details)
113
+ end
114
+
115
+ ###############################################################################
116
+
117
+ def specific()
118
+ keyvault = nil
119
+
120
+ logger.fatal("Azure CLI must be installed and accessible to use the Azure authenticator.") unless cli
121
+
122
+ logger.fatal("Azure authenticator mandatory option 'subscription' has not been set!") unless @options.key?("subscription")
123
+
124
+ subscription = @options["subscription"]
125
+
126
+ logger.fatal("Azure authenticator subscription must be a String!") unless subscription.kind_of?(String)
127
+ logger.fatal("Azure authenticator subscription must not be blank!") if subscription.strip.empty?
128
+
129
+ if @options.key?("keyvault") then
130
+ keyvault = @options["keyvault"]
131
+
132
+ logger.fatal("Azure authenticator keyvault name must be a String if specified!") unless keyvault.kind_of?(String)
133
+ logger.fatal("Azure authenticator keyvault name must not be blank if specified!") if keyvault.strip.empty?
134
+
135
+ username = @options.key?("username-secret") ? @options["username-secret"] : "terraform-username"
136
+
137
+ logger.fatal("Azure authenticator keyvault secret for username must be a String if keyvault name is specified!") unless username.kind_of?(String)
138
+ logger.fatal("Azure authenticator keyvault secret for username must not be blank if keyvault name is specified!") if username.strip.empty?
139
+
140
+ password = @options.key?("username-password") ? @options["username-password"] : "terraform-password"
141
+
142
+ logger.fatal("Azure authenticator keyvault secret for password must be a String if keyvault name is specified!") unless password.kind_of?(String)
143
+ logger.fatal("Azure authenticator keyvault secret for password must not be blank if keyvault name is specified!") if password.strip.empty?
144
+ end
145
+
146
+ begin
147
+ subscription = subscription % @variables
148
+ keyvault = keyvault % @variables unless keyvault.nil?
149
+ username = username % @variables unless keyvault.nil?
150
+ password = password % @variables unless keyvault.nil?
151
+ rescue
152
+ logger.fatal("Azure authenticator options contain variables that are not included in the configuration file!")
153
+ end
154
+
155
+ details = subscription_details(subscription: subscription)
156
+
157
+ @subscription = details["id"]
158
+ @tenant = details["tenant"]
159
+ @username = keyvault.nil? ? nil : secret(vault: keyvault, name: username)
160
+ @password = keyvault.nil? ? nil : secret(vault: keyvault, name: password)
161
+ end
162
+
163
+ ###############################################################################
164
+
165
+ end
166
+
167
+ ###############################################################################
168
+
169
+ end
170
+
171
+ ###############################################################################
172
+
173
+ end
174
+
175
+ ###############################################################################
176
+
177
+ end
178
+
179
+ ###############################################################################
@@ -0,0 +1,95 @@
1
+ ###############################################################################
2
+
3
+ module TerraformWrapper
4
+
5
+ ###############################################################################
6
+
7
+ module Shared
8
+
9
+ ###############################################################################
10
+
11
+ module Auths
12
+
13
+ ###############################################################################
14
+
15
+ class Common
16
+
17
+ ###############################################################################
18
+
19
+ include TerraformWrapper::Shared::Logging
20
+
21
+ ###############################################################################
22
+
23
+ @@type
24
+
25
+ ###############################################################################
26
+
27
+ @options
28
+ @variables
29
+
30
+ ###############################################################################
31
+
32
+ def initialize(code:, config:, options:, service:, variables:)
33
+ logger.fatal("This class should not be used directly! Please create an authenticator-specific class instead!")
34
+ end
35
+
36
+ ###############################################################################
37
+
38
+ def auth()
39
+ logger.fatal("The authenticator specific class should override the 'auth' method to complete the authentication process!")
40
+ end
41
+
42
+ ###############################################################################
43
+
44
+ def clear()
45
+ logger.fatal("The authenticator specific class should override the 'auth' method to clear any authentication details!")
46
+ end
47
+
48
+ ###############################################################################
49
+
50
+ def type()
51
+ logger.fatal("The authenticator specific class should set the 'type' class variable to a string!") unless @@type.kind_of?(String)
52
+
53
+ return @@type
54
+ end
55
+
56
+ ###############################################################################
57
+
58
+ private
59
+
60
+ ###############################################################################
61
+
62
+ def construct(code:, config:, options:, service:, variables:)
63
+ @options = options
64
+ @variables = variables.values.merge({
65
+ component: code.name,
66
+ config: config,
67
+ service: service
68
+ })
69
+
70
+ specific
71
+ end
72
+
73
+ ###############################################################################
74
+
75
+ def specific()
76
+ logger.fatal("The authenticator specific class should override the 'specific' method to include authenticator specific validation and setup, or simply return 'true' if it is not required.")
77
+ end
78
+
79
+ ###############################################################################
80
+
81
+ end
82
+
83
+ ###############################################################################
84
+
85
+ end
86
+
87
+ ###############################################################################
88
+
89
+ end
90
+
91
+ ###############################################################################
92
+
93
+ end
94
+
95
+ ###############################################################################
@@ -14,6 +14,10 @@ module TerraformWrapper
14
14
 
15
15
  class AWS < Common
16
16
 
17
+ ###############################################################################
18
+
19
+ include TerraformWrapper::Shared::Logging
20
+
17
21
  ###############################################################################
18
22
 
19
23
  @@default_class = "terraform-state"
@@ -25,14 +29,13 @@ module TerraformWrapper
25
29
  ###############################################################################
26
30
 
27
31
  attr_reader :bucket
28
- attr_reader :class
29
32
  attr_reader :key
30
33
  attr_reader :region
31
34
 
32
35
  ###############################################################################
33
36
 
34
- def initialize(service:, code:, identifiers:, overrides: Hash.new)
35
- construct(service: service, code: code, identifiers: identifiers, overrides: overrides)
37
+ def initialize(code:, config:, options:, service:, variables:)
38
+ construct(code: code, config: config, options: options, service: service, variables: variables)
36
39
  end
37
40
 
38
41
  ###############################################################################
@@ -52,39 +55,41 @@ module TerraformWrapper
52
55
  ###############################################################################
53
56
 
54
57
  def specific()
55
- if @overrides.key?("class") and @overrides["class"].kind_of?(String) and not @overrides["class"].strip.empty? then
56
- @class = @overrides["class"]
57
- else
58
- @class = @@default_class
59
- end
58
+ logger.fatal("AWS backend mandatory option 'bucket' has not been set!") unless @options.key?("bucket")
59
+ logger.fatal("AWS backend mandatory option 'region' has not been set!") unless @options.key?("region")
60
60
 
61
- if @overrides.key?("region") and @overrides["region"].kind_of?(String) and not @overrides["region"].strip.empty? then
62
- @region = @overrides["region"]
63
- else
64
- raise "Mandatory identifier 'region' or override 'region' must be set in provided configuration to backend of type: #{@@type}" unless @identifier.key?("region")
65
- raise "Mandatory identifier 'region' is not a string in provided configuration to backend of type: #{@@type}" unless @identifier["region"].kind_of?(String)
66
- raise "Mandatory identifier 'region' is empty in provided configuration to backend of type: #{@@type}" if @identifier["region"].strip.empty?
61
+ bucket = @options["bucket"]
67
62
 
68
- @region = @identifiers["account"].strip.downcase
69
- end
63
+ logger.fatal("AWS backend S3 bucket name must be a String!") unless bucket.kind_of?(String)
64
+ logger.fatal("AWS backend S3 bucket name must not be blank!") if bucket.strip.empty?
70
65
 
71
- if @overrides.key?("bucket") and @overrides["bucket"].kind_of?(String) and not @overrides["bucket"].strip.empty? then
72
- @bucket = @overrides["bucket"]
73
- else
74
- raise "Mandatory identifier 'account' or override 'bucket' must be set in provided configuration to backend of type: #{@@type}" unless @identifier.key?("account")
75
- raise "Mandatory identifier 'account' is not a string in provided configuration to backend of type: #{@@type}" unless @identifier["account"].kind_of?(String)
76
- raise "Mandatory identifier 'account' is empty in provided configuration to backend of type: #{@@type}" if @identifier["account"].strip.empty?
66
+ region = @options["region"]
77
67
 
78
- @bucket = @class + "-" + @region + "-" + @identifiers["account"].strip.downcase
79
- end
68
+ logger.fatal("AWS backend S3 bucket region must be a String!") unless region.kind_of?(String)
69
+ logger.fatal("AWS backend S3 bucket region must not be blank!") if region.strip.empty?
70
+
71
+ key = @options.key?("key") ? @options["key"] : File.join("%{service}", "%{config}", "%{component}" + @@ext)
72
+
73
+ logger.fatal("AWS backend S3 bucket key must be a String!") unless key.kind_of?(String)
74
+ logger.fatal("AWS backend S3 bucket key must not be blank!") if key.strip.empty?
80
75
 
81
- key = File.join(@identifiers.path, @service, @component + @@ext)
76
+ logger.fatal("AWS backend S3 bucket name or key must include %{service}.") unless (bucket.include?("%{service}") or key.include?("%{service}"))
77
+ logger.fatal("AWS backend S3 bucket name or key must include %{config}.") unless (bucket.include?("%{config}") or key.include?("%{config}"))
78
+ logger.fatal("AWS backend S3 bucket name or key must include %{component}.") unless (bucket.include?("%{component}") or key.include?("%{component}"))
82
79
 
83
- if key.length > 1024 then
84
- raise "Key: #{key} is too long for backend of type: #{@@type}"
85
- else
86
- @key = key
80
+ begin
81
+ bucket = bucket % @variables
82
+ region = region % @variables
83
+ key = key % @variables
84
+ rescue
85
+ logger.fatal("AWS backend options contain variables that are not included in the configuration file!")
87
86
  end
87
+
88
+ logger.fatal("Key: #{key} is too long for backend of type: #{@@type}") if key.length > 1024
89
+
90
+ @bucket = bucket
91
+ @region = region
92
+ @key = key
88
93
  end
89
94
 
90
95
  ###############################################################################