persistence-providers 0.0.4 → 0.0.4.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/lib/crd_client.rb +24 -9
- data/lib/persistence_providers.rb +1 -0
- data/lib/state/component/providers/influxdb.rb +30 -67
- data/lib/state/component/providers/influxdb/client.rb +24 -27
- data/lib/state/component/providers/influxdb/measurement.rb +17 -9
- data/lib/state/component/providers/influxdb/measurement/errors.rb +6 -0
- data/lib/state/component/providers/influxdb/measurement/events.rb +12 -1
- data/lib/state/component/providers/influxdb/measurement/states.rb +13 -1
- data/lib/state/component_def.rb +3 -0
- data/lib/state/crd_assembly.rb +3 -1
- data/lib/state/workflow_instance.rb +5 -0
- data/lib/utils.rb +3 -0
- data/lib/utils/log.rb +22 -0
- data/persistence-providers.gemspec +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bc555b9367087540ccddc49bc1ce3fa937b0a36be7b3d6ff832373a9beeadd0
|
4
|
+
data.tar.gz: 5ae84500a46b183544d53b1d7d2f90cf6b49bcf52d34d2b95eba8474f7653c93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52cc878735fdf04cb19b7a202ff2622872b4514f40c1b849a0ff73a821f4e8e333c1aa9a3ac6ba6b31de29b199f4c49fb5fbd3df2c2bdf64fd4d421f6ff67e7d
|
7
|
+
data.tar.gz: a9b7fbf25e02a5b1dc15220760e91ca1bc703e7f1c2f388f6f2b083c48170c1162ffc483464cbde99f31e2465dd687c78bc47006a5ad9ee6157c5c40538083e9
|
data/lib/crd_client.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
require 'kubeclient'
|
2
2
|
require 'celluloid/io'
|
3
|
-
require 'singleton'
|
3
|
+
# require 'singleton'
|
4
4
|
|
5
5
|
module DTK
|
6
6
|
class CrdClient
|
7
|
-
include Singleton
|
7
|
+
# include Singleton
|
8
|
+
DEFAULT_API_VERSION = 'v1alpha1'
|
9
|
+
|
10
|
+
# COMPONENT_DEF_CRD_VERSION = ENV["COMPONENT_DEF_CRD_VERSION"]
|
11
|
+
# ASSEMBLY_CRD_VERSION = ENV["ASSEMBLY_CRD_VERSION"]
|
12
|
+
# WORKFLOW_CRD_VERSION = ENV["WORKFLOW_CRD_VERSION"]
|
13
|
+
# WORKFLOW_INSTANCE_CRD_VERSION = ENV["WORKFLOW_INSTANCE_CRD_VERSION"]
|
8
14
|
|
9
15
|
attr_accessor :kubeclient
|
10
16
|
|
@@ -12,17 +18,26 @@ module DTK
|
|
12
18
|
if @kubeclient = opts[:kubeclient]
|
13
19
|
@kubeclient
|
14
20
|
else
|
15
|
-
|
21
|
+
kubeclient_version(opts)
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
if
|
23
|
-
return
|
25
|
+
def self.kubeclient_version(opts = {})
|
26
|
+
version = opts[:apiVersion] || DEFAULT_API_VERSION
|
27
|
+
|
28
|
+
if existing_version = KubeclientVersions[version]
|
29
|
+
return existing_version
|
30
|
+
else
|
31
|
+
new_instance = new(version).kubeclient
|
32
|
+
KubeclientVersions[version] = new_instance
|
33
|
+
new_instance
|
24
34
|
end
|
35
|
+
end
|
36
|
+
KubeclientVersions = {}
|
25
37
|
|
38
|
+
# opts can have keys
|
39
|
+
# kubernetes_client - already instantiated kubernetes client
|
40
|
+
def initialize(apiVersion)
|
26
41
|
ssl_options = {}
|
27
42
|
auth_options = { bearer_token_file: '/var/run/secrets/kubernetes.io/serviceaccount/token' }
|
28
43
|
|
@@ -37,7 +52,7 @@ module DTK
|
|
37
52
|
|
38
53
|
@kubeclient = Kubeclient::Client.new(
|
39
54
|
'https://kubernetes.default.svc/apis/',
|
40
|
-
|
55
|
+
"dtk.io/#{apiVersion}",
|
41
56
|
auth_options: auth_options,
|
42
57
|
ssl_options: ssl_options,
|
43
58
|
socket_options: socket_options
|
@@ -13,88 +13,51 @@ module DTK::State
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def get(namespace, component_name, assembly_name, attribute_name, opts = {})
|
16
|
-
required_tags = get_required_tags(namespace, component_name, assembly_name, attribute_name)
|
17
|
-
if opts[:provider] == "correlation"
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
elsif
|
22
|
-
last_value = measurement.get_last_point(required_tags)
|
23
|
-
last_value
|
24
|
-
end
|
16
|
+
required_tags = measurement.get_required_tags(namespace, component_name, assembly_name, attribute_name)
|
17
|
+
required_tags.merge! measurement.get_correlator_type(opts[:entrypoint]) if opts[:provider] == "correlation"
|
18
|
+
measurement.get_last_point(required_tags)
|
19
|
+
rescue => e
|
20
|
+
raise "Error happened while getting attribute from InfluxDB.\nError: #{e}"
|
25
21
|
end
|
26
22
|
|
27
23
|
def write(namespace, component_name, assembly_name, attribute_name, value, opts = {}, timestamp = nil)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
elsif
|
34
|
-
required_tags = get_required_tags(namespace, component_name, assembly_name, attribute_name)
|
35
|
-
measurement.write(value, required_tags, timestamp)
|
36
|
-
end
|
24
|
+
required_tags = measurement.get_required_tags(namespace, component_name, assembly_name, attribute_name)
|
25
|
+
required_tags.merge! measurement.get_correlator_type(opts[:entrypoint]) if opts[:provider] == "correlation"
|
26
|
+
measurement.write(value.to_s, required_tags, timestamp)
|
27
|
+
rescue => e
|
28
|
+
raise "Error happened while writing attribute into InfluxDB.\Error: #{e}"
|
37
29
|
end
|
38
30
|
|
39
31
|
def write_event(event_id, pod_name, pod_namespace, event_source, event_message, component_name, attribute_name, task_id, timestamp)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
pod_namespace: pod_namespace,
|
47
|
-
component_name: component_name,
|
48
|
-
attribute_name: attribute_name,
|
49
|
-
task_id: task_id
|
50
|
-
}
|
51
|
-
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
52
|
-
rescue => error
|
53
|
-
fail error
|
54
|
-
end
|
32
|
+
fail "Bad timestamp input, write operation wont be completed" if timestamp > Time.new
|
33
|
+
value_to_write = { event_source: event_source, event_message: event_message }
|
34
|
+
required_tags = measurement.get_required_tags(event_id, pod_name, pod_namespace, component_name, attribute_name, task_id)
|
35
|
+
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
36
|
+
rescue => error
|
37
|
+
raise "Error happened while writing event into InfluxDB.\nError: #{e}"
|
55
38
|
end
|
56
39
|
|
57
40
|
def get_event(event_id, pod_name, pod_namespace, component_name, attribute_name, task_id)
|
58
|
-
required_tags =
|
59
|
-
event_id: event_id,
|
60
|
-
pod_name: pod_name,
|
61
|
-
pod_namespace: pod_namespace,
|
62
|
-
component_name: component_name,
|
63
|
-
attribute_name: attribute_name,
|
64
|
-
task_id: task_id
|
65
|
-
}
|
41
|
+
required_tags = measurement.get_required_tags(event_id, pod_name, pod_namespace, component_name, attribute_name, task_id)
|
66
42
|
last_point = measurement.get_last_point(required_tags)
|
43
|
+
rescue => e
|
44
|
+
raise "Error happened while getting event from InfluxDB.\nError: #{e}"
|
67
45
|
end
|
68
46
|
|
69
47
|
def write_state(type, name, namespace, object_state, spec, status, component_name, attribute_name, task_id, timestamp)
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
namespace: namespace,
|
77
|
-
object_state: object_state,
|
78
|
-
component_name: component_name,
|
79
|
-
attribute_name: attribute_name,
|
80
|
-
task_id: task_id
|
81
|
-
}
|
82
|
-
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
83
|
-
rescue => error
|
84
|
-
fail error
|
85
|
-
end
|
48
|
+
raise "Bad timestamp input, write operation to InfluxDB wont be completed" if timestamp > Time.new
|
49
|
+
value_to_write = { spec: spec, status: status }
|
50
|
+
required_tags = measurement.get_required_tags(type, name, namespace, object_state, component_name, attribute_name, task_id)
|
51
|
+
measurement.write(value_to_write.to_s, required_tags, timestamp)
|
52
|
+
rescue => e
|
53
|
+
raise "Error happened while writing state into InfluxDB.\nError: #{e}"
|
86
54
|
end
|
87
|
-
|
88
|
-
private
|
89
55
|
|
90
|
-
def
|
91
|
-
required_tags =
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
attribute_name: attribute_name,
|
96
|
-
task_id: "1"
|
97
|
-
}
|
56
|
+
def get_state(type, name, namespace, object_state, component_name, attribute_name, task_id)
|
57
|
+
required_tags = measurement.get_required_tags(type, name, namespace, object_state, component_name, attribute_name, task_id)
|
58
|
+
measurement.get_last_point(required_tags)
|
59
|
+
rescue => e
|
60
|
+
raise "Error happened while getting state from InfluxDB.\nError: #{e}"
|
98
61
|
end
|
99
62
|
end
|
100
63
|
end
|
@@ -10,30 +10,24 @@ module DTK::State
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def query(query_expression)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
fail "Failed in query"
|
18
|
-
end
|
13
|
+
query_api = self.connection.create_query_api
|
14
|
+
query_api.query(query_expression)
|
15
|
+
rescue => e
|
16
|
+
raise "Failed while processing flux query!. Error: #{e}"
|
19
17
|
end
|
20
18
|
|
21
19
|
def write_point(data)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
fail error
|
27
|
-
end
|
20
|
+
write_api = self.connection.create_write_api
|
21
|
+
write_api.write(data: data)
|
22
|
+
rescue => e
|
23
|
+
raise e
|
28
24
|
end
|
29
25
|
|
30
26
|
def measurement_helper(measurement_name)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
fail error
|
36
|
-
end
|
27
|
+
klass = Measurement.const_get(measurement_name.to_sym.capitalize)
|
28
|
+
klass.new(measurement_name, self)
|
29
|
+
rescue => e
|
30
|
+
raise e
|
37
31
|
end
|
38
32
|
|
39
33
|
attr_reader :connection_parameters, :connection
|
@@ -53,18 +47,21 @@ module DTK::State
|
|
53
47
|
org: params[:org],
|
54
48
|
bucket: params[:bucket]
|
55
49
|
}
|
50
|
+
rescue => e
|
51
|
+
raise "Problem happened while processing InfluxDB connection parameters. Error: #{e}"
|
56
52
|
end
|
57
53
|
|
58
54
|
def return_connection(connection_parameters)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
client = InfluxDB2::Client.new(connection_parameters[:url], connection_parameters[:token],
|
56
|
+
bucket: connection_parameters[:bucket],
|
57
|
+
org: connection_parameters[:org],
|
58
|
+
precision: InfluxDB2::WritePrecision::MILLISECOND,
|
59
|
+
use_ssl: false)
|
60
|
+
query_api = client.create_query_api
|
61
|
+
query_api.query(query: 'from(bucket:"' + connection_parameters[:bucket] + '") |> range(start: -5)')
|
62
|
+
client
|
63
|
+
rescue => e
|
64
|
+
raise "Connection with InfluxDB could not be established. #{e}"
|
68
65
|
end
|
69
66
|
end
|
70
67
|
end
|
@@ -20,14 +20,22 @@ module DTK::State
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def get_last_point(params_hash = {})
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
check_params_hash(params_hash)
|
24
|
+
flux_query = 'from(bucket:"' + client.connection_parameters[:bucket] + '") |> range(start:-5) |> filter(fn: (r) => r._measurement == "' + name.to_s + '")' + flux_filter(params_hash) + ' |> last()' + '|> drop(columns: ["_start", "_stop", "_field", "_measurement", "attribute_name", "assembly_name", "task_id", "component_name", "namespace"])'
|
25
|
+
result = self.client.query(query: flux_query)
|
26
|
+
result.values.map(&:records).flatten.map(&:values)
|
27
|
+
rescue => e
|
28
|
+
raise "Failed while getting last attribute point. Error: #{e}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_required_tags(namespace, component_name, assembly_name, attribute_name)
|
32
|
+
required_tags = {
|
33
|
+
namespace: namespace,
|
34
|
+
component_name: component_name,
|
35
|
+
assembly_name: assembly_name,
|
36
|
+
attribute_name: attribute_name,
|
37
|
+
task_id: "1"
|
38
|
+
}
|
31
39
|
end
|
32
40
|
|
33
41
|
protected
|
@@ -90,7 +98,7 @@ module DTK::State
|
|
90
98
|
fail "Parameter '#{name}' has an illegal type, legal types are #{LEGAL_TAG_CLASSES.join(', ')}"
|
91
99
|
end
|
92
100
|
end
|
93
|
-
|
101
|
+
|
94
102
|
end
|
95
103
|
end
|
96
104
|
end
|
@@ -8,12 +8,23 @@ module DTK::State
|
|
8
8
|
write_point(value, checked_params_hash, timestamp)
|
9
9
|
end
|
10
10
|
|
11
|
+
def get_required_tags(event_id, pod_name, pod_namespace, component_name, attribute_name, task_id)
|
12
|
+
{
|
13
|
+
event_id: event_id,
|
14
|
+
pod_name: pod_name,
|
15
|
+
pod_namespace: pod_namespace,
|
16
|
+
component_name: component_name,
|
17
|
+
attribute_name: attribute_name,
|
18
|
+
task_id: task_id
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
11
22
|
protected
|
12
23
|
|
13
24
|
def required_params
|
14
25
|
[:event_id, :pod_name, :pod_namespace, :component_name, :attribute_name, :task_id]
|
15
26
|
end
|
16
|
-
|
27
|
+
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
@@ -8,12 +8,24 @@ module DTK::State
|
|
8
8
|
write_point(value, checked_params_hash, timestamp)
|
9
9
|
end
|
10
10
|
|
11
|
+
def get_required_tags(type, name, namespace, object_state, component_name, attribute_name, task_id)
|
12
|
+
{
|
13
|
+
type: type,
|
14
|
+
name: name,
|
15
|
+
namespace: namespace,
|
16
|
+
object_state: object_state,
|
17
|
+
component_name: component_name,
|
18
|
+
attribute_name: attribute_name,
|
19
|
+
task_id: task_id
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
11
23
|
protected
|
12
24
|
|
13
25
|
def required_params
|
14
26
|
[:type, :name, :namespace, :object_state, :component_name, :attribute_name, :task_id]
|
15
27
|
end
|
16
|
-
|
28
|
+
|
17
29
|
end
|
18
30
|
end
|
19
31
|
end
|
data/lib/state/component_def.rb
CHANGED
@@ -2,6 +2,8 @@ module DTK::State
|
|
2
2
|
class ComponentDef
|
3
3
|
require_relative 'component_def/attribute_type_info'
|
4
4
|
|
5
|
+
COMPONENT_DEF_CRD_VERSION = ENV["COMPONENT_DEF_CRD_VERSION"]
|
6
|
+
|
5
7
|
attr_reader :name, :namespace, :executable_actions, :attribute_type_info
|
6
8
|
|
7
9
|
def initialize(namespace, name, content)
|
@@ -12,6 +14,7 @@ module DTK::State
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def self.get(namespace, name, opts = {})
|
17
|
+
opts[:apiVersion] = COMPONENT_DEF_CRD_VERSION
|
15
18
|
crd_component_def = ::DTK::CrdClient.get_kubeclient(opts).get_componentdef(name, namespace)
|
16
19
|
ComponentDef.new(namespace, name, crd_component_def)
|
17
20
|
end
|
data/lib/state/crd_assembly.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module DTK::State
|
2
2
|
class CrdAssembly
|
3
|
+
ASSEMBLY_CRD_VERSION = ENV["ASSEMBLY_CRD_VERSION"]
|
4
|
+
|
3
5
|
attr_reader :name, :namespace, :crd_content, :components, :references
|
4
6
|
|
5
7
|
def initialize(namespace, name, crd_content)
|
@@ -11,7 +13,7 @@ module DTK::State
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def self.get(namespace, name, opts = {})
|
14
|
-
|
16
|
+
opts[:apiVersion] = ASSEMBLY_CRD_VERSION
|
15
17
|
crd_assembly = ::DTK::CrdClient.get_kubeclient(opts).get_assembly(name, namespace)
|
16
18
|
CrdAssembly.new(namespace, name, crd_assembly)
|
17
19
|
end
|
@@ -2,6 +2,8 @@ module DTK::State
|
|
2
2
|
class WorkflowInstance
|
3
3
|
require_relative 'workflow_instance/attribute_type_info'
|
4
4
|
|
5
|
+
WORKFLOW_INSTANCE_CRD_VERSION = ENV["WORKFLOW_INSTANCE_CRD_VERSION"]
|
6
|
+
|
5
7
|
attr_reader :name, :namespace, :assembly, :workflow_template, :attributes, :workflow, :attribute_type_info
|
6
8
|
|
7
9
|
def initialize(namespace, name, crd_content)
|
@@ -15,6 +17,7 @@ module DTK::State
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def self.get(namespace, name, opts = {})
|
20
|
+
opts[:apiVersion] = WORKFLOW_INSTANCE_CRD_VERSION
|
18
21
|
workflow_instance = ::DTK::CrdClient.get_kubeclient(opts).get_workflow_instance(name, namespace)
|
19
22
|
WorkflowInstance.new(namespace, name, workflow_instance)
|
20
23
|
end
|
@@ -35,6 +38,7 @@ module DTK::State
|
|
35
38
|
def self.update_action_level_result_attributes(namespace, name, attributes, action_id, opts = {})
|
36
39
|
return "Dynamic attributes do not exist for action with id #{@action_id}, nothing to update" if attributes.nil? || attributes.empty?
|
37
40
|
attributes.delete_if { |key, value| value.nil? || value.to_s.strip == '' }
|
41
|
+
opts[:apiVersion] = WORKFLOW_INSTANCE_CRD_VERSION
|
38
42
|
workflow_instance = ::DTK::CrdClient.get_kubeclient(opts).get_workflow_instance(name, namespace)
|
39
43
|
workflow = workflow_instance[:spec][:workflow]
|
40
44
|
|
@@ -63,6 +67,7 @@ module DTK::State
|
|
63
67
|
end
|
64
68
|
|
65
69
|
def self.update_action_status(namespace, name, parent_id, action_id, status, error_message = "", opts = {})
|
70
|
+
opts[:apiVersion] = WORKFLOW_INSTANCE_CRD_VERSION
|
66
71
|
workflow_instance = ::DTK::CrdClient.get_kubeclient(opts).get_workflow_instance(name, namespace)
|
67
72
|
steps = workflow_instance[:spec][:status][:steps]
|
68
73
|
action_index_steps = steps.find_index { |action| action[:id].eql? action_id }
|
data/lib/utils.rb
ADDED
data/lib/utils/log.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Utils
|
2
|
+
module Log
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
def self.instance
|
6
|
+
@instance ||= Logger.new('/proc/1/fd/1', formatter: proc { |severity, datetime, progname, msg|
|
7
|
+
orange_color = "\x1b[33m"
|
8
|
+
white_color = "\x1b[37m"
|
9
|
+
red_color = "\x1b[31m"
|
10
|
+
|
11
|
+
date_format = datetime.strftime("%Y-%m-%d %H:%M:%S:%L")
|
12
|
+
if severity == "INFO"
|
13
|
+
"#{orange_color}[#{date_format}] - #{white_color}#{msg}\n"
|
14
|
+
elsif severity == "WARN"
|
15
|
+
"#{orange_color}[#{date_format}] [WARNING] - #{msg}\n"
|
16
|
+
elsif severity == "ERROR"
|
17
|
+
"#{red_color}[#{date_format}] [ERROR] - #{msg}\n"
|
18
|
+
end
|
19
|
+
})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: persistence-providers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.4
|
4
|
+
version: 0.0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reactor8
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kubeclient
|
@@ -79,6 +79,8 @@ files:
|
|
79
79
|
- lib/state/executable_action/attribute_type_info.rb
|
80
80
|
- lib/state/workflow_instance.rb
|
81
81
|
- lib/state/workflow_instance/attribute_type_info.rb
|
82
|
+
- lib/utils.rb
|
83
|
+
- lib/utils/log.rb
|
82
84
|
- persistence-providers.gemspec
|
83
85
|
- test-destroy-influxdb.rb
|
84
86
|
- test-influxdb.rb
|