kstor 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -2
  3. data/bin/kstor +48 -40
  4. data/bin/kstor-srv +2 -2
  5. data/lib/kstor/config.rb +2 -1
  6. data/lib/kstor/controller/authentication.rb +25 -4
  7. data/lib/kstor/controller/base.rb +61 -0
  8. data/lib/kstor/controller/request_handler.rb +84 -16
  9. data/lib/kstor/controller/secret.rb +63 -64
  10. data/lib/kstor/controller/users.rb +11 -22
  11. data/lib/kstor/controller.rb +3 -3
  12. data/lib/kstor/crypto/armored_value.rb +82 -0
  13. data/lib/kstor/crypto/keys.rb +9 -41
  14. data/lib/kstor/crypto.rb +0 -1
  15. data/lib/kstor/error.rb +36 -3
  16. data/lib/kstor/log/simple_logger.rb +83 -0
  17. data/lib/kstor/log/systemd_logger.rb +22 -0
  18. data/lib/kstor/log.rb +53 -4
  19. data/lib/kstor/message/base.rb +223 -0
  20. data/lib/kstor/message/error.rb +15 -0
  21. data/lib/kstor/message/group_create.rb +14 -0
  22. data/lib/kstor/message/group_created.rb +16 -0
  23. data/lib/kstor/message/ping.rb +14 -0
  24. data/lib/kstor/message/pong.rb +14 -0
  25. data/lib/kstor/message/secret_create.rb +16 -0
  26. data/lib/kstor/message/secret_created.rb +14 -0
  27. data/lib/kstor/message/secret_delete.rb +14 -0
  28. data/lib/kstor/message/secret_deleted.rb +14 -0
  29. data/lib/kstor/message/secret_list.rb +14 -0
  30. data/lib/kstor/message/secret_search.rb +14 -0
  31. data/lib/kstor/message/secret_unlock.rb +14 -0
  32. data/lib/kstor/message/secret_update_meta.rb +15 -0
  33. data/lib/kstor/message/secret_update_value.rb +15 -0
  34. data/lib/kstor/message/secret_updated.rb +14 -0
  35. data/lib/kstor/message/secret_value.rb +35 -0
  36. data/lib/kstor/message.rb +26 -113
  37. data/lib/kstor/model.rb +42 -25
  38. data/lib/kstor/server.rb +15 -3
  39. data/lib/kstor/session.rb +34 -2
  40. data/lib/kstor/socket_server.rb +20 -1
  41. data/lib/kstor/sql_connection.rb +16 -1
  42. data/lib/kstor/store.rb +182 -72
  43. data/lib/kstor/systemd.rb +5 -0
  44. data/lib/kstor/version.rb +2 -1
  45. data/lib/kstor.rb +1 -1
  46. metadata +25 -3
@@ -3,6 +3,7 @@
3
3
  require 'kstor/store'
4
4
  require 'kstor/model'
5
5
  require 'kstor/crypto'
6
+ require 'kstor/controller/base'
6
7
 
7
8
  module KStor
8
9
  class SecretNotFound < Error
@@ -12,79 +13,70 @@ module KStor
12
13
 
13
14
  module Controller
14
15
  # Handle secret-related requests.
15
- class Secret
16
- def initialize(store)
17
- @store = store
18
- end
19
-
20
- def handle_request(user, req)
21
- case req.type
22
- when 'secret-create' then handle_create(user, req)
23
- when 'secret-search' then handle_search(user, req)
24
- when 'secret-unlock' then handle_unlock(user, req)
25
- when 'secret-update-meta' then handle_update_meta(user, req)
26
- when 'secret-update-value' then handle_update_value(user, req)
27
- when 'secret-delete' then handle_delete(user, req)
28
- else
29
- raise Error.for_code('REQ/UNKNOWN', req.type)
30
- end
31
- end
16
+ class Secret < Base
17
+ request_type Message::SecretCreate
18
+ request_type Message::SecretSearch
19
+ request_type Message::SecretUnlock
20
+ request_type Message::SecretUpdateMeta
21
+ request_type Message::SecretUpdateValue
22
+ request_type Message::SecretDelete
23
+
24
+ response_type Message::SecretCreated
25
+ response_type Message::SecretList
26
+ response_type Message::SecretValue
27
+ response_type Message::SecretUpdated
28
+ response_type Message::SecretDeleted
32
29
 
