kstor 0.4.3 → 0.5.0

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.
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