polyseerio 0.0.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 +7 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +12 -0
- data/Gemfile +4 -0
- data/HISTORY.md +3 -0
- data/LICENSE +21 -0
- data/Makefile +43 -0
- data/README.md +307 -0
- data/lib/agent/agent.rb +35 -0
- data/lib/agent/default_config.rb +51 -0
- data/lib/agent/enum.rb +35 -0
- data/lib/agent/executor.rb +62 -0
- data/lib/agent/handler/event.rb +32 -0
- data/lib/agent/handler/expectation.rb +10 -0
- data/lib/agent/handler/fact.rb +18 -0
- data/lib/agent/handler/index.rb +15 -0
- data/lib/agent/handler/interface.rb +11 -0
- data/lib/agent/handler/metric.rb +23 -0
- data/lib/agent/handler/process.rb +10 -0
- data/lib/agent/helper.rb +137 -0
- data/lib/client.rb +47 -0
- data/lib/constant.rb +12 -0
- data/lib/enum.rb +82 -0
- data/lib/helper.rb +153 -0
- data/lib/middleware.rb +51 -0
- data/lib/polyseerio.rb +115 -0
- data/lib/request.rb +84 -0
- data/lib/resource/base.rb +73 -0
- data/lib/resource/definition.rb +166 -0
- data/lib/resource/factory.rb +149 -0
- data/lib/resource/helper.rb +91 -0
- data/lib/resource/routine.rb +26 -0
- data/lib/response.rb +27 -0
- data/lib/sdk/factory.rb +34 -0
- data/lib/sdk/helper.rb +50 -0
- data/lib/sdk/method/add_fact.rb +14 -0
- data/lib/sdk/method/add_gauge.rb +14 -0
- data/lib/sdk/method/attach.rb +26 -0
- data/lib/sdk/method/check.rb +11 -0
- data/lib/sdk/method/detach.rb +11 -0
- data/lib/sdk/method/execute.rb +11 -0
- data/lib/sdk/method/fact.rb +11 -0
- data/lib/sdk/method/gauge.rb +11 -0
- data/lib/sdk/method/index.rb +10 -0
- data/lib/sdk/method/message.rb +11 -0
- data/lib/sdk/method/remove.rb +11 -0
- data/lib/sdk/method/save.rb +32 -0
- data/lib/sdk/method/to_json.rb +11 -0
- data/lib/sdk/method/trigger.rb +17 -0
- data/lib/sdk/static/attach.rb +11 -0
- data/lib/sdk/static/check.rb +11 -0
- data/lib/sdk/static/create.rb +21 -0
- data/lib/sdk/static/detach.rb +11 -0
- data/lib/sdk/static/execute.rb +11 -0
- data/lib/sdk/static/find.rb +20 -0
- data/lib/sdk/static/find_by_id.rb +21 -0
- data/lib/sdk/static/find_by_name.rb +28 -0
- data/lib/sdk/static/index.rb +10 -0
- data/lib/sdk/static/message.rb +15 -0
- data/lib/sdk/static/remove.rb +21 -0
- data/lib/sdk/static/trigger.rb +17 -0
- data/lib/sdk/static/update.rb +18 -0
- data/lib/url_builder.rb +55 -0
- data/polyseerio.gemspec +32 -0
- metadata +205 -0
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'enum'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
# Defines polyseer.io resources
|
5
|
+
module Resource
|
6
|
+
module Definition
|
7
|
+
STATICS = :statics
|
8
|
+
METHODS = :methods
|
9
|
+
|
10
|
+
CREATABLE_STATICS = [
|
11
|
+
:create
|
12
|
+
].freeze
|
13
|
+
READABLE_STATICS = [
|
14
|
+
:find,
|
15
|
+
:find_by_id
|
16
|
+
].freeze
|
17
|
+
DELETABLE_STATICS = [
|
18
|
+
:remove
|
19
|
+
].freeze
|
20
|
+
UPDATABLE_STATICS = [
|
21
|
+
:update
|
22
|
+
].freeze
|
23
|
+
CRUD_STATICS = [
|
24
|
+
*CREATABLE_STATICS,
|
25
|
+
*READABLE_STATICS,
|
26
|
+
*DELETABLE_STATICS,
|
27
|
+
*UPDATABLE_STATICS
|
28
|
+
].freeze
|
29
|
+
|
30
|
+
RESOURCE_INSTANCE = [
|
31
|
+
:to_json
|
32
|
+
].freeze
|
33
|
+
|
34
|
+
SAVABLE_INSTANCE = [
|
35
|
+
:save
|
36
|
+
].freeze
|
37
|
+
|
38
|
+
DEFINITION = {
|
39
|
+
Enum::Resource::ALERT => {
|
40
|
+
STATICS => [
|
41
|
+
*CRUD_STATICS,
|
42
|
+
:find_by_name,
|
43
|
+
:trigger
|
44
|
+
],
|
45
|
+
METHODS => [
|
46
|
+
*SAVABLE_INSTANCE,
|
47
|
+
*RESOURCE_INSTANCE,
|
48
|
+
:trigger,
|
49
|
+
:remove
|
50
|
+
]
|
51
|
+
},
|
52
|
+
Enum::Resource::CHANNEL => {
|
53
|
+
STATICS => [
|
54
|
+
*CRUD_STATICS,
|
55
|
+
:find_by_name,
|
56
|
+
:message
|
57
|
+
],
|
58
|
+
METHODS => [
|
59
|
+
*SAVABLE_INSTANCE,
|
60
|
+
*RESOURCE_INSTANCE,
|
61
|
+
:message,
|
62
|
+
:remove
|
63
|
+
]
|
64
|
+
},
|
65
|
+
Enum::Resource::ENVIRONMENT => {
|
66
|
+
STATICS => [
|
67
|
+
*CRUD_STATICS,
|
68
|
+
:find_by_name,
|
69
|
+
:message
|
70
|
+
],
|
71
|
+
METHODS => [
|
72
|
+
*SAVABLE_INSTANCE,
|
73
|
+
*RESOURCE_INSTANCE,
|
74
|
+
:message,
|
75
|
+
:remove
|
76
|
+
]
|
77
|
+
},
|
78
|
+
Enum::Resource::EVENT => {
|
79
|
+
STATICS => [
|
80
|
+
*CREATABLE_STATICS,
|
81
|
+
*READABLE_STATICS
|
82
|
+
],
|
83
|
+
METHODS => [
|
84
|
+
*SAVABLE_INSTANCE,
|
85
|
+
*RESOURCE_INSTANCE
|
86
|
+
]
|
87
|
+
},
|
88
|
+
Enum::Resource::EXPECTATION => {
|
89
|
+
STATICS => [
|
90
|
+
*CRUD_STATICS,
|
91
|
+
:find_by_name,
|
92
|
+
:check
|
93
|
+
],
|
94
|
+
METHODS => [
|
95
|
+
*SAVABLE_INSTANCE,
|
96
|
+
*RESOURCE_INSTANCE,
|
97
|
+
:remove,
|
98
|
+
:check
|
99
|
+
]
|
100
|
+
},
|
101
|
+
Enum::Resource::INSTANCE => {
|
102
|
+
STATICS => [
|
103
|
+
*CRUD_STATICS,
|
104
|
+
:find_by_name,
|
105
|
+
:attach
|
106
|
+
],
|
107
|
+
METHODS => [
|
108
|
+
*SAVABLE_INSTANCE,
|
109
|
+
*RESOURCE_INSTANCE,
|
110
|
+
:add_gauge,
|
111
|
+
:attach,
|
112
|
+
:detach,
|
113
|
+
:fact,
|
114
|
+
:gauge,
|
115
|
+
:remove,
|
116
|
+
:add_fact
|
117
|
+
]
|
118
|
+
},
|
119
|
+
Enum::Resource::LOGIC_BLOCK => {
|
120
|
+
STATICS => [
|
121
|
+
*CRUD_STATICS,
|
122
|
+
:execute
|
123
|
+
],
|
124
|
+
METHODS => [
|
125
|
+
*SAVABLE_INSTANCE,
|
126
|
+
*RESOURCE_INSTANCE,
|
127
|
+
:remove,
|
128
|
+
:execute
|
129
|
+
]
|
130
|
+
},
|
131
|
+
Enum::Resource::MEMBER => {
|
132
|
+
STATICS => [
|
133
|
+
*CRUD_STATICS
|
134
|
+
],
|
135
|
+
METHODS => [
|
136
|
+
*SAVABLE_INSTANCE,
|
137
|
+
*RESOURCE_INSTANCE,
|
138
|
+
:remove
|
139
|
+
]
|
140
|
+
},
|
141
|
+
Enum::Resource::MESSAGE => {
|
142
|
+
STATICS => [
|
143
|
+
*CRUD_STATICS
|
144
|
+
],
|
145
|
+
METHODS => [
|
146
|
+
*SAVABLE_INSTANCE,
|
147
|
+
*RESOURCE_INSTANCE
|
148
|
+
]
|
149
|
+
},
|
150
|
+
Enum::Resource::SETTING => {
|
151
|
+
STATICS => []
|
152
|
+
},
|
153
|
+
Enum::Resource::TASK => {
|
154
|
+
STATICS => [
|
155
|
+
*CRUD_STATICS
|
156
|
+
],
|
157
|
+
METHODS => [
|
158
|
+
*SAVABLE_INSTANCE,
|
159
|
+
*RESOURCE_INSTANCE,
|
160
|
+
:remove
|
161
|
+
]
|
162
|
+
}
|
163
|
+
}.freeze
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'resource/definition'
|
2
|
+
require 'resource/helper'
|
3
|
+
require 'resource/base'
|
4
|
+
require 'sdk/factory'
|
5
|
+
require 'inflection'
|
6
|
+
require 'sdk/helper'
|
7
|
+
|
8
|
+
module Polyseerio
|
9
|
+
module Resource
|
10
|
+
# Resource building methods.
|
11
|
+
module Factory
|
12
|
+
# Determine if a resource definition represents a singleton.
|
13
|
+
def self.defines_singleton?(definition)
|
14
|
+
!definition.key?(:methods) || definition[:methods].empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a static method to a Class.
|
18
|
+
def self.add_static(*args)
|
19
|
+
proc do |(name, method), resource|
|
20
|
+
resource.class_eval do
|
21
|
+
define_singleton_method(name, &method)
|
22
|
+
end
|
23
|
+
end.curry.call(*args)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add an instance method to a Class.
|
27
|
+
def self.add_method(*args)
|
28
|
+
proc do |(name, method), resource|
|
29
|
+
resource.class_eval do
|
30
|
+
define_method(name, &Helper.forward_self(method))
|
31
|
+
end
|
32
|
+
end.curry.call(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Add a collection of static methods to a Class.
|
36
|
+
def self.add_statics(resource, statics = {})
|
37
|
+
return resource if statics.empty?
|
38
|
+
|
39
|
+
statics.each_with_object(resource, &add_static)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Add a collection of instance methods to a Class.
|
43
|
+
def self.add_methods(resource, _request, methods = {})
|
44
|
+
return resource if methods.empty?
|
45
|
+
|
46
|
+
methods.each_with_object(resource, &add_method)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Takes a resource name and creates a class name.
|
50
|
+
def self.to_class_name(resource, cid = '')
|
51
|
+
parts = resource.to_s.split('-').map(&:capitalize)
|
52
|
+
|
53
|
+
parts[parts.size - 1] = Inflection.singular(parts.last)
|
54
|
+
|
55
|
+
name = parts.join ''
|
56
|
+
|
57
|
+
"#{name}#{cid}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create a resource.
|
61
|
+
# TODO: copts are not optional
|
62
|
+
def self.create(type, request, cid, copts = {})
|
63
|
+
resource = Object.const_set(to_class_name(type, cid), Class.new(Base))
|
64
|
+
resource.define_singleton_method(:copts) do
|
65
|
+
copts
|
66
|
+
end
|
67
|
+
|
68
|
+
resource.define_singleton_method(:type) do
|
69
|
+
type
|
70
|
+
end
|
71
|
+
|
72
|
+
resource.define_singleton_method(:request) do
|
73
|
+
request
|
74
|
+
end
|
75
|
+
|
76
|
+
resource.define_singleton_method(:cid) do
|
77
|
+
cid
|
78
|
+
end
|
79
|
+
|
80
|
+
resource
|
81
|
+
end
|
82
|
+
|
83
|
+
# Create a resource.
|
84
|
+
def self._make
|
85
|
+
proc do |type, request, cid, options = {}|
|
86
|
+
unless Definition::DEFINITION.key? type
|
87
|
+
raise ArgumentError, 'Could not find definition for resource: ' \
|
88
|
+
"#{type}"
|
89
|
+
end
|
90
|
+
|
91
|
+
definition = Definition::DEFINITION.fetch(type)
|
92
|
+
|
93
|
+
# Create the resource / class.
|
94
|
+
resource = if defines_singleton? definition
|
95
|
+
{}
|
96
|
+
else
|
97
|
+
create(type, request, cid, options)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add statics.
|
101
|
+
if definition.key? Definition::STATICS
|
102
|
+
statics = SDK::Static.factory(
|
103
|
+
request,
|
104
|
+
type,
|
105
|
+
definition[Definition::STATICS],
|
106
|
+
options
|
107
|
+
)
|
108
|
+
|
109
|
+
add_statics(resource, statics)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Add methods.
|
113
|
+
if definition.key? Definition::METHODS
|
114
|
+
methods = SDK::Method.factory(
|
115
|
+
request,
|
116
|
+
type,
|
117
|
+
definition[Definition::METHODS],
|
118
|
+
options
|
119
|
+
)
|
120
|
+
|
121
|
+
add_methods(resource, request, methods)
|
122
|
+
end
|
123
|
+
|
124
|
+
resource
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Generate a memoize key based on factory arguments
|
129
|
+
def self.get_memoize_key(resource, _request, cid, _options = {})
|
130
|
+
:"#{resource}_#{cid}"
|
131
|
+
end
|
132
|
+
|
133
|
+
# Convenience for get_memoize_key in proc form.
|
134
|
+
def self.memoize_key
|
135
|
+
proc do |*args|
|
136
|
+
get_memoize_key(*args)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# TODO: ideal API would be memoize(:make, memoize_key) - in future.
|
141
|
+
@make = Polyseerio::Helper.memoize_function(_make, memoize_key)
|
142
|
+
|
143
|
+
# Memoized calls to make. A little ugly, would like a better memoize API.
|
144
|
+
def self.make(*args)
|
145
|
+
@make.call(*args)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Polyseerio
|
2
|
+
module Resource
|
3
|
+
# Helper methods for building and working with resources
|
4
|
+
module Helper
|
5
|
+
EID_REGEX = Regexp.new('/environments/([\da-z\.-]+)/')
|
6
|
+
|
7
|
+
# Forward self as first argument. Used for method procs.
|
8
|
+
def self.forward_self(func)
|
9
|
+
proc do |*args|
|
10
|
+
func.call(self, *args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Given a request path an eid is returned or nil
|
15
|
+
def self.get_eid_from_resource_path(path)
|
16
|
+
result = EID_REGEX.match path
|
17
|
+
|
18
|
+
return result if result.nil?
|
19
|
+
|
20
|
+
result[1]
|
21
|
+
end
|
22
|
+
|
23
|
+
# True if the response is a resource based response
|
24
|
+
def self.resource_response?(body)
|
25
|
+
body.key?(:data) &&
|
26
|
+
(resource?(body[:data]) || resource_collection?(body[:data]))
|
27
|
+
end
|
28
|
+
|
29
|
+
# True if response data is a resource collection (alias)
|
30
|
+
def self.resource_collection?(data)
|
31
|
+
data.is_a? Array
|
32
|
+
end
|
33
|
+
|
34
|
+
# True if response data is a resource collection (alias)
|
35
|
+
def self.resource?(data)
|
36
|
+
data.is_a? Hash
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convert parsed response data into an instance
|
40
|
+
# TODO: hard to unit-test (due to Factory.make)
|
41
|
+
def self.to_instance(data, _meta, _included, cid)
|
42
|
+
type = data.fetch(:type, nil)
|
43
|
+
id = data.fetch(:id, nil)
|
44
|
+
attributes = data.fetch(:attributes, {})
|
45
|
+
|
46
|
+
attributes[:id] = id
|
47
|
+
|
48
|
+
# parse_response would only eve be called once the client has been
|
49
|
+
# constructed meaning in order to get the class we simply need to
|
50
|
+
# pass the type and cid. make is memoized on the type and cid args.
|
51
|
+
resource = Factory.make(type, nil, cid)
|
52
|
+
|
53
|
+
resource.new(attributes) # TODO: need to include meta
|
54
|
+
end
|
55
|
+
|
56
|
+
# Parse a resource response
|
57
|
+
# TODO: hard to unit-test (due to Factory.make)
|
58
|
+
def self.parse_resource_response(response, cid)
|
59
|
+
body = response.body
|
60
|
+
meta = body[:meta] || {}
|
61
|
+
included = body[:included] || {}
|
62
|
+
data = body[:data]
|
63
|
+
|
64
|
+
eid = get_eid_from_resource_path response.request.uri.path
|
65
|
+
|
66
|
+
# attach eid if we have attributes and an id
|
67
|
+
# would need to occur for each?????
|
68
|
+
data[:attributes][:eid] = eid if !eid.nil? && data.key?(:attributes)
|
69
|
+
|
70
|
+
# if resource collection if so map return
|
71
|
+
if resource_collection? data
|
72
|
+
return data.map do |item|
|
73
|
+
to_instance(item, meta, included, cid)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# convert to instance
|
78
|
+
to_instance(data, meta, included, cid)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Parse a response
|
82
|
+
def self.parse_response(response, cid)
|
83
|
+
if resource_response? response.body
|
84
|
+
return parse_resource_response(response, cid)
|
85
|
+
end
|
86
|
+
|
87
|
+
response
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
module Resource
|
5
|
+
# Reusable resource routines.
|
6
|
+
module Routine
|
7
|
+
DEFAULT_UPSERT_OPTIONS = {
|
8
|
+
key: :name
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
# Upsert a resource.
|
12
|
+
def self.upsert(resource, attributes)
|
13
|
+
unless attributes.key? :name
|
14
|
+
raise ArgumentError, 'Passed attributes must contain a name.'
|
15
|
+
end
|
16
|
+
|
17
|
+
resource.find_by_name(attributes[:name])
|
18
|
+
.then(proc do |reason|
|
19
|
+
raise reason if reason.http_code != 404
|
20
|
+
|
21
|
+
resource.create(attributes).execute.value
|
22
|
+
end)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/response.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'concurrent'
|
3
|
+
|
4
|
+
module Polyseerio
|
5
|
+
# HTTP response wrapper.
|
6
|
+
class Response
|
7
|
+
def initialize(rest_response)
|
8
|
+
@rest_response = rest_response
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the response body.
|
12
|
+
#
|
13
|
+
# NOTE: This function is memoized.
|
14
|
+
def body
|
15
|
+
@body_result ||= JSON.parse(@rest_response.body, symbolize_names: true)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the original request obect.
|
19
|
+
def request
|
20
|
+
@rest_response.request
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_accessor :rest_response
|
26
|
+
end
|
27
|
+
end
|