33
30
  private
34
31
 
35
- def handle_create(user, req)
36
- meta = Model::SecretMeta.new(**req.args['meta'])
37
- secret_groups = req.args['group_ids'].map { |gid| groups[gid.to_i] }
38
- secret_id = create(
39
- user, req.args['plaintext'], secret_groups, meta
40
- )
41
- Response.new('secret.created', 'secret_id' => secret_id)
42
- end
43
-
44
- def handle_search(user, req)
45
- secrets = search(user, Model::SecretMeta.new(**req.args))
46
- args = secrets.map do |s|
47
- h = s.to_h
48
- h.delete('group_id')
49
- h
32
+ def handle_secret_create(user, req)
33
+ meta = Model::SecretMeta.new(**req.meta)
34
+ secret_groups = req.group_ids.map do |gid|
35
+ @store.groups[gid.to_i]
50
36
  end
51
- Response.new(
52
- 'secret.list',
53
- 'secrets' => args
54
- )
37
+ args = {
38
+ 'secret_id' => create(user, req.plaintext, secret_groups, meta)
39
+ }
40
+ [Message::SecretCreated, args]
55
41
  end
56
42
 
57
- def handle_unlock(user, req)
58
- secret_id = req.args['secret_id']
59
- secret = unlock(user, secret_id)
43
+ def handle_secret_search(user, req)
44
+ Log.debug("secretcontroller#handle_secret_search: #{req.args.inspect}")
45
+ secrets = search(user, Model::SecretMeta.new(**req.meta))
46
+ args = { 'secrets' => secrets.map { |s| s.to_h.except('group_id') } }
47
+ [Message::SecretList, args]
48
+ end
49
+
50
+ def handle_secret_unlock(user, req)
51
+ secret = unlock(user, req.secret_id)
60
52
  args = unlock_format(secret)
61
53
 
62
- Response.new('secret.value', **args)
54
+ [Message::SecretValue, args]
63
55
  end
64
56
 
65
- def handle_update_meta(user, req)
66
- meta = Model::SecretMeta.new(req.args['meta'])
57
+ def handle_secret_update_meta(user, req)
58
+ meta = Model::SecretMeta.new(req.meta)
67
59
  Log.debug("secret#handle_update_meta: meta=#{meta.to_h.inspect}")
68
- update_meta(user, req.args['secret_id'], meta)
69
- Response.new('secret.updated', 'secret_id' => req.args['secret_id'])
60
+ update_meta(user, req.secret_id, meta)
61
+ [Message::SecretUpdated, { 'secret_id' => req.secret_id }]
70
62
  end
71
63
 
72
- def handle_update_value(user, req)
73
- update_value(user, req.args['secret_id'], req.args['plaintext'])
74
- Response.new('secret.updated', 'secret_id' => req.args['secret_id'])
64
+ def handle_secret_update_value(user, req)
65
+ update_value(user, req.secret_id, req.plaintext)
66
+ [Message::SecretUpdated, { 'secret_id' => req.secret_id }]
75
67
  end
76
68
 
77
- def handle_delete(user, req)
78
- delete(user, req.args['secret_id'])
79
- Response.new('secret.deleted', 'secret_id' => req.args['secret_id'])
69
+ def handle_secret_delete(user, req)
70
+ delete(user, req.secret_id)
71
+ [Message::SecretDeleted, { 'secret_id' => req.secret_id }]
80
72
  end
81
73
 
82
74
  def users
83
- @users ||= @store.users
75
+ @store.users
84
76
  end
85
77
 
86
78
  def groups
87
- @groups ||= @store.groups
79
+ @store.groups
88
80
  end
89
81
 
90
82
  # in: metadata wildcards
@@ -106,13 +98,13 @@ module KStor
106
98
  # needs: private key of one common group between user and secret
107
99
  # out: plaintext
108
100
  def unlock(user, secret_id)
109
- secret = @store.secret_fetch(secret_id, user.id)
101
+ secret = secret_fetch(secret_id, user.id)
110
102
  group_privk = user.keychain[secret.group_id].privk
111
103
 
112
- value_author = users[secret.value_author_id]
104
+ value_author = @store.users[secret.value_author_id]
113
105
  secret.unlock(value_author.pubk, group_privk)
114
106
 
