cloud_powers 0.2.7 → 0.2.7.1
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.rdoc.mdown +180 -0
- data/Rakefile +5 -0
- data/cloud_powers.gemspec +1 -1
- data/lib/cloud_powers/auth.rb +24 -10
- data/lib/cloud_powers/aws_resources.rb +70 -114
- data/lib/cloud_powers/context.rb +66 -31
- data/lib/cloud_powers/helper.rb +36 -33
- data/lib/cloud_powers/node.rb +2 -2
- data/lib/cloud_powers/self_awareness.rb +18 -11
- data/lib/cloud_powers/synapse/broadcast/broadcast.rb +27 -9
- data/lib/cloud_powers/synapse/pipe/pipe.rb +77 -31
- data/lib/cloud_powers/synapse/queue/board.rb +78 -32
- data/lib/cloud_powers/synapse/queue/queue.rb +164 -38
- data/lib/cloud_powers/synapse/synapse.rb +7 -6
- data/lib/cloud_powers/version.rb +1 -1
- data/lib/cloud_powers/zenv.rb +11 -11
- data/lib/cloud_powers.rb +10 -0
- data/lib/stubs/aws_stubs.rb +132 -4
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f93298a530fa939a15a4e6631b7cda3bc64e558d
|
4
|
+
data.tar.gz: 6f0498a0f808e3aa52cfefe4a58878a6393ae929
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1516b53957f5229ef3ea64ac37f639262060a0337dbcdbae46ff584c5f03f23018cc284097b34f7813186d5fa0f3cbd76b0a5d1100662eeacc65532789e340dc
|
7
|
+
data.tar.gz: 0ab5d2c4213506152e93c21cbcc76153a10c967df3283531615e43898898f8ec8f66816c4be115675856fe67ec2f78f98cf4fb454b02046677c280d570d2bf6b
|
data/Gemfile.lock
CHANGED
data/README.rdoc.mdown
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
# CloudPowers
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
CloudPowers is a wrapper around certain AWS services. It was developed with the _need_ instead of the _resource_ in mind so even though AWS is the only service provider included now, it shouldn't be the only one forever. There are several pieces of the Cloud Power module to talk about:
|
6
|
+
* SelfAwareness: Gathers data about "self"
|
7
|
+
* Synapse: Handles communication needs
|
8
|
+
* Delegator: dynamically include Ruby executables from S3
|
9
|
+
and more...
|
10
|
+
|
11
|
+
* Each module in Cloud Powers is in charge of a specific type of task that helps bring projects together and communicate with the outside world.
|
12
|
+
|
13
|
+
Below is a breakdown of the installation, common services provided and an example or 2 of popular methods.
|
14
|
+
_Better docs are on the way_
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Add this line to your application's Gemfile:
|
19
|
+
|
20
|
+
```Ruby
|
21
|
+
gem 'cloud_powers'
|
22
|
+
```
|
23
|
+
|
24
|
+
then execute:
|
25
|
+
|
26
|
+
$ bundle
|
27
|
+
|
28
|
+
Or install it yourself as:
|
29
|
+
|
30
|
+
$ gem install cloud_powers
|
31
|
+
|
32
|
+
then either:
|
33
|
+
* set environment variables that matches the below group
|
34
|
+
* fill out a .env file and load it from the class that is using CloudPowers, like this
|
35
|
+
Notes:
|
36
|
+
* The code does its best in many cases to make a good guess at some of the configuration
|
37
|
+
for you but if you set them in your system environment variables or in the .env file,
|
38
|
+
it'll have a much better
|
39
|
+
```Ruby
|
40
|
+
require 'dotenv'
|
41
|
+
Dotenv.load('path to your .env file')
|
42
|
+
```
|
43
|
+
_things you need for pre-v1_:
|
44
|
+
```Ruby
|
45
|
+
# Aws access:
|
46
|
+
AWS_ACCESS_KEY_ID=""
|
47
|
+
AWS_SECRET_ACCESS_KEY=""
|
48
|
+
|
49
|
+
# Aws areas and auth-related locations:
|
50
|
+
AWS_REGION=""
|
51
|
+
|
52
|
+
# Aws Build info:
|
53
|
+
AMI_NAME="for Cerebrums to create a node"
|
54
|
+
|
55
|
+
# Aws kinesis stream names
|
56
|
+
STATUS_STREAM="e.g. kinesis stream name"
|
57
|
+
|
58
|
+
# Aws s3 buckets etc
|
59
|
+
TASK_STORAGE="e.g. s3 object name"
|
60
|
+
|
61
|
+
# Aws sqs queue addresses
|
62
|
+
BACKLOG_QUEUE_ADDRESS=""
|
63
|
+
WIP_QUEUE_ADDRESS=""
|
64
|
+
FINISHED_QUEUE_ADDRESS=""
|
65
|
+
```
|
66
|
+
|
67
|
+
## Usage
|
68
|
+
|
69
|
+
### AwsResource
|
70
|
+
* AWS resources that should be used by many services, e.g. Delegator _on EC2_ uses S3, EC2 and SQS to gain knowledge about the
|
71
|
+
context it will be working in.
|
72
|
+
|
73
|
+
|
74
|
+
### Delegator
|
75
|
+
* Helps a node figure out what task it should be running, where its executables are, gathers it/them and loads them.
|
76
|
+
* Lives in the Job and Task instantiation chain
|
77
|
+
|
78
|
+
|
79
|
+
### Helper
|
80
|
+
* useful shared methods, like one that turns a string into snake_case
|
81
|
+
|
82
|
+
|
83
|
+
### SelfAwareness
|
84
|
+
* gets and sets info about the instance -> Neuron/Cerebrum/etc)
|
85
|
+
```Ruby
|
86
|
+
get_awareness!
|
87
|
+
```
|
88
|
+
* retrieves and sets all metadata from the EC2 instance and a few other things like the instance hostname (can find the instance IP from here).
|
89
|
+
* See EC2 metadata for details on the instance/node metadata that is set.
|
90
|
+
* Additionally, the instance public hostname, id and a few others are set using other-than-EC2-metadata methods.
|
91
|
+
|
92
|
+
|
93
|
+
### SmashError
|
94
|
+
|
95
|
+
|
96
|
+
### Storage
|
97
|
+
* S3
|
98
|
+
|
99
|
+
|
100
|
+
### Synapse
|
101
|
+
* A Synapse is used for communicating, usually between nodes and an external source for status updates but the Synapse can handle any kind of information that needs to be passed.
|
102
|
+
* Architecture
|
103
|
+
* The Synapse is a communications module that is broken up into separate types of communication, for separate needs.
|
104
|
+
* There are 2 modules, soon to be 3, inside the Synapse module:
|
105
|
+
|
106
|
+
#### Queue
|
107
|
+
* like a task list or a message board for asynchronous communication
|
108
|
+
* Board <Struct>:
|
109
|
+
* interface with Queue config, data, name, etc.
|
110
|
+
```Ruby
|
111
|
+
default_workflow = Workflow.new
|
112
|
+
board = Board.new(default_workflow)
|
113
|
+
board.name
|
114
|
+
=> 'backlog'
|
115
|
+
board.address
|
116
|
+
=> 'http://aws-url/backlog-board-url'
|
117
|
+
board.next_board # useful because this is a simple state-machine implementation
|
118
|
+
=> 'wip'
|
119
|
+
```
|
120
|
+
Example usage:
|
121
|
+
1. Give the entire stream name or a symbol or string that is found in the .env for the name of the Queue
|
122
|
+
2. provide a block that will create the record that gets sent to the board
|
123
|
+
```Ruby
|
124
|
+
poll(board_name <string|symbol>, opts <optional config Hash>) { block }
|
125
|
+
```
|
126
|
+
or
|
127
|
+
```Ruby
|
128
|
+
poll(:backlog) { |msg, stats| Task.new(instance_id, msg) if stats.success? }
|
129
|
+
```
|
130
|
+
or
|
131
|
+
```Ruby
|
132
|
+
poll(:backlog, wait_time: 30, delete: false) do
|
133
|
+
edited_message = sitrep.merge(foo: 'bar')
|
134
|
+
update = some_method(edited_message)
|
135
|
+
end
|
136
|
+
```
|
137
|
+
#### Pipe
|
138
|
+
* Good for real time information passing, like status updates, results reporting, operations, etc.
|
139
|
+
* The Pipe module is for communicating via streams. Piping is meant to be a way to communicate status, problems and other general info or huge result sets and things of that nature. There can be very high traffic through the pipe or none at all. Very soon (probably V-0.2.6 or 7), Cerebrums will be data consumers, to the Java KCL and MultiLangDaemon level, so keeping messages straight is done via partition ID. The partition ID of any message is to identify which node the message is about or the "batch" or "group" or any other concept like that. So the instance ID is used in nodes like the Neuron and Cerebrum and other identifiers that are deemed best are used in other projects as a batch ID.
|
140
|
+
|
141
|
+
Example usage:
|
142
|
+
```Ruby
|
143
|
+
pipe_to(stream_name <string/symbol>) { &block }
|
144
|
+
```
|
145
|
+
```Ruby
|
146
|
+
pipe_to(:status_queue) { sitrep(content: 'workflowComplete') }
|
147
|
+
```
|
148
|
+
and for multiple records (KCL)
|
149
|
+
```Ruby
|
150
|
+
flow_to(stream_name <string/symbol>) { &block }
|
151
|
+
```
|
152
|
+
```Ruby
|
153
|
+
flow_to(:status_queue) do
|
154
|
+
interesting_instances = neurons.map do |neuron|
|
155
|
+
return neuron if neuron.workflow.done?
|
156
|
+
end
|
157
|
+
find_efficient_neurons(interesting_instances) # this gets sent through the Pipe
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
|
162
|
+
#### Memory
|
163
|
+
* Allows the nodes to have a collective awareness of each other, the environment they work in and other Jobs (Coming soon...)
|
164
|
+
|
165
|
+
|
166
|
+
## Development
|
167
|
+
|
168
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
169
|
+
|
170
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
171
|
+
|
172
|
+
## Contributing
|
173
|
+
|
174
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/adam-phillipps/cloud_powers.
|
175
|
+
|
176
|
+
|
177
|
+
## License
|
178
|
+
|
179
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
180
|
+
|
data/Rakefile
CHANGED
data/cloud_powers.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
15
15
|
It was developed specifically for the Brain project but hopefully can be used
|
16
16
|
in any other ruby project that needs to use cloud service providers' resources.
|
17
17
|
|
18
|
-
Version 0.2.
|
18
|
+
Version 0.2.8 has a little EC2, S3, SQS, SNS, Kinesis, websockets and a few other
|
19
19
|
features you can find in the docs. There is also limitted support for stubbing
|
20
20
|
AWS RESTful API calls. That can come in handy for local testing and extra setup on
|
21
21
|
AWS resource clients.
|
data/lib/cloud_powers/auth.rb
CHANGED
@@ -4,26 +4,40 @@ require_relative 'zenv'
|
|
4
4
|
|
5
5
|
module Smash
|
6
6
|
module CloudPowers
|
7
|
+
# Provides authentication to cloud resources, e.g. AWS
|
7
8
|
module Auth
|
8
9
|
extend Smash::CloudPowers::Zenv
|
9
10
|
|
10
|
-
# This method is
|
11
|
-
# to provide
|
12
|
-
#
|
13
|
-
def self.region
|
14
|
-
zfind(:aws_region) || 'us-west-2'
|
15
|
-
end
|
16
|
-
|
17
|
-
# This method is able to be called before an object is instantiated in order
|
18
|
-
# to provide an Aws::Credentials object that will allow access to all the
|
19
|
-
# resources in the account that zfind searches for, using the "ACCOUNT_NUMBER"
|
11
|
+
# This method is usable before an object is instantiated in order
|
12
|
+
# to provide an <tt>Aws::Credentials</tt> object that will allow access to all the
|
13
|
+
# resources in the account that zfind searches for, using the <tt>ACCOUNT_NUMBER</tt>
|
20
14
|
# key.
|
15
|
+
#
|
16
|
+
# === Returns
|
17
|
+
# <tt>Aws::Credentials</tt>
|
18
|
+
#
|
19
|
+
# === Example
|
20
|
+
# Auth.creds
|
21
|
+
# => Aws::Credentials
|
21
22
|
def self.creds
|
22
23
|
@creds ||= Aws::Credentials.new(
|
23
24
|
zfind(:aws_access_key_id),
|
24
25
|
zfind(:aws_secret_access_key)
|
25
26
|
)
|
26
27
|
end
|
28
|
+
|
29
|
+
# This method is able to be called before an object is instantiated in order
|
30
|
+
# to provide a region in AWS-landia.
|
31
|
+
#
|
32
|
+
# === Returns
|
33
|
+
# The region set in configuration or a <tt>'us-west-2'</tt> default <tt>String</tt>
|
34
|
+
#
|
35
|
+
# === Example
|
36
|
+
# Auth.region
|
37
|
+
# => 'us-east-1'
|
38
|
+
def self.region
|
39
|
+
zfind(:aws_region) || 'us-west-2'
|
40
|
+
end
|
27
41
|
end
|
28
42
|
end
|
29
43
|
end
|
@@ -10,41 +10,28 @@ module Smash
|
|
10
10
|
include Smash::CloudPowers::Zenv
|
11
11
|
|
12
12
|
# Get the region from the environment/context or use a default region for AWS API calls.
|
13
|
-
#
|
13
|
+
#
|
14
|
+
# === Returns
|
15
|
+
# +String+
|
14
16
|
def region
|
15
17
|
zfind(:aws_region) || 'us-west-2'
|
16
18
|
end
|
17
19
|
|
18
20
|
# Get or create an EC2 client and cache that client so that a Context is more well tied together
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
21
|
+
#
|
22
|
+
# Parameters
|
23
|
+
# * opts +Hash+ (optional)
|
24
|
+
# * * stub_responses - defaulted to +false+ but it can be overriden with the desired responses for local testing
|
25
|
+
# * * region - defaulted to use the <tt>#region()</tt> method
|
26
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
27
|
+
#
|
28
|
+
# === Returns
|
29
|
+
# <tt>AWS::EC2::Client</tt>
|
30
|
+
#
|
24
31
|
# === Sample Usage
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# instances: [
|
29
|
-
# { instance_id: 'asd-1234', launch_time: Time.now, state: { name: 'running' }
|
30
|
-
# ] }
|
31
|
-
# describe_instances: {
|
32
|
-
# reservations: [
|
33
|
-
# { instances: [
|
34
|
-
# { instance_id: 'asd-1234', state: { code: 200, name: 'running' } },
|
35
|
-
# ] }] },
|
36
|
-
# describe_images: {
|
37
|
-
# images: [
|
38
|
-
# { image_id: 'asdf', state: 'available' }
|
39
|
-
# ] }
|
40
|
-
# }
|
41
|
-
#
|
42
|
-
# ec2(config) # sets and gets an EC2 client
|
43
|
-
#
|
44
|
-
# images = ec2.describe_images
|
45
|
-
# images.first[:image_id]
|
46
|
-
# # => 'asdf'
|
47
|
-
# ```
|
32
|
+
# images = ec2.describe_images
|
33
|
+
# images.first[:image_id]
|
34
|
+
# # => 'asdf'
|
48
35
|
def ec2(opts = {})
|
49
36
|
config = {
|
50
37
|
stub_responses: false,
|
@@ -59,11 +46,15 @@ module Smash
|
|
59
46
|
# Get an image using a name and filters functionality from EC2. The name is required but the filter defaults
|
60
47
|
# to search for the tag with the key `aminame` because this is the key that most Nodes will search for, when
|
61
48
|
# they gather an AMI to start with.
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
49
|
+
#
|
50
|
+
# Parameters
|
51
|
+
# * opts [Hash]
|
52
|
+
# * * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
53
|
+
# * * region: defaulted to use the `#region()` method
|
54
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
55
|
+
#
|
56
|
+
# === Returns
|
57
|
+
# Aws::EC2::Image
|
67
58
|
def image(name, opts = {})
|
68
59
|
config = {
|
69
60
|
filters: [{ name: 'tag:aminame', values: [name.to_s] }]
|
@@ -74,36 +65,18 @@ module Smash
|
|
74
65
|
end
|
75
66
|
|
76
67
|
# Get or create an Kinesis client and cache that client so that a Context is more well tied together
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
# sequence_number: opts[:sequence_number] || Time.now.to_i.to_s
|
90
|
-
# },
|
91
|
-
# describe_stream: {
|
92
|
-
# stream_description: {
|
93
|
-
# stream_name: opts[:name] || 'somePipe',
|
94
|
-
# stream_arn: 'arnarnarnarnar',
|
95
|
-
# stream_status: 'ACTIVE',
|
96
|
-
# }
|
97
|
-
# }
|
98
|
-
# }
|
99
|
-
# }
|
100
|
-
# }
|
101
|
-
#
|
102
|
-
# kinesis(config) # sets and gets an Kinesis client
|
103
|
-
#
|
104
|
-
# pipe_to('somePipe') { update_body(status: 'waHoo') }
|
105
|
-
# # => sequence_number: '1676151970'
|
106
|
-
# ```
|
68
|
+
# Parameters
|
69
|
+
# * opts <tt>Hash</tt>
|
70
|
+
# * * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
71
|
+
# * * region: defaulted to use the `#region()` method
|
72
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
73
|
+
#
|
74
|
+
# === Returns
|
75
|
+
# AWS::Kinesis client
|
76
|
+
#
|
77
|
+
# === Example
|
78
|
+
# pipe_to('somePipe') { update_body(status: 'waHoo') } # uses Aws::Kinesis::Client.put_recor()
|
79
|
+
# # => sequence_number: '1676151970'
|
107
80
|
def kinesis(opts = {})
|
108
81
|
config = {
|
109
82
|
stub_responses: false,
|
@@ -116,21 +89,19 @@ module Smash
|
|
116
89
|
end
|
117
90
|
|
118
91
|
# Get or create an S3 client and cache that client so that a Context is more well tied together
|
119
|
-
# === @params: opts [Hash]
|
120
|
-
# * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
121
|
-
# * region: defaulted to use the `#region()` method
|
122
|
-
# * AWS::Credentials object, which will also scour the context and environment for your keys
|
123
|
-
# === @returns: AWS::S3 client
|
124
|
-
# === Sample Usage
|
125
|
-
# ```
|
126
|
-
# config = {
|
127
|
-
# stub_responses: {
|
128
92
|
#
|
129
|
-
#
|
130
|
-
#
|
93
|
+
# Parameters
|
94
|
+
# * opts <tt>Hash</tt>
|
95
|
+
# * * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
96
|
+
# * * region: defaulted to use the `#region()` method
|
97
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
131
98
|
#
|
132
|
-
#
|
133
|
-
|
99
|
+
# === Returns
|
100
|
+
# AWS::S3 client
|
101
|
+
#
|
102
|
+
# === Example
|
103
|
+
# expect(s3.head_bucket).to be_empty
|
104
|
+
# # passing expectation
|
134
105
|
def s3(opts = {})
|
135
106
|
config = {
|
136
107
|
stub_responses: false,
|
@@ -143,28 +114,18 @@ module Smash
|
|
143
114
|
end
|
144
115
|
|
145
116
|
# Get or create an SNS client and cache that client so that a Context is more well tied together
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
# publish: {},
|
159
|
-
# subscribe: {}
|
160
|
-
# }
|
161
|
-
# }
|
162
|
-
#
|
163
|
-
# sns(config) # sets and gets an Kinesis client
|
164
|
-
#
|
165
|
-
# create_channel!('testBroadcast')
|
166
|
-
# # => true
|
167
|
-
# ```
|
117
|
+
# Parameters
|
118
|
+
# * opts +Hash+
|
119
|
+
# * * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
120
|
+
# * * region: defaulted to use the `#region()` method
|
121
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
122
|
+
#
|
123
|
+
# === Returns
|
124
|
+
# AWS::SNS client
|
125
|
+
#
|
126
|
+
# === Example
|
127
|
+
# create_channel!('testBroadcast') # uses Aws::SNS::Client
|
128
|
+
# # => true
|
168
129
|
def sns(opts = {})
|
169
130
|
config = {
|
170
131
|
stub_responses: false,
|
@@ -177,23 +138,18 @@ module Smash
|
|
177
138
|
end
|
178
139
|
|
179
140
|
# Get or create an SQS client and cache that client so that a Context is more well tied together
|
180
|
-
# === @params: opts [Hash]
|
181
|
-
# * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
182
|
-
# * region: defaulted to use the `#region()` method
|
183
|
-
# * AWS::Credentials object, which will also scour the context and environment for your keys
|
184
|
-
# === @returns: AWS::SQS client
|
185
|
-
# === Sample Usage
|
186
|
-
# ```
|
187
|
-
# config = stub_responses: {
|
188
|
-
# create_queue: {
|
189
|
-
# queue_url: "https://sqs.us-west-2.amazonaws.com/12345678/#{opts[:name] || 'testQueue'}"
|
190
|
-
# }
|
191
|
-
# }
|
192
141
|
#
|
193
|
-
#
|
142
|
+
# Parameters
|
143
|
+
# * opts <tt>Hash</tt>
|
144
|
+
# * * stub_responses: defaulted to false but it can be overriden with the desired responses for local testing
|
145
|
+
# * * region: defaulted to use the `#region()` method
|
146
|
+
# * * AWS::Credentials object, which will also scour the context and environment for your keys
|
147
|
+
#
|
148
|
+
# === Returns
|
149
|
+
# AWS::SQS client
|
194
150
|
#
|
195
|
-
#
|
196
|
-
#
|
151
|
+
# === Example
|
152
|
+
# create_queue('someQueue') # Uses Aws::SQS::Client
|
197
153
|
def sqs(opts = {})
|
198
154
|
config = {
|
199
155
|
stub_responses: false,
|