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/agent/enum.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Polyseerio
|
2
|
+
module Agent
|
3
|
+
module Enum
|
4
|
+
module Expectation
|
5
|
+
IS_ALIVE = :is_alive
|
6
|
+
end
|
7
|
+
|
8
|
+
module Event
|
9
|
+
START = :start
|
10
|
+
STOP = :stop
|
11
|
+
end
|
12
|
+
|
13
|
+
module Fact
|
14
|
+
PID = :pid
|
15
|
+
GID = :gid
|
16
|
+
end
|
17
|
+
|
18
|
+
module Signal
|
19
|
+
SIGHUP = :HUP
|
20
|
+
SIGINT = :INT
|
21
|
+
SIGTERM = :TERM
|
22
|
+
end
|
23
|
+
|
24
|
+
module Process
|
25
|
+
EXIT = :exit
|
26
|
+
end
|
27
|
+
|
28
|
+
module Metric
|
29
|
+
MEMORY = :memory
|
30
|
+
CPU = :cpu
|
31
|
+
UPTIME = :uptime
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
require 'helper'
|
3
|
+
require 'resource/routine'
|
4
|
+
require 'agent/handler/index'
|
5
|
+
require 'agent/helper'
|
6
|
+
require 'agent/default_config'
|
7
|
+
|
8
|
+
module Polyseerio
|
9
|
+
module Agent
|
10
|
+
# Agent executor functions.
|
11
|
+
module Executor
|
12
|
+
# Setsup a client's agent.
|
13
|
+
def self.setup(client, options = {})
|
14
|
+
options = Polyseerio::Helper.defaults(options, DEFAULT_CONFIG)
|
15
|
+
|
16
|
+
Concurrent::Promise.new do
|
17
|
+
if options[:attach]
|
18
|
+
name = Helper.resolve_name(options)
|
19
|
+
|
20
|
+
# Resolve the instance.
|
21
|
+
# TODO: better handle failure to upsert.
|
22
|
+
instance = Resource::Routine.upsert(
|
23
|
+
client.Instance,
|
24
|
+
name: name
|
25
|
+
).execute.value
|
26
|
+
|
27
|
+
# Set the client's instance.
|
28
|
+
client.instance = instance
|
29
|
+
|
30
|
+
# Create a setup handler.
|
31
|
+
handler_options = Helper.extract_handler_options options
|
32
|
+
setup_handler = Helper.setup_with_handler(
|
33
|
+
Polyseerio::Agent::Handler::MAP,
|
34
|
+
client,
|
35
|
+
handler_options
|
36
|
+
)
|
37
|
+
|
38
|
+
# Gather setup operations.
|
39
|
+
setups = handler_options.map { |key, _| setup_handler.call(key) }
|
40
|
+
|
41
|
+
# Perform setups.
|
42
|
+
Concurrent::Promise.zip(*setups).execute.value
|
43
|
+
|
44
|
+
# Start monitoring.
|
45
|
+
instance.attach.execute.value
|
46
|
+
|
47
|
+
instance
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Tearsdown a client's agent.
|
53
|
+
def self.teardown(client, instance)
|
54
|
+
Concurrent::Promise.new do
|
55
|
+
teardown_handler('event', client)
|
56
|
+
|
57
|
+
instance.detach.excecute.value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'agent/enum'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
module Agent
|
5
|
+
# Introduce event handlers.
|
6
|
+
module Handler
|
7
|
+
include Agent::Enum
|
8
|
+
|
9
|
+
def self.event
|
10
|
+
{
|
11
|
+
Event::START => proc do |_config, client|
|
12
|
+
client.Event.create(
|
13
|
+
name: "#{client.instance.name} agent has started.",
|
14
|
+
color: Polyseerio::Enum::Color::GREEN,
|
15
|
+
icon: Polyseerio::Enum::Icon::CHAIN
|
16
|
+
)
|
17
|
+
end,
|
18
|
+
|
19
|
+
Event::STOP => {
|
20
|
+
Interface::TEARDOWN => proc do |_config, client|
|
21
|
+
client.Event.create(
|
22
|
+
name: "#{client.instance.name} agent has stopped.",
|
23
|
+
color: Polyseerio::Enum::Color::ORANGE,
|
24
|
+
icon: Polyseerio::Enum::Icon::CHAIN_BROKER
|
25
|
+
)
|
26
|
+
end
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Polyseerio
|
2
|
+
module Agent
|
3
|
+
# Introduce fact handlers.
|
4
|
+
module Handler
|
5
|
+
def self.fact
|
6
|
+
{
|
7
|
+
Fact::PID => proc do |_config, client|
|
8
|
+
client.instance.set_fact('pid', ::Process.pid)
|
9
|
+
end,
|
10
|
+
|
11
|
+
Fact::GID => proc do |_config, client|
|
12
|
+
client.instance.set_fact('gid', ::Process.gid)
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
module Agent
|
5
|
+
# Contains handlers and handler map.
|
6
|
+
module Handler
|
7
|
+
MAP = Polyseerio::Helper.dir_proc_map(File.dirname(__FILE__), self)
|
8
|
+
|
9
|
+
# Extracts handler type options from agent options.
|
10
|
+
def self.extract_options(options)
|
11
|
+
options.select { |key, _| MAP.key? key }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Polyseerio
|
2
|
+
module Agent
|
3
|
+
# Introduce metric handlers.
|
4
|
+
module Handler
|
5
|
+
def self.metric
|
6
|
+
{
|
7
|
+
Metric::MEMORY => proc do |_config, client|
|
8
|
+
client.instance.add_gauge 'memory', 0
|
9
|
+
end,
|
10
|
+
|
11
|
+
Metric::CPU => proc do |_config, client|
|
12
|
+
client.instance.add_gauge 'cpu_user', 0
|
13
|
+
client.instance.add_gauge 'cpu_system', 0
|
14
|
+
end,
|
15
|
+
|
16
|
+
Metric::UPTIME => proc do |_config, client|
|
17
|
+
client.instance.add_gauge 'uptime', 0
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/agent/helper.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'functional'
|
2
|
+
require 'concurrent'
|
3
|
+
require 'agent/handler/index'
|
4
|
+
require 'agent/handler/interface'
|
5
|
+
|
6
|
+
module Polyseerio
|
7
|
+
module Agent
|
8
|
+
# Helper functions for Agent
|
9
|
+
module Helper
|
10
|
+
# Returns an iterator for a handler subtype.
|
11
|
+
def self.create_subtype_iterator(handlers, iteratee, *args)
|
12
|
+
proc do |key, value|
|
13
|
+
if handlers.key? key.to_sym # TODO: unit-test to_sym
|
14
|
+
iteratee.call(handlers, key, value, *args)
|
15
|
+
else
|
16
|
+
Concurrent::Promise.reject('Could not find a handler subtype: ' \
|
17
|
+
"#{key}.")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a handler function.
|
23
|
+
def self.create_handler(iteratee)
|
24
|
+
proc do |map, client, config, type, *args|
|
25
|
+
if map.key? type.to_sym
|
26
|
+
if config.key? type
|
27
|
+
# TODO: unit-test passed args
|
28
|
+
work = config.fetch(type)
|
29
|
+
.map(&iteratee.call(map.fetch(type), client, *args))
|
30
|
+
|
31
|
+
Concurrent::Promise.zip(*work)
|
32
|
+
else
|
33
|
+
Concurrent::Promise.fulfill []
|
34
|
+
end
|
35
|
+
else
|
36
|
+
Concurrent::Promise.reject('Could not find a handler type: ' \
|
37
|
+
"#{type}.")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a setup handler function.
|
43
|
+
@setup = proc do |handlers_outer, *args_outer|
|
44
|
+
setup_iterator = proc do |handlers, key, value, *args|
|
45
|
+
handler = handlers.fetch(key)
|
46
|
+
|
47
|
+
if handler.respond_to? :call
|
48
|
+
handler.call(value, *args) # TODO: unit-test passed args
|
49
|
+
elsif handler.key? Handler::Interface::SETUP
|
50
|
+
# TODO: unit-test passed args
|
51
|
+
handler[Handler::Interface::SETUP].call(value, *args)
|
52
|
+
else
|
53
|
+
Concurrent::Promise.fulfill
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
create_subtype_iterator(handlers_outer, setup_iterator, *args_outer)
|
58
|
+
end
|
59
|
+
|
60
|
+
@teardown = proc do |handlers_outer, *args_outer|
|
61
|
+
teardown_iterator = proc do |handlers, key, _value, *args|
|
62
|
+
if handlers.fetch(key).key? Handler::Interface::TEARDOWN
|
63
|
+
handlers.fetch(key).fetch(Handler::Interface::TEARDOWN).call(*args)
|
64
|
+
else
|
65
|
+
Concurrent::Promise.fulfill
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
create_subtype_iterator(handlers_outer, teardown_iterator, *args_outer)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Sets up a handler type.
|
73
|
+
def self.setup_with_handler(*args)
|
74
|
+
create_handler(@setup).curry.call(*args)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Tears down a handler type.
|
78
|
+
def self.teardown_with_handler(*args)
|
79
|
+
create_handler(@teardown).curry.call(*args)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns a unique name.
|
83
|
+
def self.generate_name
|
84
|
+
'ruby-instance'
|
85
|
+
end
|
86
|
+
|
87
|
+
# Reduce handler options based on if they are enabled.
|
88
|
+
def self.reduce_handler_option
|
89
|
+
proc do |(name, config), acc|
|
90
|
+
acc[name] = config if handle? config
|
91
|
+
|
92
|
+
acc
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Given handler options, enabled subtype options are returned.
|
97
|
+
def self.filter_enabled_handler_options(options)
|
98
|
+
options.each_with_object({}, &reduce_handler_option)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Given agent options, handlers options are returned.
|
102
|
+
def self.filter_handlers(options)
|
103
|
+
options.each_with_object({}) do |(name, config), acc|
|
104
|
+
acc[name] = filter_enabled_handler_options config
|
105
|
+
|
106
|
+
acc
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Extracts handler options and then filters them based on if they
|
111
|
+
# are enabled or not. TODO: unit-test or integration-test
|
112
|
+
def self.extract_handler_options(options)
|
113
|
+
options = Handler.extract_options options
|
114
|
+
|
115
|
+
filter_handlers options
|
116
|
+
end
|
117
|
+
|
118
|
+
# Determines if a handler configuration should be handled.
|
119
|
+
def self.handle?(value)
|
120
|
+
return value if value == true
|
121
|
+
|
122
|
+
if Functional::TypeCheck::Type?(value, Hash) && (value.key? :enabled)
|
123
|
+
return value[:enabled]
|
124
|
+
end
|
125
|
+
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
# Given an agent config a name will be returned.
|
130
|
+
def self.resolve_name(config)
|
131
|
+
return config[:name] if config.key?(:name) && !config[:name].nil?
|
132
|
+
|
133
|
+
generate_name
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/client.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'agent/agent'
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
module Polyseerio
|
5
|
+
# The Polyseer.io client.
|
6
|
+
class Client
|
7
|
+
INITIALIZE_DEFAULTS = {
|
8
|
+
agent_class: Agent::Agent,
|
9
|
+
request: nil
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
attr_accessor :cid, :agent, :instance
|
13
|
+
attr_writer :instance
|
14
|
+
|
15
|
+
def initialize(cid, options = {})
|
16
|
+
options = Helper.defaults(options, INITIALIZE_DEFAULTS)
|
17
|
+
|
18
|
+
if options[:request].nil?
|
19
|
+
raise ArgumentError, 'Cannot create an instance of Client without' \
|
20
|
+
'passing a request instance.'
|
21
|
+
end
|
22
|
+
|
23
|
+
if options.key? :resources
|
24
|
+
options[:resources].each(&Helper.attach_to_instance!(self))
|
25
|
+
end
|
26
|
+
|
27
|
+
@cid = cid
|
28
|
+
@agent = nil
|
29
|
+
@instance = nil
|
30
|
+
@request = options[:request]
|
31
|
+
@agent_class = options[:agent_class]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Start an agent using this client.
|
35
|
+
def start_agent(*args)
|
36
|
+
raise 'Agent has already started.' unless @agent.nil?
|
37
|
+
|
38
|
+
@agent = @agent_class.new(self)
|
39
|
+
|
40
|
+
@agent.start(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_accessor :request, :agent_class
|
46
|
+
end
|
47
|
+
end
|
data/lib/constant.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Polyseerio
|
2
|
+
module Constant
|
3
|
+
ACCESS_TOKEN_HEADER = 'X-AUTH-HEADER'.freeze
|
4
|
+
DEFAULT_API_BASE_URL = 'api.polyseer.io/polyseer'.freeze
|
5
|
+
DEFAULT_API_PROTOCOL = 'https://'.freeze
|
6
|
+
DEFAULT_API_VERSION = 'v1'.freeze
|
7
|
+
DEFAULT_ENV = 'RAILS_ENV'.freeze
|
8
|
+
DEFAULT_ENVIRONMENT = 'development'.freeze
|
9
|
+
DEFAULT_TIMEOUT = 10_000
|
10
|
+
DEFAULT_TOKEN_ENV = 'POLYSEERIO_TOKEN'.freeze
|
11
|
+
end
|
12
|
+
end
|
data/lib/enum.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Polyseerio
|
4
|
+
module Enum
|
5
|
+
# Contains resource routes.
|
6
|
+
module Resource
|
7
|
+
ALERT = 'alerts'.freeze
|
8
|
+
CHANNEL = 'channels'.freeze
|
9
|
+
ENVIRONMENT = 'environments'.freeze
|
10
|
+
EVENT = 'events'.freeze
|
11
|
+
EXPECTATION = 'expectations'.freeze
|
12
|
+
INSTANCE = 'instances'.freeze
|
13
|
+
LOGIC_BLOCK = 'logic-blocks'.freeze
|
14
|
+
MEMBER = 'members'.freeze
|
15
|
+
MESSAGE = 'messages'.freeze
|
16
|
+
SETTING = 'settings'.freeze
|
17
|
+
TASK = 'tasks'.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
# Contains type constants for use with API calls.
|
21
|
+
module Type
|
22
|
+
Resource.constants.each do |key|
|
23
|
+
value = Helper.resource_to_type Resource.const_get(key)
|
24
|
+
|
25
|
+
const_set(key, value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module Determiner
|
30
|
+
ONE = 'one'.freeze
|
31
|
+
SOME = 'some'.freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
module Direction
|
35
|
+
INBOUND = 'inbound'.freeze
|
36
|
+
OUTBOUND = 'outbound'.freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
module Subtype
|
40
|
+
LONG_RUNNING = 'long_running'.freeze
|
41
|
+
PERIODIC = 'periodic'.freeze
|
42
|
+
end
|
43
|
+
|
44
|
+
module Color
|
45
|
+
BLUE = 'blue'.freeze
|
46
|
+
BROWN = 'brown'.freeze
|
47
|
+
GREEN = 'green'.freeze
|
48
|
+
ORANGE = 'orange'.freeze
|
49
|
+
PURPLE = 'purple'.freeze
|
50
|
+
RED = 'red'.freeze
|
51
|
+
TEAL = 'teal'.freeze
|
52
|
+
WHITE = 'white'.freeze
|
53
|
+
YELLOW = 'yellow'.freeze
|
54
|
+
NONE = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
module Icon
|
58
|
+
THUMBS_UP = 'thumbs-up'.freeze
|
59
|
+
CALENDAR = 'calendar'.freeze
|
60
|
+
SERVER = 'server'.freeze
|
61
|
+
SIGNAL = 'wifi'.freeze
|
62
|
+
GIT = 'git'.freeze
|
63
|
+
CODE = 'code'.freeze
|
64
|
+
CHECK = 'check'.freeze
|
65
|
+
ERROR = 'exclamation-triangle'.freeze
|
66
|
+
PENCIL = 'pencil'.freeze
|
67
|
+
CHAIN = 'chain'.freeze
|
68
|
+
CHAIN_BROKEN = 'chain-broken'.freeze
|
69
|
+
NONE = nil
|
70
|
+
end
|
71
|
+
|
72
|
+
module Protocol
|
73
|
+
SMTP = 'smtp'.freeze
|
74
|
+
SMS = 'sms'.freeze
|
75
|
+
end
|
76
|
+
|
77
|
+
module Strategy
|
78
|
+
FALLBACK = :fallback
|
79
|
+
ID = :id
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|