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
data/lib/helper.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'inflection'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
# General helper functions for SDK
|
5
|
+
module Helper
|
6
|
+
DEFAULT_REQUIRE_DIRECTORY_OPTIONS = {
|
7
|
+
exclude: ['index'].freeze
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
# Simple conversion to seconds from ms.
|
11
|
+
def self.ms_to_seconds(ms)
|
12
|
+
ms / 1000.0
|
13
|
+
end
|
14
|
+
|
15
|
+
# Given directory and module a map of module procs will be created.
|
16
|
+
# TODO: this is really a dir func map not a proc map
|
17
|
+
def self.dir_proc_map(dir, mod)
|
18
|
+
map = Polyseerio::Helper.dir_to_path_map dir
|
19
|
+
|
20
|
+
map.each { |(_, path)| require path }
|
21
|
+
|
22
|
+
map.each_with_object({}, &Helper.add_to_proc_map(mod))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds a proc method to an accumulator by its name.
|
26
|
+
# TODO: this is really a dir func map not always a proc map.
|
27
|
+
def self.add_to_proc_map(*args)
|
28
|
+
proc do |mod, (name, _), acc|
|
29
|
+
if mod.respond_to? name
|
30
|
+
result = mod.send name
|
31
|
+
|
32
|
+
acc[name] = result unless result.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
acc
|
36
|
+
end.curry.call(*args)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Convert resource string to resource type.
|
40
|
+
def self.resource_to_type(resource)
|
41
|
+
Inflection.singular(resource)
|
42
|
+
end
|
43
|
+
|
44
|
+
# A memoize function that has an optional cache key.
|
45
|
+
def self.memoize_function(func, get_key)
|
46
|
+
lambda do
|
47
|
+
results = {}
|
48
|
+
|
49
|
+
proc do |*args|
|
50
|
+
key = get_key.call(*args) # TODO: assert key is sym?
|
51
|
+
|
52
|
+
if results.key? key
|
53
|
+
results.fetch key
|
54
|
+
else
|
55
|
+
result = func.call(*args)
|
56
|
+
|
57
|
+
results[key] = result
|
58
|
+
|
59
|
+
result
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end.call
|
63
|
+
end
|
64
|
+
|
65
|
+
# Simple identity function.
|
66
|
+
def self.identity(value)
|
67
|
+
proc { |x| x }.call(value)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Maps filename to file path
|
71
|
+
def self.dir_to_path_map(directory, options = {})
|
72
|
+
directory = "#{directory}/*#{options[:extension]}"
|
73
|
+
options = defaults(options, DEFAULT_REQUIRE_DIRECTORY_OPTIONS)
|
74
|
+
|
75
|
+
paths = Dir[directory].select do |file|
|
76
|
+
name = File.basename(file, '.*')
|
77
|
+
|
78
|
+
!options[:exclude].include? name
|
79
|
+
end
|
80
|
+
|
81
|
+
paths.each_with_object({}) do |file, acc|
|
82
|
+
name = File.basename(file, '.*')
|
83
|
+
|
84
|
+
acc[name.to_sym] = file
|
85
|
+
|
86
|
+
acc
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Load an include an entire directory.
|
91
|
+
def self.require_directory(directory, options = {})
|
92
|
+
directory = "#{directory}/*#{options[:extension]}"
|
93
|
+
options = defaults(options, DEFAULT_REQUIRE_DIRECTORY_OPTIONS)
|
94
|
+
|
95
|
+
Dir[directory].select do |file|
|
96
|
+
pathname = Pathname.new(file)
|
97
|
+
|
98
|
+
!options[:exclude].include? pathname.basename
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Format a resouce payload for API consumption
|
103
|
+
def self.format_payload(payload)
|
104
|
+
{ data: { attributes: payload.clone } }
|
105
|
+
end
|
106
|
+
|
107
|
+
# Attempt to geta token.
|
108
|
+
def self.resolve_token(options)
|
109
|
+
return options[:token] unless options[:token].nil?
|
110
|
+
|
111
|
+
if ENV.key? options[:token_env]
|
112
|
+
value = ENV.fetch(options[:token_env], nil)
|
113
|
+
|
114
|
+
return value unless value.nil?
|
115
|
+
end
|
116
|
+
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
# Generates default options.
|
121
|
+
def self.defaults(options, *defaults)
|
122
|
+
result = {}
|
123
|
+
|
124
|
+
defaults.reverse_each do |opts|
|
125
|
+
result.merge!(opts)
|
126
|
+
end
|
127
|
+
|
128
|
+
result.merge!(options)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Used to attach a method to an instance
|
132
|
+
def self.attach_to_instance!(*args)
|
133
|
+
lambda do |instance, (key, value)|
|
134
|
+
instance.instance_eval do
|
135
|
+
define_singleton_method(key, proc { value })
|
136
|
+
end
|
137
|
+
end.curry.call(*args)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Rekey a hash using a remapping hash.
|
141
|
+
def self.rekey(hash, map)
|
142
|
+
hash.each_with_object({}) do |(key, value), acc|
|
143
|
+
if map.key? key
|
144
|
+
acc[map[key]] = value
|
145
|
+
else
|
146
|
+
acc[key] = value
|
147
|
+
end
|
148
|
+
|
149
|
+
acc
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
data/lib/middleware.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'json'
|
3
|
+
require 'response'
|
4
|
+
require 'resource/helper'
|
5
|
+
|
6
|
+
module Polyseerio
|
7
|
+
module Middleware
|
8
|
+
# Pre request middleware.
|
9
|
+
module Pre
|
10
|
+
# Requests arguments run through there.
|
11
|
+
def self.format_arguments
|
12
|
+
proc do |*args|
|
13
|
+
new_args = args
|
14
|
+
|
15
|
+
if new_args.size > 1
|
16
|
+
new_args[1] = Helper.format_payload new_args[1]
|
17
|
+
new_args[1] = new_args[1].to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
new_args
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Post request middleware.
|
26
|
+
module Post
|
27
|
+
# Takes rest-client and response and converts it to internal response.
|
28
|
+
def self.to_response
|
29
|
+
proc do |response|
|
30
|
+
Response.new(response)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Request results run through there.
|
35
|
+
def self.parse_response
|
36
|
+
proc do |response|
|
37
|
+
Resource::Helper.parse_response(response, 0) # TODO: need a cid
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Request rejection (error) middleware.
|
43
|
+
module Reject
|
44
|
+
def self.handle_rejection
|
45
|
+
proc do |error|
|
46
|
+
error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/polyseerio.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'resource/factory'
|
2
|
+
require 'request'
|
3
|
+
require 'middleware'
|
4
|
+
require 'constant'
|
5
|
+
require 'enum'
|
6
|
+
require 'client'
|
7
|
+
require 'url_builder'
|
8
|
+
require 'rest-client'
|
9
|
+
require 'helper'
|
10
|
+
|
11
|
+
# Main Polyseerio module.
|
12
|
+
module Polyseerio
|
13
|
+
# Default client options.
|
14
|
+
DEFAULT_CLIENT_OPTIONS = {
|
15
|
+
agent: {},
|
16
|
+
deduce: true,
|
17
|
+
env: Constant::DEFAULT_ENV,
|
18
|
+
timeout: Constant::DEFAULT_TIMEOUT,
|
19
|
+
environment: Constant::DEFAULT_ENVIRONMENT,
|
20
|
+
token: nil,
|
21
|
+
token_env: Constant::DEFAULT_TOKEN_ENV,
|
22
|
+
upsert_env: true,
|
23
|
+
version: Constant::DEFAULT_API_VERSION
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
# Required resources for constructing a client.
|
27
|
+
REQUIRED_RESOURCES = [
|
28
|
+
Enum::Resource::ALERT,
|
29
|
+
Enum::Resource::CHANNEL,
|
30
|
+
Enum::Resource::ENVIRONMENT,
|
31
|
+
Enum::Resource::EVENT,
|
32
|
+
Enum::Resource::EXPECTATION,
|
33
|
+
Enum::Resource::INSTANCE,
|
34
|
+
Enum::Resource::LOGIC_BLOCK,
|
35
|
+
Enum::Resource::MEMBER,
|
36
|
+
Enum::Resource::SETTING,
|
37
|
+
Enum::Resource::TASK
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
# Maps resources to paths within a Client
|
41
|
+
CLIENT_RESOURCE_PATHS = {
|
42
|
+
Enum::Resource::ALERT => :Alert,
|
43
|
+
Enum::Resource::CHANNEL => :Channel,
|
44
|
+
Enum::Resource::ENVIRONMENT => :Environment,
|
45
|
+
Enum::Resource::EVENT => :Event,
|
46
|
+
Enum::Resource::EXPECTATION => :Expectation,
|
47
|
+
Enum::Resource::INSTANCE => :Instance,
|
48
|
+
Enum::Resource::LOGIC_BLOCK => :LogicBlock,
|
49
|
+
Enum::Resource::MEMBER => :Member,
|
50
|
+
Enum::Resource::SETTING => :Settings,
|
51
|
+
Enum::Resource::TASK => :Task
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
# Create a client and start it's agent.
|
55
|
+
def self.start(*args)
|
56
|
+
client = make(*args)
|
57
|
+
|
58
|
+
client.start_agent
|
59
|
+
end
|
60
|
+
|
61
|
+
@make_call_count = 0
|
62
|
+
|
63
|
+
# Create a client.
|
64
|
+
def self.make(options = {})
|
65
|
+
options = Helper.defaults(options, DEFAULT_CLIENT_OPTIONS)
|
66
|
+
|
67
|
+
cid = @make_call_count
|
68
|
+
|
69
|
+
token = Helper.resolve_token options
|
70
|
+
|
71
|
+
base_url = URL.get_base_url(
|
72
|
+
Constant::DEFAULT_API_BASE_URL,
|
73
|
+
Constant::DEFAULT_API_PROTOCOL,
|
74
|
+
options[:version]
|
75
|
+
)
|
76
|
+
|
77
|
+
if token.nil?
|
78
|
+
raise ArgumentError, 'Could not find an access token. None was passed' \
|
79
|
+
'and non could be found in the environment variable: ' \
|
80
|
+
"#{options[:token_env]}."
|
81
|
+
end
|
82
|
+
|
83
|
+
headers = {
|
84
|
+
Constant::ACCESS_TOKEN_HEADER => token,
|
85
|
+
:content_type => 'application/json'
|
86
|
+
}
|
87
|
+
|
88
|
+
rest_resource = RestClient::Resource.new(
|
89
|
+
base_url,
|
90
|
+
headers: headers,
|
91
|
+
timeout: Helper.ms_to_seconds(options[:timeout])
|
92
|
+
)
|
93
|
+
|
94
|
+
# Create a request instance that uses middleware.
|
95
|
+
request = Request.new(
|
96
|
+
rest_resource,
|
97
|
+
pre: [Middleware::Pre.format_arguments],
|
98
|
+
post: [Middleware::Post.to_response, Middleware::Post.parse_response]
|
99
|
+
)
|
100
|
+
|
101
|
+
resources = REQUIRED_RESOURCES.each_with_object({}) do |resource, acc|
|
102
|
+
acc[resource] = Resource::Factory.make(resource, request, cid, options)
|
103
|
+
|
104
|
+
acc
|
105
|
+
end
|
106
|
+
|
107
|
+
resources = Helper.rekey(resources, CLIENT_RESOURCE_PATHS)
|
108
|
+
|
109
|
+
client = Client.new(cid, request: request, resources: resources)
|
110
|
+
|
111
|
+
@make_call_count += 1
|
112
|
+
|
113
|
+
client
|
114
|
+
end
|
115
|
+
end
|
data/lib/request.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'concurrent'
|
3
|
+
|
4
|
+
module Polyseerio
|
5
|
+
# HTTP request wrapper that can use attached middleware.
|
6
|
+
class Request
|
7
|
+
module Middleware
|
8
|
+
PRE = :pre
|
9
|
+
POST = :post
|
10
|
+
REJECT = :reject
|
11
|
+
end
|
12
|
+
|
13
|
+
INITIALIZE_DEFAULTS = {
|
14
|
+
Middleware::PRE => [],
|
15
|
+
Middleware::POST => [],
|
16
|
+
Middleware::REJECT => []
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def initialize(resource, options = {})
|
20
|
+
# need to ensure taht pre, post, reject are all arrays otherwise raise
|
21
|
+
options = Helper.defaults(options, INITIALIZE_DEFAULTS)
|
22
|
+
|
23
|
+
@resource = resource
|
24
|
+
|
25
|
+
@pre_request = options[Middleware::PRE]
|
26
|
+
@post_request = options[Middleware::POST]
|
27
|
+
@reject_request = options[Middleware::REJECT]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Perform a GET request.
|
31
|
+
def get(*args)
|
32
|
+
execute(:get, *args)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Perform a POST request.
|
36
|
+
def post(*args)
|
37
|
+
execute(:post, *args)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Perform a PUT request.
|
41
|
+
def put(*args)
|
42
|
+
execute(:put, *args)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Perform a DELETE request.
|
46
|
+
def delete(*args)
|
47
|
+
execute(:delete, *args)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Execute a request using pre, post, and reject middleware.
|
53
|
+
#
|
54
|
+
# method - The HTTP method.
|
55
|
+
# ... - Arguments to forward to execute.
|
56
|
+
#
|
57
|
+
# Returns a promise.
|
58
|
+
def execute(method, *args)
|
59
|
+
new_args = args
|
60
|
+
|
61
|
+
@pre_request.each do |middleware|
|
62
|
+
new_args = middleware.call(*new_args)
|
63
|
+
end
|
64
|
+
|
65
|
+
path = new_args.empty? ? '' : new_args.shift
|
66
|
+
|
67
|
+
req = proc do ||
|
68
|
+
@resource[path].send(method, *new_args)
|
69
|
+
end
|
70
|
+
|
71
|
+
post = proc do |result|
|
72
|
+
@post_request.each do |middleware|
|
73
|
+
result = middleware.call(result)
|
74
|
+
end
|
75
|
+
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
79
|
+
Concurrent::Promise.new(&req).on_success(&post)
|
80
|
+
end
|
81
|
+
|
82
|
+
attr_accessor :resource, :pre_request, :post_request, :reject_request
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'sdk/helper'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
module Resource
|
5
|
+
# Base class for any resource.
|
6
|
+
class Base
|
7
|
+
attr_accessor :eid
|
8
|
+
attr_writer :eid
|
9
|
+
|
10
|
+
def initialize(attributes = {})
|
11
|
+
@eid = if attributes.include? :eid
|
12
|
+
attributes[:eid]
|
13
|
+
else
|
14
|
+
Polyseerio::SDK::Helper.resolve_eid(copts)
|
15
|
+
end
|
16
|
+
@attributes = attributes
|
17
|
+
end
|
18
|
+
|
19
|
+
# Set a property hash on the instance.
|
20
|
+
def override_properties(properties)
|
21
|
+
properties.each_with_object(self) do |(key, value), this|
|
22
|
+
this.send(:"#{key}=", value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a copy of class attributes.
|
27
|
+
def properties
|
28
|
+
attributes.clone
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the type of the class.
|
32
|
+
def type
|
33
|
+
self.class.type
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the client options this class was constructed with.
|
37
|
+
def copts
|
38
|
+
self.class.copts
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the client's request object.
|
42
|
+
def request
|
43
|
+
self.class.request
|
44
|
+
end
|
45
|
+
|
46
|
+
# True if the resource is new (not yet saved).
|
47
|
+
def new?
|
48
|
+
id.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_missing(name, *args) # rubocop:disable all
|
52
|
+
# Setter.
|
53
|
+
if name =~ /^(\w+)=$/
|
54
|
+
name = :"#{$1}" # rubocop:disable all
|
55
|
+
|
56
|
+
@attributes[:"#{$1}"] = args[0] # rubocop:disable all
|
57
|
+
end
|
58
|
+
|
59
|
+
# Getter.
|
60
|
+
@attributes.fetch(name, nil)
|
61
|
+
end
|
62
|
+
|
63
|
+
def respond_to_missing?(_method_name)
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
attr_accessor :attributes
|
70
|
+
attr_writer :attributes
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|