lmc 0.12.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 +4 -4
- data/.idea/vcs.xml +1 -1
- data/.rubocop.yml +61 -1
- data/Rakefile +9 -4
- data/coverage/.last_run.json +1 -1
- data/lib/lmc.rb +15 -2
- data/lib/lmc/Account.rb +19 -11
- data/lib/lmc/Cloud.rb +51 -29
- data/lib/lmc/Response.rb +4 -3
- data/lib/lmc/Site.rb +0 -1
- data/lib/lmc/User.rb +2 -6
- data/lib/lmc/authority.rb +1 -2
- data/lib/lmc/config/device_config.rb +11 -8
- data/lib/lmc/config/device_dsc_ui.rb +2 -4
- data/lib/lmc/entity.rb +1 -1
- data/lib/lmc/exceptions/lmc_outdated_terms_of_use_exception.rb +1 -5
- data/lib/lmc/exceptions/lmc_two_factor_required_exception.rb +8 -0
- data/lib/lmc/exceptions/response_exception.rb +22 -0
- data/lib/lmc/version.rb +1 -1
- data/lmc.gemspec +4 -3
- metadata +30 -28
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 96d4cb0e5c48a388b0fcaed6aa9bbbfe43275dfa4e5f8de31ed9f22973cd002d
|
|
4
|
+
data.tar.gz: fcb70677fc2ef666fc28d5e1dd6ca69d6de053fbe9f1a8fbd825d973d32643c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f94290c326379b14fb128e595a27713af19d14cbcb5eeb9cc59abd193ad6cd5894a85debcf7b22812b6c1ca570a6af0e49bbd0745c5708805b202ca47836c324
|
|
7
|
+
data.tar.gz: 79751ea5bdbd51b6d1cf9fa76ad0fdadd1c8b070fda7a68b3a7b683b82ddd18f49b006ef0c862526e09ef60286169df6459be55eaedc40bf45728027481e0beb
|
data/.idea/vcs.xml
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -5,4 +5,64 @@ Layout/FirstHashElementIndentation:
|
|
|
5
5
|
Layout/LineLength:
|
|
6
6
|
Max: 110
|
|
7
7
|
Style/IfUnlessModifier:
|
|
8
|
-
Enabled: false
|
|
8
|
+
Enabled: false
|
|
9
|
+
Gemspec/DateAssignment: # (new in 1.10)
|
|
10
|
+
Enabled: true
|
|
11
|
+
Layout/SpaceBeforeBrackets: # (new in 1.7)
|
|
12
|
+
Enabled: true
|
|
13
|
+
Lint/AmbiguousAssignment: # (new in 1.7)
|
|
14
|
+
Enabled: true
|
|
15
|
+
Lint/DeprecatedConstants: # (new in 1.8)
|
|
16
|
+
Enabled: true
|
|
17
|
+
Lint/DuplicateBranch: # (new in 1.3)
|
|
18
|
+
Enabled: true
|
|
19
|
+
Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
|
|
20
|
+
Enabled: true
|
|
21
|
+
Lint/EmptyBlock: # (new in 1.1)
|
|
22
|
+
Enabled: true
|
|
23
|
+
Lint/EmptyClass: # (new in 1.3)
|
|
24
|
+
Enabled: true
|
|
25
|
+
Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
|
|
26
|
+
Enabled: true
|
|
27
|
+
Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
|
|
28
|
+
Enabled: true
|
|
29
|
+
Lint/NumberedParameterAssignment: # (new in 1.9)
|
|
30
|
+
Enabled: true
|
|
31
|
+
Lint/OrAssignmentToConstant: # (new in 1.9)
|
|
32
|
+
Enabled: true
|
|
33
|
+
Lint/RedundantDirGlobSort: # (new in 1.8)
|
|
34
|
+
Enabled: true
|
|
35
|
+
Lint/SymbolConversion: # (new in 1.9)
|
|
36
|
+
Enabled: true
|
|
37
|
+
Lint/ToEnumArguments: # (new in 1.1)
|
|
38
|
+
Enabled: true
|
|
39
|
+
Lint/TripleQuotes: # (new in 1.9)
|
|
40
|
+
Enabled: true
|
|
41
|
+
Lint/UnexpectedBlockArity: # (new in 1.5)
|
|
42
|
+
Enabled: true
|
|
43
|
+
Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
|
|
44
|
+
Enabled: true
|
|
45
|
+
Style/ArgumentsForwarding: # (new in 1.1)
|
|
46
|
+
Enabled: true
|
|
47
|
+
Style/CollectionCompact: # (new in 1.2)
|
|
48
|
+
Enabled: true
|
|
49
|
+
Style/DocumentDynamicEvalDefinition: # (new in 1.1)
|
|
50
|
+
Enabled: true
|
|
51
|
+
Style/EndlessMethod: # (new in 1.8)
|
|
52
|
+
Enabled: true
|
|
53
|
+
Style/HashConversion: # (new in 1.10)
|
|
54
|
+
Enabled: true
|
|
55
|
+
Style/HashExcept: # (new in 1.7)
|
|
56
|
+
Enabled: true
|
|
57
|
+
Style/IfWithBooleanLiteralBranches: # (new in 1.9)
|
|
58
|
+
Enabled: true
|
|
59
|
+
Style/NegatedIfElseCondition: # (new in 1.2)
|
|
60
|
+
Enabled: true
|
|
61
|
+
Style/NilLambda: # (new in 1.3)
|
|
62
|
+
Enabled: true
|
|
63
|
+
Style/RedundantArgument: # (new in 1.4)
|
|
64
|
+
Enabled: true
|
|
65
|
+
Style/StringChars: # (new in 1.12)
|
|
66
|
+
Enabled: true
|
|
67
|
+
Style/SwapValues: # (new in 1.1)
|
|
68
|
+
Enabled: true
|
data/Rakefile
CHANGED
|
@@ -13,23 +13,28 @@ end
|
|
|
13
13
|
|
|
14
14
|
RuboCop::RakeTask.new(:autocop) do |t|
|
|
15
15
|
autofix = [
|
|
16
|
+
'Gemspec/OrderedDependencies',
|
|
17
|
+
'Layout/EmptyLineBetweenDefs',
|
|
16
18
|
'Layout/EmptyLines',
|
|
17
19
|
'Layout/EmptyLinesAroundClassBody',
|
|
20
|
+
'Layout/EmptyLinesAroundMethodBody',
|
|
18
21
|
'Layout/EmptyLinesAroundModuleBody',
|
|
19
|
-
'Layout/EmptyLineBetweenDefs',
|
|
20
22
|
'Layout/LeadingCommentSpace',
|
|
23
|
+
'Layout/SpaceAfterComma',
|
|
21
24
|
'Layout/SpaceAroundOperators',
|
|
22
25
|
'Layout/SpaceInsideBlockBraces',
|
|
23
26
|
'Layout/SpaceInsideHashLiteralBraces',
|
|
24
27
|
'Layout/TrailingEmptyLines',
|
|
28
|
+
'Lint/RedundantStringCoercion',
|
|
29
|
+
'Lint/UnusedBlockArgument',
|
|
25
30
|
'Style/CommentAnnotation',
|
|
26
31
|
'Style/FrozenStringLiteralComment',
|
|
27
32
|
'Style/MethodDefParentheses',
|
|
28
|
-
'Style/RedundantSelf',
|
|
29
33
|
'Style/RedundantReturn',
|
|
30
|
-
'Style/
|
|
31
|
-
'Style/StringLiteralsInInterpolation',
|
|
34
|
+
'Style/RedundantSelf',
|
|
32
35
|
'Style/StabbyLambdaParentheses',
|
|
36
|
+
'Style/StringLiterals',
|
|
37
|
+
'Style/StringLiteralsInInterpolation'
|
|
33
38
|
]
|
|
34
39
|
t.options = ['--only', autofix.join(','), '--auto-correct', 'lib', 'test', 'Rakefile', 'lmc.gemspec']
|
|
35
40
|
end
|
data/coverage/.last_run.json
CHANGED
data/lib/lmc.rb
CHANGED
|
@@ -5,10 +5,23 @@ require 'restclient'
|
|
|
5
5
|
|
|
6
6
|
module LMC
|
|
7
7
|
SERVICELIST = ['cloud-service-auth',
|
|
8
|
+
'cloud-service-backstage',
|
|
9
|
+
'cloud-service-config',
|
|
8
10
|
'cloud-service-devices',
|
|
11
|
+
'cloud-service-devicetunnel',
|
|
12
|
+
'cloud-service-dyndns',
|
|
13
|
+
'cloud-service-fields',
|
|
14
|
+
'cloud-service-geolocation',
|
|
15
|
+
'cloud-service-hotspot',
|
|
16
|
+
'cloud-service-jobs',
|
|
9
17
|
'cloud-service-monitoring',
|
|
10
|
-
'cloud-service-
|
|
11
|
-
'cloud-service-
|
|
18
|
+
'cloud-service-messaging',
|
|
19
|
+
'cloud-service-notification',
|
|
20
|
+
'cloud-service-licenses',
|
|
21
|
+
'cloud-service-logging',
|
|
22
|
+
'cloud-service-preferences',
|
|
23
|
+
'cloud-service-uf-translator'
|
|
24
|
+
]
|
|
12
25
|
|
|
13
26
|
def self.useful
|
|
14
27
|
true
|
data/lib/lmc/Account.rb
CHANGED
|
@@ -73,13 +73,14 @@ module LMC
|
|
|
73
73
|
def members
|
|
74
74
|
ids = Cloud.instance.get ['cloud-service-auth', 'accounts', @id, 'members'], 'select' => 'id'
|
|
75
75
|
puts ids.inspect if Cloud.debug
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
# these are not actual membership objects
|
|
77
|
+
memberships = ids.map do |member_id|
|
|
78
|
+
response = Cloud.instance.get ['cloud-service-auth', 'accounts', @id, 'members', member_id]
|
|
79
|
+
memberships = response.body
|
|
80
|
+
puts memberships.inspect if Cloud.debug
|
|
81
|
+
memberships
|
|
81
82
|
end
|
|
82
|
-
|
|
83
|
+
memberships
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
def find_member_by_name(name)
|
|
@@ -93,10 +94,12 @@ module LMC
|
|
|
93
94
|
member
|
|
94
95
|
end
|
|
95
96
|
|
|
97
|
+
#--
|
|
96
98
|
# def update_member(principal_id, data)
|
|
97
99
|
# response = @cloud.post ["cloud-service-auth", "accounts", id, 'members', principal_id], data
|
|
98
100
|
# return response
|
|
99
101
|
# end
|
|
102
|
+
#++
|
|
100
103
|
|
|
101
104
|
def remove_membership(member_id)
|
|
102
105
|
@cloud.delete ['cloud-service-auth', 'accounts', id, 'members', member_id]
|
|
@@ -123,16 +126,21 @@ module LMC
|
|
|
123
126
|
end
|
|
124
127
|
|
|
125
128
|
def children
|
|
126
|
-
@cloud.auth_for_accounts([
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
@cloud.auth_for_accounts([ROOT_ACCOUNT_UUID])
|
|
130
|
+
# Projects can not have children, return empty map immediately as optimization
|
|
131
|
+
if type != 'PROJECT'
|
|
132
|
+
response = @cloud.get ['cloud-service-auth', 'accounts', id, 'children']
|
|
133
|
+
response.map { |child| Account.new @cloud, child }
|
|
134
|
+
else
|
|
135
|
+
[]
|
|
136
|
+
end
|
|
129
137
|
end
|
|
130
138
|
|
|
139
|
+
# This can only show the most recent page of logs so far
|
|
131
140
|
def logs
|
|
132
|
-
# https://lmctest/cloud-service-logging/accounts/6392b234-b11c-498a-a077-a5f5b23c54a0/logs?lang=DE
|
|
133
141
|
cloud = Cloud.instance
|
|
134
142
|
cloud.auth_for_accounts [id]
|
|
135
|
-
cloud.get(['cloud-service-logging', 'accounts', id, 'logs?lang=DE']).body
|
|
143
|
+
cloud.get(['cloud-service-logging', 'accounts', id, 'logs', 'paginated?lang=DE']).body.logs
|
|
136
144
|
end
|
|
137
145
|
|
|
138
146
|
def sites
|
data/lib/lmc/Cloud.rb
CHANGED
|
@@ -7,31 +7,33 @@ require 'restclient'
|
|
|
7
7
|
module LMC
|
|
8
8
|
class Cloud
|
|
9
9
|
class << self
|
|
10
|
-
attr_accessor :cloud_host, :user, :password, :verbose, :debug, :verify_tls, :use_tls
|
|
10
|
+
attr_accessor :cloud_host, :user, :password, :code, :verbose, :debug, :verify_tls, :use_tls
|
|
11
11
|
Cloud.use_tls = true
|
|
12
12
|
Cloud.verify_tls = true
|
|
13
|
+
Cloud.code = nil
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def self.instance(opts = { authorize: true })
|
|
16
|
-
@@inst ||= new(@cloud_host, @user, @password, opts[:authorize])
|
|
17
|
+
@@inst ||= new(@cloud_host, @user, @password, @code, opts[:authorize])
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
attr_reader :auth_ok, :cloud_host, :user, :password
|
|
20
21
|
|
|
21
|
-
def initialize(cloud_host, user,
|
|
22
|
+
def initialize(cloud_host, user, password, code = nil, auth = true)
|
|
22
23
|
@auth_ok = false
|
|
23
24
|
@cloud_host = cloud_host
|
|
24
25
|
@user = user
|
|
25
|
-
@password =
|
|
26
|
+
@password = password
|
|
27
|
+
@code = code
|
|
26
28
|
@verify_tls = Cloud.verify_tls
|
|
27
29
|
@last_authorized_account_ids = nil
|
|
28
30
|
@logger ||= ::LMC::Logger.new(STDOUT) if Cloud.debug
|
|
29
31
|
@logger.cloud = self if Cloud.debug
|
|
30
32
|
RestClient.log = @logger if Cloud.debug
|
|
31
|
-
|
|
33
|
+
login if auth
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
# hide
|
|
36
|
+
# hide secret fields from being displayed in dumps
|
|
35
37
|
def inspect
|
|
36
38
|
"#<Cloud:#{object_id}, #{build_url}>"
|
|
37
39
|
end
|
|
@@ -72,9 +74,9 @@ module LMC
|
|
|
72
74
|
prepared_headers = headers
|
|
73
75
|
prepared_headers[:params] = params
|
|
74
76
|
args = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
:method => :get,
|
|
78
|
+
:url => build_url(path),
|
|
79
|
+
:headers => prepared_headers
|
|
78
80
|
}
|
|
79
81
|
execute_request args
|
|
80
82
|
end
|
|
@@ -83,22 +85,22 @@ module LMC
|
|
|
83
85
|
prepared_headers = headers
|
|
84
86
|
prepared_headers[:params] = params
|
|
85
87
|
args = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
:method => :put,
|
|
89
|
+
:url => build_url(path),
|
|
90
|
+
:payload => body_object.to_json,
|
|
91
|
+
:headers => prepared_headers
|
|
90
92
|
}
|
|
91
93
|
execute_request args
|
|
92
94
|
end
|
|
93
95
|
|
|
94
|
-
def post(path, body_object, params=nil
|
|
96
|
+
def post(path, body_object, params = nil)
|
|
95
97
|
prepared_headers = headers
|
|
96
98
|
prepared_headers[:params] = params
|
|
97
99
|
args = {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
:method => :post,
|
|
101
|
+
:url => build_url(path),
|
|
102
|
+
:payload => body_object.to_json,
|
|
103
|
+
:headers => prepared_headers
|
|
102
104
|
}
|
|
103
105
|
execute_request args
|
|
104
106
|
end
|
|
@@ -107,9 +109,9 @@ module LMC
|
|
|
107
109
|
prepared_headers = headers
|
|
108
110
|
prepared_headers[:params] = params
|
|
109
111
|
args = {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
:method => :delete,
|
|
113
|
+
:url => build_url(path),
|
|
114
|
+
:headers => prepared_headers
|
|
113
115
|
}
|
|
114
116
|
execute_request args
|
|
115
117
|
end
|
|
@@ -143,7 +145,7 @@ module LMC
|
|
|
143
145
|
|
|
144
146
|
private
|
|
145
147
|
|
|
146
|
-
def authorize(accounts = []
|
|
148
|
+
def authorize(accounts = [])
|
|
147
149
|
account_ids = accounts.map { |a|
|
|
148
150
|
if a.respond_to? :id
|
|
149
151
|
a.id
|
|
@@ -153,19 +155,39 @@ module LMC
|
|
|
153
155
|
}
|
|
154
156
|
if account_ids != @last_authorized_account_ids
|
|
155
157
|
begin
|
|
156
|
-
reply = post(['cloud-service-auth', 'auth'],
|
|
158
|
+
reply = post(['cloud-service-auth', 'auth'],
|
|
159
|
+
name: @user,
|
|
160
|
+
password: @password,
|
|
161
|
+
code: @code,
|
|
162
|
+
accountIds: account_ids,
|
|
163
|
+
)
|
|
157
164
|
@last_authorized_account_ids = account_ids
|
|
158
165
|
@auth_token = reply
|
|
159
166
|
@auth_ok = true
|
|
160
|
-
rescue ::RestClient::ExceptionWithResponse => e
|
|
161
|
-
response = JSON.parse(e.response.body)
|
|
162
|
-
if response['code'] == 100
|
|
163
|
-
raise LMC::OutdatedTermsOfUseException.new(response)
|
|
164
|
-
end
|
|
165
167
|
end
|
|
166
168
|
end
|
|
167
169
|
end
|
|
168
170
|
|
|
171
|
+
def login(tos = [])
|
|
172
|
+
begin
|
|
173
|
+
reply = post(['cloud-service-auth', 'userlogin'],
|
|
174
|
+
name: @user,
|
|
175
|
+
password: @password,
|
|
176
|
+
code: @code,
|
|
177
|
+
termsOfUse: tos)
|
|
178
|
+
@auth_token = reply
|
|
179
|
+
@auth_ok = true
|
|
180
|
+
rescue ResponseException => e
|
|
181
|
+
if e.response['code'] == 104
|
|
182
|
+
raise LMC::MissingCodeException.new e.response
|
|
183
|
+
end
|
|
184
|
+
if e.response['code'] == 100
|
|
185
|
+
raise LMC::OutdatedTermsOfUseException.new e.response
|
|
186
|
+
end
|
|
187
|
+
raise e
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
169
191
|
def auth_bearer
|
|
170
192
|
"Bearer #{session_token}"
|
|
171
193
|
end
|
|
@@ -198,7 +220,7 @@ module LMC
|
|
|
198
220
|
puts 'EX.response: ' + e.response.to_s
|
|
199
221
|
puts JSON.parse(e.response)['message']
|
|
200
222
|
end
|
|
201
|
-
raise e
|
|
223
|
+
raise ResponseException.new e.response
|
|
202
224
|
end
|
|
203
225
|
end
|
|
204
226
|
end
|
data/lib/lmc/Response.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'ostruct'
|
|
4
|
+
require 'recursive-open-struct'
|
|
4
5
|
module LMC
|
|
5
6
|
class LMCResponse
|
|
6
7
|
attr_reader :body, :code, :headers
|
|
@@ -13,12 +14,12 @@ module LMC
|
|
|
13
14
|
if @body_object.class == Array
|
|
14
15
|
@body = @body_object.map { |elem|
|
|
15
16
|
if elem.is_a? Hash then
|
|
16
|
-
|
|
17
|
+
RecursiveOpenStruct.new(elem, recurse_over_arrays: true)
|
|
17
18
|
else
|
|
18
19
|
elem
|
|
19
20
|
end}
|
|
20
21
|
elsif @body_object.class == Hash
|
|
21
|
-
@body =
|
|
22
|
+
@body = RecursiveOpenStruct.new(@body_object, recurse_over_arrays: true)
|
|
22
23
|
elsif @body_object.class == TrueClass || @body_object.class == FalseClass
|
|
23
24
|
@body = @body_object
|
|
24
25
|
else
|
|
@@ -51,7 +52,7 @@ module LMC
|
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
def to_s
|
|
54
|
-
"Response: Code: #{@code}, Body: #{@body_object
|
|
55
|
+
"Response: Code: #{@code}, Body: #{@body_object}"
|
|
55
56
|
end
|
|
56
57
|
|
|
57
58
|
def empty?
|
data/lib/lmc/Site.rb
CHANGED
data/lib/lmc/User.rb
CHANGED
|
@@ -22,18 +22,14 @@ module LMC
|
|
|
22
22
|
|
|
23
23
|
def update(old_pw)
|
|
24
24
|
cloud = Cloud.instance
|
|
25
|
-
|
|
26
|
-
cloud.post ['cloud-service-auth', 'users', 'self', 'password'], 'password' => @password, 'verification' => old_pw
|
|
27
|
-
rescue RestClient::BadRequest => e
|
|
28
|
-
response_body = JSON.parse(e.response)
|
|
29
|
-
raise "#{e.message} - #{response_body['message']}"
|
|
30
|
-
end
|
|
25
|
+
cloud.post ['cloud-service-auth', 'users', 'self', 'password'], 'password' => @password, 'verification' => old_pw
|
|
31
26
|
end
|
|
32
27
|
|
|
33
28
|
def request_pw_reset
|
|
34
29
|
action = AuthAction.new Cloud.instance
|
|
35
30
|
action.type = 'PASSWORD_RESET'
|
|
36
31
|
action.name = @email
|
|
32
|
+
action.data = nil
|
|
37
33
|
action.post
|
|
38
34
|
end
|
|
39
35
|
end
|
data/lib/lmc/authority.rb
CHANGED
|
@@ -54,7 +54,7 @@ module LMC
|
|
|
54
54
|
def descriptive_confighash
|
|
55
55
|
item_map = dscui.item_by_id_map
|
|
56
56
|
confighash.map { |k, v|
|
|
57
|
-
[item_map[k].description, v]
|
|
57
|
+
[item_map[k.to_s].description, v]
|
|
58
58
|
}.to_h
|
|
59
59
|
end
|
|
60
60
|
|
|
@@ -75,12 +75,12 @@ module LMC
|
|
|
75
75
|
|
|
76
76
|
result = ''
|
|
77
77
|
result += lcf_header
|
|
78
|
-
items.each do |key, value|
|
|
78
|
+
items.to_h.each do |key, value|
|
|
79
79
|
if value.instance_of? String
|
|
80
80
|
result += "#{key} = #{value}\n"
|
|
81
81
|
elsif value.instance_of? Hash
|
|
82
|
-
rows = value[
|
|
83
|
-
col_ids = value[
|
|
82
|
+
rows = value[:rows]
|
|
83
|
+
col_ids = value[:colIds]
|
|
84
84
|
if rows.length > 0
|
|
85
85
|
result += "<#{key}>\n"
|
|
86
86
|
rows.each_with_index { |row, index|
|
|
@@ -92,7 +92,7 @@ module LMC
|
|
|
92
92
|
raise 'Unexpected value in config items: ' + value.class.to_s
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
|
-
result
|
|
95
|
+
result + lcf_footer
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def current_device_type
|
|
@@ -127,6 +127,7 @@ module LMC
|
|
|
127
127
|
# @return [String]
|
|
128
128
|
def lcf_feature_id_string
|
|
129
129
|
hex_features = current_device_type.features.map { |feature| feature.to_s 16 }
|
|
130
|
+
hex_features << '80000800' # Magic feature to cause lanconfig to show the password
|
|
130
131
|
"IDs:#{hex_features.join(',')}"
|
|
131
132
|
end
|
|
132
133
|
|
|
@@ -161,7 +162,8 @@ module LMC
|
|
|
161
162
|
end
|
|
162
163
|
|
|
163
164
|
def fetch_result
|
|
164
|
-
|
|
165
|
+
# TODO: Make parameters settable
|
|
166
|
+
response_or_ticket = @cloud.get(url_configbuilder, { includePasswords: 'TRUE', includeSmartApps: 'FALSE' }).body
|
|
165
167
|
if response_or_ticket.respond_to? 'ticketId'
|
|
166
168
|
@ticket_id = response_or_ticket.ticketId
|
|
167
169
|
redeem_ticket 5
|
|
@@ -172,16 +174,17 @@ module LMC
|
|
|
172
174
|
end
|
|
173
175
|
|
|
174
176
|
def redeem_ticket(tries)
|
|
177
|
+
wait_seconds = 0.5
|
|
175
178
|
attempts = 1
|
|
176
179
|
until @response
|
|
177
|
-
raise
|
|
180
|
+
raise "Timeout waiting for config (#{attempts * wait_seconds}s)" if attempts > tries
|
|
178
181
|
attempts += 1
|
|
179
182
|
body = @cloud.get(url_ticket).body
|
|
180
183
|
unless body.respond_to? :ticketId
|
|
181
184
|
@ticket_id = nil
|
|
182
185
|
@response = body
|
|
183
186
|
end
|
|
184
|
-
sleep
|
|
187
|
+
sleep wait_seconds * attempts
|
|
185
188
|
end
|
|
186
189
|
end
|
|
187
190
|
|
|
@@ -28,11 +28,10 @@ module LMC
|
|
|
28
28
|
attr_reader :version_string, :sections
|
|
29
29
|
|
|
30
30
|
def initialize(v_hash)
|
|
31
|
-
keys = v_hash.keys
|
|
31
|
+
keys = v_hash.to_h.keys
|
|
32
32
|
raise('More than one version key contained in dscui.') if keys.length > 1
|
|
33
33
|
@version_string = keys.first
|
|
34
34
|
@sections = v_hash[@version_string].map { |section_wrapper| Section.new section_wrapper }
|
|
35
|
-
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
def items
|
|
@@ -54,7 +53,6 @@ module LMC
|
|
|
54
53
|
@groups = members.map { |group_wrapper|
|
|
55
54
|
Group.new group_wrapper unless group_wrapper['group'].nil?
|
|
56
55
|
}.compact
|
|
57
|
-
|
|
58
56
|
end
|
|
59
57
|
end
|
|
60
58
|
|
|
@@ -76,7 +74,7 @@ module LMC
|
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
def initialize(item_wrapper)
|
|
79
|
-
keys = item_wrapper.keys
|
|
77
|
+
keys = item_wrapper.to_h.keys
|
|
80
78
|
raise('More than one key contained in item wrapper') if keys.length > 1
|
|
81
79
|
@type = keys.first
|
|
82
80
|
item = item_wrapper[@type]
|
data/lib/lmc/entity.rb
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module LMC
|
|
4
|
-
class OutdatedTermsOfUseException <
|
|
5
|
-
def initialize(response = {})
|
|
6
|
-
@response = response
|
|
7
|
-
end
|
|
8
|
-
|
|
4
|
+
class OutdatedTermsOfUseException < ResponseException
|
|
9
5
|
def response
|
|
10
6
|
r = "Terms of use must be accepted before using this LMC instance:\n"
|
|
11
7
|
missing.each do |tos|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module LMC
|
|
3
|
+
class ResponseException < RuntimeError
|
|
4
|
+
attr_reader :response
|
|
5
|
+
|
|
6
|
+
# Initialize a ResponseException.
|
|
7
|
+
#
|
|
8
|
+
# @param [Object] response restclient Response
|
|
9
|
+
def initialize(response)
|
|
10
|
+
if response.is_a? LMCResponse
|
|
11
|
+
@response = response
|
|
12
|
+
else
|
|
13
|
+
@response = LMCResponse.new response
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def message
|
|
18
|
+
cause.message
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
data/lib/lmc/version.rb
CHANGED
data/lmc.gemspec
CHANGED
|
@@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.authors = ['erpel']
|
|
11
11
|
spec.email = ['philipp@copythat.de']
|
|
12
12
|
|
|
13
|
+
spec.required_ruby_version = '~> 2.0'
|
|
13
14
|
spec.summary = %q{Library for interacting with LMC cloud instances}
|
|
14
15
|
spec.license = 'BSD-3-Clause'
|
|
15
16
|
|
|
@@ -32,13 +33,13 @@ Gem::Specification.new do |spec|
|
|
|
32
33
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
33
34
|
spec.add_development_dependency 'minitest', '~> 5.11'
|
|
34
35
|
spec.add_development_dependency 'minitest-reporters', '~> 1'
|
|
36
|
+
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
|
35
37
|
spec.add_development_dependency 'rake', '~> 12.0'
|
|
36
|
-
spec.add_development_dependency '
|
|
38
|
+
spec.add_development_dependency 'rubocop', '~> 1.14'
|
|
37
39
|
spec.add_development_dependency 'simplecov', '~> 0.15'
|
|
38
|
-
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
|
39
|
-
spec.add_development_dependency 'rubocop', '~> 0.58.1'
|
|
40
40
|
|
|
41
41
|
spec.add_runtime_dependency 'json', '~> 2.3'
|
|
42
|
+
spec.add_runtime_dependency 'recursive-open-struct', '~> 1.1'
|
|
42
43
|
spec.add_runtime_dependency 'rest-client', '~> 2.0'
|
|
43
44
|
end
|
|
44
45
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lmc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 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:
|
|
11
|
+
date: 2021-08-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -53,89 +53,89 @@ dependencies:
|
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
54
|
version: '1'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
56
|
+
name: pry-nav
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
61
|
+
version: 0.2.4
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
68
|
+
version: 0.2.4
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: rake
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
75
|
+
version: '12.0'
|
|
76
76
|
type: :development
|
|
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: '
|
|
82
|
+
version: '12.0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: rubocop
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '1.14'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '1.14'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
98
|
+
name: simplecov
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 0.
|
|
103
|
+
version: '0.15'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 0.
|
|
110
|
+
version: '0.15'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
112
|
+
name: json
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
115
|
- - "~>"
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version:
|
|
118
|
-
type: :
|
|
117
|
+
version: '2.3'
|
|
118
|
+
type: :runtime
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - "~>"
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
124
|
+
version: '2.3'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
126
|
+
name: recursive-open-struct
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
129
|
- - "~>"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
131
|
+
version: '1.1'
|
|
132
132
|
type: :runtime
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
136
|
- - "~>"
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
138
|
+
version: '1.1'
|
|
139
139
|
- !ruby/object:Gem::Dependency
|
|
140
140
|
name: rest-client
|
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,7 +150,7 @@ dependencies:
|
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '2.0'
|
|
153
|
-
description:
|
|
153
|
+
description:
|
|
154
154
|
email:
|
|
155
155
|
- philipp@copythat.de
|
|
156
156
|
executables: []
|
|
@@ -190,6 +190,8 @@ files:
|
|
|
190
190
|
- lib/lmc/device_config_state.rb
|
|
191
191
|
- lib/lmc/entity.rb
|
|
192
192
|
- lib/lmc/exceptions/lmc_outdated_terms_of_use_exception.rb
|
|
193
|
+
- lib/lmc/exceptions/lmc_two_factor_required_exception.rb
|
|
194
|
+
- lib/lmc/exceptions/response_exception.rb
|
|
193
195
|
- lib/lmc/logger.rb
|
|
194
196
|
- lib/lmc/membership.rb
|
|
195
197
|
- lib/lmc/mixins/json_able.rb
|
|
@@ -201,19 +203,19 @@ files:
|
|
|
201
203
|
- lib/lmc/version.rb
|
|
202
204
|
- lmc.gemspec
|
|
203
205
|
- misc/debug_log_experiment.rb
|
|
204
|
-
homepage:
|
|
206
|
+
homepage:
|
|
205
207
|
licenses:
|
|
206
208
|
- BSD-3-Clause
|
|
207
209
|
metadata: {}
|
|
208
|
-
post_install_message:
|
|
210
|
+
post_install_message:
|
|
209
211
|
rdoc_options: []
|
|
210
212
|
require_paths:
|
|
211
213
|
- lib
|
|
212
214
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
213
215
|
requirements:
|
|
214
|
-
- - "
|
|
216
|
+
- - "~>"
|
|
215
217
|
- !ruby/object:Gem::Version
|
|
216
|
-
version: '0'
|
|
218
|
+
version: '2.0'
|
|
217
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
220
|
requirements:
|
|
219
221
|
- - ">="
|
|
@@ -221,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
221
223
|
version: '0'
|
|
222
224
|
requirements: []
|
|
223
225
|
rubygems_version: 3.1.2
|
|
224
|
-
signing_key:
|
|
226
|
+
signing_key:
|
|
225
227
|
specification_version: 4
|
|
226
228
|
summary: Library for interacting with LMC cloud instances
|
|
227
229
|
test_files: []
|