aws-sdk-resources 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/aws-sdk-resources.rb +36 -0
- data/lib/aws-sdk-resources/batch.rb +100 -0
- data/lib/aws-sdk-resources/builder.rb +86 -0
- data/lib/aws-sdk-resources/builder_sources.rb +136 -0
- data/lib/aws-sdk-resources/collection.rb +137 -0
- data/lib/aws-sdk-resources/definition.rb +363 -0
- data/lib/aws-sdk-resources/documenter.rb +18 -0
- data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +269 -0
- data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +47 -0
- data/lib/aws-sdk-resources/documenter/enumerate_data_operation_documenter.rb +50 -0
- data/lib/aws-sdk-resources/documenter/enumerate_resource_operation_documenter.rb +69 -0
- data/lib/aws-sdk-resources/documenter/operation_documenter.rb +43 -0
- data/lib/aws-sdk-resources/documenter/reference_operation_documenter.rb +102 -0
- data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +65 -0
- data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +81 -0
- data/lib/aws-sdk-resources/errors.rb +15 -0
- data/lib/aws-sdk-resources/operation_methods.rb +53 -0
- data/lib/aws-sdk-resources/operations.rb +294 -0
- data/lib/aws-sdk-resources/options.rb +23 -0
- data/lib/aws-sdk-resources/request.rb +39 -0
- data/lib/aws-sdk-resources/request_params.rb +225 -0
- data/lib/aws-sdk-resources/resource.rb +137 -0
- data/lib/aws-sdk-resources/source.rb +39 -0
- data/lib/aws-sdk-resources/validator.rb +152 -0
- data/lib/aws-sdk-resources/validator/context.rb +60 -0
- data/lib/aws-sdk-resources/validator/identifier_validator.rb +107 -0
- data/lib/aws-sdk-resources/validator/operation_validator.rb +352 -0
- data/lib/aws-sdk-resources/validator/rule.rb +45 -0
- data/lib/aws-sdk-resources/validator/shape_validator.rb +47 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2258aa532dd93701acb1dd469ef9d45c2ffac526
|
4
|
+
data.tar.gz: 6d2aacfaae954de3f151c22a5da7455922519f5d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a319ba138c25889d126981b916917f7a11eb02d2445074f74b81d722d2ecaff841fadfa6722153a4aa8c28855da2f50d46de4e2b9dae7d2ddd544da4ccaf78a6
|
7
|
+
data.tar.gz: 9508bad7873f5f233c91eff4dac292c99aead6dc3c4748f1f0312e39139464125256457d61090cad9aa0d5d139044a110f4679a76f9f8992315dd8eaa2de16ef
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'aws-sdk-core'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Resources
|
5
|
+
|
6
|
+
autoload :Batch, 'aws-sdk-resources/batch'
|
7
|
+
autoload :Builder, 'aws-sdk-resources/builder'
|
8
|
+
autoload :BuilderSources, 'aws-sdk-resources/builder_sources'
|
9
|
+
autoload :Collection, 'aws-sdk-resources/collection'
|
10
|
+
autoload :Definition, 'aws-sdk-resources/definition'
|
11
|
+
autoload :Documenter, 'aws-sdk-resources/documenter'
|
12
|
+
autoload :Errors, 'aws-sdk-resources/errors'
|
13
|
+
autoload :Operations, 'aws-sdk-resources/operations'
|
14
|
+
autoload :OperationMethods, 'aws-sdk-resources/operation_methods'
|
15
|
+
autoload :Options, 'aws-sdk-resources/options'
|
16
|
+
autoload :Request, 'aws-sdk-resources/request'
|
17
|
+
autoload :RequestParams, 'aws-sdk-resources/request_params'
|
18
|
+
autoload :Resource, 'aws-sdk-resources/resource'
|
19
|
+
autoload :Source, 'aws-sdk-resources/source'
|
20
|
+
autoload :Validator, 'aws-sdk-resources/validator'
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
service_added do |_, svc_module, options|
|
25
|
+
definition = options[:resources]
|
26
|
+
definition = case definition
|
27
|
+
when nil then Resources::Definition.new({})
|
28
|
+
when Resources::Definition then definition
|
29
|
+
when Hash then Resources::Definition.new(definition)
|
30
|
+
when String then Resources::Definition.new(Aws.load_json(definition), source_path: definition)
|
31
|
+
else raise ArgumentError, "invalid resource definition #{definition}"
|
32
|
+
end
|
33
|
+
definition.apply(svc_module)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Aws
|
2
|
+
module Resources
|
3
|
+
|
4
|
+
# A batch provides array like access to a list of resources. Batches
|
5
|
+
# also provide the ability to invoke certain operations against
|
6
|
+
# the entire batch.
|
7
|
+
#
|
8
|
+
# ## Getting a Batch
|
9
|
+
#
|
10
|
+
# You should normally not need to construct a batch. Anywhere a list
|
11
|
+
# of resources is returned, they are returned as a batch:
|
12
|
+
#
|
13
|
+
# # security_groups is a batch
|
14
|
+
# security_groups = ec2.instance('i-12345678').security_groups
|
15
|
+
#
|
16
|
+
# When the possible number of resources is unknown or large, the
|
17
|
+
# resources will be returned in a collection. Collections can enumerate
|
18
|
+
# individual resources or batches. They manage paging over the
|
19
|
+
# AWS request/responses to produce batches.
|
20
|
+
#
|
21
|
+
# # objects is a collection
|
22
|
+
# objects = s3.bucket('aws-sdk').objects
|
23
|
+
#
|
24
|
+
# You can invoke batch operations against collections and they will
|
25
|
+
# invoke them on each batch.
|
26
|
+
#
|
27
|
+
# # delets all all objects in this bucket in batches of 1k
|
28
|
+
# objects = s3.bucket('aws-sdk').objects
|
29
|
+
# objects.delete
|
30
|
+
#
|
31
|
+
# ## Batch Operations
|
32
|
+
#
|
33
|
+
# Batches provide operations that operate on the entire batch. These
|
34
|
+
# operations are only defined for resources where the AWS API accepts
|
35
|
+
# multiple inputs. This means a batch operation for n elements will
|
36
|
+
# only make one request.
|
37
|
+
#
|
38
|
+
# Resource classes document each of their own batch operations.
|
39
|
+
# See {S3::Object} for an example.
|
40
|
+
#
|
41
|
+
class Batch
|
42
|
+
|
43
|
+
include Enumerable
|
44
|
+
extend OperationMethods
|
45
|
+
|
46
|
+
# @param [Array<Resource>] resources
|
47
|
+
# @option options [Seahorse::Client::Response] :response
|
48
|
+
def initialize(resources, options = {})
|
49
|
+
@resources = resources
|
50
|
+
@options = options
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Seahorse::Client::Response, nil]
|
54
|
+
def response
|
55
|
+
@options[:response]
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Integer]
|
59
|
+
def size
|
60
|
+
@resources.size
|
61
|
+
end
|
62
|
+
|
63
|
+
alias count size
|
64
|
+
|
65
|
+
# @param [Integer] index
|
66
|
+
# @return [Resource]
|
67
|
+
def [](index)
|
68
|
+
@resources[index]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Yields each resource of the batch, one at a time.
|
72
|
+
def each(&block)
|
73
|
+
enum = @resources.to_enum
|
74
|
+
enum.each(&block) if block_given?
|
75
|
+
enum
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param [Integer] count
|
79
|
+
# @return [Resource, Batch]
|
80
|
+
def first(count = nil)
|
81
|
+
if count
|
82
|
+
self.class.new(@resources.first(count), @options)
|
83
|
+
else
|
84
|
+
@resources.first
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [Boolean]
|
89
|
+
def empty?
|
90
|
+
@resources.empty?
|
91
|
+
end
|
92
|
+
|
93
|
+
# @api private
|
94
|
+
def inspect
|
95
|
+
"#<#{self.class.name} resources=#{@resources}>"
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'jamespath'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Resources
|
5
|
+
|
6
|
+
# A {Builder} construct resource objects. It extracts resource identifiers
|
7
|
+
# for the objects it builds from another resource object and/or an
|
8
|
+
# AWS response.
|
9
|
+
class Builder
|
10
|
+
|
11
|
+
include Options
|
12
|
+
|
13
|
+
# @option options [required, Class<Resource>] resource_class
|
14
|
+
# @option options [Array<BuilderSources::Source>] :sources ([])
|
15
|
+
def initialize(options = {})
|
16
|
+
@resource_class = options[:resource_class]
|
17
|
+
@sources = options[:sources] || []
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Class<Resource>]
|
21
|
+
attr_reader :resource_class
|
22
|
+
|
23
|
+
# @return [Array<BuilderSources::Source>] A list of resource
|
24
|
+
# identifier sources.
|
25
|
+
attr_reader :sources
|
26
|
+
|
27
|
+
# @return [Boolean] Returns `true` if this builder returns an array
|
28
|
+
# of resource objects from {#build}.
|
29
|
+
def plural?
|
30
|
+
@sources.any?(&:plural?)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @option [Resource] :resource
|
34
|
+
# @option [Seahorse::Client::Response] :response
|
35
|
+
# @return [Resource, Array<Resource>] Returns a resource object or an
|
36
|
+
# array of resource objects if {#plural?}.
|
37
|
+
def build(options = {})
|
38
|
+
identifier_map = @sources.each.with_object({}) do |source, hash|
|
39
|
+
hash[source.target] = source.extract(options)
|
40
|
+
end
|
41
|
+
if plural?
|
42
|
+
build_batch(identifier_map, options)
|
43
|
+
else
|
44
|
+
build_one(identifier_map, options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def build_batch(identifier_map, options, &block)
|
51
|
+
resources = (0...resource_count(identifier_map)).collect do |n|
|
52
|
+
identifiers = @sources.each.with_object({}) do |source, identifiers|
|
53
|
+
identifiers[source.target] = source.plural? ?
|
54
|
+
identifier_map[source.target][n] :
|
55
|
+
identifier_map[source.target]
|
56
|
+
end
|
57
|
+
resource = build_one(identifiers, options)
|
58
|
+
yield(resource) if block_given?
|
59
|
+
resource
|
60
|
+
end
|
61
|
+
resource_class::Batch.new(resources, options)
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_one(identifiers, options)
|
65
|
+
if identifiers.values.any?(&:nil?)
|
66
|
+
nil
|
67
|
+
else
|
68
|
+
@resource_class.new(identifiers.merge(
|
69
|
+
client: client(options)
|
70
|
+
))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def resource_count(identifier_map)
|
75
|
+
identifier_map.values.inject(0) do |max, values|
|
76
|
+
[max, values.is_a?(Array) ? values.size : 0].max
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def client(options)
|
81
|
+
Array(options[:resource]).first.client
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'jamespath'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Resources
|
5
|
+
module BuilderSources
|
6
|
+
|
7
|
+
# Used by a {Builder} to extract resource identifiers from an AWS
|
8
|
+
# response or from another resource object.
|
9
|
+
#
|
10
|
+
# This is the base class of each of the builder sources. Each
|
11
|
+
# source is responsible for extracting a single identifier.
|
12
|
+
#
|
13
|
+
# @see {Argument}
|
14
|
+
# @see {Identifier}
|
15
|
+
# @see {DataMember}
|
16
|
+
# @see {RequestParameter}
|
17
|
+
# @see {ResponsePath}
|
18
|
+
#
|
19
|
+
class Base
|
20
|
+
|
21
|
+
include Options
|
22
|
+
|
23
|
+
# @param [String] source
|
24
|
+
# @param [Symbol] target
|
25
|
+
def initialize(source, target)
|
26
|
+
@source = source
|
27
|
+
@target = target.to_sym
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
attr_reader :source
|
32
|
+
|
33
|
+
# @return [Symbol]
|
34
|
+
attr_reader :target
|
35
|
+
|
36
|
+
# @return [Boolean]
|
37
|
+
def plural?
|
38
|
+
source.include?('[')
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param [Hash] options
|
42
|
+
# @return [String, Array<String>]
|
43
|
+
def extract(options)
|
44
|
+
raise NotImplementedError, 'must be defined in subclasses'
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Argument < Base
|
50
|
+
|
51
|
+
def initialize(target)
|
52
|
+
super(target.to_s, target)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @option [required, String] :argument
|
56
|
+
def extract(options)
|
57
|
+
(options[:args] || []).first
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# Extracts an identifier from a parent resource identifier. Used
|
63
|
+
# when building a {Resource} from the context of another resource.
|
64
|
+
class Identifier < Base
|
65
|
+
|
66
|
+
# @option [required, Resource] :resource
|
67
|
+
def extract(options)
|
68
|
+
resource(options).identifiers[source.to_sym]
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def resource(options)
|
74
|
+
option(:resource, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
# Extracts an identifier from the data of a parent resource. Used
|
80
|
+
# when building a {Resource} from the context of another resource.
|
81
|
+
class DataMember < Base
|
82
|
+
|
83
|
+
# @option [required, Resource] :resource
|
84
|
+
def extract(options)
|
85
|
+
Jamespath.search(source, resource(options).data)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def resource(options)
|
91
|
+
option(:resource, options)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
# Extracts an identifier from the request parameters used to generate
|
97
|
+
# a response. Used when building a {Resource} object from the response
|
98
|
+
# of an operation.
|
99
|
+
class RequestParameter < Base
|
100
|
+
|
101
|
+
# @option [required, Seahorse::Client::Response] :response
|
102
|
+
def extract(options)
|
103
|
+
response(options).context.params[source.to_sym]
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def response(options)
|
109
|
+
option(:response, options)
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
# Extracts an identifier from the data of a response. Used when
|
115
|
+
# building a {Resource} object from the response of an operation.
|
116
|
+
class ResponsePath < Base
|
117
|
+
|
118
|
+
# @option [required, Seahorse::Client::Response] :response
|
119
|
+
def extract(options)
|
120
|
+
if source == '$'
|
121
|
+
response(options).data
|
122
|
+
else
|
123
|
+
Jamespath.search(source, response(options).data)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def response(options)
|
130
|
+
option(:response, options)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Aws
|
2
|
+
module Resources
|
3
|
+
class Collection
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
# @param [EnumerateResourceOperation] operation
|
8
|
+
# @option (see EnumerateResourceOperation#call)
|
9
|
+
# @api private
|
10
|
+
def initialize(operation, options)
|
11
|
+
@operation = operation
|
12
|
+
@options = options
|
13
|
+
reject_limit_param(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Enumerator<Resource>]
|
17
|
+
def each(&block)
|
18
|
+
if block_given?
|
19
|
+
batches.each { |batch| batch.each(&block) }
|
20
|
+
else
|
21
|
+
self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Enumerator<Batch>]
|
26
|
+
def batches(&block)
|
27
|
+
@operation.batches(@options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Specifies the maximum number of items to enumerate.
|
31
|
+
#
|
32
|
+
# collection.limit(10).each do |resource|
|
33
|
+
# # yields at most 10 times
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# @param [Integer] limit The maximum number of items to yield
|
37
|
+
# via {#each} or {#batches}.
|
38
|
+
# @return [Collection]
|
39
|
+
def limit(limit)
|
40
|
+
self.class.new(@operation, @options.merge(limit: limit))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Specifies max size of each batch. Some services may return fewer
|
44
|
+
# than `size` number of items per request.
|
45
|
+
#
|
46
|
+
# @example Enumerate the collection in batches with a max size
|
47
|
+
#
|
48
|
+
# collection.batch_size(10).batches.each do |batch|
|
49
|
+
# # batch has at most 10 items
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# @param [Integer] size
|
53
|
+
# @return [Collection]
|
54
|
+
def batch_size(size)
|
55
|
+
if limit_key
|
56
|
+
self.class.new(@operation, @options.merge(batch_size: size))
|
57
|
+
else
|
58
|
+
resource = resource_class.name
|
59
|
+
method_name = @operation.request.method_name
|
60
|
+
msg = "batch size not supported by #{resource}##{method_name}"
|
61
|
+
raise NotImplementedError, msg
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the first resource from the collection.
|
66
|
+
#
|
67
|
+
# resource = collection.first
|
68
|
+
#
|
69
|
+
# If you pass a count, then the first `count` resources are returned in
|
70
|
+
# a single batch. See the resource specific batch documentation for
|
71
|
+
# a list of supported batch methods.
|
72
|
+
#
|
73
|
+
# resources = collection.first(10)
|
74
|
+
# resources.delete
|
75
|
+
#
|
76
|
+
# @return [Resource, Batch]
|
77
|
+
def first(count = 1)
|
78
|
+
if count == 1
|
79
|
+
limit(1).to_a.first
|
80
|
+
else
|
81
|
+
resource_class::Batch.new(limit(count).to_a)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @api private
|
86
|
+
def respond_to?(method_name, *args)
|
87
|
+
if resource_class::Batch.instance_methods.include?(method_name.to_sym)
|
88
|
+
true
|
89
|
+
else
|
90
|
+
super
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @api private
|
95
|
+
def method_missing(method_name, *args, &block)
|
96
|
+
if respond_to?(method_name)
|
97
|
+
batches.each do |batch|
|
98
|
+
batch.send(method_name, *args, &block)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
super
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# @api private
|
106
|
+
def inspect
|
107
|
+
parts = {}
|
108
|
+
parts[:type] = resource_class.name
|
109
|
+
parts[:limit] = @options[:limit]
|
110
|
+
parts[:batch_size] = @options[:batch_size] if limit_key
|
111
|
+
parts[:params] = @options[:params] || {}
|
112
|
+
parts = parts.inject("") {|s,(k,v)| s << " #{k}=#{v.inspect}" }
|
113
|
+
['#<', self.class.name, parts, '>'].join
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# @api private
|
119
|
+
def limit_key
|
120
|
+
@operation.limit_key
|
121
|
+
end
|
122
|
+
|
123
|
+
def reject_limit_param(options)
|
124
|
+
if options[:params] && options[:params][limit_key]
|
125
|
+
msg = "invalid option :#{limit_key}, call #limit or #batch_size "
|
126
|
+
msg << "on the returned Aws::Resources::Collection instead"
|
127
|
+
raise ArgumentError, msg
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def resource_class
|
132
|
+
@operation.builder.resource_class
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|