kanrisuru 0.7.0 → 0.8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/kanrisuru/core/system.rb +87 -0
- data/lib/kanrisuru/core/zypper.rb +3 -0
- data/lib/kanrisuru/os_package.rb +13 -15
- data/lib/kanrisuru/version.rb +1 -1
- data/spec/functional/core/system_spec.rb +15 -0
- data/spec/functional/core/zypper_spec.rb +6 -0
- data/spec/functional/os_package_spec.rb +94 -0
- data/spec/spec_helper.rb +0 -1
- data/spec/unit/core/system_spec.rb +12 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f5fe692ff53ac4de87ca38181765a63cf88f0beab4e44145c780ba9af934ede
|
4
|
+
data.tar.gz: 58acc02d34aff916670ab26c9659f7e40205d31492ec5f043ea51487df33cb62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2b8134ef2351a86f88286a7ed50a1f768510c75f65ecbf9d9684f376606b46ea023f1b78723ae550183c7606e230d7152614d263b19f1a31c6bf6fe0cfa2cc3
|
7
|
+
data.tar.gz: f7382ab716a20185ec071f96b6793afa7fcc1e11d32a0dd3174455cb7a5ba19d3fb61aa0fbb7d5574f26af36d983b3fae4ee9ec5757f16ef2a21edc43d5d83cd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## Kanrisuru 0.8.0 (August 18, 2021) ##
|
2
|
+
* Add last / lastb implementation in system core module.
|
3
|
+
|
4
|
+
## Kanrisuru 0.7.3 (August 9, 2021) ##
|
5
|
+
* Fixed bug with zypper remove package, where the package names weren't being added to the linux command.
|
6
|
+
* Test case added to ensure package is removed.
|
7
|
+
|
8
|
+
## Kanrisuru 0.7.2 (August 9, 2021) ##
|
9
|
+
* Fixed bug with the `os_method_cache` instance variable set in the namespaced instance of a host. This was causing collision issues inbetween host instances, where, hosts with the same aliased method name was getting overwritten (with a different OS), since the namespace instance variable existing on the host class definition wasn't getting reset inbetween host instantiations. Given that the `os_method_cache` is normally re-instantiated, this bug fix addresses this so that the `os_method_cache` is always defined on the host instance, ie:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
host.instance_variable_get(:@os_method_cache)
|
13
|
+
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
14
|
+
```
|
15
|
+
This is done instead of being saved on the namespace module. With the previous bug fix of using namespaced keys, there's no way for a method to be overwritten otherwise with a global `os_method_cache`.
|
16
|
+
|
17
|
+
## Kanrisuru 0.7.1 (August 8, 2021) ##
|
18
|
+
* Fix bug with `os_include` when caching namespace unbound methods, use the namespace in the
|
19
|
+
cache key to avoid any namespace collisions with the same method name, namely:
|
20
|
+
```ruby
|
21
|
+
"#{namespace}.#{method_name}"
|
22
|
+
```
|
23
|
+
|
1
24
|
## Kanrisuru 0.7.0 (August 8, 2021) ##
|
2
25
|
* Simplify `FileInfo` struct for return object of `ls` command.
|
3
26
|
* Rename `size` to `fsize` for the `OpenFile` struct to avoid method naming conflicts of the struct class.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'date'
|
4
|
+
require 'ipaddr'
|
4
5
|
|
5
6
|
module Kanrisuru
|
6
7
|
module Core
|
@@ -19,6 +20,7 @@ module Kanrisuru
|
|
19
20
|
os_define :linux, :kstat
|
20
21
|
|
21
22
|
os_define :linux, :lsof
|
23
|
+
os_define :linux, :last
|
22
24
|
|
23
25
|
os_define :linux, :uptime
|
24
26
|
|
@@ -116,6 +118,19 @@ module Kanrisuru
|
|
116
118
|
:name
|
117
119
|
)
|
118
120
|
|
121
|
+
SessionDetail = Struct.new(
|
122
|
+
:tty,
|
123
|
+
:login_at,
|
124
|
+
:logout_at,
|
125
|
+
:ip_address,
|
126
|
+
:success
|
127
|
+
)
|
128
|
+
|
129
|
+
LoginUser = Struct.new(
|
130
|
+
:user,
|
131
|
+
:sessions
|
132
|
+
)
|
133
|
+
|
119
134
|
def load_env
|
120
135
|
command = Kanrisuru::Command.new('env')
|
121
136
|
execute_shell(command)
|
@@ -271,6 +286,65 @@ module Kanrisuru
|
|
271
286
|
Kanrisuru::Result.new(command, &:to_i)
|
272
287
|
end
|
273
288
|
|
289
|
+
def last(opts = {})
|
290
|
+
command =
|
291
|
+
if opts[:failed_attempts]
|
292
|
+
Kanrisuru::Command.new('lastb')
|
293
|
+
else
|
294
|
+
Kanrisuru::Command.new('last')
|
295
|
+
end
|
296
|
+
|
297
|
+
command.append_flag('-i')
|
298
|
+
command.append_flag('-F')
|
299
|
+
command.append_arg('-f', opts[:file])
|
300
|
+
|
301
|
+
## Some systems only use 1 space between user and TTY field
|
302
|
+
## Add an additional space in output formatting for simple parsing
|
303
|
+
## logic.
|
304
|
+
command | "sed 's/ / /'"
|
305
|
+
|
306
|
+
execute_shell(command)
|
307
|
+
|
308
|
+
Kanrisuru::Result.new(command) do |cmd|
|
309
|
+
lines = cmd.to_a
|
310
|
+
|
311
|
+
mapping = {}
|
312
|
+
|
313
|
+
lines.each do |line|
|
314
|
+
next if Kanrisuru::Util.blank?(line)
|
315
|
+
next if line.include?('wtmp') || line.include?('btmp')
|
316
|
+
|
317
|
+
line = line.gsub(' still logged in', '- still logged in') if line.include?('still logged in')
|
318
|
+
|
319
|
+
values = line.split(/\s{2,}/, 4)
|
320
|
+
user = values[0]
|
321
|
+
tty = values[1]
|
322
|
+
ip = IPAddr.new(values[2])
|
323
|
+
|
324
|
+
date_range = values[3]
|
325
|
+
login, logout = date_range.split(' - ')
|
326
|
+
|
327
|
+
login = parse_last_date(login) if login
|
328
|
+
|
329
|
+
logout = parse_last_date(logout) if logout
|
330
|
+
|
331
|
+
detail = SessionDetail.new
|
332
|
+
detail.tty = tty
|
333
|
+
detail.ip_address = ip
|
334
|
+
detail.login_at = login
|
335
|
+
detail.logout_at = logout
|
336
|
+
|
337
|
+
detail.success = !Kanrisuru::Util.present?(opts[:failed_attemps])
|
338
|
+
|
339
|
+
mapping[user] = LoginUser.new(user, []) unless mapping.key?(user)
|
340
|
+
|
341
|
+
mapping[user].sessions << detail
|
342
|
+
end
|
343
|
+
|
344
|
+
mapping.values
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
274
348
|
def ps(opts = {})
|
275
349
|
group = opts[:group]
|
276
350
|
user = opts[:user]
|
@@ -567,6 +641,19 @@ module Kanrisuru
|
|
567
641
|
line.split(char, 2)[1]
|
568
642
|
end
|
569
643
|
|
644
|
+
def parse_last_date(string)
|
645
|
+
tokens = string.split
|
646
|
+
|
647
|
+
return if tokens.length < 4
|
648
|
+
|
649
|
+
month_abbr = tokens[1]
|
650
|
+
day = tokens[2]
|
651
|
+
timestamp = tokens[3]
|
652
|
+
year = tokens[4]
|
653
|
+
|
654
|
+
DateTime.parse("#{day} #{month_abbr} #{year} #{timestamp}")
|
655
|
+
end
|
656
|
+
|
570
657
|
def parse_policy_abbr(value)
|
571
658
|
case value
|
572
659
|
when '-'
|
@@ -714,6 +714,9 @@ module Kanrisuru
|
|
714
714
|
zypper_package_type_opt(command, opts)
|
715
715
|
zypper_solver_opts(command, opts)
|
716
716
|
|
717
|
+
packages = Kanrisuru::Util.string_join_array(opts[:packages], ' ')
|
718
|
+
command << packages
|
719
|
+
|
717
720
|
execute_shell(command)
|
718
721
|
Kanrisuru::Result.new(command)
|
719
722
|
end
|
data/lib/kanrisuru/os_package.rb
CHANGED
@@ -8,7 +8,6 @@ module Kanrisuru
|
|
8
8
|
def self.extended(base)
|
9
9
|
base.instance_variable_set(:@os_method_properties, {})
|
10
10
|
base.instance_variable_set(:@os_methods, Set.new)
|
11
|
-
base.instance_variable_set(:@os_method_cache, {})
|
12
11
|
end
|
13
12
|
|
14
13
|
def os_define(os_name, method_name, options = {})
|
@@ -102,12 +101,6 @@ module Kanrisuru
|
|
102
101
|
include_methods = (public_methods + protected_methods + private_methods).flatten
|
103
102
|
|
104
103
|
include_method_bindings = proc do
|
105
|
-
define_method 'os_method_cache' do
|
106
|
-
@os_method_cache ||= {}
|
107
|
-
end
|
108
|
-
|
109
|
-
private :os_method_cache
|
110
|
-
|
111
104
|
include_methods.each do |method_name|
|
112
105
|
define_method method_name do |*args, &block|
|
113
106
|
unbound_method = mod.instance_method(method_name)
|
@@ -144,10 +137,11 @@ module Kanrisuru
|
|
144
137
|
## defined with the methods added.
|
145
138
|
if Kanrisuru::Remote::Host.instance_variable_defined?("@#{namespace}")
|
146
139
|
namespace_class = Kanrisuru::Remote::Host.const_get(Kanrisuru::Util.camelize(namespace))
|
147
|
-
namespace_instance = instance_variable_get("@#{namespace}")
|
140
|
+
namespace_instance = Kanrisuru::Remote::Host.instance_variable_get("@#{namespace}")
|
148
141
|
else
|
149
142
|
namespace_class = Kanrisuru::Remote::Host.const_set(Kanrisuru::Util.camelize(namespace), Class.new)
|
150
143
|
namespace_instance = Kanrisuru::Remote::Host.instance_variable_set("@#{namespace}", namespace_class.new)
|
144
|
+
|
151
145
|
class_eval do
|
152
146
|
define_method namespace do
|
153
147
|
namespace_instance.instance_variable_set(:@host, self)
|
@@ -168,11 +162,12 @@ module Kanrisuru
|
|
168
162
|
define_method method_name do |*args, &block|
|
169
163
|
unbound_method = nil
|
170
164
|
|
171
|
-
|
172
|
-
|
173
|
-
else
|
174
|
-
host = namespace_instance.instance_variable_get(:@host)
|
165
|
+
host = namespace_instance.instance_variable_get(:@host)
|
166
|
+
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
175
167
|
|
168
|
+
if os_method_cache.key?("#{namespace}.#{method_name}")
|
169
|
+
unbound_method = os_method_cache["#{namespace}.#{method_name}"]
|
170
|
+
else
|
176
171
|
## Find the correct method to resolve based on the OS for the remote host.
|
177
172
|
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
178
173
|
unless defined_method_name
|
@@ -185,7 +180,8 @@ module Kanrisuru
|
|
185
180
|
|
186
181
|
## Cache the unbound method on this host instance for faster resolution on
|
187
182
|
## the next invocation of this method
|
188
|
-
os_method_cache[method_name] = unbound_method
|
183
|
+
os_method_cache["#{namespace}.#{method_name}"] = unbound_method
|
184
|
+
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
189
185
|
end
|
190
186
|
|
191
187
|
## Bind the method to host instance and
|
@@ -197,11 +193,12 @@ module Kanrisuru
|
|
197
193
|
define_method method_name do |*args, &block|
|
198
194
|
unbound_method = nil
|
199
195
|
|
196
|
+
host = self
|
197
|
+
os_method_cache = host.instance_variable_get(:@os_method_cache) || {}
|
198
|
+
|
200
199
|
if os_method_cache.key?(method_name)
|
201
200
|
unbound_method = os_method_cache[method_name]
|
202
201
|
else
|
203
|
-
host = self
|
204
|
-
|
205
202
|
## Find the correct method to resolve based on the OS for the remote host.
|
206
203
|
defined_method_name = host.resolve_os_method_name(os_method_properties, method_name)
|
207
204
|
raise NoMethodError, "undefined method `#{method_name}' for #{self.class}" unless defined_method_name
|
@@ -213,6 +210,7 @@ module Kanrisuru
|
|
213
210
|
## Cache the unbound method on this host instance for faster resolution on
|
214
211
|
## the next invocation of this method
|
215
212
|
os_method_cache[method_name] = unbound_method
|
213
|
+
host.instance_variable_set(:@os_method_cache, os_method_cache)
|
216
214
|
end
|
217
215
|
|
218
216
|
## Bind the method to host instance and
|
data/lib/kanrisuru/version.rb
CHANGED
@@ -96,6 +96,21 @@ RSpec.describe Kanrisuru::Core::System do
|
|
96
96
|
expect(result.cpus.length).to eq(host.cpu.cores)
|
97
97
|
end
|
98
98
|
|
99
|
+
it 'gets login details' do
|
100
|
+
host.su('root')
|
101
|
+
|
102
|
+
result = host.last
|
103
|
+
expect(result).to be_success
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'gets failed login attempts' do
|
107
|
+
host.su('root')
|
108
|
+
|
109
|
+
result = host.last(failed_attempts: true)
|
110
|
+
puts result.data
|
111
|
+
expect(result).to be_success
|
112
|
+
end
|
113
|
+
|
99
114
|
it 'gets process details' do
|
100
115
|
result = host.ps
|
101
116
|
|
@@ -40,6 +40,12 @@ RSpec.describe Kanrisuru::Core::Zypper do
|
|
40
40
|
expect(result).to be_success
|
41
41
|
end
|
42
42
|
|
43
|
+
it 'removes a package' do
|
44
|
+
host.su('root')
|
45
|
+
result = host.zypper('remove', packages: ['ffmpeg'])
|
46
|
+
expect(result).to be_success
|
47
|
+
end
|
48
|
+
|
43
49
|
it 'lists updates' do
|
44
50
|
result = host.zypper('list-updates')
|
45
51
|
expect(result).to be_success
|
@@ -40,18 +40,66 @@ module Kanrisuru
|
|
40
40
|
a - b
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
module TestAliasNames
|
45
|
+
extend Kanrisuru::OsPackage::Define
|
46
|
+
|
47
|
+
os_define :fedora, :output_fedora, alias: :output
|
48
|
+
os_define :debian, :output_debian, alias: :output
|
49
|
+
os_define :sles, :output_sles, alias: :output
|
50
|
+
|
51
|
+
def output_debian
|
52
|
+
'debian'
|
53
|
+
end
|
54
|
+
|
55
|
+
def output_fedora
|
56
|
+
'fedora'
|
57
|
+
end
|
58
|
+
|
59
|
+
def output_sles
|
60
|
+
'sles'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module TestAliasNamesNamespace
|
65
|
+
extend Kanrisuru::OsPackage::Define
|
66
|
+
|
67
|
+
os_define :fedora, :output_fedora, alias: :output
|
68
|
+
os_define :debian, :output_debian, alias: :output
|
69
|
+
os_define :sles, :output_sles, alias: :output
|
70
|
+
|
71
|
+
def output_debian
|
72
|
+
'debian'
|
73
|
+
end
|
74
|
+
|
75
|
+
def output_fedora
|
76
|
+
'fedora'
|
77
|
+
end
|
78
|
+
|
79
|
+
def output_sles
|
80
|
+
'sles'
|
81
|
+
end
|
82
|
+
end
|
43
83
|
end
|
44
84
|
|
45
85
|
module Kanrisuru
|
46
86
|
module Remote
|
47
87
|
class Host
|
48
88
|
os_include Kanrisuru::TestInclude
|
89
|
+
|
90
|
+
os_include Kanrisuru::TestAliasNames
|
91
|
+
os_include Kanrisuru::TestAliasNamesNamespace, namespace: :alias
|
92
|
+
|
49
93
|
os_include Kanrisuru::TestNamespaceAdditions, namespace: :asdf
|
50
94
|
os_include Kanrisuru::TestNamespace, namespace: :asdf
|
51
95
|
end
|
52
96
|
|
53
97
|
class Cluster
|
54
98
|
os_collection Kanrisuru::TestInclude
|
99
|
+
|
100
|
+
os_collection Kanrisuru::TestAliasNames
|
101
|
+
os_collection Kanrisuru::TestAliasNamesNamespace, namespace: :alias
|
102
|
+
|
55
103
|
os_collection Kanrisuru::TestNamespaceAdditions, namespace: :asdf
|
56
104
|
os_collection Kanrisuru::TestNamespace, namespace: :asdf
|
57
105
|
end
|
@@ -94,6 +142,52 @@ RSpec.describe Kanrisuru::OsPackage do
|
|
94
142
|
expect(cluster.asdf.tester).to be_instance_of(Array)
|
95
143
|
|
96
144
|
host.disconnect
|
145
|
+
host2.disconnect
|
146
|
+
cluster.disconnect
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'includes the correct alias named method' do
|
150
|
+
host1 = Kanrisuru::Remote::Host.new(host: 'ubuntu-host', username: 'ubuntu', keys: ['~/.ssh/id_rsa'])
|
151
|
+
host2 = Kanrisuru::Remote::Host.new(host: 'centos-host', username: 'centos', keys: ['~/.ssh/id_rsa'])
|
152
|
+
host3 = Kanrisuru::Remote::Host.new(host: 'opensuse-host', username: 'opensuse', keys: ['~/.ssh/id_rsa'])
|
153
|
+
|
154
|
+
cluster = Kanrisuru::Remote::Cluster.new([host1, host2, host3])
|
155
|
+
|
156
|
+
expect(host1).to respond_to(:output)
|
157
|
+
expect(host2).to respond_to(:output)
|
158
|
+
expect(host3).to respond_to(:output)
|
159
|
+
expect(host1.output).to eq('debian')
|
160
|
+
expect(host2.output).to eq('fedora')
|
161
|
+
expect(host3.output).to eq('sles')
|
162
|
+
|
163
|
+
expect(cluster).to respond_to(:output)
|
164
|
+
expect(cluster.output).to eq([
|
165
|
+
{ host: 'ubuntu-host', result: 'debian' },
|
166
|
+
{ host: 'centos-host', result: 'fedora' },
|
167
|
+
{ host: 'opensuse-host', result: 'sles' }
|
168
|
+
])
|
169
|
+
|
170
|
+
expect(host1).to respond_to(:alias)
|
171
|
+
expect(host2).to respond_to(:alias)
|
172
|
+
expect(host3).to respond_to(:alias)
|
173
|
+
expect(host1.alias).to respond_to(:output)
|
174
|
+
expect(host2.alias).to respond_to(:output)
|
175
|
+
expect(host3.alias).to respond_to(:output)
|
176
|
+
expect(host1.alias.output).to eq('debian')
|
177
|
+
expect(host2.alias.output).to eq('fedora')
|
178
|
+
expect(host3.alias.output).to eq('sles')
|
179
|
+
|
180
|
+
expect(cluster).to respond_to(:alias)
|
181
|
+
expect(cluster.alias).to respond_to(:output)
|
182
|
+
expect(cluster.alias.output).to eq([
|
183
|
+
{ host: 'ubuntu-host', result: 'debian' },
|
184
|
+
{ host: 'centos-host', result: 'fedora' },
|
185
|
+
{ host: 'opensuse-host', result: 'sles' }
|
186
|
+
])
|
187
|
+
|
188
|
+
host1.disconnect
|
189
|
+
host2.disconnect
|
190
|
+
host3.disconnect
|
97
191
|
cluster.disconnect
|
98
192
|
end
|
99
193
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -86,5 +86,17 @@ RSpec.describe Kanrisuru::Core::System do
|
|
86
86
|
:inode,
|
87
87
|
:name
|
88
88
|
)
|
89
|
+
expect(Kanrisuru::Core::System::SessionDetail.new).to respond_to(
|
90
|
+
:tty,
|
91
|
+
:login_at,
|
92
|
+
:logout_at,
|
93
|
+
:ip_address,
|
94
|
+
:success
|
95
|
+
)
|
96
|
+
|
97
|
+
expect(Kanrisuru::Core::System::LoginUser.new).to respond_to(
|
98
|
+
:user,
|
99
|
+
:sessions
|
100
|
+
)
|
89
101
|
end
|
90
102
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kanrisuru
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Mammina
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|