lmcadm 0.11.0 → 0.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 745a5304645376df76004e6c5130341aba234243
4
- data.tar.gz: 9ace3654a56c6d756417317fc1a5ebcf07edb1eb
2
+ SHA256:
3
+ metadata.gz: 44c6d0a6cd45c6c772311396c13646899f7db20675004254fc70cb1821620d3c
4
+ data.tar.gz: 93484873efe2767cb5c7911d00e72be3937cc7fbed2e29dfd3cbaeeb4d634d1d
5
5
  SHA512:
6
- metadata.gz: f350bbb06491ffc16d75be0e6e47987882f7c9fd1e3c8211f340c417bc1e04558fe778891f20738ac0f136a9236f455742317a33c27d501c164280f740a1061a
7
- data.tar.gz: 1bb9baf23b511dff5df7424b694fd080723face9035bcb2ebfb1853e484b75c8cb46e926bfe8514e3489f9b98fa38d8c636bd42687856c463f9f28a4bc00634d
6
+ metadata.gz: d9790f5e3e28fcd2fc3b4a8633b47019b3190e166bc15e9e926ee552620a6ad9a1edb4364f2355c9c4a0cc523db6997f042bccbcdf8f07d781611d1fdf4759ee
7
+ data.tar.gz: 92ed71b779d0bb817035a51965f4c308ce76cff89c4ddc86f8b06faf940766242e513260164eec6fb62b9c198fbb1e722072a8dc9c65e1be2f475070221d01f8
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
5
+ </profile>
6
+ </component>
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <project version="4">
3
3
  <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
4
+ <mapping directory="" vcs="Git" />
5
5
  </component>
6
6
  </project>
@@ -1 +1 @@
1
- 2.4.1
1
+ 2.7.1
data/README.md CHANGED
@@ -8,6 +8,12 @@ Install via rubygems:
8
8
 
9
9
  $ gem install lmcadm
10
10
 
11
+ ### Requirements
12
+ Building native extensions for certain dependencies require ruby headers or source code to be present.
13
+ These can usually be installed the same way ruby was installed.
14
+
15
+ On Ubuntu for example, installing the `ruby-dev` via the package manager is sufficient.
16
+
11
17
  ## Usage
12
18
 
13
19
  The primary usage documentation is in the help output of lmcadm:
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
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ #wrapper script
3
+ #set -x
4
+ LMCADM_PATH_DEP=1 GLI_DEBUG=false bundle exec exe/lmcadm "$@"
data/exe/lmcadm CHANGED
@@ -25,7 +25,7 @@ module LMCAdm
25
25
  commands_from "lmcadm/commands"
26
26
 
27
27
  desc 'Be verbose'
28
- switch [:v, :verbose]
28
+ switch :verbose, :v
29
29
 
30
30
  desc 'debug'
31
31
  switch [:debug]
@@ -33,9 +33,9 @@ module LMCAdm
33
33
  desc 'Measure time taken for operations'
34
34
  switch "take-time"
35
35
 
36
- desc 'cloud host'
36
+ desc 'LMC host, may include a port number'
37
37
  default_value "cloud.lancom.de"
38
- flag :C, :cloud_host
38
+ flag :cloud_host, :C
39
39
 
40
40
  desc 'Use encrypted connection'
41
41
  default_value true
@@ -46,13 +46,16 @@ module LMCAdm
46
46
  switch "verify-tls"
47
47
 
48
48
  desc 'username'
49
- default_value "admin"
50
- flag :U, :user
49
+ default_value ""
50
+ flag :user, :U
51
51
 
52
52
  desc 'password'
53
53
  default_value ""
54
- flag [:P, :password], :mask => true
54
+ flag [:password, :P], :mask => true
55
55
 
56
+ desc 'Use 2FA code'
57
+ default_value false
58
+ switch [:code, 'F']
56
59
 
57
60
  pre do |global, command, options, args|
58
61
  # Pre logic here
@@ -60,12 +63,23 @@ module LMCAdm
60
63
  # chosen command
61
64
  # Use skips_pre before a command to skip this block
62
65
  # on that command only
63
- if command.name != :completion && global[:password] == ""
64
- global[:password] = Helpers::read_pw "Enter password for #{global[:user]}:"
66
+ if command.name != :completion
67
+ if global[:user] == ""
68
+ print "Enter user:"
69
+ global[:user] = STDIN.gets.chomp
70
+ end
71
+ if global[:password] == ""
72
+ global[:password] = Helpers::read_pw "Enter password for #{global[:user]}:"
73
+ end
74
+ twofactor_code = nil
75
+ if global[:code]
76
+ twofactor_code = Helpers::read_pw "Enter 2FA code:"
77
+ end
65
78
  end
66
79
  ::LMC::Cloud.cloud_host = global[:cloud_host]
67
80
  ::LMC::Cloud.user = global[:user]
68
81
  ::LMC::Cloud.password = global[:password]
82
+ ::LMC::Cloud.code = twofactor_code
69
83
  ::LMC::Cloud.verbose = global[:verbose]
70
84
  ::LMC::Cloud.debug = global[:debug]
71
85
  ::LMC::Cloud.verify_tls = global["verify-tls"]