115
- meta_author = users[secret.meta_author_id]
107
+ meta_author = @store.users[secret.meta_author_id]
116
108
  secret.unlock_metadata(meta_author.pubk, group_privk)
117
109
 
118
110
  secret
@@ -137,12 +129,12 @@ module KStor
137
129
  # needs: every group public key for this secret, user private key
138
130
  # out: nil
139
131
  def update_meta(user, secret_id, partial_meta)
140
- secret = @store.secret_fetch(secret_id, user.id)
132
+ secret = secret_fetch(secret_id, user.id)
141
133
  unlock_metadata(user, secret)
142
134
  meta = secret.metadata.merge(partial_meta)
143
135
  group_ids = @store.groups_for_secret(secret.id)
144
136
  group_encrypted_metadata = group_ids.to_h do |group_id|
145
- group_pubk = groups[group_id].pubk
137
+ group_pubk = @store.groups[group_id].pubk
146
138
  author_privk = user.privk
147
139
  encrypted_meta = Crypto.encrypt_secret_metadata(
148
140
  group_pubk, author_privk, meta.to_h
@@ -156,10 +148,10 @@ module KStor
156
148
  # needs: every group public key for this secret, user private key
157
149
  # out: nil
158
150
  def update_value(user, secret_id, plaintext)
159
- secret = @store.secret_fetch(secret_id, user.id)
151
+ secret = secret_fetch(secret_id, user.id)
160
152
  group_ids = @store.groups_for_secret(secret.id)
161
153
  group_ciphertexts = group_ids.to_h do |group_id|
162
- group_pubk = groups[group_id].pubk
154
+ group_pubk = @store.groups[group_id].pubk
163
155
  author_privk = user.privk
164
156
  encrypted_value = Crypto.encrypt_secret_value(
165
157
  group_pubk, author_privk, plaintext
@@ -174,7 +166,7 @@ module KStor
174
166
  # out: nil
175
167
  def delete(user, secret_id)
176
168
  # Check if user can see this secret:
177
- secret = @store.secret_fetch(secret_id, user.id)
169
+ secret = secret_fetch(secret_id, user.id)
178
170
  raise Error.for_code('SECRET/NOTFOUND', secret_id) if secret.nil?
179
171
 
180
172
  @store.secret_delete(secret_id)
@@ -182,20 +174,27 @@ module KStor
182
174
 
183
175
  def unlock_format(secret)
184
176
  args = secret.to_h
185
- args['value_author'] = users[secret.value_author_id].to_h
186
- args['metadata_author'] = users[secret.meta_author_id].to_h
177
+ args['value_author'] = @store.users[secret.value_author_id].to_h
178
+ args['metadata_author'] = @store.users[secret.meta_author_id].to_h
187
179
 
188
180
  group_ids = @store.groups_for_secret(secret.id)
189
- args['groups'] = groups.values_at(*group_ids).map(&:to_h)
181
+ args['groups'] = @store.groups.values_at(*group_ids).map(&:to_h)
190
182
 
191
183
  args
192
184
  end
193
185
 
194
186
  def unlock_metadata(user, secret)
195
187
  group_privk = user.keychain[secret.group_id].privk
196
- author = users[secret.meta_author_id]
188
+ author = @store.users[secret.meta_author_id]
197
189
  secret.unlock_metadata(author.pubk, group_privk)
198
190
  end
191
+
192
+ def secret_fetch(secret_id, user_id)
193
+ secret = @store.secret_fetch(secret_id, user_id)
194
+ raise Error.for_code('SECRET/NOTFOUND', secret_id) if secret.nil?
195
+
196
+ secret
197
+ end
199
198
  end
200
199
  end
201
200
  end
@@ -4,36 +4,25 @@ require 'kstor/store'
4
4
  require 'kstor/model'
5
5
  require 'kstor/crypto'
6
6
  require 'kstor/log'
7
+ require 'kstor/controller/base'
7
8
 
8
9
  module KStor
9
10
  module Controller
10
11
  # Handle user and group related requests.
11
- class User
12
- def initialize(store)
13
- @store = store
14
- end
15
-
16
- def handle_request(user, req)
17
- case req.type
18
- when /^group-create$/ then handle_group_create(user, req)
19
- end
20
- end
12
+ class User < Base
13
+ request_type Message::GroupCreate
14
+ response_type Message::GroupCreated
21
15
 
22
16
  private
23
17
 
24
18
  def handle_group_create(user, req)
25
- unless req.args['name']
26
- raise Error.for_code('REQ/MISSINGARG', 'name', req.type)
27
- end
28
-
29
- group = group_create(user, req.args['name'])
30
- @groups = nil
31
- Response.new(
32
- 'group.created',
33
- 'group_id' => group.id,
34
- 'group_name' => group.name,
35
- 'group_pubk' => group.pubk
36
- )
19
+ group = group_create(user, req.name)
20
+ args = {
21
+ group_id: group.id,
22
+ group_name: group.name,
23
+ group_pubk: group.pubk
24
+ }
25
+ [Message::GroupCreated, args]
37
26
  end
38
27
 
39
28
  def group_create(user, name)
@@ -34,8 +34,8 @@ module KStor
34
34
  end
35
35
 
36
36
  # Error: missing request argument.
37
- class MissingArgument < Error
38
- error_code 'REQ/MISSINGARG'
39
- error_message 'Missing argument %s for request type %s'
37
+ class MissingMessageArgument < Error
38
+ error_code 'REQ/MISSINGARGS'
39
+ error_message 'Missing argument(s) %s for message type %s'
40
40
  end
41
41
  end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kstor/crypto/ascii_armor'
4
+
5
+ module KStor
6
+ module Crypto
7
+ # Wrapper class for an ASCII-armored value.
8
+ class ArmoredValue
9
+ # Create a new ASCII-armored value.
10
+ #
11
+ # @param value [String] ASCII-armored string
12
+ # @return [KStor::Crypto::ArmoredValue] new armored value
13
+ #
14
+ # @see KStor::Crypto::ASCIIArmor#decode
15
+ # @see KStor::Crypto::ASCIIArmor#encode
16
+ def initialize(value)
17
+ @value = value
18
+ end
19
+
20
+ # Serialize value.
21
+ #
22
+ # @return [String] serialized value
23
+ def to_ascii
24
+ @value
25
+ end
26
+ alias to_s to_ascii
27
+
28
+ # Get back original value.
29
+ #
30
+ # @return [String] binary data
31
+ def to_binary
32
+ ASCIIArmor.decode(@value)
33
+ end
34
+
35
+ # Create from binary data
36
+ #
37
+ # @param bin_str [String] binary data
38
+ # @return [KStor::Crypto::ArmoredValue] new value
39
+ def self.from_binary(bin_str)
40
+ new(ASCIIArmor.encode(bin_str))
41
+ end
42
+ end
43
+
44
+ # A Hash that can be easily serialized to ASCII chars.
45
+ #
46
+ # Uses JSON as intermediary data format.
47
+ class ArmoredHash < ArmoredValue
48
+ # Create from Ruby Hash.
49
+ #
50
+ # @param hash [Hash] a Ruby Hash.
51
+ # @return [KStor::Crypto::ArmoredHash] new hash
52
+ def self.from_hash(hash)
53
+ from_binary(hash.to_json)
54
+ end
55
+
56
+ # Convert to Ruby Hash.
57
+ #
58
+ # @return [Hash] new Ruby Hash
59
+ def to_hash
60
+ JSON.parse(to_binary)
61
+ end
62
+
63
+ # Access value for this key.
64
+ #
65
+ # @param key [String] what to lookup
66
+ # @return [Any, nil] value
67
+ def [](key)
68
+ to_hash[key]
69
+ end
70
+
71
+ # Set value for a key.
72
+ #
73
+ # @param key [String] hash key
74
+ # @param val [Any] hash value
75
+ def []=(key, val)
76
+ h = to_hash
77
+ h[key] = val
78
+ @value = ASCIIArmor.encode(h.to_json)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'kstor/crypto/ascii_armor'
4
+ require 'kstor/crypto/armored_value'
4
5
 
5
6
  module KStor
6
7
  module Crypto
@@ -39,49 +40,13 @@ module KStor
39
40
  end
40
41
  end
41
42
 
42
- # Wrapper class for an ASCII-armored value.
43
- class ArmoredValue
44
- def initialize(value)
45
- @value = value
46
- end
47
-
48
- def to_ascii
49
- @value
50
- end
51
- alias to_s to_ascii
52
-
53
- def to_binary
54
- ASCIIArmor.decode(@value)
55
- end
56
-
57
- def self.from_binary(bin_str)
58
- new(ASCIIArmor.encode(bin_str))
59
- end
60
- end
61
-
62
- # A Hash.
63
- class ArmoredHash < ArmoredValue
64
- def self.from_hash(hash)
65
- from_binary(hash.to_json)
66
- end
67
-
68
- def to_hash
69
- JSON.parse(to_binary)
70
- end
71
-
72
- def [](key)
73
- to_hash[key]
74
- end
75
-
76
- def []=(key, val)
77
- h = to_hash
78
- h[key] = val
79
- @value = ASCIIArmor.encode(h.to_json)
80
- end
81
- end
82
-
83
43
  # KDF parameters.
84
44
  class KDFParams < ArmoredHash
45
+ # Create new Key Derivation Function parameters from a Ruby Hash.
46
+ #
47
+ # Hash parameter must have keys for "salt"," opslimit" and "memlimit".
48
+ #
49
+ # @param hash [Hash] KDF parameters data.
85
50
  def self.from_hash(hash)
86
51
  hash['salt'] = ASCIIArmor.encode(hash['salt'])
87
52
  hash['opslimit'] = hash['opslimit'].to_s
@@ -89,6 +54,7 @@ module KStor
89
54
  super(hash)
90
55
  end
91
56
 
57
+ # Convert back to a Ruby Hash.
92
58
  def to_hash
93
59
  hash = super
94
60
  hash['salt'] = ASCIIArmor.decode(hash['salt'])
@@ -101,6 +67,7 @@ module KStor
101
67
 
102
68
  # A private key.
103
69
  class PrivateKey < ArmoredValue
70
+ # Convert ASCII-armored value to a RbNaCl private key.
104
71
  def to_rbnacl
105
72
  RbNaCl::PrivateKey.new(to_binary)
106
73
  end
@@ -108,6 +75,7 @@ module KStor
108
75
 
109
76
  # A public key.
110
77
  class PublicKey < ArmoredValue
78
+ # Convert ASCII-armored value to a RbNaCl public key.
111
79
  def to_rbnacl
112
80
  RbNaCl::PublicKey.new(to_binary)
113
81
  end
data/lib/kstor/crypto.rb CHANGED
@@ -39,7 +39,6 @@ module KStor
39
39
  # @return [SecretKey] secret key and KDF parameters
40
40
  def key_derive(passphrase, params = nil)
41
41
  params ||= key_derive_params_generate
42
- Log.debug("crypto: kdf params = #{params.to_hash}")
43
42
  data = RbNaCl::PasswordHash.argon2(
44
43
  passphrase, params['salt'],
45
44
  params['opslimit'], params['memlimit'], params['digest_size']
data/lib/kstor/error.rb CHANGED
@@ -12,26 +12,41 @@ module KStor
12
12
  attr_reader :message
13
13
  attr_reader :registry
14
14
 
15
+ # Declare error code for a subclass.
16
+ #
17
+ # @param str [String] unique error code.
15
18
  def error_code(str)
16
19
  @code = str
17
20
  end
18
21
 
22
+ # Declare error message for a subclass.
23
+ #
24
+ # This will be passed to String#format as a format string.
25
+ #
26
+ # @param str [String] error message or format.
19
27
  def error_message(str)
20
28
  @message = str
21
29
  end
22
30
 
31
+ # Create a new error for this code.
32
+ #
33
+ # @param code [String] error code
34
+ # @param args [Array] arguments to subclass initialize method.
23
35
  def for_code(code, *args)
24
36
  @registry[code].new(*args)
25
37
  end
26
38
 
39
+ # List of all subclasses.
27
40
  def list
28
41
  @registry.classes
29
42
  end
30
43
  end
31
44
 
45
+ # When subclassed, add child to registry.
46
+ #
47
+ # @param subclass [Class] subclass to add to error registry.
32
48
  def self.inherited(subclass)
33
49
  super
34
- Log.debug("#{subclass} inherits from Error")
35
50
  @registry ||= ErrorRegistry.new
36
51
  if @registry.key?(subclass.code)
37
52
  code = subclass.code
@@ -43,35 +58,53 @@ module KStor
43
58
  @registry << subclass
44
59
  end
45
60
 
61
+ # Create new error.
62
+ #
63
+ # @param args [Array] arguments to String#format with the message as a
64
+ # format string.
65
+ # @return [KStor::Error] instance of subclass of Error.
46
66
  def initialize(*args)
47
67
  super(format("ERR/%s #{self.class.message}", self.class.code, *args))
48
68
  end
49
69
 
50
- def response
51
- Response.new('error', 'code' => self.class.code, 'message' => message)
70
+ # Create a new server response from an error.
71
+ #
72
+ # @return [KStor::Message::Error] error response
73
+ def response(sid)
74
+ Message::Error.new(
75
+ { 'code' => self.class.code, 'message' => message },
76
+ { session_id: sid }
77
+ )
52
78
  end
53
79
  end
54
80
 
81
+ # Basically an Array of error subclasses, with an index on error codes.
82
+ #
55
83
  # @api private
56
84
  class ErrorRegistry
85
+ # Create new registry.
57
86
  def initialize
58
87
  @error_classes = []
59
88
  @index = nil
60
89
  end
61
90
 
91
+ # List of subclasses.
62
92
  def classes
63
93
  @error_classes.values
64
94
  end
65
95
 
96
+ # Append an error class.
66
97
  def <<(klass)
67
98
  @error_classes << klass
68
99
  @index = nil
69
100
  end
70
101
 
102
+ # True if registry knows a subclass with this error code.
71
103
  def key?(code)
72
104
  index.key?(code)
73
105
  end
74
106
 
107
+ # Return subclass for this error code.
75
108
  def [](code)
76
109
  index[code]
77
110
  end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module KStor
6
+ # rubocop:disable Style/Documentation
7
+ module Log
8
+ # rubocop:enable Style/Documentation
9
+
10
+ # Simple logger using Ruby Logger.
11
+ #
12
+ # It just defines some convenient methods that Journald::Logger has.
13
+ #
14
+ # @api private
15
+ class SimpleLogger
16
+ # Create a new logger.
17
+ #
18
+ # @return [KStor::Log::SimpleLogger] a simple logger to STDOUT
19
+ def initialize
20
+ @logger = Logger.new($stdout)
21
+ end
22
+
23
+ # Set minimum log level
24
+ #
25
+ # @param lvl [Integer] log level from constants in Logger class
26
+ def level=(lvl)
27
+ @logger.level = lvl
28
+ end
29
+
30
+ # Log a debug message.
31
+ #
32
+ # @param msg [String] message
33
+ def debug(msg)
34
+ @logger.debug(msg)
35
+ end
36
+
37
+ # Log an informative message.
38
+ #
39
+ # @param msg [String] message
40
+ def info(msg)
41
+ @logger.info(msg)
42
+ end
43
+
44
+ # Log a warning.
45
+ #
46
+ # @param msg [String] message
47
+ def warn(msg)
48
+ @logger.warn(msg)
49
+ end
50
+
51
+ # Log an error message.
52
+ #
53
+ # @param msg [String] message
54
+ def error(msg)
55
+ @logger.error(msg)
56
+ end
57
+
58
+ # Log an exception with full backtrace and all.
59
+ #
60
+ # @param exc [Exception] an exception
61
+ def exception(exc)
62
+ @logger.error(exc.full_message)
63
+ end
64
+
65
+ alias notice info
66
+ alias critical error
67
+ alias alert error
68
+ alias emergency error
69
+ end
70
+
71
+ DEBUG = Logger::DEBUG
72
+ INFO = Logger::INFO
73
+ WARN = Logger::WARN
74
+ ERROR = Logger::ERROR
75
+
76
+ class << self
77
+ # Create new simple logger to stdout
78
+ def create_logger
79
+ SimpleLogger.new
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'journald/logger'
4
+
5
+ module KStor
6
+ # rubocop:disable Style/Documentation
7
+ module Log
8
+ # rubocop:enable Style/Documentation
9
+
10
+ DEBUG = Journald::LOG_DEBUG
11
+ INFO = Journald::LOG_INFO
12
+ WARN = Journald::LOG_WARNING
13
+ ERROR = Journald::LOG_ERR
14
+
15
+ class << self
16
+ # Create new systemd journald logger
17
+ def create_logger
18
+ Journald::Logger.new('kstor')
19
+ end
20
+ end
21
+ end
22
+ end