lmcadm 0.10.0 → 0.14.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 +5 -5
- data/.idea/inspectionProfiles/Project_Default.xml +6 -0
- data/.idea/vcs.xml +1 -1
- data/.ruby-version +1 -1
- data/Rakefile +6 -1
- data/dev_lmcadm +4 -0
- data/lib/lmcadm.rb +0 -4
- data/lib/lmcadm/account_commands.rb +2 -2
- data/lib/lmcadm/cloud_commands.rb +1 -0
- data/lib/lmcadm/commands/maintenance.rb +30 -5
- data/lib/lmcadm/commands/preferences.rb +31 -0
- data/lib/lmcadm/commands/terminal.rb +118 -0
- data/lib/lmcadm/helpers/args_helpers.rb +21 -0
- data/lib/lmcadm/helpers/device_helpers.rb +14 -0
- data/lib/lmcadm/helpers/password_helper.rb +1 -1
- data/lib/lmcadm/version.rb +1 -1
- data/lmcadm +1 -1
- data/lmcadm.gemspec +3 -2
- metadata +27 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '0925f20d360b3e8e6740c298a99c12b67474ae9d8d0c1ff6a426109cc9810ef7'
|
4
|
+
data.tar.gz: a3be3188b433d777bce80b5807c497ca41d15c9fa65037eaec5421abd2c6490b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1958b20290dcad4adcddfbb87de3e0352f9e6efa8f5ddd8e343bf1bb3ac5b757ec6cffb61081402fdff986a7d454210ad64d1662f4ac8519e3b9c406e53b5a08
|
7
|
+
data.tar.gz: 3398cb285de12bb7a2211a609fea72cd7f421827e45133c751482f072fa370509d860707c94a7ff1042d2a243ebe0553086cb09da316e24b837b4a46e3a80b15
|
data/.idea/vcs.xml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.1
|
data/Rakefile
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require 'rdoc/task'
|
3
4
|
|
4
5
|
Rake::TestTask.new(:test) do |t|
|
5
6
|
t.libs << "test"
|
6
7
|
t.libs << "lib"
|
7
8
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
9
|
end
|
9
|
-
|
10
|
+
RDoc::Task.new do |rdoc|
|
11
|
+
rdoc.rdoc_dir = 'doc'
|
12
|
+
#rdoc.main = "README.rdoc"
|
13
|
+
#rdoc.rdoc_files.include("lib/lmcadm/helpers/args_helpers.rb")
|
14
|
+
end
|
10
15
|
task :default => :test
|
data/dev_lmcadm
ADDED
data/lib/lmcadm.rb
CHANGED
@@ -29,9 +29,9 @@ module LMCAdm
|
|
29
29
|
accounts.sort {|a, b| a["name"] <=> b["name"]}.each do |account|
|
30
30
|
puts account.inspect if global_options[:v]
|
31
31
|
if options[:l]
|
32
|
-
puts account
|
32
|
+
puts account.summary
|
33
33
|
else
|
34
|
-
puts
|
34
|
+
puts "\"#{account}\" (#{account["type"]})"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
puts accounts.length.to_s + " Accounts found"
|
@@ -7,27 +7,37 @@ module LMCAdm
|
|
7
7
|
root_account = LMC::Account.get LMC::Account::ROOT_ACCOUNT_UUID
|
8
8
|
cloud = LMC::Cloud.instance
|
9
9
|
cloud.auth_for_account root_account
|
10
|
-
result = cloud.post ['cloud-service-devices', 'maintenance', 'licenses', 'resync'], {
|
10
|
+
result = cloud.post ['cloud-service-devices', 'maintenance', 'licenses', 'resync'], {'accountId' => args[0]}
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
maintenance.arg_name 'UUID'
|
14
|
+
maintenance.arg_name 'UUID', [:required]
|
15
15
|
maintenance.desc 'Enable scripting for an account'
|
16
16
|
maintenance.command :scripting do |scr|
|
17
|
+
scr.desc 'Change the state of scripting'
|
17
18
|
scr.switch :enable
|
19
|
+
scr.desc 'Get the state of scripting'
|
20
|
+
scr.switch :get
|
18
21
|
scr.action do |global_options, options, args|
|
22
|
+
raise "No account UUID specified" if args.length < 1
|
19
23
|
root_account = LMC::Account.get LMC::Account::ROOT_ACCOUNT_UUID
|
20
24
|
cloud = LMC::Cloud.instance
|
21
25
|
cloud.auth_for_account root_account
|
22
|
-
|
23
|
-
|
26
|
+
if options[:get]
|
27
|
+
result = cloud.get ['cloud-service-config', 'configroot', 'accounts', args.first, 'scriptauthority']
|
28
|
+
puts result.body
|
29
|
+
else
|
30
|
+
result = cloud.put ['cloud-service-config', 'configroot', 'accounts', args.first, 'scriptauthority'], options[:enable]
|
31
|
+
raise "error - unexpected result" unless result.body == options[:enable]
|
32
|
+
end
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
27
|
-
maintenance.arg_name 'UUID'
|
36
|
+
maintenance.arg_name 'UUID'
|
28
37
|
maintenance.desc 'Exempt user from brute force blocking'
|
29
38
|
maintenance.command :whitelist do |wl|
|
30
39
|
wl.action do |_g, _o, args|
|
40
|
+
Helpers.ensure_arg args, kind: 'user uuid'
|
31
41
|
cloud = LMC::Cloud.instance
|
32
42
|
root_account = LMC::Account.get LMC::Account::ROOT_ACCOUNT_UUID
|
33
43
|
cloud.auth_for_account root_account
|
@@ -36,5 +46,20 @@ module LMCAdm
|
|
36
46
|
cloud.post url_components, {}
|
37
47
|
end
|
38
48
|
end
|
49
|
+
|
50
|
+
maintenance.arg_name 'UUID', required: true
|
51
|
+
maintenance.desc 'Remove entity from blacklist'
|
52
|
+
maintenance.command :unblacklist do |unbl|
|
53
|
+
unbl.flag 'entity-type', :t, desc: 'Entity type. Choose "principals" or "accounts".', required: true
|
54
|
+
unbl.flag 'process-type', :p, desc: 'Process type', default_value: 'CLAIMING'
|
55
|
+
unbl.action do |_g, o, args|
|
56
|
+
Helpers.ensure_arg args, kind: 'entity uuid'
|
57
|
+
cloud = LMC::Cloud.instance
|
58
|
+
root_account = LMC::Account.get LMC::Account::ROOT_ACCOUNT_UUID
|
59
|
+
cloud.auth_for_account root_account
|
60
|
+
url_components = ['cloud-service-devices', 'accesscontrol', o['process-type'], o['entity-type'], args.first]
|
61
|
+
cloud.delete url_components
|
62
|
+
end
|
63
|
+
end
|
39
64
|
end
|
40
65
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LMCAdm #:nodoc:
|
4
|
+
desc 'Manipulate preferences'
|
5
|
+
command :preferences do |preferences|
|
6
|
+
preferences.desc 'Get last account data'
|
7
|
+
preferences.arg_name 'accounts'
|
8
|
+
preferences.command :lastaccounts do |la|
|
9
|
+
la.action do |g, _o, args|
|
10
|
+
cloud = LMC::Cloud.new(g[:cloud_host], g[:user], g[:password])
|
11
|
+
self_ui = cloud.preferences [:principals, :self, :ui]
|
12
|
+
if args.empty?
|
13
|
+
ids = self_ui.get 'lastAccountIds'
|
14
|
+
accounts = ids.map do |id|
|
15
|
+
LMC::Account.get id
|
16
|
+
end
|
17
|
+
accounts.each { |a|
|
18
|
+
puts a.summary
|
19
|
+
}
|
20
|
+
else
|
21
|
+
account_ids = args.map { |arg|
|
22
|
+
LMC::Account.get_by_uuid_or_name(arg).id
|
23
|
+
}
|
24
|
+
puts account_ids
|
25
|
+
puts self_ui.put 'lastAccountIds', account_ids
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'websocket-eventmachine-client'
|
2
|
+
require 'io/console'
|
3
|
+
require 'date'
|
4
|
+
module LMCAdm
|
5
|
+
|
6
|
+
class KeyboardHandler < EM::Connection
|
7
|
+
def receive_data(data)
|
8
|
+
if data == "\C-c"
|
9
|
+
EventMachine::stop_event_loop
|
10
|
+
end
|
11
|
+
LMCAdm::getWS.send '1' + data, type: 'binary'
|
12
|
+
|
13
|
+
end
|
14
|
+
#include EM::Protocols::LineText2
|
15
|
+
|
16
|
+
#def receive_line(data)
|
17
|
+
# LMCAdm::getWS.send '1' + data.strip + "\r", type: 'binary'
|
18
|
+
#end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.getWS
|
22
|
+
@ws
|
23
|
+
end
|
24
|
+
|
25
|
+
arg_name "device"
|
26
|
+
desc "Open terminal"
|
27
|
+
command :terminal do |t|
|
28
|
+
t.desc "Account name|UUID"
|
29
|
+
t.flag :account, :A, :required => true
|
30
|
+
|
31
|
+
t.action do |g, o, args|
|
32
|
+
account = LMC::Account.get_by_uuid_or_name o[:account]
|
33
|
+
device = Helpers::find_device account.devices, name: args.first, id: args.first
|
34
|
+
account.cloud.auth_for_account account
|
35
|
+
payload = {type: 'TERMINAL',
|
36
|
+
deviceIds: [device.id]}
|
37
|
+
sessionInfo = account.cloud.post ['cloud-service-devicetunnel', 'accounts', account.id, 'terminal'], payload
|
38
|
+
|
39
|
+
|
40
|
+
if g['use-tls']
|
41
|
+
url = 'wss://'
|
42
|
+
else
|
43
|
+
url = 'ws://'
|
44
|
+
end
|
45
|
+
url += g[:cloud_host]
|
46
|
+
url += '/cloud-service-devicetunnel/session'
|
47
|
+
headers_hash = {
|
48
|
+
'Sec-WebSocket-Protocol' => "TYPE_TERMINAL, REQU_USER, IDEN_#{sessionInfo.body.first['id']}, ACCT_#{account.id}, DEVC_#{device.id}"
|
49
|
+
}
|
50
|
+
begin
|
51
|
+
EventMachine.epoll
|
52
|
+
EventMachine.run do
|
53
|
+
trap("TERM") { stop g[:debug] }
|
54
|
+
trap("INT") { stop g[:debug] }
|
55
|
+
IO.console.raw!
|
56
|
+
EventMachine.open_keyboard(LMCAdm::KeyboardHandler)
|
57
|
+
@ws = WebSocket::EventMachine::Client.connect({uri: url, headers: headers_hash})
|
58
|
+
closing = false
|
59
|
+
|
60
|
+
@ws.onopen do
|
61
|
+
print "Connected to #{device.name} (#{device.id}):\r\n"
|
62
|
+
remaining_args = args.drop(1)
|
63
|
+
if remaining_args.length > 0
|
64
|
+
@ws.send '1' + remaining_args.join(' ') + "\r", type: 'binary'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
@ws.onmessage do |msg, type|
|
69
|
+
print "##{msg.length}##{msg.inspect}#" if g[:debug]
|
70
|
+
# respond to custom keepalive
|
71
|
+
if msg.start_with? '0'
|
72
|
+
@ws.send '0', type: 'binary'
|
73
|
+
end
|
74
|
+
if msg.start_with? "1"
|
75
|
+
print msg[1..-1].gsub("\n", "\r\n")
|
76
|
+
else
|
77
|
+
print msg if g[:debug]
|
78
|
+
end
|
79
|
+
print DateTime.now.to_s if g[:debug]
|
80
|
+
if msg.include? "\n\nGoodbye\n\n"
|
81
|
+
stop g[:debug]
|
82
|
+
closing = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
@ws.onclose do
|
87
|
+
print DateTime.now.to_s if g[:debug]
|
88
|
+
print "Disconnected\r\n"
|
89
|
+
stop g[:debug] unless closing
|
90
|
+
end
|
91
|
+
|
92
|
+
@ws.onerror do |e|
|
93
|
+
puts "Error: #{e}"
|
94
|
+
end
|
95
|
+
|
96
|
+
@ws.onping do |msg|
|
97
|
+
puts "Received ping: #{msg}" if g[:verbose]
|
98
|
+
end
|
99
|
+
|
100
|
+
@ws.onpong do |msg|
|
101
|
+
puts "Received pong: #{msg}" if g[:verbose]
|
102
|
+
end
|
103
|
+
|
104
|
+
def stop(debug = false)
|
105
|
+
print DateTime.now.to_s if debug
|
106
|
+
print "Terminating connection\r\n"
|
107
|
+
EventMachine.stop
|
108
|
+
end
|
109
|
+
end
|
110
|
+
ensure
|
111
|
+
IO.console.cooked!
|
112
|
+
end
|
113
|
+
# disabled, getting 401 anyways
|
114
|
+
#account.cloud.auth_for_account account
|
115
|
+
#account.cloud.delete ['cloud-service-devicetunnel', 'accounts', account.id, "terminal?ids=#{sessionInfo.body.first['id']}"]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module LMCAdm
|
3
|
+
module Helpers
|
4
|
+
# Verifies that args contains at least one object.
|
5
|
+
# Raises RuntimeError with either the given message or an error explaining that kind is expected.
|
6
|
+
#
|
7
|
+
# @param [Object] args
|
8
|
+
# @param [String (frozen)] kind optional
|
9
|
+
# @param [Object] message optional
|
10
|
+
def self.ensure_arg(args, kind: 'argument', message: nil)
|
11
|
+
error = ""
|
12
|
+
if args.length < 1
|
13
|
+
error = "Argument missing: No #{kind} specified."
|
14
|
+
error = message if message
|
15
|
+
end
|
16
|
+
raise error unless error.empty?
|
17
|
+
return args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module LMCAdm
|
3
|
+
module Helpers
|
4
|
+
def self.find_device(devices, name: '', id: '')
|
5
|
+
found = devices.select do |device|
|
6
|
+
(id == device.id) || (name == device.name)
|
7
|
+
end
|
8
|
+
raise "More than one device found for: #{name} #{id}" if found.length > 1
|
9
|
+
raise "Device not found: #{name} #{id}" if found.length < 1
|
10
|
+
return found.first
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
data/lib/lmcadm/version.rb
CHANGED
data/lmcadm
CHANGED
data/lmcadm.gemspec
CHANGED
@@ -20,12 +20,13 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 2.0"
|
23
|
-
spec.add_development_dependency "rake", "~>
|
23
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
24
24
|
spec.add_development_dependency "minitest", "~> 5.0"
|
25
25
|
spec.add_development_dependency "pry-nav", "0.2.4"
|
26
26
|
|
27
|
-
spec.add_runtime_dependency 'lmc', '~> 0.
|
27
|
+
spec.add_runtime_dependency 'lmc', '~> 0.12.0'
|
28
28
|
spec.add_runtime_dependency 'gli', '~> 2.17'
|
29
29
|
spec.add_runtime_dependency 'table_print', '~> 1.5'
|
30
30
|
spec.add_runtime_dependency 'colorize', '~> 0.8'
|
31
|
+
spec.add_runtime_dependency 'websocket-eventmachine-client', '~> 1.3.0'
|
31
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lmcadm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- erpel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.12.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.12.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: gli
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0.8'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: websocket-eventmachine-client
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.3.0
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.3.0
|
125
139
|
description:
|
126
140
|
email:
|
127
141
|
- philipp@copythat.de
|
@@ -132,6 +146,7 @@ extra_rdoc_files: []
|
|
132
146
|
files:
|
133
147
|
- ".gitignore"
|
134
148
|
- ".idea/encodings.xml"
|
149
|
+
- ".idea/inspectionProfiles/Project_Default.xml"
|
135
150
|
- ".idea/vcs.xml"
|
136
151
|
- ".ruby-version"
|
137
152
|
- Gemfile
|
@@ -140,6 +155,7 @@ files:
|
|
140
155
|
- Rakefile
|
141
156
|
- bin/console
|
142
157
|
- bin/setup
|
158
|
+
- dev_lmcadm
|
143
159
|
- exe/lmcadm
|
144
160
|
- lib/lmcadm.rb
|
145
161
|
- lib/lmcadm/ColoredProgressVisualizer.rb
|
@@ -152,11 +168,15 @@ files:
|
|
152
168
|
- lib/lmcadm/commands/completion.rb
|
153
169
|
- lib/lmcadm/commands/maintenance.rb
|
154
170
|
- lib/lmcadm/commands/monitor.rb
|
171
|
+
- lib/lmcadm/commands/preferences.rb
|
155
172
|
- lib/lmcadm/commands/principal.rb
|
156
173
|
- lib/lmcadm/commands/privatecloud.rb
|
157
174
|
- lib/lmcadm/commands/rights.rb
|
175
|
+
- lib/lmcadm/commands/terminal.rb
|
158
176
|
- lib/lmcadm/config_commands.rb
|
159
177
|
- lib/lmcadm/device_commands.rb
|
178
|
+
- lib/lmcadm/helpers/args_helpers.rb
|
179
|
+
- lib/lmcadm/helpers/device_helpers.rb
|
160
180
|
- lib/lmcadm/helpers/password_helper.rb
|
161
181
|
- lib/lmcadm/helpers/string_helpers.rb
|
162
182
|
- lib/lmcadm/version.rb
|
@@ -181,8 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
201
|
- !ruby/object:Gem::Version
|
182
202
|
version: '0'
|
183
203
|
requirements: []
|
184
|
-
|
185
|
-
rubygems_version: 2.6.11
|
204
|
+
rubygems_version: 3.1.2
|
186
205
|
signing_key:
|
187
206
|
specification_version: 4
|
188
207
|
summary: lmcadm is a command line client for LMC
|