@@ -1,7 +1,3 @@
1
- #require "lmcadm/version"
2
- #require 'lmcadm/account_commands'
3
- #require 'lmcadm/test_command_container'
4
-
5
1
  Dir.glob(File.expand_path("../lmcadm/*.rb", __FILE__)).each do |file|
6
2
  require file
7
3
  end
@@ -16,7 +16,7 @@ module LMCAdm
16
16
  account_list.switch :l, :long
17
17
  account_list.action do |global_options, options, args|
18
18
  t = ProgressVisualizer.new "Cloud login"
19
- lmcen = LMC::Cloud.new(global_options[:cloud_host], global_options[:user], global_options[:password])
19
+ lmcen = LMC::Cloud.instance
20
20
  t.done
21
21
  t = ProgressVisualizer.new "Getting accounts"
22
22
  accounts = lmcen.get_accounts_objects
@@ -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["name"] + " (" + account["type"] + ") ID: " + account["id"]
32
+ puts account.summary
33
33
  else
34
- puts account["name"] + " (" + account["type"] + ")"
34
+ puts "\"#{account}\" (#{account["type"]})"
35
35
  end
36
36
  end
37
37
  puts accounts.length.to_s + " Accounts found"
@@ -8,13 +8,15 @@ module LMCAdm
8
8
  command :cloud do |c|
9
9
  c.desc 'Check cloud connectivity'
10
10
  c.action do |global_options|
11
- lmcen = LMC::Cloud.new(global_options[:cloud_host], global_options[:user], global_options[:password])
11
+ lmcen = LMC::Cloud.instance
12
12
  puts "Base URL: #{lmcen.build_url}"
13
13
  puts "Cloud connection OK" if lmcen.auth_ok
14
14
  if global_options[:v]
15
15
  puts "authentication token: " + lmcen.session_token
16
16
  end
17
17
  end
18
+
19
+ c.desc 'Display cloud version information'
18
20
  c.command :about do |cloud_about|
19
21
  cloud_about.action do |global_options|
20
22
  cloud = LMC::Cloud.instance
@@ -27,6 +29,7 @@ module LMCAdm
27
29
  }}
28
30
  tp backstage_infos
29
31
  puts '---'
32
+ puts "Base URL: #{cloud.build_url}"
30
33
  puts "Principal: #{LMC::Principal.get_self(cloud)}"
31
34
 
32
35
  end
@@ -7,7 +7,7 @@ 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'], { 'accountId' => args[0] }
10
+ result = cloud.post ['cloud-service-devices', 'maintenance', 'licenses', 'resync'], {'accountId' => args[0]}
11
11
  end
12
12
  end
13
13
 
@@ -33,10 +33,11 @@ module LMCAdm
33
33
  end
34
34
  end
35
35
 
36
- maintenance.arg_name 'UUID', required: true
36
+ maintenance.arg_name 'UUID'
37
37
  maintenance.desc 'Exempt user from brute force blocking'
38
38
  maintenance.command :whitelist do |wl|
39
39
  wl.action do |_g, _o, args|
40
+ Helpers.ensure_arg args, kind: 'user uuid'
40
41
  cloud = LMC::Cloud.instance
41
42
  root_account = LMC::Account.get LMC::Account::ROOT_ACCOUNT_UUID
42
43
  cloud.auth_for_account root_account
@@ -45,5 +46,20 @@ module LMCAdm
45
46
  cloud.post url_components, {}
46
47
  end
47
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
48
64
  end
49
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.instance
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
+
@@ -1,5 +1,5 @@
1
- require 'io/console'
2
1
  # frozen_string_literal: true
2
+ require 'io/console'
3
3
 
4
4
  module LMCAdm
5
5
  # This module includes helpers for shared functionality across the
@@ -1,3 +1,3 @@
1
1
  module LMCAdm
2
- VERSION = '0.11.0'
2
+ VERSION = '0.15.0'
3
3
  end
@@ -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", "~> 10.0"
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.10.1'
27
+ spec.add_runtime_dependency 'lmc', '~> 0.13.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.11.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - erpel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-10 00:00:00.000000000 Z
11
+ date: 2021-01-15 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: '10.0'
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: '10.0'
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.10.1
75
+ version: 0.13.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.10.1
82
+ version: 0.13.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: gli
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -122,7 +122,21 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.8'
125
- description:
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
139
+ description:
126
140
  email:
127
141
  - philipp@copythat.de
128
142
  executables:
@@ -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,21 +168,25 @@ 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
163
183
  - lmcadm
164
184
  - lmcadm.gemspec
165
- homepage:
185
+ homepage:
166
186
  licenses:
167
187
  - BSD-3-Clause
168
188
  metadata: {}
169
- post_install_message:
189
+ post_install_message:
170
190
  rdoc_options: []
171
191
  require_paths:
172
192
  - lib
@@ -181,9 +201,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
181
201
  - !ruby/object:Gem::Version
182
202
  version: '0'
183
203
  requirements: []
184
- rubyforge_project:
185
- rubygems_version: 2.6.11
186
- signing_key:
204
+ rubygems_version: 3.1.2
205
+ signing_key:
187
206
  specification_version: 4
188
207
  summary: lmcadm is a command line client for LMC
189
208
  test_files: []