lmc 0.8.0 → 0.12.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/encodings.xml +4 -0
- data/.idea/inspectionProfiles/Project_Default.xml +1 -1
- data/.rubocop.yml +8 -2
- data/.ruby-version +1 -1
- data/PATTERNS.md +26 -0
- data/{README.md → README.rdoc} +0 -0
- data/Rakefile +32 -7
- data/coverage/.last_run.json +1 -1
- data/lib/lmc.rb +2 -2
- data/lib/lmc/Account.rb +57 -47
- data/lib/lmc/Cloud.rb +45 -30
- data/lib/lmc/Configstates.rb +3 -4
- data/lib/lmc/Device.rb +18 -23
- data/lib/lmc/Response.rb +3 -4
- data/lib/lmc/Site.rb +11 -21
- data/lib/lmc/User.rb +9 -10
- data/lib/lmc/account_manager.rb +29 -28
- data/lib/lmc/auth/auth_action.rb +3 -2
- data/lib/lmc/authority.rb +11 -9
- data/lib/lmc/config/device_config.rb +193 -0
- data/lib/lmc/config/device_dsc_ui.rb +94 -0
- data/lib/lmc/device_config_state.rb +1 -1
- data/lib/lmc/entity.rb +8 -8
- data/lib/lmc/exceptions/lmc_outdated_terms_of_use_exception.rb +3 -3
- data/lib/lmc/logger.rb +9 -2
- data/lib/lmc/membership.rb +5 -5
- data/lib/lmc/mixins/json_able.rb +3 -2
- data/lib/lmc/mixins/service_resource.rb +5 -10
- data/lib/lmc/monitoring/monitoring_record.rb +5 -4
- data/lib/lmc/preferences/preferences.rb +24 -0
- data/lib/lmc/principal.rb +9 -8
- data/lib/lmc/uuid.rb +17 -0
- data/lib/lmc/version.rb +2 -1
- data/lmc.gemspec +17 -15
- metadata +32 -14
- data/.travis.yml +0 -5
data/lib/lmc/Configstates.rb
CHANGED
@@ -5,12 +5,11 @@ module LMC
|
|
5
5
|
attr_reader :actual, :outdated
|
6
6
|
|
7
7
|
def initialize(data)
|
8
|
-
@actual = data[
|
9
|
-
@outdated = data[
|
8
|
+
@actual = data['ACTUAL']
|
9
|
+
@outdated = data['OUTDATED']
|
10
10
|
@actual ||= 0
|
11
11
|
@outdated ||= 0
|
12
12
|
end
|
13
|
-
|
14
13
|
end
|
14
|
+
end
|
15
15
|
|
16
|
-
end
|
data/lib/lmc/Device.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module LMC
|
4
4
|
class Device
|
5
|
-
attr_reader :id, :name, :model, :serial, :heartbeatstate
|
5
|
+
attr_reader :id, :name, :model, :serial, :heartbeatstate, :cloud, :account, :status
|
6
6
|
|
7
7
|
def initialize(data)
|
8
8
|
@id = data['id']
|
@@ -17,51 +17,42 @@ module LMC
|
|
17
17
|
@cloud ||= Cloud.instance
|
18
18
|
end
|
19
19
|
|
20
|
-
def get_config_for_account(account)
|
21
|
-
response = @cloud.get ["cloud-service-config", "configbuilder", "accounts", account.id, "devices", @id, "ui"]
|
22
|
-
JSON.parse(JSON.generate(response.body.to_h)) #terrible hack to get it to work for now. needs way to get more raw body_object from Response
|
23
|
-
end
|
24
|
-
|
25
20
|
def set_config_for_account(config, account)
|
26
|
-
@cloud.put [
|
21
|
+
@cloud.put ['cloud-service-config', 'configbuilder', 'accounts', account.id, 'devices', @id, 'ui'], config
|
27
22
|
end
|
28
23
|
|
29
24
|
def get_monitor_widgets(widget_item_ids)
|
30
|
-
@cloud.get [
|
25
|
+
@cloud.get ['cloud-service-monitoring', @account.id, 'devices', @id, 'monitordata'], :widgetItemIds => widget_item_ids.join(',')
|
31
26
|
end
|
32
27
|
|
33
28
|
def self.get_for_account(account)
|
34
29
|
cloud = Cloud.instance
|
35
30
|
cloud.auth_for_accounts [account.id]
|
36
|
-
list = cloud.get [
|
31
|
+
list = cloud.get ['cloud-service-devices', 'accounts', account.id, 'devices']
|
37
32
|
if list.code != 200
|
38
33
|
puts "Error getting devices: #{list.body.message}"
|
39
34
|
exit 1
|
40
35
|
end
|
41
36
|
devices = list.map do |data|
|
42
|
-
data[
|
37
|
+
data['account'] = account
|
43
38
|
LMC::Device.new(data)
|
44
39
|
end
|
45
|
-
|
40
|
+
devices
|
46
41
|
end
|
47
42
|
|
48
43
|
def self.get_for_account_id(account_id)
|
49
|
-
|
44
|
+
get_for_account Account.get(account_id)
|
50
45
|
end
|
51
46
|
|
52
47
|
def config_state
|
53
48
|
@config_state ||= get_config_state
|
54
49
|
end
|
55
50
|
|
56
|
-
def
|
57
|
-
|
58
|
-
#cloud = Cloud.instance
|
59
|
-
##cloud.auth_for_accounts [id]
|
60
|
-
#cloud.get ["cloud-service-logging", "accounts", id, "logs?lang=DE"]
|
61
|
-
raise "device logs not supported"
|
51
|
+
def config
|
52
|
+
LMC::DeviceConfig.new(@cloud, @account, self)
|
62
53
|
end
|
63
54
|
|
64
|
-
def record
|
55
|
+
def record(name)
|
65
56
|
MonitoringRecord.new(@cloud, @account, self, name)
|
66
57
|
end
|
67
58
|
|
@@ -69,17 +60,21 @@ module LMC
|
|
69
60
|
'DEVICE'
|
70
61
|
end
|
71
62
|
|
63
|
+
def hwmask_hex
|
64
|
+
format format '%#010x', status['hwMask']
|
65
|
+
end
|
66
|
+
|
72
67
|
private
|
73
68
|
|
69
|
+
##
|
70
|
+
# TODO: This functionality is now duplicated in the DeviceConfig class and it's worse there.
|
74
71
|
def get_config_state
|
75
|
-
reply = @cloud.get [
|
72
|
+
reply = @cloud.get ['cloud-service-config', 'configdevice', 'accounts', @account.id, 'state'], 'deviceIds' => @id
|
76
73
|
if reply.code == 200
|
77
74
|
# binding.pry
|
78
75
|
DeviceConfigState.new reply.body[@id]
|
79
76
|
end
|
80
77
|
end
|
81
|
-
|
82
|
-
|
83
78
|
end
|
84
|
-
|
85
79
|
end
|
80
|
+
|
data/lib/lmc/Response.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'ostruct'
|
4
4
|
module LMC
|
5
5
|
class LMCResponse
|
6
|
-
|
7
6
|
attr_reader :body, :code, :headers
|
8
7
|
|
9
8
|
def initialize(response)
|
@@ -12,7 +11,7 @@ module LMC
|
|
12
11
|
@body_object = JSON.parse response.body
|
13
12
|
end
|
14
13
|
if @body_object.class == Array
|
15
|
-
@body = @body_object.map {|elem|
|
14
|
+
@body = @body_object.map { |elem|
|
16
15
|
if elem.is_a? Hash then
|
17
16
|
OpenStruct.new(elem)
|
18
17
|
else
|
@@ -23,7 +22,7 @@ module LMC
|
|
23
22
|
elsif @body_object.class == TrueClass || @body_object.class == FalseClass
|
24
23
|
@body = @body_object
|
25
24
|
else
|
26
|
-
raise "Unknown json parse result"
|
25
|
+
raise "Unknown json parse result: #{@body_object.class}"
|
27
26
|
end
|
28
27
|
@code = response.code
|
29
28
|
@headers = response.headers
|
@@ -59,5 +58,5 @@ module LMC
|
|
59
58
|
@body_object.empty?
|
60
59
|
end
|
61
60
|
end
|
62
|
-
|
63
61
|
end
|
62
|
+
|
data/lib/lmc/Site.rb
CHANGED
@@ -3,38 +3,28 @@
|
|
3
3
|
module LMC
|
4
4
|
class Site
|
5
5
|
attr_accessor :name
|
6
|
-
attr_reader :id, :account
|
6
|
+
attr_reader :id, :account, :subnet_group_id
|
7
7
|
|
8
8
|
def initialize(data, account)
|
9
|
-
@cloud =
|
10
|
-
@
|
11
|
-
@name = data["name"]
|
12
|
-
@subnet_group_id = data["subnetGroupId"]
|
9
|
+
@cloud = account.cloud
|
10
|
+
@cloud.auth_for_account account if account
|
13
11
|
@account = account
|
12
|
+
data = @cloud.get ['cloud-service-devices', 'accounts', @account.id, 'sites', data] if data.is_a? UUID
|
13
|
+
|
14
|
+
@id = data['id']
|
15
|
+
@name = data['name']
|
16
|
+
@subnet_group_id = data['subnetGroupId']
|
14
17
|
|
15
|
-
if @account
|
16
|
-
@cloud.auth_for_account @account
|
17
|
-
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_s
|
21
21
|
"#{@name}"
|
22
22
|
end
|
23
23
|
|
24
|
-
def account=(account)
|
25
|
-
if @account == nil
|
26
|
-
@account = account
|
27
|
-
return true
|
28
|
-
else
|
29
|
-
raise "Cannot replace account for site"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
24
|
def configstates
|
34
|
-
response = @cloud.get [
|
35
|
-
|
36
|
-
return states
|
25
|
+
response = @cloud.get ['cloud-service-config', 'configsubnetgroup', 'accounts', @account.id, 'subnetgroups', @subnet_group_id, 'updatestates']
|
26
|
+
LMC::Configstates.new response.body
|
37
27
|
end
|
38
28
|
end
|
39
|
-
|
40
29
|
end
|
30
|
+
|
data/lib/lmc/User.rb
CHANGED
@@ -2,28 +2,28 @@
|
|
2
2
|
|
3
3
|
module LMC
|
4
4
|
class User
|
5
|
-
#
|
5
|
+
# TODO: look into hiding password
|
6
6
|
attr_reader :email
|
7
7
|
|
8
8
|
def initialize(data)
|
9
|
-
@email = data[
|
10
|
-
@password = data[
|
9
|
+
@email = data['email']
|
10
|
+
@password = data['password']
|
11
11
|
end
|
12
12
|
|
13
13
|
# current registration process unclear and likely to have changed
|
14
14
|
# since this code was written.
|
15
|
-
#def register()
|
15
|
+
# def register()
|
16
16
|
# # cloud instance by default authenticates.
|
17
17
|
# # for registration specifically, no authentication is required
|
18
18
|
# # should be possible without email and password for "admin" user
|
19
19
|
# cloud = Cloud.instance
|
20
20
|
# cloud.post ["cloud-service-auth", "users"], {"password" => @password, "email" => @email}
|
21
|
-
#end
|
21
|
+
# end
|
22
22
|
|
23
23
|
def update(old_pw)
|
24
24
|
cloud = Cloud.instance
|
25
25
|
begin
|
26
|
-
cloud.post [
|
26
|
+
cloud.post ['cloud-service-auth', 'users', 'self', 'password'], 'password' => @password, 'verification' => old_pw
|
27
27
|
rescue RestClient::BadRequest => e
|
28
28
|
response_body = JSON.parse(e.response)
|
29
29
|
raise "#{e.message} - #{response_body['message']}"
|
@@ -32,11 +32,10 @@ module LMC
|
|
32
32
|
|
33
33
|
def request_pw_reset
|
34
34
|
action = AuthAction.new Cloud.instance
|
35
|
-
action.type=
|
36
|
-
action.name
|
35
|
+
action.type = 'PASSWORD_RESET'
|
36
|
+
action.name = @email
|
37
37
|
action.post
|
38
38
|
end
|
39
|
-
|
40
39
|
end
|
40
|
+
end
|
41
41
|
|
42
|
-
end
|
data/lib/lmc/account_manager.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module LMC
|
4
4
|
class AccountManager
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# @options
|
6
|
+
# @global_options
|
7
|
+
# @errors
|
8
8
|
attr_reader :errors
|
9
9
|
|
10
10
|
def initialize(options, global_options)
|
@@ -15,59 +15,59 @@ module LMC
|
|
15
15
|
|
16
16
|
# returns nil if invite did not work
|
17
17
|
def invite(lmcen, distro, line, type, authority_name)
|
18
|
-
lmcen.auth_for_accounts([distro[
|
18
|
+
lmcen.auth_for_accounts([distro['id']])
|
19
19
|
line = line.strip.downcase
|
20
20
|
begin
|
21
|
-
account = Account.get(distro[
|
21
|
+
account = Account.get(distro['id'])
|
22
22
|
account_authorities = account.authorities
|
23
|
-
#puts account_authorities.inspect if @global_options[:debug]
|
23
|
+
# puts account_authorities.inspect if @global_options[:debug]
|
24
24
|
if @global_options[:debug]
|
25
25
|
account_authorities.each do |a|
|
26
|
-
puts a[
|
26
|
+
puts a['name']
|
27
27
|
puts a.inspect
|
28
28
|
end
|
29
29
|
end
|
30
|
-
authority = account_authorities.find {|auth| auth[
|
31
|
-
#puts "account authorities: #{account_authorities}" if @global_options[:debug]
|
30
|
+
authority = account_authorities.find { |auth| auth['name'] == authority_name }
|
31
|
+
# puts "account authorities: #{account_authorities}" if @global_options[:debug]
|
32
32
|
puts authority if @global_options[:debug]
|
33
33
|
if !@options[:dry]
|
34
|
-
# TODO wenn der default authority nicht gibt geht das ding kaputt
|
35
|
-
invited = lmcen.invite_user_to_account(line, distro[
|
36
|
-
puts
|
37
|
-
puts
|
34
|
+
# TODO: wenn der default authority nicht gibt geht das ding kaputt
|
35
|
+
invited = lmcen.invite_user_to_account(line, distro['id'], type, [authority['id']])
|
36
|
+
puts 'Invite response:' + invited.inspect if @global_options[:debug]
|
37
|
+
puts 'Invited ' + invited['name'].to_s + " to account #{distro['name']}(#{invited.code})." if @global_options[:v]
|
38
38
|
if invited.code != 200
|
39
|
-
@errors << {:line => line, :result => invited.body}
|
39
|
+
@errors << { :line => line, :result => invited.body }
|
40
40
|
return nil
|
41
41
|
end
|
42
42
|
else
|
43
|
-
invited = {
|
43
|
+
invited = { 'name' => line }
|
44
44
|
end
|
45
45
|
|
46
|
-
invite_url = lmcen.build_url(
|
47
|
-
if @options[
|
48
|
-
puts "\n" + invited[
|
46
|
+
invite_url = lmcen.build_url('#', 'register', Base64.encode64(invited['name']))
|
47
|
+
if @options['show-csv']
|
48
|
+
puts "\n" + invited['name'] + ', ' + invite_url
|
49
49
|
end
|
50
|
-
if @options[
|
50
|
+
if @options['send-mail'] && invited
|
51
51
|
mailbody = <<END
|
52
52
|
Hallo,
|
53
|
-
auf #{lmcen.cloud_host} wurde eine Einladung zu dem Account #{distro[
|
53
|
+
auf #{lmcen.cloud_host} wurde eine Einladung zu dem Account #{distro['name']} für den Nutzer #{invited['name']} erstellt.
|
54
54
|
|
55
55
|
Falls der Account noch nicht existiert, kann dieser Link zur Registrierung genutzt werden:
|
56
56
|
END
|
57
57
|
mail = Mail.new do
|
58
|
-
from
|
59
|
-
to invited[
|
60
|
-
subject
|
58
|
+
from 'Philipp Erbelding <philipp.erbelding@lancom.de>'
|
59
|
+
to invited['name']
|
60
|
+
subject 'Einladung auf ' + lmcen.cloud_host
|
61
61
|
body mailbody + invite_url
|
62
62
|
end
|
63
63
|
|
64
64
|
puts invite_url
|
65
65
|
if !@options[:dry]
|
66
|
-
puts
|
67
|
-
mail.delivery_method :smtp, address:
|
66
|
+
puts 'sending mail to ' + invited['name']
|
67
|
+
mail.delivery_method :smtp, address: 'lcs-mail'
|
68
68
|
mail.deliver
|
69
69
|
else
|
70
|
-
puts
|
70
|
+
puts '[DRY RUN] would send mail to ' + invited['name']
|
71
71
|
end
|
72
72
|
puts mail.to_s if @global_options[:v]
|
73
73
|
end
|
@@ -77,9 +77,10 @@ END
|
|
77
77
|
puts invited.inspect
|
78
78
|
resp = JSON.parse(e.response)
|
79
79
|
puts resp.inspect
|
80
|
-
puts resp[
|
80
|
+
puts resp['message']
|
81
81
|
end
|
82
|
-
|
82
|
+
true
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
|
+
|
data/lib/lmc/auth/auth_action.rb
CHANGED
data/lib/lmc/authority.rb
CHANGED
@@ -5,6 +5,7 @@ module LMC
|
|
5
5
|
attr_accessor :account, :id, :name, :visibility, :type
|
6
6
|
|
7
7
|
def initialize(data, account)
|
8
|
+
# TODO: Use cloud object from account
|
8
9
|
@cloud = Cloud.instance
|
9
10
|
apply_data(data)
|
10
11
|
@account = account
|
@@ -14,26 +15,26 @@ module LMC
|
|
14
15
|
# GET /accounts/{accountId}/authorities/{authorityId}/rights
|
15
16
|
@cloud.auth_for_account @account
|
16
17
|
response = @cloud.get ['cloud-service-auth', 'accounts', @account.id, 'authorities', @id, 'rights']
|
17
|
-
|
18
|
+
response.body.to_s
|
18
19
|
end
|
19
20
|
|
20
|
-
#returns itself, allows chaining
|
21
|
+
# returns itself, allows chaining
|
21
22
|
def save
|
22
23
|
response = if @id.nil?
|
23
|
-
Cloud.instance.post [
|
24
|
+
Cloud.instance.post ['cloud-service-auth', 'accounts', @account.id, 'authorities'], self
|
24
25
|
else
|
25
|
-
raise
|
26
|
-
|
26
|
+
raise 'editing authorities not supported'
|
27
|
+
# @cloud.put ["cloud-service-auth", "principals", @id], self
|
27
28
|
end
|
28
29
|
apply_data(response.body)
|
29
|
-
|
30
|
+
self
|
30
31
|
end
|
31
32
|
|
32
33
|
def to_json(*a)
|
33
34
|
{
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
'name' => @name,
|
36
|
+
'type' => @type,
|
37
|
+
'visibility' => @visibility
|
37
38
|
}.to_json(*a)
|
38
39
|
end
|
39
40
|
|
@@ -51,3 +52,4 @@ module LMC
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
55
|
+
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LMC
|
4
|
+
# Represents a device config in LMC
|
5
|
+
class DeviceConfig
|
6
|
+
attr_reader :state
|
7
|
+
|
8
|
+
def url_configbuilder
|
9
|
+
['cloud-service-config', 'configbuilder', 'accounts',
|
10
|
+
@account.id, 'devices', @device.id, 'ui']
|
11
|
+
end
|
12
|
+
|
13
|
+
def url_ticket
|
14
|
+
['cloud-service-config',
|
15
|
+
'configbuilder',
|
16
|
+
'accounts',
|
17
|
+
@account.id,
|
18
|
+
'devices',
|
19
|
+
@device.id,
|
20
|
+
'tickets',
|
21
|
+
@ticket_id]
|
22
|
+
end
|
23
|
+
|
24
|
+
def url_state
|
25
|
+
%W(cloud-service-config configdevice accounts #{@account.id} state)
|
26
|
+
end
|
27
|
+
|
28
|
+
# def url_stringtable
|
29
|
+
# ['cloud-service-config', 'configdsc', 'stringtable', dscui['stringtableId']]
|
30
|
+
# end
|
31
|
+
|
32
|
+
def initialize(cloud, account, device)
|
33
|
+
@cloud = cloud
|
34
|
+
@account = account
|
35
|
+
@device = device
|
36
|
+
@response = nil
|
37
|
+
@ticket_id = nil
|
38
|
+
# state returns an object with each requested device id pointing to a state object.
|
39
|
+
@state = @cloud.get(url_state, deviceIds: @device.id.to_s).body[@device.id]
|
40
|
+
end
|
41
|
+
|
42
|
+
def configjson
|
43
|
+
confighash.to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def confighash
|
47
|
+
items.to_h
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Returns a hash similar to #confighash but with the OIDs replaced with more
|
52
|
+
# meaningful descriptions.
|
53
|
+
|
54
|
+
def descriptive_confighash
|
55
|
+
item_map = dscui.item_by_id_map
|
56
|
+
confighash.map { |k, v|
|
57
|
+
[item_map[k].description, v]
|
58
|
+
}.to_h
|
59
|
+
end
|
60
|
+
|
61
|
+
def items
|
62
|
+
response.items
|
63
|
+
end
|
64
|
+
|
65
|
+
def dscui
|
66
|
+
@dscui ||= DeviceDSCUi.new @device
|
67
|
+
end
|
68
|
+
|
69
|
+
def lcf
|
70
|
+
# lfc format findings:
|
71
|
+
# group headings in {} do not matter
|
72
|
+
# indentation does not matter
|
73
|
+
# table oids need to be enclosed in <>
|
74
|
+
# table cell oids need to be enclosed in () and should follow table oids
|
75
|
+
|
76
|
+
result = ''
|
77
|
+
result += lcf_header
|
78
|
+
items.each do |key, value|
|
79
|
+
if value.instance_of? String
|
80
|
+
result += "#{key} = #{value}\n"
|
81
|
+
elsif value.instance_of? Hash
|
82
|
+
rows = value['rows']
|
83
|
+
col_ids = value['colIds']
|
84
|
+
if rows.length > 0
|
85
|
+
result += "<#{key}>\n"
|
86
|
+
rows.each_with_index { |row, index|
|
87
|
+
row.each_with_index { |col, col_index|
|
88
|
+
result += "(#{key}.#{index + 1}.#{col_ids[col_index]}) = #{col}\n"}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
else
|
92
|
+
raise 'Unexpected value in config items: ' + value.class.to_s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
result += lcf_footer
|
96
|
+
end
|
97
|
+
|
98
|
+
def current_device_type
|
99
|
+
OpenStruct.new JSON.parse state['currentDeviceType']
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# @return [String]
|
104
|
+
def feature_mask_lower32_hex
|
105
|
+
feature_mask = 0
|
106
|
+
lower_features = current_device_type.features.select { |feature| feature < 32 }
|
107
|
+
lower_features.each do |feature_pos|
|
108
|
+
feature = 2**feature_pos
|
109
|
+
feature_mask = feature_mask | feature
|
110
|
+
end
|
111
|
+
if feature_mask == 0
|
112
|
+
'0x00000000'
|
113
|
+
else
|
114
|
+
format '%#010x', feature_mask
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def lcf_device_version
|
119
|
+
v = 'v'
|
120
|
+
v += "#{@device.status['fwMajor']}."
|
121
|
+
v += "#{@device.status['fwMinor']}."
|
122
|
+
v + format('%04d', @device.status['fwBuild'])
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Gives the feature IDs as a string like this: "IDs:2,3,f"
|
127
|
+
# @return [String]
|
128
|
+
def lcf_feature_id_string
|
129
|
+
hex_features = current_device_type.features.map { |feature| feature.to_s 16 }
|
130
|
+
"IDs:#{hex_features.join(',')}"
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
##
|
136
|
+
# Produces lcf header
|
137
|
+
# @return [String]
|
138
|
+
def lcf_header
|
139
|
+
"(LMC Configuration of '#{@device.name}' at #{Time.now} via ruby-lmc #{LMC::VERSION})
|
140
|
+
(#{@device.status['fwLabel']}) (#{lcf_feature_hw_string})
|
141
|
+
[#{@device.model}] #{lcf_device_version}
|
142
|
+
[TYPE: LCF; VERSION: 1.00; HASHTYPE: none;]
|
143
|
+
"
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Gives the feature mask, the feature IDs and the hardware mask as string for the lcf
|
148
|
+
# header like this: "0x0000c010,IDs:4,e,f//e0901447,2b;0x0c000002"
|
149
|
+
# @return [String]
|
150
|
+
def lcf_feature_hw_string
|
151
|
+
"#{feature_mask_lower32_hex},#{lcf_feature_id_string};#{@device.hwmask_hex}"
|
152
|
+
end
|
153
|
+
|
154
|
+
def lcf_footer
|
155
|
+
"[END: LCF;]\n"
|
156
|
+
end
|
157
|
+
|
158
|
+
def response
|
159
|
+
return @response unless @response.nil?
|
160
|
+
fetch_result
|
161
|
+
end
|
162
|
+
|
163
|
+
def fetch_result
|
164
|
+
response_or_ticket = @cloud.get(url_configbuilder).body
|
165
|
+
if response_or_ticket.respond_to? 'ticketId'
|
166
|
+
@ticket_id = response_or_ticket.ticketId
|
167
|
+
redeem_ticket 5
|
168
|
+
else
|
169
|
+
@response = response_or_ticket
|
170
|
+
end
|
171
|
+
@response
|
172
|
+
end
|
173
|
+
|
174
|
+
def redeem_ticket(tries)
|
175
|
+
attempts = 1
|
176
|
+
until @response
|
177
|
+
raise 'Too many attempts' if attempts > tries
|
178
|
+
attempts += 1
|
179
|
+
body = @cloud.get(url_ticket).body
|
180
|
+
unless body.respond_to? :ticketId
|
181
|
+
@ticket_id = nil
|
182
|
+
@response = body
|
183
|
+
end
|
184
|
+
sleep 0.5
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# def stringtable
|
189
|
+
# @stringtable ||= @cloud.get(url_stringtable).body
|
190
|
+
# end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|